#!/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): 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_2(db, key, val): if db is None: print "ERROR: NO DATABASE SET!" return try: tmp = db.Get(key) tmpl = tmp.split(SEP) if val in tmpl: return else: tmpl.append(val) db.Put(key,SEP.join(tmpl)) except KeyError: db.Put(key,SEP.join([val])) new_key = key.split('.',1)[-1] if new_key != key: db_add_domain_2(db,new_key,key) 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_append(db, k, data) def db_add_certs(db, data): if db is None: print "ERROR: NO DATABASE SET!" return for cert in data: try: db_add_domain_2(db, cert["subject"].split("CN=")[1], str(cert)) except IndexError: pass try: for line in cert["SAN"].split("DNS:")[1:]: db_add_domain_2(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) last = False one_more = False while True: try: intermediate.remove("") except ValueError: pass try: cur_domain = domain_list.pop() + "." + cur_domain except IndexError: return res # Prune next_level = [] # print intermediate for item in intermediate: if match_domain(cur_domain, item): try: tmp = db.Get(item).split(SEP) for tmp_item in tmp: if tmp_item[0] == '{': res.append(tmp_item) else: next_level.append(tmp_item) except KeyError: pass intermediate = next_level return res