summaryrefslogtreecommitdiff
path: root/monitor/josef_leveldb.py
blob: 9557bb23a6d2b2dece767293feefc2ac411f66f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/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