monitor_client.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. # -*- Mode: Python -*-
  2. # monitor client, unix version.
  3. import supervisor.medusa.asyncore_25 as asyncore
  4. import supervisor.medusa.asynchat_25 as asynchat
  5. import supervisor.medusa.text_socket as socket
  6. import sys
  7. import os
  8. from supervisor.compat import md5
  9. from supervisor.compat import print_function
  10. from supervisor.compat import raw_input
  11. class stdin_channel (asyncore.file_dispatcher):
  12. def handle_read (self):
  13. data = self.recv(512)
  14. if not data:
  15. print_function('\nclosed.')
  16. self.sock_channel.close()
  17. try:
  18. self.close()
  19. except:
  20. pass
  21. data = data.replace('\n', '\r\n')
  22. self.sock_channel.push (data)
  23. def writable (self):
  24. return 0
  25. def log (self, *ignore):
  26. pass
  27. class monitor_client (asynchat.async_chat):
  28. def __init__ (self, password, addr=('',8023), socket_type=socket.AF_INET):
  29. asynchat.async_chat.__init__ (self)
  30. self.create_socket (socket_type, socket.SOCK_STREAM)
  31. self.terminator = '\r\n'
  32. self.connect (addr)
  33. self.sent_auth = 0
  34. self.timestamp = ''
  35. self.password = password
  36. def collect_incoming_data (self, data):
  37. if not self.sent_auth:
  38. self.timestamp = self.timestamp + data
  39. else:
  40. sys.stdout.write (data)
  41. sys.stdout.flush()
  42. def found_terminator (self):
  43. if not self.sent_auth:
  44. self.push (hex_digest (self.timestamp + self.password) + '\r\n')
  45. self.sent_auth = 1
  46. else:
  47. print_function()
  48. def handle_close (self):
  49. # close all the channels, which will make the standard main
  50. # loop exit.
  51. for c in asyncore.socket_map.values():
  52. c.close()
  53. def log (self, *ignore):
  54. pass
  55. class encrypted_monitor_client (monitor_client):
  56. """Wrap push() and recv() with a stream cipher"""
  57. def init_cipher (self, cipher, key):
  58. self.outgoing = cipher.new (key)
  59. self.incoming = cipher.new (key)
  60. def push (self, data):
  61. # push the encrypted data instead
  62. return monitor_client.push (self, self.outgoing.encrypt (data))
  63. def recv (self, block_size):
  64. data = monitor_client.recv (self, block_size)
  65. if data:
  66. return self.incoming.decrypt (data)
  67. else:
  68. return data
  69. def hex_digest (s):
  70. m = md5.md5()
  71. m.update(s)
  72. return ''.join([hex (ord (x))[2:] for x in m.digest()])
  73. if __name__ == '__main__':
  74. if len(sys.argv) == 1:
  75. print_function('Usage: %s host port' % sys.argv[0])
  76. sys.exit(0)
  77. if '-e' in sys.argv:
  78. encrypt = 1
  79. sys.argv.remove ('-e')
  80. else:
  81. encrypt = 0
  82. sys.stderr.write ('Enter Password: ')
  83. sys.stderr.flush()
  84. try:
  85. os.system ('stty -echo')
  86. p = raw_input()
  87. print_function()
  88. finally:
  89. os.system ('stty echo')
  90. stdin = stdin_channel (0)
  91. if len(sys.argv) > 1:
  92. if encrypt:
  93. client = encrypted_monitor_client(p, (sys.argv[1], int(sys.argv[2])))
  94. import sapphire
  95. client.init_cipher (sapphire, p)
  96. else:
  97. client = monitor_client (p, (sys.argv[1], int(sys.argv[2])))
  98. else:
  99. # default to local host, 'standard' port
  100. client = monitor_client (p)
  101. stdin.sock_channel = client
  102. asyncore.loop()