Ignore:
Timestamp:
Sep 20, 2007, 4:11:09 AM (15 years ago)
Author:
charles
Message:
  • add a public API call for setting encryption preferences
  • fix upload bug that caused us to send the same block out more than once
  • fix handshake bug that caused us to shun uTorrent and vice versa
  • fix minor memory leaks (valgrind).
  • move extension handshakes into peer-msgs
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/encryption/libtransmission/handshake.c

    r3079 r3101  
    4444#define HANDSHAKE_SIZE          68
    4545
     46/***
     47****
     48***/
     49
     50enum
     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
    4659#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 )
    4962#else
    5063#define HANDSHAKE_HAS_EXTMSGS( bits ) ( 0 )
     
    5366
    5467#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 )
    5770#else
    5871#define HANDSHAKE_HAS_AZPROTO( bits ) ( 0 )
     
    7083#define HANDSHAKE_EXTPREF_AZMP_FORCE   ( 0x3 )
    7184
     85enum
     86{
     87    PadA_MAXLEN = 512,
     88    PadB_MAXLEN = 512,
     89    PadC_MAXLEN = 512,
     90    PadD_MAXLEN = 512
     91};
     92
    7293extern const char* getPeerId( void ) ;
    7394
     
    7798struct tr_handshake
    7899{
    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;
    81104    tr_peerIo * io;
    82105    tr_crypto * crypto;
     
    85108    uint8_t mySecret[96];
    86109    uint8_t state;
    87     uint8_t encryptionPreference;
    88110    uint16_t pad_c_len;
    89111    uint16_t pad_d_len;
     
    96118};
    97119
    98 static void
    99 fireDoneCB( tr_handshake * handshake, int isConnected );
    100 
    101120/**
    102121***
    103122**/
    104123
    105 enum /*ccc*/
     124enum
    106125{
    107126    /* incoming */
     
    123142***
    124143**/
     144
     145static void
     146myDebug( 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 )
    125162
    126163static const char* getStateName( short state )
     
    141178        case AWAITING_CRYPTO_SELECT:  str = "awaiting crypto select"; break;
    142179        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;
    144181    }
    145182    return str;
     
    149186setState( tr_handshake * handshake, short state )
    150187{
    151     fprintf( stderr, "handshake %p: setting to state [%s]\n", handshake, getStateName(state) );
     188    dbgmsg( handshake, "setting to state [%s]", getStateName(state) );
    152189    handshake->state = state;
    153190}
     
    160197}
    161198
     199static uint8_t *
     200buildHandshakeMessage( 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 */
    162254static void
    163 sendPublicKey( tr_handshake * handshake )
     255sendYa( tr_handshake * handshake )
    164256{
    165257    int i;
     
    167259    const uint8_t * public_key;
    168260    struct evbuffer * outbuf = evbuffer_new( );
    169     uint8_t pad[512];
     261    uint8_t pad_a[PadA_MAXLEN];
    170262
    171263    /* add our public key (Ya) */
     
    176268
    177269    /* add some bullshit padding */
    178     len = tr_rand( 512 );
     270    len = tr_rand( PadA_MAXLEN );
    179271    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 );
    182274
    183275    /* send it */
    184276    setReadState( handshake, AWAITING_YB );
    185     //setState( handshake, SENDING_YA );
    186277    tr_peerIoWriteBuf( handshake->io, outbuf );
    187278
     
    189280    evbuffer_free( outbuf );
    190281}
    191 
    192 static void
    193 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 void
    213 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 void
    223 sendHandshake( tr_handshake * handshake )
    224 {
    225     if( ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_PREFERRED ) ||
    226         ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_REQUIRED ) )
    227     {
    228         sendPublicKey( handshake );
    229     }
    230     else
    231     {
    232         sendPlaintextHandshake( handshake );
    233     }
    234 }
    235 
    236 static void
    237 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, &ltep_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 int
    284 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 int
    315 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 int
    343 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 int
    393 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 int
    411 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 **/
    430282
    431283static int
     
    440292    if( EVBUFFER_LENGTH(inbuf) < needlen )
    441293        return READ_MORE;
    442 fprintf( stderr, "%*.*s\n", HANDSHAKE_NAME_LEN, HANDSHAKE_NAME_LEN, EVBUFFER_DATA(inbuf) );
    443294
    444295    isEncrypted = memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
     
    449300    }
    450301
    451     fprintf( stderr, "got a %s handshake\n", (isEncrypted ? "encrypted" : "plaintext") );
     302    dbgmsg( handshake, "got a %s handshake", (isEncrypted ? "encrypted" : "plaintext") );
     303
    452304    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 );
    456307    if( !isEncrypted ) {
    457308        setState( handshake, AWAITING_HANDSHAKE );
     
    503354        /* crypto_provide */
    504355        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 */
    508358            crypto_provide |= (1<<1);
    509359        assert( 1<=crypto_provide && crypto_provide<=3 );
     
    528378    {
    529379        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 );
    534384        tr_cryptoEncrypt( handshake->crypto, sizeof(uint16_t), &i, &i );
    535385        evbuffer_add( outbuf, &i, sizeof(uint16_t) );
    536386
    537         tr_cryptoEncrypt( handshake->crypto, HANDSHAKE_SIZE, msg, msg );
     387        tr_cryptoEncrypt( handshake->crypto, msgSize, msg, msg );
    538388        evbuffer_add( outbuf, msg, HANDSHAKE_SIZE );
     389        handshake->haveSentBitTorrentHandshake = 1;
     390
     391        tr_free( msg );
    539392    }
    540393
     
    562415    {
    563416        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" );
    565418            return READ_MORE;
    566419        }
     
    575428    }
    576429
    577     fprintf( stderr, "got it!\n" );
     430    dbgmsg( handshake, "got it!" );
    578431    evbuffer_drain( inbuf, key_len );
    579432    setState( handshake, AWAITING_CRYPTO_SELECT );
     
    594447    assert( crypto_select==1 || crypto_select==2 );
    595448    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 );
    597450
    598451    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 );
    600453    assert( pad_d_len <= 512 );
    601454    handshake->pad_d_len = pad_d_len;
     
    611464    uint8_t * tmp;
    612465
    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) );
    614467    if( EVBUFFER_LENGTH(inbuf) < needlen )
    615468        return READ_MORE;
     
    626479}
    627480
     481/***
     482****
     483****  INCOMING CONNECTIONS
     484****
     485***/
     486
    628487static void
    629 gotError( struct bufferevent * evbuf UNUSED, short what UNUSED, void * arg );
    630 
    631 /*ccc*/
     488tr_handshakeDone( tr_handshake * handshake, int isConnected );
     489
    632490static int
    633491readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
    634492{
    635493    int i;
    636     int ltep = 0;
    637     int azmp = 0;
    638     int isEncrypted;
     494    uint8_t ltep = 0;
     495    uint8_t azmp = 0;
    639496    uint8_t pstrlen;
    640497    uint8_t * pstr;
    641498    uint8_t reserved[8];
    642499    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) );
    646502
    647503    if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE )
    648504        return READ_MORE;
    649505
    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 ) ) {
     506for( i=0; i<(int)EVBUFFER_LENGTH(inbuf); ++i )
     507fprintf( stderr, "[%c]", EVBUFFER_DATA(inbuf)[i] );
     508fprintf( 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..." );
    666524            setState( handshake, AWAITING_YA );
    667525            return READ_AGAIN;
    668526        }
    669527        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
    672537    evbuffer_drain( inbuf, 1 );
    673     fprintf( stderr, "pstrlen is %d [%c]\n", (int)pstrlen, pstrlen );
    674     assert( pstrlen == 19 );
    675538
    676539    /* pstr (BitTorrent) */
     
    678541    tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen );
    679542    pstr[pstrlen] = '\0';
    680     fprintf( stderr, "pstrlen is [%s]\n", pstr );
    681     bytesRead += pstrlen;
    682     fprintf( stderr, "%*.*s", pstrlen, pstrlen, (char*)pstr );
    683543    if( strcmp( (char*)pstr, "BitTorrent protocol" ) ) {
    684544        tr_free( pstr );
    685         gotError( NULL, 0, handshake );
     545        tr_handshakeDone( handshake, FALSE );
    686546        return READ_DONE;
    687547    }
     
    690550    /* reserved bytes */
    691551    tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof(reserved) );
    692     bytesRead += sizeof(reserved);
    693552
    694553    /* torrent hash */
    695554    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof(hash) );
    696     bytesRead += sizeof(hash);
    697555    if( tr_peerIoIsIncoming( handshake->io ) )
    698556    {
    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 ) );
    704572        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        }
    706579    }
    707580
     
    709582    tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) );
    710583    tr_peerIoSetPeersId( handshake->io, handshake->peer_id );
    711     bytesRead += sizeof(handshake->peer_id);
    712584    handshake->havePeerID = TRUE;
    713585
    714     assert( bytesRead == HANDSHAKE_SIZE );
    715 
    716586    /**
    717     ***
     587    *** Extension negotiation
    718588    **/
    719589
    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 );
    722592    if( ltep && azmp ) {
    723593        switch( HANDSHAKE_GET_EXTPREF( reserved ) ) {
     
    733603    }
    734604    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" ); }
    738608    tr_peerIoSetExtension( handshake->io, i );
    739609
    740610
    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
     631static int
     632readYa( 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
     662static int
     663readPadA( 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
     690static int
     691readCryptoProvide( 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
     740static int
     741readPadC( 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
     758static int
     759readIA( 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***/
    760774
    761775static ReadState
     
    765779    struct evbuffer * inbuf = EVBUFFER_INPUT ( evin );
    766780    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) );
    768782
    769783    switch( handshake->state )
     
    788802
    789803static void
    790 tr_handshakeFree( tr_handshake * handshake )
    791 {
    792     tr_free( handshake );
    793 }
    794 
    795 static void
    796 fireDoneCB( tr_handshake * handshake, int isConnected )
     804fireDoneFunc( tr_handshake * handshake, int isConnected )
    797805{
    798806    const uint8_t * peer_id = isConnected && handshake->havePeerID
     
    805813                          handshake->peerSupportsEncryption,
    806814                          handshake->doneUserData );
    807     tr_handshakeFree( handshake );
     815}
     816
     817void
     818tr_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
     826void
     827tr_handshakeAbort( tr_handshake * handshake )
     828{
     829    tr_handshakeDone( handshake, FALSE );
    808830}
    809831
     
    817839     * try a plaintext handshake */
    818840    if(    ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) )
    819         && ( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED )
     841        && ( !handshake->shunUnencryptedPeers )
    820842        && ( !tr_peerIoReconnect( handshake->io ) ) )
    821843    {
    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 );
    825849    }
    826850    else
    827851    {
    828         tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
    829         fireDoneCB( handshake, FALSE );
     852        tr_handshakeDone( handshake, FALSE );
    830853    }
    831854}
     
    836859
    837860tr_handshake*
    838 tr_handshakeNew( tr_peerIo        * io,
    839                  int                encryptionPreference,
    840                  handshakeDoneCB    doneCB,
    841                  void             * doneUserData )
     861tr_handshakeNew( tr_peerIo           * io,
     862                 tr_encryption_mode    encryption_mode,
     863                 handshakeDoneCB       doneCB,
     864                 void                * doneUserData )
    842865{
    843866    tr_handshake * handshake;
    844867
    845 //w00t
     868// w00t
    846869//static int count = 0;
    847870//if( count++ ) return NULL;
     
    850873    handshake->io = io;
    851874    handshake->crypto = tr_peerIoGetCrypto( io );
    852     handshake->encryptionPreference = encryptionPreference;
     875    handshake->shunUnencryptedPeers = encryption_mode==TR_ENCRYPTION_REQUIRED;
    853876    handshake->doneCB = doneCB;
    854877    handshake->doneUserData = doneUserData;
     
    858881    tr_peerIoSetIOFuncs( io, canRead, NULL, gotError, handshake );
    859882
    860 fprintf( stderr, "handshake %p: new handshake for io %p\n", handshake, io );
     883dbgmsg( handshake, "new handshake for io %p", io );
    861884
    862885    if( tr_peerIoIsIncoming( io ) )
    863     {
    864886        setReadState( handshake, AWAITING_HANDSHAKE );
    865     }
    866887    else
    867     {
    868         sendHandshake( handshake );
    869     }
     888        sendYa( handshake );
    870889
    871890    return handshake;
    872891}
    873 
    874 void
    875 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.