From 90bd73177964246a0e1a5d6c5e4255dcc8ec700d Mon Sep 17 00:00:00 2001 From: Magnus Ahltorp Date: Fri, 27 Feb 2015 13:53:32 +0100 Subject: Require authentication for merge calls --- tools/merge.py | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'tools/merge.py') diff --git a/tools/merge.py b/tools/merge.py index f4a007d..6becf7e 100755 --- a/tools/merge.py +++ b/tools/merge.py @@ -11,6 +11,9 @@ import urllib import urllib2 import sys import time +import ecdsa +import hashlib +import urlparse from certtools import build_merkle_tree, create_sth_signature, check_sth_signature, get_eckey_from_file, timing_point parser = argparse.ArgumentParser(description="") @@ -19,6 +22,8 @@ parser.add_argument("--frontend", action="append", metavar="url", help="Base URL parser.add_argument("--storage", action="append", metavar="url", help="Base URL for storage server", required=True) parser.add_argument("--mergedb", metavar="dir", help="Merge database directory", required=True) parser.add_argument("--keyfile", metavar="keyfile", help="File containing log key", required=True) +parser.add_argument("--own-keyname", metavar="keyname", help="The key name of the merge node", required=True) +parser.add_argument("--own-keyfile", metavar="keyfile", help="The file containing the private key of the merge node", required=True) parser.add_argument("--nomerge", action='store_true', help="Don't actually do merge") args = parser.parse_args() @@ -52,9 +57,26 @@ def add_to_logorder(key): f.write(base64.b16encode(key) + "\n") f.close() +def http_request(url, data=None): + req = urllib2.Request(url, data) + keyname = args.own_keyname + privatekey = get_eckey_from_file(args.own_keyfile) + sk = ecdsa.SigningKey.from_der(privatekey) + parsed_url = urlparse.urlparse(url) + if data == None: + data = parsed_url.query + method = "GET" + else: + method = "POST" + signature = sk.sign("%s\0%s\0%s" % (method, parsed_url.path, data), hashfunc=hashlib.sha256, + sigencode=ecdsa.util.sigencode_der) + req.add_header('X-Catlfish-Auth', base64.b64encode(signature) + ";key=" + keyname) + result = urllib2.urlopen(req).read() + return result + def get_new_entries(baseurl): try: - result = urllib2.urlopen(baseurl + "ct/storage/fetchnewentries").read() + result = http_request(baseurl + "ct/storage/fetchnewentries") parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": return [base64.b64decode(entry) for entry in parsed_result[u"entries"]] @@ -67,7 +89,7 @@ def get_new_entries(baseurl): def get_entries(baseurl, hashes): try: params = urllib.urlencode({"hash":[base64.b64encode(hash) for hash in hashes]}, doseq=True) - result = urllib2.urlopen(baseurl + "ct/storage/getentry?" + params).read() + result = http_request(baseurl + "ct/storage/getentry?" + params) parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": entries = dict([(base64.b64decode(entry["hash"]), base64.b64decode(entry["entry"])) for entry in parsed_result[u"entries"]]) @@ -82,7 +104,7 @@ def get_entries(baseurl, hashes): def get_curpos(baseurl): try: - result = urllib2.urlopen(baseurl + "ct/frontend/currentposition").read() + result = http_request(baseurl + "ct/frontend/currentposition") parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": return parsed_result[u"position"] @@ -94,8 +116,8 @@ def get_curpos(baseurl): def sendlog(baseurl, submission): try: - result = urllib2.urlopen(baseurl + "ct/frontend/sendlog", - json.dumps(submission)).read() + result = http_request(baseurl + "ct/frontend/sendlog", + json.dumps(submission)) return json.loads(result) except urllib2.HTTPError, e: print "ERROR: sendlog", e.read() @@ -110,8 +132,8 @@ def sendlog(baseurl, submission): def sendentry(baseurl, entry, hash): try: - result = urllib2.urlopen(baseurl + "ct/frontend/sendentry", - json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)})).read() + result = http_request(baseurl + "ct/frontend/sendentry", + json.dumps({"entry":base64.b64encode(entry), "treeleafhash":base64.b64encode(hash)})) return json.loads(result) except urllib2.HTTPError, e: print "ERROR: sendentry", e.read() @@ -126,8 +148,8 @@ def sendentry(baseurl, entry, hash): def sendsth(baseurl, submission): try: - result = urllib2.urlopen(baseurl + "ct/frontend/sendsth", - json.dumps(submission)).read() + result = http_request(baseurl + "ct/frontend/sendsth", + json.dumps(submission)) return json.loads(result) except urllib2.HTTPError, e: print "ERROR: sendsth", e.read() @@ -142,7 +164,7 @@ def sendsth(baseurl, submission): def get_missingentries(baseurl): try: - result = urllib2.urlopen(baseurl + "ct/frontend/missingentries").read() + result = http_request(baseurl + "ct/frontend/missingentries") parsed_result = json.loads(result) if parsed_result.get(u"result") == u"ok": return parsed_result[u"entries"] -- cgit v1.1