From c6a0aeca3b30d177a588da2e32652bd9c170b0cf Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Fri, 22 Jun 2018 14:41:41 -0400 Subject: [PATCH] Fix dispatch of commands with InputData Inputdata needed to be serialized for the network. Further, had to have a JSON-safe payload for indicating name for certificate look up, to avoid doing pickle load on client input prior to client validation. --- confluent_client/confluent/tlvdata.py | 8 ++++++++ confluent_server/confluent/core.py | 16 ++++++++-------- confluent_server/confluent/sockapi.py | 5 +++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/confluent_client/confluent/tlvdata.py b/confluent_client/confluent/tlvdata.py index 216975ad..f5ea8229 100644 --- a/confluent_client/confluent/tlvdata.py +++ b/confluent_client/confluent/tlvdata.py @@ -89,6 +89,14 @@ def send(handle, data): handle.sendall(struct.pack("!I", tl)) handle.sendall(sdata) +def recvall(handle, size): + rd = handle.recv(size) + while len(rd) < size: + nd = handle.recv(size - len(rd)) + if not nd: + raise Exception("Error reading data") + rd += nd + return rd def recv(handle): tl = handle.recv(4) diff --git a/confluent_server/confluent/core.py b/confluent_server/confluent/core.py index b2b90b56..26a7f9da 100644 --- a/confluent_server/confluent/core.py +++ b/confluent_server/confluent/core.py @@ -575,12 +575,13 @@ def abbreviate_noderange(configmanager, inputdata, operation): return (msg.KeyValueData({'noderange': noderange.ReverseNodeRange(inputdata['nodes'], configmanager).noderange}),) -def handle_dispatch(connection, cert, dispatch): +def handle_dispatch(connection, cert, dispatch, peername): cert = crypto.dump_certificate(crypto.FILETYPE_ASN1, cert) if not util.cert_matches( - cfm.get_collective_member(dispatch['name'])['fingerprint'], cert): + cfm.get_collective_member(peername)['fingerprint'], cert): connection.close() return + dispatch = pickle.loads(dispatch) configmanager = cfm.ConfigManager(dispatch['tenant']) nodes = dispatch['nodes'] inputdata = dispatch['inputdata'] @@ -802,12 +803,11 @@ def dispatch_request(nodes, manager, element, configmanager, inputdata, tlvdata.recv(remote) tlvdata.recv(remote) myname = collective.get_myname() - tlvdata.send(remote, - {'dispatch': {'name': myname, 'nodes': list(nodes), - 'path': element, - 'tenant': configmanager.tenant, - 'operation': operation, - 'inputdata': inputdata}}) + dreq = pickle.dumps({'name': myname, 'nodes': list(nodes), + 'path': element,'tenant': configmanager.tenant, + 'operation': operation, 'inputdata': inputdata}) + tlvdata.send(remote, {'dispatch': {'name': myname, 'length': len(dreq)}}) + remote.sendall(dreq) while True: rlen = remote.recv(8) while len(rlen) < 8: diff --git a/confluent_server/confluent/sockapi.py b/confluent_server/confluent/sockapi.py index 0ebad971..757a59ef 100644 --- a/confluent_server/confluent/sockapi.py +++ b/confluent_server/confluent/sockapi.py @@ -123,8 +123,9 @@ def sessionhdl(connection, authname, skipauth=False, cert=None): return collective.handle_connection(connection, cert, response['collective']) if 'dispatch' in response: - return pluginapi.handle_dispatch(connection, cert, - response['dispatch']) + dreq = tlvdata.recvall(connection, response['dispatch']['length']) + return pluginapi.handle_dispatch(connection, cert, dreq, + response['dispatch']['name']) if 'proxyconsole' in response: return start_proxy_term(connection, cert, response['proxyconsole']) authname = response['username']