about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-08-30 14:15:41 -0400
committerJune McEnroe <june@causal.agency>2020-08-30 14:15:41 -0400
commitfd36b26b99ccd13489441e04966e978664967997 (patch)
tree04043a2efcbbe76455e850290d5cec33d7932244
parentRefactor certificate loading and load all certs from config paths (diff)
downloadpounce-fd36b26b99ccd13489441e04966e978664967997.tar.gz
pounce-fd36b26b99ccd13489441e04966e978664967997.zip
Sandbox pounce with unveil(2)
-rw-r--r--README.714
-rw-r--r--bounce.c46
2 files changed, 58 insertions, 2 deletions
diff --git a/README.7 b/README.7
index 0d6bc16..241627c 100644
--- a/README.7
+++ b/README.7
@@ -1,4 +1,4 @@
-.Dd August 28, 2020
+.Dd August 30, 2020
 .Dt README 7
 .Os "Causal Agency"
 .
@@ -51,9 +51,19 @@ or by LibreSSL.
 It primarily targets
 .Fx ,
 where it is sandboxed with
-.Xr capsicum 4 .
+.Xr capsicum 4 ,
+and
+.Ox ,
+where it is sandboxed with
+.Xr pledge 2
+and
+.Xr unveil 2 .
 Linux and macOS
 are also supported.
+On
+.Ox ,
+configure with
+.Fl \-mandir=/usr/local/man .
 .Bd -literal -offset indent
 \&./configure
 make all
diff --git a/bounce.c b/bounce.c
index 67b5f99..4d9b077 100644
--- a/bounce.c
+++ b/bounce.c
@@ -184,6 +184,41 @@ static void capLimit(int fd, const cap_rights_t *rights) {
 }
 #endif
 
+#ifdef __OpenBSD__
+static void unveilParent(const char *path, const char *mode) {
+	char buf[PATH_MAX];
+	strlcpy(buf, path, sizeof(buf));
+	char *base = strrchr(buf, '/');
+	if (base) *base = '\0';
+	int error = unveil((base ? buf : "."), mode);
+	if (error && errno != ENOENT) err(EX_OSERR, "unveil");
+}
+static void unveilTarget(const char *path, const char *mode) {
+	char buf[PATH_MAX];
+	strlcpy(buf, path, sizeof(buf));
+	char *base = strrchr(buf, '/');
+	base = (base ? base + 1 : buf);
+	ssize_t len = readlink(path, base, sizeof(buf) - (base - buf) - 1);
+	if (len < 0) return;
+	base[len] = '\0';
+	unveilParent(buf, mode);
+}
+static void unveilConfig(const char *path) {
+	const char *dirs = NULL;
+	for (const char *abs; NULL != (abs = configPath(&dirs, path));) {
+		unveilParent(abs, "r");
+		unveilTarget(abs, "r");
+	}
+}
+static void unveilData(const char *path) {
+	const char *dirs = NULL;
+	for (const char *abs; NULL != (abs = dataPath(&dirs, path));) {
+		int error = unveil(abs, "rwc");
+		if (error && errno != ENOENT) err(EX_OSERR, "unveil");
+	}
+}
+#endif
+
 static volatile sig_atomic_t signals[NSIG];
 static void signalHandler(int signal) {
 	signals[signal] = 1;
@@ -364,6 +399,17 @@ int main(int argc, char *argv[]) {
 	}
 
 #ifdef __OpenBSD__
+	unveilConfig(certPath);
+	unveilConfig(privPath);
+	if (caPath) unveilConfig(caPath);
+	if (clientCert) unveilConfig(clientCert);
+	if (clientPriv) unveilConfig(clientPriv);
+	if (savePath) unveilData(savePath);
+	if (bindPath[0]) unveilParent(bindPath, "rwc");
+
+	error = unveil(tls_default_ca_cert_file(), "r");
+	if (error) err(EX_OSFILE, "%s", tls_default_ca_cert_file());
+
 	error = pledge("stdio rpath wpath cpath inet flock unix dns recvfd", NULL);
 	if (error) err(EX_OSERR, "pledge");
 #endif