Changeset 6031


Ignore:
Timestamp:
Jun 4, 2008, 5:14:58 PM (13 years ago)
Author:
charles
Message:

RPC ACL: (1) add a new call for testing ACLs (2) add wildcard notation support (3) add regression tests for the ACL tester and wildcard handler

Location:
trunk/libtransmission
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/Makefile.am

    r5869 r6031  
    9292    clients-test \
    9393    json-test \
     94    rpc-test \
    9495    test-fastset \
    9596    test-peer-id \
     
    118119json_test_SOURCES = json-test.c
    119120json_test_LDADD = $(APPS_LDADD)
     121rpc_test_SOURCES = rpc-test.c
     122rpc_test_LDADD = $(APPS_LDADD)
    120123test_fastset_SOURCES = test-fastset.c
    121124test_fastset_LDADD = $(APPS_LDADD)
  • trunk/libtransmission/rpc-server.c

    r6026 r6031  
    1212
    1313#include <assert.h>
     14#include <ctype.h> /* isdigit */
     15#include <errno.h>
     16#include <stdlib.h> /* strtol */
    1417#include <string.h>
    1518
     
    219222}
    220223
     224/* 192.*.*.* --> 192.0.0.0/8
     225   192.64.*.* --> 192.64.0.0/16
     226   192.64.1.* --> 192.64.1.0/24
     227   192.64.1.2 --> 192.64.1.2/32 */
     228static void
     229cidrizeOne( const char * in, int len, struct evbuffer * out )
     230{
     231    int stars = 0;
     232    const char * pch;
     233    const char * end;
     234    char zero = '0';
     235    char huh = '?';
     236
     237    for( pch=in, end=pch+len; pch!=end; ++pch ) {
     238        if( stars && isdigit(*pch) )
     239            evbuffer_add( out, &huh, 1 );
     240        else if( *pch!='*' )
     241            evbuffer_add( out, pch, 1 );
     242        else {
     243            evbuffer_add( out, &zero, 1 );
     244            ++stars;
     245        }
     246    }
     247
     248    evbuffer_add_printf( out, "/%d", (32-(stars*8)));
     249}
     250
     251char*
     252cidrize( const char * acl )
     253{
     254    int len;
     255    const char * walk = acl;
     256    char * ret;
     257    struct evbuffer * out = evbuffer_new( );
     258
     259    FOR_EACH_WORD_IN_LIST( walk, len )
     260    {
     261        cidrizeOne( walk, len, out );
     262        evbuffer_add_printf( out, ", " );
     263    }
     264
     265    /* the -2 is to eat the final ", " */
     266    ret = tr_strndup( (char*) EVBUFFER_DATA(out), EVBUFFER_LENGTH(out)-2 );
     267    evbuffer_free( out );
     268    return ret;
     269}
     270
    221271int
    222 tr_rpcSetACL( tr_rpc_server * server, const char * acl, char ** setme_errmsg )
    223 {
    224     const int isRunning = server->ctx != NULL;
     272tr_rpcTestACL( const tr_rpc_server  * server UNUSED,
     273               const char           * acl,
     274               char                ** setme_errmsg )
     275{
    225276    int ret = 0;
    226     char * errmsg = testACL( acl );
    227 
     277    char * cidr = cidrize( acl );
     278    char * errmsg = testACL( cidr );
    228279    if( errmsg )
    229280    {
     
    234285        ret = -1;
    235286    }
    236     else
    237     {
     287    tr_free( cidr );
     288    return ret;
     289}
     290
     291int
     292tr_rpcSetACL( tr_rpc_server   * server,
     293              const char      * acl,
     294              char           ** setme_errmsg )
     295{
     296    char * cidr = cidrize( acl );
     297    const int ret = tr_rpcTestACL( server, cidr, setme_errmsg );
     298
     299    if( ret )
     300    {
     301        const int isRunning = server->ctx != NULL;
     302
    238303        if( isRunning )
    239304            stopServer( server );
    240305
    241306        tr_free( server->acl );
    242         server->acl = tr_strdup( acl );
     307        server->acl = tr_strdup( cidr );
    243308
    244309        if( isRunning )
  • trunk/libtransmission/rpc-server.h

    r6004 r6031  
    3333int         tr_rpcGetPort   ( const tr_rpc_server    * server );
    3434
     35int         tr_rpcSetTest   ( const tr_rpc_server    * server,
     36                              const char             * acl,
     37                              char                  ** allocme_errmsg );
     38
    3539int         tr_rpcSetACL    ( tr_rpc_server          * server,
    3640                              const char             * acl,
  • trunk/libtransmission/session.c

    r6004 r6031  
    777777
    778778int
     779tr_sessionTestRPCACL( const tr_handle  * session,
     780                      const char       * acl,
     781                      char            ** allocme_errmsg )
     782{
     783    return tr_rpcTestACL( session->rpcServer, acl, allocme_errmsg );
     784}
     785
     786int
    779787tr_sessionSetRPCACL( tr_handle    * session,
    780788                     const char   * acl,
  • trunk/libtransmission/transmission.h

    r6018 r6031  
    293293
    294294/**
    295  * Specify access control list (ACL). ACL is a comma separated list
    296  * of IP subnets, each subnet is prepended by a '-' or '+' sign.
    297  * Plus means allow, minus means deny. If the subnet mask is omitted,
    298  * like * "-1.2.3.4", it means a single IP address. The mask may vary
    299  * from 0 to 32 inclusive.
    300  *
    301  * The default string is "+127.0.0.1"
    302  *
    303  * @param acl the new ACL to use.
     295 * @brief test an ACL's syntax without modifying the RPC settings.
     296 *
     297 * ACL is a comma separated list of IP subnets, each subnet is prepended
     298 * by a '+' or '-' sign to denote 'allow' or 'deny'.  If the subnet mask
     299 * is omitted, like "-1.2.3.4", it means a single IP address. The mask
     300 * may vary from 0 to 32 inclusive.  A simple primer on x.x.x.x/n notation
     301 * can be found at <http://25yearsofprogramming.com/blog/20070803.htm>.
     302 *
     303 * Since wildcards are more familiar to most users than netmasks,
     304 * libtransmission supports a wildcard notation that it
     305 * converts into cidr required by the embedded http server.
     306 * So, notation like "+192.168.*.*" is accepted by libtransmission and is
     307 * converted to "+192.168.0.0/16" before it reaches the server.
     308
     309 * @param acl the ACL to test
    304310 * @param allocme_errmsg If the ACL can't be parsed, this is set to a
    305311 *                       newly-allocated error string describing the problem.
    306312 *                       The client should tr_free() this string when done.
    307  *
    308313 * @return 0 on success, -1 on failure due to an unparseable ACL.
    309  *
     314 */
     315int tr_sessionTestRPCACL( const tr_handle  * session,
     316                          const char       * acl,
     317                          char            ** allocme_errmsg );
     318
     319/**
     320 * @brief Specify access control list (ACL).
     321 ACL is a comma separated list
     322 * of IP subnets, each subnet is prepended by a '-' or '+' sign.
     323 * Plus means allow, minus means deny. If the subnet mask is omitted,
     324 * like "-1.2.3.4", it means a single IP address. The mask may vary
     325 * from 0 to 32 inclusive.
     326 *
     327 * http://25yearsofprogramming.com/blog/20070803.htm has a simple
     328 * primer on x.x.x.x/n notation for those interested.
     329 *
     330 * The parameters and return value follow the same behavior as
     331 * tr_sessionTestRPCACL().
     332 *
     333 * @see tr_sessionTestRPCACL
    310334 * @see tr_sessionInitFull
    311335 * @see tr_sessionGetRPCACL
Note: See TracChangeset for help on using the changeset viewer.