snac2

Fork of https://codeberg.org/grunfink/snac2
git clone https://git.inz.fi/snac2
Log | Files | Refs | README | LICENSE

commit 4c1a2d24d374d00c656c4489db7d28f80d64f9dc
parent 4e3d596bee1cee2c4146265eb6ac827f09820c53
Author: shtrophic <christoph@liebender.dev>
Date:   Mon, 20 Jan 2025 22:59:30 +0100

add port parsing for sandboxing

Diffstat:
Mactivitypub.c | 4++--
Msandbox.c | 31+++++++++++++++----------------
Msnac.h | 1+
Mutils.c | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
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; +}