1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-27 01:57:52 +00:00

(libT): added an ACL tester to tr_sessionSetRPCACL() and return an error string if the ACL can't be parsed.

This commit is contained in:
Charles Kerr 2008-06-02 19:44:19 +00:00
parent a4520742e5
commit f8d40cdf00
5 changed files with 79 additions and 19 deletions

View file

@ -175,19 +175,72 @@ tr_rpcGetPort( const tr_rpc_server * server )
return server->port; return server->port;
} }
void /*
tr_rpcSetACL( tr_rpc_server * server, const char * acl ) * DELIM_CHARS, FOR_EACH_WORD_IN_LIST, isbyte, and testACL are from, or modified from,
* shttpd, written by Sergey Lyubka under this license:
* "THE BEER-WARE LICENSE" (Revision 42):
* Sergey Lyubka wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return.
*/
#define DELIM_CHARS " ," /* Separators for lists */
#define FOR_EACH_WORD_IN_LIST(s,len) \
for (; s != NULL && (len = strcspn(s, DELIM_CHARS)) != 0; \
s += len, s+= strspn(s, DELIM_CHARS))
static int isbyte(int n) { return (n >= 0 && n <= 255); }
static char*
testACL( const char * s )
{
int len;
FOR_EACH_WORD_IN_LIST(s, len)
{
char flag;
int a, b, c, d, n, mask;
if( sscanf(s, "%c%d.%d.%d.%d%n",&flag,&a,&b,&c,&d,&n) != 5 )
return tr_strdup_printf( _( "[%s]: subnet must be [+|-]x.x.x.x[/x]" ), s );
if( flag != '+' && flag != '-')
return tr_strdup_printf( _( "[%s]: flag must be + or -" ), s );
if( !isbyte(a) || !isbyte(b) || !isbyte(c) || !isbyte(d) )
return tr_strdup_printf( _( "[%s]: bad ip address" ), s );
if( sscanf(s + n, "/%d", &mask) == 1 && ( mask<0 || mask>32 ) )
return tr_strdup_printf( _( "[%s]: bad subnet mask %d" ), s, n );
}
return NULL;
}
int
tr_rpcSetACL( tr_rpc_server * server, const char * acl, char ** setme_errmsg )
{ {
const int isRunning = server->ctx != NULL; const int isRunning = server->ctx != NULL;
int ret = 0;
char * errmsg = testACL( acl );
if( isRunning ) if( errmsg )
stopServer( server ); {
*setme_errmsg = errmsg;
ret = -1;
}
else
{
if( isRunning )
stopServer( server );
tr_free( server->acl ); tr_free( server->acl );
server->acl = tr_strdup( acl ); server->acl = tr_strdup( acl );
if( isRunning ) if( isRunning )
startServer( server ); startServer( server );
}
return ret;
} }
const char* const char*

View file

@ -32,8 +32,9 @@ void tr_rpcSetPort ( tr_rpc_server * server,
int tr_rpcGetPort ( const tr_rpc_server * server ); int tr_rpcGetPort ( const tr_rpc_server * server );
void tr_rpcSetACL ( tr_rpc_server * server, int tr_rpcSetACL ( tr_rpc_server * server,
const char * acl ); const char * acl,
char ** allocme_errmsg );
const char* tr_rpcGetACL ( const tr_rpc_server * server ); const char* tr_rpcGetACL ( const tr_rpc_server * server );

View file

@ -775,10 +775,12 @@ tr_sessionSetRPCCallback( tr_handle * session,
session->rpc_func_user_data = user_data; session->rpc_func_user_data = user_data;
} }
void int
tr_sessionSetRPCACL( tr_handle * session, const char * acl ) tr_sessionSetRPCACL( tr_handle * session,
const char * acl,
char ** allocme_errmsg )
{ {
tr_rpcSetACL( session->rpcServer, acl ); return tr_rpcSetACL( session->rpcServer, acl, allocme_errmsg );
} }
const char* const char*

View file

@ -300,15 +300,19 @@ int tr_sessionGetRPCPort( const tr_handle * );
* *
* The default string is "+127.0.0.1" * The default string is "+127.0.0.1"
* *
* IMPORTANT: a malformed ACL is likely to cause Transmission to crash. * @param acl the new ACL to use.
* Client applications need to validate user input, or better yet * @param allocme_errmsg If the ACL can't be parsed, this is set to a
* generate it from a higher-level interface that doesn't allow user error, * newly-allocated error string describing the problem.
* before calling this function. * The client should tr_free() this string when done.
*
* @return 0 on success, -1 on failure due to an unparseable ACL.
* *
* @see tr_sessionInitFull * @see tr_sessionInitFull
* @see tr_sessionGetRPCACL * @see tr_sessionGetRPCACL
*/ */
void tr_sessionSetRPCACL( tr_handle *, const char * acl ); int tr_sessionSetRPCACL( tr_handle * session,
const char * acl,
char ** allocme_errmsg );
/** Returns the Access Control List for allowing/denying RPC requests. /** Returns the Access Control List for allowing/denying RPC requests.
@see tr_sessionInitFull @see tr_sessionInitFull

View file

@ -3,7 +3,7 @@
#include "transmission.h" #include "transmission.h"
#include "utils.h" #include "utils.h"
#define VERBOSE 1 #define VERBOSE 0
#define NUM_LOOPS 1 #define NUM_LOOPS 1
#define SPEED_TEST 0 #define SPEED_TEST 0