Implement command parsing and fix plaintext listener and encodings

This commit is contained in:
Mark Veidemanis 2017-11-20 21:40:04 +00:00
parent a1051dfa68
commit f235c5cb44
2 changed files with 69 additions and 6 deletions

View File

@ -3,5 +3,7 @@
"bind":"127.0.0.1", "bind":"127.0.0.1",
"usessl":true, "usessl":true,
"key":"key.pem", "key":"key.pem",
"cert":"cert.pem" "cert":"cert.pem",
"usepassword":true,
"password":"example"
} }

View File

@ -21,6 +21,18 @@ def error(data):
print("[ERROR]", data) print("[ERROR]", data)
exit(1) exit(1)
def sendData(addr, data):
connections[addr].send(data)
def sendSuccess(addr, data):
sendData(addr, "[y] " + data)
def sendFailure(addr, data):
sendData(addr, "[n] " + data)
def sendInfo(addr, data):
sendData(addr, "[i] " + data)
class Base(Protocol): class Base(Protocol):
def __init__(self, addr): def __init__(self, addr):
self.addr = addr self.addr = addr
@ -32,8 +44,9 @@ class Base(Protocol):
self.transport.write(data) self.transport.write(data)
def dataReceived(self, data): def dataReceived(self, data):
data = data.rstrip() data = data.decode("utf-8", "replace")
log("Data received from %s:%s -- %s" % (self.addr.host, self.addr.port, data)) log("Data received from %s:%s -- %s" % (self.addr.host, self.addr.port, repr(data)))
helper.parseCommand(self.addr, self.authed, data)
def connectionMade(self): def connectionMade(self):
log("Connection from %s:%s" % (self.addr.host, self.addr.port)) log("Connection from %s:%s" % (self.addr.host, self.addr.port))
@ -41,7 +54,7 @@ class Base(Protocol):
def connectionLost(self, reason): def connectionLost(self, reason):
global connections global connections
log("Connection lost from %s: %s" % (self.addr.host, reason.getErrorMessage())) log("Connection lost from %s:%s -- %s" % (self.addr.host, self.addr.port, reason.getErrorMessage()))
if not listener == None: if not listener == None:
if self.addr in connections.keys(): if self.addr in connections.keys():
del connections[self.addr] del connections[self.addr]
@ -69,14 +82,62 @@ class Helper(object):
def getConfig(self): def getConfig(self):
with open("config.json", "r") as f: with open("config.json", "r") as f:
config = load(f) config = load(f)
if set(["port", "bind", "usessl"]).issubset(set(config.keys())): if set(["port", "bind", "usessl", "usepassword"]).issubset(set(config.keys())):
if config["usessl"] == True: if config["usessl"] == True:
if not set(["cert", "key"]).issubset(set(config.keys())): if not set(["cert", "key"]).issubset(set(config.keys())):
error("SSL is on but certificate or key is not defined") error("SSL is on but certificate or key is not defined")
if config["usepassword"] == True:
if not "password" in config.keys():
error("Password authentication is on but password is not defined")
return config return config
else: else:
error("Mandatory values missing from config") error("Mandatory values missing from config")
def parseCommand(self, addr, authed, data):
data = data.strip()
spl = data.split()
obj = connections[addr]
success = lambda data: sendSuccess(addr, data)
failure = lambda data: sendFailure(addr, data)
info = lambda data: sendInfo(addr, data)
incUsage = lambda: sendFailure(addr, "Incorrect usage")
length = len(spl)
if len(spl) > 0:
cmd = spl[0]
else:
send("No text was sent")
return
if authed == True:
if cmd == "pass":
info("You are already authenticated")
return
elif cmd == "logout":
obj.authed = False
success("Logged out")
return
else:
incUsage()
return
else:
if cmd == "pass":
if length == 2:
if spl[1] == config["password"]:
success("Authenticated successfully")
obj.authed = True
return
else:
failure("Password incorrect")
obj.transport.loseConnection()
return
else:
incUsage()
return
else:
incUsage()
return
if __name__ == "__main__": if __name__ == "__main__":
helper = Helper() helper = Helper()
config = helper.getConfig() config = helper.getConfig()
@ -86,7 +147,7 @@ if __name__ == "__main__":
reactor.listenSSL(config["port"], listener, DefaultOpenSSLContextFactory(config["key"], config["cert"]), interface=config["bind"]) reactor.listenSSL(config["port"], listener, DefaultOpenSSLContextFactory(config["key"], config["cert"]), interface=config["bind"])
log("Threshold running with SSL on %s:%s" % (config["bind"], config["port"])) log("Threshold running with SSL on %s:%s" % (config["bind"], config["port"]))
else: else:
reactor.listen(config["port"], listener, interface=config["bind"]) reactor.listenTCP(config["port"], listener, interface=config["bind"])
log("Threshold running on %s:%s" % (config["bind"], config["port"])) log("Threshold running on %s:%s" % (config["bind"], config["port"]))
reactor.run() reactor.run()