Sandbox with unveil(2) on OpenBSD in restricted mode
I wrote all this in vi and it was nice.weechat-hashes
parent
c6cd90c2dd
commit
df280aa7d6
58
chat.c
58
chat.c
|
@ -40,6 +40,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <sysexits.h>
|
#include <sysexits.h>
|
||||||
|
#include <tls.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
|
@ -123,6 +124,54 @@ static void parseHash(char *str) {
|
||||||
if (*str) hashBound = strtoul(&str[1], NULL, 0);
|
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 volatile sig_atomic_t signals[NSIG];
|
||||||
static void signalHandler(int signal) {
|
static void signalHandler(int signal) {
|
||||||
signals[signal] = 1;
|
signals[signal] = 1;
|
||||||
|
@ -131,11 +180,6 @@ static void signalHandler(int signal) {
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
setlocale(LC_CTYPE, "");
|
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 insecure = false;
|
||||||
bool printCert = false;
|
bool printCert = false;
|
||||||
const char *bind = NULL;
|
const char *bind = NULL;
|
||||||
|
@ -237,6 +281,10 @@ int main(int argc, char *argv[]) {
|
||||||
editCompleteAdd();
|
editCompleteAdd();
|
||||||
commandCompleteAdd();
|
commandCompleteAdd();
|
||||||
|
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
sandbox(trust, cert, priv);
|
||||||
|
#endif
|
||||||
|
|
||||||
ircConfig(insecure, trust, cert, priv);
|
ircConfig(insecure, trust, cert, priv);
|
||||||
if (printCert) {
|
if (printCert) {
|
||||||
ircConnect(bind, host, port);
|
ircConnect(bind, host, port);
|
||||||
|
|
Loading…
Reference in New Issue