#!/usr/bin/python # -*- coding: utf-8 -*- import sys from josef_lib import * import leveldb SEP = ";" # db = None def match_domain(d1, d2): # Exact match if d1 == 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'): db = leveldb.LevelDB(fn) return db def db_append(db, key, val): # print "Appending " + val if db is None: print "ERROR: NO DATABASE SET!" return try: tmp = db.Get(key) except KeyError: tmp = "" # print "Key: ", key, "Val: ", val, "Found: ", tmp tmpl = tmp.split(SEP) if val in tmpl: pass else: # print tmpl tmpl.append(val) # print tmpl db.Put(key,SEP.join(tmpl)) # print "Storing " + SEP.join(tmpl) def db_add_domain(db, domain, data): if db is None: print "ERROR: NO DATABASE SET!" return tmpl = domain.split('.') k = "" for item in reversed(tmpl): if k == "": next_k = item else: next_k = item + '.' + k db_append(db, k, next_k) k = next_k # db.Delete(k) # print "Got ", db.Get(k) # print "Put-ing", data db_append(db, k, data) # print "Got ", db.Get(k) def db_add_certs(db, data): if db is None: print "ERROR: NO DATABASE SET!" return for cert in data: try: db_add_domain(db, cert["subject"].split("CN=")[1], str(cert)) except IndexError: pass try: for line in cert["SAN"].split("DNS:")[1:]: db_add_domain(db, line, str(cert)) except KeyError: pass except IndexError: pass def db_lookup_domain(db, domain): domain_list = domain.split('.') res = [] cur_domain = domain_list.pop() intermediate = db.Get(cur_domain).split(SEP) while True: try: intermediate.remove("") except ValueError: pass try: cur_domain = domain_list.pop() + "." + cur_domain except IndexError: return res # Prune next_level = [] for item in intermediate: if match_domain(cur_domain, item): # print item try: tmp = db.Get(item) if tmp[1] == '{': res.append(tmp[1:]) next_level += tmp.split(SEP) except KeyError: # print "Could not find " + item pass else: intermediate.remove(item) intermediate = next_level return res