source: branches/encryption/libtransmission/handshake.c @ 3077

Last change on this file since 3077 was 3077, checked in by charles, 15 years ago

remove PRIME_LEN from handshake.c

  • Property svn:keywords set to Date Rev Author Id
File size: 26.5 KB
Line 
1/*
2 * This file Copyright (C) 2007 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 3077 2007-09-15 20:47:11Z 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#include <arpa/inet.h>
20
21#include <sys/types.h> /* event.h needs this */
22#include <event.h>
23
24#include "transmission.h"
25#include "bencode.h"
26#include "crypto.h"
27#include "handshake.h"
28#include "peer-io.h"
29#include "utils.h"
30
31/* enable LibTransmission extension protocol */
32#define ENABLE_LTEP
33
34/* enable Azureus messaging protocol */
35//#define ENABLE_AZMP
36
37/***
38****
39***/
40
41#define HANDSHAKE_NAME          "\023BitTorrent protocol"
42#define HANDSHAKE_NAME_LEN      20
43#define HANDSHAKE_FLAGS_LEN     8
44#define HANDSHAKE_SIZE          68
45
46#ifdef ENABLE_LTEP
47#define HANDSHAKE_HAS_EXTMSGS( bits ) ( (bits)[5] & 0x10 )
48#define HANDSHAKE_SET_EXTMSGS( bits ) ( (bits)[5] |= 0x10 )
49#else
50#define HANDSHAKE_HAS_EXTMSGS( bits ) ( 0 )
51#define HANDSHAKE_SET_EXTMSGS( bits ) ( (void)0 )
52#endif
53
54#ifdef ENABLE_AZMP
55#define HANDSHAKE_HAS_AZPROTO( bits ) ( (bits)[0] & 0x80 )
56#define HANDSHAKE_SET_AZPROTO( bits ) ( (bits)[0] |= 0x80 )
57#else
58#define HANDSHAKE_HAS_AZPROTO( bits ) ( 0 )
59#define HANDSHAKE_SET_AZPROTO( bits ) ( (void)0 )
60#endif
61
62/* http://www.azureuswiki.com/index.php/Extension_negotiation_protocol
63   these macros are to be used if both extended messaging and the
64   azureus protocol is supported, they indicate which protocol is preferred */
65#define HANDSHAKE_GET_EXTPREF( reserved )      ( (reserved)[5] & 0x03 )
66#define HANDSHAKE_SET_EXTPREF( reserved, val ) ( (reserved)[5] |= 0x03 & (val) )
67#define HANDSHAKE_EXTPREF_LTEP_FORCE   ( 0x0 )
68#define HANDSHAKE_EXTPREF_LTEP_PREFER  ( 0x1 )
69#define HANDSHAKE_EXTPREF_AZMP_PREFER  ( 0x2 )
70#define HANDSHAKE_EXTPREF_AZMP_FORCE   ( 0x3 )
71
72extern const char* getPeerId( void ) ;
73
74#define KEY_LEN 96
75#define VC_LENGTH 8
76
77struct tr_handshake
78{
79    unsigned int peerSupportsEncryption : 1;
80    tr_peerIo * io;
81    tr_crypto * crypto;
82    struct tr_handle * handle;
83    uint8_t myPublicKey[96];
84    uint8_t mySecret[96];
85    uint8_t state;
86    uint8_t encryptionPreference;
87    uint16_t pad_c_len;
88    uint16_t pad_d_len;
89    int ia_len;
90    int crypto_select;
91    uint8_t myReq1[SHA_DIGEST_LENGTH];
92    uint8_t peer_id[20];
93    int have_peer_id;
94    handshakeDoneCB doneCB;
95    void * doneUserData;
96};
97
98static void
99fireDoneCB( tr_handshake * handshake, int isConnected );
100
101/**
102***
103**/
104
105enum /*ccc*/
106{
107    /* incoming */
108    AWAITING_HANDSHAKE,
109    AWAITING_YA,
110    AWAITING_PAD_A,
111    AWAITING_CRYPTO_PROVIDE,
112    AWAITING_PAD_C,
113    AWAITING_IA,
114
115    /* outgoing */
116    AWAITING_YB,
117    AWAITING_VC,
118    AWAITING_CRYPTO_SELECT,
119    AWAITING_PAD_D,
120};
121
122/**
123***
124**/
125
126static const char* getStateName( short state )
127{
128    const char * str = "f00!";
129    switch( state ) {
130        case AWAITING_HANDSHAKE:      str = "awaiting handshake"; break;
131        case AWAITING_YA:             str = "awaiting ya"; break;
132        //case SENDING_YB:              str = "sending yb"; break;
133        case AWAITING_PAD_A:          str = "awaiting pad a"; break;
134        case AWAITING_CRYPTO_PROVIDE: str = "awaiting crypto_provide"; break;
135        case AWAITING_PAD_C:          str = "awaiting pad c"; break;
136        case AWAITING_IA:             str = "awaiting ia"; break;
137        //case SENDING_YA:              str = "sending ya"; break;
138        case AWAITING_YB:             str = "awaiting yb"; break;
139        //case SENDING_CRYPTO_PROVIDE:  str = "sending crypto provide"; break;
140        case AWAITING_VC:             str = "awaiting vc"; break;
141        case AWAITING_CRYPTO_SELECT:  str = "awaiting crypto select"; break;
142        case AWAITING_PAD_D:          str = "awaiting pad d"; break;
143        //case SENDING_PLAINTEXT_HANDSHAKE: str = "sending plaintext handshake"; break;
144    }
145    return str;
146}
147
148static void
149setState( tr_handshake * handshake, short state )
150{
151    fprintf( stderr, "handshake %p: setting to state [%s]\n", handshake, getStateName(state) );
152    handshake->state = state;
153}
154
155static void
156setReadState( tr_handshake * handshake, int state )
157{
158    setState( handshake, state );
159    //tr_peerIoSetIOMode( handshake->io, EV_READ, EV_WRITE );
160}
161
162static void
163sendPublicKey( tr_handshake * handshake )
164{
165    int i;
166    int len;
167    const uint8_t * public_key;
168    struct evbuffer * outbuf = evbuffer_new( );
169    uint8_t pad[512];
170
171    /* add our public key (Ya) */
172    public_key = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
173    assert( len == KEY_LEN );
174    assert( public_key != NULL );
175    evbuffer_add( outbuf, public_key, len );
176
177    /* add some bullshit padding */
178    len = tr_rand( 512 );
179    for( i=0; i<len; ++i )
180        pad[i] = tr_rand( UCHAR_MAX );
181    evbuffer_add( outbuf, pad, len );
182
183    /* send it */
184    setReadState( handshake, AWAITING_YB );
185    //setState( handshake, SENDING_YA );
186    tr_peerIoWriteBuf( handshake->io, outbuf );
187
188    /* cleanup */
189    evbuffer_free( outbuf );
190}
191
192static void
193buildHandshakeMessage( tr_handshake * handshake, uint8_t * buf )
194{
195    uint8_t *walk = buf;
196    const uint8_t * torrentHash = tr_cryptoGetTorrentHash( handshake->crypto );
197
198    memcpy( walk, HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
199    walk += HANDSHAKE_NAME_LEN;
200    memset( walk, 0, HANDSHAKE_FLAGS_LEN );
201    HANDSHAKE_SET_EXTMSGS( walk );
202    HANDSHAKE_SET_AZPROTO( walk );
203    HANDSHAKE_SET_EXTPREF( walk, HANDSHAKE_EXTPREF_LTEP_PREFER );
204    walk += HANDSHAKE_FLAGS_LEN;
205    memcpy( walk, torrentHash, SHA_DIGEST_LENGTH );
206    walk += SHA_DIGEST_LENGTH;
207    memcpy( walk, getPeerId(), TR_ID_LEN );
208    walk += TR_ID_LEN;
209    assert( walk-buf == HANDSHAKE_SIZE );
210}
211
212static void
213sendPlaintextHandshake( tr_handshake * handshake )
214{
215    uint8_t buf[HANDSHAKE_SIZE];
216    buildHandshakeMessage( handshake, buf );
217
218    setReadState( handshake, AWAITING_HANDSHAKE );
219    tr_peerIoWrite( handshake->io, buf, HANDSHAKE_SIZE );
220}
221
222static void
223sendHandshake( tr_handshake * handshake )
224{
225    if( ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_PREFERRED ) ||
226        ( handshake->encryptionPreference == HANDSHAKE_ENCRYPTION_REQUIRED ) )
227    {
228        sendPublicKey( handshake );
229    }
230    else
231    {
232        sendPlaintextHandshake( handshake );
233    }
234}
235
236static void
237sendLtepHandshake( tr_handshake * handshake )
238{
239    benc_val_t val, *m;
240    char * buf;
241    int len;
242    const char * v = TR_NAME " " USERAGENT_PREFIX;
243    const int port = tr_getPublicPort( handshake->handle );
244    struct evbuffer * outbuf = evbuffer_new( );
245    uint32_t msglen;
246    const uint8_t tr_msgid = 20; /* ltep extension id */
247    const uint8_t ltep_msgid = 0; /* handshake id */
248
249    tr_bencInit( &val, TYPE_DICT );
250    tr_bencDictReserve( &val, 3 );
251    m  = tr_bencDictAdd( &val, "m" );
252    tr_bencInit( m, TYPE_DICT );
253    tr_bencDictReserve( m, 1 );
254    tr_bencInitInt( tr_bencDictAdd( m, "ut_pex" ), 1 );
255    if( port > 0 )
256        tr_bencInitInt( tr_bencDictAdd( &val, "p" ), port );
257    tr_bencInitStr( tr_bencDictAdd( &val, "v" ), v, 0, 1 );
258
259    fprintf( stderr, "handshake %p: sending ltep handshake...\n", handshake );
260    buf = tr_bencSaveMalloc( &val,  &len );
261    tr_bencPrint( &val );
262
263    msglen = sizeof(tr_msgid) + sizeof(ltep_msgid) + len;
264    tr_peerIoWriteUint32( handshake->io, outbuf, msglen );
265    tr_peerIoWriteBytes ( handshake->io, outbuf, &tr_msgid, 1 );
266    tr_peerIoWriteBytes ( handshake->io, outbuf, &ltep_msgid, 1 );
267    tr_peerIoWriteBytes ( handshake->io, outbuf, buf, len );
268   
269    tr_peerIoWriteBuf( handshake->io, outbuf );
270    fireDoneCB( handshake, TRUE );
271 
272    /* cleanup */ 
273    tr_bencFree( &val );
274    tr_free( buf ); 
275    evbuffer_free( outbuf );
276}
277
278
279/**
280***
281**/
282
283static int
284readYa( tr_handshake * handshake, struct evbuffer  * inbuf )
285{
286    uint8_t ya[KEY_LEN];
287    uint8_t *walk, outbuf[KEY_LEN + 512];
288    const uint8_t *myKey, *secret;
289    int len;
290
291    if( EVBUFFER_LENGTH( inbuf ) < KEY_LEN )
292        return READ_MORE;
293
294    /* read the incoming peer's public key */
295    evbuffer_remove( inbuf, ya, KEY_LEN );
296    secret = tr_cryptoComputeSecret( handshake->crypto, ya );
297    memcpy( handshake->mySecret, secret, KEY_LEN );
298    tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL );
299
300    /* send our public key to the peer */
301    walk = outbuf;
302    myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len );
303    memcpy( walk, myKey, len );
304    len = tr_rand( 512 );
305    while( len-- )
306        *walk++ = tr_rand( UCHAR_MAX );
307
308    setReadState( handshake, AWAITING_PAD_A );
309    tr_peerIoWrite( handshake->io, outbuf, walk-outbuf );
310
311    return READ_DONE;
312}
313
314static int
315readPadA( tr_handshake * handshake, struct evbuffer * inbuf )
316{
317    uint8_t * pch;
318
319    /**
320    *** Resynchronizing on HASH('req1',S)
321    **/
322
323    pch = memchr( EVBUFFER_DATA(inbuf),
324                  handshake->myReq1[0],
325                  EVBUFFER_LENGTH(inbuf) );
326    if( pch == NULL ) {
327        evbuffer_drain( inbuf, EVBUFFER_LENGTH(inbuf) );
328        return READ_MORE;
329    }
330    evbuffer_drain( inbuf, pch-EVBUFFER_DATA(inbuf) );
331    if( EVBUFFER_LENGTH(inbuf) < SHA_DIGEST_LENGTH )
332        return READ_MORE;
333    if( memcmp( EVBUFFER_DATA(inbuf), handshake->myReq1, SHA_DIGEST_LENGTH ) ) {
334        evbuffer_drain( inbuf, 1 );
335        return READ_AGAIN;
336    }
337
338    setState( handshake, AWAITING_CRYPTO_PROVIDE );
339    return READ_AGAIN;
340}
341
342static int
343readCryptoProvide( tr_handshake * handshake, struct evbuffer * inbuf )
344{
345    /* HASH('req2', SKEY) xor HASH('req3', S), ENCRYPT(VC, crypto_provide, len(PadC)) */
346
347    int i;
348    uint8_t vc_in[VC_LENGTH];
349    uint8_t req2[SHA_DIGEST_LENGTH];
350    uint8_t req3[SHA_DIGEST_LENGTH];
351    uint8_t obfuscatedTorrentHash[SHA_DIGEST_LENGTH];
352    uint16_t padc_len = 0;
353    uint32_t crypto_provide = 0;
354    const size_t needlen = SHA_DIGEST_LENGTH + VC_LENGTH + sizeof(crypto_provide) + sizeof(padc_len);
355    tr_torrent * tor = NULL;
356
357    if( EVBUFFER_LENGTH(inbuf) < needlen )
358        return READ_MORE;
359
360    /* TODO: confirm they sent HASH('req1',S) here? */
361    evbuffer_drain( inbuf, SHA_DIGEST_LENGTH );
362
363    /* This next piece is HASH('req2', SKEY) xor HASH('req3', S) ...
364     * we can get the first half of that (the obufscatedTorrentHash)
365     * by building the latter and xor'ing it with what the peer sent us */
366    fprintf( stderr, "reading obfuscated torrent hash...\n" );
367    evbuffer_remove( inbuf, req2, SHA_DIGEST_LENGTH );
368    tr_sha1( req3, "req3", 4, handshake->mySecret, KEY_LEN, NULL );
369    for( i=0; i<SHA_DIGEST_LENGTH; ++i )
370        obfuscatedTorrentHash[i] = req2[i] ^ req3[i];
371    tor = tr_torrentFindFromObfuscatedHash( handshake->handle, obfuscatedTorrentHash );
372    assert( tor != NULL );
373    fprintf( stderr, "found the torrent; it's [%s]\n", tor->info.name );
374    tr_peerIoSetTorrentHash( handshake->io, tor->info.hash );
375
376    /* next part: ENCRYPT(VC, crypto_provide, len(PadC), */
377
378    tr_cryptoDecryptInit( handshake->crypto );
379
380    tr_peerIoReadBytes( handshake->io, inbuf, vc_in, VC_LENGTH );
381
382    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );
383    fprintf( stderr, "crypto_provide is %d\n", (int)crypto_provide );
384
385    tr_peerIoReadUint16( handshake->io, inbuf, &padc_len );
386    fprintf( stderr, "padc is %d\n", (int)padc_len );
387    handshake->pad_c_len = padc_len;
388    setState( handshake, AWAITING_PAD_C );
389    return READ_AGAIN;
390}
391
392static int
393readPadC( tr_handshake * handshake, struct evbuffer * inbuf )
394{
395    uint16_t ia_len;
396    const size_t needlen = handshake->pad_c_len + sizeof(uint16_t);
397
398    if( EVBUFFER_LENGTH(inbuf) < needlen )
399        return READ_MORE;
400
401    evbuffer_drain( inbuf, needlen );
402
403    tr_peerIoReadUint16( handshake->io, inbuf, &ia_len );
404    fprintf( stderr, "ia_len is %d\n", (int)ia_len );
405    handshake->ia_len = ia_len;
406    setState( handshake, AWAITING_IA );
407    return READ_AGAIN;
408}
409
410static int
411readIA( tr_handshake * handshake, struct evbuffer * inbuf )
412{
413    const size_t needlen = handshake->ia_len;
414    uint8_t * ia;
415
416    if( EVBUFFER_LENGTH(inbuf) < needlen )
417        return READ_MORE;
418
419    ia = tr_new( uint8_t, handshake->ia_len );
420    tr_peerIoReadBytes( handshake->io, inbuf, ia, handshake->ia_len );
421    fprintf( stderr, "got their payload ia: [%*.*s]\n", (int)needlen, (int)needlen, ia );
422
423    handshake->state = -1;
424    assert( 0 && "asdf" );
425}
426
427/**
428***
429**/
430
431static int
432readYb( tr_handshake * handshake, struct evbuffer * inbuf )
433{
434    int isEncrypted;
435    const uint8_t * secret;
436    uint8_t yb[KEY_LEN];
437    struct evbuffer * outbuf;
438    size_t needlen = HANDSHAKE_NAME_LEN;
439
440    if( EVBUFFER_LENGTH(inbuf) < needlen )
441        return READ_MORE;
442fprintf( stderr, "%*.*s\n", HANDSHAKE_NAME_LEN, HANDSHAKE_NAME_LEN, EVBUFFER_DATA(inbuf) );
443
444    isEncrypted = memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN );
445    if( isEncrypted ) {
446        needlen = KEY_LEN;
447        if( EVBUFFER_LENGTH(inbuf) < needlen )
448            return READ_MORE;
449    }
450
451    fprintf( stderr, "got a %s handshake\n", (isEncrypted ? "encrypted" : "plaintext") );
452    handshake->peerSupportsEncryption = isEncrypted;
453    tr_peerIoSetEncryption( handshake->io, isEncrypted
454        ? PEER_ENCRYPTION_RC4
455        : PEER_ENCRYPTION_PLAINTEXT );
456    if( !isEncrypted ) {
457        setState( handshake, AWAITING_HANDSHAKE );
458        return READ_AGAIN;
459    }
460
461    /* compute the secret */
462    evbuffer_remove( inbuf, yb, KEY_LEN );
463    secret = tr_cryptoComputeSecret( handshake->crypto, yb );
464    memcpy( handshake->mySecret, secret, KEY_LEN );
465
466    /* now send these: HASH('req1', S), HASH('req2', SKEY) xor HASH('req3', S),
467     * ENCRYPT(VC, crypto_provide, len(PadC), PadC, len(IA)), ENCRYPT(IA) */
468    outbuf = evbuffer_new( );
469
470    /* HASH('req1', S) */
471    {
472        uint8_t req1[SHA_DIGEST_LENGTH];
473        tr_sha1( req1, "req1", 4, secret, KEY_LEN, NULL );
474        evbuffer_add( outbuf, req1, SHA_DIGEST_LENGTH );
475    }
476
477    /* HASH('req2', SKEY) xor HASH('req3', S) */
478    {
479        int i;
480        uint8_t req2[SHA_DIGEST_LENGTH];
481        uint8_t req3[SHA_DIGEST_LENGTH];
482        uint8_t buf[SHA_DIGEST_LENGTH];
483        tr_sha1( req2, "req2", 4, tr_cryptoGetTorrentHash(handshake->crypto), SHA_DIGEST_LENGTH, NULL );
484        tr_sha1( req3, "req3", 4, secret, KEY_LEN, NULL );
485        for( i=0; i<SHA_DIGEST_LENGTH; ++i )
486            buf[i] = req2[i] ^ req3[i];
487        evbuffer_add( outbuf, buf, SHA_DIGEST_LENGTH );
488    }
489     
490    /* ENCRYPT(VC, crypto_provide, len(PadC), PadC */
491    {
492        uint8_t vc[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
493        uint8_t pad[512];
494        uint16_t i, len;
495        uint32_t crypto_provide;
496
497        tr_cryptoEncryptInit( handshake->crypto );
498       
499        /* vc */ 
500        tr_cryptoEncrypt( handshake->crypto, VC_LENGTH, vc, vc );
501        evbuffer_add( outbuf, vc, VC_LENGTH );
502
503        /* crypto_provide */
504        crypto_provide = 0;
505        if( handshake->encryptionPreference != HANDSHAKE_PLAINTEXT_REQUIRED )
506            crypto_provide |= (1<<0);
507        if( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED )
508            crypto_provide |= (1<<1);
509        assert( 1<=crypto_provide && crypto_provide<=3 );
510
511        crypto_provide = htonl( crypto_provide );
512        tr_cryptoEncrypt( handshake->crypto, sizeof(crypto_provide), &crypto_provide, &crypto_provide );
513        evbuffer_add( outbuf, &crypto_provide, sizeof(crypto_provide) );
514
515        /* len(padc) */
516        i = len = tr_rand( 512 );
517        i = htons( i );
518        tr_cryptoEncrypt( handshake->crypto, sizeof(i), &i, &i );
519        evbuffer_add( outbuf, &i, sizeof(i) );
520
521        /* padc */
522        for( i=0; i<len; ++i ) pad[i] = tr_rand( UCHAR_MAX );
523        tr_cryptoEncrypt( handshake->crypto, len, pad, pad );
524        evbuffer_add( outbuf, pad, len );
525    }
526
527    /* ENCRYPT len(IA)), ENCRYPT(IA) */
528    {
529        uint16_t i;
530        uint8_t msg[HANDSHAKE_SIZE];
531        buildHandshakeMessage( handshake, msg );
532
533        i = htons( HANDSHAKE_SIZE );
534        tr_cryptoEncrypt( handshake->crypto, sizeof(uint16_t), &i, &i );
535        evbuffer_add( outbuf, &i, sizeof(uint16_t) );
536
537        tr_cryptoEncrypt( handshake->crypto, HANDSHAKE_SIZE, msg, msg );
538        evbuffer_add( outbuf, msg, HANDSHAKE_SIZE );
539    }
540
541    /* send it */
542    tr_cryptoDecryptInit( handshake->crypto );
543    setReadState( handshake, AWAITING_VC );
544    tr_peerIoWriteBuf( handshake->io, outbuf );
545
546    /* cleanup */
547    evbuffer_free( outbuf );
548    return READ_DONE;
549}
550
551static int
552readVC( tr_handshake * handshake, struct evbuffer * inbuf )
553{
554    const uint8_t key[VC_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0 };
555    const int key_len = VC_LENGTH;
556    uint8_t tmp[VC_LENGTH];
557
558    /* note: this works w/o having to `unwind' the buffer if
559     * we read too much, but it is pretty brute-force.
560     * it would be nice to make this cleaner. */
561    for( ;; )
562    {
563        if( EVBUFFER_LENGTH(inbuf) < VC_LENGTH ) {
564            fprintf( stderr, "not enough bytes... returning read_more\n" );
565            return READ_MORE;
566        }
567
568        memcpy( tmp, EVBUFFER_DATA(inbuf), key_len );
569        tr_cryptoDecryptInit( handshake->crypto );
570        tr_cryptoDecrypt( handshake->crypto, key_len, tmp, tmp );
571        if( !memcmp( tmp, key, key_len ) )
572            break;
573
574        evbuffer_drain( inbuf, 1 );
575    }
576
577    fprintf( stderr, "got it!\n" );
578    evbuffer_drain( inbuf, key_len );
579    setState( handshake, AWAITING_CRYPTO_SELECT );
580    return READ_AGAIN;
581}
582
583static int
584readCryptoSelect( tr_handshake * handshake, struct evbuffer * inbuf )
585{
586    uint32_t crypto_select;
587    uint16_t pad_d_len;
588    const size_t needlen = sizeof(uint32_t) + sizeof(uint16_t);
589
590    if( EVBUFFER_LENGTH(inbuf) < needlen )
591        return READ_MORE;
592
593    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_select );
594    assert( crypto_select==1 || crypto_select==2 );
595    handshake->crypto_select = crypto_select;
596    fprintf( stderr, "crypto select is %d\n", crypto_select );
597
598    tr_peerIoReadUint16( handshake->io, inbuf, &pad_d_len );
599    fprintf( stderr, "pad_d_len is %d\n", (int)pad_d_len );
600    assert( pad_d_len <= 512 );
601    handshake->pad_d_len = pad_d_len;
602
603    setState( handshake, AWAITING_PAD_D );
604    return READ_AGAIN;
605}
606
607static int
608readPadD( tr_handshake * handshake, struct evbuffer * inbuf )
609{
610    const size_t needlen = handshake->pad_d_len;
611    uint8_t * tmp;
612
613fprintf( stderr, "pad d: need %d, got %d\n", (int)needlen, (int)EVBUFFER_LENGTH(inbuf) );
614    if( EVBUFFER_LENGTH(inbuf) < needlen )
615        return READ_MORE;
616
617    tmp = tr_new( uint8_t, needlen );
618    tr_peerIoReadBytes( handshake->io, inbuf, tmp, needlen );
619    tr_free( tmp );
620
621    tr_peerIoSetEncryption( handshake->io,
622                                    handshake->crypto_select );
623
624    setState( handshake, AWAITING_HANDSHAKE );
625    return READ_AGAIN;
626}
627
628static void
629gotError( struct bufferevent * evbuf UNUSED, short what UNUSED, void * arg );
630
631/*ccc*/
632static int
633readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
634{
635    int i;
636    int ltep = 0;
637    int azmp = 0;
638    int isEncrypted;
639    uint8_t pstrlen;
640    uint8_t * pstr;
641    uint8_t reserved[8];
642    uint8_t hash[SHA_DIGEST_LENGTH];
643    int bytesRead = 0;
644
645fprintf( stderr, "handshake payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) );
646
647    if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE )
648        return READ_MORE;
649
650    /* pstrlen */
651    pstrlen = EVBUFFER_DATA(inbuf)[0];
652    fprintf( stderr, "pstrlen 1 is %d [%c]\n", (int)pstrlen, pstrlen );
653    fprintf( stderr, "the buf is [%c][%c][%c][%c]",
654        EVBUFFER_DATA(inbuf)[0], 
655        EVBUFFER_DATA(inbuf)[1], 
656        EVBUFFER_DATA(inbuf)[2], 
657        EVBUFFER_DATA(inbuf)[3] );
658    isEncrypted = pstrlen != 19;
659    handshake->peerSupportsEncryption = isEncrypted;
660    tr_peerIoSetEncryption( handshake->io, isEncrypted
661        ? PEER_ENCRYPTION_RC4
662        : PEER_ENCRYPTION_PLAINTEXT );
663    if( isEncrypted ) {
664        fprintf( stderr, "I guess it's encrypted...\n" );
665        if( tr_peerIoIsIncoming( handshake->io ) ) {
666            setState( handshake, AWAITING_YA );
667            return READ_AGAIN;
668        }
669        tr_cryptoDecrypt( handshake->crypto, 1, &pstrlen, &pstrlen );
670    }
671    bytesRead++;
672    evbuffer_drain( inbuf, 1 );
673    fprintf( stderr, "pstrlen is %d [%c]\n", (int)pstrlen, pstrlen );
674    assert( pstrlen == 19 );
675
676    /* pstr (BitTorrent) */
677    pstr = tr_new( uint8_t, pstrlen+1 );
678    tr_peerIoReadBytes( handshake->io, inbuf, pstr, pstrlen );
679    pstr[pstrlen] = '\0';
680    fprintf( stderr, "pstrlen is [%s]\n", pstr );
681    bytesRead += pstrlen;
682    fprintf( stderr, "%*.*s", pstrlen, pstrlen, (char*)pstr );
683    if( strcmp( (char*)pstr, "BitTorrent protocol" ) ) {
684        tr_free( pstr );
685        gotError( NULL, 0, handshake );
686        return READ_DONE;
687    }
688    tr_free( pstr );
689
690    /* reserved bytes */
691    tr_peerIoReadBytes( handshake->io, inbuf, reserved, sizeof(reserved) );
692    bytesRead += sizeof(reserved);
693
694    /* torrent hash */
695    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof(hash) );
696    bytesRead += sizeof(hash);
697    if( tr_peerIoIsIncoming( handshake->io ) )
698    {
699        assert( !tr_peerIoHasTorrentHash( handshake->io ) );
700        tr_peerIoSetTorrentHash( handshake->io, hash );
701    }
702    else
703    {
704        assert( tr_peerIoHasTorrentHash( handshake->io ) );
705        assert( !memcmp( hash, tr_peerIoGetTorrentHash(handshake->io), SHA_DIGEST_LENGTH ) );
706    }
707
708    /* peer id */
709    tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) );
710    tr_peerIoSetPeersId( handshake->io, handshake->peer_id );
711    bytesRead += sizeof(handshake->peer_id);
712    handshake->have_peer_id = TRUE;
713
714    assert( bytesRead == HANDSHAKE_SIZE );
715
716    /**
717    ***
718    **/
719
720    ltep = HANDSHAKE_HAS_EXTMSGS( reserved ) ? 1 : 0;
721    azmp = HANDSHAKE_HAS_AZPROTO( reserved ) ? 1 : 0;
722    if( ltep && azmp ) {
723        switch( HANDSHAKE_GET_EXTPREF( reserved ) ) {
724            case HANDSHAKE_EXTPREF_LTEP_FORCE:
725            case HANDSHAKE_EXTPREF_LTEP_PREFER:
726                azmp = 0;
727                break;
728            case HANDSHAKE_EXTPREF_AZMP_FORCE:
729            case HANDSHAKE_EXTPREF_AZMP_PREFER:
730                ltep = 0;
731                break;
732        }
733    }
734    assert( !ltep || !azmp );
735         if( ltep ) { i = LT_EXTENSIONS_LTEP; fprintf(stderr,"using ltep\n" ); }
736    else if( azmp ) { i = LT_EXTENSIONS_AZMP; fprintf(stderr,"using azmp\n" ); }
737    else            { i = LT_EXTENSIONS_NONE; fprintf(stderr,"using no extensions\n" ); }
738    tr_peerIoSetExtension( handshake->io, i );
739
740
741    if( i == LT_EXTENSIONS_LTEP )
742    {
743        sendLtepHandshake( handshake );
744        return READ_DONE;
745    }
746    else if( !tr_peerIoIsIncoming( handshake->io ) && ( i != LT_EXTENSIONS_AZMP ) )
747    {
748        fireDoneCB( handshake, TRUE );
749        return READ_DONE;
750    }
751
752
753    fprintf( stderr, " UNHANDLED -- azmp " );
754    return 0;
755}
756
757/**
758***
759**/
760
761static ReadState
762canRead( struct bufferevent * evin, void * arg )
763{
764    tr_handshake * handshake = (tr_handshake *) arg;
765    struct evbuffer * inbuf = EVBUFFER_INPUT ( evin );
766    ReadState ret;
767    fprintf( stderr, "handshake %p handling canRead; state is [%s]\n", handshake, getStateName(handshake->state) );
768
769    switch( handshake->state )
770    {
771        case AWAITING_HANDSHAKE:       ret = readHandshake    ( handshake, inbuf ); break;
772        case AWAITING_YA:              ret = readYa           ( handshake, inbuf ); break;
773        case AWAITING_PAD_A:           ret = readPadA         ( handshake, inbuf ); break;
774        case AWAITING_CRYPTO_PROVIDE:  ret = readCryptoProvide( handshake, inbuf ); break;
775        case AWAITING_PAD_C:           ret = readPadC         ( handshake, inbuf ); break;
776        case AWAITING_IA:              ret = readIA           ( handshake, inbuf ); break;
777
778        case AWAITING_YB:              ret = readYb           ( handshake, inbuf ); break;
779        case AWAITING_VC:              ret = readVC           ( handshake, inbuf ); break;
780        case AWAITING_CRYPTO_SELECT:   ret = readCryptoSelect ( handshake, inbuf ); break;
781        case AWAITING_PAD_D:           ret = readPadD         ( handshake, inbuf ); break;
782
783        default: assert( 0 );
784    }
785
786    return ret;
787}
788
789static void
790tr_handshakeFree( tr_handshake * handshake )
791{
792    tr_free( handshake );
793}
794
795static void
796fireDoneCB( tr_handshake * handshake, int isConnected )
797{
798    const uint8_t * peer_id = isConnected && handshake->have_peer_id
799        ? handshake->peer_id
800        : NULL;
801    (*handshake->doneCB)( handshake,
802                          handshake->io,
803                          isConnected,
804                          peer_id,
805                          handshake->peerSupportsEncryption,
806                          handshake->doneUserData );
807    tr_handshakeFree( handshake );
808}
809
810static void
811gotError( struct bufferevent * evbuf UNUSED, short what UNUSED, void * arg )
812{
813    tr_handshake * handshake = (tr_handshake *) arg;
814
815    /* if the error happened while we were sending a public key, we might
816     * have encountered a peer that doesn't do encryption... reconnect and
817     * try a plaintext handshake */
818    if(    ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) )
819        && ( handshake->encryptionPreference != HANDSHAKE_ENCRYPTION_REQUIRED )
820        && ( !tr_peerIoReconnect( handshake->io ) ) )
821    {
822fprintf( stderr, "handshake %p trying again in plaintext...\n", handshake );
823        handshake->encryptionPreference = HANDSHAKE_PLAINTEXT_REQUIRED;
824        sendPlaintextHandshake( handshake );
825    }
826    else
827    {
828        tr_peerIoSetIOFuncs( handshake->io, NULL, NULL, NULL, NULL );
829        fireDoneCB( handshake, FALSE );
830    }
831}
832
833/**
834***
835**/
836
837tr_handshake*
838tr_handshakeNew( tr_peerIo        * io,
839                 int                encryptionPreference,
840                 handshakeDoneCB    doneCB,
841                 void             * doneUserData )
842{
843    tr_handshake * handshake;
844
845//w00t
846//static int count = 0;
847//if( count++ ) return NULL;
848
849    handshake = tr_new0( tr_handshake, 1 );
850    handshake->io = io;
851    handshake->crypto = tr_peerIoGetCrypto( io );
852    handshake->encryptionPreference = encryptionPreference;
853    handshake->doneCB = doneCB;
854    handshake->doneUserData = doneUserData;
855    handshake->handle = tr_peerIoGetHandle( io );
856
857    tr_peerIoSetIOMode( io, EV_READ|EV_WRITE, 0 );
858    tr_peerIoSetIOFuncs( io, canRead, NULL, gotError, handshake );
859
860fprintf( stderr, "handshake %p: new handshake for io %p\n", handshake, io );
861
862    if( tr_peerIoIsIncoming( io ) )
863    {
864        setReadState( handshake, AWAITING_HANDSHAKE );
865    }
866    else
867    {
868        sendHandshake( handshake );
869    }
870
871    return handshake;
872}
873
874void
875tr_handshakeAbort( tr_handshake * handshake )
876{
877    tr_peerIoFree( handshake->io );
878    tr_handshakeFree( handshake );
879}
Note: See TracBrowser for help on using the repository browser.