@@ -5,7 +5,6 @@ FLAGS += \ | |||||
SOURCES = $(wildcard src/*.cpp src/*/*.cpp) \ | SOURCES = $(wildcard src/*.cpp src/*/*.cpp) \ | ||||
ext/nanovg/src/nanovg.c | ext/nanovg/src/nanovg.c | ||||
include arch.mk | include arch.mk | ||||
ifeq ($(ARCH), lin) | ifeq ($(ARCH), lin) | ||||
@@ -23,7 +22,7 @@ ifeq ($(ARCH), mac) | |||||
CXXFLAGS += -DAPPLE -stdlib=libc++ | CXXFLAGS += -DAPPLE -stdlib=libc++ | ||||
LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | LDFLAGS += -stdlib=libc++ -lpthread -ldl \ | ||||
-framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo \ | -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 | TARGET = Rack | ||||
BUNDLE = dist/$(TARGET).app | BUNDLE = dist/$(TARGET).app | ||||
endif | endif | ||||
@@ -93,6 +92,7 @@ ifeq ($(ARCH), mac) | |||||
mkdir -p $(BUNDLE)/Contents/Resources | mkdir -p $(BUNDLE)/Contents/Resources | ||||
cp Info.plist $(BUNDLE)/Contents/ | cp Info.plist $(BUNDLE)/Contents/ | ||||
cp -R LICENSE* res $(BUNDLE)/Contents/Resources | cp -R LICENSE* res $(BUNDLE)/Contents/Resources | ||||
cp Rack.sb $(BUNDLE)/Contents/Resources | |||||
mkdir -p $(BUNDLE)/Contents/MacOS | mkdir -p $(BUNDLE)/Contents/MacOS | ||||
cp Rack $(BUNDLE)/Contents/MacOS/ | cp Rack $(BUNDLE)/Contents/MacOS/ | ||||
@@ -0,0 +1,25 @@ | |||||
(version 1) | |||||
(import "system.sb") | |||||
(allow ipc-posix-shm) | |||||
(allow network-outbound) | |||||
(allow network-inbound) | |||||
(allow sysctl-read) | |||||
(allow file-read-metadata) | |||||
(allow signal) | |||||
(allow iokit-open) | |||||
(allow mach-lookup) | |||||
(allow system-socket) | |||||
(allow file-read* (subpath (param "rackLocal"))) | |||||
(allow file-write* (subpath (param "rackLocal"))) | |||||
(allow file-read* (subpath (param "rackGlobal"))) | |||||
(deny default) |
@@ -0,0 +1,5 @@ | |||||
#pragma once | |||||
namespace rack { | |||||
bool sandboxInit(); | |||||
} |
@@ -1,6 +1,7 @@ | |||||
#include "engine.hpp" | #include "engine.hpp" | ||||
#include "gui.hpp" | #include "gui.hpp" | ||||
#include "app.hpp" | #include "app.hpp" | ||||
#include "sandbox.hpp" | |||||
#include "plugin.hpp" | #include "plugin.hpp" | ||||
#include "settings.hpp" | #include "settings.hpp" | ||||
#include "asset.hpp" | #include "asset.hpp" | ||||
@@ -31,6 +32,10 @@ int main(int argc, char* argv[]) { | |||||
info("Local directory: %s", localDir.c_str()); | info("Local directory: %s", localDir.c_str()); | ||||
} | } | ||||
if(!sandboxInit()) { | |||||
info("Refusing to run without sandbox"); | |||||
exit(1); | |||||
} | |||||
pluginInit(); | pluginInit(); | ||||
engineInit(); | engineInit(); | ||||
guiInit(); | guiInit(); | ||||
@@ -0,0 +1,85 @@ | |||||
#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* 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); | |||||
} else { | |||||
info("Sandbox initialized!"); | |||||
} | |||||
sandbox_free_error(error_buff); | |||||
return success; | |||||
} | |||||
#else | |||||
bool sandboxInit() { | |||||
return false; | |||||
} | |||||
#endif | |||||
} |