Commit 738aceb6 authored by Amos Latteier's avatar Amos Latteier

Added medusa monitor server to ZServer. This allows you to securly access Zope...

Added medusa monitor server to ZServer. This allows you to securly access Zope via a remote python prompt! You could do some serious Zope hacking with this--debug the server while it's running, tweaking live Zope objects, etc. Needless to say this is dangerous.
parent a84d9d53
# -*- Mode: Python; tab-width: 4 -*-
# Author: Sam Rushing <rushing@nightmare.com>
#
# python REPL channel.
#
RCS_ID = '$Id: monitor.py,v 1.1 1999/05/26 02:11:36 amos Exp $'
import md5
import socket
import string
import sys
import time
VERSION = string.split(RCS_ID)[2]
import asyncore
import asynchat
from counter import counter
import producers
class monitor_channel (asynchat.async_chat):
try_linemode = 1
def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock)
self.server = server
self.addr = addr
self.set_terminator ('\r\n')
self.data = ''
# local bindings specific to this channel
self.local_env = {}
self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt()
self.number = server.total_sessions.as_long()
self.line_counter = counter()
self.multi_line = []
def handle_connect (self):
# send IAC DO LINEMODE
self.push ('\377\375\"')
def close (self):
self.server.closed_sessions.increment()
asynchat.async_chat.close(self)
def prompt (self):
self.push ('>>> ')
def collect_incoming_data (self, data):
self.data = self.data + data
if len(self.data) > 1024:
# denial of service.
self.push ('BCNU\r\n')
self.close_when_done()
def found_terminator (self):
line = self.clean_line (self.data)
self.data = ''
self.line_counter.increment()
# check for special case inputs...
if not line and not self.multi_line:
self.prompt()
return
if line in ['\004', 'exit']:
self.push ('BCNU\r\n')
self.close_when_done()
return
oldout = sys.stdout
olderr = sys.stderr
try:
p = output_producer(self, olderr)
sys.stdout = p
sys.stderr = p
try:
# this is, of course, a blocking operation.
# if you wanted to thread this, you would have
# to synchronize, etc... and treat the output
# like a pipe. Not Fun.
#
# try eval first. If that fails, try exec. If that fails,
# hurl.
try:
if self.multi_line:
# oh, this is horrible...
raise SyntaxError
co = compile (line, repr(self), 'eval')
result = eval (co, self.local_env)
method = 'eval'
if result is not None:
print repr(result)
self.local_env['_'] = result
except SyntaxError:
try:
if self.multi_line:
if line and line[0] in [' ','\t']:
self.multi_line.append (line)
self.push ('... ')
return
else:
self.multi_line.append (line)
line = string.join (self.multi_line, '\n')
co = compile (line, repr(self), 'exec')
self.multi_line = []
else:
co = compile (line, repr(self), 'exec')
except SyntaxError, why:
if why[0] == 'unexpected EOF while parsing':
self.push ('... ')
self.multi_line.append (line)
return
exec co in self.local_env
method = 'exec'
except:
method = 'exception'
self.multi_line = []
(file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
print t, v, tbinfo
finally:
sys.stdout = oldout
sys.stderr = olderr
print '%s:%s (%s)> %s' % (
self.number,
self.line_counter,
method,
repr(line)
)
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.
# gee, it would be fun to write a full-blown line-editing
# environment, etc...
def clean_line (self, line):
chars = []
for ch in line:
oc = ord(ch)
if oc < 127:
if oc in [8,177]:
# backspace
chars = chars[:-1]
else:
chars.append (ch)
return string.join (chars, '')
class monitor_server (asyncore.dispatcher):
SERVER_IDENT = 'Monitor Server (V%s)' % VERSION
channel_class = monitor_channel
def __init__ (self, hostname='127.0.0.1', port=8023):
self.hostname = hostname
self.port = port
self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind ((hostname, port))
print '%s started on port %d' % (self.SERVER_IDENT, port)
self.listen (5)
self.closed = 0
self.failed_auths = 0
self.total_sessions = counter()
self.closed_sessions = counter()
def writable (self):
return 0
def handle_accept (self):
conn, addr = self.accept()
print 'Incoming monitor connection from %s:%d' % addr
self.channel_class (self, conn, addr)
self.total_sessions.increment()
def status (self):
return producers.simple_producer (
'<h2>%s</h2>' % self.SERVER_IDENT
+ '<br><b>Total Sessions:</b> %s' % self.total_sessions
+ '<br><b>Current Sessions:</b> %d' % (
self.total_sessions.as_long()-self.closed_sessions.as_long()
)
)
def hex_digest (s):
m = md5.md5()
m.update (s)
return string.joinfields (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'',
)
class secure_monitor_channel (monitor_channel):
authorized = 0
def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock)
self.server = server
self.addr = addr
self.set_terminator ('\r\n')
self.data = ''
# local bindings specific to this channel
self.local_env = {}
# send timestamp string
self.timestamp = str(time.time())
self.count = 0
self.line_counter = counter()
self.number = int(server.total_sessions.as_long())
self.multi_line = []
self.push (self.timestamp + '\r\n')
def found_terminator (self):
if not self.authorized:
if hex_digest ('%s%s' % (self.timestamp, self.server.password)) != self.data:
self.log ('%s: failed authorization' % self)
self.server.failed_auths = self.server.failed_auths + 1
self.close()
else:
self.authorized = 1
self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt()
self.data = ''
else:
monitor_channel.found_terminator (self)
class secure_encrypted_monitor_channel (secure_monitor_channel):
"Wrap send() and recv() with a stream cipher"
def __init__ (self, server, conn, addr):
key = server.password
self.outgoing = server.cipher.new (key)
self.incoming = server.cipher.new (key)
secure_monitor_channel.__init__ (self, server, conn, addr)
def send (self, data):
# send the encrypted data instead
ed = self.outgoing.encrypt (data)
return secure_monitor_channel.send (self, ed)
def recv (self, block_size):
data = secure_monitor_channel.recv (self, block_size)
if data:
dd = self.incoming.decrypt (data)
return dd
else:
return data
class secure_monitor_server (monitor_server):
channel_class = secure_monitor_channel
def __init__ (self, password, hostname='', port=8023):
monitor_server.__init__ (self, hostname, port)
self.password = password
def status (self):
p = monitor_server.status (self)
# kludge
p.data = p.data + ('<br><b>Failed Authorizations:</b> %d' % self.failed_auths)
return p
# don't try to print from within any of the methods
# of this object. 8^)
class output_producer:
def __init__ (self, channel, real_stderr):
self.channel = channel
self.data = ''
# use _this_ for debug output
self.stderr = real_stderr
def check_data (self):
if len(self.data) > 1<<16:
# runaway output, close it.
self.channel.close()
def write (self, data):
lines = string.splitfields (data, '\n')
data = string.join (lines, '\r\n')
self.data = self.data + data
self.check_data()
def writeline (self, line):
self.data = self.data + line + '\r\n'
self.check_data()
def writelines (self, lines):
self.data = self.data + string.joinfields (
lines,
'\r\n'
) + '\r\n'
self.check_data()
def ready (self):
return (len (self.data) > 0)
def flush (self):
pass
def softspace (self, *args):
pass
def more (self):
if self.data:
result = self.data[:512]
self.data = self.data[512:]
return result
else:
return ''
if __name__ == '__main__':
import string
import sys
if '-s' in sys.argv:
sys.argv.remove ('-s')
print 'Enter password: ',
password = raw_input()
else:
password = None
if '-e' in sys.argv:
sys.argv.remove ('-e')
encrypt = 1
else:
encrypt = 0
print sys.argv
if len(sys.argv) > 1:
port = string.atoi (sys.argv[1])
else:
port = 8023
if password is not None:
s = secure_monitor_server (password, '', port)
if encrypt:
s.channel_class = secure_encrypted_monitor_channel
import sapphire
s.cipher = sapphire
else:
s = monitor_server ('', port)
asyncore.loop()
# -*- Mode: Python; tab-width: 4 -*-
# monitor client, unix version.
import asyncore
import asynchat
import regsub
import socket
import string
import sys
import os
import md5
import time
class stdin_channel (asyncore.file_dispatcher):
def handle_read (self):
data = self.recv(512)
if not data:
print '\nclosed.'
self.sock_channel.close()
try:
self.close()
except:
pass
data = regsub.gsub ('\n', '\r\n', data)
self.sock_channel.push (data)
def writable (self):
return 0
def log (self, *ignore):
pass
class monitor_client (asynchat.async_chat):
def __init__ (self, password, addr=('',8023), socket_type=socket.AF_INET):
asynchat.async_chat.__init__ (self)
self.create_socket (socket_type, socket.SOCK_STREAM)
self.terminator = '\r\n'
self.connect (addr)
self.sent_auth = 0
self.timestamp = ''
self.password = password
def collect_incoming_data (self, data):
if not self.sent_auth:
self.timestamp = self.timestamp + data
else:
sys.stdout.write (data)
sys.stdout.flush()
def found_terminator (self):
if not self.sent_auth:
self.push (hex_digest (self.timestamp + self.password) + '\r\n')
self.sent_auth = 1
else:
print
def handle_close (self):
# close all the channels, which will make the standard main
# loop exit.
map (lambda x: x.close(), asyncore.socket_map.keys())
def log (self, *ignore):
pass
class encrypted_monitor_client (monitor_client):
"Wrap push() and recv() with a stream cipher"
def init_cipher (self, cipher, key):
self.outgoing = cipher.new (key)
self.incoming = cipher.new (key)
def push (self, data):
# push the encrypted data instead
return monitor_client.push (self, self.outgoing.encrypt (data))
def recv (self, block_size):
data = monitor_client.recv (self, block_size)
if data:
return self.incoming.decrypt (data)
else:
return data
def hex_digest (s):
m = md5.md5()
m.update (s)
return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'',
)
if __name__ == '__main__':
if len(sys.argv) == 1:
print 'Usage: %s host port' % sys.argv[0]
sys.exit(0)
if ('-e' in sys.argv):
encrypt = 1
sys.argv.remove ('-e')
else:
encrypt = 0
sys.stderr.write ('Enter Password: ')
sys.stderr.flush()
import os
try:
os.system ('stty -echo')
p = raw_input()
print
finally:
os.system ('stty echo')
stdin = stdin_channel (0)
if len(sys.argv) > 1:
if encrypt:
client = encrypted_monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
import sapphire
client.init_cipher (sapphire, p)
else:
client = monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
else:
# default to local host, 'standard' port
client = monitor_client (p)
stdin.sock_channel = client
asyncore.loop()
# -*- Mode: Python; tab-width: 4 -*-
# monitor client, win32 version
# since we can't do select() on stdin/stdout, we simply
# use threads and blocking sockets. <sigh>
import regsub
import socket
import string
import sys
import thread
import md5
def hex_digest (s):
m = md5.md5()
m.update (s)
return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'',
)
def reader (lock, sock, password):
# first grab the timestamp
ts = sock.recv (1024)[:-2]
sock.send (hex_digest (ts+password) + '\r\n')
while 1:
d = sock.recv (1024)
if not d:
lock.release()
print 'Connection closed. Hit <return> to exit'
thread.exit()
sys.stdout.write (d)
sys.stdout.flush()
def writer (lock, sock, barrel="just kidding"):
while lock.locked():
sock.send (
sys.stdin.readline()[:-1] + '\r\n'
)
if __name__ == '__main__':
if len(sys.argv) == 1:
print 'Usage: %s host port'
sys.exit(0)
print 'Enter Password: ',
p = raw_input()
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect ((sys.argv[1], string.atoi(sys.argv[2])))
l = thread.allocate_lock()
l.acquire()
thread.start_new_thread (reader, (l, s, p))
writer (l, s)
# -*- Mode: Python; tab-width: 4 -*-
# Author: Sam Rushing <rushing@nightmare.com>
#
# python REPL channel.
#
RCS_ID = '$Id: monitor.py,v 1.1 1999/05/26 02:11:36 amos Exp $'
import md5
import socket
import string
import sys
import time
VERSION = string.split(RCS_ID)[2]
import asyncore
import asynchat
from counter import counter
import producers
class monitor_channel (asynchat.async_chat):
try_linemode = 1
def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock)
self.server = server
self.addr = addr
self.set_terminator ('\r\n')
self.data = ''
# local bindings specific to this channel
self.local_env = {}
self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt()
self.number = server.total_sessions.as_long()
self.line_counter = counter()
self.multi_line = []
def handle_connect (self):
# send IAC DO LINEMODE
self.push ('\377\375\"')
def close (self):
self.server.closed_sessions.increment()
asynchat.async_chat.close(self)
def prompt (self):
self.push ('>>> ')
def collect_incoming_data (self, data):
self.data = self.data + data
if len(self.data) > 1024:
# denial of service.
self.push ('BCNU\r\n')
self.close_when_done()
def found_terminator (self):
line = self.clean_line (self.data)
self.data = ''
self.line_counter.increment()
# check for special case inputs...
if not line and not self.multi_line:
self.prompt()
return
if line in ['\004', 'exit']:
self.push ('BCNU\r\n')
self.close_when_done()
return
oldout = sys.stdout
olderr = sys.stderr
try:
p = output_producer(self, olderr)
sys.stdout = p
sys.stderr = p
try:
# this is, of course, a blocking operation.
# if you wanted to thread this, you would have
# to synchronize, etc... and treat the output
# like a pipe. Not Fun.
#
# try eval first. If that fails, try exec. If that fails,
# hurl.
try:
if self.multi_line:
# oh, this is horrible...
raise SyntaxError
co = compile (line, repr(self), 'eval')
result = eval (co, self.local_env)
method = 'eval'
if result is not None:
print repr(result)
self.local_env['_'] = result
except SyntaxError:
try:
if self.multi_line:
if line and line[0] in [' ','\t']:
self.multi_line.append (line)
self.push ('... ')
return
else:
self.multi_line.append (line)
line = string.join (self.multi_line, '\n')
co = compile (line, repr(self), 'exec')
self.multi_line = []
else:
co = compile (line, repr(self), 'exec')
except SyntaxError, why:
if why[0] == 'unexpected EOF while parsing':
self.push ('... ')
self.multi_line.append (line)
return
exec co in self.local_env
method = 'exec'
except:
method = 'exception'
self.multi_line = []
(file, fun, line), t, v, tbinfo = asyncore.compact_traceback()
print t, v, tbinfo
finally:
sys.stdout = oldout
sys.stderr = olderr
print '%s:%s (%s)> %s' % (
self.number,
self.line_counter,
method,
repr(line)
)
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.
# gee, it would be fun to write a full-blown line-editing
# environment, etc...
def clean_line (self, line):
chars = []
for ch in line:
oc = ord(ch)
if oc < 127:
if oc in [8,177]:
# backspace
chars = chars[:-1]
else:
chars.append (ch)
return string.join (chars, '')
class monitor_server (asyncore.dispatcher):
SERVER_IDENT = 'Monitor Server (V%s)' % VERSION
channel_class = monitor_channel
def __init__ (self, hostname='127.0.0.1', port=8023):
self.hostname = hostname
self.port = port
self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
self.set_reuse_addr()
self.bind ((hostname, port))
print '%s started on port %d' % (self.SERVER_IDENT, port)
self.listen (5)
self.closed = 0
self.failed_auths = 0
self.total_sessions = counter()
self.closed_sessions = counter()
def writable (self):
return 0
def handle_accept (self):
conn, addr = self.accept()
print 'Incoming monitor connection from %s:%d' % addr
self.channel_class (self, conn, addr)
self.total_sessions.increment()
def status (self):
return producers.simple_producer (
'<h2>%s</h2>' % self.SERVER_IDENT
+ '<br><b>Total Sessions:</b> %s' % self.total_sessions
+ '<br><b>Current Sessions:</b> %d' % (
self.total_sessions.as_long()-self.closed_sessions.as_long()
)
)
def hex_digest (s):
m = md5.md5()
m.update (s)
return string.joinfields (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'',
)
class secure_monitor_channel (monitor_channel):
authorized = 0
def __init__ (self, server, sock, addr):
asynchat.async_chat.__init__ (self, sock)
self.server = server
self.addr = addr
self.set_terminator ('\r\n')
self.data = ''
# local bindings specific to this channel
self.local_env = {}
# send timestamp string
self.timestamp = str(time.time())
self.count = 0
self.line_counter = counter()
self.number = int(server.total_sessions.as_long())
self.multi_line = []
self.push (self.timestamp + '\r\n')
def found_terminator (self):
if not self.authorized:
if hex_digest ('%s%s' % (self.timestamp, self.server.password)) != self.data:
self.log ('%s: failed authorization' % self)
self.server.failed_auths = self.server.failed_auths + 1
self.close()
else:
self.authorized = 1
self.push ('Python ' + sys.version + '\r\n')
self.push (sys.copyright+'\r\n')
self.push ('Welcome to %s\r\n' % self)
self.push ("[Hint: try 'from __main__ import *']\r\n")
self.prompt()
self.data = ''
else:
monitor_channel.found_terminator (self)
class secure_encrypted_monitor_channel (secure_monitor_channel):
"Wrap send() and recv() with a stream cipher"
def __init__ (self, server, conn, addr):
key = server.password
self.outgoing = server.cipher.new (key)
self.incoming = server.cipher.new (key)
secure_monitor_channel.__init__ (self, server, conn, addr)
def send (self, data):
# send the encrypted data instead
ed = self.outgoing.encrypt (data)
return secure_monitor_channel.send (self, ed)
def recv (self, block_size):
data = secure_monitor_channel.recv (self, block_size)
if data:
dd = self.incoming.decrypt (data)
return dd
else:
return data
class secure_monitor_server (monitor_server):
channel_class = secure_monitor_channel
def __init__ (self, password, hostname='', port=8023):
monitor_server.__init__ (self, hostname, port)
self.password = password
def status (self):
p = monitor_server.status (self)
# kludge
p.data = p.data + ('<br><b>Failed Authorizations:</b> %d' % self.failed_auths)
return p
# don't try to print from within any of the methods
# of this object. 8^)
class output_producer:
def __init__ (self, channel, real_stderr):
self.channel = channel
self.data = ''
# use _this_ for debug output
self.stderr = real_stderr
def check_data (self):
if len(self.data) > 1<<16:
# runaway output, close it.
self.channel.close()
def write (self, data):
lines = string.splitfields (data, '\n')
data = string.join (lines, '\r\n')
self.data = self.data + data
self.check_data()
def writeline (self, line):
self.data = self.data + line + '\r\n'
self.check_data()
def writelines (self, lines):
self.data = self.data + string.joinfields (
lines,
'\r\n'
) + '\r\n'
self.check_data()
def ready (self):
return (len (self.data) > 0)
def flush (self):
pass
def softspace (self, *args):
pass
def more (self):
if self.data:
result = self.data[:512]
self.data = self.data[512:]
return result
else:
return ''
if __name__ == '__main__':
import string
import sys
if '-s' in sys.argv:
sys.argv.remove ('-s')
print 'Enter password: ',
password = raw_input()
else:
password = None
if '-e' in sys.argv:
sys.argv.remove ('-e')
encrypt = 1
else:
encrypt = 0
print sys.argv
if len(sys.argv) > 1:
port = string.atoi (sys.argv[1])
else:
port = 8023
if password is not None:
s = secure_monitor_server (password, '', port)
if encrypt:
s.channel_class = secure_encrypted_monitor_channel
import sapphire
s.cipher = sapphire
else:
s = monitor_server ('', port)
asyncore.loop()
# -*- Mode: Python; tab-width: 4 -*-
# monitor client, unix version.
import asyncore
import asynchat
import regsub
import socket
import string
import sys
import os
import md5
import time
class stdin_channel (asyncore.file_dispatcher):
def handle_read (self):
data = self.recv(512)
if not data:
print '\nclosed.'
self.sock_channel.close()
try:
self.close()
except:
pass
data = regsub.gsub ('\n', '\r\n', data)
self.sock_channel.push (data)
def writable (self):
return 0
def log (self, *ignore):
pass
class monitor_client (asynchat.async_chat):
def __init__ (self, password, addr=('',8023), socket_type=socket.AF_INET):
asynchat.async_chat.__init__ (self)
self.create_socket (socket_type, socket.SOCK_STREAM)
self.terminator = '\r\n'
self.connect (addr)
self.sent_auth = 0
self.timestamp = ''
self.password = password
def collect_incoming_data (self, data):
if not self.sent_auth:
self.timestamp = self.timestamp + data
else:
sys.stdout.write (data)
sys.stdout.flush()
def found_terminator (self):
if not self.sent_auth:
self.push (hex_digest (self.timestamp + self.password) + '\r\n')
self.sent_auth = 1
else:
print
def handle_close (self):
# close all the channels, which will make the standard main
# loop exit.
map (lambda x: x.close(), asyncore.socket_map.keys())
def log (self, *ignore):
pass
class encrypted_monitor_client (monitor_client):
"Wrap push() and recv() with a stream cipher"
def init_cipher (self, cipher, key):
self.outgoing = cipher.new (key)
self.incoming = cipher.new (key)
def push (self, data):
# push the encrypted data instead
return monitor_client.push (self, self.outgoing.encrypt (data))
def recv (self, block_size):
data = monitor_client.recv (self, block_size)
if data:
return self.incoming.decrypt (data)
else:
return data
def hex_digest (s):
m = md5.md5()
m.update (s)
return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'',
)
if __name__ == '__main__':
if len(sys.argv) == 1:
print 'Usage: %s host port' % sys.argv[0]
sys.exit(0)
if ('-e' in sys.argv):
encrypt = 1
sys.argv.remove ('-e')
else:
encrypt = 0
sys.stderr.write ('Enter Password: ')
sys.stderr.flush()
import os
try:
os.system ('stty -echo')
p = raw_input()
print
finally:
os.system ('stty echo')
stdin = stdin_channel (0)
if len(sys.argv) > 1:
if encrypt:
client = encrypted_monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
import sapphire
client.init_cipher (sapphire, p)
else:
client = monitor_client (p, (sys.argv[1], string.atoi (sys.argv[2])))
else:
# default to local host, 'standard' port
client = monitor_client (p)
stdin.sock_channel = client
asyncore.loop()
# -*- Mode: Python; tab-width: 4 -*-
# monitor client, win32 version
# since we can't do select() on stdin/stdout, we simply
# use threads and blocking sockets. <sigh>
import regsub
import socket
import string
import sys
import thread
import md5
def hex_digest (s):
m = md5.md5()
m.update (s)
return string.join (
map (lambda x: hex (ord (x))[2:], map (None, m.digest())),
'',
)
def reader (lock, sock, password):
# first grab the timestamp
ts = sock.recv (1024)[:-2]
sock.send (hex_digest (ts+password) + '\r\n')
while 1:
d = sock.recv (1024)
if not d:
lock.release()
print 'Connection closed. Hit <return> to exit'
thread.exit()
sys.stdout.write (d)
sys.stdout.flush()
def writer (lock, sock, barrel="just kidding"):
while lock.locked():
sock.send (
sys.stdin.readline()[:-1] + '\r\n'
)
if __name__ == '__main__':
if len(sys.argv) == 1:
print 'Usage: %s host port'
sys.exit(0)
print 'Enter Password: ',
p = raw_input()
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.connect ((sys.argv[1], string.atoi(sys.argv[2])))
l = thread.allocate_lock()
l.acquire()
thread.start_new_thread (reader, (l, s, p))
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