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)
|