Allow networks to be used instead of ip addresses when blessing is involved

master
Dirk Engling 9 months ago
parent ede702c7ff
commit 543ab73017

@ -104,7 +104,7 @@ static void install_signal_handlers( void ) {
} }
static void usage( char *name ) { 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 #ifdef WANT_ACCESSLIST_BLACK
" [-b blacklistfile]" " [-b blacklistfile]"
#elif defined ( WANT_ACCESSLIST_WHITE ) #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("-r redirecturl","specify url where / should be redirected to (default none)");
HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")"); 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("-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 #ifdef WANT_ACCESSLIST_BLACK
HELPLINE("-b file","specify blacklist file."); HELPLINE("-b file","specify blacklist file.");
#elif defined( WANT_ACCESSLIST_WHITE ) #elif defined( WANT_ACCESSLIST_WHITE )
@ -395,7 +395,7 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) {
s += off; s += off;
if( bracket && *s == ']' ) ++s; if( bracket && *s == ']' ) ++s;
if( *s == 0 || isspace(*s)) return s-src; if( *s == 0 || isspace(*s)) return s-src;
if( !ip6_isv4mapped(ip)){ if( !ip6_isv4mapped(ip)) {
if( *s != ':' && *s != '.' ) return 0; if( *s != ':' && *s != '.' ) return 0;
if( !bracket && *(s) == ':' ) return 0; if( !bracket && *(s) == ':' ) return 0;
s++; s++;
@ -407,10 +407,35 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) {
return off+s-src; 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 ) { int parse_configfile( char * config_filename ) {
FILE * accesslist_filehandle; FILE * accesslist_filehandle;
char inbuf[512]; char inbuf[512];
ot_ip6 tmpip; ot_ip6 tmpip;
#if defined(WANT_RESTRICT_STATS) || defined(WANT_IP_FROM_PROXY) || defined(WANT_SYNC_LIVE)
ot_net tmpnet;
#endif
int bound = 0; int bound = 0;
accesslist_filehandle = fopen( config_filename, "r" ); accesslist_filehandle = fopen( config_filename, "r" );
@ -474,22 +499,22 @@ int parse_configfile( char * config_filename ) {
#endif #endif
#ifdef WANT_RESTRICT_STATS #ifdef WANT_RESTRICT_STATS
} else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) { } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) {
if( !scan_ip6( p+13, tmpip )) goto parse_error; if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error;
accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_STAT );
#endif #endif
} else if(!byte_diff(p, 17, "access.stats_path" ) && isspace(p[17])) { } else if(!byte_diff(p, 17, "access.stats_path" ) && isspace(p[17])) {
set_config_option( &g_stats_path, p+18 ); set_config_option( &g_stats_path, p+18 );
#ifdef WANT_IP_FROM_PROXY #ifdef WANT_IP_FROM_PROXY
} else if(!byte_diff(p, 12, "access.proxy" ) && isspace(p[12])) { } else if(!byte_diff(p, 12, "access.proxy" ) && isspace(p[12])) {
if( !scan_ip6( p+13, tmpip )) goto parse_error; if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error;
accesslist_blessip( tmpip, OT_PERMISSION_MAY_PROXY ); accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_PROXY );
#endif #endif
} else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) {
set_config_option( &g_redirecturl, p+21 ); set_config_option( &g_redirecturl, p+21 );
#ifdef WANT_SYNC_LIVE #ifdef WANT_SYNC_LIVE
} else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) { } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) {
if( !scan_ip6( p+25, tmpip )) goto parse_error; if( !scan_ip6_net( p+25, &tmpnet )) goto parse_error;
accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC ); accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_LIVESYNC );
} else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) { } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) {
uint16_t tmpport = LIVESYNC_PORT; uint16_t tmpport = LIVESYNC_PORT;
if( !scan_ip6_port( p+24, tmpip, &tmpport )) goto parse_error; 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 ) { int main( int argc, char **argv ) {
ot_ip6 serverip, tmpip; ot_ip6 serverip;
ot_net tmpnet;
int bound = 0, scanon = 1; int bound = 0, scanon = 1;
uint16_t tmpport; uint16_t tmpport;
char * statefile = 0; char * statefile = 0;
@ -641,8 +667,8 @@ int main( int argc, char **argv ) {
case 'r': set_config_option( &g_redirecturl, optarg ); break; case 'r': set_config_option( &g_redirecturl, optarg ); break;
case 'l': statefile = optarg; break; case 'l': statefile = optarg; break;
case 'A': case 'A':
if( !scan_ip6( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } if( !scan_ip6_net( optarg, &tmpnet )) { usage( argv[0] ); exit( 1 ); }
accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ accesslist_bless_net( &tmpnet, 0xffff ); /* Allow everything for now */
break; break;
case 'f': bound += parse_configfile( optarg ); break; case 'f': bound += parse_configfile( optarg ); break;
case 'h': help( argv[0] ); exit( 0 ); case 'h': help( argv[0] ); exit( 0 );

@ -21,6 +21,7 @@
#include "scan.h" #include "scan.h"
#include "ip6.h" #include "ip6.h"
#include "mmap.h" #include "mmap.h"
#include "fmt.h"
/* Opentracker */ /* Opentracker */
#include "trackerlogic.h" #include "trackerlogic.h"
@ -509,29 +510,37 @@ int proxylist_check_proxy( const ot_ip6 proxy, const ot_ip6 address ) {
#endif #endif
static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; static ot_net g_admin_nets[OT_ADMINIP_MAX];
static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; static ot_permissions g_admin_nets_permissions[OT_ADMINIP_MAX];
static unsigned int g_adminip_count = 0; static unsigned int g_admin_nets_count = 0;
int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { int accesslist_bless_net( ot_net *net, ot_permissions permissions ) {
if( g_adminip_count >= OT_ADMINIP_MAX ) if( g_admin_nets_count >= OT_ADMINIP_MAX )
return -1; return -1;
memcpy(g_adminip_addresses + g_adminip_count,ip,sizeof(ot_ip6)); memcpy(g_admin_nets + g_admin_nets_count, &net, sizeof(ot_net));
g_adminip_permissions[ g_adminip_count++ ] = permissions; g_admin_nets_permissions[ g_admin_nets_count++ ] = permissions;
#ifdef _DEBUG #ifdef _DEBUG
{ {
char _debug[512]; char _debug[512];
int off = snprintf( _debug, sizeof(_debug), "Blessing ip address " ); int off = snprintf( _debug, sizeof(_debug), "Blessing ip net " );
off += fmt_ip6c(_debug+off, ip ); 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_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_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_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 & 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++] = '.';
_debug[off++] = '\n';
(void)write( 2, _debug, off ); (void)write( 2, _debug, off );
} }
#endif #endif
@ -539,10 +548,10 @@ int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) {
return 0; return 0;
} }
int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ) { int accesslist_is_blessed( ot_ip6 ip, ot_permissions permissions ) {
unsigned int i; unsigned int i;
for( i=0; i<g_adminip_count; ++i ) for( i=0; i<g_admin_nets_count; ++i )
if( !memcmp( g_adminip_addresses + i, ip, sizeof(ot_ip6)) && ( g_adminip_permissions[ i ] & permissions ) ) if( address_in_net(ip, g_admin_nets + i) && (g_admin_nets_permissions[ i ] & permissions ))
return 1; return 1;
return 0; return 0;
} }

@ -82,7 +82,7 @@ typedef enum {
OT_PERMISSION_MAY_PROXY = 0x8 OT_PERMISSION_MAY_PROXY = 0x8
} ot_permissions; } ot_permissions;
int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ); int accesslist_bless_net( ot_net *net, ot_permissions permissions );
int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ); int accesslist_is_blessed( ot_ip6 ip, ot_permissions permissions );
#endif #endif

@ -215,7 +215,7 @@ static const ot_keywords keywords_format[] =
#ifdef WANT_RESTRICT_STATS #ifdef WANT_RESTRICT_STATS
struct http_data *cookie = io_getcookie( sock ); struct http_data *cookie = io_getcookie( sock );
if( !cookie || !accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) if( !cookie || !accesslist_is_blessed( cookie->ip, OT_PERMISSION_MAY_STAT ) )
HTTPERROR_403_IP; HTTPERROR_403_IP;
#endif #endif
@ -417,7 +417,7 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
} }
#ifdef WANT_IP_FROM_PROXY #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; ot_ip6 proxied_ip;
char *fwd = http_header( ws->request, ws->header_size, "x-forwarded-for" ); char *fwd = http_header( ws->request, ws->header_size, "x-forwarded-for" );
if( fwd && scan_ip6( fwd, proxied_ip ) ) 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 #ifdef WANT_FULLLOG_NETWORKS
case 8: /* matched "lognet" */ 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; char *tmp_buf = ws->reply;
ot_net net; ot_net net;
signed short parsed, bits; signed short parsed, bits;

@ -192,7 +192,7 @@ static void * livesync_worker( void * args ) {
/* Expect at least tracker id and packet type */ /* Expect at least tracker id and packet type */
if( ws.request_size <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) ) if( ws.request_size <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) )
continue; continue;
if( !accesslist_isblessed(in_ip, OT_PERMISSION_MAY_LIVESYNC)) if( !accesslist_is_blessed(in_ip, OT_PERMISSION_MAY_LIVESYNC))
continue; continue;
if( !memcmp( ws.inbuf, &g_tracker_id, sizeof( g_tracker_id ) ) ) { if( !memcmp( ws.inbuf, &g_tracker_id, sizeof( g_tracker_id ) ) ) {
/* TODO: log packet coming from ourselves */ /* TODO: log packet coming from ourselves */

Loading…
Cancel
Save