Changeset 6049


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.

Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/gtk/main.c

    r6036 r6049  
    429429                            pref_flag_get( PREF_KEY_RPC_ENABLED ),
    430430                            pref_int_get( PREF_KEY_RPC_PORT ),
    431                             pref_string_get( PREF_KEY_RPC_ACL ) );
     431                            pref_string_get( PREF_KEY_RPC_ACL ),
     432                            pref_flag_get( PREF_KEY_RPC_PASSWORD_ENABLED ),
     433                            pref_string_get( PREF_KEY_RPC_USERNAME ),
     434                            pref_string_get( PREF_KEY_RPC_PASSWORD ) );
    432435        cbdata->core = tr_core_new( h );
    433436
     
    949952        g_free( s );
    950953    }
     954    else if( !strcmp( key, PREF_KEY_RPC_USERNAME ) )
     955    {
     956        char * s = pref_string_get( key );
     957        tr_sessionSetRPCUsername( tr, s );
     958        g_free( s );
     959    }
    951960    else if( !strcmp( key, PREF_KEY_RPC_PASSWORD ) )
    952961    {
    953962        char * s = pref_string_get( key );
    954         /*FIXMEtr_sessionSetRPCACL( tr, s );*/
     963        tr_sessionSetRPCPassword( tr, s );
    955964        g_free( s );
    956965    }
     
    958967    {
    959968        const gboolean enabled = pref_flag_get( key );
    960         /*FIXME tr_sessionSetRPCEnabled( tr, enabled );*/
     969        tr_sessionSetRPCPasswordEnabled( tr, enabled );
    961970    }
    962971}
  • trunk/gtk/tr-prefs.c

    r6036 r6049  
    3636{
    3737    int i;
    38     char pw[12];
     38    char pw[32];
    3939    const char * str;
     40    const char * pool = "abcdefghijklmnopqrstuvwxyz"
     41                        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     42                        "1234567890";
    4043
    4144    cf_check_older_configs( );
     
    102105    pref_string_set_default ( PREF_KEY_RPC_ACL, TR_DEFAULT_RPC_ACL );
    103106
    104     for( i=0; i<8; ++i )
    105         pw[i] = 'a' + tr_rand(26);
    106     pw[8] = '\0';
     107    for( i=0; i<16; ++i )
     108        pw[i] = pool[ tr_rand( strlen( pool ) ) ];
     109    pw[16] = '\0';
     110    pref_string_set_default( PREF_KEY_RPC_USERNAME, "transmission" );
    107111    pref_string_set_default( PREF_KEY_RPC_PASSWORD, pw );
    108112    pref_flag_set_default  ( PREF_KEY_RPC_PASSWORD_ENABLED, FALSE );
    109 
    110113
    111114    pref_save( NULL );
     
    616619    GtkListStore * store;
    617620    GtkWidget * remove_button;
    618     GtkWidget * pw_entry;
    619621    GSList * widgets;
     622    GSList * auth_widgets;
    620623    GtkToggleButton * rpc_tb;
    621     GtkToggleButton * pw_tb;
     624    GtkToggleButton * auth_tb;
    622625};
    623626
     
    728731    GSList * l;
    729732    const int rpc_active = gtk_toggle_button_get_active( page->rpc_tb );
    730     const int pw_active = gtk_toggle_button_get_active( page->pw_tb );
     733    const int auth_active = gtk_toggle_button_get_active( page->auth_tb );
    731734    GtkTreeSelection * sel = gtk_tree_view_get_selection( page->view );
    732735    const int have_addr = gtk_tree_selection_get_selected( sel, NULL, NULL );
     
    737740        gtk_widget_set_sensitive( GTK_WIDGET( l->data ), rpc_active );
    738741
    739     gtk_widget_set_sensitive( page->pw_entry, rpc_active && pw_active );
     742    for( l=page->auth_widgets; l!=NULL; l=l->next )
     743        gtk_widget_set_sensitive( GTK_WIDGET( l->data ), rpc_active && auth_active);
    740744
    741745    gtk_widget_set_sensitive( page->remove_button,
     
    745749static void
    746750onRPCToggled( GtkToggleButton * tb UNUSED, gpointer page )
    747 {
    748     refreshRPCSensitivity( page );
    749 }
    750 static void
    751 onRPCPassToggled( GtkToggleButton * tb UNUSED, gpointer page )
    752751{
    753752    refreshRPCSensitivity( page );
     
    766765    GtkWidget * t;
    767766    GtkWidget * w;
    768     GtkWidget * w2;
    769     GtkWidget * enabled_toggle;
    770767    struct remote_page * page = g_new0( struct remote_page, 1 );
    771768
     
    781778        w = new_check_button( s, PREF_KEY_RPC_ENABLED, core );
    782779        hig_workarea_add_wide_control( t, &row, w );
    783         enabled_toggle = w;
    784780        page->rpc_tb = GTK_TOGGLE_BUTTON( w );
    785781        g_signal_connect( w, "clicked", G_CALLBACK(onRPCToggled), page );
    786782
    787         /* password protection */
    788         s = _( "Require _password:" );
     783        /* require authentication */
     784        s = _( "Require _authentication" );
    789785        w = new_check_button( s, PREF_KEY_RPC_PASSWORD_ENABLED, core );
    790         g_signal_connect( w, "clicked", G_CALLBACK(onRPCPassToggled), page );
    791         page->pw_tb = GTK_TOGGLE_BUTTON( w );
     786        hig_workarea_add_wide_control( t, &row, w );
     787        page->auth_tb = GTK_TOGGLE_BUTTON( w );
    792788        page->widgets = g_slist_append( page->widgets, w );
    793         //toggles_set_sensitivity( w, enabled_toggle, NULL );
    794         w2 = page->pw_entry = new_entry( PREF_KEY_RPC_PASSWORD, core );
    795         //toggles_set_sensitivity( w2, enabled_toggle, w, NULL );
    796         gtk_entry_set_visibility( GTK_ENTRY( w2 ), FALSE );
    797         hig_workarea_add_row_w( t, &row, w, w2, NULL );
     789        g_signal_connect( w, "clicked", G_CALLBACK(onRPCToggled), page );
     790
     791        /* username */
     792        s = _( "_Username:" );
     793        w = new_entry( PREF_KEY_RPC_USERNAME, core );
     794        page->auth_widgets = g_slist_append( page->auth_widgets, w );
     795        w = hig_workarea_add_row( t, &row, s, w, NULL );
     796        page->auth_widgets = g_slist_append( page->auth_widgets, w );
     797
     798        /* password */
     799        s = _( "_Password:" );
     800        w = new_entry( PREF_KEY_RPC_PASSWORD, core );
     801        gtk_entry_set_visibility( GTK_ENTRY( w ), FALSE );
     802        page->auth_widgets = g_slist_append( page->auth_widgets, w );
     803        w = hig_workarea_add_row( t, &row, s, w, NULL );
     804        page->auth_widgets = g_slist_append( page->auth_widgets, w );
    798805
    799806        /* port */
    800807        w = new_spin_button( PREF_KEY_RPC_PORT, core, 0, 65535, 1 );
    801808        page->widgets = g_slist_append( page->widgets, w );
    802         //toggles_set_sensitivity( w, enabled_toggle, NULL );
    803809        w = hig_workarea_add_row( t, &row, _( "Listening _port:" ), w, NULL );
    804810        page->widgets = g_slist_append( page->widgets, w );
    805         //toggles_set_sensitivity( w, enabled_toggle, NULL );
    806811
    807812        /* access control list */
     
    822827
    823828        page->widgets = g_slist_append( page->widgets, w );
    824         //toggles_set_sensitivity( w, enabled_toggle, NULL );
    825829        v = page->view = GTK_TREE_VIEW( w );
    826830        gtk_tooltips_set_tip( tips, w,
     
    850854        gtk_misc_set_alignment( GTK_MISC( w ), 0.0f, 0.1f );
    851855        page->widgets = g_slist_append( page->widgets, w );
    852         //toggles_set_sensitivity( w, enabled_toggle, NULL );
    853856        g_free( val );
    854857
     
    876879        w = gtk_button_new_from_stock( GTK_STOCK_ADD );
    877880        page->widgets = g_slist_append( page->widgets, w );
    878         //toggles_set_sensitivity( w, enabled_toggle, NULL );
    879881        g_signal_connect( w, "clicked", G_CALLBACK(onAddACLClicked), page );
    880882        gtk_box_pack_start_defaults( GTK_BOX( h ), w );
     
    885887        }
    886888
     889    refreshRPCSensitivity( page );
    887890    hig_workarea_finish( t, &row );
    888891    return t;
  • trunk/gtk/tr-prefs.h

    r6007 r6049  
    6060#define PREF_KEY_RPC_PASSWORD_ENABLED   "rpc-password-required"
    6161#define PREF_KEY_RPC_PASSWORD           "rpc-password"
     62#define PREF_KEY_RPC_USERNAME           "rpc-username"
    6263
    6364
  • trunk/libtransmission/JSON_parser.c

    r5969 r6049  
    5858
    5959#if _MSC_VER >= 1400 /* Visual Studio 2005 and up */
    60 #       pragma warning(disable:4996) // unsecure sscanf
     60#       pragma warning(disable:4996) /* unsecure sscanf */
    6161#endif
    6262
  • trunk/libtransmission/completion.c

    r5708 r6049  
    106106        {
    107107            if( !info->pieces[i].dnd ) {
    108                 // we want the piece...
     108                /* we want the piece... */
    109109                size += tr_torPieceCountBytes( tor, i );
    110110            } else if( tr_cpPieceIsComplete( cp, i ) ) {
    111                 // we have the piece...
     111                /* we have the piece... */
    112112                size += tr_torPieceCountBytes( tor, i );
    113113            } else if( cp->completeBlocks[i] ) {
    114                 // we have part of the piece...
     114                /* we have part of the piece... */
    115115                const tr_block_index_t b = tr_torPieceFirstBlock( tor, i );
    116116                const tr_block_index_t e = b + tr_torPieceCountBlocks( tor, i );
  • 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 )
  • trunk/libtransmission/rpc-server.h

    r6043 r6049  
    1616typedef struct tr_rpc_server tr_rpc_server;
    1717
    18 tr_rpc_server * tr_rpcInit  ( struct tr_handle       * session,
    19                               int                      isEnabled,
    20                               int                      port,
    21                               const char             * acl );
     18tr_rpc_server * tr_rpcInit       ( struct tr_handle     * session,
     19                                   int                    isEnabled,
     20                                   int                    port,
     21                                   const char           * acl,
     22                                   int                    isPasswordEnabled,
     23                                   const char           * username,
     24                                   const char           * password );
    2225
    23 void        tr_rpcClose     ( tr_rpc_server         ** freeme );
     26void    tr_rpcClose              ( tr_rpc_server       ** freeme );
    2427
    25 void        tr_rpcSetEnabled( tr_rpc_server          * server,
    26                               int                      isEnabled );
     28void    tr_rpcSetEnabled         ( tr_rpc_server        * server,
     29                                   int                    isEnabled );
    2730
    28 int         tr_rpcIsEnabled ( const tr_rpc_server    * server );
     31int     tr_rpcIsEnabled          ( const tr_rpc_server  * server );
    2932
    30 void        tr_rpcSetPort   ( tr_rpc_server          * server,
    31                               int                      port );
     33void    tr_rpcSetPort            ( tr_rpc_server        * server,
     34                                   int                    port );
    3235
    33 int         tr_rpcGetPort   ( const tr_rpc_server    * server );
     36int     tr_rpcGetPort            ( const tr_rpc_server  * server );
    3437
    35 int         tr_rpcSetTest   ( const tr_rpc_server    * server,
    36                               const char             * acl,
    37                               char                  ** allocme_errmsg );
     38int     tr_rpcSetTest            ( const tr_rpc_server  * server,
     39                                   const char           * acl,
     40                                   char                ** allocme_errmsg );
    3841
    39 int         tr_rpcTestACL   ( const tr_rpc_server    * server,
    40                               const char             * acl,
    41                               char                  ** allocme_errmsg );
     42int     tr_rpcTestACL            ( const tr_rpc_server  * server,
     43                                   const char           * acl,
     44                                   char                ** allocme_errmsg );
    4245
    43 int         tr_rpcSetACL    ( tr_rpc_server          * server,
    44                               const char             * acl,
    45                               char                  ** allocme_errmsg );
     46int     tr_rpcSetACL             ( tr_rpc_server        * server,
     47                                   const char           * acl,
     48                                   char                ** allocme_errmsg );
    4649
    47 const char* tr_rpcGetACL    ( const tr_rpc_server    * server );
     50char*   tr_rpcGetACL             ( const tr_rpc_server  * server );
     51
     52void    tr_rpcSetPassword        ( tr_rpc_server        * server,
     53                                   const char           * password );
     54
     55char*   tr_rpcGetPassword        ( const tr_rpc_server  * server );
     56
     57void    tr_rpcSetUsername        ( tr_rpc_server        * server,
     58                                   const char           * username );
     59
     60char*   tr_rpcGetUsername        ( const tr_rpc_server  * server );
     61
     62void    tr_rpcSetPasswordEnabled ( tr_rpc_server        * server,
     63                                   int                    isEnabled );
     64
     65int     tr_rpcIsPasswordEnabled  ( const tr_rpc_server  * session );
    4866
    4967#endif
  • trunk/libtransmission/session.c

    r6031 r6049  
    138138                    int          rpcIsEnabled,
    139139                    int          rpcPort,
    140                     const char * rpcACL )
     140                    const char * rpcACL,
     141                    int          rpcPasswordIsEnabled,
     142                    const char * rpcUsername,
     143                    const char * rpcPassword )
    141144{
    142145    tr_handle * h;
     
    200203
    201204    h->web = tr_webInit( h );
    202     h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort, rpcACL );
     205    h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort, rpcACL,
     206                                  rpcPasswordIsEnabled, rpcUsername, rpcPassword );
    203207
    204208    metainfoLookupRescan( h );
     
    230234                               TR_DEFAULT_RPC_ENABLED,
    231235                               TR_DEFAULT_RPC_PORT,
    232                                TR_DEFAULT_RPC_ACL );
     236                               TR_DEFAULT_RPC_ACL,
     237                               FALSE,
     238                               "fnord",
     239                               "potzrebie" );
    233240}
    234241
     
    792799}
    793800
    794 const char*
     801char*
    795802tr_sessionGetRPCACL( const tr_session * session )
    796803{
    797804    return tr_rpcGetACL( session->rpcServer );
    798805}
     806
     807void
     808tr_sessionSetRPCPassword( tr_handle * session, const char * password )
     809{
     810    tr_rpcSetPassword( session->rpcServer, password );
     811}
     812
     813char*
     814tr_sessionGetRPCPassword( const tr_handle * session )
     815{
     816    return tr_rpcGetPassword( session->rpcServer );
     817}
     818
     819void
     820tr_sessionSetRPCUsername( tr_handle * session, const char * username )
     821{
     822    tr_rpcSetUsername( session->rpcServer, username );
     823}
     824
     825char*
     826tr_sessionGetRPCUsername( const tr_handle * session )
     827{
     828    return tr_rpcGetUsername( session->rpcServer );
     829}
     830
     831void
     832tr_sessionSetRPCPasswordEnabled( tr_handle * session, int isEnabled )
     833{
     834    tr_rpcSetPasswordEnabled( session->rpcServer, isEnabled );
     835}
     836
     837int
     838tr_sessionIsRPCPasswordEnabled( const tr_handle * session )
     839{
     840    return tr_rpcIsPasswordEnabled( session->rpcServer );
     841}
  • trunk/libtransmission/tracker.c

    r6042 r6049  
    328328
    329329            if(( tr_bencDictFindStr( &benc, "failure reason", &str ))) {
    330                // publishErrorMessageAndStop( t, str );
    331330                publishMessage( t, str, TR_TRACKER_ERROR );
    332331                success = FALSE;
  • trunk/libtransmission/transmission.h

    r6031 r6049  
    230230                                int          rpcIsEnabled,
    231231                                int          rpcPort,
    232                                 const char * rpcAccessControlList );
     232                                const char * rpcAccessControlList,
     233                                int          rpcPasswordIsEnabled,
     234                                const char * rpcUsername,
     235                                const char * rpcPassword );
    233236
    234237/** @brief Shorter form of tr_sessionInitFull()
     
    339342                         char       ** allocme_errmsg );
    340343
    341 /** Returns the Access Control List for allowing/denying RPC requests.
     344/** @brief get the Access Control List for allowing/denying RPC requests.
     345    @return a comma-separated string of ACL rules.  tr_free() when done.
    342346    @see tr_sessionInitFull
    343347    @see tr_sessionSetRPCACL */
    344 const char* tr_sessionGetRPCACL( const tr_handle * );
     348char* tr_sessionGetRPCACL( const tr_handle * );
     349
     350void  tr_sessionSetRPCPassword( tr_handle       * session,
     351                                const char      * password );
     352
     353void  tr_sessionSetRPCUsername( tr_handle       * session,
     354                                const char      * username );
     355
     356/** @brief get the password used to restrict RPC requests.
     357    @return the password string. tr_free() when done.
     358    @see tr_sessionInitFull()
     359    @see tr_sessionSetRPCPassword() */
     360char* tr_sessionGetRPCPassword( const tr_handle * session );
     361
     362char* tr_sessionGetRPCUsername( const tr_handle * session  );
     363
     364void  tr_sessionSetRPCPasswordEnabled( tr_handle * session,
     365                                       int         isEnabled );
     366
     367int   tr_sessionIsRPCPasswordEnabled( const tr_handle * session );
     368
    345369
    346370typedef enum
Note: See TracChangeset for help on using the changeset viewer.