mirror of
https://github.com/transmission/transmission
synced 2024-12-25 01:03:01 +00:00
(trunk libT) #1276 - hash rpc password with sha1
This commit is contained in:
parent
5cd6c41ec7
commit
44ea61bced
3 changed files with 57 additions and 13 deletions
|
@ -355,21 +355,59 @@ tr_cryptoRandBuf( unsigned char *buf,
|
||||||
***/
|
***/
|
||||||
|
|
||||||
char*
|
char*
|
||||||
tr_crypt( const void * plaintext )
|
tr_ssha1( const void * plaintext )
|
||||||
{
|
{
|
||||||
static const char * salter = "0123456789"
|
static const char * salter = "0123456789"
|
||||||
"abcdefghijklmnopqrstuvwxyz"
|
"abcdefghijklmnopqrstuvwxyz"
|
||||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||||
"./";
|
"./";
|
||||||
static const size_t salter_len = 64;
|
static const size_t salter_len = 64;
|
||||||
|
static const size_t saltval_len = 8;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
char salt[12];
|
char salt[saltval_len];
|
||||||
|
char sha[SHA_DIGEST_LENGTH];
|
||||||
|
char buf[2*SHA_DIGEST_LENGTH + saltval_len + 2];
|
||||||
|
|
||||||
memcpy( salt, "$1$", 3 );
|
for( i=0; i<=saltval_len; ++i )
|
||||||
for( i=0; i<8; ++i )
|
salt[i] = salter[ tr_cryptoRandInt( salter_len ) ];
|
||||||
salt[3+i] = salter[ tr_cryptoRandInt( salter_len ) ];
|
|
||||||
salt[11] = '\0';
|
|
||||||
|
|
||||||
return tr_strdup( DES_crypt( plaintext, salt ) );
|
tr_sha1( sha, plaintext, strlen( plaintext ), salt, saltval_len, NULL );
|
||||||
|
tr_sha1_to_hex( &buf[1], &sha );
|
||||||
|
memcpy( &buf[1+2*SHA_DIGEST_LENGTH], &salt, saltval_len );
|
||||||
|
buf[1+2*SHA_DIGEST_LENGTH + saltval_len] = '\0';
|
||||||
|
buf[0] = '{'; /* signal that this is a hash. this makes saving/restoring
|
||||||
|
easier */
|
||||||
|
|
||||||
|
return tr_strdup( &buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
tr_bool
|
||||||
|
tr_ssha1_matches( const char * source, const char * pass )
|
||||||
|
{
|
||||||
|
char * salt;
|
||||||
|
size_t saltlen;
|
||||||
|
char * hashed;
|
||||||
|
char buf[SHA_DIGEST_LENGTH];
|
||||||
|
tr_bool result;
|
||||||
|
|
||||||
|
/* extract the salt */
|
||||||
|
saltlen = strlen( source ) - 2*SHA_DIGEST_LENGTH-1;
|
||||||
|
salt = tr_malloc( saltlen );
|
||||||
|
memcpy( salt, source + 2*SHA_DIGEST_LENGTH+1, saltlen );
|
||||||
|
|
||||||
|
/* hash pass + salt */
|
||||||
|
hashed = tr_malloc( 2*SHA_DIGEST_LENGTH + saltlen + 2 );
|
||||||
|
tr_sha1( &buf, pass, strlen( pass ), salt, saltlen, NULL );
|
||||||
|
tr_sha1_to_hex( &hashed[1], &buf );
|
||||||
|
memcpy( hashed + 1+2*SHA_DIGEST_LENGTH, salt, saltlen );
|
||||||
|
hashed[1+2*SHA_DIGEST_LENGTH + saltlen] = '\0';
|
||||||
|
hashed[0] = '{';
|
||||||
|
|
||||||
|
result = strcmp( source, hashed ) == 0 ? TRUE : FALSE;
|
||||||
|
|
||||||
|
tr_free( hashed );
|
||||||
|
tr_free( salt );
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,7 +95,8 @@ int tr_cryptoWeakRandInt( int n );
|
||||||
void tr_cryptoRandBuf( unsigned char *buf,
|
void tr_cryptoRandBuf( unsigned char *buf,
|
||||||
size_t len );
|
size_t len );
|
||||||
|
|
||||||
char* tr_crypt( const void * plaintext );
|
char* tr_ssha1( const void * plaintext );
|
||||||
|
|
||||||
|
tr_bool tr_ssha1_matches( const char * source, const char * pass );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -465,7 +465,6 @@ handle_request( struct evhttp_request * req,
|
||||||
{
|
{
|
||||||
user = p;
|
user = p;
|
||||||
*pass++ = '\0';
|
*pass++ = '\0';
|
||||||
pass = tr_crypt( pass );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +478,8 @@ handle_request( struct evhttp_request * req,
|
||||||
}
|
}
|
||||||
else if( server->isPasswordEnabled
|
else if( server->isPasswordEnabled
|
||||||
&& ( !pass || !user || strcmp( server->username, user )
|
&& ( !pass || !user || strcmp( server->username, user )
|
||||||
|| strcmp( server->password, pass ) ) )
|
|| !tr_ssha1_matches( server->password,
|
||||||
|
pass ) ) )
|
||||||
{
|
{
|
||||||
evhttp_add_header( req->output_headers,
|
evhttp_add_header( req->output_headers,
|
||||||
"WWW-Authenticate",
|
"WWW-Authenticate",
|
||||||
|
@ -511,7 +511,6 @@ handle_request( struct evhttp_request * req,
|
||||||
send_simple_response( req, HTTP_NOTFOUND, req->uri );
|
send_simple_response( req, HTTP_NOTFOUND, req->uri );
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_free( pass );
|
|
||||||
tr_free( user );
|
tr_free( user );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,7 +670,10 @@ tr_rpcSetPassword( tr_rpc_server * server,
|
||||||
const char * password )
|
const char * password )
|
||||||
{
|
{
|
||||||
tr_free( server->password );
|
tr_free( server->password );
|
||||||
server->password = tr_crypt( password );
|
if( *password != '{' )
|
||||||
|
server->password = tr_ssha1( password );
|
||||||
|
else
|
||||||
|
server->password = strdup( password );
|
||||||
dbgmsg( "setting our Password to [%s]", server->password );
|
dbgmsg( "setting our Password to [%s]", server->password );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -762,7 +764,10 @@ tr_rpcInit( tr_session * session,
|
||||||
|
|
||||||
found = tr_bencDictFindStr( settings, TR_PREFS_KEY_RPC_PASSWORD, &str );
|
found = tr_bencDictFindStr( settings, TR_PREFS_KEY_RPC_PASSWORD, &str );
|
||||||
assert( found );
|
assert( found );
|
||||||
s->password = tr_strdup( str );
|
if( *str != '{' )
|
||||||
|
s->password = tr_ssha1( str );
|
||||||
|
else
|
||||||
|
s->password = strdup( str );
|
||||||
|
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
s->stream.zalloc = (alloc_func) Z_NULL;
|
s->stream.zalloc = (alloc_func) Z_NULL;
|
||||||
|
|
Loading…
Reference in a new issue