*** empty log message ***

svn path=/trunk/boinc/; revision=10356
This commit is contained in:
Charlie Fenton 2006-06-15 11:11:41 +00:00
parent 44d70ff082
commit 477677ac5a
10 changed files with 332 additions and 121 deletions

View File

@ -6036,3 +6036,29 @@ Rom 15 June 2006
forum_moderate_post_action.php
forum_moderate_thread_action.php
forum_report_post.php
Charlie 15 June 2006
- Mac sandbox:
- 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
of both the Manager and Client use the current user and group, and
temporarily change the ownership of the BOINC Data hierarchy if
necessary.
- Manager and Client call check_security(); deployment versions notify
the user and quit if they find a problem with ownership or permissions
of either the application or the BOINC Data.
- Better setting of _DEBUG and __WXDEBUG__ in Manager and Client builds.
client/
check_security.C
main.C
clientgui/
BOINCGUIApp.cpp
mac/
MacGUI.pch
SecurityUtility.cpp
SetupSecurity.cpp,h
mac_build/
boinc.xcodeproj/
project.pbxproj

View File

@ -28,38 +28,69 @@
#include <sys/param.h> // for MAXPATHLEN
#include "util.h"
#include "error_numbers.h"
#include "file_names.h"
#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];
#else
#define boinc_master_user_name "boinc_master"
#define boinc_master_group_name "boinc_master"
#endif
#define boinc_master_name "boinc_master"
#define boinc_project_name "boinc_project"
// Returns FALSE (0) if owners and permissions are OK, else TRUE (1)
int check_security(int isManager) {
int check_security() {
passwd *pw;
gid_t egid, rgid, boinc_master_gid, boinc_project_gid;
uid_t euid, ruid, boinc_master_uid, boinc_project_uid;
gid_t egid, boinc_master_gid, boinc_project_gid;
uid_t euid, boinc_master_uid, boinc_project_uid;
char *p;
group *grp;
int i;
char dir_path[MAXPATHLEN];
char dir_path[MAXPATHLEN], full_path[MAXPATHLEN];
struct stat sbuf;
int retval;
#ifdef __WXMAC__ // If Mac BOINC Manager
ProcessSerialNumber ourPSN;
FSRef ourFSRef;
#endif
pw = getpwnam(boinc_master_name);
#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.
boinc_master_uid = geteuid();
pw = getpwuid(boinc_master_uid);
if (pw == NULL)
return ERR_USER_REJECTED; // Should never happen
strlcpy(boinc_master_user_name, pw->pw_name, sizeof(boinc_master_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));
#else
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;
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
pw = getpwnam(boinc_project_name);
if (pw == NULL)
return ERR_USER_REJECTED; // User boinc_project does not exist
boinc_project_uid = pw->pw_uid;
grp = getgrnam(boinc_master_name);
if (grp == NULL)
return ERR_GETGRNAM; // Group boinc_master does not exist
boinc_master_gid = grp->gr_gid;
grp = getgrnam(boinc_project_name);
if (grp == NULL)
return ERR_GETGRNAM; // Group boinc_project does not exist
@ -69,26 +100,82 @@ int check_security(int isManager) {
p = grp->gr_mem[i];
if (p == NULL)
return ERR_GETGRNAM; // User boinc_master is not a member of group boinc_project
if (strcmp(p, boinc_master_name) == 0)
if (strcmp(p, boinc_master_user_name) == 0)
break;
}
rgid = getgid();
#ifdef __WXMAC__ // If Mac BOINC Manager
// Get the full path to BOINC Manager application's bundle
retval = GetCurrentProcess (&ourPSN);
if (retval)
return retval; // Should never happen
retval = GetProcessBundleLocation(&ourPSN, &ourFSRef);
if (retval)
return retval; // Should never happen
retval = FSRefMakePath (&ourFSRef, (UInt8*)dir_path, sizeof(dir_path));
if (retval)
return retval; // Should never happen
// Get the full path to BOINC Manager inside this application's bundle
strlcpy(full_path, dir_path, sizeof(full_path));
strlcat(full_path, "/Contents/MacOS/", sizeof(full_path));
// To allow for branding, assume name of executable inside bundle is same as name of bundle
p = strrchr(dir_path, '/'); // Assume name of executable inside bundle is same as name of bundle
if (p == NULL)
p = dir_path - 1;
strlcat(full_path, p, sizeof(full_path));
p = strrchr(full_path, '.'); // Strip off bundle extension (".app")
if (p)
*p = '\0';
retval = stat(dir_path, &sbuf);
if (retval)
return retval; // Should never happen
if (sbuf.st_gid != boinc_master_gid)
return ERR_USER_PERMISSION;
if ((sbuf.st_mode & S_ISGID) != S_ISGID)
return ERR_USER_PERMISSION;
// 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(dir_path, &sbuf);
if (retval)
return retval; // Should never happen
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 & S_ISUID | S_ISGID) != S_ISUID | S_ISGID)
return ERR_USER_PERMISSION;
#endif // Mac BOINC Manager
// rgid = getgid();
// ruid = getuid();
egid = getegid();
euid = geteuid();
#ifndef _DEBUG
if (egid != boinc_master_gid)
return ERR_USER_PERMISSION; // We should be running setgid boinc_master
ruid = getuid();
euid = geteuid();
if (! isManager) {
if (euid != boinc_master_uid)
return ERR_USER_PERMISSION; // BOINC Client should be running setuid 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));
retval = stat(dir_path, &sbuf);
if (retval)
return retval;
return retval; // Should never happen
// The top-level BOINC Data directory can have a different user if created by the Manager,
// but it should always have group boinc_master.
@ -99,9 +186,10 @@ int check_security(int isManager) {
if ((sbuf.st_mode & 0575) != 0575)
return ERR_USER_PERMISSION;
getcwd(dir_path, sizeof(dir_path));
strlcat(dir_path, "/projects", MAXPATHLEN);
retval = stat(dir_path, &sbuf);
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 ERR_USER_PERMISSION;
@ -109,13 +197,14 @@ int check_security(int isManager) {
if (sbuf.st_uid != boinc_master_uid)
return ERR_USER_PERMISSION;
if ((sbuf.st_mode & 0775) != 0775)
if (sbuf.st_mode != 0775)
return ERR_USER_PERMISSION;
}
getcwd(dir_path, sizeof(dir_path));
strlcat(dir_path, "/slots", MAXPATHLEN);
retval = stat(dir_path, &sbuf);
strlcpy(full_path, dir_path, sizeof(dir_path));
strlcat(full_path, "/", sizeof(full_path));
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 ERR_USER_PERMISSION;
@ -123,7 +212,22 @@ int check_security(int isManager) {
if (sbuf.st_uid != boinc_master_uid)
return ERR_USER_PERMISSION;
if ((sbuf.st_mode & 0775) != 0775)
if (sbuf.st_mode != 0775)
return ERR_USER_PERMISSION;
}
strlcpy(full_path, dir_path, sizeof(full_path));
strlcat(full_path, "/", sizeof(full_path));
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 ERR_USER_PERMISSION;
if (sbuf.st_uid != boinc_master_uid)
return ERR_USER_PERMISSION;
if (sbuf.st_mode != 0770)
return ERR_USER_PERMISSION;
}

View File

@ -45,13 +45,14 @@ typedef void (CALLBACK* ClientLibraryShutdown)();
#include <sys/types.h>
#include <sys/socket.h>
#endif
#include <sys/stat.h>
#include <syslog.h>
#include <unistd.h>
#include <csignal>
#endif
#ifdef __APPLE__
#include <sys/stat.h> // for umask()
#if (defined (__APPLE__) && defined(SANDBOX) && defined(_DEBUG))
#include "SetupSecurity.h"
#endif
#ifdef __EMX__
@ -343,11 +344,11 @@ static void init_core_client(int argc, char** argv) {
SetCurrentDirectory(szPath);
}
#endif
#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();
@ -743,6 +744,19 @@ int main(int argc, char** argv) {
#else
#ifdef __APPLE__
#ifdef SANDBOX
if (check_security()) {
#ifdef _DEBUG
// 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
SetBOINCDataOwnersGroupsAndPermissions();
#else
printf( "\nBOINC ownership or permissions are not set properly; please reinstall BOINC\n" );
return ERR_USER_PERMISSION;
#endif // _DEBUG
}
#endif // SANDBOX
// Initialize Mac OS X idle time measurement / idle detection
gEventHandle = NXOpenEventStatus();
#endif // __APPLE__

View File

@ -25,6 +25,9 @@
#include <Carbon/Carbon.h>
#include "filesys.h"
#include "util.h"
#if (defined(SANDBOX) && defined(_DEBUG))
#include "SetupSecurity.h"
#endif
#endif
#include "stdwx.h"
@ -243,7 +246,7 @@ bool CBrandingScheme::OnInit( wxConfigBase *pConfig ) {
bool CBOINCGUIApp::OnInit() {
#ifdef SANDBOX
#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
#endif
@ -320,23 +323,30 @@ bool CBOINCGUIApp::OnInit() {
strDirectory += wxT("BOINC Data"); // We don't customize BOINC Data directory name for branding
if (! wxDirExists(strDirectory)) {
#ifdef SANDBOX
gid_t gid;
// Create BOINC Data directory writable by group boinc_master only
success = wxMkdir(strDirectory, 0575);
#ifndef _DEBUG
gid_t gid;
lookup_group("boinc_master", gid);
boinc_chown("BOINC Data", gid);
#else
#endif // ! _DEBUG
#else // SANDBOX
success = wxMkdir(strDirectory, 0777); // Does nothing if dir exists
#endif
#endif // ! SANDBOX
}
success = ::wxSetWorkingDirectory(strDirectory);
// wxChar *wd = wxGetWorkingDirectory(buf, 1000); // For debugging
}
#endif // __WXMAC__
#ifdef SANDBOX
if (check_security(true)) {
#ifdef _DEBUG
// 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())
SetBOINCDataOwnersGroupsAndPermissions();
#endif // _DEBUG
if (check_security()) {
wxMessageDialog* pDlg =
new wxMessageDialog(m_pFrame, _("BOINC ownership or permissions are not set properly; please reinstall BOINC"),wxT(""), wxOK);
pDlg->ShowModal();
@ -344,7 +354,8 @@ bool CBOINCGUIApp::OnInit() {
pDlg->Destroy();
return false;
}
#endif
#endif // SANDBOX
#endif // __WXMAC__
// Initialize the BOINC Diagnostics Framework
int dwDiagnosticsFlags =

View File

@ -32,29 +32,23 @@
#define HAVE_SSIZE_T
#ifdef _DEBUG
#undef _DEBUG // so we don't have to link wih debug Wx libs
#undef __WXDEBUG__
#include "stdwx.h"
#include "config.h"
// We want to define __WXDEBUG__ to enable certain test code within our project,
// but only for Development builds. Unfortunately, XCode allows us to modify
// compiler or linker flags by build style only on a project-wide basis. If we
// do that, then the compiler & linker flags override these settings for all
// targets in the project. But our different targets need different settings.
// XCode does not provide any way to do this on a per-target basis.
// This means that we can neither add -D__WXDEBUG to the compiler flags for only
// Development Builds of the BOINC Manager, but we also cannot link in the debug
// build of wxWidgets for only Development Builds of the BOINC Manager.
// So we use a couple of ugly hacks here:
// (1) We take advantage that __OPTIMIZE__ is defined only for Deployment builds.
// (2) We define __WXDEBUG__ AFTER including stdwx.h, so as not to require the
// debug build of the wxWidgets library.
// __OPTIMIZE__ is defined in Deployment builds, not in Development builds
#ifndef __OPTIMIZE__
// Define this AFTER including stdwx.h so we don't have to link wih debug Wx libs
#define _DEBUG // Redefine _DEBUG for the rest of the code
#define __WXDEBUG__
#endif
#else // _DEBUG
#include "stdwx.h"
#endif // ! _DEBUG
#include "config.h"
// Prototypes for Mac_GUI.cpp
Boolean Mac_Authorize(void);

View File

@ -42,7 +42,8 @@ int main(int argc, char *argv[]) {
getwd(boincPath);
//ShowSecurityError("Current Working Directory is %s", wd);
err = SetBOINCAppOwnersGroupsAndPermissions(boincPath, "BOINCManager", true);
strlcat(boincPath, "/BOINCManager.app", sizeof(boincPath));
err = SetBOINCAppOwnersGroupsAndPermissions(boincPath);
if (err != noErr)
return err;

View File

@ -31,19 +31,32 @@
#include "SetupSecurity.h"
static OSStatus CreateUserAndGroup(char * name);
static OSStatus GetAuthorization(void);
OSStatus DoPrivilegedExec(const char *pathToTool, char *arg1, char *arg2, char *arg3, char *arg4, char *arg5);
static pascal Boolean ErrorDlgFilterProc(DialogPtr theDialog, EventRecord *theEvent, short *theItemHit);
static void SleepTicks(UInt32 ticksToSleep);
#ifdef _DEBUG
static OSStatus SetFakeMasterNames(void);
#else
static OSStatus CreateUserAndGroup(char * user_name, char * group_name);
#endif
static AuthorizationRef gOurAuthRef = NULL;
#define DELAY_TICKS 3
#define DELAY_TICKS_R 10
#define boinc_master_name "boinc_master"
#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];
#else
#define boinc_master_user_name "boinc_master"
#define boinc_master_group_name "boinc_master"
#endif
#define boinc_project_name "boinc_project"
#define MIN_ID 25 /* Minimum user ID / Group ID to create */
@ -53,41 +66,47 @@ static char chmodPath[] = "/bin/chmod";
static char chownPath[] = "/usr/sbin/chown";
#define RIGHTS_COUNT 3 /* Count of the 3 above items */
OSStatus CreateBOINCUsersAndGroups() {
int CreateBOINCUsersAndGroups() {
#ifndef _DEBUG
char buf1[80];
OSStatus err = noErr;
err = CreateUserAndGroup(boinc_master_name);
err = CreateUserAndGroup(boinc_master_user_name, boinc_master_group_name);
if (err != noErr)
return err;
err = CreateUserAndGroup(boinc_project_name);
err = CreateUserAndGroup(boinc_project_name, boinc_project_name);
if (err != noErr)
return err;
// Add user boinc_master to group boinc_project
sprintf(buf1, "/groups/%s", boinc_project_name);
// "dscl . -merge /groups/boinc_project users boinc_master"
err = DoPrivilegedExec(dsclPath, ".", "-merge", buf1, "users", boinc_master_name);
err = DoPrivilegedExec(dsclPath, ".", "-merge", buf1, "users", boinc_master_user_name);
if (err != noErr)
return err;
system("lookupd -flushcache");
system("memberd -r");
#endif // ! _DEBUG
return noErr;
}
OSStatus SetBOINCAppOwnersGroupsAndPermissions(char *path, char *managerName, Boolean development) {
int SetBOINCAppOwnersGroupsAndPermissions(char *path) {
char fullpath[MAXPATHLEN];
char buf1[80];
char *p;
OSStatus err = noErr;
#ifdef _DEBUG
err = SetFakeMasterNames();
if (err)
return err;
#endif
strlcpy(fullpath, path, MAXPATHLEN);
strlcat(fullpath, "/", MAXPATHLEN);
strlcat(fullpath, managerName, MAXPATHLEN);
strlcat(fullpath, ".app", MAXPATHLEN);
if (strlen(fullpath) >= (MAXPATHLEN-1)) {
ShowSecurityError("SetBOINCAppOwnersGroupsAndPermissions: path to Manager is too long");
return -1;
@ -101,59 +120,64 @@ OSStatus SetBOINCAppOwnersGroupsAndPermissions(char *path, char *managerName, Bo
return err;
strlcat(fullpath, "/Contents/MacOS/", MAXPATHLEN);
strlcat(fullpath, managerName, MAXPATHLEN);
// To allow for branding, assume name of executable inside bundle is same as name of bundle
p = strrchr(path, '/'); // Assume name of executable inside bundle is same as name of bundle
if (p == NULL)
p = path - 1;
strlcat(fullpath, p, MAXPATHLEN);
p = strrchr(fullpath, '.'); // Strip off bundle extension (".app")
if (p)
*p = '\0';
if (strlen(fullpath) >= (MAXPATHLEN-1)) {
ShowSecurityError("SetBOINCAppOwnersGroupsAndPermissions: path to Manager is too long");
return -1;
}
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master path/BOINCManager.app/Contents/MacOS/BOINCManager
err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL);
if (err)
return err;
if (development) {
#ifdef _DEBUG
// chmod u=rwx,g=rwsx,o=rx path/BOINCManager.app/Contents/MacOS/BOINCManager
// 02775 = S_ISGID | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH
// setgid-on-execution plus read, write and execute permission for user, group & others
err = DoPrivilegedExec(chmodPath, "u=rwx,g=rwsx,o=rx", fullpath, NULL, NULL, NULL);
} else {
#else
// chmod u=rx,g=rsx,o=rx path/BOINCManager.app/Contents/MacOS/BOINCManager
// 02555 = S_ISGID | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
// setgid-on-execution plus read and execute permission for user, group & others
err = DoPrivilegedExec(chmodPath, "u=rx,g=rsx,o=rx", fullpath, NULL, NULL, NULL);
}
#endif
if (err)
return err;
strlcpy(fullpath, path, MAXPATHLEN);
strlcat(fullpath, "/", MAXPATHLEN);
strlcat(fullpath, managerName, MAXPATHLEN);
strlcat(fullpath, ".app/Contents/Resources/boinc", MAXPATHLEN);
strlcat(fullpath, "/Contents/Resources/boinc", MAXPATHLEN);
if (strlen(fullpath) >= (MAXPATHLEN-1)) {
ShowSecurityError("SetBOINCAppOwnersGroupsAndPermissions: path to client is too long");
return -1;
}
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master path/BOINCManager.app/Contents/Resources/boinc
err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL);
if (err)
return err;
if (development) {
#ifdef _DEBUG
// chmod u=rwsx,g=rwsx,o=rx path/BOINCManager.app/Contents/Resources/boinc
// 06775 = S_ISUID | S_ISGID | S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IXOTH
// setuid-on-execution, setgid-on-execution plus read, write and execute permission for user, group & others
err = DoPrivilegedExec(chmodPath, "u=rwsx,g=rwsx,o=rx", fullpath, NULL, NULL, NULL);
} else {
#else
// chmod u=rsx,g=rsx,o=rx path/BOINCManager.app/Contents/Resources/boinc
// 06555 = S_ISUID | S_ISGID | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
// setuid-on-execution, setgid-on-execution plus read and execute permission for user, group & others
err = DoPrivilegedExec(chmodPath, "u=rsx,g=rsx,o=rx", fullpath, NULL, NULL, NULL);
}
#endif
if (err)
return err;
@ -161,7 +185,7 @@ OSStatus SetBOINCAppOwnersGroupsAndPermissions(char *path, char *managerName, Bo
}
OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
int SetBOINCDataOwnersGroupsAndPermissions() {
FSRef ref;
Boolean isDirectory;
char fullpath[MAXPATHLEN];
@ -169,6 +193,12 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
OSStatus err = noErr;
OSStatus result;
char *BOINCDataDirPath = "/Library/Application Support/BOINC Data";
#ifdef _DEBUG
err = SetFakeMasterNames();
if (err)
return err;
#endif
strlcpy(fullpath, BOINCDataDirPath, MAXPATHLEN);
@ -178,7 +208,7 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
return noErr; // BOINC Data Directory does not exist
// Set owner and group of BOINC Data directory's contents
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master "/Library/Applications/BOINC Data"
err = DoPrivilegedExec(chownPath, "-R", buf1, fullpath, NULL, NULL);
if (err)
@ -194,7 +224,7 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
#if 0 // Redundant if we already set BOINC Data directory to boinc_master:boinc_master
// Set owner and group of BOINC Data directory itself
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master "/Library/Applications/BOINC Data"
err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL);
if (err)
@ -219,7 +249,7 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
// Make gui_rpc_auth.cfg file readable and writable only by user boinc_master and group boinc_master
// Set owner and group of gui_rpc_auth.cfg file
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master "/Library/Applications/BOINC Data/gui_rpc_auth.cfg"
err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL);
if (err)
@ -241,14 +271,14 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory);
if ((result == noErr) && (isDirectory)) {
// Set owner and group of projects directory's contents
sprintf(buf1, "%s:%s", boinc_master_name, boinc_project_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_project "/Library/Applications/BOINC Data/projects"
err = DoPrivilegedExec(chownPath, "-R", buf1, fullpath, NULL, NULL);
if (err)
return err;
// Set owner and group of projects directory itself
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master "/Library/Applications/BOINC Data/projects"
err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL);
if (err)
@ -270,14 +300,14 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory);
if ((result == noErr) && (isDirectory)) {
// Set owner and group of slots directory's contents
sprintf(buf1, "%s:%s", boinc_master_name, boinc_project_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_project "/Library/Applications/BOINC Data/slots"
err = DoPrivilegedExec(chownPath, "-R", buf1, fullpath, NULL, NULL);
if (err)
return err;
// Set owner and group of slots directory itself
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master "/Library/Applications/BOINC Data/slots"
err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL);
if (err)
@ -300,7 +330,7 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory);
if ((result == noErr) && (isDirectory)) {
// Set owner and group of locale directory and all its contents
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master "/Library/Applications/BOINC Data/locale"
err = DoPrivilegedExec(chownPath, "-R", buf1, fullpath, NULL, NULL);
if (err)
@ -323,7 +353,7 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
result = FSPathMakeRef((StringPtr)fullpath, &ref, &isDirectory);
if ((result == noErr) && (isDirectory)) {
// Set owner and group of switcher directory
sprintf(buf1, "%s:%s", boinc_master_name, boinc_master_name);
sprintf(buf1, "%s:%s", boinc_master_user_name, boinc_master_group_name);
// chown boinc_master:boinc_master "/Library/Applications/BOINC Data/switcher"
err = DoPrivilegedExec(chownPath, buf1, fullpath, NULL, NULL, NULL);
if (err)
@ -361,7 +391,8 @@ OSStatus SetBOINCDataOwnersGroupsAndPermissions() {
}
static OSStatus CreateUserAndGroup(char * name) {
#ifndef _DEBUG
static OSStatus CreateUserAndGroup(char * user_name, char * group_name) {
OSStatus err = noErr;
passwd *pw = NULL;
group *grp = NULL;
@ -375,13 +406,13 @@ static OSStatus CreateUserAndGroup(char * name) {
char buf2[80];
char buf3[80];
pw = getpwnam(name);
pw = getpwnam(user_name);
if (pw) {
userid = pw->pw_uid;
userExists = true;
}
grp = getgrnam(name);
grp = getgrnam(group_name);
if (grp) {
groupid = grp->gr_gid;
groupExists = true;
@ -437,7 +468,7 @@ static OSStatus CreateUserAndGroup(char * name) {
}
}
sprintf(buf1, "/groups/%s", name);
sprintf(buf1, "/groups/%s", group_name);
sprintf(buf2, "%d", groupid);
if (! groupExists) { // If we need to create group
@ -452,7 +483,7 @@ static OSStatus CreateUserAndGroup(char * name) {
return err;
} // if (! groupExists)
sprintf(buf1, "/users/%s", name);
sprintf(buf1, "/users/%s", user_name);
sprintf(buf2, "%d", groupid);
sprintf(buf3, "%d", userid);
@ -484,16 +515,18 @@ static OSStatus CreateUserAndGroup(char * name) {
err = DoPrivilegedExec(dsclPath, ".", "-create", buf1, "gid", buf2);
if (err)
return err;
return noErr;
}
#endif // ! _DEBUG
OSStatus AddAdminUserToGroups(char *user_name) {
int AddAdminUserToGroups(char *user_name) {
#ifndef _DEBUG
char buf1[80];
OSStatus err = noErr;
sprintf(buf1, "/groups/%s", boinc_master_name);
sprintf(buf1, "/groups/%s", boinc_master_group_name);
// "dscl . -merge /groups/boinc_master users user_name"
err = DoPrivilegedExec(dsclPath, ".", "-merge", buf1, "users", user_name);
@ -510,10 +543,38 @@ OSStatus AddAdminUserToGroups(char *user_name) {
system("lookupd -flushcache");
system("memberd -r");
#endif // ! _DEBUG
return noErr;
}
#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 OSStatus SetFakeMasterNames() {
passwd *pw;
group *grp;
gid_t boinc_master_gid;
uid_t boinc_master_uid;
boinc_master_uid = geteuid();
pw = getpwuid(boinc_master_uid);
if (pw == NULL)
return -1; // Should never happen
strlcpy(boinc_master_user_name, pw->pw_name, sizeof(boinc_master_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));
return noErr;
}
#endif
static OSStatus GetAuthorization (void) {
static Boolean sIsAuthorized = false;
AuthorizationRights ourAuthRights;

View File

@ -19,11 +19,10 @@
// SetupSecurity.h
OSStatus CreateBOINCUsersAndGroups(void);
OSStatus SetBOINCAppOwnersGroupsAndPermissions(char *path, char *managerName, Boolean development);
OSStatus SetBOINCDataOwnersGroupsAndPermissions(void);
OSStatus AddAdminUserToGroups(char *user_name);
int CreateBOINCUsersAndGroups(void);
int SetBOINCAppOwnersGroupsAndPermissions(char *path);
int SetBOINCDataOwnersGroupsAndPermissions(void);
int AddAdminUserToGroups(char *user_name);
void ShowSecurityError(const char *format, ...);
int CheckSecurity(int isManager);

View File

@ -132,7 +132,7 @@ extern const char* boincerror(int which_error);
#ifndef _WIN32
extern int lookup_group(char*, gid_t& gid);
extern int check_security(int isManager);
extern int check_security(void);
#endif
#endif

View File

@ -121,6 +121,9 @@
DD40826307D3076400163EF5 /* reduce_main.C in Sources */ = {isa = PBXBuildFile; fileRef = DD40825807D3076400163EF5 /* reduce_main.C */; };
DD40826507D3076400163EF5 /* x_opengl.C in Sources */ = {isa = PBXBuildFile; fileRef = DD40825A07D3076400163EF5 /* x_opengl.C */; };
DD40D05107F03A030096C645 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
DD431F230A415EDF0060585A /* SetupSecurity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7748B40A356D6C0025D05E /* SetupSecurity.cpp */; };
DD431F240A415EE70060585A /* SetupSecurity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7748B40A356D6C0025D05E /* SetupSecurity.cpp */; };
DD431FAA0A41660D0060585A /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
DD48091F081A66F100A174AA /* BOINCSaver.nib in Resources */ = {isa = PBXBuildFile; fileRef = DD48091E081A66F100A174AA /* BOINCSaver.nib */; };
DD4DD0A207EAA648008A6468 /* BOINCTaskBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD81C40307C5D1020098A04D /* BOINCTaskBar.cpp */; };
DD4EC61108A0A083009AA08F /* texture.C in Sources */ = {isa = PBXBuildFile; fileRef = DD4EC60F08A0A083009AA08F /* texture.C */; };
@ -184,7 +187,6 @@
DDA12AA20A369B5500FBDD12 /* SetupSecurity.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD7748B40A356D6C0025D05E /* SetupSecurity.cpp */; };
DDA12AAE0A369C5800FBDD12 /* SecurityUtility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA12AAD0A369C5800FBDD12 /* SecurityUtility.cpp */; };
DDA9D3BC09189A8C0060E7A7 /* Mac_GUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDA9D3BB09189A8C0060E7A7 /* Mac_GUI.cpp */; };
DDADA51508BAC96200053BFB /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
DDAEC9FF07FA5A5C00A7BC36 /* SetVersion.C in Sources */ = {isa = PBXBuildFile; fileRef = DDAEC9E707FA58A000A7BC36 /* SetVersion.C */; };
DDB5060E0958247800181B75 /* libwx_mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDB5060D0958247800181B75 /* libwx_mac.a */; };
DDB506FA0958446900181B75 /* ProxyInfoPage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDB506F80958446900181B75 /* ProxyInfoPage.cpp */; };
@ -1116,7 +1118,7 @@
buildActionMask = 2147483647;
files = (
DD130F320820C47C001A0291 /* IOKit.framework in Frameworks */,
DDADA51508BAC96200053BFB /* Carbon.framework in Frameworks */,
DD431FAA0A41660D0060585A /* Carbon.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1404,6 +1406,7 @@
DD344B4807C5AC4C0043025C /* app_control.C */,
DD344B4907C5AC4C0043025C /* app_graphics.C */,
DD344B5A07C5AC9F0043025C /* app_start.C */,
DD6617870A3FFD8C00FFEBEB /* check_security.C */,
DD344B6B07C5AD270043025C /* check_state.C */,
DD344B6C07C5AD270043025C /* client_msgs.C */,
DD344B6D07C5AD270043025C /* client_msgs.h */,
@ -1424,7 +1427,6 @@
F54B8FC902AC0A0C01FB7237 /* cs_scheduler.C */,
DD344B9307C5AE2E0043025C /* cs_statefile.C */,
DD344B9407C5AE2E0043025C /* cs_trickle.C */,
DD6617870A3FFD8C00FFEBEB /* check_security.C */,
DD344B9507C5AE2E0043025C /* dhrystone.C */,
DD344B9607C5AE2E0043025C /* dhrystone.h */,
DD344B9707C5AE2E0043025C /* dhrystone2.C */,
@ -2479,6 +2481,7 @@
DD58C47608F334EA00C1DF66 /* wizardex.cpp in Sources */,
DD8DD4A709D9432F0043019E /* BOINCDialupManager.cpp in Sources */,
DD6617890A3FFD8C00FFEBEB /* check_security.C in Sources */,
DD431F230A415EDF0060585A /* SetupSecurity.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2690,6 +2693,7 @@
DDD74DD307CF493D0065AC9D /* shmem.C in Sources */,
DDD74DD407CF493E0065AC9D /* util.C in Sources */,
DD6617880A3FFD8C00FFEBEB /* check_security.C in Sources */,
DD431F240A415EE70060585A /* SetupSecurity.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2807,6 +2811,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = NO;
GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Carbon.framework/Headers/Carbon.h";
INSTALL_PATH = "$(HOME)/bin";
OTHER_CFLAGS = "-D_DEBUG";
OTHER_LDFLAGS = (
"-framework",
Carbon,
@ -3053,7 +3058,6 @@
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
"-D_THREAD_SAFE",
"-D__WXMAC",
"-include",
../clientgui/mac/config.h,
);
@ -3062,7 +3066,6 @@
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"../../curl-7.15.3/lib/.libs/libcurl.a",
"-framework Carbon",
"-lcrypto",
"-lssl",
"-lz",
@ -3643,14 +3646,15 @@
OTHER_CFLAGS = (
"-DMAC_OS_X_VERSION_MAX_ALLOWED=1040",
"-D_THREAD_SAFE",
"-D__WXMAC",
"-D_DEBUG",
"-include",
../clientgui/mac/config.h,
);
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"-framework",
Security,
"../../curl-7.15.3/lib/.libs/libcurl.a",
"-framework Carbon",
"-lcrypto",
"-lssl",
"-lz",
@ -3688,7 +3692,6 @@
OTHER_CFLAGS = (
"-DMAC_OS_X_VERSION_MAX_ALLOWED=1030",
"-D_THREAD_SAFE",
"-D__WXMAC",
"fasm-blocks",
"-include",
../clientgui/mac/config.h,
@ -3696,7 +3699,6 @@
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"../../curl-7.15.3/lib/.libs/libcurl.a",
"-framework Carbon",
"-lcrypto",
"-lssl",
"-lz",
@ -3817,6 +3819,7 @@
"-DNOCLIPBOARD",
"-D_THREAD_SAFE",
"-D__WXMAC__",
"-D_DEBUG",
"-DHAVE_STRCASECMP_IN_STRING_H",
);
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
@ -4317,14 +4320,12 @@
MACOSX_DEPLOYMENT_TARGET = 10.4;
OTHER_CFLAGS = (
"-D_THREAD_SAFE",
"-D__WXMAC",
"-include",
../clientgui/mac/config.h,
);
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
OTHER_LDFLAGS = (
"../../curl-7.15.3/lib/.libs/libcurl.a",
"-framework Carbon",
"-lcrypto",
"-lssl",
"-lz",