source: trunk/libtransmission/handshake.c @ 12323

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

(trunk libT) more heap pruning: avoid an unnecessary malloc() + free() when reading PadD during an outbound encrypted handshake

  • Property svn:keywords set to Date Rev Author Id
File size: 37.3 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 12323 2011-04-05 21:14:44Z 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
575    dbgmsg( handshake, "pad d: need %zu, got %zu",
576            needlen, evbuffer_get_length( inbuf ) );
577    if( evbuffer_get_length( inbuf ) < needlen )
578        return READ_LATER;
579
580    tr_peerIoDrain( handshake->io, inbuf, needlen );
581
582    tr_peerIoSetEncryption( handshake->io, handshake->crypto_select );
583
584    setState( handshake, AWAITING_HANDSHAKE );
585    return READ_NOW;
586}
587
588/***
589****
590****  INCOMING CONNECTIONS
591****
592***/
593
594static int
595readHandshake( tr_handshake *    handshake,
596               struct evbuffer * inbuf )
597{
598    uint8_t   pstrlen;
599    uint8_t   pstr[20];
600    uint8_t   reserved[HANDSHAKE_FLAGS_LEN];
601    uint8_t   hash[SHA_DIGEST_LENGTH];
602
603    dbgmsg( handshake, "payload: need %d, got %zu",
604            INCOMING_HANDSHAKE_LEN, evbuffer_get_length( inbuf ) );
605
606    if( evbuffer_get_length( inbuf ) < INCOMING_HANDSHAKE_LEN )
607        return READ_LATER;
608
609    handshake->haveReadAnythingFromPeer = true;
610
611    pstrlen = evbuffer_pullup( inbuf, 1 )[0]; /* peek, don't read. We may be
612                                                 handing inbuf to AWAITING_YA */
613
614    if( pstrlen == 19 ) /* unencrypted */
615    {
616        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
617
618        if( handshake->encryptionMode == TR_ENCRYPTION_REQUIRED )
619        {
620            dbgmsg( handshake,
621                    "peer is unencrypted, and we're disallowing that" );
622            return tr_handshakeDone( handshake, false );
623        }
624    }
625    else /* encrypted or corrupt */
626    {
627        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_RC4 );
628
629        if( tr_peerIoIsIncoming( handshake->io ) )
630        {
631            dbgmsg( handshake,
632                    "I think peer is sending us an encrypted handshake..." );
633            setState( handshake, AWAITING_YA );
634            return READ_NOW;
635        }
636        tr_cryptoDecrypt( handshake->crypto, 1, &pstrlen, &pstrlen );
637
638        if( pstrlen != 19 )
639        {
640            dbgmsg( handshake,
641                    "I think peer has sent us a corrupt handshake..." );
642            return tr_handshakeDone( handshake, false );
643        }
644    }
645
646    evbuffer_drain( inbuf, 1 );
647
648    /* pstr (BitTorrent) */
649    assert( pstrlen == 19 );
650    tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen );
651    pstr[pstrlen] = '\0';
652    if( memcmp( pstr, "BitTorrent protocol", 19 ) )
653        return tr_handshakeDone( handshake, false );
654
655    /* reserved bytes */
656    tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof( reserved ) );
657
658    /**
659    *** Extensions
660    **/
661
662    tr_peerIoEnableLTEP( handshake->io, HANDSHAKE_HAS_LTEP( reserved ) );
663
664    tr_peerIoEnableFEXT( handshake->io, HANDSHAKE_HAS_FASTEXT( reserved ) );
665
666    tr_peerIoEnableDHT( handshake->io, HANDSHAKE_HAS_DHT( reserved ) );
667
668    /* torrent hash */
669    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof( hash ) );
670    if( tr_peerIoIsIncoming( handshake->io ) )
671    {
672        if( !tr_torrentExists( handshake->session, hash ) )
673        {
674            dbgmsg( handshake, "peer is trying to connect to us for a torrent we don't have." );
675            return tr_handshakeDone( handshake, false );
676        }
677        else
678        {
679            assert( !tr_peerIoHasTorrentHash( handshake->io ) );
680            tr_peerIoSetTorrentHash( handshake->io, hash );
681        }
682    }
683    else /* outgoing */
684    {
685        assert( tr_peerIoHasTorrentHash( handshake->io ) );
686        if( memcmp( hash, tr_peerIoGetTorrentHash( handshake->io ),
687                    SHA_DIGEST_LENGTH ) )
688        {
689            dbgmsg( handshake, "peer returned the wrong hash. wtf?" );
690            return tr_handshakeDone( handshake, false );
691        }
692    }
693
694    /**
695    ***  If it's an incoming message, we need to send a response handshake
696    **/
697
698    if( !handshake->haveSentBitTorrentHandshake )
699    {
700        uint8_t msg[HANDSHAKE_SIZE];
701        buildHandshakeMessage( handshake, msg );
702        tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
703        handshake->haveSentBitTorrentHandshake = 1;
704    }
705
706    setReadState( handshake, AWAITING_PEER_ID );
707    return READ_NOW;
708}
709
710static int
711readPeerId( tr_handshake    * handshake,
712            struct evbuffer * inbuf )
713{
714    bool peerIsGood;
715    char client[128];
716    tr_torrent * tor;
717    const uint8_t * tor_peer_id;
718    uint8_t peer_id[PEER_ID_LEN];
719
720    if( evbuffer_get_length( inbuf ) < PEER_ID_LEN )
721        return READ_LATER;
722
723    /* peer id */
724    tr_peerIoReadBytes( handshake->io, inbuf, peer_id, PEER_ID_LEN );
725    tr_peerIoSetPeersId( handshake->io, peer_id );
726    handshake->havePeerID = true;
727    tr_clientForId( client, sizeof( client ), peer_id );
728    dbgmsg( handshake, "peer-id is [%s] ... isIncoming is %d", client,
729            tr_peerIoIsIncoming( handshake->io ) );
730
731    /* if we've somehow connected to ourselves, don't keep the connection */
732    tor = tr_torrentFindFromHash( handshake->session, tr_peerIoGetTorrentHash( handshake->io ) );
733    tor_peer_id = tor ? tor->peer_id : tr_getPeerId( handshake->session );
734    peerIsGood = memcmp( peer_id, tor_peer_id, PEER_ID_LEN ) != 0;
735    dbgmsg( handshake, "isPeerGood == %d", (int)peerIsGood );
736    return tr_handshakeDone( handshake, peerIsGood );
737}
738
739static int
740readYa( tr_handshake *    handshake,
741        struct evbuffer * inbuf )
742{
743    uint8_t        ya[KEY_LEN];
744    uint8_t *      walk, outbuf[KEY_LEN + PadB_MAXLEN];
745    const uint8_t *myKey, *secret;
746    int            len;
747
748    dbgmsg( handshake, "in readYa... need %d, have %zu",
749            KEY_LEN, evbuffer_get_length( inbuf ) );
750    if( evbuffer_get_length( inbuf ) < KEY_LEN )
751        return READ_LATER;
752
753    /* read the incoming peer's public key */
754    evbuffer_remove( inbuf, ya, KEY_LEN );
755    secret = tr_cryptoComputeSecret( handshake->crypto, ya );
756    memcpy( handshake->mySecret, secret, KEY_LEN );
757    tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL );
758
759    dbgmsg( handshake, "sending B->A: Diffie Hellman Yb, PadB" );
760    /* send our public key to the peer */
761    walk = outbuf;
762    myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
763    memcpy( walk, myKey, len );
764    walk += len;
765    len = tr_cryptoRandInt( PadB_MAXLEN );
766    tr_cryptoRandBuf( walk, len );
767    walk += len;
768
769    setReadState( handshake, AWAITING_PAD_A );
770    tr_peerIoWriteBytes( handshake->io, outbuf, walk - outbuf, false );
771    return READ_NOW;
772}
773
774static int
775readPadA( tr_handshake * handshake, struct evbuffer * inbuf )
776{
777    /* resynchronizing on HASH('req1',S) */
778    struct evbuffer_ptr ptr = evbuffer_search( inbuf, (const char*)handshake->myReq1, SHA_DIGEST_LENGTH, NULL );
779
780    if( ptr.pos != -1 ) /* match */
781    {
782        evbuffer_drain( inbuf, ptr.pos );
783        dbgmsg( handshake, "found it... looking setting to awaiting_crypto_provide" );
784        setState( handshake, AWAITING_CRYPTO_PROVIDE );
785        return READ_NOW;
786    }
787    else
788    {
789        const size_t len = evbuffer_get_length( inbuf );
790        if( len > SHA_DIGEST_LENGTH )
791            evbuffer_drain( inbuf, len - SHA_DIGEST_LENGTH );
792        return READ_LATER;
793    }
794}
795
796static int
797readCryptoProvide( tr_handshake *    handshake,
798                   struct evbuffer * inbuf )
799{
800    /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide,
801      len(PadC)) */
802
803    int          i;
804    uint8_t      vc_in[VC_LENGTH];
805    uint8_t      req2[SHA_DIGEST_LENGTH];
806    uint8_t      req3[SHA_DIGEST_LENGTH];
807    uint8_t      obfuscatedTorrentHash[SHA_DIGEST_LENGTH];
808    uint16_t     padc_len = 0;
809    uint32_t     crypto_provide = 0;
810    const size_t needlen = SHA_DIGEST_LENGTH /* HASH('req1',s) */
811                           + SHA_DIGEST_LENGTH /* HASH('req2', SKEY) xor
812                                                 HASH('req3', S) */
813                           + VC_LENGTH
814                           + sizeof( crypto_provide )
815                           + sizeof( padc_len );
816    tr_torrent * tor = NULL;
817
818    if( evbuffer_get_length( inbuf ) < needlen )
819        return READ_LATER;
820
821    /* TODO: confirm they sent HASH('req1',S) here? */
822    evbuffer_drain( inbuf, SHA_DIGEST_LENGTH );
823
824    /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
825     * we can get the first half of that (the obufscatedTorrentHash)
826     * by building the latter and xor'ing it with what the peer sent us */
827    dbgmsg( handshake, "reading obfuscated torrent hash..." );
828    evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH );
829    tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL );
830    for( i = 0; i < SHA_DIGEST_LENGTH; ++i )
831        obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
832    if(( tor = tr_torrentFindFromObfuscatedHash( handshake->session, obfuscatedTorrentHash )))
833    {
834        const bool clientIsSeed = tr_torrentIsSeed( tor );
835        const bool peerIsSeed = tr_peerMgrPeerIsSeed( tor, tr_peerIoGetAddress( handshake->io, NULL ) );
836        dbgmsg( handshake, "got INCOMING connection's encrypted handshake for torrent [%s]",
837                tr_torrentName( tor ) );
838        tr_peerIoSetTorrentHash( handshake->io, tor->info.hash );
839
840        if( clientIsSeed && peerIsSeed )
841        {
842            dbgmsg( handshake, "another seed tried to reconnect to us!" );
843            return tr_handshakeDone( handshake, false );
844        }
845    }
846    else
847    {
848        dbgmsg( handshake, "can't find that torrent..." );
849        return tr_handshakeDone( handshake, false );
850    }
851
852    /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */
853
854    tr_cryptoDecryptInit( handshake->crypto );
855
856    tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH );
857
858    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );
859    handshake->crypto_provide = crypto_provide;
860    dbgmsg( handshake, "crypto_provide is %d", (int)crypto_provide );
861
862    tr_peerIoReadUint16( handshake->io, inbuf, &padc_len );
863    dbgmsg( handshake, "padc is %d", (int)padc_len );
864    handshake->pad_c_len = padc_len;
865    setState( handshake, AWAITING_PAD_C );
866    return READ_NOW;
867}
868
869static int
870readPadC( tr_handshake *    handshake,
871          struct evbuffer * inbuf )
872{
873    uint16_t     ia_len;
874    const size_t needlen = handshake->pad_c_len + sizeof( uint16_t );
875
876    if( evbuffer_get_length( inbuf ) < needlen )
877        return READ_LATER;
878
879    evbuffer_drain( inbuf, handshake->pad_c_len );
880
881    tr_peerIoReadUint16( handshake->io, inbuf, &ia_len );
882    dbgmsg( handshake, "ia_len is %d", (int)ia_len );
883    handshake->ia_len = ia_len;
884    setState( handshake, AWAITING_IA );
885    return READ_NOW;
886}
887
888static int
889readIA( tr_handshake *    handshake,
890        struct evbuffer * inbuf )
891{
892    const size_t      needlen = handshake->ia_len;
893    struct evbuffer * outbuf;
894    uint32_t          crypto_select;
895
896    dbgmsg( handshake, "reading IA... have %zu, need %zu",
897            evbuffer_get_length( inbuf ), needlen );
898    if( evbuffer_get_length( inbuf ) < needlen )
899        return READ_LATER;
900
901    /**
902    ***  B->A: ENCRYPT(VC, crypto_select, len(padD), padD), ENCRYPT2(Payload Stream)
903    **/
904
905    tr_cryptoEncryptInit( handshake->crypto );
906    outbuf = evbuffer_new( );
907
908    dbgmsg( handshake, "sending vc" );
909    /* send VC */
910    {
911        uint8_t vc[VC_LENGTH];
912        memset( vc, 0, VC_LENGTH );
913        evbuffer_add( outbuf, vc, VC_LENGTH );
914    }
915
916    /* send crypto_select */
917    crypto_select = getCryptoSelect( handshake, handshake->crypto_provide );
918    if( crypto_select )
919    {
920        dbgmsg( handshake, "selecting crypto mode '%d'", (int)crypto_select );
921        evbuffer_add_uint32( outbuf, crypto_select );
922    }
923    else
924    {
925        dbgmsg( handshake, "peer didn't offer an encryption mode we like." );
926        evbuffer_free( outbuf );
927        return tr_handshakeDone( handshake, false );
928    }
929
930    dbgmsg( handshake, "sending pad d" );
931    /* ENCRYPT(VC, crypto_provide, len(PadD), PadD
932     * PadD is reserved for future extensions to the handshake...
933     * standard practice at this time is for it to be zero-length */
934    {
935        const uint16_t len = 0;
936        evbuffer_add_uint16( outbuf, len );
937    }
938
939    /* maybe de-encrypt our connection */
940    if( crypto_select == CRYPTO_PROVIDE_PLAINTEXT )
941    {
942        tr_peerIoWriteBuf( handshake->io, outbuf, false );
943        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
944    }
945
946    dbgmsg( handshake, "sending handshake" );
947    /* send our handshake */
948    {
949        uint8_t msg[HANDSHAKE_SIZE];
950        buildHandshakeMessage( handshake, msg );
951
952        evbuffer_add( outbuf, msg, sizeof( msg ) );
953        handshake->haveSentBitTorrentHandshake = 1;
954    }
955
956    /* send it out */
957    tr_peerIoWriteBuf( handshake->io, outbuf, false );
958    evbuffer_free( outbuf );
959
960    /* now await the handshake */
961    setState( handshake, AWAITING_PAYLOAD_STREAM );
962    return READ_NOW;
963}
964
965static int
966readPayloadStream( tr_handshake    * handshake,
967                   struct evbuffer * inbuf )
968{
969    int i;
970    const size_t      needlen = HANDSHAKE_SIZE;
971
972    dbgmsg( handshake, "reading payload stream... have %zu, need %zu",
973            evbuffer_get_length( inbuf ), needlen );
974    if( evbuffer_get_length( inbuf ) < needlen )
975        return READ_LATER;
976
977    /* parse the handshake ... */
978    i = parseHandshake( handshake, inbuf );
979    dbgmsg( handshake, "parseHandshake returned %d", i );
980    if( i != HANDSHAKE_OK )
981        return tr_handshakeDone( handshake, false );
982
983    /* we've completed the BT handshake... pass the work on to peer-msgs */
984    return tr_handshakeDone( handshake, true );
985}
986
987/***
988****
989****
990****
991***/
992
993static ReadState
994canRead( struct tr_peerIo * io, void * arg, size_t * piece )
995{
996    tr_handshake    * handshake = arg;
997    struct evbuffer * inbuf = tr_peerIoGetReadBuffer( io );
998    ReadState         ret;
999    bool              readyForMore = true;
1000
1001    assert( tr_isPeerIo( io ) );
1002
1003    /* no piece data in handshake */
1004    *piece = 0;
1005
1006    dbgmsg( handshake, "handling canRead; state is [%s]",
1007           getStateName( handshake->state ) );
1008
1009    while( readyForMore )
1010    {
1011        switch( handshake->state )
1012        {
1013            case AWAITING_HANDSHAKE:
1014                ret = readHandshake    ( handshake, inbuf ); break;
1015
1016            case AWAITING_PEER_ID:
1017                ret = readPeerId       ( handshake, inbuf ); break;
1018
1019            case AWAITING_YA:
1020                ret = readYa           ( handshake, inbuf ); break;
1021
1022            case AWAITING_PAD_A:
1023                ret = readPadA         ( handshake, inbuf ); break;
1024
1025            case AWAITING_CRYPTO_PROVIDE:
1026                ret = readCryptoProvide( handshake, inbuf ); break;
1027
1028            case AWAITING_PAD_C:
1029                ret = readPadC         ( handshake, inbuf ); break;
1030
1031            case AWAITING_IA:
1032                ret = readIA           ( handshake, inbuf ); break;
1033
1034            case AWAITING_PAYLOAD_STREAM:
1035                ret = readPayloadStream( handshake, inbuf ); break;
1036
1037            case AWAITING_YB:
1038                ret = readYb           ( handshake, inbuf ); break;
1039
1040            case AWAITING_VC:
1041                ret = readVC           ( handshake, inbuf ); break;
1042
1043            case AWAITING_CRYPTO_SELECT:
1044                ret = readCryptoSelect ( handshake, inbuf ); break;
1045
1046            case AWAITING_PAD_D:
1047                ret = readPadD         ( handshake, inbuf ); break;
1048
1049            default:
1050                assert( 0 );
1051        }
1052
1053        if( ret != READ_NOW )
1054            readyForMore = false;
1055        else if( handshake->state == AWAITING_PAD_C )
1056            readyForMore = evbuffer_get_length( inbuf ) >= handshake->pad_c_len;
1057        else if( handshake->state == AWAITING_PAD_D )
1058            readyForMore = evbuffer_get_length( inbuf ) >= handshake->pad_d_len;
1059        else if( handshake->state == AWAITING_IA )
1060            readyForMore = evbuffer_get_length( inbuf ) >= handshake->ia_len;
1061    }
1062
1063    return ret;
1064}
1065
1066static bool
1067fireDoneFunc( tr_handshake * handshake, bool isConnected )
1068{
1069    const uint8_t * peer_id = isConnected && handshake->havePeerID
1070                            ? tr_peerIoGetPeersId( handshake->io )
1071                            : NULL;
1072    const bool success = ( *handshake->doneCB )( handshake,
1073                                                 handshake->io,
1074                                                 handshake->haveReadAnythingFromPeer,
1075                                                 isConnected,
1076                                                 peer_id,
1077                                                 handshake->doneUserData );
1078
1079    return success;
1080}
1081
1082static void
1083tr_handshakeFree( tr_handshake * handshake )
1084{
1085    if( handshake->io )
1086        tr_peerIoUnref( handshake->io ); /* balanced by the ref in tr_handshakeNew */
1087
1088    event_free( handshake->timeout_timer );
1089    tr_free( handshake );
1090}
1091
1092static int
1093tr_handshakeDone( tr_handshake * handshake, bool isOK )
1094{
1095    bool success;
1096
1097    dbgmsg( handshake, "handshakeDone: %s", isOK ? "connected" : "aborting" );
1098    tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
1099
1100    success = fireDoneFunc( handshake, isOK );
1101
1102    tr_handshakeFree( handshake );
1103
1104    return success ? READ_LATER : READ_ERR;
1105}
1106
1107void
1108tr_handshakeAbort( tr_handshake * handshake )
1109{
1110    if( handshake != NULL )
1111        tr_handshakeDone( handshake, false );
1112}
1113
1114static void
1115gotError( tr_peerIo  * io,
1116          short        what,
1117          void       * vhandshake )
1118{
1119    int errcode = errno;
1120    tr_handshake * handshake = vhandshake;
1121
1122    if( io->utp_socket && !io->isIncoming && handshake->state == AWAITING_YB ) {
1123        /* This peer probably doesn't speak uTP. */
1124        tr_torrent *tor =
1125            tr_peerIoHasTorrentHash( io ) ?
1126            tr_torrentFindFromHash( handshake->session,
1127                                    tr_peerIoGetTorrentHash( io ) ) :
1128            NULL;
1129        /* Don't mark a peer as non-uTP unless it's really a connect failure. */
1130        if( tor && ( errcode == ETIMEDOUT || errcode == ECONNREFUSED ) ) {
1131            tr_torrentLock( tor );
1132            tr_peerMgrSetUtpFailed( tor,
1133                                    tr_peerIoGetAddress( io, NULL ),
1134                                    true );
1135            tr_torrentUnlock( tor );
1136        }
1137
1138        if( !tr_peerIoReconnect( handshake->io ) ) {
1139            uint8_t msg[HANDSHAKE_SIZE];
1140            buildHandshakeMessage( handshake, msg );
1141            handshake->haveSentBitTorrentHandshake = 1;
1142            setReadState( handshake, AWAITING_HANDSHAKE );
1143            tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
1144        }
1145    }
1146
1147    /* if the error happened while we were sending a public key, we might
1148     * have encountered a peer that doesn't do encryption... reconnect and
1149     * try a plaintext handshake */
1150    if( ( ( handshake->state == AWAITING_YB )
1151        || ( handshake->state == AWAITING_VC ) )
1152      && ( handshake->encryptionMode != TR_ENCRYPTION_REQUIRED )
1153      && ( !tr_peerIoReconnect( handshake->io ) ) )
1154    {
1155        uint8_t msg[HANDSHAKE_SIZE];
1156
1157        dbgmsg( handshake, "handshake failed, trying plaintext..." );
1158        buildHandshakeMessage( handshake, msg );
1159        handshake->haveSentBitTorrentHandshake = 1;
1160        setReadState( handshake, AWAITING_HANDSHAKE );
1161        tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
1162    }
1163    else
1164    {
1165        dbgmsg( handshake, "libevent got an error what==%d, errno=%d (%s)",
1166               (int)what, errno, tr_strerror( errno ) );
1167        tr_handshakeDone( handshake, false );
1168    }
1169}
1170
1171/**
1172***
1173**/
1174
1175static void
1176handshakeTimeout( int foo UNUSED, short bar UNUSED, void * handshake )
1177{
1178    tr_handshakeAbort( handshake );
1179}
1180
1181tr_handshake*
1182tr_handshakeNew( tr_peerIo           * io,
1183                 tr_encryption_mode    encryptionMode,
1184                 handshakeDoneCB       doneCB,
1185                 void                * doneUserData )
1186{
1187    tr_handshake * handshake;
1188    tr_session * session = tr_peerIoGetSession( io );
1189
1190    handshake = tr_new0( tr_handshake, 1 );
1191    handshake->io = io;
1192    handshake->crypto = tr_peerIoGetCrypto( io );
1193    handshake->encryptionMode = encryptionMode;
1194    handshake->doneCB = doneCB;
1195    handshake->doneUserData = doneUserData;
1196    handshake->session = session;
1197    handshake->timeout_timer = evtimer_new( session->event_base, handshakeTimeout, handshake );
1198    tr_timerAdd( handshake->timeout_timer, HANDSHAKE_TIMEOUT_SEC, 0 );
1199
1200    tr_peerIoRef( io ); /* balanced by the unref in tr_handshakeFree */
1201    tr_peerIoSetIOFuncs( handshake->io, canRead, NULL, gotError, handshake );
1202    tr_peerIoSetEncryption( io, PEER_ENCRYPTION_NONE );
1203
1204    if( tr_peerIoIsIncoming( handshake->io ) )
1205        setReadState( handshake, AWAITING_HANDSHAKE );
1206    else if( encryptionMode != TR_CLEAR_PREFERRED )
1207        sendYa( handshake );
1208    else
1209    {
1210        uint8_t msg[HANDSHAKE_SIZE];
1211        buildHandshakeMessage( handshake, msg );
1212
1213        handshake->haveSentBitTorrentHandshake = 1;
1214        setReadState( handshake, AWAITING_HANDSHAKE );
1215        tr_peerIoWriteBytes( handshake->io, msg, sizeof( msg ), false );
1216    }
1217
1218    return handshake;
1219}
1220
1221struct tr_peerIo*
1222tr_handshakeGetIO( tr_handshake * handshake )
1223{
1224    assert( handshake );
1225    assert( handshake->io );
1226
1227    return handshake->io;
1228}
1229
1230struct tr_peerIo*
1231tr_handshakeStealIO( tr_handshake * handshake )
1232{
1233    struct tr_peerIo * io;
1234
1235    assert( handshake );
1236    assert( handshake->io );
1237
1238    io = handshake->io;
1239    handshake->io = NULL;
1240    return io;
1241}
1242
1243const tr_address *
1244tr_handshakeGetAddr( const struct tr_handshake * handshake,
1245                     tr_port                   * port )
1246{
1247    assert( handshake );
1248    assert( handshake->io );
1249
1250    return tr_peerIoGetAddress( handshake->io, port );
1251}
1252
Note: See TracBrowser for help on using the repository browser.