1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 01:27:28 +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;
}
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;
int ret = 0;
char * errmsg = testACL( acl );
if( isRunning )
stopServer( server );
if( errmsg )
{
*setme_errmsg = errmsg;
ret = -1;
}
else
{
if( isRunning )
stopServer( server );
tr_free( server->acl );
server->acl = tr_strdup( acl );
tr_free( server->acl );
server->acl = tr_strdup( acl );
if( isRunning )
startServer( server );
if( isRunning )
startServer( server );
}
return ret;
}
const char*

View file

@ -32,8 +32,9 @@ void tr_rpcSetPort ( tr_rpc_server * server,
int tr_rpcGetPort ( const tr_rpc_server * server );
void tr_rpcSetACL ( tr_rpc_server * server,
const char * acl );
int tr_rpcSetACL ( tr_rpc_server * server,
const char * acl,
char ** allocme_errmsg );
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;
}
void
tr_sessionSetRPCACL( tr_handle * session, const char * acl )
int
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*

View file

@ -300,15 +300,19 @@ int tr_sessionGetRPCPort( const tr_handle * );
*
* The default string is "+127.0.0.1"
*
* IMPORTANT: a malformed ACL is likely to cause Transmission to crash.
* Client applications need to validate user input, or better yet
* generate it from a higher-level interface that doesn't allow user error,
* before calling this function.
* @param acl the new ACL to use.
* @param allocme_errmsg If the ACL can't be parsed, this is set to a
* newly-allocated error string describing the problem.
* 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_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.
@see tr_sessionInitFull

View file

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