Ignore:
Timestamp:
Jun 5, 2008, 4:23:03 PM (14 years ago)
Author:
charles
Message:

get RPC password protections working in libT and the gtk+ client. mac, daemon, and cli need to be synced.

File:
1 edited

Legend:

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

    r6046 r6049  
    1717#include <string.h>
    1818
     19#include <unistd.h> /* unlink */
     20
    1921#include <libevent/event.h>
     22#include <shttpd/defs.h> /* edit_passwords */
    2023#include <shttpd/shttpd.h>
    2124
     
    2629
    2730#define MY_NAME "RPC Server"
     31#define MY_REALM "Transmission RPC Server"
    2832
    2933#define BUSY_INTERVAL_MSEC 30
     
    4044    struct evbuffer * out;
    4145    struct event timer;
     46    int isPasswordEnabled;
     47    char * username;
     48    char * password;
    4249    char * acl;
    4350};
     
    121128
    122129static void
     130getPasswordFile( tr_rpc_server * server, char * buf, int buflen )
     131{
     132    tr_buildPath( buf, buflen, tr_sessionGetConfigDir( server->session ),
     133                               "htpasswd",
     134                               NULL );
     135}
     136
     137static void
    123138startServer( tr_rpc_server * server )
    124139{
     
    128143    {
    129144        char ports[128];
     145        char passwd[MAX_PATH_LENGTH];
    130146        struct timeval tv = tr_timevalMsec( UNUSED_INTERVAL_MSEC );
     147
     148        getPasswordFile( server, passwd, sizeof( passwd ) );
     149        if( !server->isPasswordEnabled )
     150            unlink( passwd );
     151        else
     152            edit_passwords( passwd, MY_REALM, "user", "pass" );
    131153
    132154        server->ctx = shttpd_init( );
     
    136158        shttpd_set_option( server->ctx, "dir_list", "0" );
    137159        shttpd_set_option( server->ctx, "root", "/dev/null" );
     160        shttpd_set_option( server->ctx, "auth_realm", MY_REALM );
    138161        if( server->acl ) {
    139162            dbgmsg( "setting acl [%s]", server->acl );
    140163            shttpd_set_option( server->ctx, "acl", server->acl );
    141164        }
     165        if( server->isPasswordEnabled ) {
     166            char * buf = tr_strdup_printf( "/transmission=%s", passwd );
     167            shttpd_set_option( server->ctx, "protect", buf );
     168            tr_free( buf );
     169        }
    142170
    143171        evtimer_set( &server->timer, rpcPulse, server );
     
    151179    if( server->ctx )
    152180    {
     181        char passwd[MAX_PATH_LENGTH];
     182        getPasswordFile( server, passwd, sizeof( passwd ) );
     183        unlink( passwd );
     184
    153185        evtimer_del( &server->timer );
    154186        shttpd_fini( server->ctx );
     
    193225    return server->port;
    194226}
     227
     228/****
     229*****  ACL
     230****/
    195231
    196232/*
     
    328364}
    329365
    330 const char*
     366char*
    331367tr_rpcGetACL( const tr_rpc_server * server )
    332368{
    333     return server->acl ? server->acl : "";
    334 }
     369    return tr_strdup( server->acl ? server->acl : "" );
     370}
     371
     372/****
     373*****  PASSWORD
     374****/
     375
     376void
     377tr_rpcSetUsername( tr_rpc_server        * server,
     378                   const char           * username )
     379{
     380    const int isRunning = server->ctx != NULL;
     381
     382    if( isRunning )
     383        stopServer( server );
     384
     385    tr_free( server->username );
     386    server->username = tr_strdup( username );
     387    dbgmsg( "setting our Username to [%s]", server->username );
     388
     389    if( isRunning )
     390        startServer( server );
     391}
     392
     393char*
     394tr_rpcGetUsername( const tr_rpc_server  * server )
     395{
     396    return tr_strdup( server->username ? server->username : "" );
     397}
     398
     399void
     400tr_rpcSetPassword( tr_rpc_server        * server,
     401                   const char           * password )
     402{
     403    const int isRunning = server->ctx != NULL;
     404
     405    if( isRunning )
     406        stopServer( server );
     407
     408    tr_free( server->password );
     409    server->password = tr_strdup( password );
     410    dbgmsg( "setting our Password to [%s]", server->password );
     411
     412    if( isRunning )
     413        startServer( server );
     414}
     415
     416char*
     417tr_rpcGetPassword( const tr_rpc_server  * server )
     418{
     419    return tr_strdup( server->password ? server->password : "" );
     420}
     421
     422void
     423tr_rpcSetPasswordEnabled( tr_rpc_server  * server,
     424                          int              isEnabled )
     425{
     426    const int isRunning = server->ctx != NULL;
     427
     428    if( isRunning )
     429        stopServer( server );
     430
     431    server->isPasswordEnabled = isEnabled;
     432    dbgmsg( "setting 'password enabled' to %d", isEnabled );
     433
     434    if( isRunning )
     435        startServer( server );
     436}
     437
     438int
     439tr_rpcIsPasswordEnabled( const tr_rpc_server * server )
     440{
     441    return server->isPasswordEnabled;
     442}
     443
     444/****
     445*****  LIFE CYCLE
     446****/
    335447
    336448void
     
    351463            int           isEnabled,
    352464            int           port,
    353             const char  * acl )
     465            const char  * acl,
     466            int           isPasswordEnabled,
     467            const char  * username,
     468            const char  * password )
    354469{
    355470    char * errmsg;
     
    370485    s->out = evbuffer_new( );
    371486    s->acl = tr_strdup( acl );
     487    s->username = tr_strdup( username );
     488    s->password = tr_strdup( password );
     489    s->isPasswordEnabled = isPasswordEnabled;
    372490   
    373491    if( isEnabled )
Note: See TracChangeset for help on using the changeset viewer.