Changeset 3101 for branches/encryption/libtransmission/handshake.c
- Timestamp:
- Sep 20, 2007, 4:11:09 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/encryption/libtransmission/handshake.c
r3079 r3101 44 44 #define HANDSHAKE_SIZE 68 45 45 46 /*** 47 **** 48 ***/ 49 50 enum 51 { 52 HANDSHAKE_EXTPREF_LTEP_FORCE = 0x0, 53 HANDSHAKE_EXTPREF_LTEP_PREFER = 0x1, 54 HANDSHAKE_EXTPREF_AZMP_PREFER = 0x2, 55 HANDSHAKE_EXTPREF_AZMP_FORCE = 0x3 56 }; 57 58 46 59 #ifdef ENABLE_LTEP 47 #define HANDSHAKE_HAS_EXTMSGS( bits ) ( ( bits)[5] & 0x10 )48 #define HANDSHAKE_SET_EXTMSGS( bits ) ( ( bits)[5] |= 0x10 )60 #define HANDSHAKE_HAS_EXTMSGS( bits ) ( ( (bits)[5] & 0x10 ) ? 1 : 0 ) 61 #define HANDSHAKE_SET_EXTMSGS( bits ) ( ( (bits)[5] |= 0x10 ) ? 1 : 0 ) 49 62 #else 50 63 #define HANDSHAKE_HAS_EXTMSGS( bits ) ( 0 ) … … 53 66 54 67 #ifdef ENABLE_AZMP 55 #define HANDSHAKE_HAS_AZPROTO( bits ) ( ( bits)[0] & 0x80 )56 #define HANDSHAKE_SET_AZPROTO( bits ) ( ( bits)[0] |= 0x80 )68 #define HANDSHAKE_HAS_AZPROTO( bits ) ( ( (bits)[0] & 0x80 ) ? 1 : 0 ) 69 #define HANDSHAKE_SET_AZPROTO( bits ) ( ( (bits)[0] |= 0x80 ) ? 1 : 0 ) 57 70 #else 58 71 #define HANDSHAKE_HAS_AZPROTO( bits ) ( 0 ) … … 70 83 #define HANDSHAKE_EXTPREF_AZMP_FORCE ( 0x3 ) 71 84 85 enum 86 { 87 PadA_MAXLEN = 512, 88 PadB_MAXLEN = 512, 89 PadC_MAXLEN = 512, 90 PadD_MAXLEN = 512 91 }; 92 72 93 extern const char* getPeerId( void ) ; 73 94 … … 77 98 struct tr_handshake 78 99 { 79 unsigned int peerSupportsEncryption : 1; 80 unsigned int havePeerID : 1; 100 unsigned int peerSupportsEncryption : 1; 101 unsigned int havePeerID : 1; 102 unsigned int haveSentBitTorrentHandshake : 1; 103 unsigned int shunUnencryptedPeers : 1; 81 104 tr_peerIo * io; 82 105 tr_crypto * crypto; … … 85 108 uint8_t mySecret[96]; 86 109 uint8_t state; 87 uint8_t encryptionPreference;88 110 uint16_t pad_c_len; 89 111 uint16_t pad_d_len; … … 96 118 }; 97 119 98 static void99 fireDoneCB( tr_handshake * handshake, int isConnected );100 101 120 /** 102 121 *** 103 122 **/ 104 123 105 enum /*ccc*/124 enum 106 125 { 107 126 /* incoming */ … … 123 142 *** 124 143 **/ 144 145 static void 146 myDebug( const char * file, int line, const tr_handshake * handshake, const char * fmt, ... ) 147 { 148 va_list args; 149 const char * addr = tr_peerIoGetAddrStr( handshake->io ); 150 struct evbuffer * buf = evbuffer_new( ); 151 evbuffer_add_printf( buf, "[%s:%d] %s (%p) ", file, line, addr, handshake ); 152 va_start( args, fmt ); 153 evbuffer_add_vprintf( buf, fmt, args ); 154 va_end( args ); 155 156 fprintf( stderr, "%s\n", EVBUFFER_DATA(buf) ); 157 158 evbuffer_free( buf ); 159 } 160 161 #define dbgmsg(handshake, fmt...) myDebug(__FILE__, __LINE__, handshake, ##fmt ) 125 162 126 163 static const char* getStateName( short state ) … … 141 178 case AWAITING_CRYPTO_SELECT: str = "awaiting crypto select"; break; 142 179 case AWAITING_PAD_D: str = "awaiting pad d"; break; 143 //case SENDING_ PLAINTEXT_HANDSHAKE: str = "sending plaintext handshake"; break;180 //case SENDING_NONE: str = "sending plaintext handshake"; break; 144 181 } 145 182 return str; … … 149 186 setState( tr_handshake * handshake, short state ) 150 187 { 151 fprintf( stderr, "handshake %p: setting to state [%s]\n", handshake, getStateName(state) );188 dbgmsg( handshake, "setting to state [%s]", getStateName(state) ); 152 189 handshake->state = state; 153 190 } … … 160 197 } 161 198 199 static uint8_t * 200 buildHandshakeMessage( tr_handshake * handshake, 201 int extensionPreference, 202 int * setme_len ) 203 { 204 uint8_t * buf = tr_new0( uint8_t, HANDSHAKE_SIZE ); 205 uint8_t * walk = buf; 206 const uint8_t * torrentHash = tr_cryptoGetTorrentHash( handshake->crypto ); 207 208 memcpy( walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN ); 209 walk += HANDSHAKE_NAME_LEN; 210 memset( walk, 0, HANDSHAKE_FLAGS_LEN ); 211 switch( extensionPreference ) 212 { 213 case HANDSHAKE_EXTPREF_LTEP_FORCE: 214 HANDSHAKE_SET_EXTMSGS( walk ); 215 HANDSHAKE_SET_EXTPREF( walk, extensionPreference ); 216 break; 217 218 case HANDSHAKE_EXTPREF_LTEP_PREFER: 219 HANDSHAKE_SET_EXTMSGS( walk ); 220 HANDSHAKE_SET_AZPROTO( walk ); 221 HANDSHAKE_SET_EXTPREF( walk, extensionPreference ); 222 break; 223 224 case HANDSHAKE_EXTPREF_AZMP_PREFER: 225 HANDSHAKE_SET_EXTMSGS( walk ); 226 HANDSHAKE_SET_AZPROTO( walk ); 227 HANDSHAKE_SET_EXTPREF( walk, extensionPreference ); 228 break; 229 230 case HANDSHAKE_EXTPREF_AZMP_FORCE: 231 HANDSHAKE_SET_AZPROTO( walk ); 232 HANDSHAKE_SET_EXTPREF( walk, extensionPreference ); 233 break; 234 } 235 236 walk += HANDSHAKE_FLAGS_LEN; 237 memcpy( walk, torrentHash, SHA_DIGEST_LENGTH ); 238 walk += SHA_DIGEST_LENGTH; 239 memcpy( walk, getPeerId(), TR_ID_LEN ); 240 walk += TR_ID_LEN; 241 242 assert( walk-buf == HANDSHAKE_SIZE ); 243 *setme_len = walk - buf; 244 return buf; 245 } 246 247 /*** 248 **** 249 **** OUTGOING CONNECTIONS 250 **** 251 ***/ 252 253 /* 1 A->B: Diffie Hellman Ya, PadA */ 162 254 static void 163 send PublicKey( tr_handshake * handshake )255 sendYa( tr_handshake * handshake ) 164 256 { 165 257 int i; … … 167 259 const uint8_t * public_key; 168 260 struct evbuffer * outbuf = evbuffer_new( ); 169 uint8_t pad [512];261 uint8_t pad_a[PadA_MAXLEN]; 170 262 171 263 /* add our public key (Ya) */ … … 176 268 177 269 /* add some bullshit padding */ 178 len = tr_rand( 512);270 len = tr_rand( PadA_MAXLEN ); 179 271 for( i=0; i<len; ++i ) 180 pad [i] = tr_rand( UCHAR_MAX );181 evbuffer_add( outbuf, pad , len );272 pad_a[i] = tr_rand( UCHAR_MAX ); 273 evbuffer_add( outbuf, pad_a, len ); 182 274 183 275 /* send it */ 184 276 setReadState( handshake, AWAITING_YB ); 185 //setState( handshake, SENDING_YA );186 277 tr_peerIoWriteBuf( handshake->io, outbuf ); 187 278 … … 189 280 evbuffer_free( outbuf ); 190 281 } 191 192 static void193 buildHandshakeMessage( tr_handshake * handshake, uint8_t * buf )194 {195 uint8_t *walk = buf;196 const uint8_t * torrentHash = tr_cryptoGetTorrentHash( handshake->crypto );197 198 memcpy( walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );199 walk += HANDSHAKE_NAME_LEN;200 memset( walk, 0, HANDSHAKE_FLAGS_LEN );201 HANDSHAKE_SET_EXTMSGS( walk );202 HANDSHAKE_SET_AZPROTO( walk );203 HANDSHAKE_SET_EXTPREF( walk, HANDSHAKE_EXTPREF_LTEP_PREFER );204 walk += HANDSHAKE_FLAGS_LEN;205 memcpy( walk, torrentHash, SHA_DIGEST_LENGTH );206 walk += SHA_DIGEST_LENGTH;207 memcpy( walk, getPeerId(), TR_ID_LEN );208 walk += TR_ID_LEN;209 assert( walk-buf == HANDSHAKE_SIZE );210 }211 212 static void213 sendPlaintextHandshake( tr_handshake * handshake )214 {215 uint8_t buf[HANDSHAKE_SIZE];216 buildHandshakeMessage( handshake, buf );217 218 setReadState( handshake, AWAITING_HANDSHAKE );219 tr_peerIoWrite( handshake->io, buf, HANDSHAKE_SIZE );220 }221 222 static void223 sendHandshake( tr_handshake * handshake )224 {225 if( ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_PREFERRED ) ||226 ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_REQUIRED ) )227 {228 sendPublicKey( handshake );229 }230 else231 {232 sendPlaintextHandshake( handshake );233 }234 }235 236 static void237 sendLtepHandshake( tr_handshake * handshake )238 {239 benc_val_t val, *m;240 char * buf;241 int len;242 const char * v = TR_NAME " " USERAGENT_PREFIX;243 const int port = tr_getPublicPort( handshake->handle );244 struct evbuffer * outbuf = evbuffer_new( );245 uint32_t msglen;246 const uint8_t tr_msgid = 20; /* ltep extension id */247 const uint8_t ltep_msgid = 0; /* handshake id */248 249 tr_bencInit( &val, TYPE_DICT );250 tr_bencDictReserve( &val, 3 );251 m = tr_bencDictAdd( &val, "m" );252 tr_bencInit( m, TYPE_DICT );253 tr_bencDictReserve( m, 1 );254 tr_bencInitInt( tr_bencDictAdd( m, "ut_pex" ), 1 );255 if( port > 0 )256 tr_bencInitInt( tr_bencDictAdd( &val, "p" ), port );257 tr_bencInitStr( tr_bencDictAdd( &val, "v" ), v, 0, 1 );258 259 fprintf( stderr, "handshake %p: sending ltep handshake...\n", handshake );260 buf = tr_bencSaveMalloc( &val, &len );261 tr_bencPrint( &val );262 263 msglen = sizeof(tr_msgid) + sizeof(ltep_msgid) + len;264 tr_peerIoWriteUint32( handshake->io, outbuf, msglen );265 tr_peerIoWriteBytes ( handshake->io, outbuf, &tr_msgid, 1 );266 tr_peerIoWriteBytes ( handshake->io, outbuf, <ep_msgid, 1 );267 tr_peerIoWriteBytes ( handshake->io, outbuf, buf, len );268 269 tr_peerIoWriteBuf( handshake->io, outbuf );270 fireDoneCB( handshake, TRUE );271 272 /* cleanup */273 tr_bencFree( &val );274 tr_free( buf );275 evbuffer_free( outbuf );276 }277 278 279 /**280 ***281 **/282 283 static int284 readYa( tr_handshake * handshake, struct evbuffer * inbuf )285 {286 uint8_t ya[KEY_LEN];287 uint8_t *walk, outbuf[KEY_LEN + 512];288 const uint8_t *myKey, *secret;289 int len;290 291 if( EVBUFFER_LENGTH( inbuf ) < KEY_LEN )292 return READ_MORE;293 294 /* read the incoming peer's public key */295 evbuffer_remove( inbuf, ya, KEY_LEN );296 secret = tr_cryptoComputeSecret( handshake->crypto, ya );297 memcpy( handshake->mySecret, secret, KEY_LEN );298 tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL );299 300 /* send our public key to the peer */301 walk = outbuf;302 myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len );303 memcpy( walk, myKey, len );304 len = tr_rand( 512 );305 while( len-- )306 *walk++ = tr_rand( UCHAR_MAX );307 308 setReadState( handshake, AWAITING_PAD_A );309 tr_peerIoWrite( handshake->io, outbuf, walk-outbuf );310 311 return READ_DONE;312 }313 314 static int315 readPadA( tr_handshake * handshake, struct evbuffer * inbuf )316 {317 uint8_t * pch;318 319 /**320 *** Resynchronizing on HASH('req1',S)321 **/322 323 pch = memchr( EVBUFFER_DATA(inbuf),324 handshake->myReq1[0],325 EVBUFFER_LENGTH(inbuf) );326 if( pch == NULL ) {327 evbuffer_drain( inbuf, EVBUFFER_LENGTH(inbuf) );328 return READ_MORE;329 }330 evbuffer_drain( inbuf, pch-EVBUFFER_DATA(inbuf) );331 if( EVBUFFER_LENGTH(inbuf) < SHA_DIGEST_LENGTH )332 return READ_MORE;333 if( memcmp( EVBUFFER_DATA(inbuf), handshake->myReq1, SHA_DIGEST_LENGTH ) ) {334 evbuffer_drain( inbuf, 1 );335 return READ_AGAIN;336 }337 338 setState( handshake, AWAITING_CRYPTO_PROVIDE );339 return READ_AGAIN;340 }341 342 static int343 readCryptoProvide( tr_handshake * handshake, struct evbuffer * inbuf )344 {345 /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC)) */346 347 int i;348 uint8_t vc_in[VC_LENGTH];349 uint8_t req2[SHA_DIGEST_LENGTH];350 uint8_t req3[SHA_DIGEST_LENGTH];351 uint8_t obfuscatedTorrentHash[SHA_DIGEST_LENGTH];352 uint16_t padc_len = 0;353 uint32_t crypto_provide = 0;354 const size_t needlen = SHA_DIGEST_LENGTH + VC_LENGTH + sizeof(crypto_provide) + sizeof(padc_len);355 tr_torrent * tor = NULL;356 357 if( EVBUFFER_LENGTH(inbuf) < needlen )358 return READ_MORE;359 360 /* TODO: confirm they sent HASH('req1',S) here? */361 evbuffer_drain( inbuf, SHA_DIGEST_LENGTH );362 363 /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...364 * we can get the first half of that (the obufscatedTorrentHash)365 * by building the latter and xor'ing it with what the peer sent us */366 fprintf( stderr, "reading obfuscated torrent hash...\n" );367 evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH );368 tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL );369 for( i=0; i<SHA_DIGEST_LENGTH; ++i )370 obfuscatedTorrentHash[i] = req2[i] ^ req3[i];371 tor = tr_torrentFindFromObfuscatedHash( handshake->handle, obfuscatedTorrentHash );372 assert( tor != NULL );373 fprintf( stderr, "found the torrent; it's [%s]\n", tor->info.name );374 tr_peerIoSetTorrentHash( handshake->io, tor->info.hash );375 376 /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */377 378 tr_cryptoDecryptInit( handshake->crypto );379 380 tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH );381 382 tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );383 fprintf( stderr, "crypto_provide is %d\n", (int)crypto_provide );384 385 tr_peerIoReadUint16( handshake->io, inbuf, &padc_len );386 fprintf( stderr, "padc is %d\n", (int)padc_len );387 handshake->pad_c_len = padc_len;388 setState( handshake, AWAITING_PAD_C );389 return READ_AGAIN;390 }391 392 static int393 readPadC( tr_handshake * handshake, struct evbuffer * inbuf )394 {395 uint16_t ia_len;396 const size_t needlen = handshake->pad_c_len + sizeof(uint16_t);397 398 if( EVBUFFER_LENGTH(inbuf) < needlen )399 return READ_MORE;400 401 evbuffer_drain( inbuf, needlen );402 403 tr_peerIoReadUint16( handshake->io, inbuf, &ia_len );404 fprintf( stderr, "ia_len is %d\n", (int)ia_len );405 handshake->ia_len = ia_len;406 setState( handshake, AWAITING_IA );407 return READ_AGAIN;408 }409 410 static int411 readIA( tr_handshake * handshake, struct evbuffer * inbuf )412 {413 const size_t needlen = handshake->ia_len;414 uint8_t * ia;415 416 if( EVBUFFER_LENGTH(inbuf) < needlen )417 return READ_MORE;418 419 ia = tr_new( uint8_t, handshake->ia_len );420 tr_peerIoReadBytes( handshake->io, inbuf, ia, handshake->ia_len );421 fprintf( stderr, "got their payload ia: [%*.*s]\n", (int)needlen, (int)needlen, ia );422 423 handshake->state = -1;424 assert( 0 && "asdf" );425 }426 427 /**428 ***429 **/430 282 431 283 static int … … 440 292 if( EVBUFFER_LENGTH(inbuf) < needlen ) 441 293 return READ_MORE; 442 fprintf( stderr, "%*.*s\n", HANDSHAKE_NAME_LEN, HANDSHAKE_NAME_LEN, EVBUFFER_DATA(inbuf) );443 294 444 295 isEncrypted = memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN ); … … 449 300 } 450 301 451 fprintf( stderr, "got a %s handshake\n", (isEncrypted ? "encrypted" : "plaintext") ); 302 dbgmsg( handshake, "got a %s handshake", (isEncrypted ? "encrypted" : "plaintext") ); 303 452 304 handshake->peerSupportsEncryption = isEncrypted; 453 tr_peerIoSetEncryption( handshake->io, isEncrypted 454 ? PEER_ENCRYPTION_RC4 455 : PEER_ENCRYPTION_PLAINTEXT ); 305 tr_peerIoSetEncryption( handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4 306 : PEER_ENCRYPTION_NONE ); 456 307 if( !isEncrypted ) { 457 308 setState( handshake, AWAITING_HANDSHAKE ); … … 503 354 /* crypto_provide */ 504 355 crypto_provide = 0; 505 if( handshake->encryptionPreference != HANDSHAKE_PLAINTEXT_REQUIRED ) 506 crypto_provide |= (1<<0); 507 if( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED ) 356 crypto_provide |= (1<<0); /* encryption */ 357 if( !handshake->shunUnencryptedPeers ) /* plaintext */ 508 358 crypto_provide |= (1<<1); 509 359 assert( 1<=crypto_provide && crypto_provide<=3 ); … … 528 378 { 529 379 uint16_t i; 530 uint8_t msg[HANDSHAKE_SIZE];531 buildHandshakeMessage( handshake, msg);532 533 i = htons( HANDSHAKE_SIZE);380 int msgSize; 381 uint8_t * msg = buildHandshakeMessage( handshake, HANDSHAKE_EXTPREF_LTEP_PREFER, &msgSize ); 382 383 i = htons( msgSize ); 534 384 tr_cryptoEncrypt( handshake->crypto, sizeof(uint16_t), &i, &i ); 535 385 evbuffer_add( outbuf, &i, sizeof(uint16_t) ); 536 386 537 tr_cryptoEncrypt( handshake->crypto, HANDSHAKE_SIZE, msg, msg );387 tr_cryptoEncrypt( handshake->crypto, msgSize, msg, msg ); 538 388 evbuffer_add( outbuf, msg, HANDSHAKE_SIZE ); 389 handshake->haveSentBitTorrentHandshake = 1; 390 391 tr_free( msg ); 539 392 } 540 393 … … 562 415 { 563 416 if( EVBUFFER_LENGTH(inbuf) < VC_LENGTH ) { 564 fprintf( stderr, "not enough bytes... returning read_more\n" );417 dbgmsg( handshake, "not enough bytes... returning read_more" ); 565 418 return READ_MORE; 566 419 } … … 575 428 } 576 429 577 fprintf( stderr, "got it!\n" );430 dbgmsg( handshake, "got it!" ); 578 431 evbuffer_drain( inbuf, key_len ); 579 432 setState( handshake, AWAITING_CRYPTO_SELECT ); … … 594 447 assert( crypto_select==1 || crypto_select==2 ); 595 448 handshake->crypto_select = crypto_select; 596 fprintf( stderr, "crypto select is %d\n",crypto_select );449 dbgmsg( handshake, "crypto select is %d", (int)crypto_select ); 597 450 598 451 tr_peerIoReadUint16( handshake->io, inbuf, &pad_d_len ); 599 fprintf( stderr, "pad_d_len is %d\n", (int)pad_d_len );452 dbgmsg( handshake, "pad_d_len is %d", (int)pad_d_len ); 600 453 assert( pad_d_len <= 512 ); 601 454 handshake->pad_d_len = pad_d_len; … … 611 464 uint8_t * tmp; 612 465 613 fprintf( stderr, "pad d: need %d, got %d\n", (int)needlen, (int)EVBUFFER_LENGTH(inbuf) );466 dbgmsg( handshake, "pad d: need %d, got %d", (int)needlen, (int)EVBUFFER_LENGTH(inbuf) ); 614 467 if( EVBUFFER_LENGTH(inbuf) < needlen ) 615 468 return READ_MORE; … … 626 479 } 627 480 481 /*** 482 **** 483 **** INCOMING CONNECTIONS 484 **** 485 ***/ 486 628 487 static void 629 gotError( struct bufferevent * evbuf UNUSED, short what UNUSED, void * arg ); 630 631 /*ccc*/ 488 tr_handshakeDone( tr_handshake * handshake, int isConnected ); 489 632 490 static int 633 491 readHandshake( tr_handshake * handshake, struct evbuffer * inbuf ) 634 492 { 635 493 int i; 636 int ltep = 0; 637 int azmp = 0; 638 int isEncrypted; 494 uint8_t ltep = 0; 495 uint8_t azmp = 0; 639 496 uint8_t pstrlen; 640 497 uint8_t * pstr; 641 498 uint8_t reserved[8]; 642 499 uint8_t hash[SHA_DIGEST_LENGTH]; 643 int bytesRead = 0; 644 645 fprintf( stderr, "handshake payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) ); 500 501 dbgmsg( handshake, "payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) ); 646 502 647 503 if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE ) 648 504 return READ_MORE; 649 505 650 /* pstrlen */ 651 pstrlen = EVBUFFER_DATA(inbuf)[0]; 652 fprintf( stderr, "pstrlen 1 is %d [%c]\n", (int)pstrlen, pstrlen ); 653 fprintf( stderr, "the buf is [%c][%c][%c][%c]", 654 EVBUFFER_DATA(inbuf)[0], 655 EVBUFFER_DATA(inbuf)[1], 656 EVBUFFER_DATA(inbuf)[2], 657 EVBUFFER_DATA(inbuf)[3] ); 658 isEncrypted = pstrlen != 19; 659 handshake->peerSupportsEncryption = isEncrypted; 660 tr_peerIoSetEncryption( handshake->io, isEncrypted 661 ? PEER_ENCRYPTION_RC4 662 : PEER_ENCRYPTION_PLAINTEXT ); 663 if( isEncrypted ) { 664 fprintf( stderr, "I guess it's encrypted...\n" ); 665 if( tr_peerIoIsIncoming( handshake->io ) ) { 506 for( i=0; i<(int)EVBUFFER_LENGTH(inbuf); ++i ) 507 fprintf( stderr, "[%c]", EVBUFFER_DATA(inbuf)[i] ); 508 fprintf( stderr, "\n" ); 509 510 pstrlen = EVBUFFER_DATA(inbuf)[0]; /* peek, don't read. We may be 511 handing inbuf to AWAITING_YA */ 512 513 if( pstrlen == 19 ) /* unencrypted */ 514 { 515 tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE ); 516 } 517 else /* encrypted or corrupt */ 518 { 519 tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_RC4 ); 520 521 if( tr_peerIoIsIncoming( handshake->io ) ) 522 { 523 dbgmsg( handshake, "I think peer is sending us an encrypted handshake..." ); 666 524 setState( handshake, AWAITING_YA ); 667 525 return READ_AGAIN; 668 526 } 669 527 tr_cryptoDecrypt( handshake->crypto, 1, &pstrlen, &pstrlen ); 670 } 671 bytesRead++; 528 529 if( pstrlen != 19 ) 530 { 531 dbgmsg( handshake, "I think peer has sent us a corrupt handshake..." ); 532 tr_handshakeDone( handshake, FALSE ); 533 return READ_DONE; 534 } 535 } 536 672 537 evbuffer_drain( inbuf, 1 ); 673 fprintf( stderr, "pstrlen is %d [%c]\n", (int)pstrlen, pstrlen );674 assert( pstrlen == 19 );675 538 676 539 /* pstr (BitTorrent) */ … … 678 541 tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen ); 679 542 pstr[pstrlen] = '\0'; 680 fprintf( stderr, "pstrlen is [%s]\n", pstr );681 bytesRead += pstrlen;682 fprintf( stderr, "%*.*s", pstrlen, pstrlen, (char*)pstr );683 543 if( strcmp( (char*)pstr, "BitTorrent protocol" ) ) { 684 544 tr_free( pstr ); 685 gotError( NULL, 0, handshake);545 tr_handshakeDone( handshake, FALSE ); 686 546 return READ_DONE; 687 547 } … … 690 550 /* reserved bytes */ 691 551 tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof(reserved) ); 692 bytesRead += sizeof(reserved);693 552 694 553 /* torrent hash */ 695 554 tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof(hash) ); 696 bytesRead += sizeof(hash);697 555 if( tr_peerIoIsIncoming( handshake->io ) ) 698 556 { 699 assert( !tr_peerIoHasTorrentHash( handshake->io ) ); 700 tr_peerIoSetTorrentHash( handshake->io, hash ); 701 } 702 else 703 { 557 if( !tr_torrentExists( handshake->handle, hash ) ) 558 { 559 dbgmsg( handshake, "peer is trying to connect to us for a torrent we don't have." ); 560 tr_handshakeDone( handshake, FALSE ); 561 return READ_DONE; 562 } 563 else 564 { 565 assert( !tr_peerIoHasTorrentHash( handshake->io ) ); 566 tr_peerIoSetTorrentHash( handshake->io, hash ); 567 } 568 } 569 else /* outgoing */ 570 { 571 assert( tr_torrentExists( handshake->handle, hash ) ); 704 572 assert( tr_peerIoHasTorrentHash( handshake->io ) ); 705 assert( !memcmp( hash, tr_peerIoGetTorrentHash(handshake->io), SHA_DIGEST_LENGTH ) ); 573 if( memcmp( hash, tr_peerIoGetTorrentHash(handshake->io), SHA_DIGEST_LENGTH ) ) 574 { 575 dbgmsg( handshake, "peer returned the wrong hash. wtf?" ); 576 tr_handshakeDone( handshake, FALSE ); 577 return READ_DONE; 578 } 706 579 } 707 580 … … 709 582 tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) ); 710 583 tr_peerIoSetPeersId( handshake->io, handshake->peer_id ); 711 bytesRead += sizeof(handshake->peer_id);712 584 handshake->havePeerID = TRUE; 713 585 714 assert( bytesRead == HANDSHAKE_SIZE );715 716 586 /** 717 *** 587 *** Extension negotiation 718 588 **/ 719 589 720 ltep = HANDSHAKE_HAS_EXTMSGS( reserved ) ? 1 : 0;721 azmp = HANDSHAKE_HAS_AZPROTO( reserved ) ? 1 : 0;590 ltep = HANDSHAKE_HAS_EXTMSGS( reserved ); 591 azmp = HANDSHAKE_HAS_AZPROTO( reserved ); 722 592 if( ltep && azmp ) { 723 593 switch( HANDSHAKE_GET_EXTPREF( reserved ) ) { … … 733 603 } 734 604 assert( !ltep || !azmp ); 735 if( ltep ) { i = LT_EXTENSIONS_LTEP; fprintf(stderr,"using ltep\n" ); }736 else if( azmp ) { i = LT_EXTENSIONS_AZMP; fprintf(stderr,"using azmp\n" ); }737 else { i = LT_EXTENSIONS_NONE; fprintf(stderr,"using no extensions\n" ); }605 if( ltep ) { i = LT_EXTENSIONS_LTEP; dbgmsg(handshake,"using ltep" ); } 606 else if( azmp ) { i = LT_EXTENSIONS_AZMP; dbgmsg(handshake,"using azmp" ); } 607 else { i = LT_EXTENSIONS_NONE; dbgmsg(handshake,"using no extensions" ); } 738 608 tr_peerIoSetExtension( handshake->io, i ); 739 609 740 610 741 if( i == LT_EXTENSIONS_LTEP ) 742 { 743 sendLtepHandshake( handshake ); 744 return READ_DONE; 745 } 746 else if( !tr_peerIoIsIncoming( handshake->io ) && ( i != LT_EXTENSIONS_AZMP ) ) 747 { 748 fireDoneCB( handshake, TRUE ); 749 return READ_DONE; 750 } 751 752 753 fprintf( stderr, " UNHANDLED -- azmp " ); 754 return 0; 755 } 756 757 /** 758 *** 759 **/ 611 /** 612 *** If this is an incoming message, then we need to send a response handshake 613 **/ 614 615 if( !handshake->haveSentBitTorrentHandshake ) 616 { 617 const int ext = ltep ? HANDSHAKE_EXTPREF_LTEP_FORCE 618 : HANDSHAKE_EXTPREF_AZMP_FORCE; 619 int msgSize; 620 uint8_t * msg = buildHandshakeMessage( handshake, ext, &msgSize ); 621 tr_peerIoWrite( handshake->io, msg, msgSize ); 622 tr_free( msg ); 623 handshake->haveSentBitTorrentHandshake = 1; 624 } 625 626 /* we've completed the BT handshake... pass the work on to peer-msgs */ 627 tr_handshakeDone( handshake, TRUE ); 628 return READ_DONE; 629 } 630 631 static int 632 readYa( tr_handshake * handshake, struct evbuffer * inbuf ) 633 { 634 uint8_t ya[KEY_LEN]; 635 uint8_t *walk, outbuf[KEY_LEN + PadB_MAXLEN]; 636 const uint8_t *myKey, *secret; 637 int len; 638 639 if( EVBUFFER_LENGTH( inbuf ) < KEY_LEN ) 640 return READ_MORE; 641 642 /* read the incoming peer's public key */ 643 evbuffer_remove( inbuf, ya, KEY_LEN ); 644 secret = tr_cryptoComputeSecret( handshake->crypto, ya ); 645 memcpy( handshake->mySecret, secret, KEY_LEN ); 646 tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL ); 647 648 /* send our public key to the peer */ 649 walk = outbuf; 650 myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len ); 651 memcpy( walk, myKey, len ); 652 len = tr_rand( PadB_MAXLEN ); 653 while( len-- ) 654 *walk++ = tr_rand( UCHAR_MAX ); 655 656 setReadState( handshake, AWAITING_PAD_A ); 657 tr_peerIoWrite( handshake->io, outbuf, walk-outbuf ); 658 659 return READ_DONE; 660 } 661 662 static int 663 readPadA( tr_handshake * handshake, struct evbuffer * inbuf ) 664 { 665 uint8_t * pch; 666 667 /** 668 *** Resynchronizing on HASH('req1',S) 669 **/ 670 671 pch = memchr( EVBUFFER_DATA(inbuf), 672 handshake->myReq1[0], 673 EVBUFFER_LENGTH(inbuf) ); 674 if( pch == NULL ) { 675 evbuffer_drain( inbuf, EVBUFFER_LENGTH(inbuf) ); 676 return READ_MORE; 677 } 678 evbuffer_drain( inbuf, pch-EVBUFFER_DATA(inbuf) ); 679 if( EVBUFFER_LENGTH(inbuf) < SHA_DIGEST_LENGTH ) 680 return READ_MORE; 681 if( memcmp( EVBUFFER_DATA(inbuf), handshake->myReq1, SHA_DIGEST_LENGTH ) ) { 682 evbuffer_drain( inbuf, 1 ); 683 return READ_AGAIN; 684 } 685 686 setState( handshake, AWAITING_CRYPTO_PROVIDE ); 687 return READ_AGAIN; 688 } 689 690 static int 691 readCryptoProvide( tr_handshake * handshake, struct evbuffer * inbuf ) 692 { 693 /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC)) */ 694 695 int i; 696 uint8_t vc_in[VC_LENGTH]; 697 uint8_t req2[SHA_DIGEST_LENGTH]; 698 uint8_t req3[SHA_DIGEST_LENGTH]; 699 uint8_t obfuscatedTorrentHash[SHA_DIGEST_LENGTH]; 700 uint16_t padc_len = 0; 701 uint32_t crypto_provide = 0; 702 const size_t needlen = SHA_DIGEST_LENGTH + VC_LENGTH + sizeof(crypto_provide) + sizeof(padc_len); 703 tr_torrent * tor = NULL; 704 705 if( EVBUFFER_LENGTH(inbuf) < needlen ) 706 return READ_MORE; 707 708 /* TODO: confirm they sent HASH('req1',S) here? */ 709 evbuffer_drain( inbuf, SHA_DIGEST_LENGTH ); 710 711 /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ... 712 * we can get the first half of that (the obufscatedTorrentHash) 713 * by building the latter and xor'ing it with what the peer sent us */ 714 dbgmsg( handshake, "reading obfuscated torrent hash...\n" ); 715 evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH ); 716 tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL ); 717 for( i=0; i<SHA_DIGEST_LENGTH; ++i ) 718 obfuscatedTorrentHash[i] = req2[i] ^ req3[i]; 719 tor = tr_torrentFindFromObfuscatedHash( handshake->handle, obfuscatedTorrentHash ); 720 assert( tor != NULL ); 721 dbgmsg( handshake, "found the torrent; it's [%s]\n", tor->info.name ); 722 tr_peerIoSetTorrentHash( handshake->io, tor->info.hash ); 723 724 /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */ 725 726 tr_cryptoDecryptInit( handshake->crypto ); 727 728 tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH ); 729 730 tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide ); 731 dbgmsg( handshake, "crypto_provide is %d\n", (int)crypto_provide ); 732 733 tr_peerIoReadUint16( handshake->io, inbuf, &padc_len ); 734 dbgmsg( handshake, "padc is %d\n", (int)padc_len ); 735 handshake->pad_c_len = padc_len; 736 setState( handshake, AWAITING_PAD_C ); 737 return READ_AGAIN; 738 } 739 740 static int 741 readPadC( tr_handshake * handshake, struct evbuffer * inbuf ) 742 { 743 uint16_t ia_len; 744 const size_t needlen = handshake->pad_c_len + sizeof(uint16_t); 745 746 if( EVBUFFER_LENGTH(inbuf) < needlen ) 747 return READ_MORE; 748 749 evbuffer_drain( inbuf, needlen ); 750 751 tr_peerIoReadUint16( handshake->io, inbuf, &ia_len ); 752 dbgmsg( handshake, "ia_len is %d", (int)ia_len ); 753 handshake->ia_len = ia_len; 754 setState( handshake, AWAITING_IA ); 755 return READ_AGAIN; 756 } 757 758 static int 759 readIA( tr_handshake * handshake, struct evbuffer * inbuf ) 760 { 761 const size_t needlen = handshake->ia_len; 762 763 if( EVBUFFER_LENGTH(inbuf) < needlen ) 764 return READ_MORE; 765 766 return readHandshake( handshake, inbuf ); 767 } 768 769 /*** 770 **** 771 **** 772 **** 773 ***/ 760 774 761 775 static ReadState … … 765 779 struct evbuffer * inbuf = EVBUFFER_INPUT ( evin ); 766 780 ReadState ret; 767 fprintf( stderr, "handshake %p handling canRead; state is [%s]\n", handshake, getStateName(handshake->state) );781 dbgmsg( handshake, "handling canRead; state is [%s]\n", getStateName(handshake->state) ); 768 782 769 783 switch( handshake->state ) … … 788 802 789 803 static void 790 tr_handshakeFree( tr_handshake * handshake ) 791 { 792 tr_free( handshake ); 793 } 794 795 static void 796 fireDoneCB( tr_handshake * handshake, int isConnected ) 804 fireDoneFunc( tr_handshake * handshake, int isConnected ) 797 805 { 798 806 const uint8_t * peer_id = isConnected && handshake->havePeerID … … 805 813 handshake->peerSupportsEncryption, 806 814 handshake->doneUserData ); 807 tr_handshakeFree( handshake ); 815 } 816 817 void 818 tr_handshakeDone( tr_handshake * handshake, int isOK ) 819 { 820 dbgmsg( handshake, "handshakeDone: %s", isOK ? "connected" : "aborting" ); 821 tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL ); 822 fireDoneFunc( handshake, isOK ); 823 tr_free( handshake ); 824 } 825 826 void 827 tr_handshakeAbort( tr_handshake * handshake ) 828 { 829 tr_handshakeDone( handshake, FALSE ); 808 830 } 809 831 … … 817 839 * try a plaintext handshake */ 818 840 if( ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) ) 819 && ( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED)841 && ( !handshake->shunUnencryptedPeers ) 820 842 && ( !tr_peerIoReconnect( handshake->io ) ) ) 821 843 { 822 fprintf( stderr, "handshake %p trying again in plaintext...\n", handshake ); 823 handshake->encryptionPreference = HANDSHAKE_PLAINTEXT_REQUIRED; 824 sendPlaintextHandshake( handshake ); 844 int msgSize; 845 uint8_t * msg = buildHandshakeMessage( handshake, HANDSHAKE_EXTPREF_LTEP_PREFER, &msgSize ); 846 setReadState( handshake, AWAITING_HANDSHAKE ); 847 tr_peerIoWrite( handshake->io, msg, msgSize ); 848 tr_free( msg ); 825 849 } 826 850 else 827 851 { 828 tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL ); 829 fireDoneCB( handshake, FALSE ); 852 tr_handshakeDone( handshake, FALSE ); 830 853 } 831 854 } … … 836 859 837 860 tr_handshake* 838 tr_handshakeNew( tr_peerIo * io,839 int encryptionPreference,840 handshakeDoneCB doneCB,841 void * doneUserData )861 tr_handshakeNew( tr_peerIo * io, 862 tr_encryption_mode encryption_mode, 863 handshakeDoneCB doneCB, 864 void * doneUserData ) 842 865 { 843 866 tr_handshake * handshake; 844 867 845 // w00t868 // w00t 846 869 //static int count = 0; 847 870 //if( count++ ) return NULL; … … 850 873 handshake->io = io; 851 874 handshake->crypto = tr_peerIoGetCrypto( io ); 852 handshake-> encryptionPreference = encryptionPreference;875 handshake->shunUnencryptedPeers = encryption_mode==TR_ENCRYPTION_REQUIRED; 853 876 handshake->doneCB = doneCB; 854 877 handshake->doneUserData = doneUserData; … … 858 881 tr_peerIoSetIOFuncs( io, canRead, NULL, gotError, handshake ); 859 882 860 fprintf( stderr, "handshake %p: new handshake for io %p\n", handshake, io );883 dbgmsg( handshake, "new handshake for io %p", io ); 861 884 862 885 if( tr_peerIoIsIncoming( io ) ) 863 {864 886 setReadState( handshake, AWAITING_HANDSHAKE ); 865 }866 887 else 867 { 868 sendHandshake( handshake ); 869 } 888 sendYa( handshake ); 870 889 871 890 return handshake; 872 891 } 873 874 void875 tr_handshakeAbort( tr_handshake * handshake )876 {877 tr_peerIoFree( handshake->io );878 tr_handshakeFree( handshake );879 }
Note: See TracChangeset
for help on using the changeset viewer.