diff options
Diffstat (limited to 'tools/check-sth.py')
-rwxr-xr-x | tools/check-sth.py | 138 |
1 files changed, 0 insertions, 138 deletions
diff --git a/tools/check-sth.py b/tools/check-sth.py deleted file mode 100755 index dacd8e6..0000000 --- a/tools/check-sth.py +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# Copyright (c) 2015, NORDUnet A/S. -# See LICENSE for licensing information. - -import sys -import argparse -import json -import errno -import shutil -import base64 -from datetime import datetime, timedelta, tzinfo -import time -from certtools import get_sth, create_ssl_context, check_sth_signature, get_public_key_from_file, get_consistency_proof, verify_consistency_proof - -NAGIOS_OK = 0 -NAGIOS_WARN = 1 -NAGIOS_CRIT = 2 -NAGIOS_UNKNOWN = 3 - -DEFAULT_CUR_FILE = 'cur-sth.json' - -parser = argparse.ArgumentParser(description="") -parser.add_argument('--cur-sth', - metavar='file', - default=DEFAULT_CUR_FILE, - help="File containing current STH (default=%s)" % DEFAULT_CUR_FILE) -parser.add_argument('baseurl', help="Base URL for CT log") -parser.add_argument('--publickey', default=None, metavar='file', help='Public key for the CT log') -parser.add_argument('--cafile', default=None, metavar='file', help='File containing the CA cert') -parser.add_argument('--allow-lag', action='store_true', help='Allow node to lag behind previous STH') -parser.add_argument('--quiet-ok', action='store_true', help="Don't print status if OK") - -def print_sth(sth): - if sth is None: - print "NONE" - else: - print sth['timestamp'] - print sth['sha256_root_hash'] - print sth['tree_size'] - print sth['tree_head_signature'] - -def get_new_sth(baseurl): - try: - sth = get_sth(baseurl) - except Exception, e: - print e - sys.exit(NAGIOS_UNKNOWN) - return sth - -def read_sth(fn): - try: - f = open(fn) - except IOError, e: - if e.errno == errno.ENOENT: - return None - raise e - return json.loads(f.read()) - -def mv_file(fromfn, tofn): - shutil.move(fromfn, tofn) - -def write_file(fn, sth): - tempname = fn + ".new" - open(tempname, 'w').write(json.dumps(sth)) - mv_file(tempname, fn) - -class UTC(tzinfo): - def utcoffset(self, dt): - return timedelta(hours=0) - def dst(self, dt): - return timedelta(0) - -def check_age(sth): - age = time.time() - sth["timestamp"]/1000 - sth_time = datetime.fromtimestamp(sth['timestamp'] / 1000, UTC()).strftime("%Y-%m-%d %H:%M:%S") - roothash = b64_to_b16(sth['sha256_root_hash']) - if age > 6 * 3600: - print "CRITICAL: %s is older than 6h: %s UTC" % (roothash, sth_time) - sys.exit(NAGIOS_CRIT) - if age > 2 * 3600: - print "WARNING: %s is older than 2h: %s UTC" % (roothash, sth_time) - sys.exit(NAGIOS_WARN) - return "%s UTC, %d minutes ago" % (sth_time, age/60) - -def check_consistency(newsth, oldsth, baseurl): - consistency_proof = [base64.decodestring(entry) for entry in get_consistency_proof(baseurl, oldsth["tree_size"], newsth["tree_size"])] - (old_treehead, new_treehead) = verify_consistency_proof(consistency_proof, oldsth["tree_size"], newsth["tree_size"], base64.b64decode(oldsth["sha256_root_hash"])) - assert old_treehead == base64.b64decode(oldsth["sha256_root_hash"]) - assert new_treehead == base64.b64decode(newsth["sha256_root_hash"]) - -def b64_to_b16(s): - return base64.b16encode(base64.decodestring(s)) - -def main(args): - if args.cur_sth is None: - args.cur_sth = "cur-sth.json" - - create_ssl_context(cafile=args.cafile) - - logpublickey = get_public_key_from_file(args.publickey) if args.publickey else None - - newsth = get_new_sth(args.baseurl) - check_sth_signature(args.baseurl, newsth, publickey=logpublickey) - - oldsth = read_sth(args.cur_sth) - - #print_sth(newsth) - #print_sth(oldsth) - - if oldsth: - if newsth["tree_size"] == oldsth["tree_size"]: - if oldsth["sha256_root_hash"] != newsth["sha256_root_hash"]: - print "CRITICAL: root hash is different even though tree size is the same.", - print "tree size:", newsth["tree_size"], - print "old hash:", b64_to_b16(oldsth["sha256_root_hash"]) - print "new hash:", b64_to_b16(newsth["sha256_root_hash"]) - sys.exit(NAGIOS_CRIT) - elif newsth["tree_size"] < oldsth["tree_size"]: - if not args.allow_lag: - print "CRITICAL: new tree smaller than previous tree (%d < %d)" % \ - (newsth["tree_size"], oldsth["tree_size"]) - sys.exit(NAGIOS_CRIT) - - if oldsth and oldsth["tree_size"] > 0 and oldsth["tree_size"] != newsth["tree_size"]: - check_consistency(newsth, oldsth, args.baseurl) - - age = check_age(newsth) - - write_file(args.cur_sth, newsth) - - if not args.quiet_ok: - print "OK: size: %d hash: %s, %s" % (newsth["tree_size"], b64_to_b16(newsth["sha256_root_hash"])[:8], age) - sys.exit(NAGIOS_OK) - -if __name__ == '__main__': - main(parser.parse_args()) |