commit 4c1a2d2
shtrophic
·
2025-01-20 21:59:30 +0000 UTC
parent 4e3d596
add port parsing for sandboxing
4 files changed,
+70,
-18
+2,
-2
1@@ -2465,9 +2465,9 @@ int process_input_message(snac *snac, const xs_dict *msg, const xs_dict *req)
2
3
4 int send_email(const xs_dict *mailinfo)
5-/* invoke sendmail with email headers and body in msg */
6+/* invoke curl */
7 {
8- const xs_dict *smtp_cfg = xs_dict_get(srv_config, "smtp");
9+ const xs_dict *smtp_cfg = xs_dict_get(srv_config, "email_notifications");
10 const char
11 *url = xs_dict_get(smtp_cfg, "url"),
12 *user = xs_dict_get(smtp_cfg, "username"),
+15,
-16
1@@ -8,8 +8,6 @@ void sbox_enter(const char *basedir)
2 {
3 const char *address = xs_dict_get(srv_config, "address");
4
5- int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
6-
7 if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
8 srv_log(xs_dup("OpenBSD security disabled by admin"));
9 return;
10@@ -24,9 +22,6 @@ void sbox_enter(const char *basedir)
11 unveil("/etc/ssl/cert.pem", "r");
12 unveil("/usr/share/zoneinfo", "r");
13
14- if (smail)
15- unveil("/usr/sbin/sendmail", "x");
16-
17 if (*address == '/')
18 unveil(address, "rwc");
19
20@@ -36,9 +31,6 @@ void sbox_enter(const char *basedir)
21
22 xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
23
24- if (smail)
25- p = xs_str_cat(p, " exec");
26-
27 if (*address == '/')
28 p = xs_str_cat(p, " unix");
29
30@@ -55,7 +47,7 @@ void sbox_enter(const char *basedir)
31 #include "landloc.h"
32
33 static
34-LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) {
35+LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smtp_port) {
36
37 const unsigned long long
38 rd = LANDLOCK_ACCESS_FS_READ_DIR,
39@@ -94,9 +86,6 @@ LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail)
40 LL_PATH(sdir, s);
41 }
42
43- if (smail && mtime("/usr/sbin/sendmail") > 0)
44- LL_PATH("/usr/sbin/sendmail", x);
45-
46 if (*address != '/') {
47 unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
48 LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
49@@ -104,24 +93,34 @@ LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail)
50
51 LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
52 LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
53+ if (smtp_port > 0)
54+ LL_PORT((unsigned short)smtp_port, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
55
56 } LL_END
57
58 void sbox_enter(const char *basedir)
59 {
60+ const xs_val *v;
61+ const char *errstr;
62 const char *address = xs_dict_get(srv_config, "address");
63-
64- int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
65+ int smtp_port = -1;
66
67 if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
68 srv_debug(1, xs_dup("Linux sandbox disabled by admin"));
69 return;
70 }
71
72- if (sbox_enter_linux_(basedir, address, smail) == 0)
73+ if ((v = xs_dict_get(srv_config, "email_notifications")) &&
74+ (v = xs_dict_get(v, "url"))) {
75+ smtp_port = parse_port((const char *)v, &errstr);
76+ if (errstr)
77+ srv_debug(0, xs_fmt("Couldn't determine port from '%s': %s", (const char *)v, errstr));
78+ }
79+
80+ if (sbox_enter_linux_(basedir, address, smtp_port) == 0)
81 srv_debug(1, xs_dup("Linux sandbox enabled"));
82 else
83- srv_debug(1, xs_dup("Linux sandbox failed"));
84+ srv_debug(0, xs_dup("Linux sandbox failed"));
85 }
86
87 #else /* defined(WITH_LINUX_SANDBOX) */
M
snac.h
+1,
-0
1@@ -417,6 +417,7 @@ void import_blocked_accounts_csv(snac *user, const char *fn);
2 void import_following_accounts_csv(snac *user, const char *fn);
3 void import_list_csv(snac *user, const char *fn);
4 void import_csv(snac *user);
5+int parse_port(const char *url, const char **errstr);
6
7 typedef enum {
8 #define HTTP_STATUS(code, name, text) HTTP_STATUS_ ## name = code,
M
utils.c
+52,
-0
1@@ -904,3 +904,55 @@ void import_csv(snac *user)
2 else
3 snac_log(user, xs_fmt("Cannot open file %s", fn));
4 }
5+
6+static const struct {
7+ const char *proto;
8+ unsigned short default_port;
9+} FALLBACK_PORTS[] = {
10+ /* caution: https > http, smpts > smtp */
11+ {"https", 443},
12+ {"http", 80},
13+ {"smtps", 465},
14+ {"smtp", 25}
15+};
16+
17+int parse_port(const char *url, const char **errstr)
18+{
19+ const char *col, *rcol;
20+ int tmp, ret = -1;
21+
22+ if (errstr)
23+ *errstr = NULL;
24+
25+ if (!(col = strchr(url, ':'))) {
26+ if (errstr)
27+ *errstr = "bad url";
28+ return -1;
29+ }
30+
31+ for (size_t i = 0; i < sizeof(FALLBACK_PORTS) / sizeof(*FALLBACK_PORTS); ++i) {
32+ if (memcmp(url, FALLBACK_PORTS[i].proto, strlen(FALLBACK_PORTS[i].proto)) == 0) {
33+ ret = FALLBACK_PORTS[i].default_port;
34+ break;
35+ }
36+ }
37+
38+ if (!(rcol = strchr(col + 1, ':')))
39+ rcol = col;
40+
41+ if (rcol) {
42+ tmp = atoi(rcol + 1);
43+ if (tmp == 0) {
44+ if (ret != -1)
45+ return ret;
46+
47+ *errstr = strerror(errno);
48+ return -1;
49+ }
50+
51+ return tmp;
52+ }
53+
54+ *errstr = "unknown protocol";
55+ return -1;
56+}