From 543ab73017b83e251924caca9aa37a0f892fe05f Mon Sep 17 00:00:00 2001 From: Dirk Engling Date: Fri, 29 Mar 2024 03:30:13 +0100 Subject: Allow networks to be used instead of ip addresses when blessing is involved --- opentracker.c | 50 ++++++++++++++++++++++++++++++++++++++------------ ot_accesslist.c | 35 ++++++++++++++++++++++------------- ot_accesslist.h | 4 ++-- ot_http.c | 6 +++--- ot_livesync.c | 2 +- 5 files changed, 66 insertions(+), 31 deletions(-) diff --git a/opentracker.c b/opentracker.c index 2ca9e06..ff2409c 100644 --- a/opentracker.c +++ b/opentracker.c @@ -104,7 +104,7 @@ static void install_signal_handlers( void ) { } static void usage( char *name ) { - fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip] [-f config] [-s livesyncport]" + fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip[/bits]] [-f config] [-s livesyncport]" #ifdef WANT_ACCESSLIST_BLACK " [-b blacklistfile]" #elif defined ( WANT_ACCESSLIST_WHITE ) @@ -124,7 +124,7 @@ static void help( char *name ) { HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)"); HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")"); HELPLINE("-u user","specify user under whose privileges opentracker should run (default: \"nobody\")"); - HELPLINE("-A ip","bless an ip address as admin address (e.g. to allow syncs from this address)"); + HELPLINE("-A ip[/bits]","bless an ip address or net as admin address (e.g. to allow syncs from this address)"); #ifdef WANT_ACCESSLIST_BLACK HELPLINE("-b file","specify blacklist file."); #elif defined( WANT_ACCESSLIST_WHITE ) @@ -395,7 +395,7 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) { s += off; if( bracket && *s == ']' ) ++s; if( *s == 0 || isspace(*s)) return s-src; - if( !ip6_isv4mapped(ip)){ + if( !ip6_isv4mapped(ip)) { if( *s != ':' && *s != '.' ) return 0; if( !bracket && *(s) == ':' ) return 0; s++; @@ -407,10 +407,35 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) { return off+s-src; } +static int scan_ip6_net( const char *src, ot_net *net) { + const char *s = src; + int off; + while( isspace(*s) ) ++s; + if( !(off = scan_ip6( s, net->address ) ) ) + return 0; + s += off; + if(*s!='/') + net->bits = 128; + else { + s++; + if( !(off = scan_int (s, &net->bits ) ) ) + return 0; + if( ip6_isv4mapped(net->address)) + net->bits += 96; + if(net->bits > 128) + return 0; + s += off; + } + return off+s-src; +} + int parse_configfile( char * config_filename ) { FILE * accesslist_filehandle; char inbuf[512]; ot_ip6 tmpip; +#if defined(WANT_RESTRICT_STATS) || defined(WANT_IP_FROM_PROXY) || defined(WANT_SYNC_LIVE) + ot_net tmpnet; +#endif int bound = 0; accesslist_filehandle = fopen( config_filename, "r" ); @@ -474,22 +499,22 @@ int parse_configfile( char * config_filename ) { #endif #ifdef WANT_RESTRICT_STATS } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) { - if( !scan_ip6( p+13, tmpip )) goto parse_error; - accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); + if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error; + accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_STAT ); #endif } else if(!byte_diff(p, 17, "access.stats_path" ) && isspace(p[17])) { set_config_option( &g_stats_path, p+18 ); #ifdef WANT_IP_FROM_PROXY } else if(!byte_diff(p, 12, "access.proxy" ) && isspace(p[12])) { - if( !scan_ip6( p+13, tmpip )) goto parse_error; - accesslist_blessip( tmpip, OT_PERMISSION_MAY_PROXY ); + if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error; + accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_PROXY ); #endif } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { set_config_option( &g_redirecturl, p+21 ); #ifdef WANT_SYNC_LIVE } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) { - if( !scan_ip6( p+25, tmpip )) goto parse_error; - accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC ); + if( !scan_ip6_net( p+25, &tmpnet )) goto parse_error; + accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_LIVESYNC ); } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) { uint16_t tmpport = LIVESYNC_PORT; if( !scan_ip6_port( p+24, tmpip, &tmpport )) goto parse_error; @@ -591,7 +616,8 @@ int drop_privileges ( const char * const serveruser, const char * const serverdi } int main( int argc, char **argv ) { - ot_ip6 serverip, tmpip; + ot_ip6 serverip; + ot_net tmpnet; int bound = 0, scanon = 1; uint16_t tmpport; char * statefile = 0; @@ -641,8 +667,8 @@ int main( int argc, char **argv ) { case 'r': set_config_option( &g_redirecturl, optarg ); break; case 'l': statefile = optarg; break; case 'A': - if( !scan_ip6( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } - accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ + if( !scan_ip6_net( optarg, &tmpnet )) { usage( argv[0] ); exit( 1 ); } + accesslist_bless_net( &tmpnet, 0xffff ); /* Allow everything for now */ break; case 'f': bound += parse_configfile( optarg ); break; case 'h': help( argv[0] ); exit( 0 ); diff --git a/ot_accesslist.c b/ot_accesslist.c index 7df503f..5bd81f0 100644 --- a/ot_accesslist.c +++ b/ot_accesslist.c @@ -21,6 +21,7 @@ #include "scan.h" #include "ip6.h" #include "mmap.h" +#include "fmt.h" /* Opentracker */ #include "trackerlogic.h" @@ -509,29 +510,37 @@ int proxylist_check_proxy( const ot_ip6 proxy, const ot_ip6 address ) { #endif -static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; -static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; -static unsigned int g_adminip_count = 0; +static ot_net g_admin_nets[OT_ADMINIP_MAX]; +static ot_permissions g_admin_nets_permissions[OT_ADMINIP_MAX]; +static unsigned int g_admin_nets_count = 0; -int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { - if( g_adminip_count >= OT_ADMINIP_MAX ) +int accesslist_bless_net( ot_net *net, ot_permissions permissions ) { + if( g_admin_nets_count >= OT_ADMINIP_MAX ) return -1; - memcpy(g_adminip_addresses + g_adminip_count,ip,sizeof(ot_ip6)); - g_adminip_permissions[ g_adminip_count++ ] = permissions; + memcpy(g_admin_nets + g_admin_nets_count, &net, sizeof(ot_net)); + g_admin_nets_permissions[ g_admin_nets_count++ ] = permissions; #ifdef _DEBUG { char _debug[512]; - int off = snprintf( _debug, sizeof(_debug), "Blessing ip address " ); - off += fmt_ip6c(_debug+off, ip ); + int off = snprintf( _debug, sizeof(_debug), "Blessing ip net " ); + off += fmt_ip6c(_debug+off, net->address ); + if( net->bits < 128) { + _debug[off++] = '/'; + if( ip6_isv4mapped(net->address) ) + off += fmt_long(_debug+off, net->bits-96); + else + off += fmt_long(_debug+off, net->bits); + } if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" ); if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" ); if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" ); if( permissions & OT_PERMISSION_MAY_PROXY ) off += snprintf( _debug+off, 512-off, " may_proxy" ); - if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing\n" ); + if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing" ); _debug[off++] = '.'; + _debug[off++] = '\n'; (void)write( 2, _debug, off ); } #endif @@ -539,10 +548,10 @@ int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { return 0; } -int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ) { +int accesslist_is_blessed( ot_ip6 ip, ot_permissions permissions ) { unsigned int i; - for( i=0; iip, OT_PERMISSION_MAY_STAT ) ) + if( !cookie || !accesslist_is_blessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) HTTPERROR_403_IP; #endif @@ -417,7 +417,7 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, } #ifdef WANT_IP_FROM_PROXY - if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_PROXY ) ) { + if( accesslist_is_blessed( cookie->ip, OT_PERMISSION_MAY_PROXY ) ) { ot_ip6 proxied_ip; char *fwd = http_header( ws->request, ws->header_size, "x-forwarded-for" ); if( fwd && scan_ip6( fwd, proxied_ip ) ) @@ -495,7 +495,7 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws, #ifdef WANT_FULLLOG_NETWORKS case 8: /* matched "lognet" */ { - //if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) { + //if( accesslist_is_blessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) { char *tmp_buf = ws->reply; ot_net net; signed short parsed, bits; diff --git a/ot_livesync.c b/ot_livesync.c index cded0f7..75a5f9f 100644 --- a/ot_livesync.c +++ b/ot_livesync.c @@ -192,7 +192,7 @@ static void * livesync_worker( void * args ) { /* Expect at least tracker id and packet type */ if( ws.request_size <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) ) continue; - if( !accesslist_isblessed(in_ip, OT_PERMISSION_MAY_LIVESYNC)) + if( !accesslist_is_blessed(in_ip, OT_PERMISSION_MAY_LIVESYNC)) continue; if( !memcmp( ws.inbuf, &g_tracker_id, sizeof( g_tracker_id ) ) ) { /* TODO: log packet coming from ourselves */ -- cgit v1.2.3