diff options
| author | Dirk Engling <erdgeist@erdgeist.org> | 2024-03-29 03:30:13 +0100 |
|---|---|---|
| committer | Dirk Engling <erdgeist@erdgeist.org> | 2024-03-29 03:30:13 +0100 |
| commit | 543ab73017b83e251924caca9aa37a0f892fe05f (patch) | |
| tree | 7b58b9b4e1e7f05db81f25b50e062fb5ff36c421 | |
| parent | ede702c7ffc90f1635c069d20c8a46b0b2a6ab66 (diff) | |
Allow networks to be used instead of ip addresses when blessing is involved
| -rw-r--r-- | opentracker.c | 50 | ||||
| -rw-r--r-- | ot_accesslist.c | 35 | ||||
| -rw-r--r-- | ot_accesslist.h | 4 | ||||
| -rw-r--r-- | ot_http.c | 6 | ||||
| -rw-r--r-- | 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 ) { | |||
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static void usage( char *name ) { | 106 | static 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 | ||
| 410 | static 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 | |||
| 410 | int parse_configfile( char * config_filename ) { | 432 | int 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 | ||
| 593 | int main( int argc, char **argv ) { | 618 | int 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 | ||
| 512 | static ot_ip6 g_adminip_addresses[OT_ADMINIP_MAX]; | 513 | static ot_net g_admin_nets[OT_ADMINIP_MAX]; |
| 513 | static ot_permissions g_adminip_permissions[OT_ADMINIP_MAX]; | 514 | static ot_permissions g_admin_nets_permissions[OT_ADMINIP_MAX]; |
| 514 | static unsigned int g_adminip_count = 0; | 515 | static unsigned int g_admin_nets_count = 0; |
| 515 | 516 | ||
| 516 | int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ) { | 517 | int 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 | ||
| 542 | int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ) { | 551 | int 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 | ||
| 85 | int accesslist_blessip( ot_ip6 ip, ot_permissions permissions ); | 85 | int accesslist_bless_net( ot_net *net, ot_permissions permissions ); |
| 86 | int accesslist_isblessed( ot_ip6 ip, ot_permissions permissions ); | 86 | int accesslist_is_blessed( ot_ip6 ip, ot_permissions permissions ); |
| 87 | 87 | ||
| 88 | #endif | 88 | #endif |
| @@ -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 */ |
