diff --git a/gtk/tr-prefs.c b/gtk/tr-prefs.c index 47ecc4327..36d952048 100644 --- a/gtk/tr-prefs.c +++ b/gtk/tr-prefs.c @@ -40,6 +40,7 @@ tr_prefs_init_global( void ) const char * pool = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "1234567890"; + GRand *rand; cf_check_older_configs( ); @@ -112,8 +113,11 @@ tr_prefs_init_global( void ) pref_int_set_default ( PREF_KEY_RPC_PORT, TR_DEFAULT_RPC_PORT ); pref_string_set_default ( PREF_KEY_RPC_ACL, TR_DEFAULT_RPC_ACL ); + rand = g_rand_new (); for( i=0; i<16; ++i ) - pw[i] = pool[ tr_rand( strlen( pool ) ) ]; + pw[i] = pool[ g_rand_int_range (rand, 0, strlen(pool))]; + g_rand_free (rand); + pw[16] = '\0'; pref_string_set_default( PREF_KEY_RPC_USERNAME, "transmission" ); pref_string_set_default( PREF_KEY_RPC_PASSWORD, pw ); diff --git a/libtransmission/crypto.c b/libtransmission/crypto.c index a824bc407..d51778076 100644 --- a/libtransmission/crypto.c +++ b/libtransmission/crypto.c @@ -10,6 +10,8 @@ * $Id$ */ +#include /* for abs() */ +#include /* for INT_MAX */ #include /* for event.h, as well as netinet/in.h on some platforms */ #include #include /* uint8_t */ @@ -20,6 +22,7 @@ #include #include #include +#include #include @@ -264,3 +267,18 @@ tr_cryptoHasTorrentHash( const tr_crypto * crypto ) return crypto->torrentHashIsSet ? 1 : 0; } + +int tr_cryptoRandInt( int sup ) +{ + int r; + + RAND_pseudo_bytes ((unsigned char *) &r, sizeof r); + + return ((int) (sup * (abs(r) / (INT_MAX + 1.0)))); +} + +void tr_cryptoRandBuf ( unsigned char *buf, size_t len ) +{ + RAND_pseudo_bytes ( buf, len ); +} + diff --git a/libtransmission/crypto.h b/libtransmission/crypto.h index c511f050d..b6abda651 100644 --- a/libtransmission/crypto.h +++ b/libtransmission/crypto.h @@ -75,4 +75,11 @@ void tr_sha1 ( uint8_t * setme, int content1_len, ... ); + +/** Returns a random number in the range of [0...n) */ +int tr_cryptoRandInt ( int n ); + +/** Fills a buffer with random bytes */ +void tr_cryptoRandBuf ( unsigned char *buf, size_t len ); + #endif diff --git a/libtransmission/handshake.c b/libtransmission/handshake.c index bfedad15f..09c4552bd 100644 --- a/libtransmission/handshake.c +++ b/libtransmission/handshake.c @@ -277,7 +277,6 @@ parseHandshake( tr_handshake * handshake, static void sendYa( tr_handshake * handshake ) { - int i; int len; const uint8_t * public_key; struct evbuffer * outbuf = evbuffer_new( ); @@ -290,9 +289,8 @@ sendYa( tr_handshake * handshake ) evbuffer_add( outbuf, public_key, len ); /* add some bullshit padding */ - len = tr_rand( PadA_MAXLEN ); - for( i=0; imySecret, secret, KEY_LEN ); tr_sha1( handshake->myReq1, "req1", 4, secret, KEY_LEN, NULL ); -dbgmsg( handshake, "sending B->A: Diffie Hellman Yb, PadB" ); + dbgmsg( handshake, "sending B->A: Diffie Hellman Yb, PadB" ); /* send our public key to the peer */ walk = outbuf; myKey = tr_cryptoGetMyPublicKey( handshake->crypto, &len ); memcpy( walk, myKey, len ); walk += len; - len = tr_rand( PadB_MAXLEN ); - while( len-- ) - *walk++ = tr_rand( UCHAR_MAX ); + len = tr_cryptoRandInt( PadB_MAXLEN ); + tr_cryptoRandBuf( walk, len ); + walk += len; setReadState( handshake, AWAITING_PAD_A ); tr_peerIoWrite( handshake->io, outbuf, walk-outbuf ); diff --git a/libtransmission/peer-mgr.c b/libtransmission/peer-mgr.c index ff60484f1..7f0cb560b 100644 --- a/libtransmission/peer-mgr.c +++ b/libtransmission/peer-mgr.c @@ -600,7 +600,7 @@ getPreferredPieces( Torrent * t, setme->piece = piece; setme->priority = inf->pieces[piece].priority; setme->peerCount = 0; - setme->random = tr_rand( UINT16_MAX ); + setme->random = tr_cryptoRandInt( UINT16_MAX ); setme->missingBlockCount = tr_cpMissingBlocksInPiece( tor->completion, piece ); for( k=0; kdoUnchoke = 1; t->optimistic = c->peer; } diff --git a/libtransmission/session.c b/libtransmission/session.c index db48c9d8c..db9b599fa 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -37,6 +37,7 @@ #include "trevent.h" #include "utils.h" #include "web.h" +#include "crypto.h" /* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric characters, where x is the major version number, y is the @@ -55,7 +56,7 @@ tr_peerIdNew( void ) memcpy( buf, PEERID_PREFIX, 8 ); for( i=8; i<19; ++i ) { - val = tr_rand( base ); + val = tr_cryptoRandInt( base ); total += val; buf[i] = pool[val]; } diff --git a/libtransmission/torrent.c b/libtransmission/torrent.c index 7bab92f2d..16228f704 100644 --- a/libtransmission/torrent.c +++ b/libtransmission/torrent.c @@ -379,7 +379,7 @@ randomizeTiers( tr_info * info ) struct RandomTracker * r = tr_new0( struct RandomTracker, n ); for( i=0; itrackers[i]; - r[i].random_value = tr_rand( INT_MAX ); + r[i].random_value = tr_cryptoRandInt( INT_MAX ); } qsort( r, n, sizeof( struct RandomTracker ), compareRandomTracker ); for( i=0; ilastScrapeResponse = -1; t->manualAnnounceAllowedAt = ~(time_t)0; t->name = tr_strdup( info->name ); - t->randOffset = tr_rand( 30 ); + t->randOffset = tr_cryptoRandInt( 30 ); memcpy( t->hash, info->hash, SHA_DIGEST_LENGTH ); escape( t->escaped, info->hash, SHA_DIGEST_LENGTH ); generateKeyParam( t->key_param, KEYLEN ); diff --git a/libtransmission/utils.c b/libtransmission/utils.c index bd66cd458..b7468a320 100644 --- a/libtransmission/utils.c +++ b/libtransmission/utils.c @@ -265,20 +265,6 @@ tr_msg( const char * file, int line, int level, tr_lockUnlock( messageLock ); } -int tr_rand( int sup ) -{ - static int init = 0; - - assert( sup > 0 ); - - if( !init ) - { - srand( tr_date() ); - init = 1; - } - return rand() % sup; -} - /*** **** ***/ diff --git a/libtransmission/utils.h b/libtransmission/utils.h index 81b229f2d..90cffefdc 100644 --- a/libtransmission/utils.h +++ b/libtransmission/utils.h @@ -117,9 +117,6 @@ void tr_deepLog( const char * file, int line, char* tr_getLogTimeStr( char * buf, int buflen ); -/** Returns a random number in the range of [0...n) */ -int tr_rand ( int n ); - /** * a portability wrapper around mkdir(). * On WIN32, the `permissions' argument is unused.