#!/usr/bin/python # -*- coding: utf-8 -*- import sys from josef_lib import * import leveldb SEP = ";" # db = None def match_domain(d1, d2): # print d1, d2 # Exact match if d1 == d2: return True # Wildcard match d1l = d1.split('.') d2l = d2.split('.') if d1l[0] == '*': # print d1l[1:], d2l[-(len(d1l)-1):] if d1l[1:] == d2l[-(len(d1l)-1):]: return True if d2l[0] == '*': # print d2l[1:], d1l[-(len(d2l)-1):] 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): 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) db.Put(key,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) db_append(db, k, data) def db_add_certs(db, data): if db is None: print "ERROR: NO DATABASE SET!" return # print data, type(data) # batch = leveldb.WriteBatch() 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: # # print "Failed adding SAN in " + str(cert) # pass # db.Write(batch, sync = True) 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