diff options
author | June McEnroe <june@causal.agency> | 2021-01-10 19:23:01 -0500 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2021-01-10 19:23:01 -0500 |
commit | df280aa7d658163adae378b468db6fe884bbe02e (patch) | |
tree | 4082e39d87bc68e8654ad01c088260c787dee528 | |
parent | Print chain to stdout with -o (diff) | |
download | catgirl-df280aa7d658163adae378b468db6fe884bbe02e.tar.gz catgirl-df280aa7d658163adae378b468db6fe884bbe02e.zip |
Sandbox with unveil(2) on OpenBSD in restricted mode
I wrote all this in vi and it was nice.
-rw-r--r-- | chat.c | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/chat.c b/chat.c index 3f020fd..b4458be 100644 --- a/chat.c +++ b/chat.c @@ -40,6 +40,7 @@ #include <sys/stat.h> #include <sys/wait.h> #include <sysexits.h> +#include <tls.h> #include <unistd.h> #include "chat.h" @@ -123,6 +124,54 @@ static void parseHash(char *str) { if (*str) hashBound = strtoul(&str[1], NULL, 0); } +#ifdef __OpenBSD__ + +static void unveilConfig(const char *name) { + const char *dirs = NULL; + for (const char *path; NULL != (path = configPath(&dirs, name));) { + int error = unveil(path, "r"); + if (error && errno != ENOENT) err(EX_NOINPUT, "%s", path); + } +} + +static void unveilData(const char *name) { + const char *dirs = NULL; + for (const char *path; NULL != (path = dataPath(&dirs, name));) { + int error = unveil(path, "rwc"); + if (error && errno != ENOENT) err(EX_CANTCREAT, "%s", path); + } +} + +static void sandbox(const char *trust, const char *cert, const char *priv) { + int error = pledge( + "stdio rpath wpath cpath inet dns tty proc exec unveil", NULL + ); + if (error) err(EX_OSERR, "pledge"); + if (!self.restricted) return; + + dataMkdir(""); + unveilData(""); + if (trust) unveilConfig(trust); + if (cert) unveilConfig(cert); + if (priv) unveilConfig(priv); + if (save) unveilData(save); + struct { + const char *path; + const char *perm; + } paths[] = { + { "/usr/bin/man", "x" }, + { "/usr/share/terminfo", "r" }, + { tls_default_ca_cert_file(), "r" }, + { NULL, NULL }, + }; + for (size_t i = 0; i < ARRAY_LEN(paths); ++i) { + int error = unveil(paths[i].path, paths[i].perm); + if (error) err(EX_OSFILE, "%s", paths[i].path); + } +} + +#endif /* __OpenBSD__ */ + static volatile sig_atomic_t signals[NSIG]; static void signalHandler(int signal) { signals[signal] = 1; @@ -131,11 +180,6 @@ static void signalHandler(int signal) { int main(int argc, char *argv[]) { setlocale(LC_CTYPE, ""); -#ifdef __OpenBSD__ - int error = pledge("stdio rpath wpath cpath inet dns tty proc exec", NULL); - if (error) err(EX_OSERR, "pledge"); -#endif - bool insecure = false; bool printCert = false; const char *bind = NULL; @@ -237,6 +281,10 @@ int main(int argc, char *argv[]) { editCompleteAdd(); commandCompleteAdd(); +#ifdef __OpenBSD__ + sandbox(trust, cert, priv); +#endif + ircConfig(insecure, trust, cert, priv); if (printCert) { ircConnect(bind, host, port); |