source: trunk/libtransmission/handshake.c @ 12322

Last change on this file since 12322 was 12322, checked in by jordan, 11 years ago

(trunk libT) more heap pruning: avoid an unnecessary malloc() + strcmp() + free() when parsing the initial handshake string from a peer

  • Property svn:keywords set to Date Rev Author Id
File size: 37.4 KB
Line 
1/*
2 * This file Copyright (C) Mnemosyne LLC
3 *
4 * This file is licensed by the GPL version 2. Works owned by the
5 * Transmission project are granted a special exemption to clause 2(b)
6 * so that the bulk of its code can remain under the MIT license.
7 * This exemption does not extend to derived works not owned by
8 * the Transmission project.
9 *
10 * $Id: handshake.c 12322 2011-04-05 18:16:21Z jordan $
11 */
12
13#include <assert.h>
14#include <errno.h>
15#include <string.h> /* strcmp(), strlen() */
16
17#include <event2/buffer.h>
18#include <event2/event.h>
19
20#include "transmission.h"
21#include "clients.h"
22#include "crypto.h"
23#include "handshake.h"
24#include "peer-io.h"
25#include "peer-mgr.h"
26#include "session.h"
27#include "torrent.h"
28#include "tr-dht.h"
29#include "utils.h"
30
31/* enable LibTransmission extension protocol */
32#define ENABLE_LTEP * /
33/* fast extensions */
34#define ENABLE_FAST * /
35/* DHT */
36#define ENABLE_DHT * /
37
38/***
39****
40***/
41
42#define HANDSHAKE_NAME "\023BitTorrent protocol"
43
44enum
45{
46    /* BitTorrent Handshake Constants */
47    HANDSHAKE_NAME_LEN             = 20,
48    HANDSHAKE_FLAGS_LEN            = 8,
49    HANDSHAKE_SIZE                 = 68,
50    INCOMING_HANDSHAKE_LEN         = 48,
51
52    /* Encryption Constants */
53    PadA_MAXLEN                    = 512,
54    PadB_MAXLEN                    = 512,
55    PadC_MAXLEN                    = 512,
56    PadD_MAXLEN                    = 512,
57    VC_LENGTH                      = 8,
58    KEY_LEN                        = 96,
59    CRYPTO_PROVIDE_PLAINTEXT       = 1,
60    CRYPTO_PROVIDE_CRYPTO          = 2,
61
62    /* how long to wait before giving up on a handshake */
63    HANDSHAKE_TIMEOUT_SEC          = 30
64};
65
66
67#ifdef ENABLE_LTEP
68 #define HANDSHAKE_HAS_LTEP( bits ) ( ( ( bits )[5] & 0x10 ) ? 1 : 0 )
69 #define HANDSHAKE_SET_LTEP( bits ) ( ( bits )[5] |= 0x10 )
70#else
71 #define HANDSHAKE_HAS_LTEP( bits ) ( 0 )
72 #define HANDSHAKE_SET_LTEP( bits ) ( (void)0 )
73#endif
74
75#ifdef ENABLE_FAST
76 #define HANDSHAKE_HAS_FASTEXT( bits ) ( ( ( bits )[7] & 0x04 ) ? 1 : 0 )
77 #define HANDSHAKE_SET_FASTEXT( bits ) ( ( bits )[7] |= 0x04 )
78#else
79 #define HANDSHAKE_HAS_FASTEXT( bits ) ( 0 )
80 #define HANDSHAKE_SET_FASTEXT( bits ) ( (void)0 )
81#endif
82
83#ifdef ENABLE_DHT
84 #define HANDSHAKE_HAS_DHT( bits ) ( ( ( bits )[7] & 0x01 ) ? 1 : 0 )
85 #define HANDSHAKE_SET_DHT( bits ) ( ( bits )[7] |= 0x01 )
86#else
87 #define HANDSHAKE_HAS_DHT( bits ) ( 0 )
88 #define HANDSHAKE_SET_DHT( bits ) ( (void)0 )
89#endif
90
91/* http://www.azureuswiki.com/index.php/Extension_negotiation_protocol
92   these macros are to be used if both extended messaging and the
93   azureus protocol is supported, they indicate which protocol is preferred */
94#define HANDSHAKE_GET_EXTPREF( reserved )      ( ( reserved )[5] & 0x03 )
95#define HANDSHAKE_SET_EXTPREF( reserved, val ) ( ( reserved )[5] |= 0x03 &\
96                                                                    ( val ) )
97
98typedef uint8_t handshake_state_t;
99
100struct tr_handshake
101{
102    bool                  haveReadAnythingFromPeer;
103    bool                  havePeerID;
104    bool                  haveSentBitTorrentHandshake;
105    tr_peerIo *           io;
106    tr_crypto *           crypto;
107    tr_session *          session;
108    uint8_t               mySecret[KEY_LEN];
109    handshake_state_t     state;
110    tr_encryption_mode    encryptionMode;
111    uint16_t              pad_c_len;
112    uint16_t              pad_d_len;
113    uint16_t              ia_len;
114    uint32_t              crypto_select;
115    uint32_t              crypto_provide;
116    uint8_t               myReq1[SHA_DIGEST_LENGTH];
117    handshakeDoneCB       doneCB;
118    void *                doneUserData;
119    struct event        * timeout_timer;
120};
121
122/**
123***
124**/
125
126enum
127{
128    /* incoming */
129    AWAITING_HANDSHAKE,
130    AWAITING_PEER_ID,
131    AWAITING_YA,
132    AWAITING_PAD_A,
133    AWAITING_CRYPTO_PROVIDE,
134    AWAITING_PAD_C,
135    AWAITING_IA,
136    AWAITING_PAYLOAD_STREAM,
137
138    /* outgoing */
139    AWAITING_YB,
140    AWAITING_VC,
141    AWAITING_CRYPTO_SELECT,
142    AWAITING_PAD_D,
143};
144
145/**
146***
147**/
148
149#define dbgmsg( handshake, ... ) \
150    do { \
151        if( tr_deepLoggingIsActive( ) ) \
152            tr_deepLog( __FILE__, __LINE__, tr_peerIoGetAddrStr( handshake->io ), __VA_ARGS__ ); \
153    } while( 0 )
154
155static const char*
156getStateName( const handshake_state_t state )
157{
158    const char * str = "f00!";
159
160    switch( state )
161    {
162        case AWAITING_HANDSHAKE:
163            str = "awaiting handshake"; break;
164
165        case AWAITING_PEER_ID:
166            str = "awaiting peer id"; break;
167
168        case AWAITING_YA:
169            str = "awaiting ya"; break;
170
171        case AWAITING_PAD_A:
172            str = "awaiting pad a"; break;
173
174        case AWAITING_CRYPTO_PROVIDE:
175            str = "awaiting crypto_provide"; break;
176
177        case AWAITING_PAD_C:
178            str = "awaiting pad c"; break;
179
180        case AWAITING_IA:
181            str = "awaiting ia"; break;
182
183        case AWAITING_YB:
184            str = "awaiting yb"; break;
185
186        case AWAITING_VC:
187            str = "awaiting vc"; break;
188
189        case AWAITING_CRYPTO_SELECT:
190            str = "awaiting crypto select"; break;
191
192        case AWAITING_PAD_D:
193            str = "awaiting pad d"; break;
194    }
195    return str;
196}
197
198static void
199setState( tr_handshake * handshake, handshake_state_t state )
200{
201    dbgmsg( handshake, "setting to state [%s]", getStateName( state ) );
202    handshake->state = state;
203}
204
205static void
206setReadState( tr_handshake * handshake, handshake_state_t state )
207{
208    setState( handshake, state );
209}
210
211static void
212buildHandshakeMessage( tr_handshake * handshake, uint8_t * buf )
213{
214    uint8_t          * walk = buf;
215    const uint8_t    * torrentHash = tr_cryptoGetTorrentHash( handshake->crypto );
216    const tr_torrent * tor = tr_torrentFindFromHash( handshake->session, torrentHash );
217    const uint8_t    * peer_id = tor && *tor->peer_id ? tor->peer_id : tr_getPeerId( handshake->session );
218
219    memcpy( walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
220    walk += HANDSHAKE_NAME_LEN;
221    memset( walk, 0, HANDSHAKE_FLAGS_LEN );
222    HANDSHAKE_SET_LTEP( walk );
223    HANDSHAKE_SET_FASTEXT( walk );
224
225    /* Note that this doesn't depend on whether the torrent is private.
226     * We don't accept DHT peers for a private torrent,
227     * but we participate in the DHT regardless. */
228    if( tr_dhtEnabled( handshake->session ) )
229        HANDSHAKE_SET_DHT( walk );
230
231    walk += HANDSHAKE_FLAGS_LEN;
232    memcpy( walk, torrentHash, SHA_DIGEST_LENGTH );
233    walk += SHA_DIGEST_LENGTH;
234    memcpy( walk, peer_id, PEER_ID_LEN );
235    walk += PEER_ID_LEN;
236
237    assert( strlen( ( const char* )peer_id ) == PEER_ID_LEN );
238    assert( walk - buf == HANDSHAKE_SIZE );
239}
240
241static int tr_handshakeDone( tr_handshake * handshake,
242                             bool           isConnected );
243
244enum
245{
246    HANDSHAKE_OK,
247    HANDSHAKE_ENCRYPTION_WRONG,
248    HANDSHAKE_BAD_TORRENT,
249    HANDSHAKE_PEER_IS_SELF,
250};
251
252static int
253parseHandshake( tr_handshake *    handshake,
254                struct evbuffer * inbuf )
255{
256    uint8_t name[HANDSHAKE_NAME_LEN];
257    uint8_t reserved[HANDSHAKE_FLAGS_LEN];
258    uint8_t hash[SHA_DIGEST_LENGTH];
259    const tr_torrent * tor;
260    const uint8_t * tor_peer_id;
261    uint8_t peer_id[PEER_ID_LEN];
262
263    dbgmsg( handshake, "payload: need %d, got %zu",
264            HANDSHAKE_SIZE, evbuffer_get_length( inbuf ) );
265
266    if( evbuffer_get_length( inbuf ) < HANDSHAKE_SIZE )
267        return READ_LATER;
268
269    /* confirm the protocol */
270    tr_peerIoReadBytes( handshake->io, inbuf, name, HANDSHAKE_NAME_LEN );
271    if( memcmp( name, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN ) )
272        return HANDSHAKE_ENCRYPTION_WRONG;
273
274    /* read the reserved bytes */
275    tr_peerIoReadBytes( handshake->io, inbuf, reserved, HANDSHAKE_FLAGS_LEN );
276
277    /* torrent hash */
278    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof( hash ) );
279    assert( tr_peerIoHasTorrentHash( handshake->io ) );
280    if( !tr_torrentExists( handshake->session, hash )
281      || memcmp( hash, tr_peerIoGetTorrentHash( handshake->io ),
282                 SHA_DIGEST_LENGTH ) )
283    {
284        dbgmsg( handshake, "peer returned the wrong hash. wtf?" );
285        return HANDSHAKE_BAD_TORRENT;
286    }
287
288    /* peer_id */
289    tr_peerIoReadBytes( handshake->io, inbuf, peer_id, sizeof( peer_id ) );
290    tr_peerIoSetPeersId( handshake->io, peer_id );
291
292    /* peer id */
293    handshake->havePeerID = true;
294    dbgmsg( handshake, "peer-id is [%*.*s]", PEER_ID_LEN, PEER_ID_LEN, peer_id );
295
296    tor = tr_torrentFindFromHash( handshake->session, hash );
297    tor_peer_id = tor ? tor->peer_id : tr_getPeerId( handshake->session );
298    if( !memcmp( peer_id, tor_peer_id, PEER_ID_LEN ) )
299    {
300        dbgmsg( handshake, "streuth!  we've connected to ourselves." );
301        return HANDSHAKE_PEER_IS_SELF;
302    }
303
304    /**
305    *** Extensions
306    **/
307
308    tr_peerIoEnableLTEP( handshake->io, HANDSHAKE_HAS_LTEP( reserved ) );
309
310    tr_peerIoEnableFEXT( handshake->io, HANDSHAKE_HAS_FASTEXT( reserved ) );
311
312    tr_peerIoEnableDHT( handshake->io, HANDSHAKE_HAS_DHT( reserved ) );
313
314    return HANDSHAKE_OK;
315}
316
317/***
318****
319****  OUTGOING CONNECTIONS
320****
321***/
322
323/* 1 A->B: Diffie Hellman Ya, PadA */
324static void
325sendYa( tr_handshake * handshake )
326{
327    int               len;
328    const uint8_t *   public_key;
329    char              outbuf[ KEY_LEN + PadA_MAXLEN ], *walk=outbuf;
330
331    /* add our public key (Ya) */
332    public_key = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
333    assert( len == KEY_LEN );
334    assert( public_key );
335    memcpy( walk, public_key, len );
336    walk += len;
337
338    /* add some bullshit padding */
339    len = tr_cryptoRandInt( PadA_MAXLEN );
340    tr_cryptoRandBuf( walk, len );
341    walk += len;
342
343    /* send it */
344    setReadState( handshake, AWAITING_YB );
345    tr_peerIoWriteBytes( handshake->io, outbuf, walk - outbuf, false );
346}
347
348static uint32_t
349getCryptoProvide( const tr_handshake * handshake )
350{
351    uint32_t provide = 0;
352
353    switch( handshake->encryptionMode )
354    {
355        case TR_ENCRYPTION_REQUIRED:
356        case TR_ENCRYPTION_PREFERRED:
357            provide |= CRYPTO_PROVIDE_CRYPTO;
358            break;
359
360        case TR_CLEAR_PREFERRED:
361            provide |= CRYPTO_PROVIDE_CRYPTO | CRYPTO_PROVIDE_PLAINTEXT;
362            break;
363    }
364
365    return provide;
366}
367
368static uint32_t
369getCryptoSelect( const tr_handshake * handshake,
370                 uint32_t             crypto_provide )
371{
372    uint32_t choices[2];
373    int      i, nChoices = 0;
374
375    switch( handshake->encryptionMode )
376    {
377        case TR_ENCRYPTION_REQUIRED:
378            choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
379            break;
380
381        case TR_ENCRYPTION_PREFERRED:
382            choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
383            choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
384            break;
385
386        case TR_CLEAR_PREFERRED:
387            choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
388            choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
389            break;
390    }
391
392    for( i = 0; i < nChoices; ++i )
393        if( crypto_provide & choices[i] )
394            return choices[i];
395
396    return 0;
397}
398
399static int
400readYb( tr_handshake * handshake, struct evbuffer * inbuf )
401{
402    int               isEncrypted;
403    const uint8_t *   secret;
404    uint8_t           yb[KEY_LEN];
405    struct evbuffer * outbuf;
406    size_t            needlen = HANDSHAKE_NAME_LEN;
407
408    if( evbuffer_get_length( inbuf ) < needlen )
409        return READ_LATER;
410
411    isEncrypted = memcmp( evbuffer_pullup( inbuf, HANDSHAKE_NAME_LEN ), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
412    if( isEncrypted )
413    {
414        needlen = KEY_LEN;
415        if( evbuffer_get_length( inbuf ) < needlen )
416            return READ_LATER;
417    }
418
419    dbgmsg( handshake, "got a %s handshake",
420           ( isEncrypted ? "encrypted" : "plaintext" ) );
421
422    tr_peerIoSetEncryption( handshake->io, isEncrypted ? PEER_ENCRYPTION_RC4
423                                                       : PEER_ENCRYPTION_NONE );
424    if( !isEncrypted )
425    {
426        setState( handshake, AWAITING_HANDSHAKE );
427        return READ_NOW;
428    }
429
430    handshake->haveReadAnythingFromPeer = true;
431
432    /* compute the secret */
433    evbuffer_remove( inbuf, yb, KEY_LEN );
434    secret = tr_cryptoComputeSecret( handshake->crypto, yb );
435    memcpy( handshake->mySecret, secret, KEY_LEN );
436
437    /* now send these: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S),
438     * ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA) */
439    outbuf = evbuffer_new( );
440
441    /* HASH('req1', S) */
442    {
443        uint8_t req1[SHA_DIGEST_LENGTH];
444        tr_sha1( req1, "req1", 4, secret, KEY_LEN, NULL );
445        evbuffer_add( outbuf, req1, SHA_DIGEST_LENGTH );
446    }
447
448    /* HASH('req2', SKEY) xor HASH('req3', S) */
449    {
450        int     i;
451        uint8_t req2[SHA_DIGEST_LENGTH];
452        uint8_t req3[SHA_DIGEST_LENGTH];
453        uint8_t buf[SHA_DIGEST_LENGTH];
454        tr_sha1( req2, "req2", 4,
455                 tr_cryptoGetTorrentHash( handshake->crypto ),
456                 SHA_DIGEST_LENGTH, NULL );
457        tr_sha1( req3, "req3", 4, secret, KEY_LEN, NULL );
458        for( i = 0; i < SHA_DIGEST_LENGTH; ++i )
459            buf[i] = req2[i] ^ req3[i];
460        evbuffer_add( outbuf, buf, SHA_DIGEST_LENGTH );
461    }
462
463    /* ENCRYPT(VC, crypto_provide, len(PadC), PadC
464     * PadC is reserved for future extensions to the handshake...
465     * standard practice at this time is for it to be zero-length */
466    {
467        uint8_t vc[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
468
469        tr_peerIoWriteBuf( handshake->io, outbuf, false );
470        tr_cryptoEncryptInit( handshake->crypto );
471        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_RC4 );
472
473        evbuffer_add        ( outbuf, vc, VC_LENGTH );
474        evbuffer_add_uint32 ( outbuf, getCryptoProvide( handshake ) );
475        evbuffer_add_uint16 ( outbuf, 0 );
476    }
477
478    /* ENCRYPT len(IA)), ENCRYPT(IA) */
479    {
480        uint8_t msg[HANDSHAKE_SIZE];
481        buildHandshakeMessage( handshake, msg );
482
483        evbuffer_add_uint16 ( outbuf, sizeof( msg ) );
484        evbuffer_add        ( outbuf, msg, sizeof( msg ) );
485
486        handshake->haveSentBitTorrentHandshake = 1;
487    }
488
489    /* send it */
490    tr_cryptoDecryptInit( handshake->crypto );
491    setReadState( handshake, AWAITING_VC );
492    tr_peerIoWriteBuf( handshake->io, outbuf, false );
493
494    /* cleanup */
495    evbuffer_free( outbuf );
496    return READ_LATER;
497}
498
499static int
500readVC( tr_handshake *    handshake,
501        struct evbuffer * inbuf )
502{
503    const uint8_t key[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
504    const int     key_len = VC_LENGTH;
505    uint8_t       tmp[VC_LENGTH];
506
507    /* note: this works w/o having to `unwind' the buffer if
508     * we read too much, but it is pretty brute-force.
509     * it would be nice to make this cleaner. */
510    for( ; ; )
511    {
512        if( evbuffer_get_length( inbuf ) < VC_LENGTH )
513        {
514            dbgmsg( handshake, "not enough bytes... returning read_more" );
515            return READ_LATER;
516        }
517
518        memcpy( tmp, evbuffer_pullup( inbuf, key_len ), key_len );
519        tr_cryptoDecryptInit( handshake->crypto );
520        tr_cryptoDecrypt( handshake->crypto, key_len, tmp, tmp );
521        if( !memcmp( tmp, key, key_len ) )
522            break;
523
524        evbuffer_drain( inbuf, 1 );
525    }
526
527    dbgmsg( handshake, "got it!" );
528    evbuffer_drain( inbuf, key_len );
529    setState( handshake, AWAITING_CRYPTO_SELECT );
530    return READ_NOW;
531}
532
533static int
534readCryptoSelect( tr_handshake *    handshake,
535                  struct evbuffer * inbuf )
536{
537    uint32_t     crypto_select;
538    uint16_t     pad_d_len;
539    const size_t needlen = sizeof( uint32_t ) + sizeof( uint16_t );
540
541    if( evbuffer_get_length( inbuf ) < needlen )
542        return READ_LATER;
543
544    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_select );
545    handshake->crypto_select = crypto_select;
546    dbgmsg( handshake, "crypto select is %d", (int)crypto_select );
547    if( !( crypto_select & getCryptoProvide( handshake ) ) )
548    {
549        dbgmsg( handshake,
550                "peer selected an encryption option we didn't provide" );
551        return tr_handshakeDone( handshake, false );
552    }
553
554    tr_peerIoReadUint16( handshake->io, inbuf, &pad_d_len );
555    dbgmsg( handshake, "pad_d_len is %d", (int)pad_d_len );
556
557    if( pad_d_len > 512 )
558    {
559        dbgmsg( handshake, "encryption handshake: pad_d_len is too long" );
560        return tr_handshakeDone( handshake, false );
561    }
562
563    handshake->pad_d_len = pad_d_len;
564
565    setState( handshake, AWAITING_PAD_D );
566    return READ_NOW;
567}
568
569static int
570readPadD( tr_handshake *    handshake,
571          struct evbuffer * inbuf )
572{
573    const size_t needlen = handshake->pad_d_len;
574    uint8_t *    tmp;
575
576    dbgmsg( handshake, "pad d: need %zu, got %zu",
577            needlen, evbuffer_get_length( inbuf ) );
578    if( evbuffer_get_length( inbuf ) < needlen )
579        return READ_LATER;
580
581    tmp = tr_new( uint8_t, needlen );
582    tr_peerIoReadBytes( handshake->io, inbuf, tmp, needlen );
583    tr_free( tmp );
584
585    tr_peerIoSetEncryption( handshake->io, handshake->crypto_select );
586
587    setState( handshake, AWAITING_HANDSHAKE );
588    return READ_NOW;
589}
590
591/***
592****
593****  INCOMING CONNECTIONS
594****
595***/
596
597static int
598readHandshake( tr_handshake *    handshake,
599               struct evbuffer * inbuf )
600{
601    uint8_t   pstrlen;
602    uint8_t   pstr[20];
603    uint8_t   reserved[HANDSHAKE_FLAGS_LEN];
604    uint8_t   hash[SHA_DIGEST_LENGTH];
605
606    dbgmsg( handshake, "payload: need %d, got %zu",
607            INCOMING_HANDSHAKE_LEN, evbuffer_get_length( inbuf ) );
608
609    if( evbuffer_get_length( inbuf ) < INCOMING_HANDSHAKE_LEN )
610        return READ_LATER;
611
612    handshake->haveReadAnythingFromPeer = true;
613
614    pstrlen = evbuffer_pullup( inbuf, 1 )[0]; /* peek, don't read. We may be
615                                                 handing inbuf to AWAITING_YA */
616
617    if( pstrlen == 19 ) /* unencrypted */
618    {
619        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
620
621        if( handshake->encryptionMode == TR_ENCRYPTION_REQUIRED )
622        {
623            dbgmsg( handshake,
624                    "peer is unencrypted, and we're disallowing that" );
625            return tr_handshakeDone( handshake, false );
626        }
627    }
628    else /* encrypted or corrupt */
629    {
630        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_RC4 );
631
632        if( tr_peerIoIsIncoming( handshake->io ) )
633        {
634            dbgmsg( handshake,
635                    "I think peer is sending us an encrypted handshake..." );
636            setState( handshake, AWAITING_YA );
637            return READ_NOW;
638        }
639        tr_cryptoDecrypt( handshake->crypto, 1, &pstrlen, &pstrlen );
640
641        if( pstrlen != 19 )
642        {
643            dbgmsg( handshake,
644                    "I think peer has sent us a corrupt handshake..." );
645            return tr_handshakeDone( handshake, false );
646        }
647    }
648
649    evbuffer_drain( inbuf, 1 );
650
651    /* pstr (BitTorrent) */
652    assert( pstrlen == 19 );
653    tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen );
654    pstr[pstrlen] = '\0';
655    if( memcmp( pstr, "BitTorrent protocol", 19 ) )
656        return tr_handshakeDone( handshake, false );
657
658    /* reserved bytes */
659    tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof( reserved ) );
660
661    /**
662    *** Extensions
663    **/
664
665    tr_peerIoEnableLTEP( handshake->io, HANDSHAKE_HAS_LTEP( reserved ) );
666
667    tr_peerIoEnableFEXT( handshake->io, HANDSHAKE_HAS_FASTEXT( reserved ) );
668
669    tr_peerIoEnableDHT( handshake->io, HANDSHAKE_HAS_DHT( reserved ) );
670
671    /* torrent hash */
672    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof( hash ) );
673    if( tr_peerIoIsIncoming( handshake->io ) )
674    {
675        if( !tr_torrentExists( handshake->session, hash ) )
676        {
677            dbgmsg( handshake, "peer is trying to connect to us for a torrent we don't have." );
678            return tr_handshakeDone( handshake, false );
679        }
680        else
681        {
682            assert( !tr_peerIoHasTorrentHash( handshake->io ) );
683            tr_peerIoSetTorrentHash( handshake->io, hash );
684        }
685    }
686    else /* outgoing */
687    {
688        assert( tr_peerIoHasTorrentHash( handshake->io ) );
689        if( memcmp( hash, tr_peerIoGetTorrentHash( handshake->io ),
690                    SHA_DIGEST_LENGTH ) )
691        {
692            dbgmsg( handshake, "peer returned the wrong hash. wtf?" );
693            return tr_handshakeDone( handshake, false );
694        }
695    }
696
697    /**
698    ***  If it's an incoming message, we need to send a response handshake
699    **/
700
701    if( !handshake->haveSentBitTorrentHandshake )
702    {
703        uint8_t msg[HANDSHAKE_SIZE];
704        buildHandshakeMessage( handshake, msg );
705        tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
706        handshake->haveSentBitTorrentHandshake = 1;
707    }
708
709    setReadState( handshake, AWAITING_PEER_ID );
710    return READ_NOW;
711}
712
713static int
714readPeerId( tr_handshake    * handshake,
715            struct evbuffer * inbuf )
716{
717    bool peerIsGood;
718    char client[128];
719    tr_torrent * tor;
720    const uint8_t * tor_peer_id;
721    uint8_t peer_id[PEER_ID_LEN];
722
723    if( evbuffer_get_length( inbuf ) < PEER_ID_LEN )
724        return READ_LATER;
725
726    /* peer id */
727    tr_peerIoReadBytes( handshake->io, inbuf, peer_id, PEER_ID_LEN );
728    tr_peerIoSetPeersId( handshake->io, peer_id );
729    handshake->havePeerID = true;
730    tr_clientForId( client, sizeof( client ), peer_id );
731    dbgmsg( handshake, "peer-id is [%s] ... isIncoming is %d", client,
732            tr_peerIoIsIncoming( handshake->io ) );
733
734    /* if we've somehow connected to ourselves, don't keep the connection */
735    tor = tr_torrentFindFromHash( handshake->session, tr_peerIoGetTorrentHash( handshake->io ) );
736    tor_peer_id = tor ? tor->peer_id : tr_getPeerId( handshake->session );
737    peerIsGood = memcmp( peer_id, tor_peer_id, PEER_ID_LEN ) != 0;
738    dbgmsg( handshake, "isPeerGood == %d", (int)peerIsGood );
739    return tr_handshakeDone( handshake, peerIsGood );
740}
741
742static int
743readYa( tr_handshake *    handshake,
744        struct evbuffer * inbuf )
745{
746    uint8_t        ya[KEY_LEN];
747    uint8_t *      walk, outbuf[KEY_LEN + PadB_MAXLEN];
748    const uint8_t *myKey, *secret;
749    int            len;
750
751    dbgmsg( handshake, "in readYa... need %d, have %zu",
752            KEY_LEN, evbuffer_get_length( inbuf ) );
753    if( evbuffer_get_length( inbuf ) < KEY_LEN )
754        return READ_LATER;
755
756    /* read the incoming peer's public key */
757    evbuffer_remove( inbuf, ya, KEY_LEN );
758    secret = tr_cryptoComputeSecret( handshake->crypto, ya );
759    memcpy( handshake->mySecret, secret, KEY_LEN );
760    tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL );
761
762    dbgmsg( handshake, "sending B->A: Diffie Hellman Yb, PadB" );
763    /* send our public key to the peer */
764    walk = outbuf;
765    myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
766    memcpy( walk, myKey, len );
767    walk += len;
768    len = tr_cryptoRandInt( PadB_MAXLEN );
769    tr_cryptoRandBuf( walk, len );
770    walk += len;
771
772    setReadState( handshake, AWAITING_PAD_A );
773    tr_peerIoWriteBytes( handshake->io, outbuf, walk - outbuf, false );
774    return READ_NOW;
775}
776
777static int
778readPadA( tr_handshake * handshake, struct evbuffer * inbuf )
779{
780    /* resynchronizing on HASH('req1',S) */
781    struct evbuffer_ptr ptr = evbuffer_search( inbuf, (const char*)handshake->myReq1, SHA_DIGEST_LENGTH, NULL );
782
783    if( ptr.pos != -1 ) /* match */
784    {
785        evbuffer_drain( inbuf, ptr.pos );
786        dbgmsg( handshake, "found it... looking setting to awaiting_crypto_provide" );
787        setState( handshake, AWAITING_CRYPTO_PROVIDE );
788        return READ_NOW;
789    }
790    else
791    {
792        const size_t len = evbuffer_get_length( inbuf );
793        if( len > SHA_DIGEST_LENGTH )
794            evbuffer_drain( inbuf, len - SHA_DIGEST_LENGTH );
795        return READ_LATER;
796    }
797}
798
799static int
800readCryptoProvide( tr_handshake *    handshake,
801                   struct evbuffer * inbuf )
802{
803    /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide,
804      len(PadC)) */
805
806    int          i;
807    uint8_t      vc_in[VC_LENGTH];
808    uint8_t      req2[SHA_DIGEST_LENGTH];
809    uint8_t      req3[SHA_DIGEST_LENGTH];
810    uint8_t      obfuscatedTorrentHash[SHA_DIGEST_LENGTH];
811    uint16_t     padc_len = 0;
812    uint32_t     crypto_provide = 0;
813    const size_t needlen = SHA_DIGEST_LENGTH /* HASH('req1',s) */
814                           + SHA_DIGEST_LENGTH /* HASH('req2', SKEY) xor
815                                                 HASH('req3', S) */
816                           + VC_LENGTH
817                           + sizeof( crypto_provide )
818                           + sizeof( padc_len );
819    tr_torrent * tor = NULL;
820
821    if( evbuffer_get_length( inbuf ) < needlen )
822        return READ_LATER;
823
824    /* TODO: confirm they sent HASH('req1',S) here? */
825    evbuffer_drain( inbuf, SHA_DIGEST_LENGTH );
826
827    /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
828     * we can get the first half of that (the obufscatedTorrentHash)
829     * by building the latter and xor'ing it with what the peer sent us */
830    dbgmsg( handshake, "reading obfuscated torrent hash..." );
831    evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH );
832    tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL );
833    for( i = 0; i < SHA_DIGEST_LENGTH; ++i )
834        obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
835    if(( tor = tr_torrentFindFromObfuscatedHash( handshake->session, obfuscatedTorrentHash )))
836    {
837        const bool clientIsSeed = tr_torrentIsSeed( tor );
838        const bool peerIsSeed = tr_peerMgrPeerIsSeed( tor, tr_peerIoGetAddress( handshake->io, NULL ) );
839        dbgmsg( handshake, "got INCOMING connection's encrypted handshake for torrent [%s]",
840                tr_torrentName( tor ) );
841        tr_peerIoSetTorrentHash( handshake->io, tor->info.hash );
842
843        if( clientIsSeed && peerIsSeed )
844        {
845            dbgmsg( handshake, "another seed tried to reconnect to us!" );
846            return tr_handshakeDone( handshake, false );
847        }
848    }
849    else
850    {
851        dbgmsg( handshake, "can't find that torrent..." );
852        return tr_handshakeDone( handshake, false );
853    }
854
855    /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */
856
857    tr_cryptoDecryptInit( handshake->crypto );
858
859    tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH );
860
861    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );
862    handshake->crypto_provide = crypto_provide;
863    dbgmsg( handshake, "crypto_provide is %d", (int)crypto_provide );
864
865    tr_peerIoReadUint16( handshake->io, inbuf, &padc_len );
866    dbgmsg( handshake, "padc is %d", (int)padc_len );
867    handshake->pad_c_len = padc_len;
868    setState( handshake, AWAITING_PAD_C );
869    return READ_NOW;
870}
871
872static int
873readPadC( tr_handshake *    handshake,
874          struct evbuffer * inbuf )
875{
876    uint16_t     ia_len;
877    const size_t needlen = handshake->pad_c_len + sizeof( uint16_t );
878
879    if( evbuffer_get_length( inbuf ) < needlen )
880        return READ_LATER;
881
882    evbuffer_drain( inbuf, handshake->pad_c_len );
883
884    tr_peerIoReadUint16( handshake->io, inbuf, &ia_len );
885    dbgmsg( handshake, "ia_len is %d", (int)ia_len );
886    handshake->ia_len = ia_len;
887    setState( handshake, AWAITING_IA );
888    return READ_NOW;
889}
890
891static int
892readIA( tr_handshake *    handshake,
893        struct evbuffer * inbuf )
894{
895    const size_t      needlen = handshake->ia_len;
896    struct evbuffer * outbuf;
897    uint32_t          crypto_select;
898
899    dbgmsg( handshake, "reading IA... have %zu, need %zu",
900            evbuffer_get_length( inbuf ), needlen );
901    if( evbuffer_get_length( inbuf ) < needlen )
902        return READ_LATER;
903
904    /**
905    ***  B->A: ENCRYPT(VC, crypto_select, len(padD), padD), ENCRYPT2(Payload Stream)
906    **/
907
908    tr_cryptoEncryptInit( handshake->crypto );
909    outbuf = evbuffer_new( );
910
911    dbgmsg( handshake, "sending vc" );
912    /* send VC */
913    {
914        uint8_t vc[VC_LENGTH];
915        memset( vc, 0, VC_LENGTH );
916        evbuffer_add( outbuf, vc, VC_LENGTH );
917    }
918
919    /* send crypto_select */
920    crypto_select = getCryptoSelect( handshake, handshake->crypto_provide );
921    if( crypto_select )
922    {
923        dbgmsg( handshake, "selecting crypto mode '%d'", (int)crypto_select );
924        evbuffer_add_uint32( outbuf, crypto_select );
925    }
926    else
927    {
928        dbgmsg( handshake, "peer didn't offer an encryption mode we like." );
929        evbuffer_free( outbuf );
930        return tr_handshakeDone( handshake, false );
931    }
932
933    dbgmsg( handshake, "sending pad d" );
934    /* ENCRYPT(VC, crypto_provide, len(PadD), PadD
935     * PadD is reserved for future extensions to the handshake...
936     * standard practice at this time is for it to be zero-length */
937    {
938        const uint16_t len = 0;
939        evbuffer_add_uint16( outbuf, len );
940    }
941
942    /* maybe de-encrypt our connection */
943    if( crypto_select == CRYPTO_PROVIDE_PLAINTEXT )
944    {
945        tr_peerIoWriteBuf( handshake->io, outbuf, false );
946        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
947    }
948
949    dbgmsg( handshake, "sending handshake" );
950    /* send our handshake */
951    {
952        uint8_t msg[HANDSHAKE_SIZE];
953        buildHandshakeMessage( handshake, msg );
954
955        evbuffer_add( outbuf, msg, sizeof( msg ) );
956        handshake->haveSentBitTorrentHandshake = 1;
957    }
958
959    /* send it out */
960    tr_peerIoWriteBuf( handshake->io, outbuf, false );
961    evbuffer_free( outbuf );
962
963    /* now await the handshake */
964    setState( handshake, AWAITING_PAYLOAD_STREAM );
965    return READ_NOW;
966}
967
968static int
969readPayloadStream( tr_handshake    * handshake,
970                   struct evbuffer * inbuf )
971{
972    int i;
973    const size_t      needlen = HANDSHAKE_SIZE;
974
975    dbgmsg( handshake, "reading payload stream... have %zu, need %zu",
976            evbuffer_get_length( inbuf ), needlen );
977    if( evbuffer_get_length( inbuf ) < needlen )
978        return READ_LATER;
979
980    /* parse the handshake ... */
981    i = parseHandshake( handshake, inbuf );
982    dbgmsg( handshake, "parseHandshake returned %d", i );
983    if( i != HANDSHAKE_OK )
984        return tr_handshakeDone( handshake, false );
985
986    /* we've completed the BT handshake... pass the work on to peer-msgs */
987    return tr_handshakeDone( handshake, true );
988}
989
990/***
991****
992****
993****
994***/
995
996static ReadState
997canRead( struct tr_peerIo * io, void * arg, size_t * piece )
998{
999    tr_handshake    * handshake = arg;
1000    struct evbuffer * inbuf = tr_peerIoGetReadBuffer( io );
1001    ReadState         ret;
1002    bool              readyForMore = true;
1003
1004    assert( tr_isPeerIo( io ) );
1005
1006    /* no piece data in handshake */
1007    *piece = 0;
1008
1009    dbgmsg( handshake, "handling canRead; state is [%s]",
1010           getStateName( handshake->state ) );
1011
1012    while( readyForMore )
1013    {
1014        switch( handshake->state )
1015        {
1016            case AWAITING_HANDSHAKE:
1017                ret = readHandshake    ( handshake, inbuf ); break;
1018
1019            case AWAITING_PEER_ID:
1020                ret = readPeerId       ( handshake, inbuf ); break;
1021
1022            case AWAITING_YA:
1023                ret = readYa           ( handshake, inbuf ); break;
1024
1025            case AWAITING_PAD_A:
1026                ret = readPadA         ( handshake, inbuf ); break;
1027
1028            case AWAITING_CRYPTO_PROVIDE:
1029                ret = readCryptoProvide( handshake, inbuf ); break;
1030
1031            case AWAITING_PAD_C:
1032                ret = readPadC         ( handshake, inbuf ); break;
1033
1034            case AWAITING_IA:
1035                ret = readIA           ( handshake, inbuf ); break;
1036
1037            case AWAITING_PAYLOAD_STREAM:
1038                ret = readPayloadStream( handshake, inbuf ); break;
1039
1040            case AWAITING_YB:
1041                ret = readYb           ( handshake, inbuf ); break;
1042
1043            case AWAITING_VC:
1044                ret = readVC           ( handshake, inbuf ); break;
1045
1046            case AWAITING_CRYPTO_SELECT:
1047                ret = readCryptoSelect ( handshake, inbuf ); break;
1048
1049            case AWAITING_PAD_D:
1050                ret = readPadD         ( handshake, inbuf ); break;
1051
1052            default:
1053                assert( 0 );
1054        }
1055
1056        if( ret != READ_NOW )
1057            readyForMore = false;
1058        else if( handshake->state == AWAITING_PAD_C )
1059            readyForMore = evbuffer_get_length( inbuf ) >= handshake->pad_c_len;
1060        else if( handshake->state == AWAITING_PAD_D )
1061            readyForMore = evbuffer_get_length( inbuf ) >= handshake->pad_d_len;
1062        else if( handshake->state == AWAITING_IA )
1063            readyForMore = evbuffer_get_length( inbuf ) >= handshake->ia_len;
1064    }
1065
1066    return ret;
1067}
1068
1069static bool
1070fireDoneFunc( tr_handshake * handshake, bool isConnected )
1071{
1072    const uint8_t * peer_id = isConnected && handshake->havePeerID
1073                            ? tr_peerIoGetPeersId( handshake->io )
1074                            : NULL;
1075    const bool success = ( *handshake->doneCB )( handshake,
1076                                                 handshake->io,
1077                                                 handshake->haveReadAnythingFromPeer,
1078                                                 isConnected,
1079                                                 peer_id,
1080                                                 handshake->doneUserData );
1081
1082    return success;
1083}
1084
1085static void
1086tr_handshakeFree( tr_handshake * handshake )
1087{
1088    if( handshake->io )
1089        tr_peerIoUnref( handshake->io ); /* balanced by the ref in tr_handshakeNew */
1090
1091    event_free( handshake->timeout_timer );
1092    tr_free( handshake );
1093}
1094
1095static int
1096tr_handshakeDone( tr_handshake * handshake, bool isOK )
1097{
1098    bool success;
1099
1100    dbgmsg( handshake, "handshakeDone: %s", isOK ? "connected" : "aborting" );
1101    tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
1102
1103    success = fireDoneFunc( handshake, isOK );
1104
1105    tr_handshakeFree( handshake );
1106
1107    return success ? READ_LATER : READ_ERR;
1108}
1109
1110void
1111tr_handshakeAbort( tr_handshake * handshake )
1112{
1113    if( handshake != NULL )
1114        tr_handshakeDone( handshake, false );
1115}
1116
1117static void
1118gotError( tr_peerIo  * io,
1119          short        what,
1120          void       * vhandshake )
1121{
1122    int errcode = errno;
1123    tr_handshake * handshake = vhandshake;
1124
1125    if( io->utp_socket && !io->isIncoming && handshake->state == AWAITING_YB ) {
1126        /* This peer probably doesn't speak uTP. */
1127        tr_torrent *tor =
1128            tr_peerIoHasTorrentHash( io ) ?
1129            tr_torrentFindFromHash( handshake->session,
1130                                    tr_peerIoGetTorrentHash( io ) ) :
1131            NULL;
1132        /* Don't mark a peer as non-uTP unless it's really a connect failure. */
1133        if( tor && ( errcode == ETIMEDOUT || errcode == ECONNREFUSED ) ) {
1134            tr_torrentLock( tor );
1135            tr_peerMgrSetUtpFailed( tor,
1136                                    tr_peerIoGetAddress( io, NULL ),
1137                                    true );
1138            tr_torrentUnlock( tor );
1139        }
1140
1141        if( !tr_peerIoReconnect( handshake->io ) ) {
1142            uint8_t msg[HANDSHAKE_SIZE];
1143            buildHandshakeMessage( handshake, msg );
1144            handshake->haveSentBitTorrentHandshake = 1;
1145            setReadState( handshake, AWAITING_HANDSHAKE );
1146            tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
1147        }
1148    }
1149
1150    /* if the error happened while we were sending a public key, we might
1151     * have encountered a peer that doesn't do encryption... reconnect and
1152     * try a plaintext handshake */
1153    if( ( ( handshake->state == AWAITING_YB )
1154        || ( handshake->state == AWAITING_VC ) )
1155      && ( handshake->encryptionMode != TR_ENCRYPTION_REQUIRED )
1156      && ( !tr_peerIoReconnect( handshake->io ) ) )
1157    {
1158        uint8_t msg[HANDSHAKE_SIZE];
1159
1160        dbgmsg( handshake, "handshake failed, trying plaintext..." );
1161        buildHandshakeMessage( handshake, msg );
1162        handshake->haveSentBitTorrentHandshake = 1;
1163        setReadState( handshake, AWAITING_HANDSHAKE );
1164        tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
1165    }
1166    else
1167    {
1168        dbgmsg( handshake, "libevent got an error what==%d, errno=%d (%s)",
1169               (int)what, errno, tr_strerror( errno ) );
1170        tr_handshakeDone( handshake, false );
1171    }
1172}
1173
1174/**
1175***
1176**/
1177
1178static void
1179handshakeTimeout( int foo UNUSED, short bar UNUSED, void * handshake )
1180{
1181    tr_handshakeAbort( handshake );
1182}
1183
1184tr_handshake*
1185tr_handshakeNew( tr_peerIo           * io,
1186                 tr_encryption_mode    encryptionMode,
1187                 handshakeDoneCB       doneCB,
1188                 void                * doneUserData )
1189{
1190    tr_handshake * handshake;
1191    tr_session * session = tr_peerIoGetSession( io );
1192
1193    handshake = tr_new0( tr_handshake, 1 );
1194    handshake->io = io;
1195    handshake->crypto = tr_peerIoGetCrypto( io );
1196    handshake->encryptionMode = encryptionMode;
1197    handshake->doneCB = doneCB;
1198    handshake->doneUserData = doneUserData;
1199    handshake->session = session;
1200    handshake->timeout_timer = evtimer_new( session->event_base, handshakeTimeout, handshake );
1201    tr_timerAdd( handshake->timeout_timer, HANDSHAKE_TIMEOUT_SEC, 0 );
1202
1203    tr_peerIoRef( io ); /* balanced by the unref in tr_handshakeFree */
1204    tr_peerIoSetIOFuncs( handshake->io, canRead, NULL, gotError, handshake );
1205    tr_peerIoSetEncryption( io, PEER_ENCRYPTION_NONE );
1206
1207    if( tr_peerIoIsIncoming( handshake->io ) )
1208        setReadState( handshake, AWAITING_HANDSHAKE );
1209    else if( encryptionMode != TR_CLEAR_PREFERRED )
1210        sendYa( handshake );
1211    else
1212    {
1213        uint8_t msg[HANDSHAKE_SIZE];
1214        buildHandshakeMessage( handshake, msg );
1215
1216        handshake->haveSentBitTorrentHandshake = 1;
1217        setReadState( handshake, AWAITING_HANDSHAKE );
1218        tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
1219    }
1220
1221    return handshake;
1222}
1223
1224struct tr_peerIo*
1225tr_handshakeGetIO( tr_handshake * handshake )
1226{
1227    assert( handshake );
1228    assert( handshake->io );
1229
1230    return handshake->io;
1231}
1232
1233struct tr_peerIo*
1234tr_handshakeStealIO( tr_handshake * handshake )
1235{
1236    struct tr_peerIo * io;
1237
1238    assert( handshake );
1239    assert( handshake->io );
1240
1241    io = handshake->io;
1242    handshake->io = NULL;
1243    return io;
1244}
1245
1246const tr_address *
1247tr_handshakeGetAddr( const struct tr_handshake * handshake,
1248                     tr_port                   * port )
1249{
1250    assert( handshake );
1251    assert( handshake->io );
1252
1253    return tr_peerIoGetAddress( handshake->io, port );
1254}
1255
Note: See TracBrowser for help on using the repository browser.