source: trunk/libtransmission/handshake.c @ 12344

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

(trunk libT) remove unneeded assert()ion

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