From: Charles Kerr Date: Wed, 1 Oct 2008 20:23:57 +0000 (+0000) Subject: #1309: Web/RPC interface ACL ignored X-Git-Tag: 1.40~261 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bddf34d7a877a382a1c84ddeaa9a93fbf758c929;p=transmission #1309: Web/RPC interface ACL ignored --- diff --git a/cli/cli.c b/cli/cli.c index 2326c111b..3ef218271 100644 --- a/cli/cli.c +++ b/cli/cli.c @@ -310,7 +310,7 @@ main( int argc, peerSocketTOS, TR_DEFAULT_RPC_ENABLED, TR_DEFAULT_RPC_PORT, - TR_DEFAULT_RPC_ACL, + TR_DEFAULT_RPC_WHITELIST, FALSE, "fnord", "potzrebie", TR_DEFAULT_PROXY_ENABLED, TR_DEFAULT_PROXY, diff --git a/daemon/daemon.c b/daemon/daemon.c index d4dcedea8..795a2d458 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -44,7 +44,7 @@ static char myConfigFilename[MAX_PATH_LENGTH]; #define KEY_AUTH_REQUIRED "rpc-authentication-required" #define KEY_USERNAME "rpc-username" #define KEY_PASSWORD "rpc-password" -#define KEY_ACL "rpc-access-control-list" +#define KEY_WHITELIST "rpc-whitelist" #define KEY_RPC_PORT "rpc-port" #define KEY_DSPEED "download-limit" #define KEY_DSPEED_ENABLED "download-limit-enabled" @@ -99,7 +99,7 @@ saveState( tr_session * s ) replaceStr( &d, KEY_PASSWORD, strs[n++] = tr_sessionGetRPCPassword( s ) ); - replaceStr( &d, KEY_ACL, strs[n++] = tr_sessionGetRPCACL( s ) ); + replaceStr( &d, KEY_WHITELIST, strs[n++] = tr_sessionGetRPCWhitelist( s ) ); replaceInt( &d, KEY_RPC_PORT, tr_sessionGetRPCPort( s ) ); replaceInt( &d, KEY_AUTH_REQUIRED, tr_sessionIsRPCPasswordEnabled( s ) ); replaceInt( &d, KEY_DSPEED, @@ -160,7 +160,7 @@ static void session_init( const char * configDir, const char * downloadDir, int rpcPort, - const char * acl, + const char * whitelist, int authRequired, const char * username, const char * password, @@ -208,8 +208,8 @@ session_init( const char * configDir, TR_DEFAULT_BLOCKLIST_ENABLED ); getConfigInt( dict, KEY_RPC_PORT, &rpcPort, TR_DEFAULT_RPC_PORT ); - getConfigStr( dict, KEY_ACL, &acl, - TR_DEFAULT_RPC_ACL ); + getConfigStr( dict, KEY_WHITELIST, &whitelist, + TR_DEFAULT_RPC_WHITELIST ); getConfigInt( dict, KEY_AUTH_REQUIRED, &authRequired, FALSE ); getConfigStr( dict, KEY_USERNAME, &username, NULL ); getConfigStr( dict, KEY_PASSWORD, &password, NULL ); @@ -231,7 +231,7 @@ session_init( const char * configDir, TR_MSG_INF, 0, blocklistEnabled, TR_DEFAULT_PEER_SOCKET_TOS, - TRUE, rpcPort, acl, authRequired, + TRUE, rpcPort, whitelist, authRequired, username, password, TR_DEFAULT_PROXY_ENABLED, TR_DEFAULT_PROXY, @@ -270,8 +270,8 @@ getUsage( void ) static const struct tr_option options[] = { - { 'a', "acl", - "Access Control List. (Default: " TR_DEFAULT_RPC_ACL ")", "a", + { 'a', "allowed", + "Allowed IP addresses. (Default: " TR_DEFAULT_RPC_WHITELIST ")", "a", 1, "" }, { 'b', "blocklist", "Enable peer blocklists", "b", 0, NULL }, @@ -312,7 +312,7 @@ readargs( int argc, const char ** configDir, const char ** downloadDir, int * rpcPort, - const char ** acl, + const char ** whitelist, int * authRequired, const char ** username, const char ** password, @@ -326,7 +326,7 @@ readargs( int argc, switch( c ) { case 'a': - *acl = optarg; break; + *whitelist = optarg; break; case 'b': *blocklistEnabled = 1; break; @@ -457,7 +457,7 @@ main( int argc, char * freeme = NULL; const char * configDir = NULL; const char * downloadDir = NULL; - const char * acl = NULL; + const char * whitelist = NULL; const char * username = NULL; const char * password = NULL; @@ -468,7 +468,7 @@ main( int argc, signal( SIGHUP, SIG_IGN ); readargs( argc, (const char**)argv, &nofork, &configDir, &downloadDir, - &rpcPort, &acl, &authRequired, &username, &password, + &rpcPort, &whitelist, &authRequired, &username, &password, &blocklistEnabled ); if( configDir == NULL ) configDir = freeme = tr_strdup_printf( "%s-daemon", @@ -486,7 +486,7 @@ main( int argc, } session_init( configDir, downloadDir, - rpcPort, acl, authRequired, username, password, + rpcPort, whitelist, authRequired, username, password, blocklistEnabled ); while( !closing ) diff --git a/daemon/transmission-daemon.1 b/daemon/transmission-daemon.1 index eab93e2a8..3d03a9555 100644 --- a/daemon/transmission-daemon.1 +++ b/daemon/transmission-daemon.1 @@ -30,12 +30,11 @@ via RPC commands from transmission's web interface or .Sh OPTIONS .Bl -tag -width Ds -.It Fl a Fl -acl Ar (+|-)x.x.x.x,... -Specify access control list (ACL) to control which hosts may submit RPC requests. -This is a comma-separated list of IP addresses, each prepended by a '-' or '+' -to denote that access should be denied or allowed to that address. +.It Fl a Fl -allowed Ar x.x.x.x,... +Allow RPC accecss to a comma-delimited whitelist of IP addresses. Wildcards can be specified in an address by using '*'. -Default: +127.0.0.1 +Default: "127.0.0.1" +Example: "127.0.0.*,192.168.1.*" .It Fl b Fl -blocklist Enable peer blocklists. Transmission understands the bluetack blocklist file format. diff --git a/gtk/main.c b/gtk/main.c index 92ea41d1a..fbd778f8c 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -484,7 +484,7 @@ main( int argc, pref_int_get( PREF_KEY_PEER_SOCKET_TOS ), pref_flag_get( PREF_KEY_RPC_ENABLED ), pref_int_get( PREF_KEY_RPC_PORT ), - pref_string_get( PREF_KEY_RPC_ACL ), + pref_string_get( PREF_KEY_RPC_WHITELIST ), pref_flag_get( PREF_KEY_RPC_AUTH_ENABLED ), pref_string_get( PREF_KEY_RPC_USERNAME ), pref_string_get( PREF_KEY_RPC_PASSWORD ), @@ -1192,10 +1192,10 @@ prefschanged( TrCore * core UNUSED, { tr_sessionSetRPCEnabled( tr, pref_flag_get( key ) ); } - else if( !strcmp( key, PREF_KEY_RPC_ACL ) ) + else if( !strcmp( key, PREF_KEY_RPC_WHITELIST ) ) { const char * s = pref_string_get( key ); - tr_sessionSetRPCACL( tr, s ); + tr_sessionSetRPCWhitelist( tr, s ); } else if( !strcmp( key, PREF_KEY_RPC_USERNAME ) ) { diff --git a/gtk/tr-prefs.c b/gtk/tr-prefs.c index c1171f802..433426ee3 100644 --- a/gtk/tr-prefs.c +++ b/gtk/tr-prefs.c @@ -127,7 +127,7 @@ tr_prefs_init_global( void ) pref_flag_set_default ( PREF_KEY_RPC_ENABLED, TR_DEFAULT_RPC_ENABLED ); pref_int_set_default ( PREF_KEY_RPC_PORT, TR_DEFAULT_RPC_PORT ); - pref_string_set_default ( PREF_KEY_RPC_ACL, TR_DEFAULT_RPC_ACL ); + pref_string_set_default ( PREF_KEY_RPC_WHITELIST, TR_DEFAULT_RPC_WHITELIST ); rand = g_rand_new ( ); for( i = 0; i < 16; ++i ) @@ -556,29 +556,14 @@ peerPage( GObject * core ) ***** Web Tab ****/ -static GtkTreeModel* -allow_deny_model_new( void ) -{ - GtkTreeIter iter; - GtkListStore * store = gtk_list_store_new( 2, G_TYPE_STRING, - G_TYPE_CHAR ); - - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, 0, _( "Allow" ), 1, '+', -1 ); - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, 0, _( "Deny" ), 1, '-', -1 ); - return GTK_TREE_MODEL( store ); -} - enum { COL_ADDRESS, - COL_PERMISSION, N_COLS }; static GtkTreeModel* -acl_tree_model_new( const char * acl ) +whitelist_tree_model_new( const char * whitelist ) { int i; char ** rules; @@ -586,23 +571,15 @@ acl_tree_model_new( const char * acl ) G_TYPE_STRING, G_TYPE_STRING ); - rules = g_strsplit( acl, ",", 0 ); + rules = g_strsplit( whitelist, ",", 0 ); for( i = 0; rules && rules[i]; ++i ) { + GtkTreeIter iter; const char * s = rules[i]; while( isspace( *s ) ) ++s; - - if( *s == '+' || *s == '-' ) - { - GtkTreeIter iter; - gtk_list_store_append( store, &iter ); - gtk_list_store_set( store, &iter, - COL_PERMISSION, *s == '+' ? _( - "Allow" ) : _( "Deny" ), - COL_ADDRESS, s + 1, - -1 ); - } + gtk_list_store_append( store, &iter ); + gtk_list_store_set( store, &iter, COL_ADDRESS, s, -1 ); } g_strfreev( rules ); @@ -622,7 +599,7 @@ struct remote_page }; static void -refreshACL( struct remote_page * page ) +refreshWhitelist( struct remote_page * page ) { GtkTreeIter iter; GtkTreeModel * model = GTK_TREE_MODEL( page->store ); @@ -630,68 +607,43 @@ refreshACL( struct remote_page * page ) if( gtk_tree_model_get_iter_first( model, &iter ) ) do { - char * permission; char * address; - gtk_tree_model_get( model, &iter, COL_PERMISSION, &permission, + gtk_tree_model_get( model, &iter, COL_ADDRESS, &address, -1 ); - g_string_append_c( gstr, strcmp( permission, _( - "Allow" ) ) ? '-' : '+' ); g_string_append( gstr, address ); - g_string_append( gstr, ", " ); + g_string_append( gstr, "," ); g_free( address ); - g_free( permission ); } while( gtk_tree_model_iter_next( model, &iter ) ); - g_string_truncate( gstr, gstr->len - 2 ); /* remove the trailing ", " */ + g_string_truncate( gstr, gstr->len - 1 ); /* remove the trailing comma */ - tr_core_set_pref( page->core, PREF_KEY_RPC_ACL, gstr->str ); + tr_core_set_pref( page->core, PREF_KEY_RPC_WHITELIST, gstr->str ); g_string_free( gstr, TRUE ); } -static void -onPermissionEdited( GtkCellRendererText * renderer UNUSED, - gchar * path_string, - gchar * new_text, - gpointer gpage ) -{ - GtkTreeIter iter; - GtkTreePath * path = gtk_tree_path_new_from_string( path_string ); - struct remote_page * page = gpage; - GtkTreeModel * model = GTK_TREE_MODEL( page->store ); - - if( gtk_tree_model_get_iter( model, &iter, path ) ) - gtk_list_store_set( page->store, &iter, COL_PERMISSION, new_text, - -1 ); - gtk_tree_path_free( path ); - refreshACL( page ); -} - static void onAddressEdited( GtkCellRendererText * r UNUSED, gchar * path_string, - gchar * new_text, + gchar * address, gpointer gpage ) { - char * acl; GtkTreeIter iter; struct remote_page * page = gpage; GtkTreeModel * model = GTK_TREE_MODEL( page->store ); GtkTreePath * path = gtk_tree_path_new_from_string( path_string ); - acl = g_strdup_printf( "+%s", new_text ); if( gtk_tree_model_get_iter( model, &iter, path ) ) - gtk_list_store_set( page->store, &iter, COL_ADDRESS, new_text, -1 ); + gtk_list_store_set( page->store, &iter, COL_ADDRESS, address, -1 ); - g_free( acl ); gtk_tree_path_free( path ); - refreshACL( page ); + refreshWhitelist( page ); } static void -onAddACLClicked( GtkButton * b UNUSED, +onAddWhitelistClicked( GtkButton * b UNUSED, gpointer gpage ) { GtkTreeIter iter; @@ -700,7 +652,6 @@ onAddACLClicked( GtkButton * b UNUSED, gtk_list_store_append( page->store, &iter ); gtk_list_store_set( page->store, &iter, - COL_PERMISSION, _( "Allow" ), COL_ADDRESS, "0.0.0.0", -1 ); @@ -713,7 +664,7 @@ onAddACLClicked( GtkButton * b UNUSED, } static void -onRemoveACLClicked( GtkButton * b UNUSED, +onRemoveWhitelistClicked( GtkButton * b UNUSED, gpointer gpage ) { struct remote_page * page = gpage; @@ -723,7 +674,7 @@ onRemoveACLClicked( GtkButton * b UNUSED, if( gtk_tree_selection_get_selected( sel, NULL, &iter ) ) { gtk_list_store_remove( page->store, &iter ); - refreshACL( page ); + refreshWhitelist( page ); } } @@ -761,7 +712,7 @@ onRPCToggled( GtkToggleButton * tb UNUSED, } static void -onACLSelectionChanged( GtkTreeSelection * sel UNUSED, +onWhitelistSelectionChanged( GtkTreeSelection * sel UNUSED, gpointer page ) { refreshRPCSensitivity( page ); @@ -840,8 +791,8 @@ webPage( GObject * core ) /* access control list */ { - const char * val = pref_string_get( PREF_KEY_RPC_ACL ); - GtkTreeModel * m = acl_tree_model_new( val ); + const char * val = pref_string_get( PREF_KEY_RPC_WHITELIST ); + GtkTreeModel * m = whitelist_tree_model_new( val ); GtkTreeViewColumn * c; GtkCellRenderer * r; GtkTreeSelection * sel; @@ -850,7 +801,6 @@ webPage( GObject * core ) GtkWidget * h; GtkTooltips * tips = gtk_tooltips_new( ); - s = _( "Access control list:" ); page->store = GTK_LIST_STORE( m ); w = gtk_tree_view_new_with_model( m ); g_signal_connect( w, "button-release-event", @@ -864,7 +814,7 @@ webPage( GObject * core ) NULL ); sel = gtk_tree_view_get_selection( v ); g_signal_connect( sel, "changed", - G_CALLBACK( onACLSelectionChanged ), page ); + G_CALLBACK( onWhitelistSelectionChanged ), page ); g_object_unref( G_OBJECT( m ) ); gtk_tree_view_set_headers_visible( v, TRUE ); w = gtk_frame_new( NULL ); @@ -876,43 +826,29 @@ webPage( GObject * core ) g_signal_connect( r, "edited", G_CALLBACK( onAddressEdited ), page ); g_object_set( G_OBJECT( r ), "editable", TRUE, NULL ); - c = gtk_tree_view_column_new_with_attributes( _( "IP Address" ), r, + c = gtk_tree_view_column_new_with_attributes( NULL, r, "text", COL_ADDRESS, NULL ); gtk_tree_view_column_set_expand( c, TRUE ); gtk_tree_view_append_column( v, c ); + gtk_tree_view_set_headers_visible( v, FALSE ); + s = _( "Allowed _IP Addresses:" ); w = hig_workarea_add_row( t, &row, s, w, NULL ); - gtk_misc_set_alignment( GTK_MISC( w ), 0.0f, 0.1f ); + gtk_misc_set_alignment( GTK_MISC( w ), 0.0f, 0.0f ); + gtk_misc_set_padding( GTK_MISC( w ), 0, GUI_PAD ); page->widgets = g_slist_append( page->widgets, w ); - /* permission column */ - m = allow_deny_model_new( ); - r = gtk_cell_renderer_combo_new( ); - g_object_set( G_OBJECT( r ), "model", m, - "editable", TRUE, - "has-entry", FALSE, - "text-column", 0, - NULL ); - c = gtk_tree_view_column_new_with_attributes( _( - "Permission" ), r, - "text", - COL_PERMISSION, - NULL ); - g_signal_connect( r, "edited", - G_CALLBACK( onPermissionEdited ), page ); - gtk_tree_view_append_column( v, c ); - h = gtk_hbox_new( TRUE, GUI_PAD ); w = gtk_button_new_from_stock( GTK_STOCK_REMOVE ); g_signal_connect( w, "clicked", G_CALLBACK( - onRemoveACLClicked ), page ); + onRemoveWhitelistClicked ), page ); page->remove_button = w; - onACLSelectionChanged( sel, page ); + onWhitelistSelectionChanged( sel, page ); gtk_box_pack_start_defaults( GTK_BOX( h ), w ); w = gtk_button_new_from_stock( GTK_STOCK_ADD ); page->widgets = g_slist_append( page->widgets, w ); - g_signal_connect( w, "clicked", G_CALLBACK( onAddACLClicked ), page ); + g_signal_connect( w, "clicked", G_CALLBACK( onAddWhitelistClicked ), page ); gtk_box_pack_start_defaults( GTK_BOX( h ), w ); w = gtk_hbox_new( FALSE, 0 ); gtk_box_pack_start_defaults( GTK_BOX( w ), diff --git a/gtk/tr-prefs.h b/gtk/tr-prefs.h index f5aa81ade..515da3e27 100644 --- a/gtk/tr-prefs.h +++ b/gtk/tr-prefs.h @@ -65,7 +65,7 @@ GtkWidget * tr_prefs_dialog_new( GObject * core, #define PREF_KEY_MAIN_WINDOW_Y "main-window-y" #define PREF_KEY_RPC_PORT "rpc-port" #define PREF_KEY_RPC_ENABLED "rpc-enabled" -#define PREF_KEY_RPC_ACL "rpc-access-control-list" +#define PREF_KEY_RPC_WHITELIST "rpc-whitelist" #define PREF_KEY_RPC_AUTH_ENABLED "rpc-authentication-required" #define PREF_KEY_RPC_PASSWORD "rpc-password" #define PREF_KEY_RPC_USERNAME "rpc-username" diff --git a/libtransmission/rpc-server.c b/libtransmission/rpc-server.c index 7edd357f2..6bbf38520 100644 --- a/libtransmission/rpc-server.c +++ b/libtransmission/rpc-server.c @@ -20,7 +20,7 @@ #include /* close */ #ifdef HAVE_LIBZ -#include + #include #endif #include @@ -42,17 +42,17 @@ struct tr_rpc_server { - unsigned int isEnabled : 1; - unsigned int isPasswordEnabled : 1; - uint16_t port; - struct evhttp * httpd; - tr_handle * session; - char * username; - char * password; - char * acl; + unsigned int isEnabled : 1; + unsigned int isPasswordEnabled : 1; + uint16_t port; + struct evhttp * httpd; + tr_handle * session; + char * username; + char * password; + char * whitelist; }; -#define dbgmsg( fmt... ) tr_deepLog( __FILE__, __LINE__, MY_NAME, ## fmt ) +#define dbgmsg( fmt ... ) tr_deepLog( __FILE__, __LINE__, MY_NAME, ## fmt ) /** *** @@ -187,16 +187,16 @@ mimetype_guess( const char * path ) const struct { - const char * suffix; - const char * mime_type; + const char * suffix; + const char * mime_type; } types[] = { /* these are just the ones we need for serving clutch... */ - { "css", "text/css" }, - { "gif", "image/gif" }, - { "html", "text/html" }, - { "ico", "image/vnd.microsoft.icon" }, - { "js", "application/javascript" }, - { "png", "image/png" } + { "css", "text/css" }, + { "gif", "image/gif" }, + { "html", "text/html" }, + { "ico", "image/vnd.microsoft.icon" }, + { "js", "application/javascript" }, + { "png", "image/png" } }; const char * dot = strrchr( path, '.' ); @@ -211,42 +211,52 @@ mimetype_guess( const char * path ) static void compress_evbuf( struct evbuffer * evbuf ) { - static struct evbuffer *tmp; - static z_stream stream; - static unsigned char buffer[2048]; - - if( !tmp ) { + static struct evbuffer * tmp; + static z_stream stream; + static unsigned char buffer[2048]; + + if( !tmp ) + { tmp = evbuffer_new( ); deflateInit( &stream, Z_BEST_COMPRESSION ); } deflateReset( &stream ); - stream.next_in = EVBUFFER_DATA(evbuf); - stream.avail_in = EVBUFFER_LENGTH(evbuf); + stream.next_in = EVBUFFER_DATA( evbuf ); + stream.avail_in = EVBUFFER_LENGTH( evbuf ); - do { + do + { stream.next_out = buffer; stream.avail_out = sizeof( buffer ); if( deflate( &stream, Z_FULL_FLUSH ) == Z_OK ) evbuffer_add( tmp, buffer, sizeof( buffer ) - stream.avail_out ); else break; - } while (stream.avail_out == 0); + } + while( stream.avail_out == 0 ); -/*fprintf( stderr, "deflated response from %zu to %zu bytes\n", EVBUFFER_LENGTH( evbuf ), EVBUFFER_LENGTH( tmp ) );*/ - evbuffer_drain(evbuf, EVBUFFER_LENGTH(evbuf)); - evbuffer_add_buffer(evbuf, tmp); +/*fprintf( stderr, "deflated response from %zu to %zu bytes\n", EVBUFFER_LENGTH( + evbuf ), EVBUFFER_LENGTH( tmp ) );*/ + evbuffer_drain( evbuf, EVBUFFER_LENGTH( evbuf ) ); + evbuffer_add_buffer( evbuf, tmp ); } + #endif static void -maybe_deflate_response( struct evhttp_request * req, struct evbuffer * response ) +maybe_deflate_response( struct evhttp_request * req, + struct evbuffer * response ) { #ifdef HAVE_LIBZ - const char * accept_encoding = evhttp_find_header( req->input_headers, "Accept-Encoding" ); - const int do_deflate = accept_encoding && strstr( accept_encoding, "deflate" ); - if( do_deflate ) { - evhttp_add_header( req->output_headers, "Content-Encoding", "deflate" ); + const char * accept_encoding = evhttp_find_header( req->input_headers, + "Accept-Encoding" ); + const int do_deflate = accept_encoding && strstr( accept_encoding, + "deflate" ); + if( do_deflate ) + { + evhttp_add_header( req->output_headers, "Content-Encoding", + "deflate" ); compress_evbuf( response ); } #endif @@ -315,7 +325,6 @@ handle_clutch( struct evhttp_request * req, evbuffer_free( buf ); } - static void handle_rpc( struct evhttp_request * req, struct tr_rpc_server * server ) @@ -356,20 +365,20 @@ static int isAddressAllowed( const tr_rpc_server * server, const char * address ) { - const char * acl; + const char * str; - for( acl = server->acl; acl && *acl; ) + for( str = server->whitelist; str && *str; ) { - const char * delimiter = strchr( acl, ',' ); - const int len = delimiter ? delimiter - acl : (int)strlen( acl ); - char * token = tr_strndup( acl, len ); - const int match = tr_wildmat( address, token + 1 ); + const char * delimiter = strchr( str, ',' ); + const int len = delimiter ? delimiter - str : (int)strlen( str ); + char * token = tr_strndup( str, len ); + const int match = tr_wildmat( address, token ); tr_free( token ); if( match ) - return *acl == '+'; + return 1; if( !delimiter ) break; - acl = delimiter + 1; + str = delimiter + 1; } return 0; @@ -402,7 +411,7 @@ handle_request( struct evhttp_request * req, } } - if( server->acl && !isAddressAllowed( server, req->remote_host ) ) + if( server->whitelist && !isAddressAllowed( server, req->remote_host ) ) { send_simple_response( req, 401, "Unauthorized IP Address" ); } @@ -480,7 +489,6 @@ onEnabledChanged( void * vserver ) else startServer( server ); } - void tr_rpcSetEnabled( tr_rpc_server * server, @@ -529,17 +537,17 @@ tr_rpcGetPort( const tr_rpc_server * server ) } void -tr_rpcSetACL( tr_rpc_server * server, - const char * acl ) +tr_rpcSetWhitelist( tr_rpc_server * server, + const char * whitelist ) { - tr_free( server->acl ); - server->acl = tr_strdup( acl ); + tr_free( server->whitelist ); + server->whitelist = tr_strdup( whitelist ); } char* -tr_rpcGetACL( const tr_rpc_server * server ) +tr_rpcGetWhitelist( const tr_rpc_server * server ) { - return tr_strdup( server->acl ? server->acl : "" ); + return tr_strdup( server->whitelist ? server->whitelist : "" ); } /**** @@ -598,8 +606,9 @@ static void closeServer( void * vserver ) { tr_rpc_server * s = vserver; + stopServer( s ); - tr_free( s->acl ); + tr_free( s->whitelist ); tr_free( s->username ); tr_free( s->password ); tr_free( s ); @@ -608,7 +617,7 @@ closeServer( void * vserver ) void tr_rpcClose( tr_rpc_server ** ps ) { - tr_runInEventThread( (*ps)->session, closeServer, *ps ); + tr_runInEventThread( ( *ps )->session, closeServer, *ps ); *ps = NULL; } @@ -616,7 +625,7 @@ tr_rpc_server * tr_rpcInit( tr_handle * session, int isEnabled, uint16_t port, - const char * acl, + const char * whitelist, int isPasswordEnabled, const char * username, const char * password ) @@ -626,7 +635,7 @@ tr_rpcInit( tr_handle * session, s = tr_new0( tr_rpc_server, 1 ); s->session = session; s->port = port; - s->acl = tr_strdup( acl && *acl ? acl : TR_DEFAULT_RPC_ACL ); + s->whitelist = tr_strdup( whitelist && *whitelist ? whitelist : TR_DEFAULT_RPC_WHITELIST ); s->username = tr_strdup( username ); s->password = tr_strdup( password ); s->isPasswordEnabled = isPasswordEnabled != 0; diff --git a/libtransmission/rpc-server.h b/libtransmission/rpc-server.h index 6062ec5a1..407a5696c 100644 --- a/libtransmission/rpc-server.h +++ b/libtransmission/rpc-server.h @@ -18,7 +18,7 @@ typedef struct tr_rpc_server tr_rpc_server; tr_rpc_server * tr_rpcInit( struct tr_handle * session, int isEnabled, uint16_t port, - const char * acl, + const char * whitelist, int isPasswordEnabled, const char * username, const char * password ); @@ -36,13 +36,13 @@ void tr_rpcSetPort( tr_rpc_server * server, uint16_t tr_rpcGetPort( const tr_rpc_server * server ); int tr_rpcSetTest( const tr_rpc_server * server, - const char * acl, + const char * whitelist, char ** allocme_errmsg ); -void tr_rpcSetACL( tr_rpc_server * server, - const char * acl ); +void tr_rpcSetWhitelist( tr_rpc_server * server, + const char * whitelist ); -char* tr_rpcGetACL( const tr_rpc_server * server ); +char* tr_rpcGetWhitelist( const tr_rpc_server * server ); void tr_rpcSetPassword( tr_rpc_server * server, const char * password ); @@ -59,8 +59,5 @@ void tr_rpcSetPasswordEnabled( tr_rpc_server * server, int tr_rpcIsPasswordEnabled( const tr_rpc_server * session ); -/** (public for the unit tests) */ -char* cidrize( const char * acl ); - #endif diff --git a/libtransmission/session.c b/libtransmission/session.c index b74cc0364..ced5092ec 100644 --- a/libtransmission/session.c +++ b/libtransmission/session.c @@ -216,7 +216,7 @@ tr_sessionInitFull( const char * configDir, int peerSocketTOS, int rpcIsEnabled, uint16_t rpcPort, - const char * rpcACL, + const char * rpcWhitelist, int rpcAuthIsEnabled, const char * rpcUsername, const char * rpcPassword, @@ -294,7 +294,7 @@ tr_sessionInitFull( const char * configDir, tr_statsInit( h ); h->web = tr_webInit( h ); - h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort, rpcACL, + h->rpcServer = tr_rpcInit( h, rpcIsEnabled, rpcPort, rpcWhitelist, rpcAuthIsEnabled, rpcUsername, rpcPassword ); metainfoLookupRescan( h ); @@ -326,7 +326,7 @@ tr_sessionInit( const char * configDir, TR_DEFAULT_PEER_SOCKET_TOS, TR_DEFAULT_RPC_ENABLED, TR_DEFAULT_RPC_PORT, - TR_DEFAULT_RPC_ACL, + TR_DEFAULT_RPC_WHITELIST, FALSE, "fnord", "potzrebie", @@ -1003,16 +1003,16 @@ tr_sessionSetRPCCallback( tr_session * session, } void -tr_sessionSetRPCACL( tr_session * session, - const char * acl ) +tr_sessionSetRPCWhitelist( tr_session * session, + const char * whitelist ) { - return tr_rpcSetACL( session->rpcServer, acl ); + return tr_rpcSetWhitelist( session->rpcServer, whitelist ); } char* -tr_sessionGetRPCACL( const tr_session * session ) +tr_sessionGetRPCWhitelist( const tr_session * session ) { - return tr_rpcGetACL( session->rpcServer ); + return tr_rpcGetWhitelist( session->rpcServer ); } void diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h index 242415c16..4a86801a3 100644 --- a/libtransmission/transmission.h +++ b/libtransmission/transmission.h @@ -129,7 +129,7 @@ tr_proxy_type; /** @see tr_sessionInitFull */ #define TR_DEFAULT_RPC_PORT_STR "9091" /** @see tr_sessionInitFull */ -#define TR_DEFAULT_RPC_ACL "+127.0.0.1" +#define TR_DEFAULT_RPC_WHITELIST "127.0.0.1" /** @see tr_sessionInitFull */ #define TR_DEFAULT_PROXY_ENABLED 0 /** @see tr_sessionInitFull */ @@ -236,16 +236,15 @@ tr_encryption_mode; * @param rpcPort * The port on which to listen for incoming RPC requests * - * @param rpcACL - * The access control list for allowing/denying RPC requests - * from specific IP ranges. - * @see tr_sessionSetRPCACL() + * @param rpcWhitelist + * The list of IP addresses allowed to make RPC connections. + * @see tr_sessionSetRPCWhitelist() * * @see TR_DEFAULT_PEER_SOCKET_TOS * @see TR_DEFAULT_BLOCKLIST_ENABLED * @see TR_DEFAULT_RPC_ENABLED * @see TR_DEFAULT_RPC_PORT - * @see TR_DEFAULT_RPC_ACL + * @see TR_DEFAULT_RPC_WHITELIST * @see tr_sessionClose() */ tr_handle * tr_sessionInitFull( const char * configDir, @@ -267,7 +266,7 @@ tr_handle * tr_sessionInitFull( const char * configDir, int peerSocketTOS, int rpcIsEnabled, uint16_t rpcPort, - const char * rpcAccessControlList, + const char * rpcWhitelist, int rpcPasswordIsEnabled, const char * rpcUsername, const char * rpcPassword, @@ -346,21 +345,21 @@ void tr_sessionSetRPCPort( tr_handle * session, uint16_t tr_sessionGetRPCPort( const tr_handle * ); /** - * @brief Specify access control list (ACL). + * @brief Specify a whitelist for remote RPC access * - * ACL is a comma-delimited list of dotted-quad IP addresses, each preceded - * by a '+' or '-' sign to denote 'allow' or 'deny'. Wildmat notation is - * supported, meaning that '?' is interpreted as a single-character wildcard - * and '*' is interprted as a multi-character wildcard. + * The whitelist is a comma-separated list of dotted-quad IP addresses + * to be allowed. Wildmat notation is supported, meaning that + * '?' is interpreted as a single-character wildcard and + * '*' is interprted as a multi-character wildcard. */ -void tr_sessionSetRPCACL( tr_session * session, - const char * acl ); +void tr_sessionSetRPCWhitelist( tr_session * session, + const char * whitelist ); /** @brief get the Access Control List for allowing/denying RPC requests. - @return a comma-separated string of ACL rules. tr_free() when done. + @return a comma-separated string of whitelist domains. tr_free() when done. @see tr_sessionInitFull - @see tr_sessionSetRPCACL */ -char* tr_sessionGetRPCACL( const tr_session * ); + @see tr_sessionSetRPCWhitelist */ +char* tr_sessionGetRPCWhitelist( const tr_session * ); void tr_sessionSetRPCPassword( tr_session * session, const char * password ); diff --git a/libtransmission/trevent.c b/libtransmission/trevent.c index f652c2ae9..854aea06c 100644 --- a/libtransmission/trevent.c +++ b/libtransmission/trevent.c @@ -161,7 +161,7 @@ libeventThreadFunc( void * veh ) readFromPipe, veh ); event_add( &eh->pipeEvent, NULL ); - + event_set_log_callback( logFunc ); event_dispatch( ); tr_lockFree( eh->lock );