diff options
author | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-04-15 12:36:37 +0000 |
---|---|---|
committer | Christian Fuchs <christian.fuchs@cfuchs.net> | 2013-04-15 12:36:37 +0000 |
commit | ad68ae150f17cf6e0b2c605c9331cf0aedfce1d0 (patch) | |
tree | 9079e9ce1b942683e45f2f5212fe2f9ce1bd5d56 /src/util | |
parent | fbda84a3f00a667f4b149f00f9a7d330e5db54a8 (diff) | |
download | gnunet-ad68ae150f17cf6e0b2c605c9331cf0aedfce1d0.tar.gz gnunet-ad68ae150f17cf6e0b2c605c9331cf0aedfce1d0.zip |
extended the GNUNET_OS_check_helper_binary parameters to do previlege
checking in windows. To do so, tested binaries must still be supplied
with valid commandline arguments, but on windows gnunet will utilize the
-d flag to run the programs initialization phase or privileged
operations only. In these modes, a program will not enter its mainloop
or communicate with the outside.
updated relevant function calls gnunet-wide to meet the extended
function parameters.
Diffstat (limited to 'src/util')
-rw-r--r-- | src/util/os_installation.c | 79 | ||||
-rw-r--r-- | src/util/os_priority.c | 4 |
2 files changed, 63 insertions, 20 deletions
diff --git a/src/util/os_installation.c b/src/util/os_installation.c index b63a19d2e..8445fd1cc 100644 --- a/src/util/os_installation.c +++ b/src/util/os_installation.c | |||
@@ -654,12 +654,17 @@ GNUNET_OS_get_libexec_binary_path (const char *progname) | |||
654 | * | 654 | * |
655 | * @param binary the name of the file to check. | 655 | * @param binary the name of the file to check. |
656 | * W32: must not have an .exe suffix. | 656 | * W32: must not have an .exe suffix. |
657 | * @return GNUNET_YES if the file is SUID, | 657 | * @param check_suid input true if the binary should be checked for SUID (*nix) |
658 | * GNUNET_NO if not SUID (but binary exists) | 658 | * W32: checks if the program has sufficient privileges by executing this |
659 | * binary with the -d flag. -d omits a programs main loop and only | ||
660 | * executes all privileged operations in an binary. | ||
661 | * @param params parameters used for w32 privilege checking (can be NULL for != w32 ) | ||
662 | * @return GNUNET_YES if the file is SUID (*nix) or can be executed with current privileges (W32), | ||
663 | * GNUNET_NO if not SUID (but binary exists), | ||
659 | * GNUNET_SYSERR on error (no such binary or not executable) | 664 | * GNUNET_SYSERR on error (no such binary or not executable) |
660 | */ | 665 | */ |
661 | int | 666 | int |
662 | GNUNET_OS_check_helper_binary (const char *binary) | 667 | GNUNET_OS_check_helper_binary (const char *binary, const boolean check_suid, const char *params) |
663 | { | 668 | { |
664 | struct stat statbuf; | 669 | struct stat statbuf; |
665 | char *p; | 670 | char *p; |
@@ -725,24 +730,62 @@ GNUNET_OS_check_helper_binary (const char *binary) | |||
725 | GNUNET_free (p); | 730 | GNUNET_free (p); |
726 | return GNUNET_SYSERR; | 731 | return GNUNET_SYSERR; |
727 | } | 732 | } |
733 | if (check_suid){ | ||
728 | #ifndef MINGW | 734 | #ifndef MINGW |
729 | if ((0 != (statbuf.st_mode & S_ISUID)) && (0 == statbuf.st_uid)) | 735 | if ((0 != (statbuf.st_mode & S_ISUID)) && (0 == statbuf.st_uid)) |
730 | { | 736 | { |
731 | GNUNET_free (p); | 737 | GNUNET_free (p); |
732 | return GNUNET_YES; | 738 | return GNUNET_YES; |
733 | } | 739 | } |
734 | /* binary exists, but not SUID */ | 740 | /* binary exists, but not SUID */ |
735 | #else | 741 | #else |
736 | return GNUNET_YES; | 742 | STARTUPINFO start; |
737 | /* FIXME: | 743 | char parameters[512]; |
738 | * no suid for windows possible! | 744 | PROCESS_INFORMATION proc; |
739 | * permissions-checking is too specific(as in non-portable) | 745 | DWORD exit_value; |
740 | * user/group checking is pointless (users/applications can drop privileges) | 746 | |
741 | * using token checking for elevated permissions would limit gnunet | 747 | GNUNET_snprintf (¶meters, 512, "-d %s", params); |
742 | * to run only on winserver 2008 and 2012! | 748 | memset (&start, 0, sizeof (start)); |
743 | * | 749 | start.cb = sizeof (start); |
744 | * thus, ad add "dryrun" checking */ | 750 | memset (&proc, 0, sizeof (proc)); |
751 | |||
752 | |||
753 | // Start the child process. | ||
754 | if ( ! (CreateProcess( p, // current windows (2k3 and up can handle / instead of \ in paths)) | ||
755 | parameters, // execute dryrun/priviliege checking mode | ||
756 | NULL, // Process handle not inheritable | ||
757 | NULL, // Thread handle not inheritable | ||
758 | FALSE, // Set handle inheritance to FALSE | ||
759 | CREATE_DEFAULT_ERROR_MODE, // No creation flags | ||
760 | NULL, // Use parent's environment block | ||
761 | NULL, // Use parent's starting directory | ||
762 | &start, // Pointer to STARTUPINFO structure | ||
763 | &proc ) // Pointer to PROCESS_INFORMATION structure | ||
764 | )) | ||
765 | { | ||
766 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
767 | _("CreateProcess failed for binary %s (%d).\n"), | ||
768 | p, GetLastError()); | ||
769 | return GNUNET_SYSERR; | ||
770 | } | ||
771 | |||
772 | // Wait until child process exits. | ||
773 | WaitForSingleObject( proc.hProcess, INFINITE ); | ||
774 | |||
775 | if ( ! GetExitCodeProcess (proc.hProcess, &exit_value)){ | ||
776 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
777 | _("GetExitCodeProcess failed for binary %s (%d).\n"), | ||
778 | p, GetLastError() ); | ||
779 | return GNUNET_SYSERR; | ||
780 | } | ||
781 | // Close process and thread handles. | ||
782 | CloseHandle( proc.hProcess ); | ||
783 | CloseHandle( proc.hThread ); | ||
784 | |||
785 | if (!exit_value) | ||
786 | return GNUNET_YES; | ||
745 | #endif | 787 | #endif |
788 | } | ||
746 | GNUNET_free (p); | 789 | GNUNET_free (p); |
747 | return GNUNET_NO; | 790 | return GNUNET_NO; |
748 | } | 791 | } |
diff --git a/src/util/os_priority.c b/src/util/os_priority.c index b8b854963..e86de968a 100644 --- a/src/util/os_priority.c +++ b/src/util/os_priority.c | |||
@@ -634,7 +634,7 @@ start_process (int pipe_control, | |||
634 | int fd_stdin_read; | 634 | int fd_stdin_read; |
635 | int fd_stdin_write; | 635 | int fd_stdin_write; |
636 | 636 | ||
637 | if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename)) | 637 | if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename, FALSE, NULL)) |
638 | return NULL; /* not executable */ | 638 | return NULL; /* not executable */ |
639 | if (GNUNET_YES == pipe_control) | 639 | if (GNUNET_YES == pipe_control) |
640 | { | 640 | { |
@@ -865,7 +865,7 @@ start_process (int pipe_control, | |||
865 | BOOL bresult; | 865 | BOOL bresult; |
866 | DWORD error_code; | 866 | DWORD error_code; |
867 | 867 | ||
868 | if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename)) | 868 | if (GNUNET_SYSERR == GNUNET_OS_check_helper_binary (filename, FALSE, NULL)) |
869 | return NULL; /* not executable */ | 869 | return NULL; /* not executable */ |
870 | 870 | ||
871 | /* Search in prefix dir (hopefully - the directory from which | 871 | /* Search in prefix dir (hopefully - the directory from which |