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

(1.5x) add a session_id cookie to the rpc server

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/1.5x/libtransmission/rpc-server.c

    r8204 r8352  
    3030#include "transmission.h"
    3131#include "bencode.h"
     32#include "crypto.h"
    3233#include "list.h"
    3334#include "platform.h"
     
    5455    struct evhttp *    httpd;
    5556    tr_session *       session;
     57    char *             sessionId;
    5658    char *             username;
    5759    char *             password;
     
    446448}
    447449
    448 static void
    449 handle_request( struct evhttp_request * req,
    450                 void *                  arg )
     450static char*
     451session_id_new( void )
     452{
     453    int i;
     454    const int n = 48;
     455    const char * pool = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
     456    const size_t pool_size = strlen( pool );
     457    char * buf = tr_new( char, n+1 );
     458    for( i=0; i<n; ++i )
     459        buf[i] = pool[ tr_cryptoRandInt( pool_size ) ];
     460    buf[n] = '\0';
     461    return buf;
     462}
     463
     464static tr_bool
     465test_session_id( struct tr_rpc_server * server, struct evhttp_request * req )
     466{
     467    char * needle = tr_strdup_printf( "session_id=%s", server->sessionId );
     468    const char * haystack = evhttp_find_header( req->input_headers, "Cookie" );
     469    const tr_bool success = (haystack!=NULL) && (strstr(haystack,needle)!=NULL);
     470    tr_free( needle );
     471    return success;
     472}
     473
     474static void
     475handle_request( struct evhttp_request * req, void * arg )
    451476{
    452477    struct tr_rpc_server * server = arg;
     
    455480    {
    456481        const char * auth;
    457         char *       user = NULL;
    458         char *       pass = NULL;
     482        char * user = NULL;
     483        char * pass = NULL;
     484        char * cookie;
    459485
    460486        evhttp_add_header( req->output_headers, "Server", MY_REALM );
     487        cookie = tr_strdup_printf( "session_id=%s;Path=/;Discard", server->sessionId );
     488        evhttp_add_header( req->output_headers, "Set-Cookie", cookie );
     489        tr_free( cookie );
    461490
    462491        auth = evhttp_find_header( req->input_headers, "Authorization" );
    463 
    464492        if( auth && !strncasecmp( auth, "basic ", 6 ) )
    465493        {
     
    475503        if( !isAddressAllowed( server, req->remote_host ) )
    476504        {
    477             send_simple_response( req, 401,
     505            send_simple_response( req, 403,
    478506                "<p>Unauthorized IP Address.</p>"
    479507                "<p>Either disable the IP address whitelist or add your address to it.</p>"
     
    505533        {
    506534            handle_clutch( req, server );
     535        }
     536        else if( !test_session_id( server, req ) )
     537        {
     538            send_simple_response( req, 409, "<p>Invalid session_id cookie.</p>" );
    507539        }
    508540        else if( !strncmp( req->uri, "/transmission/rpc", 17 ) )
     
    742774    s = tr_new0( tr_rpc_server, 1 );
    743775    s->session = session;
     776    s->sessionId = session_id_new( );
    744777
    745778    found = tr_bencDictFindInt( settings, TR_PREFS_KEY_RPC_ENABLED, &i );
Note: See TracChangeset for help on using the changeset viewer.