tcp-proxy.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/env python3
  2. import sys
  3. from twisted.internet import defer
  4. from twisted.internet import protocol
  5. from twisted.internet import reactor
  6. from twisted.python import log
  7. HOST = '127.0.0.1'
  8. PORT = 2002
  9. LISTEN_PORT = 9999
  10. LISTEN_ON = '127.0.0.1'
  11. class ProxyClientProtocol(protocol.Protocol):
  12. def connectionMade(self):
  13. log.msg("Client: connected to peer")
  14. self.cli_queue = self.factory.cli_queue
  15. self.cli_queue.get().addCallback(self.serverDataReceived)
  16. def serverDataReceived(self, chunk):
  17. # rlogin looks like this: \x00 password \x00 username \x00 terminal/speed \x00
  18. # b'\x00up2lat3\x00bugz\x00ansi-bbs/115200\x00'
  19. # We're looking for 4 \x00!
  20. # TODO: Line processing, and line cleaning (remove ANSI color codes)
  21. if chunk is False:
  22. self.cli_queue = None
  23. log.msg("Client: disconnecting from peer")
  24. self.factory.continueTrying = False
  25. self.transport.loseConnection()
  26. elif b'\x00' in chunk:
  27. # Hint: User rlogin reversed in syncterm
  28. log.msg("Maybe RLOGIN?")
  29. parts = chunk.split(b'\x00')
  30. user = parts[1].decode('utf-8')
  31. log.msg("GREETINGS {0}!".format(user))
  32. # b'\x00up2lat3\x00bugz\x00ansi-bbs/115200\x00'
  33. self.transport.write(chunk)
  34. self.cli_queue.get().addCallback(self.serverDataReceived)
  35. elif b"$" == chunk:
  36. self.factory.svr_queue.put(b"HELLO.\r\n")
  37. self.cli_queue.get().addCallback(self.serverDataReceived)
  38. elif self.cli_queue:
  39. log.msg("Client: writing %d bytes to peer" % len(chunk))
  40. log.msg(">>", repr(chunk))
  41. self.transport.write(chunk)
  42. self.cli_queue.get().addCallback(self.serverDataReceived)
  43. else:
  44. self.factory.cli_queue.put(chunk)
  45. def dataReceived(self, chunk):
  46. log.msg("Client: %d bytes received from peer" % len(chunk))
  47. log.msg("<<", repr(chunk))
  48. self.factory.svr_queue.put(chunk)
  49. def connectionLost(self, why):
  50. log.msg("connectionLost because: %s" % why)
  51. # if self.cli_queue:
  52. # self.cli_queue = None
  53. # log.msg("Client: peer disconnect unexpectedly")
  54. self.factory.svr_queue.put(False)
  55. self.cli_queue = None
  56. self.transport.loseConnection()
  57. # class ProxyClientFactory(protocol.ReconnectingClientFactory):
  58. class ProxyClientFactory(protocol.ClientFactory):
  59. maxDelay = 10
  60. # continueTrying = True
  61. # continueTrying = False
  62. protocol = ProxyClientProtocol
  63. def __init__(self, svr_queue, cli_queue):
  64. self.svr_queue = svr_queue
  65. self.cli_queue = cli_queue
  66. class ProxyServer(protocol.Protocol):
  67. def connectionMade(self):
  68. self.svr_queue = defer.DeferredQueue()
  69. self.cli_queue = defer.DeferredQueue()
  70. self.svr_queue.get().addCallback(self.clientDataReceived)
  71. factory = ProxyClientFactory(self.svr_queue, self.cli_queue)
  72. reactor.connectTCP(HOST, PORT, factory)
  73. def clientDataReceived(self, chunk):
  74. if chunk is False:
  75. self.transport.loseConnection()
  76. else:
  77. log.msg("Server: writing %d bytes to original client" % len(chunk))
  78. self.transport.write(chunk)
  79. self.svr_queue.get().addCallback(self.clientDataReceived)
  80. def dataReceived(self, chunk):
  81. log.msg("Server: %d bytes received" % len(chunk))
  82. self.cli_queue.put(chunk)
  83. def connectionLost(self, why):
  84. log.msg("lost connection %s" % why)
  85. self.cli_queue.put(False)
  86. if __name__ == "__main__":
  87. log.startLogging(sys.stdout)
  88. factory = protocol.Factory()
  89. factory.protocol = ProxyServer
  90. reactor.listenTCP(LISTEN_PORT, factory, interface=LISTEN_ON)
  91. reactor.run()