Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/rainbow/permissions/permlist.py
blob: 897beca376e9b976d78af5e04c05ca90b7a0cc8d (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
DOMAINS = {'network': ('via', 'to', 'port', 'rate', 'burst', 'connection-rate',
                       'transfer-limit', 'bind-port'),
          'constant-uid': (),
          'strace': (),
          'use-audio': (),
          'use-video': (),
          'use-serial': (),
          'play-background-sound': (),
          'quota': ('limit'),
          'lim_nofile': ('@NUM@'),
          'lim_mem': ('@NUM@'),
          'lim_nproc': ('@NUM@'),
          'lim_fsize': ('@NUM@'),
          'document_read_ro': ('type')
          }

class PermissionSet(object):
    def __init__(self, fp=None):
        self._permissions = {}
        self._network_permissions = []

        for line in fp:
            line = line.lower().strip()
            if not line or line.startswith('#'):
                continue

            fields = line.split()
            if not fields[0] in DOMAINS:
                print "Unknown permissions domain: [%s]" % fields[0]
                continue

            for field in fields[1:]:
                if '@NUM@' in DOMAINS[fields[0]]:
                    try:
                        float(fields[1])
                    except:
                        print "Expecting numeric value in domain [%s] (%s)" % (fields[0], fields[1])
                        continue
                else:
                    key, value = field.split(':')
                    if not key in DOMAINS[fields[0]]:
                        print "Unknown flag [%s] in domain [%s]" % (key, fields[0])
                        continue

            if fields[0] == 'network':
                self._network_permissions.append(fields[1:])
            else:
                self._permissions[fields[0]] = fields[1:] or True

    def has_permission(self, domain, key=None, value=None):
        "Fails for network, since it doesn't make sense to query those perms"
        if domain not in self._permissions:
            return False
        elif key and value:
            for permission in self._permissions[domain]:
                this_key, these_values = permission.split(':')
                if not key == this_key:
                    continue
                these_values = these_values.split(',')
                if value in these_values:
                    return True
        return self._permissions[domain] == True

    def permission_params(self, domain):
        if domain not in self._permissions:
            return None
        return(self._permissions[domain])


if __name__ == '__main__':
    import cStringIO as stringio
    from pprint import pprint

    perms = """
    network via:ipv4,ipv6 to:pgp.mit.edu,laptop.org port:80 rate:100Kb/s burst:1Mb
    network via:ipv4 port:25 connection-rate:10/min transfer-limit:8Mb/hr
    network via:ipv6 bind-port:1400

    # Comment
    use-microphone
    use-camera

    # Comment, yay
    play-background-sound

    document_read_ro type:text/plain

    quota limit:15Mb
    """

    permfp = stringio.StringIO(perms)
    permset = PermissionSet(permfp)
    pprint(permset._permissions)
    pprint(permset._network_permissions)