source: trunk/libtransmission/handshake.c @ 8050

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

(trunk libT) #1810: DoS vulnerability wrt incoming connections

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