Commit 5f32005f authored by Amos Latteier's avatar Amos Latteier

Fixed line-endings of monitor files. Thanks to Martijn Pieters for pointing out the problem.

parent 98368c63
# -*- 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.1 1999/05/26 02:11:36 amos Exp $' RCS_ID = '$Id: monitor.py,v 1.2 1999/05/27 17:25:55 amos Exp $'
import md5 import md5
import socket import socket
import string import string
import sys import sys
import time import time
VERSION = string.split(RCS_ID)[2] VERSION = string.split(RCS_ID)[2]
import asyncore import asyncore
import asynchat import asynchat
from counter import counter 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:
print repr(result) print repr(result)
self.local_env['_'] = result self.local_env['_'] = result
except SyntaxError: except SyntaxError:
try: try:
if self.multi_line: if self.multi_line:
if line and line[0] in [' ','\t']: if line and line[0] in [' ','\t']:
self.multi_line.append (line) self.multi_line.append (line)
self.push ('... ') self.push ('... ')
return return
else: else:
self.multi_line.append (line) self.multi_line.append (line)
line = string.join (self.multi_line, '\n') line = string.join (self.multi_line, '\n')
co = compile (line, repr(self), 'exec') co = compile (line, repr(self), 'exec')
self.multi_line = [] self.multi_line = []
else: else:
co = compile (line, repr(self), 'exec') co = compile (line, repr(self), 'exec')
except SyntaxError, why: except SyntaxError, why:
if why[0] == 'unexpected EOF while parsing': if why[0] == 'unexpected EOF while parsing':
self.push ('... ') self.push ('... ')
self.multi_line.append (line) self.multi_line.append (line)
return return
exec co in self.local_env exec co in self.local_env
method = 'exec' method = 'exec'
except: except:
method = 'exception' method = 'exception'
self.multi_line = [] self.multi_line = []
(file, fun, line), t, v, tbinfo = asyncore.compact_traceback() (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
print t, v, tbinfo print t, v, tbinfo
finally: finally:
sys.stdout = oldout sys.stdout = oldout
sys.stderr = olderr sys.stderr = olderr
print '%s:%s (%s)> %s' % ( print '%s:%s (%s)> %s' % (
self.number, self.number,
self.line_counter, self.line_counter,
method, method,
repr(line) repr(line)
) )
self.push_with_producer (p) self.push_with_producer (p)
self.prompt() self.prompt()
# for now, we ignore any telnet option stuff sent to # for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves. # us, and we process the backspace key ourselves.
# gee, it would be fun to write a full-blown line-editing # gee, it would be fun to write a full-blown line-editing
# environment, etc... # environment, etc...
def clean_line (self, line): def clean_line (self, line):
chars = [] chars = []
for ch in line: for ch in line:
oc = ord(ch) oc = ord(ch)
if oc < 127: if oc < 127:
if oc in [8,177]: if oc in [8,177]:
# backspace # backspace
chars = chars[:-1] chars = chars[:-1]
else: else:
chars.append (ch) chars.append (ch)
return string.join (chars, '') 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))
print '%s started on port %d' % (self.SERVER_IDENT, port) print '%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()
print 'Incoming monitor connection from %s:%d' % addr print '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 ('%s: failed authorization' % self) self.log ('%s: failed authorization' % self)
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 -*-
# monitor client, unix version. # monitor client, unix version.
import asyncore import asyncore
import asynchat import asynchat
import regsub import regsub
import socket import socket
import string import string
import sys import sys
import os import os
import md5 import md5
import time import time
class stdin_channel (asyncore.file_dispatcher): class stdin_channel (asyncore.file_dispatcher):
def handle_read (self): def handle_read (self):
data = self.recv(512) data = self.recv(512)
if not data: if not data:
print '\nclosed.' print '\nclosed.'
self.sock_channel.close() self.sock_channel.close()
try: try:
self.close() self.close()
except: except:
pass pass
data = regsub.gsub ('\n', '\r\n', data) data = regsub.gsub ('\n', '\r\n', data)
self.sock_channel.push (data) self.sock_channel.push (data)
def writable (self): def writable (self):
return 0 return 0
def log (self, *ignore): def log (self, *ignore):
pass pass
class monitor_client (asynchat.async_chat): class monitor_client (asynchat.async_chat):
def __init__ (self, password, addr=('',8023), socket_type=socket.AF_INET): def __init__ (self, password, addr=('',8023), socket_type=socket.AF_INET):
asynchat.async_chat.__init__ (self) asynchat.async_chat.__init__ (self)
self.create_socket (socket_type, socket.SOCK_STREAM) self.create_socket (socket_type, socket.SOCK_STREAM)
self.terminator = '\r\n' self.terminator = '\r\n'
self.connect (addr) self.connect (addr)
self.sent_auth = 0 self.sent_auth = 0
self.timestamp = '' self.timestamp = ''
self.password = password self.password = password
def collect_incoming_data (self, data): def collect_incoming_data (self, data):
if not self.sent_auth: if not self.sent_auth:
self.timestamp = self.timestamp + data self.timestamp = self.timestamp + data
else: else:
sys.stdout.write (data) sys.stdout.write (data)
sys.stdout.flush() sys.stdout.flush()
def found_terminator (self): def found_terminator (self):
if not self.sent_auth: if not self.sent_auth:
self.push (hex_digest (self.timestamp + self.password) + '\r\n') self.push (hex_digest (self.timestamp + self.password) + '\r\n')
self.sent_auth = 1 self.sent_auth = 1
else: else:
print print
def handle_close (self): def handle_close (self):
# close all the channels, which will make the standard main # close all the channels, which will make the standard main
# loop exit. # loop exit.
map (lambda x: x.close(), asyncore.socket_map.keys()) map (lambda x: x.close(), asyncore.socket_map.keys())
def log (self, *ignore): def log (self, *ignore):
pass pass
class encrypted_monitor_client (monitor_client): class encrypted_monitor_client (monitor_client):
"Wrap push() and recv() with a stream cipher" "Wrap push() and recv() with a stream cipher"
def init_cipher (self, cipher, key): def init_cipher (self, cipher, key):
self.outgoing = cipher.new (key) self.outgoing = cipher.new (key)
self.incoming = cipher.new (key) self.incoming = cipher.new (key)
def push (self, data): def push (self, data):
# push the encrypted data instead # push the encrypted data instead
return monitor_client.push (self, self.outgoing.encrypt (data)) return monitor_client.push (self, self.outgoing.encrypt (data))
def recv (self, block_size): def recv (self, block_size):
data = monitor_client.recv (self, block_size) data = monitor_client.recv (self, block_size)
if data: if data:
return self.incoming.decrypt (data) return self.incoming.decrypt (data)
else: else:
return data return data
def hex_digest (s): def hex_digest (s):
m = md5.md5() m = md5.md5()
m.update (s) m.update (s)
return string.join ( return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())), map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'', '',
) )
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) == 1: if len(sys.argv) == 1:
print 'Usage: %s host port' % sys.argv[0] print 'Usage: %s host port' % sys.argv[0]
sys.exit(0) sys.exit(0)
if ('-e' in sys.argv): if ('-e' in sys.argv):
encrypt = 1 encrypt = 1
sys.argv.remove ('-e') sys.argv.remove ('-e')
else: else:
encrypt = 0 encrypt = 0
sys.stderr.write ('Enter Password: ') sys.stderr.write ('Enter Password: ')
sys.stderr.flush() sys.stderr.flush()
import os import os
try: try:
os.system ('stty -echo') os.system ('stty -echo')
p = raw_input() p = raw_input()
print print
finally: finally:
os.system ('stty echo') os.system ('stty echo')
stdin = stdin_channel (0) stdin = stdin_channel (0)
if len(sys.argv) > 1: if len(sys.argv) > 1:
if encrypt: if encrypt:
client = encrypted_monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2]))) client = encrypted_monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
import sapphire import sapphire
client.init_cipher (sapphire, p) client.init_cipher (sapphire, p)
else: else:
client = monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2]))) client = monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
else: else:
# default to local host, 'standard' port # default to local host, 'standard' port
client = monitor_client (p) client = monitor_client (p)
stdin.sock_channel = client stdin.sock_channel = client
asyncore.loop() asyncore.loop()
# -*- Mode: Python; tab-width: 4 -*- # -*- Mode: Python; tab-width: 4 -*-
# monitor client, win32 version # monitor client, win32 version
# since we can't do select() on stdin/stdout, we simply # since we can't do select() on stdin/stdout, we simply
# use threads and blocking sockets. <sigh> # use threads and blocking sockets. <sigh>
import regsub import regsub
import socket import socket
import string import string
import sys import sys
import thread import thread
import md5 import md5
def hex_digest (s): def hex_digest (s):
m = md5.md5() m = md5.md5()
m.update (s) m.update (s)
return string.join ( return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())), map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'', '',
) )
def reader (lock, sock, password): def reader (lock, sock, password):
# first grab the timestamp # first grab the timestamp
ts = sock.recv (1024)[:-2] ts = sock.recv (1024)[:-2]
sock.send (hex_digest (ts+password) + '\r\n') sock.send (hex_digest (ts+password) + '\r\n')
while 1: while 1:
d = sock.recv (1024) d = sock.recv (1024)
if not d: if not d:
lock.release() lock.release()
print 'Connection closed. Hit <return> to exit' print 'Connection closed. Hit <return> to exit'
thread.exit() thread.exit()
sys.stdout.write (d) sys.stdout.write (d)
sys.stdout.flush() sys.stdout.flush()
def writer (lock, sock, barrel="just kidding"): def writer (lock, sock, barrel="just kidding"):
while lock.locked(): while lock.locked():
sock.send ( sock.send (
sys.stdin.readline()[:-1] + '\r\n' sys.stdin.readline()[:-1] + '\r\n'
) )
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) == 1: if len(sys.argv) == 1:
print 'Usage: %s host port' print 'Usage: %s host port'
sys.exit(0) sys.exit(0)
print 'Enter Password: ', print 'Enter Password: ',
p = raw_input() p = raw_input()
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect ((sys.argv[1], string.atoi(sys.argv[2]))) s.connect ((sys.argv[1], string.atoi(sys.argv[2])))
l = thread.allocate_lock() l = thread.allocate_lock()
l.acquire() l.acquire()
thread.start_new_thread (reader, (l, s, p)) thread.start_new_thread (reader, (l, s, p))
writer (l, s) writer (l, s)
# -*- 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.1 1999/05/26 02:11:36 amos Exp $' RCS_ID = '$Id: monitor.py,v 1.2 1999/05/27 17:25:55 amos Exp $'
import md5 import md5
import socket import socket
import string import string
import sys import sys
import time import time
VERSION = string.split(RCS_ID)[2] VERSION = string.split(RCS_ID)[2]
import asyncore import asyncore
import asynchat import asynchat
from counter import counter 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:
print repr(result) print repr(result)
self.local_env['_'] = result self.local_env['_'] = result
except SyntaxError: except SyntaxError:
try: try:
if self.multi_line: if self.multi_line:
if line and line[0] in [' ','\t']: if line and line[0] in [' ','\t']:
self.multi_line.append (line) self.multi_line.append (line)
self.push ('... ') self.push ('... ')
return return
else: else:
self.multi_line.append (line) self.multi_line.append (line)
line = string.join (self.multi_line, '\n') line = string.join (self.multi_line, '\n')
co = compile (line, repr(self), 'exec') co = compile (line, repr(self), 'exec')
self.multi_line = [] self.multi_line = []
else: else:
co = compile (line, repr(self), 'exec') co = compile (line, repr(self), 'exec')
except SyntaxError, why: except SyntaxError, why:
if why[0] == 'unexpected EOF while parsing': if why[0] == 'unexpected EOF while parsing':
self.push ('... ') self.push ('... ')
self.multi_line.append (line) self.multi_line.append (line)
return return
exec co in self.local_env exec co in self.local_env
method = 'exec' method = 'exec'
except: except:
method = 'exception' method = 'exception'
self.multi_line = [] self.multi_line = []
(file, fun, line), t, v, tbinfo = asyncore.compact_traceback() (file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
print t, v, tbinfo print t, v, tbinfo
finally: finally:
sys.stdout = oldout sys.stdout = oldout
sys.stderr = olderr sys.stderr = olderr
print '%s:%s (%s)> %s' % ( print '%s:%s (%s)> %s' % (
self.number, self.number,
self.line_counter, self.line_counter,
method, method,
repr(line) repr(line)
) )
self.push_with_producer (p) self.push_with_producer (p)
self.prompt() self.prompt()
# for now, we ignore any telnet option stuff sent to # for now, we ignore any telnet option stuff sent to
# us, and we process the backspace key ourselves. # us, and we process the backspace key ourselves.
# gee, it would be fun to write a full-blown line-editing # gee, it would be fun to write a full-blown line-editing
# environment, etc... # environment, etc...
def clean_line (self, line): def clean_line (self, line):
chars = [] chars = []
for ch in line: for ch in line:
oc = ord(ch) oc = ord(ch)
if oc < 127: if oc < 127:
if oc in [8,177]: if oc in [8,177]:
# backspace # backspace
chars = chars[:-1] chars = chars[:-1]
else: else:
chars.append (ch) chars.append (ch)
return string.join (chars, '') 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))
print '%s started on port %d' % (self.SERVER_IDENT, port) print '%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()
print 'Incoming monitor connection from %s:%d' % addr print '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 ('%s: failed authorization' % self) self.log ('%s: failed authorization' % self)
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 -*-
# monitor client, unix version. # monitor client, unix version.
import asyncore import asyncore
import asynchat import asynchat
import regsub import regsub
import socket import socket
import string import string
import sys import sys
import os import os
import md5 import md5
import time import time
class stdin_channel (asyncore.file_dispatcher): class stdin_channel (asyncore.file_dispatcher):
def handle_read (self): def handle_read (self):
data = self.recv(512) data = self.recv(512)
if not data: if not data:
print '\nclosed.' print '\nclosed.'
self.sock_channel.close() self.sock_channel.close()
try: try:
self.close() self.close()
except: except:
pass pass
data = regsub.gsub ('\n', '\r\n', data) data = regsub.gsub ('\n', '\r\n', data)
self.sock_channel.push (data) self.sock_channel.push (data)
def writable (self): def writable (self):
return 0 return 0
def log (self, *ignore): def log (self, *ignore):
pass pass
class monitor_client (asynchat.async_chat): class monitor_client (asynchat.async_chat):
def __init__ (self, password, addr=('',8023), socket_type=socket.AF_INET): def __init__ (self, password, addr=('',8023), socket_type=socket.AF_INET):
asynchat.async_chat.__init__ (self) asynchat.async_chat.__init__ (self)
self.create_socket (socket_type, socket.SOCK_STREAM) self.create_socket (socket_type, socket.SOCK_STREAM)
self.terminator = '\r\n' self.terminator = '\r\n'
self.connect (addr) self.connect (addr)
self.sent_auth = 0 self.sent_auth = 0
self.timestamp = '' self.timestamp = ''
self.password = password self.password = password
def collect_incoming_data (self, data): def collect_incoming_data (self, data):
if not self.sent_auth: if not self.sent_auth:
self.timestamp = self.timestamp + data self.timestamp = self.timestamp + data
else: else:
sys.stdout.write (data) sys.stdout.write (data)
sys.stdout.flush() sys.stdout.flush()
def found_terminator (self): def found_terminator (self):
if not self.sent_auth: if not self.sent_auth:
self.push (hex_digest (self.timestamp + self.password) + '\r\n') self.push (hex_digest (self.timestamp + self.password) + '\r\n')
self.sent_auth = 1 self.sent_auth = 1
else: else:
print print
def handle_close (self): def handle_close (self):
# close all the channels, which will make the standard main # close all the channels, which will make the standard main
# loop exit. # loop exit.
map (lambda x: x.close(), asyncore.socket_map.keys()) map (lambda x: x.close(), asyncore.socket_map.keys())
def log (self, *ignore): def log (self, *ignore):
pass pass
class encrypted_monitor_client (monitor_client): class encrypted_monitor_client (monitor_client):
"Wrap push() and recv() with a stream cipher" "Wrap push() and recv() with a stream cipher"
def init_cipher (self, cipher, key): def init_cipher (self, cipher, key):
self.outgoing = cipher.new (key) self.outgoing = cipher.new (key)
self.incoming = cipher.new (key) self.incoming = cipher.new (key)
def push (self, data): def push (self, data):
# push the encrypted data instead # push the encrypted data instead
return monitor_client.push (self, self.outgoing.encrypt (data)) return monitor_client.push (self, self.outgoing.encrypt (data))
def recv (self, block_size): def recv (self, block_size):
data = monitor_client.recv (self, block_size) data = monitor_client.recv (self, block_size)
if data: if data:
return self.incoming.decrypt (data) return self.incoming.decrypt (data)
else: else:
return data return data
def hex_digest (s): def hex_digest (s):
m = md5.md5() m = md5.md5()
m.update (s) m.update (s)
return string.join ( return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())), map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'', '',
) )
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) == 1: if len(sys.argv) == 1:
print 'Usage: %s host port' % sys.argv[0] print 'Usage: %s host port' % sys.argv[0]
sys.exit(0) sys.exit(0)
if ('-e' in sys.argv): if ('-e' in sys.argv):
encrypt = 1 encrypt = 1
sys.argv.remove ('-e') sys.argv.remove ('-e')
else: else:
encrypt = 0 encrypt = 0
sys.stderr.write ('Enter Password: ') sys.stderr.write ('Enter Password: ')
sys.stderr.flush() sys.stderr.flush()
import os import os
try: try:
os.system ('stty -echo') os.system ('stty -echo')
p = raw_input() p = raw_input()
print print
finally: finally:
os.system ('stty echo') os.system ('stty echo')
stdin = stdin_channel (0) stdin = stdin_channel (0)
if len(sys.argv) > 1: if len(sys.argv) > 1:
if encrypt: if encrypt:
client = encrypted_monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2]))) client = encrypted_monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
import sapphire import sapphire
client.init_cipher (sapphire, p) client.init_cipher (sapphire, p)
else: else:
client = monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2]))) client = monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
else: else:
# default to local host, 'standard' port # default to local host, 'standard' port
client = monitor_client (p) client = monitor_client (p)
stdin.sock_channel = client stdin.sock_channel = client
asyncore.loop() asyncore.loop()
# -*- Mode: Python; tab-width: 4 -*- # -*- Mode: Python; tab-width: 4 -*-
# monitor client, win32 version # monitor client, win32 version
# since we can't do select() on stdin/stdout, we simply # since we can't do select() on stdin/stdout, we simply
# use threads and blocking sockets. <sigh> # use threads and blocking sockets. <sigh>
import regsub import regsub
import socket import socket
import string import string
import sys import sys
import thread import thread
import md5 import md5
def hex_digest (s): def hex_digest (s):
m = md5.md5() m = md5.md5()
m.update (s) m.update (s)
return string.join ( return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())), map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'', '',
) )
def reader (lock, sock, password): def reader (lock, sock, password):
# first grab the timestamp # first grab the timestamp
ts = sock.recv (1024)[:-2] ts = sock.recv (1024)[:-2]
sock.send (hex_digest (ts+password) + '\r\n') sock.send (hex_digest (ts+password) + '\r\n')
while 1: while 1:
d = sock.recv (1024) d = sock.recv (1024)
if not d: if not d:
lock.release() lock.release()
print 'Connection closed. Hit <return> to exit' print 'Connection closed. Hit <return> to exit'
thread.exit() thread.exit()
sys.stdout.write (d) sys.stdout.write (d)
sys.stdout.flush() sys.stdout.flush()
def writer (lock, sock, barrel="just kidding"): def writer (lock, sock, barrel="just kidding"):
while lock.locked(): while lock.locked():
sock.send ( sock.send (
sys.stdin.readline()[:-1] + '\r\n' sys.stdin.readline()[:-1] + '\r\n'
) )
if __name__ == '__main__': if __name__ == '__main__':
if len(sys.argv) == 1: if len(sys.argv) == 1:
print 'Usage: %s host port' print 'Usage: %s host port'
sys.exit(0) sys.exit(0)
print 'Enter Password: ', print 'Enter Password: ',
p = raw_input() p = raw_input()
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM) s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect ((sys.argv[1], string.atoi(sys.argv[2]))) s.connect ((sys.argv[1], string.atoi(sys.argv[2])))
l = thread.allocate_lock() l = thread.allocate_lock()
l.acquire() l.acquire()
thread.start_new_thread (reader, (l, s, p)) thread.start_new_thread (reader, (l, s, p))
writer (l, s) writer (l, s)
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