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
|
#!/usr/bin/env python
# ~/clickclack.py -s -r <(echo 'CAPAB START 1206\r\nSERVER test.1459.io dummy 1S2 :moo.\r\nBURST %s\r\nENDBURST\r\n' socat stdio openssl:127.0.0.1:6005,cert=1S1.cert,key=1S1.key,snihost=chaos.1459.io,commonname=chaos.1459.io
CLIENT_MODE = True
DEBUG = False
CONN_SEND = b''
import select, subprocess, sys, os, tty, termios, time
def parse_irc_line(line):
source = b''
cmd = b''
_trailing = None
args = []
if line[0:1] == b':':
source_pieces = line.split(None, 1)
source = source_pieces[0][1:]
line = source_pieces[1]
if b' :' in line:
trailing_pieces = line.split(b' :', 1)
_trailing = trailing_pieces[1]
line = trailing_pieces[0]
cmd, *args = line.split()
if _trailing is not None:
args.append(_trailing)
return (source, cmd, args)
def format_irc_args(args):
if b' ' in args[-1]:
args[-1] = b':' + args[-1]
return b' '.join(args)
if __name__ == '__main__':
argv = sys.argv[1:]
while len(argv) and len(argv[0]) and argv[0][0] == '-':
opt = argv[0][1:]
del argv[0]
if opt == 's':
CLIENT_MODE = False
elif opt == 'r':
CONN_SEND = argv[0]
del argv[0]
elif opt == '-':
break
else: #h
print(f'Usage: {sys.argv[0]} [-h|-s|-r "send on connect file"|--] [socat command...]', file=sys.stderr)
sys.exit()
proc = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
conn_send_cmds = open(CONN_SEND, 'rb').read()
conn_send_cmds = conn_send_cmds.replace(b'%s', bytes(str(time.time()).encode('ascii')))
proc.stdin.write(conn_send_cmds)
proc.stdin.flush()
os.set_blocking(proc.stdout.fileno(), False)
os.set_blocking(proc.stderr.fileno(), False)
child_buffer = bytearray()
while True:
if DEBUG: print('selecting')
rd = select.select([proc.stdout, proc.stderr, sys.stdin.buffer], [], [])[0]
for f in rd:
if DEBUG: print(f'reading {f!r}')
if f is proc.stdout:
if DEBUG: print(f'writing to stdout')
child_buffer += f.read()
child_buffer.replace(b'\r',b'')
if b'\n' in child_buffer:
lines = child_buffer.split(b'\n')
for line in lines[:-1]:
if line == b'': continue
source, cmd, args = parse_irc_line(line)
sys.stdout.buffer.write(line+b'\r\n')
sys.stdout.buffer.flush()
if cmd == b'PING':
if CLIENT_MODE:
pong = b'PONG %s\r\n' % (format_irc_args(args))
else:
pong = b'PONG %s\r\n' % (source)
sys.stdout.buffer.write(pong)
sys.stdout.buffer.flush()
proc.stdin.write(pong)
proc.stdin.flush()
child_buffer = lines[-1]
if f is proc.stderr:
if DEBUG: print(f'writing to stderr')
sys.stderr.buffer.write(f.read())
sys.stderr.buffer.flush()
if f is sys.stdin.buffer:
if DEBUG: print(f'writing to child')
proc.stdin.write(f.readline())
proc.stdin.flush()
|