~aleteoryx/ntalk

ref: eca131347c4561f3102a9e2c75a0d01cd5714488 ntalk/nanobnc.py -rwxr-xr-x 1.7 KiB
eca13134Aleteoryx nanobnc a month ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env python

import socket
import threading
from sys import exit, argv, stderr, stdout, stdin
from signal import alarm, signal, SIGALRM

argv0 = 'nanobnc.py'
sok = None

def usage():
	print(f'usage: {argv0} passphrase [timeout]')
	exit(1)

def handle_args():
	global argv0, argv
	if len(argv) > 0:
		argv0 = argv[0]
		argv = argv[1:]
	if len(argv) not in (1, 2):
		usage()

	passphrase = argv[0]
	if len(argv) == 1:
		timeout = 1800
	else:
		timeout = int(argv[1])

	return passphrase, timeout

def handle_req(passphrase):
	req = input().split(maxsplit=2)
	if len(req) != 3:
		print('bad # of connection args')
		exit(3)
	host, port, pw = req

	if pw != passphrase:
		print('bad passphrase')
		print(f'bad passphrase trying to connect to {host}:{port}', file=stderr)
		exit(4)

	try:
		port = int(port)
	except:
		print('bad port')
		exit(3)

	return host, port

def shutdown():
	if sok is not None:
		try:
			sok.sendall(b'QUIT\n')
			sok.shutdown(socket.SHUT_RDWR)
		except:
			pass

def onalarm(sig, stk):
	try:
		print('timeout!')
		stdout.flush()
	except:
		pass
	try:
		print('timeout!', file=stderr)
		stderr.flush()
	except:
		pass

	shutdown()
	exit(2)

signal(SIGALRM, onalarm)

passphrase, timeout = handle_args()
alarm(timeout)
host, port = handle_req(passphrase)

try:
	sok = socket.create_connection((host, port))
except Exception as e:
	print(f'connection failed: {e}')
	exit(5)

def toserver():
	while (s := stdin.readline()) != '':
		if s == 'QUIT\n':
			break
		sok.sendall(s.encode())
	shutdown()
	exit(0)

def toclient():
	fp = sok.makefile('r', encoding='ascii', errors='ignore')
	while (s := fp.readline()) != '':
		stdout.write(s)
		stdout.flush()
	shutdown()
	exit(0)

t = threading.Thread(target=toclient)
t.start()
toserver()