1# Copyright (c) Twisted Matrix Laboratories. 2# See LICENSE for details. 3 4# You can run this .tac file directly with: 5# twistd -ny demo_draw.tac 6# 7# Re-using a private key is dangerous, generate one. 8# 9# For this example you can use: 10# 11# $ ckeygen -t rsa -f ssh-keys/ssh_host_rsa_key 12 13""" 14A trivial drawing application. 15 16Clients are allowed to connect and spew various characters out over 17the terminal. Spacebar changes the drawing character, while the arrow 18keys move the cursor. 19""" 20 21from twisted.application import internet, service 22from twisted.conch.insults import insults 23from twisted.conch.manhole_ssh import ConchFactory, TerminalRealm 24from twisted.conch.ssh import keys 25from twisted.conch.telnet import TelnetBootstrapProtocol, TelnetTransport 26from twisted.cred import checkers, portal 27from twisted.internet import protocol 28 29 30class Draw(insults.TerminalProtocol): 31 """Protocol which accepts arrow key and spacebar input and places 32 the requested characters onto the terminal. 33 """ 34 35 cursors = list("!@#$%^&*()_+-=") 36 37 def connectionMade(self): 38 self.terminal.eraseDisplay() 39 self.terminal.resetModes([insults.modes.IRM]) 40 self.cursor = self.cursors[0] 41 42 def keystrokeReceived(self, keyID, modifier): 43 if keyID == self.terminal.UP_ARROW: 44 self.terminal.cursorUp() 45 elif keyID == self.terminal.DOWN_ARROW: 46 self.terminal.cursorDown() 47 elif keyID == self.terminal.LEFT_ARROW: 48 self.terminal.cursorBackward() 49 elif keyID == self.terminal.RIGHT_ARROW: 50 self.terminal.cursorForward() 51 elif keyID == " ": 52 self.cursor = self.cursors[ 53 (self.cursors.index(self.cursor) + 1) % len(self.cursors) 54 ] 55 else: 56 return 57 self.terminal.write(self.cursor) 58 self.terminal.cursorBackward() 59 60 61def makeService(args): 62 checker = checkers.InMemoryUsernamePasswordDatabaseDontUse(username=b"password") 63 64 f = protocol.ServerFactory() 65 f.protocol = lambda: TelnetTransport( 66 TelnetBootstrapProtocol, 67 insults.ServerProtocol, 68 args["protocolFactory"], 69 *args.get("protocolArgs", ()), 70 **args.get("protocolKwArgs", {}), 71 ) 72 tsvc = internet.TCPServer(args["telnet"], f) 73 74 def chainProtocolFactory(): 75 return insults.ServerProtocol( 76 args["protocolFactory"], 77 *args.get("protocolArgs", ()), 78 **args.get("protocolKwArgs", {}), 79 ) 80 81 rlm = TerminalRealm() 82 rlm.chainedProtocolFactory = chainProtocolFactory 83 ptl = portal.Portal(rlm, [checker]) 84 f = ConchFactory(ptl) 85 f.publicKeys[b"ssh-rsa"] = keys.Key.fromFile("ssh-keys/ssh_host_rsa_key.pub") 86 f.privateKeys[b"ssh-rsa"] = keys.Key.fromFile("ssh-keys/ssh_host_rsa_key") 87 csvc = internet.TCPServer(args["ssh"], f) 88 89 m = service.MultiService() 90 tsvc.setServiceParent(m) 91 csvc.setServiceParent(m) 92 return m 93 94 95application = service.Application("Insults Demo App") 96makeService({"protocolFactory": Draw, "telnet": 6023, "ssh": 6022}).setServiceParent( 97 application 98) 99