add port parsing for sandboxing

This commit is contained in:
shtrophic
2025-01-20 22:59:30 +01:00
parent 4e3d596bee
commit 4c1a2d24d3
4 changed files with 70 additions and 18 deletions
+2 -2
View File
@@ -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"),
+15 -16
View File
@@ -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) */
+1
View File
@@ -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,
+52
View File
@@ -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;
}