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 | |
| parent | 3eeb536a44266a208a7287d4d5b57c56fd5d1c8a (diff) | |
udp now generates a cryptographically secure token for connecting clients. This is later verified.
| -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 |
