-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathABSSentinel.py
180 lines (155 loc) · 5.51 KB
/
ABSSentinel.py
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
from scapy.all import *
from netfilterqueue import NetfilterQueue
import sys
from multiprocessing import Process, Manager
from MathABS import ABS
from charm.toolbox.pairinggroup import PairingGroup
import socketserver
import socket
import json
import threading
from charm.toolbox.securerandom import OpenSSLRand
from ABSSetup import safety_addons_list, default_addons_list
def decider_of_fate(host,unknown,pkt):
'''
Checks whether the packet info has been previously approved and adds to
checklist if not
'''
port = clientlist[host]
clientiplist = iplist[host]
if unknown in clientiplist:
pkt.accept()
else:
triple = (host,port,unknown)
if triple not in checklist:
print('FIREWALL: unknown source/destination',unknown)
checklist.append(triple)
else:
pkt.drop()
def print_and_accept(pkt):
'''
Firewall packet decider framework
Lets uninteresting (non-HTTP, not marked to any client) packets through
'''
a = IP(pkt.get_payload())
if a[IP][TCP].dport == 80:
source,dest = a[IP].src, a[IP].dst
host = 0
try:
decider_of_fate(networkalias[source],dest,pkt)
except KeyError:
try:
decider_of_fate(networkalias[dest],source,pkt)
except KeyError:
pkt.accept()
else:
pkt.accept()
def FWsubprocess():
'''
Almost dummy subprocess for the firewall binding
'''
try:
nfqueue = NetfilterQueue()
nfqueue.bind(0,print_and_accept)
nfqueue.run()
except KeyboardInterrupt:
nfqueue.unbind()
class MyTCPHandler(socketserver.BaseRequestHandler):
'''
Key request service that decides the client's attributes based on the
predefined "default" and "secure" addon lists
'''
def handle(self):
try:
self.data = self.request.recv(hugeness).strip()
msg = self.data.decode('utf-8')
host,port = self.client_address[0],self.client_address[1]
print('SERVER: received from {}:{} list'.format(host,port),msg)
content = msg.split(",")
netalias = content[0]
addons = set(content[1:])
attributes = []
if addons == default_addons:
attributes.append('DEFAULTSONLY')
else:
attributes.append('UNKNOWNADDONS')
if safety_addons.issubset(addons):
attributes.append('SAFETYADDONSENABLED')
ska = absinst.generateattributes(ask,attributes)
striple = (absinst.encodestr(tpk),absinst.encodestr(apk),absinst.encodestr(ska))
clientlist[host] = port
networkalias[netalias] = host
iplist[host] = valuemanager.list()
print('SERVER: keys for {} sent, client {}:{} added to lists with netalias {}'.format(attributes,host,port, netalias))
self.request.sendall(bytes(json.dumps(striple),'utf8'))
except Exception as err:
print('SERVER: MISERABLE FAILURE:',err)
class ThreadedTCPServer(socketserver.ThreadingMixIn,socketserver.TCPServer):
pass
def checkprotocol(host,port):
'''
"Watchdog" runs every time there's an unknown in the list
This is what enforces the policy
'''
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host,int(port)))
print('WATCHDOG: Connected to client {}:{}'.format(host,port))
nonce = str(OpenSSLRand().getRandomBytes(20))[2:].replace("\\x","")
stuple = (nonce,accesspolicy)
sock.sendall(bytes(json.dumps(stuple),'utf8'))
print('WATCHDOG: Sent nonce {} and policy {}'.format(nonce,accesspolicy))
data = sock.recv(hugeness).strip()
msg = data.decode('utf-8')
signature = absinst.decodestr(msg)
judgement = absinst.verify((tpk,apk),signature,nonce,accesspolicy)
sock.sendall(bytes(str(judgement),'utf-8'))
print('WATCHDOG: Sent judgement', judgement)
return judgement
except Exception as err:
print(err)
return False
sock.close()
try:
attributes = [
'DEFAULTSONLY',
'UNKNOWNADDONS',
'SAFETYADDONSENABLED',
]
accesspolicy = '(UNKNOWNADDONS AND SAFETYADDONSENABLED) OR DEFAULTSONLY'
valuemanager = Manager()
iplist = valuemanager.dict()
clientlist = valuemanager.dict()
networkalias = valuemanager.dict()
checklist = valuemanager.list()
print('\nDEFAULT ADDONS:')
for i in default_addons_list:
print('\t',i)
print('\n\'SAFE\' ADDONS:')
for i in safety_addons_list:
print('\t',i)
default_addons = set(default_addons_list)
safety_addons = set(safety_addons_list)
group = PairingGroup('SS512')
absinst = ABS(group)
tpk = absinst.trusteesetup(attributes)
ask,apk = absinst.authoritysetup(tpk)
fwp = Process(target = FWsubprocess)
fwp.start()
print('\nFIREWALL: READY')
hugeness = 8000
host,port = 'localhost',0
server = ThreadedTCPServer((host,port),MyTCPHandler)
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
print('SERVER: READY, port',server.server_address[1])
while True:
if len(checklist)>0:
host,port,ip = checklist.pop(0)
if checkprotocol(host,port):
print('WATCHDOG: ADDED',ip,'TO IPLIST')
iplist[host].append(ip)
except KeyboardInterrupt:
fwp.join()
server.shutdown()