From: Christian Grothoff Date: Thu, 7 Jul 2011 16:02:57 +0000 (+0000) Subject: move SUID test code to util X-Git-Tag: initial-import-from-subversion-38251~17946 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=9e7b81a3cbc81c555811c2a9386e340570612f36;p=oweals%2Fgnunet.git move SUID test code to util --- diff --git a/src/include/gnunet_os_lib.h b/src/include/gnunet_os_lib.h index 7bd65adcb..85d666892 100644 --- a/src/include/gnunet_os_lib.h +++ b/src/include/gnunet_os_lib.h @@ -282,6 +282,22 @@ GNUNET_OS_install_parent_control_handler (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc); + +/** + * Check whether the suid bit is set on a file. Attempts to find the + * file using the current PATH environment variable as a search path. + * On W32, if the binary exists, this function tests if we are running + * with administrative rights (sufficient to create RAW sockets). + * + * @param binary the name of the file to check + * @return GNUNET_YES if the file is SUID, + * GNUNET_NO if not, + * GNUNET_SYSERR on error + */ +int +GNUNET_OS_check_helper_binary (const char *binary); + + #if 0 /* keep Emacsens' auto-indent happy */ { #endif diff --git a/src/nat/nat.c b/src/nat/nat.c index 182697e2b..2f38998e5 100644 --- a/src/nat/nat.c +++ b/src/nat/nat.c @@ -674,121 +674,6 @@ process_interfaces (void *cls, } -/** - * Return the actual path to a file found in the current - * PATH environment variable. - * - * @param binary the name of the file to find - * @return path to binary, NULL if not found - */ -static char * -get_path_from_PATH (const char *binary) -{ - char *path; - char *pos; - char *end; - char *buf; - const char *p; - - p = getenv ("PATH"); - if (p == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "tcp", - _("PATH environment variable is unset.\n")); - return NULL; - } - path = GNUNET_strdup (p); /* because we write on it */ - buf = GNUNET_malloc (strlen (path) + 20); - pos = path; - - while (NULL != (end = strchr (pos, PATH_SEPARATOR))) - { - *end = '\0'; - sprintf (buf, "%s/%s", pos, binary); - if (GNUNET_DISK_file_test (buf) == GNUNET_YES) - { - GNUNET_free (path); - return buf; - } - pos = end + 1; - } - sprintf (buf, "%s/%s", pos, binary); - if (GNUNET_DISK_file_test (buf) == GNUNET_YES) - { - GNUNET_free (path); - return buf; - } - GNUNET_free (buf); - GNUNET_free (path); - return NULL; -} - - -/** - * Check whether the suid bit is set on a file. - * Attempts to find the file using the current - * PATH environment variable as a search path. - * - * @param binary the name of the file to check - * @return GNUNET_YES if the file is SUID, - * GNUNET_NO if not, - * GNUNET_SYSERR on error - */ -static int -check_gnunet_nat_binary (const char *binary) -{ - struct stat statbuf; - char *p; -#ifdef MINGW - SOCKET rawsock; - char *binaryexe; - - GNUNET_asprintf (&binaryexe, "%s.exe", binary); - p = get_path_from_PATH (binaryexe); - free (binaryexe); -#else - p = get_path_from_PATH (binary); -#endif - if (p == NULL) - { - GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, - "tcp", - _("Could not find binary `%s' in PATH!\n"), - binary); - return GNUNET_NO; - } - if (0 != STAT (p, &statbuf)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("stat (%s) failed: %s\n"), - p, - STRERROR (errno)); - GNUNET_free (p); - return GNUNET_SYSERR; - } - GNUNET_free (p); -#ifndef MINGW - if ( (0 != (statbuf.st_mode & S_ISUID)) && - (statbuf.st_uid == 0) ) - return GNUNET_YES; - return GNUNET_NO; -#else - rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); - if (INVALID_SOCKET == rawsock) - { - DWORD err = GetLastError (); - GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, - "tcp", - "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n", err); - return GNUNET_NO; /* not running as administrator */ - } - closesocket (rawsock); - return GNUNET_YES; -#endif -} - - /** * Task that restarts the gnunet-helper-nat-server process after a crash * after a certain delay. @@ -1251,7 +1136,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, /* Test for SUID binaries */ if ( (h->behind_nat == GNUNET_YES) && (GNUNET_YES == h->enable_nat_server) && - (GNUNET_YES != check_gnunet_nat_binary("gnunet-helper-nat-server")) ) + (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-server")) ) { h->enable_nat_server = GNUNET_NO; GNUNET_log (GNUNET_ERROR_TYPE_WARNING, @@ -1259,7 +1144,7 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg, "gnunet-helper-nat-server"); } if ( (GNUNET_YES == h->enable_nat_client) && - (GNUNET_YES != check_gnunet_nat_binary("gnunet-helper-nat-client")) ) + (GNUNET_YES != GNUNET_OS_check_helper_binary("gnunet-helper-nat-client")) ) { h->enable_nat_client = GNUNET_NO; GNUNET_log (GNUNET_ERROR_TYPE_WARNING, diff --git a/src/util/os_installation.c b/src/util/os_installation.c index cbbc61433..ac5688aab 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c @@ -193,8 +193,15 @@ get_path_from_dyld_image () } #endif +/** + * Return the actual path to a file found in the current + * PATH environment variable. + * + * @param binary the name of the file to find + * @return path to binary, NULL if not found + */ static char * -get_path_from_PATH () +get_path_from_PATH (const char *binary) { char *path; char *pos; @@ -212,7 +219,7 @@ get_path_from_PATH () while (NULL != (end = strchr (pos, PATH_SEPARATOR))) { *end = '\0'; - sprintf (buf, "%s/%s", pos, "gnunet-arm"); + sprintf (buf, "%s/%s", pos, binary); if (GNUNET_DISK_file_test (buf) == GNUNET_YES) { pos = GNUNET_strdup (pos); @@ -222,7 +229,7 @@ get_path_from_PATH () } pos = end + 1; } - sprintf (buf, "%s/%s", pos, "gnunet-arm"); + sprintf (buf, "%s/%s", pos, binary); if (GNUNET_DISK_file_test (buf) == GNUNET_YES) { pos = GNUNET_strdup (pos); @@ -281,7 +288,7 @@ os_get_gnunet_path () if (ret != NULL) return ret; #endif - ret = get_path_from_PATH (); + ret = get_path_from_PATH ("gnunet-arm"); if (ret != NULL) return ret; /* other attempts here */ @@ -430,4 +437,69 @@ GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind) return tmp; } + +/** + * Check whether the suid bit is set on a file. + * Attempts to find the file using the current + * PATH environment variable as a search path. + * + * @param binary the name of the file to check + * @return GNUNET_YES if the file is SUID, + * GNUNET_NO if not, + * GNUNET_SYSERR on error + */ +int +GNUNET_OS_check_helper_binary (const char *binary) +{ + struct stat statbuf; + char *p; +#ifdef MINGW + SOCKET rawsock; + char *binaryexe; + + GNUNET_asprintf (&binaryexe, "%s.exe", binary); + p = get_path_from_PATH (binaryexe); + free (binaryexe); +#else + p = get_path_from_PATH (binary); +#endif + if (p == NULL) + { + GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, + "tcp", + _("Could not find binary `%s' in PATH!\n"), + binary); + return GNUNET_NO; + } + if (0 != STAT (p, &statbuf)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("stat (%s) failed: %s\n"), + p, + STRERROR (errno)); + GNUNET_free (p); + return GNUNET_SYSERR; + } + GNUNET_free (p); +#ifndef MINGW + if ( (0 != (statbuf.st_mode & S_ISUID)) && + (statbuf.st_uid == 0) ) + return GNUNET_YES; + return GNUNET_NO; +#else + rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP); + if (INVALID_SOCKET == rawsock) + { + DWORD err = GetLastError (); + GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, + "tcp", + "socket (AF_INET, SOCK_RAW, IPPROTO_ICMP) failed! GLE = %d\n", err); + return GNUNET_NO; /* not running as administrator */ + } + closesocket (rawsock); + return GNUNET_YES; +#endif +} + + /* end of os_installation.c */