Ignore:
Timestamp:
May 8, 2009, 2:37:46 AM (13 years ago)
Author:
charles
Message:

(trunk libT) add a session_id cookie to the rpc server

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/rpc-server.c

    r8340 r8351  
    5757    struct evhttp *    httpd;
    5858    tr_session *       session;
     59    char *             sessionId;
    5960    char *             username;
    6061    char *             password;
     
    451452}
    452453
    453 static void
    454 handle_request( struct evhttp_request * req,
    455                 void *                  arg )
     454static char*
     455session_id_new( void )
     456{
     457    int i;
     458    const int n = 48;
     459    const char * pool = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
     460    const size_t pool_size = strlen( pool );
     461    char * buf = tr_new( char, n+1 );
     462    for( i=0; i<n; ++i )
     463        buf[i] = pool[ tr_cryptoRandInt( pool_size ) ];
     464    buf[n] = '\0';
     465    return buf;
     466}
     467
     468static tr_bool
     469test_session_id( struct tr_rpc_server * server, struct evhttp_request * req )
     470{
     471    char * needle = tr_strdup_printf( "session_id=%s", server->sessionId );
     472    const char * haystack = evhttp_find_header( req->input_headers, "Cookie" );
     473    const tr_bool success = (haystack!=NULL) && (strstr(haystack,needle)!=NULL);
     474    tr_free( needle );
     475    return success;
     476}
     477
     478static void
     479handle_request( struct evhttp_request * req, void * arg )
    456480{
    457481    struct tr_rpc_server * server = arg;
     
    460484    {
    461485        const char * auth;
    462         char *       user = NULL;
    463         char *       pass = NULL;
     486        char * user = NULL;
     487        char * pass = NULL;
     488        char * cookie;
    464489
    465490        evhttp_add_header( req->output_headers, "Server", MY_REALM );
     491        cookie = tr_strdup_printf( "session_id=%s;Path=/;Discard", server->sessionId );
     492        evhttp_add_header( req->output_headers, "Set-Cookie", cookie );
     493        tr_free( cookie );
    466494
    467495        auth = evhttp_find_header( req->input_headers, "Authorization" );
    468 
    469496        if( auth && !strncasecmp( auth, "basic ", 6 ) )
    470497        {
     
    480507        if( !isAddressAllowed( server, req->remote_host ) )
    481508        {
    482             send_simple_response( req, 401,
     509            send_simple_response( req, 403,
    483510                "<p>Unauthorized IP Address.</p>"
    484511                "<p>Either disable the IP address whitelist or add your address to it.</p>"
     
    511538        {
    512539            handle_clutch( req, server );
     540        }
     541        else if( !test_session_id( server, req ) )
     542        {
     543            send_simple_response( req, 409, "<p>Invalid session_id cookie.</p>" );
    513544        }
    514545        else if( !strncmp( req->uri, "/transmission/rpc", 17 ) )
     
    767798    s = tr_new0( tr_rpc_server, 1 );
    768799    s->session = session;
     800    s->sessionId = session_id_new( );
    769801
    770802    found = tr_bencDictFindBool( settings, TR_PREFS_KEY_RPC_ENABLED, &boolVal );
Note: See TracChangeset for help on using the changeset viewer.