#!/usr/bin/python # -*- coding: utf-8 -*- import sys from josef_lib import * import leveldb import ast SEP = ";" dbs = {} def match_domain(d1, d2): # Exact match if str(d1) == str(d2): return True # Wildcard match d1l = d1.split('.') d2l = d2.split('.') if d1l[0] == '*': if d1l[1:] == d2l[-(len(d1l)-1):]: return True if d2l[0] == '*': if d2l[1:] == d1l[-(len(d2l)-1):]: return True # No match return False def db_open(fn='./cert_db'): global dbs if fn in dbs: return dbs[fn] else: db = leveldb.LevelDB(fn) dbs[fn] = db return db def db_close(): for db in dbs: del db def db_append(db, key, val): if db is None: print "ERROR: NO DATABASE SET!" return try: tmp = db.Get(key) except KeyError: tmp = "" tmpl = tmp.split(SEP) if val in tmpl: pass else: tmpl.append(val) # print "Storing:",key,SEP.join(tmpl) db.Put(key,SEP.join(tmpl)) def db_add_domain_2(db_dir, key_in, val_in, db_in=None): if db_in == None: val = "###" + ast.literal_eval(val_in)["leaf_hash"] cert_db = db_open(db_dir + "certificates") # print "Storing: ",val,val_in cert_db.Put(val, val_in) key_list = key_in.split('/')[0].split(',')[0].split('.') if key_list[-1] == "com": key = '.'.join(key_list[:-1]) db = db_open(db_dir + key_list[-1]) else: key = '.'.join(key_list) db = db_open(db_dir + "other") else: db = db_in key = key_in val = val_in try: tmp = db.Get(key) tmpl = tmp.split(SEP) if val in tmpl: return else: tmpl.append(val) # print "Storing: ",key,SEP.join(tmpl) db.Put(key,SEP.join(tmpl)) except KeyError: # print "Storing: ",key,SEP.join([val]) db.Put(key,SEP.join([val])) new_key = key.split('.',1)[-1] if new_key != key: db_add_domain_2(db_dir,new_key,key, db) def db_add_certs(db_dir, data): if db_dir is None: print "ERROR: NO DATABASE SET!" return for cert in data: try: db_add_domain_2(db_dir, cert["subject"].split("CN=")[1], str(cert)) except IndexError: pass try: for line in cert["SAN"].split("DNS:")[1:]: db_add_domain_2(db_dir, line, str(cert)) except KeyError: pass except IndexError: pass def db_lookup_domain(db_dir, domain): domain_list = domain.split('.') res = [] if domain_list[-1] == "com": db = db_open(db_dir + domain_list[-1]) domain_list = domain_list[:-1] key = '.'.join(domain_list) else: key = '.'.join(domain) db = db_open(db_dir + "other") cur_domain = domain_list.pop() try: intermediate = db.Get(cur_domain).split(SEP) except KeyError: return [] last = False one_more = False while True: try: intermediate.remove("") except ValueError: pass try: cur_domain = domain_list.pop() + "." + cur_domain except IndexError: break # Prune next_level = [] for item in intermediate: if match_domain(cur_domain, item): try: tmp = db.Get(item).split(SEP) for tmp_item in tmp: # This is really not a good solution... if tmp_item[0:3] == "###": res.append(tmp_item[3:]) else: next_level.append(tmp_item) except KeyError: pass intermediate = next_level certs = [] cert_db = db_open(db_dir + "certificates") for item in res: tmp = cert_db.Get("###" + str(item)) certs.append(tmp) return certs