From 7aba81537bfb410ab71db1702dbf2f1104b5d39f Mon Sep 17 00:00:00 2001 From: lurchi Date: Mon, 26 Nov 2018 19:04:02 +0100 Subject: consider HELPER_PATH for setuid binaries --- src/dns/gnunet-service-dns.c | 18 +++++++++++++++--- src/exit/gnunet-daemon-exit.c | 16 +++++++++++++--- src/nat/gnunet-service-nat.c | 6 ++++-- src/nat/gnunet-service-nat_helper.c | 34 ++++++++++++++++++++++++++++------ src/nat/gnunet-service-nat_helper.h | 10 +++++++--- src/vpn/gnunet-service-vpn.c | 22 +++++++++++++++++----- 6 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index a63205ebf..6666ff61a 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c @@ -1055,6 +1055,7 @@ run (void *cls, char *ipv6addr; char *ipv6prefix; char *dns_exit; + char *helper_path; char *binary; int nortsetup; @@ -1082,7 +1083,13 @@ run (void *cls, _("need a valid IPv4 or IPv6 address\n")); GNUNET_free_non_null (dns_exit); } - binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-dns"); + helper_path = NULL; + GNUNET_CONFIGURATION_get_value_string (cfg, + "DNS", + "HELPER_PATH", + &helper_path); + binary = GNUNET_OS_get_binary_path ("gnunet-helper-dns", helper_path); + GNUNET_free_non_null (helper_path); if (GNUNET_YES != GNUNET_OS_check_helper_binary (binary, GNUNET_YES, @@ -1095,7 +1102,6 @@ run (void *cls, GNUNET_free (binary); return; } - GNUNET_free (binary); helper_argv[0] = GNUNET_strdup ("gnunet-dns"); if (GNUNET_SYSERR == @@ -1106,6 +1112,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No entry 'IFNAME' in configuration!\n"); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -1118,6 +1125,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No entry 'IPV6ADDR' in configuration!\n"); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -1130,6 +1138,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No entry 'IPV6PREFIX' in configuration!\n"); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -1143,6 +1152,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No entry 'IPV4ADDR' in configuration!\n"); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -1153,6 +1163,7 @@ run (void *cls, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No entry 'IPV4MASK' in configuration!\n"); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -1167,10 +1178,11 @@ run (void *cls, helper_argv[7] = NULL; hijacker = GNUNET_HELPER_start (GNUNET_NO, - "gnunet-helper-dns", + binary, helper_argv, &process_helper_messages, NULL, NULL); + GNUNET_free (binary); } diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index fc29849b5..f1478d574 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c @@ -3778,6 +3778,7 @@ run (void *cls, }; struct GNUNET_HashCode port; char *policy; + char *helper_path; char *binary; char *regex; char *prefixed_regex; @@ -3797,7 +3798,14 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-exit"); + helper_path = NULL; + GNUNET_CONFIGURATION_get_value_string (cfg, + "exit", + "HELPER_PATH", + &helper_path); + binary = GNUNET_OS_get_binary_path ("gnunet-helper-exit", + helper_path); + GNUNET_free_non_null (helper_path); if (GNUNET_YES != GNUNET_OS_check_helper_binary (binary, GNUNET_YES, @@ -3812,7 +3820,6 @@ run (void *cls, global_ret = 1; return; } - GNUNET_free (binary); GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); stats = GNUNET_STATISTICS_create ("exit", @@ -3820,6 +3827,7 @@ run (void *cls, cadet_handle = GNUNET_CADET_connect (cfg); if (NULL == cadet_handle) { + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -3827,6 +3835,7 @@ run (void *cls, if (GNUNET_OK != setup_exit_helper_args ()) { + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -3923,11 +3932,12 @@ run (void *cls, } } helper_handle = GNUNET_HELPER_start (GNUNET_NO, - "gnunet-helper-exit", + binary, exit_argv, &message_token, NULL, NULL); + GNUNET_free (binary); } diff --git a/src/nat/gnunet-service-nat.c b/src/nat/gnunet-service-nat.c index 8d771f474..2498a990a 100644 --- a/src/nat/gnunet-service-nat.c +++ b/src/nat/gnunet-service-nat.c @@ -1063,7 +1063,8 @@ run_scan (void *cls) sizeof (*s4))); pos->hc = GN_start_gnunet_nat_server_ (&s4->sin_addr, &reversal_callback, - pos); + pos, + cfg); } } } @@ -1826,7 +1827,8 @@ handle_request_connection_reversal (void *cls, GNUNET_break_op (AF_INET == r4.sin_family); ret = GN_request_connection_reversal (&l4.sin_addr, ntohs (l4.sin_port), - &r4.sin_addr); + &r4.sin_addr, + cfg); if (GNUNET_OK != ret) GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("Connection reversal request failed\n")); diff --git a/src/nat/gnunet-service-nat_helper.c b/src/nat/gnunet-service-nat_helper.c index 56090bcea..d2ef934a6 100644 --- a/src/nat/gnunet-service-nat_helper.c +++ b/src/nat/gnunet-service-nat_helper.c @@ -74,6 +74,11 @@ struct HelperContext * stdout file handle (for reading) for the gnunet-helper-nat-server process */ const struct GNUNET_DISK_FileHandle *server_stdout_handle; + + /** + * Handle to the GNUnet configuration + */ + const struct GNUNET_CONFIGURATION_Handle *cfg; }; @@ -217,6 +222,7 @@ static void restart_nat_server (void *cls) { struct HelperContext *h = cls; + char *helper_path; char *binary; char ia[INET_ADDRSTRLEN]; @@ -227,8 +233,13 @@ restart_nat_server (void *cls) ia, sizeof (ia))); /* Start the server process */ - binary - = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-server"); + helper_path = NULL; + GNUNET_CONFIGURATION_get_value_string (h->cfg, + "NAT", + "HELPER_PATH", + &helper_path); + binary = GNUNET_OS_get_binary_path ("gnunet-helper-nat-server", helper_path); + GNUNET_free_non_null (helper_path); if (GNUNET_YES != GNUNET_OS_check_helper_binary (binary, GNUNET_YES, @@ -298,12 +309,14 @@ restart_nat_server (void *cls) * @param internal_address * @param cb function to call if we receive a request * @param cb_cls closure for @a cb + * @param cfg Handle to the GNUnet configuration * @return NULL on error */ struct HelperContext * GN_start_gnunet_nat_server_ (const struct in_addr *internal_address, GN_ReversalCallback cb, - void *cb_cls) + void *cb_cls, + const struct GNUNET_CONFIGURATION_Handle *cfg) { struct HelperContext *h; @@ -311,6 +324,7 @@ GN_start_gnunet_nat_server_ (const struct in_addr *internal_address, h->cb = cb; h->cb_cls = cb_cls; h->internal_address = *internal_address; + h->cfg = cfg; restart_nat_server (h); if (NULL == h->server_stdout) { @@ -366,18 +380,21 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h) * @param internal_address out internal address to use * @param internal_port port to use * @param remote_v4 the address of the peer (IPv4-only) + * @param cfg handle to the GNUnet configuration * @return #GNUNET_SYSERR on error, * #GNUNET_OK otherwise */ int GN_request_connection_reversal (const struct in_addr *internal_address, uint16_t internal_port, - const struct in_addr *remote_v4) + const struct in_addr *remote_v4, + const struct GNUNET_CONFIGURATION_Handle *cfg) { char intv4[INET_ADDRSTRLEN]; char remv4[INET_ADDRSTRLEN]; char port_as_string[6]; struct GNUNET_OS_Process *proc; + char *helper_path; char *binary; if (NULL == inet_ntop (AF_INET, @@ -407,8 +424,13 @@ GN_request_connection_reversal (const struct in_addr *internal_address, intv4, remv4, internal_port); - binary - = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-nat-client"); + helper_path = NULL; + GNUNET_CONFIGURATION_get_value_string (cfg, + "PATHS", + "SETUID_PATHS", + &helper_path); + binary = GNUNET_OS_get_binary_path ("gnunet-helper-nat-client", helper_path); + GNUNET_free_non_null (helper_path); proc = GNUNET_OS_start_process (GNUNET_NO, 0, diff --git a/src/nat/gnunet-service-nat_helper.h b/src/nat/gnunet-service-nat_helper.h index d9294d949..e2f7e3355 100644 --- a/src/nat/gnunet-service-nat_helper.h +++ b/src/nat/gnunet-service-nat_helper.h @@ -53,12 +53,14 @@ typedef void * @param internal_address * @param cb function to call if we receive a request * @param cb_cls closure for @a cb + * @param cfg Handle to the GNUnet configuration * @return NULL on error */ struct HelperContext * GN_start_gnunet_nat_server_ (const struct in_addr *internal_address, GN_ReversalCallback cb, - void *cb_cls); + void *cb_cls, + const struct GNUNET_CONFIGURATION_Handle *cfg); /** @@ -77,15 +79,17 @@ GN_stop_gnunet_nat_server_ (struct HelperContext *h); * that peer to connect to us (connection reversal). * * @param internal_address out internal address to use - * @param internal_port internal port to use + * @param internal_port port to use * @param remote_v4 the address of the peer (IPv4-only) + * @param cfg handle to the GNUnet configuration * @return #GNUNET_SYSERR on error, * #GNUNET_OK otherwise */ int GN_request_connection_reversal (const struct in_addr *internal_address, uint16_t internal_port, - const struct in_addr *sa); + const struct in_addr *remote_v4, + const struct GNUNET_CONFIGURATION_Handle *cfg); /* end of gnunet-service-nat_helper.h */ diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 91bc13fd8..7f9209b67 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c @@ -2934,10 +2934,17 @@ run (void *cls, char *ipv4mask; struct in_addr v4; struct in6_addr v6; + char *helper_path; char *binary; - binary = GNUNET_OS_get_libexec_binary_path ("gnunet-helper-vpn"); - + cfg = cfg_; + helper_path = NULL; + GNUNET_CONFIGURATION_get_value_string (cfg, + "VPN", + "HELPER_PATH", + &helper_path); + binary = GNUNET_OS_get_binary_path ("gnunet-helper-vpn", helper_path); + GNUNET_free_non_null (helper_path); if (GNUNET_YES != GNUNET_OS_check_helper_binary (binary, GNUNET_YES, @@ -2953,8 +2960,6 @@ run (void *cls, anything either */ return; } - GNUNET_free (binary); - cfg = cfg_; stats = GNUNET_STATISTICS_create ("vpn", cfg); if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_number (cfg, @@ -2980,6 +2985,7 @@ run (void *cls, GNUNET_CONFIGURATION_get_value_string (cfg, "VPN", "IFNAME", &ifname)) { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IFNAME"); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -2995,6 +3001,7 @@ run (void *cls, GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6ADDR", _("Must specify valid IPv6 address")); GNUNET_SCHEDULER_shutdown (); + GNUNET_free (binary); GNUNET_free_non_null (ipv6addr); return; } @@ -3006,6 +3013,7 @@ run (void *cls, { GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV6PREFIX"); GNUNET_SCHEDULER_shutdown (); + GNUNET_free (binary); GNUNET_free_non_null (ipv6prefix_s); return; } @@ -3018,6 +3026,7 @@ run (void *cls, { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4MASK", _("Must specify valid IPv6 mask")); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); return; } @@ -3039,6 +3048,7 @@ run (void *cls, { GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4ADDR", _("Must specify valid IPv4 address")); + GNUNET_free (binary); GNUNET_SCHEDULER_shutdown (); GNUNET_free_non_null (ipv4addr); return; @@ -3053,6 +3063,7 @@ run (void *cls, GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR, "VPN", "IPV4MASK", _("Must specify valid IPv4 mask")); GNUNET_SCHEDULER_shutdown (); + GNUNET_free (binary); GNUNET_free_non_null (ipv4mask); return; } @@ -3070,8 +3081,9 @@ run (void *cls, cadet_handle = GNUNET_CADET_connect (cfg_); // FIXME never opens ports??? helper_handle = GNUNET_HELPER_start (GNUNET_NO, - "gnunet-helper-vpn", vpn_argv, + binary, vpn_argv, &message_token, NULL, NULL); + GNUNET_free (binary); GNUNET_SCHEDULER_add_shutdown (&cleanup, NULL); } -- cgit v1.2.3