aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--Makefile5
-rw-r--r--README.md4
-rw-r--r--gmid.c53
-rw-r--r--gmid.h17
-rw-r--r--sandbox.c71
6 files changed, 105 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index ee5c066..b994993 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
2021-01-15 Omar Polo <op@omarpolo.com>
+ * sandbox.c (sandbox): sandbox on OpenBSD (pledge/unveil, as before) and on FreeBSD (capsicum) too
+
* sample.conf: added sample configuration
* gmid.c (main): changed behaviour: daemon off by default
diff --git a/Makefile b/Makefile
index fe3b4ce..c405482 100644
--- a/Makefile
+++ b/Makefile
@@ -14,8 +14,9 @@ lex.yy.c: lex.l y.tab.c
y.tab.c: parse.y
${YACC} -b y -d parse.y
-gmid: gmid.o iri.o utf8.o lex.yy.o y.tab.o
- ${CC} gmid.o iri.o utf8.o lex.yy.o y.tab.o -o gmid ${LDFLAGS}
+OBJS = gmid.o iri.o utf8.o lex.yy.o y.tab.o sandbox.o
+gmid: ${OBJS}
+ ${CC} ${OBJS} -o gmid ${LDFLAGS}
TAGS: gmid.c iri.c utf8.c
-etags gmid.c iri.c utf8.c || true
diff --git a/README.md b/README.md
index b9dd29e..658208f 100644
--- a/README.md
+++ b/README.md
@@ -22,6 +22,7 @@ CGI scripts are enabled, while the given directory is unveiled with
- (very) low memory footprint
- small codebase, easily hackable
- virtual hosts
+ - sandboxed on OpenBSD and FreeBSD
## Drawbacks
@@ -30,6 +31,9 @@ CGI scripts are enabled, while the given directory is unveiled with
connection per-second you'd probably want to run multiple gmid
instances behind relayd/haproxy or a different server.
+ - the sandbox on FreeBSD is **NOT** activated if CGI scripts are
+ enabled: CGI script cannot be used with the way `capsicum(4)` works
+
## Building
diff --git a/gmid.c b/gmid.c
index f69df77..6eed3f6 100644
--- a/gmid.c
+++ b/gmid.c
@@ -29,11 +29,6 @@
#include "gmid.h"
-#define LOGE(c, fmt, ...) logs(LOG_ERR, c, fmt, __VA_ARGS__)
-#define LOGN(c, fmt, ...) logs(LOG_NOTICE, c, fmt, __VA_ARGS__)
-#define LOGI(c, fmt, ...) logs(LOG_INFO, c, fmt, __VA_ARGS__)
-#define LOGD(c, fmt, ...) logs(LOG_DEBUG, c, fmt, __VA_ARGS__)
-
struct vhost hosts[HOSTSLEN];
int connected_clients;
@@ -90,8 +85,7 @@ fatal(const char *fmt, ...)
exit(1);
}
-__attribute__ ((format (printf, 3, 4)))
-static inline void
+void
logs(int priority, struct client *c,
const char *fmt, ...)
{
@@ -103,13 +97,18 @@ logs(int priority, struct client *c,
va_start(ap, fmt);
- len = sizeof(c->addr);
- ec = getnameinfo((struct sockaddr*)&c->addr, len,
- hbuf, sizeof(hbuf),
- sbuf, sizeof(sbuf),
- NI_NUMERICHOST | NI_NUMERICSERV);
- if (ec != 0)
- fatal("getnameinfo: %s", gai_strerror(ec));
+ if (c == NULL) {
+ strncpy(hbuf, "<internal>", sizeof(hbuf));
+ sbuf[0] = '\0';
+ } else {
+ len = sizeof(c->addr);
+ ec = getnameinfo((struct sockaddr*)&c->addr, len,
+ hbuf, sizeof(hbuf),
+ sbuf, sizeof(sbuf),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (ec != 0)
+ fatal("getnameinfo: %s", gai_strerror(ec));
+ }
if (vasprintf(&fmted, fmt, ap) == -1)
fatal("vasprintf: %s", strerror(errno));
@@ -961,30 +960,6 @@ load_vhosts(struct tls_config *tlsconf)
}
}
-/* we can augment this function to handle also capsicum and seccomp eventually */
-void
-sandbox()
-{
- struct vhost *h;
- int has_cgi = 0;
-
- for (h = hosts; h->domain != NULL; ++h) {
- if (unveil(h->dir, "rx") == -1)
- err(1, "unveil %s for domain %s", h->dir, h->domain);
-
- if (h->cgi != NULL)
- has_cgi = 1;
- }
-
- if (pledge("stdio rpath inet proc exec", NULL) == -1)
- err(1, "pledge");
-
- /* drop proc and exec if cgi isn't enabled */
- if (!has_cgi)
- if (pledge("stdio rpath inet", NULL) == -1)
- err(1, "pledge");
-}
-
void
usage(const char *me)
{
@@ -1002,7 +977,7 @@ main(int argc, char **argv)
int sock4, sock6, ch;
const char *config_path = NULL;
size_t i;
- int conftest = 0, has_cgi = 0;
+ int conftest = 0;
bzero(hosts, sizeof(hosts));
for (i = 0; i < HOSTSLEN; ++i)
diff --git a/gmid.h b/gmid.h
index cbf9da3..3477cfe 100644
--- a/gmid.h
+++ b/gmid.h
@@ -28,11 +28,6 @@
#include <tls.h>
#include <unistd.h>
-#ifndef __OpenBSD__
-# define pledge(a, b) 0
-# define unveil(a, b) 0
-#endif
-
#ifndef INFTIM
# define INFTIM -1
#endif
@@ -52,6 +47,12 @@
#define HOSTSLEN 64
+#define LOGE(c, fmt, ...) logs(LOG_ERR, c, fmt, __VA_ARGS__)
+#define LOGW(c, fmt, ...) logs(LOG_WARNING, c, fmt, __VA_ARGS__)
+#define LOGN(c, fmt, ...) logs(LOG_NOTICE, c, fmt, __VA_ARGS__)
+#define LOGI(c, fmt, ...) logs(LOG_INFO, c, fmt, __VA_ARGS__)
+#define LOGD(c, fmt, ...) logs(LOG_DEBUG, c, fmt, __VA_ARGS__)
+
struct vhost {
const char *domain;
const char *cert;
@@ -118,6 +119,8 @@ enum {
};
/* gmid.c */
+__attribute__ ((format (printf, 3, 4))) void logs(int, struct client*, const char*, ...);
+
void sig_handler(int);
int starts_with(const char*, const char*);
@@ -149,7 +152,6 @@ void yyerror(const char*);
int parse_portno(const char*);
void parse_conf(const char*);
void load_vhosts(struct tls_config*);
-void sandbox();
void usage(const char*);
@@ -158,6 +160,9 @@ extern int yylineno;
extern int yyparse(void);
extern int yylex(void);
+/* sandbox.c */
+void sandbox();
+
/* utf8.c */
int valid_multibyte_utf8(struct parser*);
diff --git a/sandbox.c b/sandbox.c
new file mode 100644
index 0000000..6618e5d
--- /dev/null
+++ b/sandbox.c
@@ -0,0 +1,71 @@
+#include "gmid.h"
+
+#if defined(__FreeBSD__)
+
+#include <sys/capsicum.h>
+#include <err.h>
+
+void
+sandbox()
+{
+ struct vhost *h;
+ int has_cgi = 0;
+
+ for (h = hosts; h->domain != NULL; ++h)
+ if (h->cgi != NULL)
+ has_cgi = 1;
+
+ if (has_cgi) {
+ LOGW(NULL, "disabling sandbox because CGI scripts are enabled");
+ return;
+ }
+
+ if (cap_enter() == -1)
+ err(1, "cap_enter");
+}
+
+#elif defined(__linux__)
+
+void
+sandbox()
+{
+ /* TODO: seccomp */
+}
+
+#elif defined(__OpenBSD__)
+
+#include <err.h>
+#include <unistd.h>
+
+void
+sandbox()
+{
+ struct vhost *h;
+ int has_cgi = 0;
+
+ for (h = hosts; h->domain != NULL; ++h) {
+ if (unveil(h->dir, "rx") == -1)
+ err(1, "unveil %s for domain %s", h->dir, h->domain);
+
+ if (h->cgi != NULL)
+ has_cgi = 1;
+ }
+
+ if (pledge("stdio rpath inet proc exec", NULL) == -1)
+ err(1, "pledge");
+
+ /* drop proc and exec if cgi isn't enabled */
+ if (!has_cgi)
+ if (pledge("stdio rpath inet", NULL) == -1)
+ err(1, "pledge");
+}
+
+#else
+
+void
+sandbox()
+{
+ LOGN(NULL, "%s", "no sandbox method known for this OS");
+}
+
+#endif