@@ -22,7 +22,7 @@ ifeq ($(ARCH), mac) | |||
CXXFLAGS += -DAPPLE -stdlib=libc++ | |||
LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | |||
-framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo \ | |||
-Ldep/lib -lGLEW -lglfw -ljansson -lsamplerate -lcurl -lzip -lrtaudio -lrtmidi -lcrypto | |||
-Ldep/lib -lGLEW -lglfw -ljansson -lsamplerate -lcurl -lzip -lrtaudio -lrtmidi -lcrypto -lsandbox | |||
TARGET = Rack | |||
BUNDLE = dist/$(TARGET).app | |||
endif | |||
@@ -56,11 +56,6 @@ ifeq ($(ARCH), win) | |||
env PATH=dep/bin:/mingw64/bin ./$< | |||
endif | |||
sandbox-run: $(TARGET) | |||
ifeq ($(ARCH), mac) | |||
sandbox-exec -D RACK_HOME=$(PWD) -f ./Rack.sb `which sh` -c 'DYLD_FALLBACK_LIBRARY_PATH=dep/lib ./$<' 2 ↵ ✹ ✭sandbox ‹2.4.2› | |||
endif | |||
debug: $(TARGET) | |||
ifeq ($(ARCH), lin) | |||
LD_LIBRARY_PATH=dep/lib gdb -ex run ./Rack | |||
@@ -97,6 +92,7 @@ ifeq ($(ARCH), mac) | |||
mkdir -p $(BUNDLE)/Contents/Resources | |||
cp Info.plist $(BUNDLE)/Contents/ | |||
cp -R LICENSE* res $(BUNDLE)/Contents/Resources | |||
cp Rack.sb $(BUNDLE)/Contents/Resources | |||
mkdir -p $(BUNDLE)/Contents/MacOS | |||
cp Rack $(BUNDLE)/Contents/MacOS/ | |||
@@ -1,26 +1,15 @@ | |||
(version 1) | |||
(debug allow) | |||
(define rack-home "RACK_HOME") | |||
(import "system.sb") | |||
; This is needed for IPC on OSX >= 10.6 | |||
(allow ipc-posix-shm) | |||
; Allow inbound and outbound connections | |||
(allow network-outbound) | |||
(allow network-inbound) | |||
; Allow reading with sysctl | |||
(allow sysctl-read) | |||
; Allow it to read metadata | |||
(allow file-read-metadata) | |||
; Allow it to run processes and fork | |||
(allow process*) | |||
; Allow it to signal self | |||
(allow signal) | |||
(allow iokit-open) | |||
@@ -29,34 +18,8 @@ | |||
(allow system-socket) | |||
(allow file-read* file-write* (subpath (param rack-home))) | |||
; Allow file reading | |||
(allow file-read* | |||
(regex | |||
#"^/Applications/Rack.app" | |||
#"^/Library/*" | |||
#"^/System/Library/*" | |||
#"^/usr/*" | |||
#"^/dev/*" | |||
#"/Users/jon/Projects/Rack" | |||
#"/Users/[^.]+/Library/Saved Application State/com.vcvrack.rack.savedState" | |||
) | |||
) | |||
; Allow write access to a subset of the above | |||
(allow file-write* | |||
(regex | |||
#"^/private/var/*" | |||
#"^/private/tmp/*" | |||
#"^/var/folders/th/*" | |||
) | |||
) | |||
(allow file-issue-extension | |||
(regex | |||
#"^/private/var/*" | |||
) | |||
) | |||
(allow file-read* (subpath (param "rackLocal"))) | |||
(allow file-write* (subpath (param "rackLocal"))) | |||
(allow file-read* (subpath (param "rackGlobal"))) | |||
(deny default) |
@@ -32,7 +32,10 @@ int main(int argc, char* argv[]) { | |||
info("Local directory: %s", localDir.c_str()); | |||
} | |||
sandboxInit(); | |||
if(!sandboxInit()) { | |||
info("Refusing to run without sandbox"); | |||
exit(1); | |||
} | |||
pluginInit(); | |||
engineInit(); | |||
guiInit(); | |||
@@ -1,13 +1,71 @@ | |||
#include "sandbox.hpp" | |||
#include "util.hpp" | |||
#include "asset.hpp" | |||
#include <vector> | |||
namespace rack { | |||
#if defined(ARCH_MAC) | |||
#include <sandbox.h> | |||
#include <stdlib.h> | |||
#include <sys/syslimits.h> | |||
extern "C" { | |||
int sandbox_init_with_parameters(const char *profile, uint64_t flags, const char *const parameters[], char **errorbuf); | |||
// Possible values for 'flags': | |||
#define SANDBOX_STRING 0x0000 | |||
#define SANDBOX_NAMED 0x0001 | |||
#define SANDBOX_BUILTIN 0x0002 | |||
#define SANDBOX_FILE 0x0003 | |||
} | |||
struct SandboxParams { | |||
void* buf; | |||
size_t count; | |||
size_t size; | |||
}; | |||
bool sandboxInit() { | |||
char* error_buff = NULL; | |||
//int error = sandbox_init(final_sandbox_profile_str.c_str(), 0, &error_buff); | |||
int error = sandbox_init(kSBXProfileNoInternet, SANDBOX_NAMED, &error_buff); | |||
/* | |||
char* params = sandbox_create_params(); | |||
if (!params) | |||
return false; | |||
sandbox_set_param(params, "rackGlobal", assetGlobal("").c_str()); | |||
sandbox_set_param(params, "rackLocal", assetLocal("").c_str()); | |||
*/ | |||
std::string profilePath = assetGlobal("Rack.sb").c_str(); | |||
FILE *file = fopen(profilePath.c_str(), "rb"); | |||
if(!file) { | |||
info("Couldn't read sandbox profile"); | |||
return false; | |||
} | |||
fseek(file, 0, SEEK_END); | |||
long fsize = ftell(file); | |||
fseek(file, 0, SEEK_SET); //same as rewind(f); | |||
char *profileStr = (char*)malloc(fsize + 1); | |||
fread(profileStr, fsize, 1, file); | |||
fclose(file); | |||
profileStr[fsize] = 0; | |||
std::vector<const char *> params; | |||
char resolved_path[PATH_MAX]; | |||
params.push_back("rackGlobal"); | |||
realpath(assetGlobal("").c_str(), resolved_path); | |||
params.push_back(resolved_path); | |||
params.push_back("rackLocal"); | |||
realpath(assetLocal("").c_str(), resolved_path); | |||
params.push_back(resolved_path); | |||
// The parameters array is null terminated. | |||
params.push_back(nullptr); | |||
char* error_buff = nullptr; | |||
int error = sandbox_init_with_parameters(profileStr, SANDBOX_STRING, params.data(), &error_buff); | |||
bool success = (error == 0 && error_buff == NULL); | |||
if(!success) { | |||
info("Sandbox initialization error (%d): %s", error, error_buff); | |||
@@ -16,6 +74,11 @@ bool sandboxInit() { | |||
} | |||
sandbox_free_error(error_buff); | |||
FILE *file2 = fopen("/Users/jon/Documents/mg.txt", "rb"); | |||
if(!file2) { | |||
info("Couldn't read private file"); | |||
} | |||
return success; | |||
} | |||