summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chat.c132
1 files changed, 80 insertions, 52 deletions
diff --git a/chat.c b/chat.c
index 0756450..106e05f 100644
--- a/chat.c
+++ b/chat.c
@@ -136,6 +136,84 @@ static void signalHandler(int signal) {
signals[signal] = 1;
}
+static void sandboxEarly(bool log);
+static void sandboxLate(int irc);
+
+#if defined __OpenBSD__
+
+static char *promisesInitial;
+static char promises[64] = "stdio tty";
+
+static void sandboxEarly(bool log) {
+ char *ptr = &promises[strlen(promises)];
+ char *end = &promises[sizeof(promises)];
+
+ if (log) {
+ const char *logdir = dataMkdir("log");
+ int error = unveil(logdir, "wc");
+ if (error) err(EX_OSERR, "unveil");
+ ptr = seprintf(ptr, end, " wpath cpath");
+ }
+
+ if (!self.restricted) {
+ int error = unveil("/", "x");
+ if (error) err(EX_OSERR, "unveil");
+ ptr = seprintf(ptr, end, " proc exec");
+ }
+
+ promisesInitial = ptr;
+ ptr = seprintf(ptr, end, " inet dns");
+ int error = pledge(promises, NULL);
+ if (error) err(EX_OSERR, "pledge");
+}
+
+static void sandboxLate(int irc) {
+ (void)irc;
+ *promisesInitial = '\0';
+ int error = pledge(promises, NULL);
+ if (error) err(EX_OSERR, "pledge");
+}
+
+#elif defined __FreeBSD__
+
+static void sandboxEarly(bool log) {
+ (void)log;
+}
+
+static void sandboxLate(int irc) {
+ if (!self.restricted) return;
+
+ // Rights are also limited in uiLoad() and logOpen().
+ cap_rights_t rights;
+ int error = 0
+ || caph_limit_stdin()
+ || caph_rights_limit(
+ STDOUT_FILENO, cap_rights_init(&rights, CAP_WRITE, CAP_IOCTL)
+ )
+ || caph_limit_stderr()
+ || caph_rights_limit(
+ irc, cap_rights_init(&rights, CAP_SEND, CAP_RECV, CAP_EVENT)
+ );
+ if (error) err(EX_OSERR, "cap_rights_limit");
+
+ // caph_cache_tzdata(3) doesn't load UTC info, which we need for
+ // certificate verification. gmtime(3) does.
+ caph_cache_tzdata();
+ gmtime(&(time_t) { time(NULL) });
+
+ error = caph_enter();
+ if (error) err(EX_OSERR, "caph_enter");
+}
+
+#else
+static void sandboxEarly(bool log) {
+ (void)log;
+}
+static void sandboxLate(int irc) {
+ (void)irc;
+}
+#endif
+
int main(int argc, char *argv[]) {
setlocale(LC_CTYPE, "");
@@ -289,60 +367,10 @@ int main(int argc, char *argv[]) {
);
uiFormat(Network, Cold, NULL, "Traveling...");
uiDraw();
-
-#ifdef __OpenBSD__
- char promises[64] = "stdio tty";
- char *ptr = &promises[strlen(promises)], *end = &promises[sizeof(promises)];
-
- if (log) {
- const char *logdir = dataMkdir("log");
- int error = unveil(logdir, "wc");
- if (error) err(EX_OSERR, "unveil");
- ptr = seprintf(ptr, end, " wpath cpath");
- }
-
- if (!self.restricted) {
- int error = unveil("/", "x");
- if (error) err(EX_OSERR, "unveil");
- ptr = seprintf(ptr, end, " proc exec");
- }
-
- char *promisesInitial = ptr;
- ptr = seprintf(ptr, end, " inet dns");
- int error = pledge(promises, NULL);
- if (error) err(EX_OSERR, "pledge");
-#endif
+ sandboxEarly(log);
int irc = ircConnect(bind, host, port);
-
-#ifdef __OpenBSD__
- *promisesInitial = '\0';
- error = pledge(promises, NULL);
- if (error) err(EX_OSERR, "pledge");
-#endif
-
-#ifdef __FreeBSD__
- cap_rights_t rights;
- int error = 0
- || caph_limit_stdin()
- || caph_rights_limit(
- STDOUT_FILENO, cap_rights_init(&rights, CAP_WRITE, CAP_IOCTL)
- )
- || caph_limit_stderr()
- || caph_rights_limit(
- irc, cap_rights_init(&rights, CAP_SEND, CAP_RECV, CAP_EVENT)
- );
- if (error) err(EX_OSERR, "cap_rights_limit");
-
- if (self.restricted) {
- // caph_cache_tzdata(3) doesn't load UTC info, which we need for
- // certificate verification. gmtime(3) does.
- caph_cache_tzdata();
- gmtime(&(time_t) { time(NULL) });
- error = caph_enter();
- if (error) err(EX_OSERR, "caph_enter");
- }
-#endif
+ sandboxLate(irc);
ircHandshake();
if (pass) {