1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 01:27:28 +00:00

added `plaintext preferred' encryption option.

This commit is contained in:
Charles Kerr 2007-11-08 21:20:08 +00:00
parent 0d819bd67e
commit 125bd34bbb
2 changed files with 66 additions and 31 deletions

View file

@ -89,13 +89,13 @@ struct tr_handshake
{ {
unsigned int havePeerID : 1; unsigned int havePeerID : 1;
unsigned int haveSentBitTorrentHandshake : 1; unsigned int haveSentBitTorrentHandshake : 1;
unsigned int allowUnencryptedPeers : 1;
tr_peerIo * io; tr_peerIo * io;
tr_crypto * crypto; tr_crypto * crypto;
struct tr_handle * handle; struct tr_handle * handle;
uint8_t myPublicKey[KEY_LEN]; uint8_t myPublicKey[KEY_LEN];
uint8_t mySecret[KEY_LEN]; uint8_t mySecret[KEY_LEN];
uint8_t state; uint8_t state;
tr_encryption_mode encryptionMode;
uint16_t pad_c_len; uint16_t pad_c_len;
uint16_t pad_d_len; uint16_t pad_d_len;
uint16_t ia_len; uint16_t ia_len;
@ -324,20 +324,53 @@ sendYa( tr_handshake * handshake )
} }
static uint32_t static uint32_t
getCryptoProvide( const tr_handshake * handshake UNUSED ) getCryptoProvide( const tr_handshake * handshake )
{ {
uint32_t i = 0; uint32_t provide = 0;
i |= CRYPTO_PROVIDE_CRYPTO; /* always allow crypto */ switch( handshake->encryptionMode )
{
case TR_ENCRYPTION_REQUIRED:
case TR_ENCRYPTION_PREFERRED:
provide |= CRYPTO_PROVIDE_CRYPTO;
break;
#if 0 case TR_PLAINTEXT_PREFERRED:
/* by the time we send a crypto_provide, we _know_ provide |= CRYPTO_PROVIDE_CRYPTO | CRYPTO_PROVIDE_PLAINTEXT;
* the peer supports encryption. */ break;
if( handshake->allowUnencryptedPeers ) }
i |= CRYPTO_PROVIDE_PLAINTEXT;
#endif
return i; return provide;
}
static uint32_t
getCryptoSelect( const tr_handshake * handshake, uint32_t crypto_provide )
{
uint32_t choices[4];
int i, nChoices=0;
switch( handshake->encryptionMode )
{
case TR_ENCRYPTION_REQUIRED:
choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
break;
case TR_ENCRYPTION_PREFERRED:
choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
break;
case TR_PLAINTEXT_PREFERRED:
choices[nChoices++] = CRYPTO_PROVIDE_PLAINTEXT;
choices[nChoices++] = CRYPTO_PROVIDE_CRYPTO;
break;
}
for( i=0; i<nChoices; ++i )
if( crypto_provide & choices[i] )
return choices[i];
return 0;
} }
static int static int
@ -544,7 +577,7 @@ readHandshake( tr_handshake * handshake, struct evbuffer * inbuf )
{ {
tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE ); tr_peerIoSetEncryption( handshake->io, PEER_ENCRYPTION_NONE );
if( !handshake->allowUnencryptedPeers ) if( handshake->encryptionMode == TR_ENCRYPTION_REQUIRED )
{ {
dbgmsg( handshake, "peer is unencrypted, and we're disallowing that" ); dbgmsg( handshake, "peer is unencrypted, and we're disallowing that" );
tr_handshakeDone( handshake, FALSE ); tr_handshakeDone( handshake, FALSE );
@ -840,25 +873,18 @@ dbgmsg( handshake, "sending vc" );
tr_peerIoWriteBytes( handshake->io, outbuf, vc, VC_LENGTH ); tr_peerIoWriteBytes( handshake->io, outbuf, vc, VC_LENGTH );
} }
dbgmsg( handshake, "sending crypto_select" );
/* send crypto_select */ /* send crypto_select */
{ crypto_select = getCryptoSelect( handshake, handshake->crypto_provide );
dbgmsg( handshake, "handshake->crypto_provide is %d", (int)handshake->crypto_provide ); if( crypto_select ) {
if( handshake->crypto_provide & CRYPTO_PROVIDE_CRYPTO ) dbgmsg( handshake, "selecting crypto mode '%d'", (int)crypto_select );
crypto_select = CRYPTO_PROVIDE_CRYPTO; tr_peerIoWriteUint32( handshake->io, outbuf, crypto_select );
else if( handshake->allowUnencryptedPeers ) } else {
crypto_select = CRYPTO_PROVIDE_PLAINTEXT; dbgmsg( handshake, "peer didn't offer an encryption mode we like." );
else {
dbgmsg( handshake, "gronk..." );
evbuffer_free( outbuf ); evbuffer_free( outbuf );
tr_handshakeDone( handshake, FALSE ); tr_handshakeDone( handshake, FALSE );
return READ_DONE; return READ_DONE;
} }
dbgmsg( handshake, "we select crypto_select as %d...", (int)crypto_select );
tr_peerIoWriteUint32( handshake->io, outbuf, crypto_select );
}
dbgmsg( handshake, "sending pad d" ); dbgmsg( handshake, "sending pad d" );
/* ENCRYPT(VC, crypto_provide, len(PadC), PadC /* ENCRYPT(VC, crypto_provide, len(PadC), PadC
* PadD is reserved for future extensions to the handshake... * PadD is reserved for future extensions to the handshake...
@ -964,7 +990,7 @@ gotError( struct bufferevent * evbuf UNUSED, short what, void * arg )
* have encountered a peer that doesn't do encryption... reconnect and * have encountered a peer that doesn't do encryption... reconnect and
* try a plaintext handshake */ * try a plaintext handshake */
if( ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) ) if( ( ( handshake->state == AWAITING_YB ) || ( handshake->state == AWAITING_VC ) )
&& ( handshake->allowUnencryptedPeers ) && ( handshake->encryptionMode != TR_ENCRYPTION_REQUIRED )
&& ( !tr_peerIoReconnect( handshake->io ) ) ) && ( !tr_peerIoReconnect( handshake->io ) ) )
{ {
int msgSize; int msgSize;
@ -990,7 +1016,7 @@ gotError( struct bufferevent * evbuf UNUSED, short what, void * arg )
tr_handshake* tr_handshake*
tr_handshakeNew( tr_peerIo * io, tr_handshakeNew( tr_peerIo * io,
tr_encryption_mode encryption_mode, tr_encryption_mode encryptionMode,
handshakeDoneCB doneCB, handshakeDoneCB doneCB,
void * doneUserData ) void * doneUserData )
{ {
@ -999,7 +1025,7 @@ tr_handshakeNew( tr_peerIo * io,
handshake = tr_new0( tr_handshake, 1 ); handshake = tr_new0( tr_handshake, 1 );
handshake->io = io; handshake->io = io;
handshake->crypto = tr_peerIoGetCrypto( io ); handshake->crypto = tr_peerIoGetCrypto( io );
handshake->allowUnencryptedPeers = encryption_mode!=TR_ENCRYPTION_REQUIRED; handshake->encryptionMode = encryptionMode;
handshake->doneCB = doneCB; handshake->doneCB = doneCB;
handshake->doneUserData = doneUserData; handshake->doneUserData = doneUserData;
handshake->handle = tr_peerIoGetHandle( io ); handshake->handle = tr_peerIoGetHandle( io );
@ -1009,8 +1035,16 @@ tr_handshakeNew( tr_peerIo * io,
if( tr_peerIoIsIncoming( handshake->io ) ) if( tr_peerIoIsIncoming( handshake->io ) )
setReadState( handshake, AWAITING_HANDSHAKE ); setReadState( handshake, AWAITING_HANDSHAKE );
else else if( encryptionMode != TR_PLAINTEXT_PREFERRED )
sendYa( handshake ); sendYa( handshake );
else {
int msgSize;
uint8_t * msg = buildHandshakeMessage( handshake, &msgSize );
handshake->haveSentBitTorrentHandshake = 1;
setReadState( handshake, AWAITING_HANDSHAKE );
tr_peerIoWrite( handshake->io, msg, msgSize );
tr_free( msg );
}
return handshake; return handshake;
} }

View file

@ -116,6 +116,7 @@ typedef struct tr_tracker_info tr_tracker_info;
typedef enum typedef enum
{ {
TR_PLAINTEXT_PREFERRED,
TR_ENCRYPTION_PREFERRED, TR_ENCRYPTION_PREFERRED,
TR_ENCRYPTION_REQUIRED TR_ENCRYPTION_REQUIRED
} }