summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2024-03-29 03:30:13 +0100
committerDirk Engling <erdgeist@erdgeist.org>2024-03-29 03:30:13 +0100
commit543ab73017b83e251924caca9aa37a0f892fe05f (patch)
tree7b58b9b4e1e7f05db81f25b50e062fb5ff36c421
parentede702c7ffc90f1635c069d20c8a46b0b2a6ab66 (diff)
Allow networks to be used instead of ip addresses when blessing is involved
-rw-r--r--opentracker.c50
-rw-r--r--ot_accesslist.c35
-rw-r--r--ot_accesslist.h4
-rw-r--r--ot_http.c6
-rw-r--r--ot_livesync.c2
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 ) {
104} 104}
105 105
106static void usage( char *name ) { 106static void usage( char *name ) {
107 fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip] [-f config] [-s livesyncport]" 107 fprintf( stderr, "Usage: %s [-i ip] [-p port] [-P port] [-r redirect] [-d dir] [-u user] [-A ip[/bits]] [-f config] [-s livesyncport]"
108#ifdef WANT_ACCESSLIST_BLACK 108#ifdef WANT_ACCESSLIST_BLACK
109 " [-b blacklistfile]" 109 " [-b blacklistfile]"
110#elif defined ( WANT_ACCESSLIST_WHITE ) 110#elif defined ( WANT_ACCESSLIST_WHITE )
@@ -124,7 +124,7 @@ static void help( char *name ) {
124 HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)"); 124 HELPLINE("-r redirecturl","specify url where / should be redirected to (default none)");
125 HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")"); 125 HELPLINE("-d dir","specify directory to try to chroot to (default: \".\")");
126 HELPLINE("-u user","specify user under whose privileges opentracker should run (default: \"nobody\")"); 126 HELPLINE("-u user","specify user under whose privileges opentracker should run (default: \"nobody\")");
127 HELPLINE("-A ip","bless an ip address as admin address (e.g. to allow syncs from this address)"); 127 HELPLINE("-A ip[/bits]","bless an ip address or net as admin address (e.g. to allow syncs from this address)");
128#ifdef WANT_ACCESSLIST_BLACK 128#ifdef WANT_ACCESSLIST_BLACK
129 HELPLINE("-b file","specify blacklist file."); 129 HELPLINE("-b file","specify blacklist file.");
130#elif defined( WANT_ACCESSLIST_WHITE ) 130#elif defined( WANT_ACCESSLIST_WHITE )
@@ -395,7 +395,7 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) {
395 s += off; 395 s += off;
396 if( bracket && *s == ']' ) ++s; 396 if( bracket && *s == ']' ) ++s;
397 if( *s == 0 || isspace(*s)) return s-src; 397 if( *s == 0 || isspace(*s)) return s-src;
398 if( !ip6_isv4mapped(ip)){ 398 if( !ip6_isv4mapped(ip)) {
399 if( *s != ':' && *s != '.' ) return 0; 399 if( *s != ':' && *s != '.' ) return 0;
400 if( !bracket && *(s) == ':' ) return 0; 400 if( !bracket && *(s) == ':' ) return 0;
401 s++; 401 s++;
@@ -407,10 +407,35 @@ static int scan_ip6_port( const char *src, ot_ip6 ip, uint16 *port ) {
407 return off+s-src; 407 return off+s-src;
408} 408}
409 409
410static int scan_ip6_net( const char *src, ot_net *net) {
411 const char *s = src;
412 int off;
413 while( isspace(*s) ) ++s;
414 if( !(off = scan_ip6( s, net->address ) ) )
415 return 0;
416 s += off;
417 if(*s!='/')
418 net->bits = 128;
419 else {
420 s++;
421 if( !(off = scan_int (s, &net->bits ) ) )
422 return 0;
423 if( ip6_isv4mapped(net->address))
424 net->bits += 96;
425 if(net->bits > 128)
426 return 0;
427 s += off;
428 }
429 return off+s-src;
430}
431
410int parse_configfile( char * config_filename ) { 432int parse_configfile( char * config_filename ) {
411 FILE * accesslist_filehandle; 433 FILE * accesslist_filehandle;
412 char inbuf[512]; 434 char inbuf[512];
413 ot_ip6 tmpip; 435 ot_ip6 tmpip;
436#if defined(WANT_RESTRICT_STATS) || defined(WANT_IP_FROM_PROXY) || defined(WANT_SYNC_LIVE)
437 ot_net tmpnet;
438#endif
414 int bound = 0; 439 int bound = 0;
415 440
416 accesslist_filehandle = fopen( config_filename, "r" ); 441 accesslist_filehandle = fopen( config_filename, "r" );
@@ -474,22 +499,22 @@ int parse_configfile( char * config_filename ) {
474#endif 499#endif
475#ifdef WANT_RESTRICT_STATS 500#ifdef WANT_RESTRICT_STATS
476 } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) { 501 } else if(!byte_diff(p, 12, "access.stats" ) && isspace(p[12])) {
477 if( !scan_ip6( p+13, tmpip )) goto parse_error; 502 if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error;
478 accesslist_blessip( tmpip, OT_PERMISSION_MAY_STAT ); 503 accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_STAT );
479#endif 504#endif
480 } else if(!byte_diff(p, 17, "access.stats_path" ) && isspace(p[17])) { 505 } else if(!byte_diff(p, 17, "access.stats_path" ) && isspace(p[17])) {
481 set_config_option( &g_stats_path, p+18 ); 506 set_config_option( &g_stats_path, p+18 );
482#ifdef WANT_IP_FROM_PROXY 507#ifdef WANT_IP_FROM_PROXY
483 } else if(!byte_diff(p, 12, "access.proxy" ) && isspace(p[12])) { 508 } else if(!byte_diff(p, 12, "access.proxy" ) && isspace(p[12])) {
484 if( !scan_ip6( p+13, tmpip )) goto parse_error; 509 if( !scan_ip6_net( p+13, &tmpnet )) goto parse_error;
485 accesslist_blessip( tmpip, OT_PERMISSION_MAY_PROXY ); 510 accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_PROXY );
486#endif 511#endif
487 } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) { 512 } else if(!byte_diff(p, 20, "tracker.redirect_url" ) && isspace(p[20])) {
488 set_config_option( &g_redirecturl, p+21 ); 513 set_config_option( &g_redirecturl, p+21 );
489#ifdef WANT_SYNC_LIVE 514#ifdef WANT_SYNC_LIVE
490 } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) { 515 } else if(!byte_diff(p, 24, "livesync.cluster.node_ip" ) && isspace(p[24])) {
491 if( !scan_ip6( p+25, tmpip )) goto parse_error; 516 if( !scan_ip6_net( p+25, &tmpnet )) goto parse_error;
492 accesslist_blessip( tmpip, OT_PERMISSION_MAY_LIVESYNC ); 517 accesslist_bless_net( &tmpnet, OT_PERMISSION_MAY_LIVESYNC );
493 } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) { 518 } else if(!byte_diff(p, 23, "livesync.cluster.listen" ) && isspace(p[23])) {
494 uint16_t tmpport = LIVESYNC_PORT; 519 uint16_t tmpport = LIVESYNC_PORT;
495 if( !scan_ip6_port( p+24, tmpip, &tmpport )) goto parse_error; 520 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
591} 616}
592 617
593int main( int argc, char **argv ) { 618int main( int argc, char **argv ) {
594 ot_ip6 serverip, tmpip; 619 ot_ip6 serverip;
620 ot_net tmpnet;
595 int bound = 0, scanon = 1; 621 int bound = 0, scanon = 1;
596 uint16_t tmpport; 622 uint16_t tmpport;
597 char * statefile = 0; 623 char * statefile = 0;
@@ -641,8 +667,8 @@ int main( int argc, char **argv ) {
641 case 'r': set_config_option( &g_redirecturl, optarg ); break; 667 case 'r': set_config_option( &g_redirecturl, optarg ); break;
642 case 'l': statefile = optarg; break; 668 case 'l': statefile = optarg; break;
643 case 'A': 669 case 'A':
644 if( !scan_ip6( optarg, tmpip )) { usage( argv[0] ); exit( 1 ); } 670 if( !scan_ip6_net( optarg, &tmpnet )) { usage( argv[0] ); exit( 1 ); }
645 accesslist_blessip( tmpip, 0xffff ); /* Allow everything for now */ 671 accesslist_bless_net( &tmpnet, 0xffff ); /* Allow everything for now */
646 break; 672 break;
647 case 'f': bound += parse_configfile( optarg ); break; 673 case 'f': bound += parse_configfile( optarg ); break;
648 case 'h': help( argv[0] ); exit( 0 ); 674 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 @@
21#include "scan.h" 21#include "scan.h"
22#include "ip6.h" 22#include "ip6.h"
23#include "mmap.h" 23#include "mmap.h"
24#include "fmt.h"
24 25
25/* Opentracker */ 26/* Opentracker */
26#include "trackerlogic.h" 27#include "trackerlogic.h"
@@ -509,29 +510,37 @@ int proxylist_check_proxy( const ot_ip6 proxy, const ot_ip6 address ) {
509 510
510#endif 511#endif
511 512
512static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; 513static ot_net g_admin_nets[OT_ADMINIP_MAX];
513static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; 514static ot_permissions g_admin_nets_permissions[OT_ADMINIP_MAX];
514static unsigned int g_adminip_count = 0; 515static unsigned int g_admin_nets_count = 0;
515 516
516int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { 517int accesslist_bless_net( ot_net *net, ot_permissions permissions ) {
517 if( g_adminip_count >= OT_ADMINIP_MAX ) 518 if( g_admin_nets_count >= OT_ADMINIP_MAX )
518 return -1; 519 return -1;
519 520
520 memcpy(g_adminip_addresses + g_adminip_count,ip,sizeof(ot_ip6)); 521 memcpy(g_admin_nets + g_admin_nets_count, &net, sizeof(ot_net));
521 g_adminip_permissions[ g_adminip_count++ ] = permissions; 522 g_admin_nets_permissions[ g_admin_nets_count++ ] = permissions;
522 523
523#ifdef _DEBUG 524#ifdef _DEBUG
524 { 525 {
525 char _debug[512]; 526 char _debug[512];
526 int off = snprintf( _debug, sizeof(_debug), "Blessing ip address " ); 527 int off = snprintf( _debug, sizeof(_debug), "Blessing ip net " );
527 off += fmt_ip6c(_debug+off, ip ); 528 off += fmt_ip6c(_debug+off, net->address );
529 if( net->bits < 128) {
530 _debug[off++] = '/';
531 if( ip6_isv4mapped(net->address) )
532 off += fmt_long(_debug+off, net->bits-96);
533 else
534 off += fmt_long(_debug+off, net->bits);
535 }
528 536
529 if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" ); 537 if( permissions & OT_PERMISSION_MAY_STAT ) off += snprintf( _debug+off, 512-off, " may_fetch_stats" );
530 if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" ); 538 if( permissions & OT_PERMISSION_MAY_LIVESYNC ) off += snprintf( _debug+off, 512-off, " may_sync_live" );
531 if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" ); 539 if( permissions & OT_PERMISSION_MAY_FULLSCRAPE ) off += snprintf( _debug+off, 512-off, " may_fetch_fullscrapes" );
532 if( permissions & OT_PERMISSION_MAY_PROXY ) off += snprintf( _debug+off, 512-off, " may_proxy" ); 540 if( permissions & OT_PERMISSION_MAY_PROXY ) off += snprintf( _debug+off, 512-off, " may_proxy" );
533 if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing\n" ); 541 if( !permissions ) off += snprintf( _debug+off, sizeof(_debug)-off, " nothing" );
534 _debug[off++] = '.'; 542 _debug[off++] = '.';
543 _debug[off++] = '\n';
535 (void)write( 2, _debug, off ); 544 (void)write( 2, _debug, off );
536 } 545 }
537#endif 546#endif
@@ -539,10 +548,10 @@ int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) {
539 return 0; 548 return 0;
540} 549}
541 550
542int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ) { 551int accesslist_is_blessed( ot_ip6 ip, ot_permissions permissions ) {
543 unsigned int i; 552 unsigned int i;
544 for( i=0; i<g_adminip_count; ++i ) 553 for( i=0; i<g_admin_nets_count; ++i )
545 if( !memcmp( g_adminip_addresses + i, ip, sizeof(ot_ip6)) && ( g_adminip_permissions[ i ] & permissions ) ) 554 if( address_in_net(ip, g_admin_nets + i) && (g_admin_nets_permissions[ i ] & permissions ))
546 return 1; 555 return 1;
547 return 0; 556 return 0;
548} 557}
diff --git a/ot_accesslist.h b/ot_accesslist.h
index 281f61b..a988791 100644
--- a/ot_accesslist.h
+++ b/ot_accesslist.h
@@ -82,7 +82,7 @@ typedef enum {
82 OT_PERMISSION_MAY_PROXY = 0x8 82 OT_PERMISSION_MAY_PROXY = 0x8
83} ot_permissions; 83} ot_permissions;
84 84
85int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ); 85int accesslist_bless_net( ot_net *net, ot_permissions permissions );
86int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ); 86int accesslist_is_blessed( ot_ip6 ip, ot_permissions permissions );
87 87
88#endif 88#endif
diff --git a/ot_http.c b/ot_http.c
index 90b7a4b..35f88b1 100644
--- a/ot_http.c
+++ b/ot_http.c
@@ -215,7 +215,7 @@ static const ot_keywords keywords_format[] =
215#ifdef WANT_RESTRICT_STATS 215#ifdef WANT_RESTRICT_STATS
216 struct http_data *cookie = io_getcookie( sock ); 216 struct http_data *cookie = io_getcookie( sock );
217 217
218 if( !cookie || !accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) 218 if( !cookie || !accesslist_is_blessed( cookie->ip, OT_PERMISSION_MAY_STAT ) )
219 HTTPERROR_403_IP; 219 HTTPERROR_403_IP;
220#endif 220#endif
221 221
@@ -417,7 +417,7 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
417 } 417 }
418 418
419#ifdef WANT_IP_FROM_PROXY 419#ifdef WANT_IP_FROM_PROXY
420 if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_PROXY ) ) { 420 if( accesslist_is_blessed( cookie->ip, OT_PERMISSION_MAY_PROXY ) ) {
421 ot_ip6 proxied_ip; 421 ot_ip6 proxied_ip;
422 char *fwd = http_header( ws->request, ws->header_size, "x-forwarded-for" ); 422 char *fwd = http_header( ws->request, ws->header_size, "x-forwarded-for" );
423 if( fwd && scan_ip6( fwd, proxied_ip ) ) 423 if( fwd && scan_ip6( fwd, proxied_ip ) )
@@ -495,7 +495,7 @@ static ssize_t http_handle_announce( const int64 sock, struct ot_workstruct *ws,
495#ifdef WANT_FULLLOG_NETWORKS 495#ifdef WANT_FULLLOG_NETWORKS
496 case 8: /* matched "lognet" */ 496 case 8: /* matched "lognet" */
497 { 497 {
498 //if( accesslist_isblessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) { 498 //if( accesslist_is_blessed( cookie->ip, OT_PERMISSION_MAY_STAT ) ) {
499 char *tmp_buf = ws->reply; 499 char *tmp_buf = ws->reply;
500 ot_net net; 500 ot_net net;
501 signed short parsed, bits; 501 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 ) {
192 /* Expect at least tracker id and packet type */ 192 /* Expect at least tracker id and packet type */
193 if( ws.request_size <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) ) 193 if( ws.request_size <= (ssize_t)(sizeof( g_tracker_id ) + sizeof( uint32_t )) )
194 continue; 194 continue;
195 if( !accesslist_isblessed(in_ip, OT_PERMISSION_MAY_LIVESYNC)) 195 if( !accesslist_is_blessed(in_ip, OT_PERMISSION_MAY_LIVESYNC))
196 continue; 196 continue;
197 if( !memcmp( ws.inbuf, &g_tracker_id, sizeof( g_tracker_id ) ) ) { 197 if( !memcmp( ws.inbuf, &g_tracker_id, sizeof( g_tracker_id ) ) ) {
198 /* TODO: log packet coming from ourselves */ 198 /* TODO: log packet coming from ourselves */