Changeset 3130


Ignore:
Timestamp:
Sep 22, 2007, 3:37:37 AM (15 years ago)
Author:
charles
Message:

get encrypted uTorrent working.

Location:
trunk/libtransmission
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/handshake.c

    r3129 r3130  
    120120    uint16_t  ia_len;
    121121    uint32_t crypto_select;
     122    uint32_t crypto_provide;
    122123    uint8_t myReq1[SHA_DIGEST_LENGTH];
    123124    uint8_t peer_id[PEER_ID_LEN];
     
    260261tr_handshakeDone( tr_handshake * handshake, int isConnected );
    261262
     263enum
     264{
     265    HANDSHAKE_OK,
     266    HANDSHAKE_ENCRYPTION_WRONG,
     267    HANDSHAKE_BAD_TORRENT,
     268    HANDSHAKE_PEER_IS_SELF,
     269};
     270
     271static int
     272parseHandshake( tr_handshake     * handshake,
     273                struct evbuffer  * inbuf )
     274{
     275    uint8_t ltep = 0;
     276    uint8_t azmp = 0;
     277    uint8_t fpex = 0;
     278    uint8_t reserved[HANDSHAKE_FLAGS_LEN];
     279    uint8_t hash[SHA_DIGEST_LENGTH];
     280
     281    dbgmsg( handshake, "payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) );
     282
     283    if( EVBUFFER_LENGTH(inbuf) < HANDSHAKE_SIZE )
     284        return READ_MORE;
     285
     286    if( memcmp( EVBUFFER_DATA(inbuf), HANDSHAKE_NAME, HANDSHAKE_NAME_LEN ) )
     287        return HANDSHAKE_ENCRYPTION_WRONG;
     288    evbuffer_drain( inbuf, HANDSHAKE_NAME_LEN );
     289
     290    tr_peerIoReadBytes( handshake->io, inbuf, reserved, HANDSHAKE_FLAGS_LEN );
     291
     292    /* torrent hash */
     293    tr_peerIoReadBytes( handshake->io, inbuf, hash, sizeof(hash) );
     294    if( tr_peerIoIsIncoming( handshake->io ) ) {
     295        if( !tr_torrentExists( handshake->handle, hash ) )
     296            return HANDSHAKE_BAD_TORRENT;
     297        assert( !tr_peerIoHasTorrentHash( handshake->io ) );
     298        tr_peerIoSetTorrentHash( handshake->io, hash );
     299    } else { /* outgoing */
     300        assert( tr_torrentExists( handshake->handle, hash ) );
     301        assert( tr_peerIoHasTorrentHash( handshake->io ) );
     302        if( memcmp( hash, tr_peerIoGetTorrentHash(handshake->io), SHA_DIGEST_LENGTH ) ) {
     303            dbgmsg( handshake, "peer returned the wrong hash. wtf?" );
     304            return HANDSHAKE_BAD_TORRENT;
     305        }
     306    }
     307
     308    /* peer_id */
     309    tr_peerIoReadBytes( handshake->io, inbuf, handshake->peer_id, sizeof(handshake->peer_id) );
     310    tr_peerIoSetPeersId( handshake->io, handshake->peer_id );
     311
     312    /* peer id */
     313    handshake->havePeerID = TRUE;
     314    dbgmsg( handshake, "peer-id is [%*.*s]", PEER_ID_LEN, PEER_ID_LEN, handshake->peer_id );
     315    if( !memcmp( handshake->peer_id, getPeerId(), PEER_ID_LEN ) ) {
     316        dbgmsg( handshake, "streuth!  we've connected to ourselves." );
     317        return HANDSHAKE_PEER_IS_SELF;
     318    }
     319
     320    /**
     321    *** Extension negotiation
     322    **/
     323
     324    ltep = HANDSHAKE_HAS_EXTMSGS( reserved );
     325    azmp = HANDSHAKE_HAS_AZPROTO( reserved );
     326    fpex = HANDSHAKE_HAS_FASTEXT( reserved );
     327
     328    if( ltep && azmp ) {
     329        switch( HANDSHAKE_GET_EXTPREF( reserved ) ) {
     330            case HANDSHAKE_EXTPREF_LTEP_FORCE:
     331            case HANDSHAKE_EXTPREF_LTEP_PREFER:
     332                azmp = 0;
     333                break;
     334            case HANDSHAKE_EXTPREF_AZMP_FORCE:
     335            case HANDSHAKE_EXTPREF_AZMP_PREFER:
     336                ltep = 0;
     337                break;
     338        }
     339    }
     340    assert( !ltep || !azmp );
     341   
     342         if( ltep ) { tr_peerIoEnableLTEP( handshake->io, 1 ); dbgmsg(handshake,"using ltep" ); }
     343    else if( azmp ) { tr_peerIoEnableAZMP( handshake->io, 1 ); dbgmsg(handshake,"using azmp" ); }
     344    else if( fpex ) { tr_peerIoEnableFEXT( handshake->io, 1 ); dbgmsg(handshake,"using fext" ); }
     345    else            { dbgmsg(handshake,"using no extensions" ); }
     346
     347    return HANDSHAKE_OK;
     348}
     349
    262350/***
    263351****
     
    523611    uint8_t reserved[HANDSHAKE_FLAGS_LEN];
    524612    uint8_t hash[SHA_DIGEST_LENGTH];
     613
     614/* FIXME: use  readHandshake here */
    525615
    526616    dbgmsg( handshake, "payload: need %d, got %d\n", (int)HANDSHAKE_SIZE, (int)EVBUFFER_LENGTH(inbuf) );
     
    758848
    759849    tr_peerIoReadUint32( handshake->io, inbuf, &crypto_provide );
     850    handshake->crypto_provide = crypto_provide;
    760851    dbgmsg( handshake, "crypto_provide is %d\n", (int)crypto_provide );
    761852
     
    788879readIA( tr_handshake * handshake, struct evbuffer * inbuf )
    789880{
     881    int i;
    790882    const size_t needlen = handshake->ia_len;
     883    struct evbuffer * outbuf = evbuffer_new( );
     884    uint32_t crypto_select;
    791885
    792886    if( EVBUFFER_LENGTH(inbuf) < needlen )
    793887        return READ_MORE;
    794888
    795     return readHandshake( handshake, inbuf );
     889    /* parse the handshake ... */
     890    i = parseHandshake( handshake, inbuf );
     891    if( i != HANDSHAKE_OK ) {
     892        tr_handshakeDone( handshake, FALSE );
     893        return READ_DONE;
     894    }
     895
     896    /* send VC */
     897    {
     898        uint8_t vc[VC_LENGTH];
     899        memset( vc, 0, VC_LENGTH );
     900        tr_peerIoWriteBytes( handshake->io, outbuf, vc, VC_LENGTH );
     901    }
     902
     903    /* send crypto_select */
     904    {
     905        if( handshake->crypto_provide & CRYPTO_PROVIDE_CRYPTO )
     906            crypto_select = CRYPTO_PROVIDE_CRYPTO;
     907        else if( handshake->allowUnencryptedPeers )
     908            crypto_select = CRYPTO_PROVIDE_PLAINTEXT;
     909        else {
     910            evbuffer_free( outbuf );
     911            tr_handshakeDone( handshake, FALSE );
     912            return READ_DONE;
     913        }
     914
     915        tr_peerIoWriteUint32( handshake->io, outbuf, crypto_select );
     916    }
     917
     918    /* send pad d */
     919    {
     920        uint8_t pad[PadD_MAXLEN];
     921        const int len = tr_rand( PadD_MAXLEN );
     922        for( i=0; i<len; ++i )
     923            pad[i] = tr_rand( UCHAR_MAX );
     924        tr_peerIoWriteUint16( handshake->io, outbuf, len );
     925        tr_peerIoWriteBytes( handshake->io, outbuf, pad, len );
     926    }
     927
     928    /* maybe de-encrypt our connection */
     929    if( crypto_select == CRYPTO_PROVIDE_PLAINTEXT )
     930        tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
     931
     932    /* send our handshake */
     933    {
     934        int msgSize;
     935        int ext;
     936        uint8_t * msg;
     937
     938        /* add our choice of protocol extension */
     939        if( tr_peerIoSupportsAZMP( handshake->io ) )
     940            ext = HANDSHAKE_EXTPREF_AZMP_FORCE;
     941        else if( tr_peerIoSupportsLTEP( handshake->io ) )
     942            ext = HANDSHAKE_EXTPREF_LTEP_FORCE;
     943        else
     944            ext = 0;
     945
     946        /* FIXME: do we do something with fast peers here? */
     947
     948        msg = buildHandshakeMessage( handshake, ext, &msgSize );
     949        tr_peerIoWriteBytes( handshake->io, outbuf, msg, msgSize );
     950        tr_free( msg );
     951        handshake->haveSentBitTorrentHandshake = 1;
     952    }
     953
     954    /* send it out */
     955    tr_peerIoWriteBuf( handshake->io, outbuf );
     956    evbuffer_free( outbuf );
     957
     958    /* we've completed the BT handshake... pass the work on to peer-msgs */
     959    tr_handshakeDone( handshake, TRUE );
     960    return READ_DONE;
    796961}
    797962
  • trunk/libtransmission/peer-msgs.c

    r3127 r3130  
    479479    benc_val_t val, * sub;
    480480    uint8_t * tmp = tr_new( uint8_t, len );
    481     evbuffer_remove( inbuf, tmp, len );
     481
     482    tr_peerIoReadBytes( msgs->io, inbuf, tmp, len );
    482483
    483484    if( tr_bencLoad( tmp, len, &val, NULL ) || val.type!=TYPE_DICT ) {
     
    502503    sub = tr_bencDictFind( &val, "v" );
    503504    if( tr_bencIsStr( sub ) ) {
    504 int i;
     505        int i;
    505506        tr_free( msgs->info->client );
    506507        fprintf( stderr, "dictionary says client is [%s]\n", sub->val.s.s );
     
    533534
    534535    tmp = tr_new( uint8_t, msglen );
    535     evbuffer_remove( inbuf, tmp, msglen );
     536    tr_peerIoReadBytes( msgs->io, inbuf, tmp, msglen );
    536537
    537538    if( tr_bencLoad( tmp, msglen, &val, NULL ) || !tr_bencIsDict( &val ) ) {
Note: See TracChangeset for help on using the changeset viewer.