summaryrefslogtreecommitdiff
path: root/monitor
diff options
context:
space:
mode:
Diffstat (limited to 'monitor')
-rwxr-xr-xmonitor/josef_logreader.py3
-rwxr-xr-xmonitor/josef_monitor.py236
-rw-r--r--monitor/monitor_conf.py4
3 files changed, 114 insertions, 129 deletions
diff --git a/monitor/josef_logreader.py b/monitor/josef_logreader.py
index 703ae98..42e1b61 100755
--- a/monitor/josef_logreader.py
+++ b/monitor/josef_logreader.py
@@ -11,6 +11,7 @@ from monitor_conf import *
TIME_LEN = 20
NEW_STH_STR = "STH updated"
START_STR = "Starting monitor"
+ERROR_STR = "ERROR"
def get_logs():
logs = []
@@ -89,7 +90,7 @@ def print_errors(l):
ages = []
for item in rev_log:
line = item[TIME_LEN:]
- if "ERROR" in line:
+ if ERROR_STR in line:
print item[:-1]
if line[:len(START_STR)] == START_STR:
break # comment this line to print all errors ever
diff --git a/monitor/josef_monitor.py b/monitor/josef_monitor.py
index d9b65a1..d23f292 100755
--- a/monitor/josef_monitor.py
+++ b/monitor/josef_monitor.py
@@ -79,12 +79,8 @@ class ctlog:
+ str(self.entries -1 ) + " of " + str(self.sth["tree_size"]-1))
if self.entries != start_size:
- if verify_subtree(self.sth, self.subtree, self.url):
- pass
- # self.log("Successfully build tree with " + str(self.entries - start_size) + \
- # " new entries. Size: " + str(self.entries))
- else:
- self.log("ERROR Failed to build tree from entries.")
+ if not verify_subtree(self.sth, self.subtree, self.url):
+ self.log(ERROR_STR + "Failed to build tree from entries!")
def fetch_and_increment_subtree(self, first, last, url, subtree =[[]]):
new_leafs = []
@@ -141,14 +137,14 @@ class ctlog:
try:
new_sth = get_sth(self.url)
except Exception, e:
- self.log("Failed to fetch STH. " +str(e))
+ self.log(ERROR_STR + "Failed to fetch STH. " +str(e))
return
try:
check_sth_signature(self.url, new_sth, base64.b64decode(self.key))
except:
- self.log("ERROR: Could not verify STH signature")
- print "ERROR: Could not verify STH signature from " + self.url
+ self.log(ERROR_STR + "Could not verify STH signature " + str(new_sth))
+ print ERROR_STR + "Could not verify STH signature from " + self.url
sth_time = datetime.datetime.fromtimestamp(new_sth['timestamp'] / 1000, UTC()).strftime("%Y-%m-%d %H:%M:%S")
if new_sth["timestamp"] != self.sth["timestamp"]:
@@ -159,7 +155,7 @@ class ctlog:
try:
roots = get_all_roots(self.url)
except Exception, e:
- self.log("Failed to fetch roots. " + str(e))
+ self.log(ERROR_STR + "Failed to fetch roots. " + str(e))
return
new_root_hash = str(hash(str(roots)))
@@ -180,15 +176,15 @@ class ctlog:
added, removed = compare_lists(hash_list, loaded_list)
if len(added) != 0:
- self.log(str(len(added)) + " new roots found")
+ # self.log(str(len(added)) + " new roots added")
for item in added:
root_cert = base64.decodestring(roots[hash_list.index(item)])
subject = get_cert_info(root_cert)["subject"]
issuer = get_cert_info(root_cert)["issuer"]
if subject == issuer:
- self.log("New Root: " + item + ", " + subject)
+ self.log("Added Root: " + item + ", " + subject)
else:
- self.log("WTF? Not a root...")
+ self.log(ERROR_STR + "Non self-signed root cert added! Subject:" + subject + " Issuer:" + issuer)
fn = cert_dir + "/" + item
tempname = fn + ".new"
@@ -198,7 +194,7 @@ class ctlog:
if len(removed) != 0:
- self.log(str(len(removed)) + " roots removed")
+ # self.log(str(len(removed)) + " roots removed")
for item in removed:
data = open(cert_dir + "/" + item).read()
root_cert = base64.decodestring(data)
@@ -207,28 +203,26 @@ class ctlog:
if subject == issuer:
self.log("Removed Root: " + item + ", " + subject)
else:
- self.log("WTF? Not a root...")
+ self.log(ERROR_STR + "Non self-signed root cert removed! Subject:" + subject + " Issuer:" + issuer)
def verify_progress(self, old):
new = self.sth
try:
if new["tree_size"] == old["tree_size"]:
if old["sha256_root_hash"] != new["sha256_root_hash"]:
- s = time.strftime('%H:%M:%S') + " CRITICAL: root hash is different for same tree size"
- self.log(s)
- print s
+ print ERROR_STR + "Root hash is different for same tree size in " + self.name
+ self.log(ERROR_STR + "New root hash for same tree size! Old:" + str(old) + " New:" + str(new))
elif new["tree_size"] < old["tree_size"]:
- s = time.strftime('%H:%M:%S') + " CRITICAL: new tree smaller than previous tree (%d < %d)" % \
- (new["tree_size"], old["tree_size"])
- self.log(s)
- print s
+ print ERROR_STR + "New tree smaller than previous tree (%d < %d) in %s" % \
+ (new["tree_size"], old["tree_size"], self.name)
+ self.log(ERROR_STR + "New tree is smaller than old tree! Old:" + str(old) + " New:" + str(new))
else:
age = time.time() - new["timestamp"]/1000
sth_time = datetime.datetime.fromtimestamp(new['timestamp'] / 1000, UTC()).strftime("%Y-%m-%d %H:%M:%S")
roothash = new['sha256_root_hash']
if age > 24 * 3600:
- s = "CRITICAL: STH is older than 24h: %s UTC" % (sth_time)
- self.log(s)
+ s = ERROR_STR + "STH is older than 24h: %s UTC" % (sth_time)
+ self.log(s + str(new))
print s
elif age > 12 * 3600:
s = "WARNING: STH is older than 12h: %s UTC" % (sth_time)
@@ -238,14 +232,12 @@ class ctlog:
s = "WARNING: STH is older than 6h: %s UTC" % (sth_time)
self.log(s)
# print s
- except:
- s = " ERROR: Failed to verify progress"
- self.log(s)
- print s
+ except Exception, e:
+ self.log(ERROR_STR + "Failed to verify progress! Old:" + str(old) + " New:" + str(new) + " Exception: " + str(e))
+ print "Failed to verify progress in " + self.name
def verify_consistency(self, old):
new = self.sth
- # for url in old:
try:
if old["tree_size"]!= new["tree_size"]:
consistency_proof = get_consistency_proof(self.url, old["tree_size"], new["tree_size"])
@@ -255,50 +247,44 @@ class ctlog:
res = verify_consistency_proof(decoded_consistency_proof, old["tree_size"], new["tree_size"], old["sha256_root_hash"])
if old["sha256_root_hash"] != str(base64.b64encode(res[0])):
- s = " Verification of old hash failed! " + \
- old["sha256_root_hash"], str(base64.b64encode(res[0]))
- self.log(s)
- print s
+ self.log(ERROR_STR + "Verification of consistency for old hash failed! Old:" \
+ + str(old) + " New:" + str(new) + " Proof:" + str(consistency_proof))
+ print ERROR_STR + "Failed to verify consistency for " + self.name
elif new["sha256_root_hash"] != str(base64.b64encode(res[1])):
- s = " Verification of new hash failed! " + \
- new["sha256_root_hash"], str(base64.b64encode(res[1]))
- self.log(s)
- print s
- # else:
- # s = "New STH, timestamp: " + str(new["timestamp"]) + \
- # ", size: " + str(new["tree_size"]) + "...OK."
- # self.log(s)
+ self.log(ERROR_STR + "Verification of consistency for new hash failed! Old:" \
+ + str(old) + " New:" + str(new) + " Proof:" + str(consistency_proof))
+ print ERROR_STR + "Failed to verify consistency for " + self.name
- except:
- self.log("ERROR: Could not verify consistency!")
- print "ERROR: Could not verify consistency for " + self.url
-
-
-def verify_inclusion_all(old, new):
- for url in old:
- try:
- if old[url] and new[url]:
- if old[url]["tree_size"]!= new[url]["tree_size"]:
- entries = []
-
- while len(entries) + old[url]["tree_size"]!= new[url]["tree_size"]:
- entries += get_entries(url, str(int(old[url]["tree_size"]) + len(entries)), new[url]["tree_size"] -1)["entries"]
- print "Got " + str(len(entries)) + " entries..."
-
- success = True
- for i in entries:
- h = get_leaf_hash(base64.b64decode(i["leaf_input"]))
- if not verify_inclusion_by_hash(url, h):
- success = False
-
- if success:
- print time.strftime("%H:%M:%S") + " Verifying inclusion for " + str(len(entries)) + " new entries in " + url + " ...OK"
- else:
- print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url
- errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url)
- except:
- print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url
- errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url)
+ except Exception, e:
+ self.log(ERROR_STR + "Could not verify consistency! " + " Old:" + str(old) + " New:" + str(new) + " Error:" + str(e))
+ print ERROR_STR + "Could not verify consistency for " + self.url
+
+
+# def verify_inclusion_all(old, new):
+# for url in old:
+# try:
+# if old[url] and new[url]:
+# if old[url]["tree_size"]!= new[url]["tree_size"]:
+# entries = []
+
+# while len(entries) + old[url]["tree_size"]!= new[url]["tree_size"]:
+# entries += get_entries(url, str(int(old[url]["tree_size"]) + len(entries)), new[url]["tree_size"] -1)["entries"]
+# print "Got " + str(len(entries)) + " entries..."
+
+# success = True
+# for i in entries:
+# h = get_leaf_hash(base64.b64decode(i["leaf_input"]))
+# if not verify_inclusion_by_hash(url, h):
+# success = False
+
+# if success:
+# print time.strftime("%H:%M:%S") + " Verifying inclusion for " + str(len(entries)) + " new entries in " + url + " ...OK"
+# else:
+# print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url
+# errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url)
+# except:
+# print time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url
+# errors.append(time.strftime('%H:%M:%S') + " ERROR: Failed to prove inclusion of all new entries in " + url)
def check_domain(raw_entry, log=None):
orig_entry = extract_original_entry(raw_entry)
@@ -316,66 +302,62 @@ def verify_subtree(sth, subtree, base_url):
root = base64.b64encode(reduce_subtree_to_root(tmp)[0])
if root == sth["sha256_root_hash"]:
- # print time.strftime('%H:%M:%S') + " Verifying root hashes for " + base_url + "...OK."
return True
else:
- print time.strftime('%H:%M:%S') + " ERROR: Failed to verify root hashes! STH root: " \
- + sth["sha256_root_hash"] + ", Tree root: " + root
return False
except:
- print time.strftime('%H:%M:%S') + " ERROR: Failed to build STH for " + base_url
return False
-def verify_inclusion_by_hash(base_url, leaf_hash):
- try:
- tmp_sth = get_sth(base_url)
- proof = get_proof_by_hash(base_url, leaf_hash, tmp_sth["tree_size"])
+# def verify_inclusion_by_hash(base_url, leaf_hash):
+# try:
+# tmp_sth = get_sth(base_url)
+# proof = get_proof_by_hash(base_url, leaf_hash, tmp_sth["tree_size"])
- decoded_inclusion_proof = []
- for item in proof["audit_path"]:
- decoded_inclusion_proof.append(base64.b64decode(item))
+# decoded_inclusion_proof = []
+# for item in proof["audit_path"]:
+# decoded_inclusion_proof.append(base64.b64decode(item))
- root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, proof["leaf_index"], tmp_sth["tree_size"], leaf_hash))
-
- if tmp_sth["sha256_root_hash"] == root:
- return True
- else:
- print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url
- return False
- except:
- print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for hashed entry in " + base_url
- return False
-
-def verify_inclusion_by_index(base_url, index):
- try:
- tmp_sth = get_sth(base_url)
- proof = get_proof_by_index(base_url, index, tmp_sth["tree_size"])
-
- decoded_inclusion_proof = []
- for item in proof["audit_path"]:
- decoded_inclusion_proof.append(base64.b64decode(item))
-
- root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, index, tmp_sth["tree_size"], get_leaf_hash(base64.b64decode(proof["leaf_input"]))))
-
- if tmp_sth["sha256_root_hash"] == root:
- print time.strftime('%H:%M:%S') + " Verifying inclusion for entry " + str(index) + " in " + base_url + "...OK."
- else:
- print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url
- errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url)
- except:
- print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url
- errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url)
-
-def get_proof_by_index(baseurl, index, tree_size):
- try:
- params = urllib.urlencode({"leaf_index":index,
- "tree_size":tree_size})
- result = \
- urlopen(baseurl + "ct/v1/get-entry-and-proof?" + params).read()
- return json.loads(result)
- except urllib2.HTTPError, e:
- print "ERROR:", e.read()
- sys.exit(0)
+# root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, proof["leaf_index"], tmp_sth["tree_size"], leaf_hash))
+
+# if tmp_sth["sha256_root_hash"] == root:
+# return True
+# else:
+# print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(proof["leaf_index"]) + " in " + base_url
+# return False
+# except:
+# print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for hashed entry in " + base_url
+# return False
+
+# def verify_inclusion_by_index(base_url, index):
+# try:
+# tmp_sth = get_sth(base_url)
+# proof = get_proof_by_index(base_url, index, tmp_sth["tree_size"])
+
+# decoded_inclusion_proof = []
+# for item in proof["audit_path"]:
+# decoded_inclusion_proof.append(base64.b64decode(item))
+
+# root = base64.b64encode(verify_inclusion_proof(decoded_inclusion_proof, index, tmp_sth["tree_size"], get_leaf_hash(base64.b64decode(proof["leaf_input"]))))
+
+# if tmp_sth["sha256_root_hash"] == root:
+# print time.strftime('%H:%M:%S') + " Verifying inclusion for entry " + str(index) + " in " + base_url + "...OK."
+# else:
+# print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url
+# errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url)
+# except:
+# print time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url
+# errors.append(time.strftime('%H:%M:%S') + " ERROR: Could not prove inclusion for entry " + str(index) + " in " + base_url)
+
+# def get_proof_by_index(baseurl, index, tree_size):
+# try:
+# params = urllib.urlencode({"leaf_index":index,
+# "tree_size":tree_size})
+# result = \
+# urlopen(baseurl + "ct/v1/get-entry-and-proof?" + params).read()
+# return json.loads(result)
+# except urllib2.HTTPError, e:
+# print "ERROR:", e.read()
+# sys.exit(0)
def get_all_roots(base_url):
result = urlopen(base_url + "ct/v1/get-roots").read()
@@ -410,17 +392,18 @@ def main(args):
# Create logs
logs = []
try:
+ # Create log objects
for item in CONFIG.CTLOGS:
logs.append(ctlog(item["name"], item["url"], item["key"], item["id"], item["build"]))
-
print time.strftime('%H:%M:%S') + " Setting up monitor for " + str(len(logs)) + " logs..."
+
# Set up state
for log in logs:
if os.path.isfile(log.savefile):
log.load()
+
# Build new entries
for log in logs:
- # if log.build:
log.incremental_build()
# Main loop: Monitor
@@ -429,13 +412,11 @@ def main(args):
time.sleep(CONFIG.INTERVAL)
for log in logs:
log.update_roots()
-
old_sth = log.sth
log.update_sth() # Should this be done if later checks fail? (reorder?)
if old_sth["timestamp"] != log.sth["timestamp"]:
log.verify_progress(old_sth)
log.verify_consistency(old_sth)
- # if log.build:
log.incremental_build()
for md in monitored_domains:
@@ -467,7 +448,6 @@ def main(args):
open(CONFIG.DOMAINS_FILE, 'w').write(json.dumps(domain_dict))
-
if __name__ == '__main__':
if CONFIG.OUTPUT_DIR and not os.path.exists(CONFIG.OUTPUT_DIR):
os.makedirs(CONFIG.OUTPUT_DIR)
diff --git a/monitor/monitor_conf.py b/monitor/monitor_conf.py
index 61df927..ca7b254 100644
--- a/monitor/monitor_conf.py
+++ b/monitor/monitor_conf.py
@@ -28,6 +28,9 @@ MONITORED_DOMAINS = [
# "*.se",
]
+# Some strings
+ERROR_STR = "ERROR: "
+
# CT logs and associated keys
CTLOGS = [
{"name" : "pilot",
@@ -88,3 +91,4 @@ CTLOGS = [
+