commit 4c1a2d24d374d00c656c4489db7d28f80d64f9dc
parent 4e3d596bee1cee2c4146265eb6ac827f09820c53
Author: shtrophic <christoph@liebender.dev>
Date: Mon, 20 Jan 2025 22:59:30 +0100
add port parsing for sandboxing
Diffstat:
4 files changed, 70 insertions(+), 18 deletions(-)
diff --git a/activitypub.c b/activitypub.c
@@ -2465,9 +2465,9 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
int send_email(const xs_dict *mailinfo)
-/* invoke sendmail with email headers and body in msg */
+/* invoke curl */
{
- const xs_dict *smtp_cfg = xs_dict_get(srv_config, "smtp");
+ const xs_dict *smtp_cfg = xs_dict_get(srv_config, "email_notifications");
const char
*url = xs_dict_get(smtp_cfg, "url"),
*user = xs_dict_get(smtp_cfg, "username"),
diff --git a/sandbox.c b/sandbox.c
@@ -8,8 +8,6 @@ void sbox_enter(const char *basedir)
{
const char *address = xs_dict_get(srv_config, "address");
- int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
-
if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
srv_log(xs_dup("OpenBSD security disabled by admin"));
return;
@@ -24,9 +22,6 @@ void sbox_enter(const char *basedir)
unveil("/etc/ssl/cert.pem", "r");
unveil("/usr/share/zoneinfo", "r");
- if (smail)
- unveil("/usr/sbin/sendmail", "x");
-
if (*address == '/')
unveil(address, "rwc");
@@ -36,9 +31,6 @@ void sbox_enter(const char *basedir)
xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
- if (smail)
- p = xs_str_cat(p, " exec");
-
if (*address == '/')
p = xs_str_cat(p, " unix");
@@ -55,7 +47,7 @@ void sbox_enter(const char *basedir)
#include "landloc.h"
static
-LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) {
+LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smtp_port) {
const unsigned long long
rd = LANDLOCK_ACCESS_FS_READ_DIR,
@@ -94,9 +86,6 @@ LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail)
LL_PATH(sdir, s);
}
- if (smail && mtime("/usr/sbin/sendmail") > 0)
- LL_PATH("/usr/sbin/sendmail", x);
-
if (*address != '/') {
unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
@@ -104,24 +93,34 @@ LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail)
LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
+ if (smtp_port > 0)
+ LL_PORT((unsigned short)smtp_port, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
} LL_END
void sbox_enter(const char *basedir)
{
+ const xs_val *v;
+ const char *errstr;
const char *address = xs_dict_get(srv_config, "address");
-
- int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
+ int smtp_port = -1;
if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
srv_debug(1, xs_dup("Linux sandbox disabled by admin"));
return;
}
- if (sbox_enter_linux_(basedir, address, smail) == 0)
+ if ((v = xs_dict_get(srv_config, "email_notifications")) &&
+ (v = xs_dict_get(v, "url"))) {
+ smtp_port = parse_port((const char *)v, &errstr);
+ if (errstr)
+ srv_debug(0, xs_fmt("Couldn't determine port from '%s': %s", (const char *)v, errstr));
+ }
+
+ if (sbox_enter_linux_(basedir, address, smtp_port) == 0)
srv_debug(1, xs_dup("Linux sandbox enabled"));
else
- srv_debug(1, xs_dup("Linux sandbox failed"));
+ srv_debug(0, xs_dup("Linux sandbox failed"));
}
#else /* defined(WITH_LINUX_SANDBOX) */
diff --git a/snac.h b/snac.h
@@ -417,6 +417,7 @@ void import_blocked_accounts_csv(snac *user, const char *fn);
void import_following_accounts_csv(snac *user, const char *fn);
void import_list_csv(snac *user, const char *fn);
void import_csv(snac *user);
+int parse_port(const char *url, const char **errstr);
typedef enum {
#define HTTP_STATUS(code, name, text) HTTP_STATUS_ ## name = code,
diff --git a/utils.c b/utils.c
@@ -904,3 +904,55 @@ void import_csv(snac *user)
else
snac_log(user, xs_fmt("Cannot open file %s", fn));
}
+
+static const struct {
+ const char *proto;
+ unsigned short default_port;
+} FALLBACK_PORTS[] = {
+ /* caution: https > http, smpts > smtp */
+ {"https", 443},
+ {"http", 80},
+ {"smtps", 465},
+ {"smtp", 25}
+};
+
+int parse_port(const char *url, const char **errstr)
+{
+ const char *col, *rcol;
+ int tmp, ret = -1;
+
+ if (errstr)
+ *errstr = NULL;
+
+ if (!(col = strchr(url, ':'))) {
+ if (errstr)
+ *errstr = "bad url";
+ return -1;
+ }
+
+ for (size_t i = 0; i < sizeof(FALLBACK_PORTS) / sizeof(*FALLBACK_PORTS); ++i) {
+ if (memcmp(url, FALLBACK_PORTS[i].proto, strlen(FALLBACK_PORTS[i].proto)) == 0) {
+ ret = FALLBACK_PORTS[i].default_port;
+ break;
+ }
+ }
+
+ if (!(rcol = strchr(col + 1, ':')))
+ rcol = col;
+
+ if (rcol) {
+ tmp = atoi(rcol + 1);
+ if (tmp == 0) {
+ if (ret != -1)
+ return ret;
+
+ *errstr = strerror(errno);
+ return -1;
+ }
+
+ return tmp;
+ }
+
+ *errstr = "unknown protocol";
+ return -1;
+}