diff options
author | erdgeist <> | 2012-05-28 15:26:13 +0000 |
---|---|---|
committer | erdgeist <> | 2012-05-28 15:26:13 +0000 |
commit | 37db5f94fadae6993585d447b4faa00cacca49a2 (patch) | |
tree | 2fb513d5440d5bad189576952bf477b37afec495 /ot_udp.c | |
parent | 3eeb536a44266a208a7287d4d5b57c56fd5d1c8a (diff) |
udp now generates a cryptographically secure token for connecting clients. This is later verified.
Diffstat (limited to 'ot_udp.c')
-rw-r--r-- | ot_udp.c | 61 |
1 files changed, 53 insertions, 8 deletions
@@ -18,15 +18,40 @@ | |||
18 | #include "trackerlogic.h" | 18 | #include "trackerlogic.h" |
19 | #include "ot_udp.h" | 19 | #include "ot_udp.h" |
20 | #include "ot_stats.h" | 20 | #include "ot_stats.h" |
21 | #include "ot_rijndael.h" | ||
21 | 22 | ||
22 | static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff }; | 23 | static const uint8_t g_static_connid[8] = { 0x23, 0x42, 0x05, 0x17, 0xde, 0x41, 0x50, 0xff }; |
24 | static uint32_t g_rijndael_round_key[44] = {0}; | ||
25 | static uint32_t g_key_of_the_hour[2] = {0}; | ||
26 | static ot_time g_hour_of_the_key; | ||
23 | 27 | ||
24 | static void udp_make_connectionid( uint32_t * connid, const ot_ip6 remoteip ) { | 28 | static void udp_generate_rijndael_round_key() { |
25 | /* Touch unused variable */ | 29 | uint8_t key[16]; |
26 | (void)remoteip; | 30 | key[0] = random(); key[1] = random(); key[2] = random(); key[3] = random(); |
31 | rijndaelKeySetupEnc128( g_rijndael_round_key, key ); | ||
27 | 32 | ||
28 | /* Use a static secret for now */ | 33 | g_key_of_the_hour[0] = random(); |
29 | memcpy( connid, g_static_connid, 8 ); | 34 | g_hour_of_the_key = g_now_minutes; |
35 | } | ||
36 | |||
37 | /* Generate current and previous connection id for ip */ | ||
38 | static void udp_make_connectionid( uint32_t connid[4], const ot_ip6 remoteip ) { | ||
39 | uint32_t plain[4], crypt[4]; | ||
40 | int age, i; | ||
41 | |||
42 | if( g_now_minutes + 60 > g_hour_of_the_key ) { | ||
43 | g_hour_of_the_key = g_now_minutes; | ||
44 | g_key_of_the_hour[1] = g_key_of_the_hour[0]; | ||
45 | g_key_of_the_hour[0] = random(); | ||
46 | } | ||
47 | |||
48 | for( age = 0; age < 1; ++age ) { | ||
49 | memcpy( plain, remoteip, sizeof( plain ) ); | ||
50 | for( i=0; i<4; ++i ) plain[i] ^= g_key_of_the_hour[age]; | ||
51 | rijndaelEncrypt128( g_rijndael_round_key, (uint8_t*)remoteip, (uint8_t*)crypt ); | ||
52 | connid[2*age ] = crypt[0] ^ crypt[1]; | ||
53 | connid[2*age+1] = crypt[2] ^ crypt[3]; | ||
54 | } | ||
30 | } | 55 | } |
31 | 56 | ||
32 | /* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */ | 57 | /* UDP implementation according to http://xbtt.sourceforge.net/udp_tracker_protocol.html */ |
@@ -35,6 +60,7 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { | |||
35 | uint32_t *inpacket = (uint32_t*)ws->inbuf; | 60 | uint32_t *inpacket = (uint32_t*)ws->inbuf; |
36 | uint32_t *outpacket = (uint32_t*)ws->outbuf; | 61 | uint32_t *outpacket = (uint32_t*)ws->outbuf; |
37 | uint32_t numwant, left, event, scopeid; | 62 | uint32_t numwant, left, event, scopeid; |
63 | uint32_t connid[4]; | ||
38 | uint16_t port, remoteport; | 64 | uint16_t port, remoteport; |
39 | size_t byte_count, scrape_count; | 65 | size_t byte_count, scrape_count; |
40 | 66 | ||
@@ -44,13 +70,29 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { | |||
44 | stats_issue_event( EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip ); | 70 | stats_issue_event( EVENT_ACCEPT, FLAG_UDP, (uintptr_t)remoteip ); |
45 | stats_issue_event( EVENT_READ, FLAG_UDP, byte_count ); | 71 | stats_issue_event( EVENT_READ, FLAG_UDP, byte_count ); |
46 | 72 | ||
73 | /* Minimum udp tracker packet size, also catches error */ | ||
74 | if( byte_count < 16 ) | ||
75 | return 1; | ||
76 | |||
77 | /* Generate the connection id we give out and expect to and from | ||
78 | the requesting ip address, this prevents udp spoofing */ | ||
79 | udp_make_connectionid( connid, remoteip ); | ||
80 | |||
47 | /* Initialise hash pointer */ | 81 | /* Initialise hash pointer */ |
48 | ws->hash = NULL; | 82 | ws->hash = NULL; |
49 | ws->peer_id = NULL; | 83 | ws->peer_id = NULL; |
50 | 84 | ||
51 | /* Minimum udp tracker packet size, also catches error */ | 85 | /* If action is not a ntohl(a) == a == 0, then we |
52 | if( byte_count < 16 ) | 86 | expect the derived connection id in first 64 bit */ |
87 | if( inpacket[2] && ( inpacket[0] != connid[0] || inpacket[1] != connid[1] ) && | ||
88 | ( inpacket[0] != connid[2] || inpacket[1] != connid[3] ) ) { | ||
89 | const size_t s = sizeof( "Connection ID missmatch." ); | ||
90 | outpacket[0] = 3; outpacket[1] = inpacket[3]; | ||
91 | memcpy( &outpacket[2], "Connection ID missmatch.", s ); | ||
92 | socket_send6( serversocket, ws->outbuf, 8 + s, remoteip, remoteport, 0 ); | ||
93 | stats_issue_event( EVENT_CONNID_MISSMATCH, FLAG_UDP, 8 + s ); | ||
53 | return 1; | 94 | return 1; |
95 | } | ||
54 | 96 | ||
55 | switch( ntohl( inpacket[2] ) ) { | 97 | switch( ntohl( inpacket[2] ) ) { |
56 | case 0: /* This is a connect action */ | 98 | case 0: /* This is a connect action */ |
@@ -60,7 +102,8 @@ int handle_udp6( int64 serversocket, struct ot_workstruct *ws ) { | |||
60 | 102 | ||
61 | outpacket[0] = 0; | 103 | outpacket[0] = 0; |
62 | outpacket[1] = inpacket[3]; | 104 | outpacket[1] = inpacket[3]; |
63 | udp_make_connectionid( outpacket + 2, remoteip ); | 105 | outpacket[2] = connid[0]; |
106 | outpacket[3] = connid[1]; | ||
64 | 107 | ||
65 | socket_send6( serversocket, ws->outbuf, 16, remoteip, remoteport, 0 ); | 108 | socket_send6( serversocket, ws->outbuf, 16, remoteip, remoteport, 0 ); |
66 | stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 ); | 109 | stats_issue_event( EVENT_CONNECT, FLAG_UDP, 16 ); |
@@ -146,6 +189,8 @@ static void* udp_worker( void * args ) { | |||
146 | 189 | ||
147 | void udp_init( int64 sock, unsigned int worker_count ) { | 190 | void udp_init( int64 sock, unsigned int worker_count ) { |
148 | pthread_t thread_id; | 191 | pthread_t thread_id; |
192 | if( !g_rijndael_round_key[0] ) | ||
193 | udp_generate_rijndael_round_key(); | ||
149 | #ifdef _DEBUG | 194 | #ifdef _DEBUG |
150 | fprintf( stderr, " installing %d workers on udp socket %ld", worker_count, (unsigned long)sock ); | 195 | fprintf( stderr, " installing %d workers on udp socket %ld", worker_count, (unsigned long)sock ); |
151 | #endif | 196 | #endif |