From fc45d0b642b482f47638ca9b0f8fe69c8c9006b3 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 13 Sep 2014 21:43:58 -0400 Subject: initial very rough sketch --- server.py | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 server.py (limited to 'server.py') diff --git a/server.py b/server.py new file mode 100644 index 0000000..f09e2b0 --- /dev/null +++ b/server.py @@ -0,0 +1,137 @@ +import paramiko +import re +import socket +import time +import threading +import vt100 + +class Connection(object): + def __init__(self): + self.buf = b'' + self.vt = vt100.vt100() + + def process(self, data): + self.buf += data + self.vt.process(data) + + def get_term(self): + term = '' + for i in range(0, 24): + for j in range(0, 80): + term += self.vt.cell(i, j).contents.contents() + term += "\n" + + return term[:-1] + +class SSHServer(paramiko.ServerInterface): + def check_channel_request(self, kind, chanid): + return paramiko.OPEN_SUCCEEDED + + def check_channel_pty_request(self, channel, term, width, height, pixelwidth, pixelheight, modes): + return True + + def check_channel_shell_request(self, channel): + return True + + def check_auth_password(self, username, password): + if password == "blah": + return paramiko.AUTH_SUCCESSFUL + return paramiko.AUTH_FAILED + + def get_allowed_auths(self, username): + return "password" + +class TermcastServer(object): + def __init__(self): + self.sessions = {} + + def listen(self): + ssh_sock = self._open_socket(2200) + tc_sock = self._open_socket(2201) + + threading.Thread( + target=lambda: self.wait_for_ssh_connection(ssh_sock) + ).start() + threading.Thread( + target=lambda: self.wait_for_tc_connection(tc_sock) + ).start() + + def wait_for_ssh_connection(self, sock): + self._wait_for_connection( + sock, + lambda client: self.handle_ssh_connection(client) + ) + + def wait_for_tc_connection(self, sock): + self._wait_for_connection( + sock, + lambda client: self.handle_tc_connection(client) + ) + + def handle_ssh_connection(self, client): + t = paramiko.Transport(client) + t.add_server_key(paramiko.RSAKey(filename='test_rsa.key')) + t.start_server(server=SSHServer()) + chan = t.accept(None) + + if b'doy' in self.sessions: + chan.send(self.sessions[b'doy'].get_term()) + else: + chan.send("no data for doy\r\n") + + time.sleep(5) + chan.close() + + def handle_tc_connection(self, client): + buf = b'' + while len(buf) < 1024 and b"\n" not in buf: + buf += client.recv(1024) + + pos = buf.find(b"\n") + if pos == -1: + print("no authentication found") + return + + auth = buf[:pos] + buf = buf[pos+1:] + + auth_re = re.compile(b'^hello ([^ ]+) ([^ ]+)$') + m = auth_re.match(auth) + if m is None: + print("no authentication found (%s)" % auth) + return + + print(b"got auth: " + auth) + conn = Connection() + self.sessions[m.group(1)] = conn + client.send(b"hello, " + m.group(1) + b"\n") + + conn.process(buf) + while True: + buf = client.recv(1024) + if len(buf) > 0: + conn.process(buf) + else: + return + + def _wait_for_connection(self, sock, cb): + while True: + try: + sock.listen(100) + client, addr = sock.accept() + except Exception as e: + print('*** Listen/accept failed: ' + str(e)) + traceback.print_exc() + continue + + threading.Thread(target=cb, args=(client,)).start() + + def _open_socket(self, port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind(('', port)) + return sock + +if __name__ == '__main__': + server = TermcastServer() + server.listen() -- cgit v1.2.3-54-g00ecf