source: trunk/libtransmission/handshake.c @ 7231

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

(libT) re-apply jhujhiti's IPv6 patch. This merges in my tr_port cleanup, so any new bugs are mine :/

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