Commit 416c8faf authored by Ken Manheimer's avatar Ken Manheimer

Added back a print so the client user sees the result of their commands.

Changed all tabs to spaces.
parent 0516b906
# -*- Mode: Python; tab-width: 4 -*- # -*- Mode: Python; tab-width: 4 -*-
# Author: Sam Rushing <rushing@nightmare.com> # Author: Sam Rushing <rushing@nightmare.com>
# #
# python REPL channel. # python REPL channel.
# #
RCS_ID = '$Id: monitor.py,v 1.3 1999/07/20 16:53:50 amos Exp $' RCS_ID = '$Id: monitor.py,v 1.4 1999/07/21 16:50:57 klm Exp $'
import md5 import md5
import socket import socket
...@@ -22,326 +22,327 @@ from counter import counter ...@@ -22,326 +22,327 @@ from counter import counter
import producers import producers
class monitor_channel (asynchat.async_chat): class monitor_channel (asynchat.async_chat):
try_linemode = 1 try_linemode = 1
def __init__ (self, server, sock, addr): def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock) asynchat.async_chat.__init__ (self, sock)
self.server = server self.server = server
self.addr = addr self.addr = addr
self.set_terminator ('\r\n') self.set_terminator ('\r\n')
self.data = '' self.data = ''
# local bindings specific to this channel # local bindings specific to this channel
self.local_env = {} self.local_env = {}
self.push ('Python ' + sys.version + '\r\n') self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n') self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self) self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n") self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt() self.prompt()
self.number = server.total_sessions.as_long() self.number = server.total_sessions.as_long()
self.line_counter = counter() self.line_counter = counter()
self.multi_line = [] self.multi_line = []
def handle_connect (self): def handle_connect (self):
# send IAC DO LINEMODE # send IAC DO LINEMODE
self.push ('\377\375\"') self.push ('\377\375\"')
def close (self): def close (self):
self.server.closed_sessions.increment() self.server.closed_sessions.increment()
asynchat.async_chat.close(self) asynchat.async_chat.close(self)
def prompt (self): def prompt (self):
self.push ('>>> ') self.push ('>>> ')
def collect_incoming_data (self, data): def collect_incoming_data (self, data):
self.data = self.data + data self.data = self.data + data
if len(self.data) > 1024: if len(self.data) > 1024:
# denial of service. # denial of service.
self.push ('BCNU\r\n') self.push ('BCNU\r\n')
self.close_when_done() self.close_when_done()
def found_terminator (self): def found_terminator (self):
line = self.clean_line (self.data) line = self.clean_line (self.data)
self.data = '' self.data = ''
self.line_counter.increment() self.line_counter.increment()
# check for special case inputs... # check for special case inputs...
if not line and not self.multi_line: if not line and not self.multi_line:
self.prompt() self.prompt()
return return
if line in ['\004', 'exit']: if line in ['\004', 'exit']:
self.push ('BCNU\r\n') self.push ('BCNU\r\n')
self.close_when_done() self.close_when_done()
return return
oldout = sys.stdout oldout = sys.stdout
olderr = sys.stderr olderr = sys.stderr
try: try:
p = output_producer(self, olderr) p = output_producer(self, olderr)
sys.stdout = p sys.stdout = p
sys.stderr = p sys.stderr = p
try: try:
# this is, of course, a blocking operation. # this is, of course, a blocking operation.
# if you wanted to thread this, you would have # if you wanted to thread this, you would have
# to synchronize, etc... and treat the output # to synchronize, etc... and treat the output
# like a pipe. Not Fun. # like a pipe. Not Fun.
# #
# try eval first. If that fails, try exec. If that fails, # try eval first. If that fails, try exec. If that fails,
# hurl. # hurl.
try: try:
if self.multi_line: if self.multi_line:
# oh, this is horrible... # oh, this is horrible...
raise SyntaxError raise SyntaxError
co = compile (line, repr(self), 'eval') co = compile (line, repr(self), 'eval')
result = eval (co, self.local_env) result = eval (co, self.local_env)
method = 'eval' method = 'eval'
if result is not None: if result is not None:
self.log_info(repr(result)) self.log_info(repr(result))
self.local_env['_'] = result print repr(result)
except SyntaxError: self.local_env['_'] = result
try: except SyntaxError:
if self.multi_line: try:
if line and line[0] in [' ','\t']: if self.multi_line:
self.multi_line.append (line) if line and line[0] in [' ','\t']:
self.push ('... ') self.multi_line.append (line)
return self.push ('... ')
else: return
self.multi_line.append (line) else:
line = string.join (self.multi_line, '\n') self.multi_line.append (line)
co = compile (line, repr(self), 'exec') line = string.join (self.multi_line, '\n')
self.multi_line = [] co = compile (line, repr(self), 'exec')
else: self.multi_line = []
co = compile (line, repr(self), 'exec') else:
except SyntaxError, why: co = compile (line, repr(self), 'exec')
if why[0] == 'unexpected EOF while parsing': except SyntaxError, why:
self.push ('... ') if why[0] == 'unexpected EOF while parsing':
self.multi_line.append (line) self.push ('... ')
return self.multi_line.append (line)
exec co in self.local_env return
method = 'exec' exec co in self.local_env
except: method = 'exec'
method = 'exception' except:
self.multi_line = [] method = 'exception'
(file, fun, line), t, v, tbinfo = asyncore.compact_traceback() self.multi_line = []
self.log_info('%s %s %s' %(t, v, tbinfo), 'warning') (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
finally: self.log_info('%s %s %s' %(t, v, tbinfo), 'warning')
sys.stdout = oldout finally:
sys.stderr = olderr sys.stdout = oldout
self.log_info('%s:%s (%s)> %s' % ( sys.stderr = olderr
self.number, self.log_info('%s:%s (%s)> %s' % (
self.line_counter, self.number,
method, self.line_counter,
repr(line)) method,
) repr(line))
self.push_with_producer (p) )
self.prompt() self.push_with_producer (p)
self.prompt()
# for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves. # for now, we ignore any telnet option stuff sent to
# gee, it would be fun to write a full-blown line-editing # us, and we process the backspace key ourselves.
# environment, etc... # gee, it would be fun to write a full-blown line-editing
def clean_line (self, line): # environment, etc...
chars = [] def clean_line (self, line):
for ch in line: chars = []
oc = ord(ch) for ch in line:
if oc < 127: oc = ord(ch)
if oc in [8,177]: if oc < 127:
# backspace if oc in [8,177]:
chars = chars[:-1] # backspace
else: chars = chars[:-1]
chars.append (ch) else:
return string.join (chars, '') chars.append (ch)
return string.join (chars, '')
class monitor_server (asyncore.dispatcher): class monitor_server (asyncore.dispatcher):
SERVER_IDENT = 'Monitor Server (V%s)' % VERSION SERVER_IDENT = 'Monitor Server (V%s)' % VERSION
channel_class = monitor_channel channel_class = monitor_channel
def __init__ (self, hostname='127.0.0.1', port=8023): def __init__ (self, hostname='127.0.0.1', port=8023):
self.hostname = hostname self.hostname = hostname
self.port = port self.port = port
self.create_socket (socket.AF_INET, socket.SOCK_STREAM) self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr() self.set_reuse_addr()
self.bind ((hostname, port)) self.bind ((hostname, port))
self.log_info('%s started on port %d' % (self.SERVER_IDENT, port)) self.log_info('%s started on port %d' % (self.SERVER_IDENT, port))
self.listen (5) self.listen (5)
self.closed = 0 self.closed = 0
self.failed_auths = 0 self.failed_auths = 0
self.total_sessions = counter() self.total_sessions = counter()
self.closed_sessions = counter() self.closed_sessions = counter()
def writable (self): def writable (self):
return 0 return 0
def handle_accept (self): def handle_accept (self):
conn, addr = self.accept() conn, addr = self.accept()
self.log_info('Incoming monitor connection from %s:%d' % addr) self.log_info('Incoming monitor connection from %s:%d' % addr)
self.channel_class (self, conn, addr) self.channel_class (self, conn, addr)
self.total_sessions.increment() self.total_sessions.increment()
def status (self): def status (self):
return producers.simple_producer ( return producers.simple_producer (
'<h2>%s</h2>' % self.SERVER_IDENT '<h2>%s</h2>' % self.SERVER_IDENT
+ '<br><b>Total Sessions:</b> %s' % self.total_sessions + '<br><b>Total Sessions:</b> %s' % self.total_sessions
+ '<br><b>Current Sessions:</b> %d' % ( + '<br><b>Current Sessions:</b> %d' % (
self.total_sessions.as_long()-self.closed_sessions.as_long() self.total_sessions.as_long()-self.closed_sessions.as_long()
) )
) )
def hex_digest (s): def hex_digest (s):
m = md5.md5() m = md5.md5()
m.update (s) m.update (s)
return string.joinfields ( return string.joinfields (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())), map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'', '',
) )
class secure_monitor_channel (monitor_channel): class secure_monitor_channel (monitor_channel):
authorized = 0 authorized = 0
def __init__ (self, server, sock, addr): def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock) asynchat.async_chat.__init__ (self, sock)
self.server = server self.server = server
self.addr = addr self.addr = addr
self.set_terminator ('\r\n') self.set_terminator ('\r\n')
self.data = '' self.data = ''
# local bindings specific to this channel # local bindings specific to this channel
self.local_env = {} self.local_env = {}
# send timestamp string # send timestamp string
self.timestamp = str(time.time()) self.timestamp = str(time.time())
self.count = 0 self.count = 0
self.line_counter = counter() self.line_counter = counter()
self.number = int(server.total_sessions.as_long()) self.number = int(server.total_sessions.as_long())
self.multi_line = [] self.multi_line = []
self.push (self.timestamp + '\r\n') self.push (self.timestamp + '\r\n')
def found_terminator (self): def found_terminator (self):
if not self.authorized: if not self.authorized:
if hex_digest ('%s%s' % (self.timestamp, self.server.password)) != self.data: if hex_digest ('%s%s' % (self.timestamp, self.server.password)) != self.data:
self.log_info ('%s: failed authorization' % self, 'warning') self.log_info ('%s: failed authorization' % self, 'warning')
self.server.failed_auths = self.server.failed_auths + 1 self.server.failed_auths = self.server.failed_auths + 1
self.close() self.close()
else: else:
self.authorized = 1 self.authorized = 1
self.push ('Python ' + sys.version + '\r\n') self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n') self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self) self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n") self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt() self.prompt()
self.data = '' self.data = ''
else: else:
monitor_channel.found_terminator (self) monitor_channel.found_terminator (self)
class secure_encrypted_monitor_channel (secure_monitor_channel): class secure_encrypted_monitor_channel (secure_monitor_channel):
"Wrap send() and recv() with a stream cipher" "Wrap send() and recv() with a stream cipher"
def __init__ (self, server, conn, addr): def __init__ (self, server, conn, addr):
key = server.password key = server.password
self.outgoing = server.cipher.new (key) self.outgoing = server.cipher.new (key)
self.incoming = server.cipher.new (key) self.incoming = server.cipher.new (key)
secure_monitor_channel.__init__ (self, server, conn, addr) secure_monitor_channel.__init__ (self, server, conn, addr)
def send (self, data): def send (self, data):
# send the encrypted data instead # send the encrypted data instead
ed = self.outgoing.encrypt (data) ed = self.outgoing.encrypt (data)
return secure_monitor_channel.send (self, ed) return secure_monitor_channel.send (self, ed)
def recv (self, block_size): def recv (self, block_size):
data = secure_monitor_channel.recv (self, block_size) data = secure_monitor_channel.recv (self, block_size)
if data: if data:
dd = self.incoming.decrypt (data) dd = self.incoming.decrypt (data)
return dd return dd
else: else:
return data return data
class secure_monitor_server (monitor_server): class secure_monitor_server (monitor_server):
channel_class = secure_monitor_channel channel_class = secure_monitor_channel
def __init__ (self, password, hostname='', port=8023): def __init__ (self, password, hostname='', port=8023):
monitor_server.__init__ (self, hostname, port) monitor_server.__init__ (self, hostname, port)
self.password = password self.password = password
def status (self): def status (self):
p = monitor_server.status (self) p = monitor_server.status (self)
# kludge # kludge
p.data = p.data + ('<br><b>Failed Authorizations:</b> %d' % self.failed_auths) p.data = p.data + ('<br><b>Failed Authorizations:</b> %d' % self.failed_auths)
return p return p
# don't try to print from within any of the methods # don't try to print from within any of the methods
# of this object. 8^) # of this object. 8^)
class output_producer: class output_producer:
def __init__ (self, channel, real_stderr): def __init__ (self, channel, real_stderr):
self.channel = channel self.channel = channel
self.data = '' self.data = ''
# use _this_ for debug output # use _this_ for debug output
self.stderr = real_stderr self.stderr = real_stderr
def check_data (self): def check_data (self):
if len(self.data) > 1<<16: if len(self.data) > 1<<16:
# runaway output, close it. # runaway output, close it.
self.channel.close() self.channel.close()
def write (self, data): def write (self, data):
lines = string.splitfields (data, '\n') lines = string.splitfields (data, '\n')
data = string.join (lines, '\r\n') data = string.join (lines, '\r\n')
self.data = self.data + data self.data = self.data + data
self.check_data() self.check_data()
def writeline (self, line): def writeline (self, line):
self.data = self.data + line + '\r\n' self.data = self.data + line + '\r\n'
self.check_data() self.check_data()
def writelines (self, lines): def writelines (self, lines):
self.data = self.data + string.joinfields ( self.data = self.data + string.joinfields (
lines, lines,
'\r\n' '\r\n'
) + '\r\n' ) + '\r\n'
self.check_data() self.check_data()
def ready (self): def ready (self):
return (len (self.data) > 0) return (len (self.data) > 0)
def flush (self): def flush (self):
pass pass
def softspace (self, *args): def softspace (self, *args):
pass pass
def more (self): def more (self):
if self.data: if self.data:
result = self.data[:512] result = self.data[:512]
self.data = self.data[512:] self.data = self.data[512:]
return result return result
else: else:
return '' return ''
if __name__ == '__main__': if __name__ == '__main__':
import string import string
import sys import sys
if '-s' in sys.argv: if '-s' in sys.argv:
sys.argv.remove ('-s') sys.argv.remove ('-s')
print 'Enter password: ', print 'Enter password: ',
password = raw_input() password = raw_input()
else: else:
password = None password = None
if '-e' in sys.argv: if '-e' in sys.argv:
sys.argv.remove ('-e') sys.argv.remove ('-e')
encrypt = 1 encrypt = 1
else: else:
encrypt = 0 encrypt = 0
print sys.argv print sys.argv
if len(sys.argv) > 1: if len(sys.argv) > 1:
port = string.atoi (sys.argv[1]) port = string.atoi (sys.argv[1])
else: else:
port = 8023 port = 8023
if password is not None: if password is not None:
s = secure_monitor_server (password, '', port) s = secure_monitor_server (password, '', port)
if encrypt: if encrypt:
s.channel_class = secure_encrypted_monitor_channel s.channel_class = secure_encrypted_monitor_channel
import sapphire import sapphire
s.cipher = sapphire s.cipher = sapphire
else: else:
s = monitor_server ('', port) s = monitor_server ('', port)
asyncore.loop() asyncore.loop()
# -*- Mode: Python; tab-width: 4 -*- # -*- Mode: Python; tab-width: 4 -*-
# Author: Sam Rushing <rushing@nightmare.com> # Author: Sam Rushing <rushing@nightmare.com>
# #
# python REPL channel. # python REPL channel.
# #
RCS_ID = '$Id: monitor.py,v 1.3 1999/07/20 16:53:50 amos Exp $' RCS_ID = '$Id: monitor.py,v 1.4 1999/07/21 16:50:57 klm Exp $'
import md5 import md5
import socket import socket
...@@ -22,326 +22,327 @@ from counter import counter ...@@ -22,326 +22,327 @@ from counter import counter
import producers import producers
class monitor_channel (asynchat.async_chat): class monitor_channel (asynchat.async_chat):
try_linemode = 1 try_linemode = 1
def __init__ (self, server, sock, addr): def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock) asynchat.async_chat.__init__ (self, sock)
self.server = server self.server = server
self.addr = addr self.addr = addr
self.set_terminator ('\r\n') self.set_terminator ('\r\n')
self.data = '' self.data = ''
# local bindings specific to this channel # local bindings specific to this channel
self.local_env = {} self.local_env = {}
self.push ('Python ' + sys.version + '\r\n') self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n') self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self) self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n") self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt() self.prompt()
self.number = server.total_sessions.as_long() self.number = server.total_sessions.as_long()
self.line_counter = counter() self.line_counter = counter()
self.multi_line = [] self.multi_line = []
def handle_connect (self): def handle_connect (self):
# send IAC DO LINEMODE # send IAC DO LINEMODE
self.push ('\377\375\"') self.push ('\377\375\"')
def close (self): def close (self):
self.server.closed_sessions.increment() self.server.closed_sessions.increment()
asynchat.async_chat.close(self) asynchat.async_chat.close(self)
def prompt (self): def prompt (self):
self.push ('>>> ') self.push ('>>> ')
def collect_incoming_data (self, data): def collect_incoming_data (self, data):
self.data = self.data + data self.data = self.data + data
if len(self.data) > 1024: if len(self.data) > 1024:
# denial of service. # denial of service.
self.push ('BCNU\r\n') self.push ('BCNU\r\n')
self.close_when_done() self.close_when_done()
def found_terminator (self): def found_terminator (self):
line = self.clean_line (self.data) line = self.clean_line (self.data)
self.data = '' self.data = ''
self.line_counter.increment() self.line_counter.increment()
# check for special case inputs... # check for special case inputs...
if not line and not self.multi_line: if not line and not self.multi_line:
self.prompt() self.prompt()
return return
if line in ['\004', 'exit']: if line in ['\004', 'exit']:
self.push ('BCNU\r\n') self.push ('BCNU\r\n')
self.close_when_done() self.close_when_done()
return return
oldout = sys.stdout oldout = sys.stdout
olderr = sys.stderr olderr = sys.stderr
try: try:
p = output_producer(self, olderr) p = output_producer(self, olderr)
sys.stdout = p sys.stdout = p
sys.stderr = p sys.stderr = p
try: try:
# this is, of course, a blocking operation. # this is, of course, a blocking operation.
# if you wanted to thread this, you would have # if you wanted to thread this, you would have
# to synchronize, etc... and treat the output # to synchronize, etc... and treat the output
# like a pipe. Not Fun. # like a pipe. Not Fun.
# #
# try eval first. If that fails, try exec. If that fails, # try eval first. If that fails, try exec. If that fails,
# hurl. # hurl.
try: try:
if self.multi_line: if self.multi_line:
# oh, this is horrible... # oh, this is horrible...
raise SyntaxError raise SyntaxError
co = compile (line, repr(self), 'eval') co = compile (line, repr(self), 'eval')
result = eval (co, self.local_env) result = eval (co, self.local_env)
method = 'eval' method = 'eval'
if result is not None: if result is not None:
self.log_info(repr(result)) self.log_info(repr(result))
self.local_env['_'] = result print repr(result)
except SyntaxError: self.local_env['_'] = result
try: except SyntaxError:
if self.multi_line: try:
if line and line[0] in [' ','\t']: if self.multi_line:
self.multi_line.append (line) if line and line[0] in [' ','\t']:
self.push ('... ') self.multi_line.append (line)
return self.push ('... ')
else: return
self.multi_line.append (line) else:
line = string.join (self.multi_line, '\n') self.multi_line.append (line)
co = compile (line, repr(self), 'exec') line = string.join (self.multi_line, '\n')
self.multi_line = [] co = compile (line, repr(self), 'exec')
else: self.multi_line = []
co = compile (line, repr(self), 'exec') else:
except SyntaxError, why: co = compile (line, repr(self), 'exec')
if why[0] == 'unexpected EOF while parsing': except SyntaxError, why:
self.push ('... ') if why[0] == 'unexpected EOF while parsing':
self.multi_line.append (line) self.push ('... ')
return self.multi_line.append (line)
exec co in self.local_env return
method = 'exec' exec co in self.local_env
except: method = 'exec'
method = 'exception' except:
self.multi_line = [] method = 'exception'
(file, fun, line), t, v, tbinfo = asyncore.compact_traceback() self.multi_line = []
self.log_info('%s %s %s' %(t, v, tbinfo), 'warning') (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
finally: self.log_info('%s %s %s' %(t, v, tbinfo), 'warning')
sys.stdout = oldout finally:
sys.stderr = olderr sys.stdout = oldout
self.log_info('%s:%s (%s)> %s' % ( sys.stderr = olderr
self.number, self.log_info('%s:%s (%s)> %s' % (
self.line_counter, self.number,
method, self.line_counter,
repr(line)) method,
) repr(line))
self.push_with_producer (p) )
self.prompt() self.push_with_producer (p)
self.prompt()
# for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves. # for now, we ignore any telnet option stuff sent to
# gee, it would be fun to write a full-blown line-editing # us, and we process the backspace key ourselves.
# environment, etc... # gee, it would be fun to write a full-blown line-editing
def clean_line (self, line): # environment, etc...
chars = [] def clean_line (self, line):
for ch in line: chars = []
oc = ord(ch) for ch in line:
if oc < 127: oc = ord(ch)
if oc in [8,177]: if oc < 127:
# backspace if oc in [8,177]:
chars = chars[:-1] # backspace
else: chars = chars[:-1]
chars.append (ch) else:
return string.join (chars, '') chars.append (ch)
return string.join (chars, '')
class monitor_server (asyncore.dispatcher): class monitor_server (asyncore.dispatcher):
SERVER_IDENT = 'Monitor Server (V%s)' % VERSION SERVER_IDENT = 'Monitor Server (V%s)' % VERSION
channel_class = monitor_channel channel_class = monitor_channel
def __init__ (self, hostname='127.0.0.1', port=8023): def __init__ (self, hostname='127.0.0.1', port=8023):
self.hostname = hostname self.hostname = hostname
self.port = port self.port = port
self.create_socket (socket.AF_INET, socket.SOCK_STREAM) self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr() self.set_reuse_addr()
self.bind ((hostname, port)) self.bind ((hostname, port))
self.log_info('%s started on port %d' % (self.SERVER_IDENT, port)) self.log_info('%s started on port %d' % (self.SERVER_IDENT, port))
self.listen (5) self.listen (5)
self.closed = 0 self.closed = 0
self.failed_auths = 0 self.failed_auths = 0
self.total_sessions = counter() self.total_sessions = counter()
self.closed_sessions = counter() self.closed_sessions = counter()
def writable (self): def writable (self):
return 0 return 0
def handle_accept (self): def handle_accept (self):
conn, addr = self.accept() conn, addr = self.accept()
self.log_info('Incoming monitor connection from %s:%d' % addr) self.log_info('Incoming monitor connection from %s:%d' % addr)
self.channel_class (self, conn, addr) self.channel_class (self, conn, addr)
self.total_sessions.increment() self.total_sessions.increment()
def status (self): def status (self):
return producers.simple_producer ( return producers.simple_producer (
'<h2>%s</h2>' % self.SERVER_IDENT '<h2>%s</h2>' % self.SERVER_IDENT
+ '<br><b>Total Sessions:</b> %s' % self.total_sessions + '<br><b>Total Sessions:</b> %s' % self.total_sessions
+ '<br><b>Current Sessions:</b> %d' % ( + '<br><b>Current Sessions:</b> %d' % (
self.total_sessions.as_long()-self.closed_sessions.as_long() self.total_sessions.as_long()-self.closed_sessions.as_long()
) )
) )
def hex_digest (s): def hex_digest (s):
m = md5.md5() m = md5.md5()
m.update (s) m.update (s)
return string.joinfields ( return string.joinfields (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())), map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'', '',
) )
class secure_monitor_channel (monitor_channel): class secure_monitor_channel (monitor_channel):
authorized = 0 authorized = 0
def __init__ (self, server, sock, addr): def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock) asynchat.async_chat.__init__ (self, sock)
self.server = server self.server = server
self.addr = addr self.addr = addr
self.set_terminator ('\r\n') self.set_terminator ('\r\n')
self.data = '' self.data = ''
# local bindings specific to this channel # local bindings specific to this channel
self.local_env = {} self.local_env = {}
# send timestamp string # send timestamp string
self.timestamp = str(time.time()) self.timestamp = str(time.time())
self.count = 0 self.count = 0
self.line_counter = counter() self.line_counter = counter()
self.number = int(server.total_sessions.as_long()) self.number = int(server.total_sessions.as_long())
self.multi_line = [] self.multi_line = []
self.push (self.timestamp + '\r\n') self.push (self.timestamp + '\r\n')
def found_terminator (self): def found_terminator (self):
if not self.authorized: if not self.authorized:
if hex_digest ('%s%s' % (self.timestamp, self.server.password)) != self.data: if hex_digest ('%s%s' % (self.timestamp, self.server.password)) != self.data:
self.log_info ('%s: failed authorization' % self, 'warning') self.log_info ('%s: failed authorization' % self, 'warning')
self.server.failed_auths = self.server.failed_auths + 1 self.server.failed_auths = self.server.failed_auths + 1
self.close() self.close()
else: else:
self.authorized = 1 self.authorized = 1
self.push ('Python ' + sys.version + '\r\n') self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n') self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self) self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n") self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt() self.prompt()
self.data = '' self.data = ''
else: else:
monitor_channel.found_terminator (self) monitor_channel.found_terminator (self)
class secure_encrypted_monitor_channel (secure_monitor_channel): class secure_encrypted_monitor_channel (secure_monitor_channel):
"Wrap send() and recv() with a stream cipher" "Wrap send() and recv() with a stream cipher"
def __init__ (self, server, conn, addr): def __init__ (self, server, conn, addr):
key = server.password key = server.password
self.outgoing = server.cipher.new (key) self.outgoing = server.cipher.new (key)
self.incoming = server.cipher.new (key) self.incoming = server.cipher.new (key)
secure_monitor_channel.__init__ (self, server, conn, addr) secure_monitor_channel.__init__ (self, server, conn, addr)
def send (self, data): def send (self, data):
# send the encrypted data instead # send the encrypted data instead
ed = self.outgoing.encrypt (data) ed = self.outgoing.encrypt (data)
return secure_monitor_channel.send (self, ed) return secure_monitor_channel.send (self, ed)
def recv (self, block_size): def recv (self, block_size):
data = secure_monitor_channel.recv (self, block_size) data = secure_monitor_channel.recv (self, block_size)
if data: if data:
dd = self.incoming.decrypt (data) dd = self.incoming.decrypt (data)
return dd return dd
else: else:
return data return data
class secure_monitor_server (monitor_server): class secure_monitor_server (monitor_server):
channel_class = secure_monitor_channel channel_class = secure_monitor_channel
def __init__ (self, password, hostname='', port=8023): def __init__ (self, password, hostname='', port=8023):
monitor_server.__init__ (self, hostname, port) monitor_server.__init__ (self, hostname, port)
self.password = password self.password = password
def status (self): def status (self):
p = monitor_server.status (self) p = monitor_server.status (self)
# kludge # kludge
p.data = p.data + ('<br><b>Failed Authorizations:</b> %d' % self.failed_auths) p.data = p.data + ('<br><b>Failed Authorizations:</b> %d' % self.failed_auths)
return p return p
# don't try to print from within any of the methods # don't try to print from within any of the methods
# of this object. 8^) # of this object. 8^)
class output_producer: class output_producer:
def __init__ (self, channel, real_stderr): def __init__ (self, channel, real_stderr):
self.channel = channel self.channel = channel
self.data = '' self.data = ''
# use _this_ for debug output # use _this_ for debug output
self.stderr = real_stderr self.stderr = real_stderr
def check_data (self): def check_data (self):
if len(self.data) > 1<<16: if len(self.data) > 1<<16:
# runaway output, close it. # runaway output, close it.
self.channel.close() self.channel.close()
def write (self, data): def write (self, data):
lines = string.splitfields (data, '\n') lines = string.splitfields (data, '\n')
data = string.join (lines, '\r\n') data = string.join (lines, '\r\n')
self.data = self.data + data self.data = self.data + data
self.check_data() self.check_data()
def writeline (self, line): def writeline (self, line):
self.data = self.data + line + '\r\n' self.data = self.data + line + '\r\n'
self.check_data() self.check_data()
def writelines (self, lines): def writelines (self, lines):
self.data = self.data + string.joinfields ( self.data = self.data + string.joinfields (
lines, lines,
'\r\n' '\r\n'
) + '\r\n' ) + '\r\n'
self.check_data() self.check_data()
def ready (self): def ready (self):
return (len (self.data) > 0) return (len (self.data) > 0)
def flush (self): def flush (self):
pass pass
def softspace (self, *args): def softspace (self, *args):
pass pass
def more (self): def more (self):
if self.data: if self.data:
result = self.data[:512] result = self.data[:512]
self.data = self.data[512:] self.data = self.data[512:]
return result return result
else: else:
return '' return ''
if __name__ == '__main__': if __name__ == '__main__':
import string import string
import sys import sys
if '-s' in sys.argv: if '-s' in sys.argv:
sys.argv.remove ('-s') sys.argv.remove ('-s')
print 'Enter password: ', print 'Enter password: ',
password = raw_input() password = raw_input()
else: else:
password = None password = None
if '-e' in sys.argv: if '-e' in sys.argv:
sys.argv.remove ('-e') sys.argv.remove ('-e')
encrypt = 1 encrypt = 1
else: else:
encrypt = 0 encrypt = 0
print sys.argv print sys.argv
if len(sys.argv) > 1: if len(sys.argv) > 1:
port = string.atoi (sys.argv[1]) port = string.atoi (sys.argv[1])
else: else:
port = 8023 port = 8023
if password is not None: if password is not None:
s = secure_monitor_server (password, '', port) s = secure_monitor_server (password, '', port)
if encrypt: if encrypt:
s.channel_class = secure_encrypted_monitor_channel s.channel_class = secure_encrypted_monitor_channel
import sapphire import sapphire
s.cipher = sapphire s.cipher = sapphire
else: else:
s = monitor_server ('', port) s = monitor_server ('', port)
asyncore.loop() asyncore.loop()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment