Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
141 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,95 +1,79 @@ | ||
#!/usr/bin/env python | ||
#!/usr/bin/env python -i | ||
import sys,os | ||
local_module_dir = os.path.join(os.path.dirname( os.path.realpath( __file__ ) ), 'libs') | ||
if os.path.isdir(local_module_dir): | ||
sys.path.append(local_module_dir) | ||
import utils, hmac, hashlib | ||
import ConfigParser | ||
import socket, threading | ||
|
||
# client example from http://www.oluyede.org/blog/2008/08/31/twisted-interactive-console/ | ||
|
||
from twisted.internet import defer, stdio, protocol, reactor | ||
from twisted.protocols import basic | ||
class testclient: | ||
def __init__(self, address_tuple, config): | ||
self.config = config | ||
print self.config.get('auth', 'shared_secret') | ||
self.socket = socket.create_connection(address_tuple) | ||
|
||
class Repl(basic.LineReceiver): | ||
delimiter = '\n' | ||
prompt_string = '>>> ' | ||
|
||
def prompt(self): | ||
self.transport.write(self.prompt_string) | ||
|
||
def connectionMade(self): | ||
self.sendLine('Welcome to Repl') | ||
# store factory and connector upon connection to the stdout | ||
self.factory = CFactory() | ||
self.connector = reactor.connectTCP('127.0.0.1', 8080, self.factory) | ||
self.prompt() | ||
|
||
def lineReceived(self, line): | ||
if not line: | ||
self.prompt() | ||
return | ||
|
||
self.issueCommand(line) | ||
|
||
def issueCommand(self, command): | ||
# write to the connector's transport, not the one writing on stdout | ||
#self.connector.transport.write("%s%s" % (command, self.delimiter)) | ||
self.connector.send_signed(command) | ||
# register the callback on the factory's deferred | ||
self.factory.deferred.addCallback(self._checkResponse) | ||
|
||
def _checkResponse(self, message): | ||
self.sendLine(message) | ||
self.prompt() | ||
# recreate the deferred each time we have the response | ||
self.factory.deferred = defer.Deferred() | ||
|
||
class Client(basic.LineReceiver): | ||
delimiter = '\n' | ||
|
||
def connectionMade(self): | ||
pass | ||
self.receiver_thread = threading.Thread(target=self.tcp_reader) | ||
self.receiver_thread.setDaemon(1) | ||
self.receiver_thread.start() | ||
|
||
|
||
def lineReceived(self, data): | ||
print "Client: got data %s" % data | ||
if data[0:6] == "HELLO\t": | ||
self.session_key = utils.hex_decode(data.split("\t")[1]) | ||
self.hmac_key = self.session_key + self.config.get('auth', 'shared_secret') | ||
message = self.verify_data(data) | ||
#print "Client: Got message %s\n" % message | ||
#print "Client: self.session_key=%s" % utils.hex_encode(self.session_key) | ||
if message == False: | ||
self.factory.deferred.callback("ERROR Hash mismatch") | ||
print "ERROR Hash mismatch" | ||
return | ||
|
||
self.factory.deferred.callback(message) | ||
|
||
def verify_data(self, data): | ||
sent_hash = utils.hex_decode(data[-40:]) | ||
#print "got hash %s" % utils.hex_encode(sent_hash) | ||
message = data[:-41] | ||
h = hmac.new(self.session_key, message, hashlib.sha1) | ||
#print "got message %s" % repr(message) | ||
h = hmac.new(self.hmac_key, message, hashlib.sha1) | ||
if sent_hash != h.digest(): | ||
return False | ||
return message | ||
|
||
def send_signed(self, message): | ||
h = hmac.new(self.session_key, message, hashlib.sha1) | ||
self.transport.write(message + "\t" + h.hexdigest() + "\n") | ||
h = hmac.new(self.hmac_key, message, hashlib.sha1) | ||
#print "session key %s" % utils.hex_encode(self.session_key) | ||
#print "hmac key %s" % repr(self.hmac_key) | ||
self.socket.sendall(message + "\t" + h.hexdigest() + "\n") | ||
|
||
def tcp_reader(self): | ||
alive = True | ||
charbuffer = '' | ||
try: | ||
while alive: | ||
data = self.socket.recv(4096) | ||
if data == '': | ||
continue | ||
|
||
# TODO: hex-encode unprintable characters (but keep newlines) | ||
sys.stdout.write(data) | ||
|
||
def responseFinished(self, num_lines, data): | ||
# just fire the callback | ||
self.factory.deferred.callback(( | ||
self.cmd_success, num_lines, data)) | ||
charbuffer += data | ||
# Partition the charbuffer at newlines and parse the command until we have no newlines left | ||
while charbuffer.find("\n") != -1: | ||
part = charbuffer.partition("\n") | ||
charbuffer = part[2] | ||
self.lineReceived(part[0]) | ||
|
||
def connectionLost(self, reason): | ||
reactor.stop() | ||
except Exception, e: | ||
print e | ||
self.alive = False | ||
|
||
|
||
class CFactory(protocol.ClientFactory): | ||
protocol = Client | ||
|
||
def __init__(self): | ||
self.deferred = defer.Deferred() | ||
if __name__ == '__main__': | ||
config = ConfigParser.SafeConfigParser() | ||
config.read('tcpserver.conf') | ||
c = testclient(('127.0.0.1', '8080'), config) | ||
|
||
if __name__ == "__main__": | ||
stdio.StandardIO(Repl()) | ||
reactor.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#!/usr/bin/env python | ||
import sys,os | ||
local_module_dir = os.path.join(os.path.dirname( os.path.realpath( __file__ ) ), 'libs') | ||
if os.path.isdir(local_module_dir): | ||
sys.path.append(local_module_dir) | ||
import utils, hmac, hashlib | ||
|
||
# client example from http://www.oluyede.org/blog/2008/08/31/twisted-interactive-console/ | ||
|
||
from twisted.internet import defer, stdio, protocol, reactor | ||
from twisted.protocols import basic | ||
|
||
class Repl(basic.LineReceiver): | ||
delimiter = '\n' | ||
prompt_string = '>>> ' | ||
|
||
def prompt(self): | ||
self.transport.write(self.prompt_string) | ||
|
||
def connectionMade(self): | ||
self.sendLine('Welcome to Repl') | ||
# store factory and connector upon connection to the stdout | ||
self.factory = CFactory() | ||
self.connector = reactor.connectTCP('127.0.0.1', 8080, self.factory) | ||
self.prompt() | ||
|
||
def lineReceived(self, line): | ||
if not line: | ||
self.prompt() | ||
return | ||
|
||
self.issueCommand(line) | ||
|
||
def issueCommand(self, command): | ||
# write to the connector's transport, not the one writing on stdout | ||
#self.connector.transport.write("%s%s" % (command, self.delimiter)) | ||
self.connector.send_signed(command) | ||
# register the callback on the factory's deferred | ||
self.factory.deferred.addCallback(self._checkResponse) | ||
|
||
def _checkResponse(self, message): | ||
self.sendLine(message) | ||
self.prompt() | ||
# recreate the deferred each time we have the response | ||
self.factory.deferred = defer.Deferred() | ||
|
||
class Client(basic.LineReceiver): | ||
delimiter = '\n' | ||
|
||
def connectionMade(self): | ||
pass | ||
|
||
def lineReceived(self, data): | ||
print "Client: got data %s" % data | ||
if data[0:6] == "HELLO\t": | ||
self.session_key = utils.hex_decode(data.split("\t")[1]) | ||
message = self.verify_data(data) | ||
#print "Client: Got message %s\n" % message | ||
#print "Client: self.session_key=%s" % utils.hex_encode(self.session_key) | ||
if message == False: | ||
self.factory.deferred.callback("ERROR Hash mismatch") | ||
return | ||
|
||
self.factory.deferred.callback(message) | ||
|
||
def verify_data(self, data): | ||
sent_hash = utils.hex_decode(data[-40:]) | ||
message = data[:-41] | ||
h = hmac.new(self.session_key, message, hashlib.sha1) | ||
if sent_hash != h.digest(): | ||
return False | ||
return message | ||
|
||
def send_signed(self, message): | ||
h = hmac.new(self.session_key, message, hashlib.sha1) | ||
self.transport.write(message + "\t" + h.hexdigest() + "\n") | ||
|
||
def responseFinished(self, num_lines, data): | ||
# just fire the callback | ||
self.factory.deferred.callback(( | ||
self.cmd_success, num_lines, data)) | ||
|
||
def connectionLost(self, reason): | ||
reactor.stop() | ||
|
||
|
||
class CFactory(protocol.ClientFactory): | ||
protocol = Client | ||
|
||
def __init__(self): | ||
self.deferred = defer.Deferred() | ||
|
||
if __name__ == "__main__": | ||
stdio.StandardIO(Repl()) | ||
reactor.run() |