From ddb2a681e42278de30f0bb7b6ad29c1a8668e7cf Mon Sep 17 00:00:00 2001 From: Vanhala Antti Date: Wed, 4 Jun 2014 21:41:33 +0300 Subject: [PATCH] Validate received graph format --- scripts/sendGraph.py | 20 ++++++++++---------- web/graph.py | 25 ++++++++++++++++++++++++- web/graphData.py | 37 ++++++++++++++++++++++--------------- web/updateGraph.py | 1 + web/web.py | 4 ++-- 5 files changed, 59 insertions(+), 28 deletions(-) diff --git a/scripts/sendGraph.py b/scripts/sendGraph.py index 2805684..87558f8 100755 --- a/scripts/sendGraph.py +++ b/scripts/sendGraph.py @@ -48,7 +48,7 @@ def main(): all_edges = [] for process in range(0, 1 if cjdns_use_default else cjdns_processes): - print "Connecting port %d..." % (cjdns_first_port + process),; sys.stdout.flush() + print 'Connecting port %d...' % (cjdns_first_port + process),; sys.stdout.flush() try: cjdns = cjdns_connect(process) @@ -62,7 +62,7 @@ def main(): if not e in all_edges: all_edges.append(e) except Exception, err: - print "Failed!" + print 'Failed!' print traceback.format_exc() success = send_graph(all_nodes, all_edges) @@ -71,10 +71,10 @@ def main(): def generate_graph(cjdns): source_nodes = cjdns_get_node_store(cjdns) - print " Found %d source nodes." % len(source_nodes) + print ' Found %d source nodes.' % len(source_nodes) nodes, edges = cjdns_graph_from_nodes(cjdns, source_nodes) - print " Found %d nodes and %d links." % (len(nodes), len(edges)) + print ' Found %d nodes and %d links.' % (len(nodes), len(edges)) return (nodes, edges) @@ -98,9 +98,10 @@ def send_graph(nodes, edges): json_str = json.dumps(graph_data) - print "Sending data...",; sys.stdout.flush() - success = send_data(json_str) - print ("Done!" if success else "Failed!") + print 'Sending data...',; sys.stdout.flush() + answer = send_data(json_str) + success = answer == 'OK' + print ('Done!' if success else answer) return success @@ -207,10 +208,9 @@ def send_data(graph_data): post_data = urllib.urlencode({'data': graph_data}) req = urllib2.Request(url, post_data) response = urllib2.urlopen(req) - output = response.read() - return output == 'OK' + return response.read() -if __name__ == "__main__": +if __name__ == '__main__': main() diff --git a/web/graph.py b/web/graph.py index 4a0cd4c..6c0b012 100644 --- a/web/graph.py +++ b/web/graph.py @@ -1,7 +1,15 @@ +import re + + class Node: def __init__(self, ip, version=None, label=None): + if not valid_cjdns_ip(ip): + raise ValueError('Invalid IP address') + if not valid_version(version): + raise ValueError('Invalid version') + self.ip = ip - self.version = version + self.version = int(version) self.label = ip[-4:] if label == None else label def __lt__(self, b): @@ -24,3 +32,18 @@ class Edge: return 'Edge(a.ip="%s", b.ip="%s")' % ( self.a.ip, self.b.ip) + + + +_re_cjdns_ip = re.compile(r'^fc[0-9a-f]{2}(:[0-9a-f]{4}){7}$', re.IGNORECASE) + +def valid_cjdns_ip(ip): + return _re_cjdns_ip.match(ip) != None + +def valid_version(version): + try: + return int(version) < 20 + except ValueError: + return False + + \ No newline at end of file diff --git a/web/graphData.py b/web/graphData.py index 28c3dc0..841bc20 100644 --- a/web/graphData.py +++ b/web/graphData.py @@ -6,30 +6,37 @@ def insert_graph_data(config, json_str): try: graph_data = json.loads(json_str) except ValueError: - return False + return 'Invalid JSON' nodes = dict() edges = [] - if not 'nodes' in graph_data or not 'edges' in graph_data: - return False - - try: for n in graph_data['nodes']: - node = Node(n['ip'], version=n['version']) - nodes[n['ip']] = node + try: + node = Node(n['ip'], version=n['version']) + nodes[n['ip']] = node + except Exception: + pass for e in graph_data['edges']: - edge = Edge(nodes[e['a']], nodes[e['b']]) - edges.append(edge) + try: + edge = Edge(nodes[e['a']], nodes[e['b']]) + edges.append(edge) + except Exception: + pass + except Exception: + return 'Invalid JSON nodes' - except TypeError: - return False + print "Accepted %d nodes and %d links." % (len(nodes), len(edges)) - print "Received %d nodes and %d links." % (len(nodes), len(edges)) + if len(nodes) == 0 or len(edges) == 0: + return 'No valid nodes or edges' - with NodeDB(config) as db: - db.insert_graph(nodes, edges) + try: + with NodeDB(config) as db: + db.insert_graph(nodes, edges) + except Exception: + return 'Database failure' - return True + return None diff --git a/web/updateGraph.py b/web/updateGraph.py index b06d679..50daaaf 100755 --- a/web/updateGraph.py +++ b/web/updateGraph.py @@ -6,6 +6,7 @@ import graphPlotter def generate_graph(time_limit=60*60*3): nodes, edges = load_graph_from_db(time_limit) + print '%d nodes, %d edges' % (len(nodes), len(edges)) graph = graphPlotter.position_nodes(nodes, edges) json = graphPlotter.get_graph_json(graph) diff --git a/web/web.py b/web/web.py index 33a4f99..25866d2 100644 --- a/web/web.py +++ b/web/web.py @@ -25,10 +25,10 @@ def page_sendGraph(): data = request.form['data'] ret = insert_graph_data(app.config, data) - if ret: + if ret == None: return 'OK' else: - return 'FAIL' + return 'Error: %s' % ret if __name__ == '__main__': app.run(host='::')