commit 4c1a2d2

shtrophic  ·  2025-01-20 21:59:30 +0000 UTC
parent 4e3d596
add port parsing for sandboxing
4 files changed,  +70, -18
M snac.h
+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,
+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+}