source: branches/1.4x/libtransmission/handshake.c @ 7455

Last change on this file since 7455 was 7455, checked in by charles, 12 years ago

(1.4x libT) backport handshake, peer, bandwidth, peer-io to 1.4x.

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