mirror of https://github.com/BOINC/boinc.git
*** empty log message ***
svn path=/trunk/boinc/; revision=10803
This commit is contained in:
parent
3be29b3ae9
commit
6ecd5de4d9
|
@ -8203,3 +8203,40 @@ Bruce 31 July 2006
|
|||
doc/
|
||||
project_options.php
|
||||
|
||||
Charlie 1 Aug 2006
|
||||
- Sandbox: extend security to all UNIX and Linux platforms. To
|
||||
enable this feature, add the compiler flag -DSANDBOX and add
|
||||
check_security.C to the source file list for both Manager and
|
||||
Client.
|
||||
- Manager and Client both accept command-line argument -insecure
|
||||
which runs without special boinc users and groups. Both
|
||||
Manager and Client check owners and permissions and refuse
|
||||
to run unless they are set correctly for the selected secure
|
||||
or insecure mode. If Manager is called with -insecure, it
|
||||
runs the Client with -insecure.
|
||||
- Added code to Mac_SA_Secure.sh and Mac_SA_Insecure.sh scripts.
|
||||
|
||||
client/
|
||||
app_start.C
|
||||
check_security.C
|
||||
client_state.C
|
||||
client_types.C
|
||||
cs_cmdline.C
|
||||
file_names.C
|
||||
gui_rpc_server.C
|
||||
main.C
|
||||
clientGUI/
|
||||
BOINCGUIApp.cpp,h
|
||||
MainDocument.cpp
|
||||
mac/
|
||||
Mac_GUI.cpp
|
||||
mac_saver_module.cpp
|
||||
lib/
|
||||
boinc_cmd.C
|
||||
filesys.C
|
||||
util.h
|
||||
mac_build/
|
||||
Mac_SA_Insecure.sh
|
||||
Mac_SA_Secure.sh
|
||||
mac_installer/
|
||||
PostInstall.cpp
|
||||
|
|
|
@ -90,11 +90,10 @@ static int make_link(const char *existing, const char *new_link) {
|
|||
if (!fp) return ERR_FOPEN;
|
||||
fprintf(fp, "<soft_link>%s</soft_link>\n", existing);
|
||||
fclose(fp);
|
||||
#ifdef SANDBOX
|
||||
return set_to_project_group(new_link);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
if (g_use_sandbox)
|
||||
return set_to_project_group(new_link);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ACTIVE_TASK::link_user_files() {
|
||||
|
@ -603,22 +602,22 @@ int ACTIVE_TASK::start(bool first_time) {
|
|||
char cmdline[8192];
|
||||
strcpy(cmdline, wup->command_line.c_str());
|
||||
sprintf(buf, "../../%s", exec_path );
|
||||
#ifdef SANDBOX
|
||||
char switcher_path[100];
|
||||
sprintf(switcher_path, "../../%s/%s", SWITCHER_DIR, SWITCHER_FILE_NAME);
|
||||
argv[0] = SWITCHER_FILE_NAME;
|
||||
argv[1] = buf;
|
||||
argv[2] = exec_name;
|
||||
parse_command_line(cmdline, argv+3);
|
||||
if (log_flags.task_debug) {
|
||||
debug_print_argv(argv);
|
||||
if (g_use_sandbox) {
|
||||
char switcher_path[100];
|
||||
sprintf(switcher_path, "../../%s/%s", SWITCHER_DIR, SWITCHER_FILE_NAME);
|
||||
argv[0] = SWITCHER_FILE_NAME;
|
||||
argv[1] = buf;
|
||||
argv[2] = exec_name;
|
||||
parse_command_line(cmdline, argv+3);
|
||||
if (log_flags.task_debug) {
|
||||
debug_print_argv(argv);
|
||||
}
|
||||
retval = execv(switcher_path, argv);
|
||||
} else {
|
||||
argv[0] = exec_name;
|
||||
parse_command_line(cmdline, argv+1);
|
||||
retval = execv(buf, argv);
|
||||
}
|
||||
retval = execv(switcher_path, argv);
|
||||
#else
|
||||
argv[0] = exec_name;
|
||||
parse_command_line(cmdline, argv+1);
|
||||
retval = execv(buf, argv);
|
||||
#endif
|
||||
msg_printf(wup->project, MSG_ERROR,
|
||||
"Process creation (%s) failed: %s, errno=%d\n", buf, boincerror(retval), errno
|
||||
);
|
||||
|
|
|
@ -31,7 +31,11 @@
|
|||
#include "error_numbers.h"
|
||||
#include "file_names.h"
|
||||
|
||||
static int CheckNestedDirectories(char * basepath, int depth);
|
||||
static int CheckNestedDirectories(char * basepath, int depth, int use_sandbox);
|
||||
|
||||
#if (! defined(__WXMAC__) && ! defined(_MAC_INSTALLER))
|
||||
static void GetPathToThisProcess(char* outbuf, size_t maxLen);
|
||||
#endif
|
||||
|
||||
#define REAL_BOINC_MASTER_NAME "boinc_master"
|
||||
#define REAL_BOINC_PROJECT_NAME "boinc_project"
|
||||
|
@ -50,8 +54,9 @@ static uid_t boinc_master_uid, boinc_project_uid;
|
|||
// Returns FALSE (0) if owners and permissions are OK, else TRUE (1)
|
||||
int check_security(
|
||||
#ifdef _MAC_INSTALLER
|
||||
char *bundlePath, char *dataPath
|
||||
char *bundlePath, char *dataPath,
|
||||
#endif
|
||||
int use_sandbox, int isManager
|
||||
) {
|
||||
passwd *pw;
|
||||
group *grp;
|
||||
|
@ -60,6 +65,7 @@ char *bundlePath, char *dataPath
|
|||
char dir_path[MAXPATHLEN], full_path[MAXPATHLEN];
|
||||
struct stat sbuf;
|
||||
int retval;
|
||||
int useFakeProjectUserAndGroup = 0;
|
||||
#ifdef __WXMAC__ // If Mac BOINC Manager
|
||||
ProcessSerialNumber ourPSN;
|
||||
ProcessInfoRec pInfo;
|
||||
|
@ -68,7 +74,12 @@ char *bundlePath, char *dataPath
|
|||
#endif
|
||||
#ifdef _MAC_INSTALLER
|
||||
char *p;
|
||||
#else
|
||||
#endif
|
||||
|
||||
#if (defined(_DEBUG) && defined(DEBUG_WITH_FAKE_PROJECT_USER_AND_GROUP))
|
||||
useFakeProjectUserAndGroup = 1;
|
||||
#else
|
||||
useFakeProjectUserAndGroup = ! use_sandbox;
|
||||
#endif
|
||||
|
||||
// GDB can't attach to applications which are running as a diferent user or group so
|
||||
|
@ -97,32 +108,38 @@ char *bundlePath, char *dataPath
|
|||
retval = FSRefMakePath (&ourFSRef, (UInt8*)dir_path, sizeof(dir_path));
|
||||
if (retval)
|
||||
return -1003; // Should never happen
|
||||
#endif
|
||||
|
||||
#ifdef _MAC_INSTALLER
|
||||
#elif defined (_MAC_INSTALLER)
|
||||
strlcpy(dir_path, bundlePath, sizeof(dir_path));
|
||||
#endif
|
||||
|
||||
#if (defined(__WXMAC__) || defined(_MAC_INSTALLER)) // If Mac BOINC Manager or installer
|
||||
// Get the full path to BOINC Clients inside this application's bundle
|
||||
strlcpy(full_path, dir_path, sizeof(full_path));
|
||||
strlcat(full_path, "/Contents/Resources/boinc", sizeof(full_path));
|
||||
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (retval)
|
||||
return -1004; // Should never happen
|
||||
|
||||
if ((sbuf.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID))
|
||||
return -1005;
|
||||
|
||||
boinc_master_uid = sbuf.st_gid;
|
||||
boinc_master_gid = sbuf.st_uid;
|
||||
if (use_sandbox) {
|
||||
#if (defined(__WXMAC__) || defined(_MAC_INSTALLER)) // If called from Mac BOINC Manager or installer
|
||||
// Get the full path to BOINC Client inside this application's bundle
|
||||
strlcpy(full_path, dir_path, sizeof(full_path));
|
||||
strlcat(full_path, "/Contents/Resources/boinc", sizeof(full_path));
|
||||
#else
|
||||
boinc_master_uid = geteuid();
|
||||
boinc_master_gid = getegid();
|
||||
|
||||
if (isManager) { // If called from BOINC Manager but not on Mac
|
||||
getcwd(full_path, sizeof(full_path)); // Assume Client is in current directory
|
||||
strlcat(full_path, "/boinc", sizeof(full_path));
|
||||
} else // If called from BOINC Client
|
||||
GetPathToThisProcess(full_path, sizeof(full_path));
|
||||
#endif
|
||||
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (retval)
|
||||
return -1004; // Should never happen
|
||||
|
||||
if ((sbuf.st_mode & (S_ISUID | S_ISGID)) != (S_ISUID | S_ISGID))
|
||||
return -1005;
|
||||
|
||||
boinc_master_uid = sbuf.st_gid;
|
||||
boinc_master_gid = sbuf.st_uid;
|
||||
} else {
|
||||
boinc_master_uid = geteuid();
|
||||
boinc_master_gid = getegid();
|
||||
|
||||
}
|
||||
|
||||
#ifdef _MAC_INSTALLER
|
||||
// Require absolute owner and group boinc_master:boinc_master
|
||||
strlcpy(boinc_master_user_name, REAL_BOINC_MASTER_NAME, sizeof(boinc_master_user_name));
|
||||
|
@ -151,25 +168,25 @@ char *bundlePath, char *dataPath
|
|||
|
||||
#endif
|
||||
|
||||
#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 -1010; // User boinc_project does not exist
|
||||
boinc_project_uid = pw->pw_uid;
|
||||
if (useFakeProjectUserAndGroup) {
|
||||
// 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 -1010; // 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 -1011; // Group boinc_project does not exist
|
||||
boinc_project_gid = grp->gr_gid;
|
||||
#endif
|
||||
strlcpy(boinc_project_group_name, REAL_BOINC_PROJECT_NAME, sizeof(boinc_project_group_name));
|
||||
grp = getgrnam(boinc_project_group_name);
|
||||
if (grp == NULL)
|
||||
return -1011; // Group boinc_project does not exist
|
||||
boinc_project_gid = grp->gr_gid;
|
||||
}
|
||||
|
||||
#if (defined(__WXMAC__) || defined(_MAC_INSTALLER)) // If Mac BOINC Manager or installer
|
||||
// Get the full path to BOINC Manager executable inside this application's bundle
|
||||
|
@ -191,13 +208,15 @@ char *bundlePath, char *dataPath
|
|||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1014;
|
||||
|
||||
if ((sbuf.st_mode & S_ISGID) != S_ISGID)
|
||||
return -1015;
|
||||
if (use_sandbox) {
|
||||
if ((sbuf.st_mode & S_ISGID) != S_ISGID)
|
||||
return -1015;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MAC_INSTALLER
|
||||
// Require absolute owner and group boinc_master:boinc_master
|
||||
// Get the full path to BOINC Clients inside this application's bundle
|
||||
// Get the full path to BOINC Client inside this application's bundle
|
||||
strlcpy(full_path, dir_path, sizeof(full_path));
|
||||
strlcat(full_path, "/Contents/Resources/boinc", sizeof(full_path));
|
||||
|
||||
|
@ -217,49 +236,59 @@ char *bundlePath, char *dataPath
|
|||
egid = getegid();
|
||||
euid = geteuid();
|
||||
|
||||
#ifndef _MAC_INSTALLER
|
||||
#ifdef _MAC_INSTALLER
|
||||
strlcpy(dir_path, dataPath, sizeof(dir_path)); // Installer
|
||||
#else // _MAC_INSTALLER
|
||||
getcwd(dir_path, sizeof(dir_path)); // Client or Manager
|
||||
|
||||
if (egid != boinc_master_gid)
|
||||
return -1019; // Client or Manager should be running setgid boinc_master
|
||||
|
||||
#ifndef __WXMAC__ // If BOINC Client
|
||||
if (euid != boinc_master_uid)
|
||||
return -1020; // BOINC Client should be running setuid boinc_master
|
||||
if (! isManager) // If BOINC Client
|
||||
if (euid != boinc_master_uid)
|
||||
return -1020; // BOINC Client should be running setuid boinc_master
|
||||
#endif
|
||||
|
||||
getcwd(dir_path, sizeof(dir_path)); // Client or Manager
|
||||
#else // _MAC_INSTALLER
|
||||
strlcpy(dir_path, dataPath, sizeof(dir_path)); // Installer
|
||||
#endif // _MAC_INSTALLER
|
||||
|
||||
retval = stat(dir_path, &sbuf);
|
||||
if (retval)
|
||||
return -1021; // Should never happen
|
||||
|
||||
if (use_sandbox) {
|
||||
|
||||
// The top-level BOINC Data directory can have a different user if created by the Manager,
|
||||
// but it should always have group boinc_master.
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1022;
|
||||
|
||||
// The top-level BOINC Data directory can have a different user if created by the Manager,
|
||||
// but it should always have group boinc_master.
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1022;
|
||||
|
||||
// The top-level BOINC Data directory should have permission 775 or 575
|
||||
if ((sbuf.st_mode & 0577) != 0575)
|
||||
return -1023;
|
||||
// The top-level BOINC Data directory should have permission 775 or 575
|
||||
if ((sbuf.st_mode & 0577) != 0575)
|
||||
return -1023;
|
||||
|
||||
} else {
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1022;
|
||||
|
||||
}
|
||||
|
||||
strlcpy(full_path, dir_path, sizeof(full_path));
|
||||
strlcat(full_path, "/", sizeof(full_path));
|
||||
strlcat(full_path, PROJECTS_DIR, sizeof(full_path));
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (! retval) { // Client can create projects directory if it does not yet exist.
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1024;
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1025;
|
||||
if (use_sandbox) {
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1024;
|
||||
|
||||
if ((sbuf.st_mode & 0777) != 0775)
|
||||
return -1025;
|
||||
}
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1026;
|
||||
|
||||
// Step through project directories
|
||||
retval = CheckNestedDirectories(full_path, 1);
|
||||
retval = CheckNestedDirectories(full_path, 1, use_sandbox);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
@ -269,17 +298,19 @@ char *bundlePath, char *dataPath
|
|||
strlcat(full_path, SLOTS_DIR, sizeof(full_path));
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (! retval) { // Client can create slots directory if it does not yet exist.
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1027;
|
||||
if (use_sandbox) {
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1027;
|
||||
|
||||
if ((sbuf.st_mode & 0777) != 0775)
|
||||
return -1028;
|
||||
}
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1028;
|
||||
|
||||
if ((sbuf.st_mode & 0777) != 0775)
|
||||
return -1029;
|
||||
|
||||
// Step through slot directories
|
||||
retval = CheckNestedDirectories(full_path, 1);
|
||||
retval = CheckNestedDirectories(full_path, 1, use_sandbox);
|
||||
if (retval)
|
||||
return retval;
|
||||
}
|
||||
|
@ -289,71 +320,78 @@ char *bundlePath, char *dataPath
|
|||
strlcat(full_path, GUI_RPC_PASSWD_FILE, sizeof(full_path));
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (! retval) { // Client can create RPC password file if it does not yet exist.
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1030;
|
||||
if (use_sandbox) {
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1030;
|
||||
|
||||
if ((sbuf.st_mode & 0777) != 0660)
|
||||
return -1032;
|
||||
} else {
|
||||
if ((sbuf.st_mode & 0717) != 0600)
|
||||
return -1032;
|
||||
}
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1031;
|
||||
|
||||
if ((sbuf.st_mode & 0777) != 0660)
|
||||
return -1032;
|
||||
}
|
||||
|
||||
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 -1033;
|
||||
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1034;
|
||||
if (use_sandbox) {
|
||||
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 -1033;
|
||||
|
||||
if (sbuf.st_gid != boinc_master_gid)
|
||||
return -1034;
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1035;
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1035;
|
||||
|
||||
if ((sbuf.st_mode & 0777) != 0550)
|
||||
return -1036;
|
||||
if ((sbuf.st_mode & 0777) != 0550)
|
||||
return -1036;
|
||||
|
||||
strlcat(full_path, "/", sizeof(full_path));
|
||||
strlcat(full_path, SWITCHER_FILE_NAME, sizeof(full_path));
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (retval)
|
||||
return -1037;
|
||||
strlcat(full_path, "/", sizeof(full_path));
|
||||
strlcat(full_path, SWITCHER_FILE_NAME, sizeof(full_path));
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (retval)
|
||||
return -1037;
|
||||
|
||||
if (sbuf.st_gid != boinc_project_gid)
|
||||
return -1038;
|
||||
|
||||
if (sbuf.st_uid != boinc_project_uid)
|
||||
return -1039;
|
||||
|
||||
if ((sbuf.st_mode & 07777) != 06551)
|
||||
return -1040;
|
||||
|
||||
strlcpy(full_path, dir_path, sizeof(dir_path));
|
||||
strlcat(full_path, "/", sizeof(full_path));
|
||||
strlcat(full_path, SWITCHER_DIR, sizeof(full_path));
|
||||
|
||||
strlcat(full_path, "/", sizeof(full_path));
|
||||
strlcat(full_path, SETPROJECTGRP_FILE_NAME, sizeof(full_path));
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (retval)
|
||||
return -1041;
|
||||
|
||||
if (sbuf.st_gid != boinc_project_gid)
|
||||
return -1042;
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1043;
|
||||
|
||||
if ((sbuf.st_mode & 07777) != 02500)
|
||||
return -1044;
|
||||
} // if (use_sandbox)
|
||||
|
||||
if (sbuf.st_gid != boinc_project_gid)
|
||||
return -1038;
|
||||
|
||||
if (sbuf.st_uid != boinc_project_uid)
|
||||
return -1039;
|
||||
|
||||
if ((sbuf.st_mode & 07777) != 06551)
|
||||
return -1040;
|
||||
|
||||
strlcpy(full_path, dir_path, sizeof(dir_path));
|
||||
strlcat(full_path, "/", sizeof(full_path));
|
||||
strlcat(full_path, SWITCHER_DIR, sizeof(full_path));
|
||||
|
||||
strlcat(full_path, "/", sizeof(full_path));
|
||||
strlcat(full_path, SETPROJECTGRP_FILE_NAME, sizeof(full_path));
|
||||
retval = stat(full_path, &sbuf);
|
||||
if (retval)
|
||||
return -1041;
|
||||
|
||||
if (sbuf.st_gid != boinc_project_gid)
|
||||
return -1042;
|
||||
|
||||
if (sbuf.st_uid != boinc_master_uid)
|
||||
return -1043;
|
||||
|
||||
if ((sbuf.st_mode & 07777) != 02500)
|
||||
return -1044;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int CheckNestedDirectories(char * basepath, int depth) {
|
||||
static int CheckNestedDirectories(char * basepath, int depth, int use_sandbox) {
|
||||
int isDirectory;
|
||||
char full_path[MAXPATHLEN];
|
||||
struct stat sbuf;
|
||||
|
@ -383,11 +421,6 @@ static int CheckNestedDirectories(char * basepath, int depth) {
|
|||
|
||||
isDirectory = S_ISDIR(sbuf.st_mode);
|
||||
|
||||
if (sbuf.st_gid != boinc_project_gid) {
|
||||
retval = -1201;
|
||||
break;
|
||||
}
|
||||
|
||||
if (depth > 1) {
|
||||
// files and subdirectories created by projects may have owner boinc_master or boinc_project
|
||||
if ( (sbuf.st_uid != boinc_master_uid) && (sbuf.st_uid != boinc_project_uid) ) {
|
||||
|
@ -395,7 +428,7 @@ static int CheckNestedDirectories(char * basepath, int depth) {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
// project & slot directories (projets/setiathome.berkeley.edu, slots/0 etc.)
|
||||
// project & slot directories (projects/setiathome.berkeley.edu, slots/0 etc.)
|
||||
// must have owner boinc_master
|
||||
if (sbuf.st_uid != boinc_master_uid) {
|
||||
retval = -1202;
|
||||
|
@ -403,38 +436,45 @@ static int CheckNestedDirectories(char * basepath, int depth) {
|
|||
}
|
||||
}
|
||||
|
||||
if (isDirectory) {
|
||||
if (depth == 1) {
|
||||
// project & slot directories (projets/setiathome.berkeley.edu, slots/0 etc.)
|
||||
// must be readable & executable by other
|
||||
if ((sbuf.st_mode & 0777) != 0775) {
|
||||
retval = -1203;
|
||||
if (use_sandbox) {
|
||||
if (sbuf.st_gid != boinc_project_gid) {
|
||||
retval = -1201;
|
||||
break;
|
||||
}
|
||||
#if 0 // We may enforce permissions later for subdirectories written by project applications
|
||||
} else {
|
||||
// subdirectories created by projects may be executable by other or not
|
||||
if ((sbuf.st_mode & 0770) != 0770) {
|
||||
retval = -1203;
|
||||
|
||||
if (isDirectory) {
|
||||
if (depth == 1) {
|
||||
// project & slot directories (projects/setiathome.berkeley.edu, slots/0 etc.)
|
||||
// must be readable & executable by other
|
||||
if ((sbuf.st_mode & 0777) != 0775) {
|
||||
retval = -1203;
|
||||
break;
|
||||
}
|
||||
#if 0 // We may enforce permissions later for subdirectories written by project applications
|
||||
} else {
|
||||
// subdirectories created by projects may be executable by other or not
|
||||
if ((sbuf.st_mode & 0770) != 0770) {
|
||||
retval = -1203;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0 // We may enforce permissions later for files written by project applications
|
||||
} else { // ! isDirectory
|
||||
if ((sbuf.st_mode & 0666) != 0660) {
|
||||
retval = -1204;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if 0 // We may enforce permissions later for files written by project applications
|
||||
} else { // ! isDirectory
|
||||
if ((sbuf.st_mode & 0666) != 0660) {
|
||||
retval = -1204;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} // if (use_sandbox)
|
||||
|
||||
if (isDirectory) {
|
||||
if (depth > 1)
|
||||
if (use_sandbox && (depth > 1))
|
||||
if ((sbuf.st_uid != boinc_master_uid) && (sbuf.st_gid != boinc_master_gid))
|
||||
continue; // We can't check subdirectories owned by boinc_project
|
||||
|
||||
retval = CheckNestedDirectories(full_path, depth + 1);
|
||||
retval = CheckNestedDirectories(full_path, depth + 1, use_sandbox);
|
||||
if (retval)
|
||||
break;
|
||||
}
|
||||
|
@ -445,3 +485,37 @@ static int CheckNestedDirectories(char * basepath, int depth) {
|
|||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
#if (! defined(__WXMAC__) && ! defined(_MAC_INSTALLER))
|
||||
static void GetPathToThisProcess(char* outbuf, size_t maxLen) {
|
||||
FILE *f;
|
||||
char buf[256], *p, *q;
|
||||
pid_t aPID = getpid();
|
||||
|
||||
*outbuf = '\0';
|
||||
|
||||
sprintf(buf, "ps -xwo command -p %d", (int)aPID);
|
||||
f = popen(buf, "r");
|
||||
if (f == NULL)
|
||||
return;
|
||||
|
||||
fgets (outbuf, maxLen, f); // Discard header line
|
||||
fgets (outbuf, maxLen, f);
|
||||
pclose(f);
|
||||
|
||||
// Strip off any arguments
|
||||
p = strstr(outbuf, " -");
|
||||
q = p;
|
||||
if (p) {
|
||||
while (*p == ' ') {
|
||||
q = p;
|
||||
if (--p < outbuf)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (q)
|
||||
*q = '\0';
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -106,6 +106,11 @@ CLIENT_STATE::CLIENT_STATE() {
|
|||
have_tentative_project = false;
|
||||
new_version_check_time = 0;
|
||||
detach_console = false;
|
||||
#ifdef SANDBOX
|
||||
g_use_sandbox = true; // User can override with -insecure command-line arg
|
||||
#else
|
||||
g_use_sandbox = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CLIENT_STATE::show_host_info() {
|
||||
|
@ -309,16 +314,16 @@ int CLIENT_STATE::init() {
|
|||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef SANDBOX
|
||||
if (g_use_sandbox) {
|
||||
#ifdef _DEBUG
|
||||
boinc_project_gid = getegid();
|
||||
boinc_project_gid = getegid();
|
||||
#else
|
||||
retval = lookup_group(BOINC_PROJECT_GROUP_NAME, boinc_project_gid);
|
||||
if (retval) return retval;
|
||||
retval = lookup_group(BOINC_PROJECT_GROUP_NAME, boinc_project_gid);
|
||||
if (retval) return retval;
|
||||
#endif // _DEBUG
|
||||
#else
|
||||
boinc_project_gid = 0;
|
||||
#endif
|
||||
} else {
|
||||
boinc_project_gid = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
check_file_existence();
|
||||
|
|
|
@ -613,37 +613,37 @@ int FILE_INFO::set_permissions() {
|
|||
// give read/exec permissions for user, group and others
|
||||
// in case someone runs BOINC from different user
|
||||
|
||||
#ifdef SANDBOX
|
||||
retval = set_to_project_group(pathname);
|
||||
if (retval) return retval;
|
||||
if (executable) {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
if (g_use_sandbox) {
|
||||
retval = set_to_project_group(pathname);
|
||||
if (retval) return retval;
|
||||
if (executable) {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
} else {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR
|
||||
|S_IRGRP|S_IWGRP
|
||||
|S_IROTH
|
||||
);
|
||||
}
|
||||
} else {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR
|
||||
|S_IRGRP|S_IWGRP
|
||||
|S_IROTH
|
||||
);
|
||||
if (executable) {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
} else {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR
|
||||
|S_IRGRP
|
||||
|S_IROTH
|
||||
);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (executable) {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
} else {
|
||||
retval = chmod(pathname,
|
||||
S_IRUSR|S_IWUSR
|
||||
|S_IRGRP
|
||||
|S_IROTH
|
||||
);
|
||||
}
|
||||
#endif
|
||||
return retval;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ static void print_options(char* prog) {
|
|||
" -dir <path> use given dir as BOINC home\n"
|
||||
" -no_gui_rpc don't allow GUI RPC, don't make socket\n"
|
||||
" -daemon run as daemon (Unix)\n"
|
||||
" -insecure disable BOINC security users and permissions (Unix, Linux)\n"
|
||||
,
|
||||
prog
|
||||
);
|
||||
|
@ -174,6 +175,8 @@ void CLIENT_STATE::parse_cmdline(int argc, char** argv) {
|
|||
}
|
||||
} else if (ARG(no_gui_rpc)) {
|
||||
no_gui_rpc = true;
|
||||
} else if (ARG(insecure)) {
|
||||
g_use_sandbox = false;
|
||||
} else {
|
||||
printf("Unknown option: %s\n", argv[i]);
|
||||
show_options = true;
|
||||
|
|
|
@ -95,23 +95,23 @@ int make_project_dir(PROJECT& p) {
|
|||
int retval;
|
||||
|
||||
boinc_mkdir(PROJECTS_DIR);
|
||||
#ifdef SANDBOX
|
||||
chmod(PROJECTS_DIR,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
#endif
|
||||
if (g_use_sandbox) {
|
||||
chmod(PROJECTS_DIR,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
}
|
||||
get_project_dir(&p, buf);
|
||||
retval = boinc_mkdir(buf);
|
||||
#ifdef SANDBOX
|
||||
chmod(buf,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
set_to_project_group(buf);
|
||||
#endif
|
||||
if (g_use_sandbox) {
|
||||
chmod(buf,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
set_to_project_group(buf);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -137,23 +137,23 @@ int make_slot_dir(int slot) {
|
|||
return ERR_NEG;
|
||||
}
|
||||
boinc_mkdir(SLOTS_DIR);
|
||||
#ifdef SANDBOX
|
||||
chmod(SLOTS_DIR,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
#endif
|
||||
if (g_use_sandbox) {
|
||||
chmod(SLOTS_DIR,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
}
|
||||
get_slot_dir(slot, buf);
|
||||
int retval = boinc_mkdir(buf);
|
||||
#ifdef SANDBOX
|
||||
chmod(buf,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
set_to_project_group(buf);
|
||||
#endif
|
||||
if (g_use_sandbox) {
|
||||
chmod(buf,
|
||||
S_IRUSR|S_IWUSR|S_IXUSR
|
||||
|S_IRGRP|S_IWGRP|S_IXGRP
|
||||
|S_IROTH|S_IXOTH
|
||||
);
|
||||
set_to_project_group(buf);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -261,17 +261,14 @@ bool is_image_file(const char* filename) {
|
|||
}
|
||||
|
||||
int set_to_project_group(const char* path) {
|
||||
#ifdef SANDBOX
|
||||
char buf[1024];
|
||||
|
||||
sprintf(buf, "%s/%s %s", SWITCHER_DIR, SETPROJECTGRP_FILE_NAME, path);
|
||||
if (system(buf))
|
||||
return ERR_CHOWN;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return ERR_CHOWN;
|
||||
#endif
|
||||
if (g_use_sandbox) {
|
||||
sprintf(buf, "%s/%s %s", SWITCHER_DIR, SETPROJECTGRP_FILE_NAME, path);
|
||||
if (system(buf))
|
||||
return ERR_CHOWN;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *BOINC_RCSID_7d362a6a52 = "$Id$";
|
||||
|
|
|
@ -104,12 +104,12 @@ int GUI_RPC_CONN_SET::get_password() {
|
|||
// they can cause code to execute as this user.
|
||||
// So better protect it.
|
||||
//
|
||||
#ifdef SANDBOX
|
||||
// Allow group access so authorized administrator can modify it
|
||||
chmod(GUI_RPC_PASSWD_FILE, S_IRUSR|S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
#else
|
||||
chmod(GUI_RPC_PASSWD_FILE, S_IRUSR|S_IWUSR);
|
||||
#endif
|
||||
if (g_use_sandbox) {
|
||||
// Allow group access so authorized administrator can modify it
|
||||
chmod(GUI_RPC_PASSWD_FILE, S_IRUSR|S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
} else {
|
||||
chmod(GUI_RPC_PASSWD_FILE, S_IRUSR|S_IWUSR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,6 +78,12 @@ typedef void (CALLBACK* ClientLibraryShutdown)();
|
|||
|
||||
int finalize();
|
||||
|
||||
// Ideally, we would access this using wxGetApp().m_use_sandbox in the Manager
|
||||
// and gstate.m_use_sandbox in the Client, but it is used by some source files
|
||||
// (filesys.C, check_security.C) that are linked with both Manager and Client
|
||||
// so the most practical solution is to use a global.
|
||||
int g_use_sandbox;
|
||||
|
||||
static bool boinc_cleanup_completed = false;
|
||||
// Used on Windows 95/98/ME to determine when it is safe to leave
|
||||
// the WM_ENDSESSION message handler and allow Windows to finish
|
||||
|
@ -335,15 +341,17 @@ static void init_core_client(int argc, char** argv) {
|
|||
}
|
||||
|
||||
#else
|
||||
#ifdef SANDBOX
|
||||
umask (2); // Set file creation mask to be writable by both user and group
|
||||
// Our umask will be inherited by all our child processes
|
||||
#endif
|
||||
#endif
|
||||
|
||||
read_config_file();
|
||||
gstate.parse_cmdline(argc, argv);
|
||||
|
||||
#ifndef _WIN32
|
||||
if (g_use_sandbox)
|
||||
umask (2); // Set file creation mask to be writable by both user and group
|
||||
// Our umask will be inherited by all our child processes
|
||||
#endif
|
||||
|
||||
// Initialize the BOINC Diagnostics Framework
|
||||
int dwDiagnosticsFlags =
|
||||
BOINC_DIAG_DUMPCALLSTACKENABLED |
|
||||
|
@ -752,13 +760,14 @@ int main(int argc, char** argv) {
|
|||
#else
|
||||
|
||||
#ifdef SANDBOX
|
||||
// Make sure owners, groups and permissions are correct for the current setting of g_use_sandbox
|
||||
#if defined(_DEBUG) && defined(__APPLE__)
|
||||
// GDB can't attach to applications which are running as a diferent user
|
||||
// or group, so fix up data with current user and group during debugging
|
||||
if (check_security())
|
||||
// GDB can't attach to applications which are running as a diferent user
|
||||
// or group, so fix up data with current user and group during debugging
|
||||
if (check_security(g_use_sandbox, false))
|
||||
SetBOINCDataOwnersGroupsAndPermissions();
|
||||
#endif // _DEBUG && __APPLE__
|
||||
int i = check_security();
|
||||
int i = check_security(g_use_sandbox, false);
|
||||
if (i) {
|
||||
printf( "\nBOINC ownership or permissions are not set properly; please reinstall BOINC. (Error code %d)\n", i);
|
||||
return ERR_USER_PERMISSION;
|
||||
|
|
|
@ -87,6 +87,13 @@ EXTERN_C DWORD BOINCGetIdleTickCount();
|
|||
IMPLEMENT_APP(CBOINCGUIApp)
|
||||
IMPLEMENT_DYNAMIC_CLASS(CBOINCGUIApp, wxApp)
|
||||
|
||||
// Ideally, we would access this using wxGetApp().m_use_sandbox in the Manager
|
||||
// and gstate.m_use_sandbox in the Client, but it is used by some source files
|
||||
// (filesys.C, check_security.C) that are linked with both Manager and Client
|
||||
// so the most practical solution is to use a global.
|
||||
int g_use_sandbox;
|
||||
|
||||
|
||||
|
||||
bool CBrandingScheme::OnInit( wxConfigBase *pConfig ) {
|
||||
wxString strBaseConfigLocation = wxEmptyString;
|
||||
|
@ -260,9 +267,19 @@ bool CBOINCGUIApp::OnInit() {
|
|||
int errCode = 0;
|
||||
#endif
|
||||
|
||||
#if (defined(SANDBOX) && !defined(_WIN32))
|
||||
umask (2); // Set file creation mask to be writable by both user and group
|
||||
// Our umask will be inherited by all our child processes
|
||||
#ifdef SANDBOX
|
||||
g_use_sandbox = true;
|
||||
// Commandline parsing is done in wxApp::OnInit()
|
||||
if (!wxApp::OnInit()) { // Command line arg -insecure sets g_use_sandbox to false
|
||||
return false;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
if (g_use_sandbox)
|
||||
umask (2); // Set file creation mask to be writable by both user and group
|
||||
// Our umask will be inherited by all our child processes
|
||||
#endif
|
||||
#else
|
||||
g_use_sandbox = false;
|
||||
#endif
|
||||
|
||||
// Setup variables with default values
|
||||
|
@ -341,10 +358,10 @@ bool CBOINCGUIApp::OnInit() {
|
|||
if (success) {
|
||||
// If SetWD failed, don't create a directory in wrong place
|
||||
strDirectory += wxT("BOINC Data"); // We don't customize BOINC Data directory name for branding
|
||||
#ifndef SANDBOX
|
||||
if (! wxDirExists(strDirectory))
|
||||
success = wxMkdir(strDirectory, 0777); // Does nothing if dir exists
|
||||
#endif // ! SANDBOX
|
||||
if (! g_use_sandbox) {
|
||||
if (! wxDirExists(strDirectory))
|
||||
success = wxMkdir(strDirectory, 0777); // Does nothing if dir exists
|
||||
}
|
||||
success = ::wxSetWorkingDirectory(strDirectory);
|
||||
// wxChar *wd = wxGetWorkingDirectory(buf, 1000); // For debugging
|
||||
}
|
||||
|
@ -354,17 +371,18 @@ bool CBOINCGUIApp::OnInit() {
|
|||
#endif // __WXMAC__
|
||||
|
||||
#ifdef SANDBOX
|
||||
// Make sure owners, groups and permissions are correct for the current setting of g_use_sandbox
|
||||
if (!errCode) {
|
||||
#if (defined(__WXMAC__) && defined(_DEBUG)) // TODO: implement this for other platforms
|
||||
// GDB can't attach to applications which are running as a different user
|
||||
// or group, so fix up data with current user and group during debugging
|
||||
if (check_security()) {
|
||||
if (check_security(g_use_sandbox, true)) {
|
||||
CreateBOINCUsersAndGroups();
|
||||
SetBOINCDataOwnersGroupsAndPermissions();
|
||||
SetBOINCAppOwnersGroupsAndPermissions(NULL);
|
||||
}
|
||||
#endif // __WXMAC__ && _DEBUG
|
||||
errCode = check_security();
|
||||
errCode = check_security(g_use_sandbox, true);
|
||||
}
|
||||
|
||||
if (errCode) {
|
||||
|
@ -424,10 +442,12 @@ bool CBOINCGUIApp::OnInit() {
|
|||
// help if you use this help provider:
|
||||
wxHelpProvider::Set(new wxHelpControllerHelpProvider());
|
||||
|
||||
#ifndef SANDBOX
|
||||
// Commandline parsing is done in wxApp::OnInit()
|
||||
if (!wxApp::OnInit()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize the main document
|
||||
m_pDocument = new CMainDocument();
|
||||
|
@ -543,6 +563,9 @@ void CBOINCGUIApp::OnInitCmdLine(wxCmdLineParser &parser) {
|
|||
wxApp::OnInitCmdLine(parser);
|
||||
static const wxCmdLineEntryDesc cmdLineDesc[] = {
|
||||
{ wxCMD_LINE_SWITCH, wxT("s"), wxT("systray"), _("Startup BOINC so only the system tray icon is visible")},
|
||||
#if (defined(SANDBOX) && ! defined(_WIN32))
|
||||
{ wxCMD_LINE_SWITCH, wxT("insecure"), wxT("insecure"), _("disable BOINC security users and permissions")},
|
||||
#endif
|
||||
{ wxCMD_LINE_NONE} //DON'T forget this line!!
|
||||
};
|
||||
parser.SetDesc(cmdLineDesc);
|
||||
|
@ -555,6 +578,9 @@ bool CBOINCGUIApp::OnCmdLineParsed(wxCmdLineParser &parser) {
|
|||
if (parser.Found(wxT("systray"))) {
|
||||
m_bGUIVisible = false;
|
||||
}
|
||||
if (parser.Found(wxT("insecure"))) {
|
||||
g_use_sandbox = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -686,7 +712,7 @@ void CBOINCGUIApp::StartupBOINCCore() {
|
|||
|
||||
{
|
||||
wxChar buf[1024];
|
||||
wxChar *argv[3];
|
||||
wxChar *argv[4];
|
||||
ProcessSerialNumber ourPSN;
|
||||
FSRef ourFSRef;
|
||||
OSErr err;
|
||||
|
@ -710,6 +736,12 @@ void CBOINCGUIApp::StartupBOINCCore() {
|
|||
argv[0] = buf;
|
||||
argv[1] = "-redirectio";
|
||||
argv[2] = NULL;
|
||||
#ifdef SANDBOX
|
||||
if (! g_use_sandbox) {
|
||||
argv[2] = "-insecure";
|
||||
argv[3] = NULL;
|
||||
}
|
||||
#endif
|
||||
m_lBOINCCoreProcessId = ::wxExecute(argv);
|
||||
#endif
|
||||
} else {
|
||||
|
@ -772,6 +804,8 @@ void CBOINCGUIApp::StartupBOINCCore() {
|
|||
|
||||
// Append boinc.exe to the end of the strExecute string and get ready to rock
|
||||
strExecute = wxT("./boinc -redirectio");
|
||||
if (! g_use_sandbox)
|
||||
strExecute += wxT(" -insecure");
|
||||
m_lBOINCCoreProcessId = ::wxExecute(strExecute);
|
||||
|
||||
#endif // ! __WXMAC__
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#define BOINC_ADVANCEDGUI 1
|
||||
#define BOINC_SIMPLEGUI 2
|
||||
|
||||
|
||||
class CBrandingScheme : public wxObject {
|
||||
private:
|
||||
bool m_bIsBranded;
|
||||
|
|
|
@ -21,16 +21,17 @@
|
|||
#pragma implementation "MainDocument.h"
|
||||
#endif
|
||||
|
||||
#ifdef SANDBOX
|
||||
#include <grp.h>
|
||||
#endif
|
||||
|
||||
#include "stdwx.h"
|
||||
#include "BOINCGUIApp.h"
|
||||
#include "BOINCBaseFrame.h"
|
||||
#include "MainDocument.h"
|
||||
#include "error_numbers.h"
|
||||
|
||||
#ifdef SANDBOX
|
||||
#include <grp.h>
|
||||
#include "util.h" // For g_use_sandbox
|
||||
#endif
|
||||
|
||||
using std::string;
|
||||
|
||||
CNetworkConnection::CNetworkConnection(CMainDocument* pDocument) :
|
||||
|
@ -594,43 +595,47 @@ int CMainDocument::CoreClientQuit() {
|
|||
|
||||
|
||||
bool CMainDocument::IsUserAuthorized() {
|
||||
#ifdef SANDBOX
|
||||
#ifdef _WIN32
|
||||
return true;
|
||||
#else // ! _WIN32
|
||||
group *grp;
|
||||
gid_t rgid, boinc_master_gid;
|
||||
char *userName, *groupMember;
|
||||
int i;
|
||||
static bool sIsAuthorized = false;
|
||||
|
||||
if (sIsAuthorized)
|
||||
return true; // We already checked and OK'd current user
|
||||
|
||||
grp = getgrnam(BOINC_MASTER_GROUP_NAME);
|
||||
if (grp) {
|
||||
boinc_master_gid = grp->gr_gid;
|
||||
#ifdef SANDBOX
|
||||
group *grp;
|
||||
gid_t rgid, boinc_master_gid;
|
||||
char *userName, *groupMember;
|
||||
int i;
|
||||
|
||||
rgid = getgid();
|
||||
if (rgid == boinc_master_gid) {
|
||||
sIsAuthorized = true; // User's primary group is boinc_master
|
||||
return true;
|
||||
}
|
||||
if (g_use_sandbox) {
|
||||
|
||||
grp = getgrnam(BOINC_MASTER_GROUP_NAME);
|
||||
if (grp) {
|
||||
boinc_master_gid = grp->gr_gid;
|
||||
|
||||
userName = getlogin();
|
||||
if (userName) {
|
||||
for (i=0; ; i++) { // Step through all users in group boinc_master
|
||||
groupMember = grp->gr_mem[i];
|
||||
if (groupMember == NULL)
|
||||
break; // User is not a member of group boinc_master
|
||||
if (strcmp(userName, groupMember) == 0) {
|
||||
sIsAuthorized = true; // User is a member of group boinc_master
|
||||
return true;
|
||||
}
|
||||
} // for (i)
|
||||
} // if (userName)
|
||||
} // if grp
|
||||
rgid = getgid();
|
||||
if (rgid == boinc_master_gid) {
|
||||
sIsAuthorized = true; // User's primary group is boinc_master
|
||||
return true;
|
||||
}
|
||||
|
||||
userName = getlogin();
|
||||
if (userName) {
|
||||
for (i=0; ; i++) { // Step through all users in group boinc_master
|
||||
groupMember = grp->gr_mem[i];
|
||||
if (groupMember == NULL)
|
||||
break; // User is not a member of group boinc_master
|
||||
if (strcmp(userName, groupMember) == 0) {
|
||||
sIsAuthorized = true; // User is a member of group boinc_master
|
||||
return true;
|
||||
}
|
||||
} // for (i)
|
||||
} // if (userName)
|
||||
} // if grp
|
||||
}
|
||||
#endif // SANDBOX
|
||||
#endif // ! _WIN32
|
||||
|
||||
#ifdef __WXMAC__
|
||||
|
@ -640,17 +645,11 @@ bool CMainDocument::IsUserAuthorized() {
|
|||
}
|
||||
#endif // __WXMAC__
|
||||
|
||||
#ifdef SANDBOX
|
||||
return false;
|
||||
|
||||
#else // ! SANDBOX
|
||||
|
||||
#ifdef __WXMAC__
|
||||
return Mac_Authorize(); // Run Mac Authentication dialog
|
||||
#else // ! __WXMAC__
|
||||
#else
|
||||
return true;
|
||||
#endif // ! __WXMAC__
|
||||
|
||||
#endif // ! SANDBOX
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <Security/AuthorizationTags.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include "util.h" // For g_use_sandbox
|
||||
|
||||
|
||||
// Determine if the currently logged-in user is auhorized to
|
||||
|
@ -45,18 +46,18 @@ Boolean Mac_Authorize()
|
|||
if (sIsAuthorized)
|
||||
return true;
|
||||
|
||||
#ifndef SANDBOX
|
||||
uid_t effectiveUserID, realUserID;
|
||||
|
||||
effectiveUserID = geteuid();
|
||||
realUserID = getuid();
|
||||
if (effectiveUserID == realUserID)
|
||||
{
|
||||
// Logged in user is also the owner
|
||||
sIsAuthorized = true;
|
||||
return true;
|
||||
if (g_use_sandbox) {
|
||||
effectiveUserID = geteuid();
|
||||
realUserID = getuid();
|
||||
if (effectiveUserID == realUserID)
|
||||
{
|
||||
// Logged in user is also the owner
|
||||
sIsAuthorized = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// User is not the owner, so require admin authorization
|
||||
ourAuthItem[0].name = kAuthorizationRightExecute;
|
||||
|
|
|
@ -147,6 +147,8 @@ const char * BOINCUnrecoverableErrorMsg = "Sorry, an unrecoverable error occurr
|
|||
const char * BOINCTestmodeMg = "This BOINC screensaver does not support Test mode";
|
||||
//const char * BOINCExitedSaverMode = "BOINC is no longer in screensaver mode.";
|
||||
|
||||
int g_use_sandbox = 0;
|
||||
|
||||
|
||||
// Returns desired Animation Frequency (per second) or 0 for no change
|
||||
int initBOINCSaver(Boolean ispreview) {
|
||||
|
|
|
@ -43,6 +43,9 @@ using std::string;
|
|||
#include "util.h"
|
||||
#include "version.h"
|
||||
|
||||
int g_use_sandbox = 0;
|
||||
|
||||
|
||||
void usage() {
|
||||
fprintf(stderr, "\
|
||||
Usage: boinc_cmd [--host hostname] [--passwd passwd] command\n\
|
||||
|
|
|
@ -258,13 +258,10 @@ int boinc_delete_file(const char* path) {
|
|||
}
|
||||
#else
|
||||
retval = unlink(path);
|
||||
#ifdef SANDBOX
|
||||
if (retval)
|
||||
// We may not have permission to read subdirectories created by projects
|
||||
if (errno == EACCES) {
|
||||
return remove_project_owned_file_or_dir(path);
|
||||
}
|
||||
#endif
|
||||
if (retval && g_use_sandbox && (errno == EACCES)) {
|
||||
// We may not have permission to read subdirectories created by projects
|
||||
return remove_project_owned_file_or_dir(path);
|
||||
}
|
||||
return retval;
|
||||
#endif
|
||||
if (retval) {
|
||||
|
@ -313,14 +310,14 @@ int clean_out_dir(const char* dirpath) {
|
|||
DIRREF dirp;
|
||||
|
||||
dirp = dir_open(dirpath);
|
||||
if (!dirp)
|
||||
#ifdef SANDBOX
|
||||
// We may not have permission to read subdirectories created by projects
|
||||
if (errno == EACCES) {
|
||||
return remove_project_owned_file_or_dir(dirpath);
|
||||
} else
|
||||
#endif
|
||||
if (!dirp) {
|
||||
if (g_use_sandbox && (errno == EACCES)) {
|
||||
// We may not have permission to read subdirectories created by projects
|
||||
return remove_project_owned_file_or_dir(dirpath);
|
||||
}
|
||||
return 0; // if dir doesn't exist, it's empty
|
||||
}
|
||||
|
||||
while (1) {
|
||||
strcpy(filename, "");
|
||||
retval = dir_scan(filename, dirp, sizeof(filename));
|
||||
|
@ -488,13 +485,9 @@ int boinc_rmdir(const char* name) {
|
|||
#else
|
||||
int retval;
|
||||
retval = rmdir(name);
|
||||
#ifdef SANDBOX
|
||||
if (retval)
|
||||
// We may not have permission to read subdirectories created by projects
|
||||
if (errno == EACCES) {
|
||||
return remove_project_owned_file_or_dir(name);
|
||||
}
|
||||
#endif
|
||||
if (retval && g_use_sandbox && (errno == EACCES))
|
||||
retval = remove_project_owned_file_or_dir(name);
|
||||
return retval;
|
||||
#endif
|
||||
}
|
||||
|
@ -502,12 +495,13 @@ int boinc_rmdir(const char* name) {
|
|||
int remove_project_owned_file_or_dir(const char* path) {
|
||||
#ifdef SANDBOX
|
||||
char cmd[1024];
|
||||
|
||||
sprintf(cmd, "%s/%s /bin/rm rm -fR \"%s\"", SWITCHER_DIR, SWITCHER_FILE_NAME, path);
|
||||
return system(cmd);
|
||||
#else
|
||||
return ERR_UNLINK;
|
||||
|
||||
if (g_use_sandbox) {
|
||||
sprintf(cmd, "%s/%s /bin/rm rm -fR \"%s\"", SWITCHER_DIR, SWITCHER_FILE_NAME, path);
|
||||
return system(cmd);
|
||||
}
|
||||
#endif
|
||||
return ERR_UNLINK;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
|
10
lib/util.h
10
lib/util.h
|
@ -34,6 +34,14 @@
|
|||
|
||||
#endif
|
||||
|
||||
// Ideally, we would access this using wxGetApp().m_use_sandbox in the Manager
|
||||
// and gstate.m_use_sandbox in the Client, but it is used by some source files
|
||||
// (filesys.C, check_security.C) that are linked with both Manager and Client
|
||||
// so the most practical solution is to use a global.
|
||||
extern int g_use_sandbox;
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_STRLCPY)
|
||||
extern size_t strlcpy(char*, const char*, size_t);
|
||||
#endif
|
||||
|
@ -143,7 +151,7 @@ extern pthread_mutex_t getrusage_mutex;
|
|||
|
||||
#ifndef _WIN32
|
||||
extern int lookup_group(char*, gid_t& gid);
|
||||
extern int check_security(void);
|
||||
extern int check_security(int use_sandbox, int isManager);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -65,7 +65,7 @@ then
|
|||
exit
|
||||
fi
|
||||
|
||||
if [ ! -f "boinc" ]
|
||||
if [ ! -x "boinc" ]
|
||||
then
|
||||
echo "Can't find boinc Client in directory $(pwd); exiting"
|
||||
exit
|
||||
|
@ -74,4 +74,15 @@ fi
|
|||
chown -R ${user}:${group} .
|
||||
chmod -R u+rw-s,g+r-w-s,o+r-w .
|
||||
chmod 600 gui_rpc_auth.cfg
|
||||
|
||||
if [ -x /Applications/BOINCManager.app/Contents/MacOS/BOINCManager ] ; then
|
||||
chown ${user}:${group} /Applications/BOINCManager.app/Contents/MacOS/BOINCManager
|
||||
chmod -R u+r-w+s,g+r-ws,o+r-ws /Applications/BOINCManager.app/Contents/MacOS/BOINCManager
|
||||
fi
|
||||
|
||||
if [ -x /Applications/BOINCManager.app/Contents/Resources/boinc ] ; then
|
||||
chown ${user}:${group} /Applications/BOINCManager.app/Contents/Resources/boinc
|
||||
chmod -R u+r-ws,g+r-ws,o+r-ws /Applications/BOINCManager.app/Contents/Resources/boinc
|
||||
fi
|
||||
|
||||
remove_boinc_users
|
||||
|
|
|
@ -189,3 +189,14 @@ set_perm switcher boinc_master boinc_master 0550
|
|||
set_perm_recursive locale boinc_master boinc_master u+r-w,g+r-w,o-rwx
|
||||
|
||||
set_perm boinc boinc_master boinc_master 6555 # boinc client
|
||||
|
||||
|
||||
if [ -x /Applications/BOINCManager.app/Contents/MacOS/BOINCManager ] ; then
|
||||
set_perm /Applications/BOINCManager.app/Contents/MacOS/BOINCManager boinc_master boinc_master 2555
|
||||
fi
|
||||
|
||||
if [ -x /Applications/BOINCManager.app/Contents/Resources/boinc ] ; then
|
||||
set_perm /Applications/BOINCManager.app/Contents/Resources/boinc boinc_master boinc_master 6555
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ static OSErr QuitAppleEventHandler(const AppleEvent *appleEvt, AppleEvent* reply
|
|||
void print_to_log_file(const char *format, ...);
|
||||
void strip_cr(char *buf);
|
||||
|
||||
extern int check_security(char *bundlePath, char *dataPath);
|
||||
extern int check_security(char *bundlePath, char *dataPath, int use_sandbox, int isManager);
|
||||
|
||||
|
||||
static Boolean gQuitFlag = false; /* global */
|
||||
|
@ -173,7 +173,7 @@ int main(int argc, char *argv[])
|
|||
continue;
|
||||
}
|
||||
|
||||
err = check_security(p, "/Library/Application Support/BOINC Data");
|
||||
err = check_security(p, "/Library/Application Support/BOINC Data", true, false);
|
||||
if (err == noErr)
|
||||
break;
|
||||
// print_to_log_file("check_security returned %d (repetition=%d)", err, i);
|
||||
|
|
Loading…
Reference in New Issue