File crap.py changed (mode: 100755) (index f49eed7..99a0c93) |
1 |
1 |
#!/usr/bin/python3 |
#!/usr/bin/python3 |
2 |
2 |
|
|
3 |
3 |
import datetime |
import datetime |
4 |
|
import socket |
|
5 |
4 |
import time |
import time |
6 |
5 |
|
|
7 |
6 |
from identity import Identity |
from identity import Identity |
|
... |
... |
if __name__ == "__main__": |
15 |
14 |
print("toxid", identity.get_printable_public_key()) |
print("toxid", identity.get_printable_public_key()) |
16 |
15 |
|
|
17 |
16 |
#relay = TcpRelay("biribiri.org", 3389, "F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67") |
#relay = TcpRelay("biribiri.org", 3389, "F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67") |
18 |
|
relay = TcpRelay("localhost", 4443, "53DE181BF5AC9A62AFF790ACAD604822246881E4BB4A02A2C63BED426E14FA20") |
|
|
17 |
|
relay = TcpRelay("localhost", 4443, "926496D61E73EB2DC2987A1DC2096D3A1DA59F4B7D2530665B4E93E27C5DDC11") |
19 |
18 |
packet = relay.get_client_hello_packet(session, identity) |
packet = relay.get_client_hello_packet(session, identity) |
20 |
19 |
|
|
21 |
|
s = socket.socket() |
|
22 |
|
s.connect((relay.hostname, relay.port)) |
|
|
20 |
|
relay.connect() |
23 |
21 |
print("connected") |
print("connected") |
24 |
22 |
|
|
25 |
|
packet.send(s) |
|
26 |
|
|
|
27 |
|
received = s.recv(4096) |
|
28 |
|
packet = TcpServerHelloPacket() |
|
29 |
|
packet.parse(received) |
|
30 |
|
packet.decrypt_payload(relay, session) |
|
31 |
|
print ("relay key", h(packet.relay_public_key)) |
|
32 |
|
print ("base nonce", h(packet.base_nonce)) |
|
33 |
|
relay.set_incoming_nonce(packet.base_nonce) |
|
34 |
|
relay.set_outgoing_public_key(packet.relay_public_key) |
|
|
23 |
|
relay.negotiate_forward_secret_keys(session, identity) |
35 |
24 |
|
|
36 |
25 |
def on_ping_recvd(packet): |
def on_ping_recvd(packet): |
37 |
|
print ("PING RECEIVED!", packet) |
|
|
26 |
|
print ("<<< PING", packet) |
|
27 |
|
def on_pong_recvd(packet): |
|
28 |
|
print ("<<< PONG", packet) |
38 |
29 |
|
|
39 |
30 |
TcpPingPacket.register_listener(on_ping_recvd) |
TcpPingPacket.register_listener(on_ping_recvd) |
|
31 |
|
TcpPongPacket.register_listener(on_pong_recvd) |
40 |
32 |
|
|
41 |
33 |
ping = TcpPingPacket(relay=relay) |
ping = TcpPingPacket(relay=relay) |
42 |
|
ping.send(s) |
|
43 |
|
|
|
44 |
|
s.setblocking(0) |
|
|
34 |
|
ping.send() |
45 |
35 |
|
|
46 |
|
incoming_stream_handler = IncomingStreamHandler(s, relay) |
|
|
36 |
|
tick = 0 |
|
37 |
|
incoming_stream_handler = IncomingStreamHandler(relay) |
47 |
38 |
while True: |
while True: |
48 |
39 |
received_packets = incoming_stream_handler.tick() |
received_packets = incoming_stream_handler.tick() |
49 |
40 |
if received_packets: |
if received_packets: |
50 |
41 |
print (datetime.datetime.now().isoformat(), received_packets) |
print (datetime.datetime.now().isoformat(), received_packets) |
51 |
42 |
time.sleep(0.1) |
time.sleep(0.1) |
|
43 |
|
tick += 1 |
52 |
44 |
|
|
53 |
|
pong = TcpPongPacket(relay) |
|
54 |
|
pong.parse(s.recv(4096)[2:]) # todo: parse length header |
|
|
45 |
|
if tick % 30 == 0: |
|
46 |
|
print (">>> PING") |
|
47 |
|
ping = TcpPingPacket(relay=relay) |
|
48 |
|
ping.send() |
55 |
49 |
|
|
56 |
50 |
s.close() |
s.close() |
File tcp.py changed (mode: 100644) (index 855dc0f..0b4efe4) |
2 |
2 |
|
|
3 |
3 |
import binascii |
import binascii |
4 |
4 |
import select |
import select |
|
5 |
|
import socket |
5 |
6 |
import struct |
import struct |
6 |
7 |
import nacl.bindings |
import nacl.bindings |
7 |
8 |
import nacl.utils |
import nacl.utils |
|
... |
... |
class TcpPacket: |
31 |
32 |
def __init__(self): |
def __init__(self): |
32 |
33 |
self.bytes = b"" |
self.bytes = b"" |
33 |
34 |
|
|
34 |
|
def send(self, socket): |
|
|
35 |
|
def send(self, socket=None): |
35 |
36 |
""" |
""" |
36 |
37 |
Serialize and send packet via socket |
Serialize and send packet via socket |
37 |
38 |
""" |
""" |
38 |
39 |
serialized_b = self.serialize() |
serialized_b = self.serialize() |
39 |
40 |
print(binascii.hexlify(serialized_b)) |
print(binascii.hexlify(serialized_b)) |
|
41 |
|
if socket is None: |
|
42 |
|
socket = self.relay.get_socket() |
40 |
43 |
socket.send(serialized_b) |
socket.send(serialized_b) |
41 |
44 |
print ("sent %d bytes" % len(serialized_b)) |
print ("sent %d bytes" % len(serialized_b)) |
42 |
45 |
|
|
|
... |
... |
class TcpPongPacket(EncryptedPacket): |
127 |
130 |
|
|
128 |
131 |
def __repr__(self): |
def __repr__(self): |
129 |
132 |
return "<TcpPongPacket(%s)>" % self.pong_message |
return "<TcpPongPacket(%s)>" % self.pong_message |
|
133 |
|
|
|
134 |
|
class TcpRoutingRequestPacket(EncryptedPacket): |
|
135 |
|
""" |
|
136 |
|
Routing request (0x00) |
|
137 |
|
""" |
|
138 |
|
packet_id = 0x00 |
|
139 |
|
def __init__(self, relay=None): |
|
140 |
|
super().__init__(relay) |
130 |
141 |
|
|
131 |
142 |
|
|
132 |
143 |
class TcpClientHelloPacket(TcpPacket): |
class TcpClientHelloPacket(TcpPacket): |
|
... |
... |
class TcpClientHelloPacket(TcpPacket): |
142 |
153 |
self.bytes += self.nonce |
self.bytes += self.nonce |
143 |
154 |
self.bytes += self.get_payload(relay, session, identity) |
self.bytes += self.get_payload(relay, session, identity) |
144 |
155 |
|
|
|
156 |
|
self.relay = relay |
|
157 |
|
|
145 |
158 |
def get_payload(self, relay, session, identity): |
def get_payload(self, relay, session, identity): |
146 |
159 |
payload = bytes(relay.get_incoming_public_key()) |
payload = bytes(relay.get_incoming_public_key()) |
147 |
160 |
payload += bytes(relay.get_outgoing_nonce_without_incrementing()) |
payload += bytes(relay.get_outgoing_nonce_without_incrementing()) |
|
... |
... |
class TcpRelay: |
201 |
214 |
# a temporary public key tied to this connection |
# a temporary public key tied to this connection |
202 |
215 |
self.outgoing_public_key = None |
self.outgoing_public_key = None |
203 |
216 |
|
|
|
217 |
|
# The socked used to connect to this relay |
|
218 |
|
self._socket = None |
|
219 |
|
|
|
220 |
|
def connect(self): |
|
221 |
|
""" |
|
222 |
|
Establish a TCP connection |
|
223 |
|
""" |
|
224 |
|
self._socket = socket.socket() |
|
225 |
|
self._socket.connect((self.hostname, self.port)) |
|
226 |
|
return self._socket |
|
227 |
|
|
|
228 |
|
def get_socket(self): |
|
229 |
|
""" |
|
230 |
|
Return a socket to TCP relay, connect if necessary |
|
231 |
|
""" |
|
232 |
|
if self._socket is not None: |
|
233 |
|
return self._socket |
|
234 |
|
return self.connect() |
|
235 |
|
|
204 |
236 |
def get_client_hello_packet(self, session, identity): |
def get_client_hello_packet(self, session, identity): |
205 |
237 |
return TcpClientHelloPacket(self, session, identity) |
return TcpClientHelloPacket(self, session, identity) |
206 |
238 |
|
|
207 |
239 |
def get_incoming_nonce(self): |
def get_incoming_nonce(self): |
|
240 |
|
""" |
|
241 |
|
Return nonce for decrypting incoming packets (TCP relay -> me), incrementing the nonce |
|
242 |
|
""" |
208 |
243 |
nonce = self.tcp_incoming_nonce |
nonce = self.tcp_incoming_nonce |
209 |
244 |
self.increment_incoming_nonce() |
self.increment_incoming_nonce() |
210 |
245 |
return nonce |
return nonce |
|
... |
... |
class TcpRelay: |
219 |
254 |
return self.private_key |
return self.private_key |
220 |
255 |
|
|
221 |
256 |
def get_dht_public_key(self): |
def get_dht_public_key(self): |
|
257 |
|
""" |
|
258 |
|
Return relay's DHT public key |
|
259 |
|
""" |
222 |
260 |
return self.dht_public_key |
return self.dht_public_key |
223 |
261 |
|
|
224 |
262 |
def set_incoming_nonce(self, nonce): |
def set_incoming_nonce(self, nonce): |
225 |
263 |
self.tcp_incoming_nonce = nonce |
self.tcp_incoming_nonce = nonce |
226 |
264 |
|
|
227 |
265 |
def set_outgoing_public_key(self, key): |
def set_outgoing_public_key(self, key): |
|
266 |
|
""" |
|
267 |
|
Set the ephemeral relay's public key with which this connection is encrypted |
|
268 |
|
""" |
228 |
269 |
self.tcp_outgoing_public_key = PublicKey(key) |
self.tcp_outgoing_public_key = PublicKey(key) |
229 |
270 |
|
|
230 |
271 |
def get_outgoing_nonce(self): |
def get_outgoing_nonce(self): |
|
272 |
|
""" |
|
273 |
|
Return the nonce used for encrypting outgoing packets (me -> TCP relay) |
|
274 |
|
Increments the nonce. |
|
275 |
|
""" |
231 |
276 |
rv = self.tcp_outgoing_nonce |
rv = self.tcp_outgoing_nonce |
232 |
277 |
self.increment_outgoing_nonce() |
self.increment_outgoing_nonce() |
233 |
278 |
return rv |
return rv |
|
... |
... |
class TcpRelay: |
241 |
286 |
def get_outgoing_public_key(self): |
def get_outgoing_public_key(self): |
242 |
287 |
return self.tcp_outgoing_public_key |
return self.tcp_outgoing_public_key |
243 |
288 |
|
|
|
289 |
|
def negotiate_forward_secret_keys(self, session, identity): |
|
290 |
|
""" |
|
291 |
|
Given our session (DHT key) and identity (long term key), send |
|
292 |
|
hello packets to the TCP relay and agree on nonce and ephemeral |
|
293 |
|
keys. |
|
294 |
|
This is a high-level function. |
|
295 |
|
""" |
|
296 |
|
hello_packet = self.get_client_hello_packet(session, identity) |
|
297 |
|
hello_packet.send() |
|
298 |
|
|
|
299 |
|
sock = self.get_socket() |
|
300 |
|
received = sock.recv(4096) |
|
301 |
|
|
|
302 |
|
packet = TcpServerHelloPacket() |
|
303 |
|
packet.parse(received) |
|
304 |
|
packet.decrypt_payload(self, session) |
|
305 |
|
print ("relay key", h(packet.relay_public_key)) |
|
306 |
|
print ("base nonce", h(packet.base_nonce)) |
|
307 |
|
self.set_incoming_nonce(packet.base_nonce) |
|
308 |
|
self.set_outgoing_public_key(packet.relay_public_key) |
|
309 |
|
self._socket.setblocking(0) |
|
310 |
|
|
244 |
311 |
class IncomingStreamHandler: |
class IncomingStreamHandler: |
245 |
312 |
""" |
""" |
246 |
313 |
Split incoming TCP stream into packets |
Split incoming TCP stream into packets |
247 |
314 |
""" |
""" |
248 |
|
def __init__(self, sock, relay): |
|
|
315 |
|
def __init__(self, relay): |
249 |
316 |
""" |
""" |
250 |
317 |
sock - tcp socket to read from |
sock - tcp socket to read from |
251 |
318 |
relay - TcpRelay instance needed for decryption |
relay - TcpRelay instance needed for decryption |
252 |
319 |
""" |
""" |
253 |
|
self.socket = sock |
|
254 |
320 |
self.relay = relay |
self.relay = relay |
|
321 |
|
self.socket = relay.get_socket() |
255 |
322 |
self.buf = b"" |
self.buf = b"" |
256 |
323 |
self.packet_types = {} |
self.packet_types = {} |
257 |
324 |
self.build_packet_types_table() |
self.build_packet_types_table() |