| 0. 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. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. | #!/usr/bin/env python # [email protected] # python license import select, socket, sys, threading class Observer: """base class for views in the Observer Pattern""" def update(self, subject, *args, **kwargs): """Implement this method in a concrete observer.""" raise "not implemented" class Subject: """base class for a model in the Observer Pattern.""" def __init__(self): """don't forget to call this in derrived classes. it initalizes the list of observers""" self.observerList = [] def attach(self, observer): """attach an observer to this model.""" self.observerList.append(observer) def detach(self, observer): """detach an observer from this model.""" self.observerList.remove(observer) def notify(self, *args, **kwargs): """for use by the model. this method is called to notify observers about changes in the model.""" for observer in self.observerList: observer.update(self, *args, **kwargs) class DirectForwarder(Subject, threading.Thread): def __init__(self, localhp, targethp): Subject.__init__(self) threading.Thread.__init__(self) self.localhp = localhp self.targethp = targethp self.verbose = 0 self.active = 1 self.setName('%d->%s:%d' % (localhp[1], targethp[0], targethp[1])) self.setDaemon(1) def run(self, forever = 1): sserver = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sserver.bind(self.localhp) sserver.listen(1) while forever and self.active: self.notify('listening on %s:%d' % self.localhp) while self.active: ready, _, _= select.select([sserver],[],[sserver], 3) # with timeout if ready: break else: self.notify('deactivated') break self.slocal, addr = sserver.accept() self.notify('Connected by %s:%d' % addr) #connecting to target self.notify('Connecting to %s:%d' % self.targethp) self.starget = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.starget.connect(self.targethp) self.notify('Connection open') self.slocal.setblocking(0) self.starget.setblocking(0) try: alive = 1 while alive: ready_to_read, ready_to_write, in_error = \ select.select( [self.slocal, self.starget], #potential_readers [], #potential_writers [self.slocal, self.starget], #potential_errs 3) #timeout for s in ready_to_read: if s is self.slocal: r = self.slocal.recv(8192) if r: self.starget.send(r) if self.verbose: self.notify('->t %d' % len(r)) else: alive = 0 elif s is self.starget: r = self.starget.recv(8192) if r: self.slocal.send(r) if self.verbose: self.notify('<-t %d' % len(r)) else: alive = 0 if in_error: alive = 0 except socket.error, msg: print msg self.notify("closing connections...") #switch off blocking to force threads to exit #t.setblocking(0); #conn.setblocking(0); self.slocal.close() self.starget.close() self.notify("Shutdown...") self.active = 0 def stop(self): if self.active: self.active = 0 self.join() def stat(self): return ('STOPPED','SERVICE')[self.active!=0] if __name__ == '__main__': import os if len(sys.argv) != 3: print "USAGE: %s username host " % sys.argv[0] sys.exit(1); username, host = sys.argv[1:3] class MSG(Observer): def update(self, model, arg): print arg f = DirectForwarder(('127.0.0.2', 139), ('127.0.0.1', 1390)) f.attach(MSG()) f.start() os.system('ssh -c blowfish -L 1390:%s:139 %s@%s' % (host, username, host)) f.stop() |