~ubuntu-branches/ubuntu/jaunty/transmission/jaunty-security

« back to all changes in this revision

Viewing changes to libtransmission/rpc-server.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Coulson
  • Date: 2008-12-28 18:50:08 UTC
  • mfrom: (1.1.20 upstream)
  • Revision ID: james.westby@ubuntu.com-20081228185008-2u8ac12dbckrwn7c
Tags: 1.42-0ubuntu1
* New upstream version (LP: #311959):
  - All platforms:
    - Better peer management in large swarms
    - Support BitTorrent Enhancement Proposal (BEP) #21 "Extension for 
      Partial Seeds"
    - Partial support for BEP #6 "Fast Extension" (reject, have all/none)
    - Honor the peer's BEP #10 reqq key, when available
    - Fix 1.40 "Got HTTP Status Code: 0" error message
    - Fix 1.40 "lazy bitfield" error
    - Fix 1.40 "jumpy upload speed" bug
    - Fix handshake peer_id error
    - Corrrectly handle Windows-style newlines in Bluetack blocklists
    - More accurate bandwidth measurement
    - File selection & priority was reset when editing a torrent's 
      tracker list
    - Fix autoconf/automake build warnings
  - GTK+:
    - In the Details dialog's peer tabs, rows were sometimes duplicated
    - Minor bugfixes, usability changes, and locale improvements
    - Three new translations: Afrikaans, Asturian, Bosnian
    - Sixteen updated translations
  - Daemon:
    - Fix 1.40 bug in handling IP whitelist
    - Minor bugfixes and output cleanup
    - Windows portability
  - CLI:
    - Fix minor free-memory-read bug

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
 * This exemption does not extend to derived works not owned by
8
8
 * the Transmission project.
9
9
 *
10
 
 * $Id: rpc-server.c 7087 2008-11-09 15:43:31Z charles $
 
10
 * $Id: rpc-server.c 7480 2008-12-23 21:34:08Z charles $
11
11
 */
12
12
 
13
13
#include <assert.h>
55
55
    tr_handle *        session;
56
56
    char *             username;
57
57
    char *             password;
58
 
    char *             whitelist;
 
58
    char *             whitelistStr;
 
59
    tr_list *          whitelist;
59
60
};
60
61
 
61
62
#define dbgmsg( ... ) \
271
272
                evbuffer_drain( out, 2 );
272
273
            }
273
274
 
 
275
#if 0
274
276
            tr_ninf( MY_NAME, _( "Deflated response from %zu bytes to %zu" ),
275
277
                              content_len,
276
278
                              EVBUFFER_LENGTH( out ) );
 
279
#endif
277
280
            evhttp_add_header( req->output_headers,
278
281
                               "Content-Encoding", "deflate" );
279
282
        }
406
409
    tr_free( out );
407
410
}
408
411
 
409
 
static int
 
412
static tr_bool
410
413
isAddressAllowed( const tr_rpc_server * server,
411
414
                  const char *          address )
412
415
{
413
 
    const char * str;
 
416
    tr_list * l;
414
417
 
415
418
    if( !server->isWhitelistEnabled )
416
 
        return 1;
417
 
 
418
 
    for( str = server->whitelist; str && *str; )
419
 
    {
420
 
        const char * delimiter = strchr( str, ',' );
421
 
        const int    len = delimiter ? delimiter - str : (int)strlen( str );
422
 
        char *       token = tr_strndup( str, len );
423
 
        const int    match = tr_wildmat( address, token );
424
 
        tr_free( token );
425
 
        if( match )
426
 
            return 1;
427
 
        if( !delimiter )
428
 
            break;
429
 
        str = delimiter + 1;
430
 
    }
431
 
 
432
 
    return 0;
 
419
        return TRUE;
 
420
 
 
421
    for( l=server->whitelist; l!=NULL; l=l->next )
 
422
        if( tr_wildmat( address, l->data ) )
 
423
            return TRUE;
 
424
 
 
425
    return FALSE;
433
426
}
434
427
 
435
428
static void
461
454
 
462
455
        if( !isAddressAllowed( server, req->remote_host ) )
463
456
        {
464
 
            send_simple_response( req, 401, "Unauthorized IP Address" );
 
457
            send_simple_response( req, 401,
 
458
                "<p>Unauthorized IP Address.</p>"
 
459
                "<p>Either disable the IP address whitelist or add your address to it.</p>"
 
460
                "<p>If you're editing settings.json, see the 'rpc-whitelist' and 'rpc-whitelist-enabled' entries.</p>"
 
461
                "<p>If you're still using ACLs, use a whitelist instead.  See the transmission-daemon manpage for details.</p>" );
465
462
        }
466
463
        else if( server->isPasswordEnabled
467
464
                 && ( !pass || !user || strcmp( server->username, user )
583
580
 
584
581
void
585
582
tr_rpcSetWhitelist( tr_rpc_server * server,
586
 
                    const char *    whitelist )
 
583
                    const char    * whitelistStr )
587
584
{
588
 
    tr_free( server->whitelist );
589
 
    server->whitelist = tr_strdup( whitelist );
 
585
    void * tmp;
 
586
    const char * walk;
 
587
 
 
588
    /* keep the string */
 
589
    tr_free( server->whitelistStr );
 
590
    server->whitelistStr = tr_strdup( whitelistStr );
 
591
 
 
592
    /* clear out the old whitelist entries */
 
593
    while(( tmp = tr_list_pop_front( &server->whitelist )))
 
594
        tr_free( tmp );
 
595
 
 
596
    /* build the new whitelist entries */
 
597
    for( walk=whitelistStr; walk && *walk; ) {
 
598
        const char * delimiters = " ,;";
 
599
        const size_t len = strcspn( walk, delimiters );
 
600
        char * token = tr_strndup( walk, len );
 
601
        tr_list_append( &server->whitelist, token );
 
602
        if( strcspn( token, "+-" ) < len )
 
603
            tr_ninf( MY_NAME, "Adding address to whitelist: %s (And it has a '+' or '-'!  Are you using an old ACL by mistake?)", token );
 
604
        else
 
605
            tr_ninf( MY_NAME, "Adding address to whitelist: %s", token );
 
606
        
 
607
        if( walk[len]=='\0' )
 
608
            break;
 
609
        walk += len + 1;
 
610
    }
590
611
}
591
612
 
592
613
char*
593
614
tr_rpcGetWhitelist( const tr_rpc_server * server )
594
615
{
595
 
    return tr_strdup( server->whitelist ? server->whitelist : "" );
 
616
    return tr_strdup( server->whitelistStr ? server->whitelistStr : "" );
596
617
}
597
618
 
598
619
void
663
684
static void
664
685
closeServer( void * vserver )
665
686
{
 
687
    void * tmp;
666
688
    tr_rpc_server * s = vserver;
667
689
 
668
690
    stopServer( s );
669
 
    tr_free( s->whitelist );
 
691
    while(( tmp = tr_list_pop_front( &s->whitelist )))
 
692
        tr_free( tmp );
 
693
    tr_free( s->whitelistStr );
670
694
    tr_free( s->username );
671
695
    tr_free( s->password );
672
696
    tr_free( s );
694
718
    s = tr_new0( tr_rpc_server, 1 );
695
719
    s->session = session;
696
720
    s->port = port;
697
 
    s->whitelist = tr_strdup( whitelist && *whitelist
698
 
                              ? whitelist
699
 
                              : TR_DEFAULT_RPC_WHITELIST );
700
721
    s->username = tr_strdup( username );
701
722
    s->password = tr_strdup( password );
702
723
    s->isWhitelistEnabled = isWhitelistEnabled != 0;
703
724
    s->isPasswordEnabled = isPasswordEnabled != 0;
704
725
    s->isEnabled = isEnabled != 0;
 
726
    tr_rpcSetWhitelist( s, whitelist ? whitelist : TR_DEFAULT_RPC_WHITELIST );
705
727
    if( isEnabled )
706
728
        tr_runInEventThread( session, startServer, s );
 
729
 
 
730
    if( isEnabled )
 
731
    {
 
732
        tr_ninf( MY_NAME, _( "Serving RPC and Web requests on port %d" ), (int)port );
 
733
 
 
734
        if( isWhitelistEnabled )
 
735
            tr_ninf( MY_NAME, _( "Whitelist enabled" ) );
 
736
 
 
737
        if( isPasswordEnabled )
 
738
            tr_ninf( MY_NAME, _( "Password required" ) );
 
739
    }
 
740
 
707
741
    return s;
708
742
}