From 01d5c14d3e47936eacc022c814b38c08af906ffb Mon Sep 17 00:00:00 2001 From: Charlie Fenton Date: Sat, 17 Jun 2006 00:20:46 +0000 Subject: [PATCH] *** empty log message *** svn path=/trunk/boinc/; revision=10381 --- checkin_notes | 14 +++++- client/check_security.C | 75 ++++++++++++++++++++++++--------- client/file_names.h | 2 + clientgui/mac/SetupSecurity.cpp | 40 +++++++++++++----- clientgui/mac/SetupSecurity.h | 7 +++ 5 files changed, 106 insertions(+), 32 deletions(-) diff --git a/checkin_notes b/checkin_notes index d0bd0deb8b..adc79bc6ad 100755 --- a/checkin_notes +++ b/checkin_notes @@ -6111,7 +6111,7 @@ Rom 16 June 2006 (HEAD) - Tag for 5.5.1 release, all platforms boinc_core_release_5_5_1 -Charlie 15 June 2006 +Charlie 16 June 2006 - Mac sandbox: bug fixes client/ @@ -6204,3 +6204,15 @@ David 16 June 2006 forum_thread_status.php (new) forum_thread_vote.php (new) white.css + +Charlie 16 June 2006 + - Mac sandbox: + - more debugging aids + - add SWITCHER_DIR, SWITCHER_FILE_NAME + + client/ + check_security.C + file_names.h + clientgui/ + mac/ + SetupSecurity.cpp,h diff --git a/client/check_security.C b/client/check_security.C index 07022ccf5a..c566323f1a 100644 --- a/client/check_security.C +++ b/client/check_security.C @@ -29,21 +29,16 @@ #include "util.h" #include "error_numbers.h" #include "file_names.h" +#include "SetupSecurity.h" + + +#define real_boinc_master_name "boinc_master" +#define real_boinc_project_name "boinc_project" -#ifdef _DEBUG -// GDB can't attach to applications which are running as a diferent user or group so -// it ignores the S_ISUID and S_ISGID permisison bits when launching an application. -// To work around this, the _DEBUG version uses the current user and group. static char boinc_master_user_name[64]; static char boinc_master_group_name[64]; static char boinc_project_user_name[64]; static char boinc_project_group_name[64]; -#else -#define boinc_master_user_name "boinc_master" -#define boinc_master_group_name "boinc_master" -#define boinc_project_user_name "boinc_project" -#define boinc_project_group_name "boinc_project" -#endif // Returns FALSE (0) if owners and permissions are OK, else TRUE (1) int check_security() { @@ -51,21 +46,17 @@ int check_security() { group *grp; gid_t egid, boinc_master_gid; uid_t euid, boinc_master_uid; -#ifndef _DEBUG gid_t boinc_project_gid; uid_t boinc_project_uid; int i; -#endif char dir_path[MAXPATHLEN], full_path[MAXPATHLEN]; struct stat sbuf; int retval; + char *p; #ifdef __WXMAC__ // If Mac BOINC Manager ProcessSerialNumber ourPSN; FSRef ourFSRef; #endif -#if (defined(__WXMAC__) || (! defined(_DEBUG))) - char *p; -#endif #ifdef _DEBUG // GDB can't attach to applications which are running as a diferent user or group so @@ -76,34 +67,46 @@ int check_security() { if (pw == NULL) return ERR_USER_REJECTED; // Should never happen strlcpy(boinc_master_user_name, pw->pw_name, sizeof(boinc_master_user_name)); - strlcpy(boinc_project_user_name, pw->pw_name, sizeof(boinc_project_user_name)); boinc_master_gid = getegid(); grp = getgrgid(boinc_master_gid); if (grp == NULL) return ERR_GETGRNAM; strlcpy(boinc_master_group_name, grp->gr_name, sizeof(boinc_master_group_name)); - strlcpy(boinc_project_group_name, grp->gr_name, sizeof(boinc_project_group_name)); -#else + +#else // if (! _DEBUG) + strlcpy(boinc_master_user_name, real_boinc_master_name, sizeof(boinc_master_user_name)); pw = getpwnam(boinc_master_user_name); if (pw == NULL) return ERR_USER_REJECTED; // User boinc_master does not exist boinc_master_uid = pw->pw_uid; + strlcpy(boinc_master_group_name, real_boinc_master_name, sizeof(boinc_master_group_name)); grp = getgrnam(boinc_master_group_name); if (grp == NULL) return ERR_GETGRNAM; // Group boinc_master does not exist boinc_master_gid = grp->gr_gid; +#endif // ! _DEBUG +#if (defined(_DEBUG) && defined(DEBUG_WITH_FAKE_PROJECT_USER_AND_GROUP)) + // For easier debugging of project applications + strlcpy(boinc_project_user_name, boinc_master_user_name, sizeof(boinc_project_user_name)); + strlcpy(boinc_project_group_name, boinc_master_group_name, sizeof(boinc_project_group_name)); + boinc_project_uid = boinc_master_uid; + boinc_project_gid = boinc_master_gid; +#else + strlcpy(boinc_project_user_name, real_boinc_project_name, sizeof(boinc_project_user_name)); pw = getpwnam(boinc_project_user_name); if (pw == NULL) return ERR_USER_REJECTED; // User boinc_project does not exist boinc_project_uid = pw->pw_uid; + strlcpy(boinc_project_group_name, real_boinc_project_name, sizeof(boinc_project_group_name)); grp = getgrnam(boinc_project_group_name); if (grp == NULL) return ERR_GETGRNAM; // Group boinc_project does not exist boinc_project_gid = grp->gr_gid; +#endif for (i=0; ; i++) { // Step through all users in group boinc_project p = grp->gr_mem[i]; @@ -112,7 +115,6 @@ int check_security() { if (strcmp(p, boinc_master_user_name) == 0) break; } -#endif #ifdef __WXMAC__ // If Mac BOINC Manager // Get the full path to BOINC Manager application's bundle @@ -172,14 +174,13 @@ int check_security() { // ruid = getuid(); egid = getegid(); euid = geteuid(); -#ifndef _DEBUG + if (egid != boinc_master_gid) return ERR_USER_PERMISSION; // We should be running setgid boinc_master #ifndef __WXMAC__ // If NOT Mac BOINC Manager if (euid != boinc_master_uid) return ERR_USER_PERMISSION; // BOINC Client should be running setuid boinc_master -#endif #endif getcwd(dir_path, sizeof(dir_path)); @@ -241,5 +242,37 @@ int check_security() { return ERR_USER_PERMISSION; } + strlcpy(full_path, dir_path, sizeof(dir_path)); + strlcat(full_path, "/", sizeof(full_path)); + strlcat(full_path, SWITCHER_DIR, sizeof(full_path)); + retval = stat(full_path, &sbuf); + if (retval) + return ERR_FILE_MISSING; + + if (sbuf.st_gid != boinc_master_gid) + return ERR_USER_PERMISSION; + + if (sbuf.st_uid != boinc_master_uid) + return ERR_USER_PERMISSION; + + if ((sbuf.st_mode & 0777) != 0770) + return ERR_USER_PERMISSION; + + strlcpy(full_path, dir_path, sizeof(full_path)); + strlcat(full_path, "/", sizeof(full_path)); + strlcat(full_path, SWITCHER_FILE_NAME, sizeof(full_path)); + retval = stat(full_path, &sbuf); + if (retval) + return ERR_FILE_MISSING; + + if (sbuf.st_gid != boinc_project_gid) + return ERR_USER_PERMISSION; + + if (sbuf.st_uid != boinc_project_uid) + return ERR_USER_PERMISSION; + + if ((sbuf.st_mode & 7777) != 6550) + return ERR_USER_PERMISSION; + return 0; } diff --git a/client/file_names.h b/client/file_names.h index 2aa7f98c51..8b938851ae 100644 --- a/client/file_names.h +++ b/client/file_names.h @@ -51,6 +51,7 @@ extern void get_master_filename(PROJECT&, char*); #define PROJECTS_DIR "projects" #define SLOTS_DIR "slots" +#define SWITCHER_DIR "switcher" #define STATE_FILE_NEXT "client_state_next.xml" #define STATE_FILE_NAME "client_state.xml" #define STATE_FILE_PREV "client_state_prev.xml" @@ -78,5 +79,6 @@ extern void get_master_filename(PROJECT&, char*); #define CREATE_ACCOUNT_FILENAME "create_account.xml" #define LOOKUP_WEBSITE_FILENAME "lookup_website.html" #define GET_CURRENT_VERSION_FILENAME "get_current_version.xml" +#define SWITCHER_FILE_NAME "switcher" #endif diff --git a/clientgui/mac/SetupSecurity.cpp b/clientgui/mac/SetupSecurity.cpp index 96e8c7b63d..12c5256809 100644 --- a/clientgui/mac/SetupSecurity.cpp +++ b/clientgui/mac/SetupSecurity.cpp @@ -29,6 +29,7 @@ #include +#include "file_names.h" #include "SetupSecurity.h" static OSStatus GetAuthorization(void); @@ -46,6 +47,10 @@ static AuthorizationRef gOurAuthRef = NULL; #define DELAY_TICKS 3 #define DELAY_TICKS_R 10 + +#define real_boinc_master_name "boinc_project" +#define real_boinc_project_name "boinc_project" + #ifdef _DEBUG // GDB can't attach to applications which are running as a diferent user or group so // it ignores the S_ISUID and S_ISGID permisison bits when launching an application. @@ -55,12 +60,15 @@ static char boinc_master_group_name[64]; static char boinc_project_user_name[64]; static char boinc_project_group_name[64]; #else -#define boinc_master_user_name "boinc_master" -#define boinc_master_group_name "boinc_master" -#define boinc_project_user_name "boinc_project" -#define boinc_project_group_name "boinc_project" +#define boinc_master_user_name real_boinc_master_name +#define boinc_master_group_name real_boinc_master_name +#define boinc_project_user_name real_boinc_project_name +#define boinc_project_group_name real_boinc_project_name #endif +#define real_boinc_master_name "boinc_project" +#define real_boinc_project_name "boinc_project" + #define MIN_ID 25 /* Minimum user ID / Group ID to create */ static char dsclPath[] = "/usr/bin/dscl"; @@ -286,7 +294,8 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Does projects directory exist? strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); - strlcat(fullpath, "/projects", MAXPATHLEN); + strlcat(fullpath, "/", MAXPATHLEN); + strlcat(fullpath, PROJECTS_DIR, MAXPATHLEN); result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); if ((result == noErr) && (isDirectory)) { @@ -315,7 +324,8 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Does slots directory exist? strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); - strlcat(fullpath, "/slots", MAXPATHLEN); + strlcat(fullpath, "/", MAXPATHLEN); + strlcat(fullpath, SLOTS_DIR, MAXPATHLEN); result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); if ((result == noErr) && (isDirectory)) { @@ -367,7 +377,8 @@ int SetBOINCDataOwnersGroupsAndPermissions() { // Does switcher directory exist? strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN); - strlcat(fullpath, "/switcher", MAXPATHLEN); + strlcat(fullpath, "/", MAXPATHLEN); + strlcat(fullpath, SWITCHER_DIR, MAXPATHLEN); #if 0 // Redundant if we already set contents of BOINC Data directory to boinc_master:boinc_master 0660 result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); @@ -388,8 +399,9 @@ int SetBOINCDataOwnersGroupsAndPermissions() { } // switcher directory #endif - strlcat(fullpath, "/switcher", MAXPATHLEN); - result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); + strlcat(fullpath, "/", MAXPATHLEN); + strlcat(fullpath, SWITCHER_FILE_NAME, MAXPATHLEN); + result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory); if ((result == noErr) && (! isDirectory)) { // Set owner and group of switcher application sprintf(buf1, "%s:%s", boinc_project_user_name, boinc_project_group_name); @@ -583,14 +595,22 @@ static OSStatus SetFakeMasterNames() { if (pw == NULL) return -1; // Should never happen strlcpy(boinc_master_user_name, pw->pw_name, sizeof(boinc_master_user_name)); - strlcpy(boinc_project_user_name, pw->pw_name, sizeof(boinc_project_user_name)); boinc_master_gid = getegid(); grp = getgrgid(boinc_master_gid); if (grp == NULL) return -1; strlcpy(boinc_master_group_name, grp->gr_name, sizeof(boinc_master_group_name)); + +#ifdef DEBUG_WITH_FAKE_PROJECT_USER_AND_GROUP + // For easier debugging of project applications + strlcpy(boinc_project_user_name, pw->pw_name, sizeof(boinc_project_user_name)); strlcpy(boinc_project_group_name, grp->gr_name, sizeof(boinc_project_group_name)); +#else + // For better debugging of SANDBOX permissions logic + strlcpy(boinc_project_user_name, real_boinc_project_name, sizeof(boinc_project_user_name)); + strlcpy(boinc_project_group_name, real_boinc_project_name, sizeof(boinc_project_group_name)); +#endif return noErr; } diff --git a/clientgui/mac/SetupSecurity.h b/clientgui/mac/SetupSecurity.h index 90f20b39e5..b00303bb99 100644 --- a/clientgui/mac/SetupSecurity.h +++ b/clientgui/mac/SetupSecurity.h @@ -19,6 +19,13 @@ // SetupSecurity.h +#ifdef _DEBUG +// Comment out this #define for easier debugging of project applications. +// Leave it active for better debugging of SANDBOX permissions logic. +#define DEBUG_WITH_FAKE_PROJECT_USER_AND_GROUP +#endif + + int CreateBOINCUsersAndGroups(void); int SetBOINCAppOwnersGroupsAndPermissions(char *path); int SetBOINCDataOwnersGroupsAndPermissions(void);