mirror of
https://github.com/transmission/transmission
synced 2024-12-26 09:37:56 +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:
parent
a4520742e5
commit
f8d40cdf00
5 changed files with 79 additions and 19 deletions
|
@ -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*
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "transmission.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define VERBOSE 1
|
||||
#define VERBOSE 0
|
||||
#define NUM_LOOPS 1
|
||||
#define SPEED_TEST 0
|
||||
|
||||
|
|
Loading…
Reference in a new issue