def sendString(self, string): ret = NetworkObject() try: if self.noServer: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sslSock = ssl.wrap_socket( self.socket, cert_reqs=ssl.CERT_REQUIRED, ca_certs="network/certs/serverCert.pem") self.sslSock.connect((consts.TCP_IP, consts.TCP_PORT)) self.noServer = False self.sslSock.send(str.encode(string + '\0')) reading = True frags = [] while reading: chunk = self.sslSock.recv(4096).decode() if chunk[len(chunk) - 1:len(chunk)] == '\0' or chunk == "": reading = False frags.append( chunk[0:len(chunk) - 1] ) # remove the null, it'll mess up NetworkObject.initialize() else: frags.append(chunk) response = ''.join(frags) ret.initialize(response) except ConnectionRefusedError: self.noServer = True ret.error = consts.ERROR_CONNECTION_FAILED finally: return ret
def run(self): try: while True: # retrieve the data sent by the client and check that they actually sent something (including "") # data = self.connection.recv(consts.BUFFER_SIZE).decode() # note that the string is encoded as an aob oldTime = int(round(time.time() * 1000000)) # reading = True # frags = [] # while reading: # chunk = self.connection.recv(4096).decode() # if chunk[len(chunk) - 1:len(chunk)] == '\0': # reading = False # frags.append(chunk[0:len(chunk) - 1]) # remove the null, it'll mess up NetworkObject.initialize() # else: # frags.append(chunk) # data = ''.join(frags) # data = self.connection.recv(4096).decode() reading = True frags = [] while reading: chunk = self.connection.recv(4096).decode() # recv can continuously return empty strings, depending on what the client does, without the check it'll go into an infinite loop # this is fixable clientside, but that opens the server up to XSS, better to fix it here and let the client do w/e if chunk[len(chunk) - 1:len(chunk)] == '\0' or chunk == "": reading = False frags.append( chunk[0:len(chunk) - 1] ) # remove the null, it'll mess up NetworkObject.initialize() else: frags.append(chunk) data = "".join(frags) # data = data[0:len(data) - 1] print("Time elapsed:", int(round(time.time() * 1000000)) - oldTime) if not data: self.connection.send( str.encode(consts.ERROR_UNKNOWN + '\0')) else: networkObject = NetworkObject() networkObject.initialize(data) result = self.parseNetworkObject(networkObject) self.connection.send(str.encode(result.serialize() + '\0')) # send result back except socket.error as e: if (e.errno == errno.EPIPE ): # broken pipe error, not sure where this is defined print("[-] Client disconnected.") else: raise except Exception as e: print(e) finally: self.connection.close()
def test_serialize_withStrPayload(self): no = NetworkObject("a", "b", "c", "d", "e") result = no.serialize() self.assertEqual( result, '{"error": "b", "command": "c", "key": "a", "table": "e", "payload": "d"}' )
def test_serialize_withDictPayload(self): no = NetworkObject("a", "b", "c", {"aKey": "aVal"}, "e") result = no.serialize() # don't know why the double backslashes are present, but the test doesn't function without them self.assertEqual( result, '{"error": "b", "command": "c", "key": "a", "table": "e", "payload": "{\\"aKey\\": \\"aVal\\"}"}' )
def test_initialize_withStrPayload(self): no = NetworkObject("a", "b", "c", "d", "e") no.initialize('{"key": "v", "error": "w", "command": "x", "payload": "y", "table": "z"}') self.assertEqual(no.key, "v") self.assertEqual(no.error, "w") self.assertEqual(no.command, "x") self.assertEqual(no.payload, "y") self.assertEqual(no.table, "z")
def setMember(self, key, id, dict): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_SET, { "id": id, "data": dict }, consts.MEMBERS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def setKey(self, key, uak, dict): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_SET, { "id": uak, "data": dict }, consts.KEYS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def setService(self, key, id, dict): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_SET, { "id": id, "data": dict }, consts.SERVICES_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def sendString(self, string): ret = NetworkObject() try: if self.noServer: self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sslSock = ssl.wrap_socket( self.socket, cert_reqs=ssl.CERT_REQUIRED, ca_certs="network/certs/serverCert.pem") self.sslSock.connect((consts.TCP_IP, consts.TCP_PORT)) self.noServer = False self.sslSock.write(str.encode(string)) response = self.sslSock.recv(self.bufferSize).decode( ) # make sure to convert from aob to string ret.initialize(response) except ConnectionRefusedError: self.noServer = True ret.error = consts.ERROR_CONNECTION_FAILED finally: return ret
def parseNetworkObject(self, networkObject): responseError = consts.ERROR_INVALID_COMMAND # no news is bad news because this should be set in one of the if blocks responseCommand = consts.NO_CMD responsePayload = {} responseTable = consts.NO_TABLE response = self.dbc.execute(networkObject.table, networkObject.command, networkObject.payload, networkObject.key) if response["error"] == consts.NO_ERROR: responsePayload = response["result"] responseError = consts.NO_ERROR else: responseError = response["error"] return NetworkObject("", responseError, responseCommand, responsePayload, responseTable)
def getAllMembers(self, key): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_GET_ALL, "", consts.MEMBERS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def removeProvider(self, key, id): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_REMOVE, id, consts.PROVIDERS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def addProvider(self, key, dict): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_ADD, dict, consts.PROVIDERS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def truncateProviders(self, key): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_TRUNCATE, "", consts.PROVIDERS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def truncateMenu(self, key): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_TRUNCATE, "", consts.MENU_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def removeMenuItem(self, key, id): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_REMOVE, id, consts.MENU_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def addMenuItem(self, key, dict): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_ADD, dict, consts.MENU_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def getMember(self, key, id): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_GET, id, consts.MEMBERS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def truncateServices(self, key): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_TRUNCATE, "", consts.SERVICES_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def removeService(self, key, id): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_REMOVE, id, consts.SERVICES_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def getAllServices(self, key): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_GET_ALL, "", consts.SERVICES_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def addKey(self, key, dict): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_ADD, dict, consts.KEYS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def addService(self, key, dict): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_ADD, dict, consts.SERVICES_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def validateKey(self, key): networkObject = NetworkObject("", consts.NO_ERROR, consts.DBC_CMD_VALIDATE_KEY, key, consts.KEYS_TABLE) response = self.network.sendNetworkObject(networkObject) return response
def removeKey(self, key, uak): networkObject = NetworkObject(key, consts.NO_ERROR, consts.DBC_CMD_REMOVE, uak, consts.KEYS_TABLE) response = self.network.sendNetworkObject(networkObject) return response