#!/usr/bin/python # -*- coding: utf-8 -*- import sys from josef_lib import * import leveldb SEP = ";" # db = None dbs = {} 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'): global dbs if fn in dbs: return dbs[fn] else: print "Opening " + fn db = leveldb.LevelDB(fn) dbs[fn] = db 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_dir, key_in, val, db_in=None): if db_in == None: 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") # key = '.'.join(key_list) # db = db_open(db_dir + key_list[-1]) # key = '.'.join(key_list) # db = db_open(db_dir) # print "DB: " + db_dir + key_list[-1] else: db = db_in key = key_in # print "key: ", key, " val: ", val 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, db) 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_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 = [] db = db_open(db_dir + domain_list[-1]) domain_list = domain_list[:-1] cur_domain = domain_list.pop() # print cur_domain 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