From bf082292c260f54108295ec04bc1987aabf11a8d Mon Sep 17 00:00:00 2001 From: Yves Rutschle Date: Sun, 22 Dec 2024 23:54:14 +0100 Subject: [PATCH] new is_unix field to create listen unix sockets --- ChangeLog | 7 +++++++ common.c | 37 +++++++++++++++++++++++++++++++++++-- common.h | 1 + echosrv-conf.c | 2 +- echosrv-conf.h | 2 +- example.cfg | 3 ++- sslh-conf.c | 23 +++++++++++++++++++++-- sslh-conf.h | 3 ++- sslhconf.cfg | 1 + test.cfg | 3 ++- version.h | 2 +- 11 files changed, 74 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index e870565..83da99a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +vNEXT: + Added a boolean setting "is_unix" for listen and + protocol entries. This will use the 'host' setting + as a path name to a socket file, and connections + (listening or connecting) will be performed on Unix + socket instead of Internet sockets. + v2.1.3: Fix Landlock access to /etc/hosts.deny and /etc/hosts.allow. diff --git a/common.c b/common.c index 441d6be..77a3009 100644 --- a/common.c +++ b/common.c @@ -178,6 +178,7 @@ static int start_listen_inet(struct listen_endpoint *sockfd[], int num_addr, str *sockfd = realloc(*sockfd, num_addr * sizeof(*sockfd[0])); (*sockfd)[num_addr-1].socketfd = listen_single_addr(addr, cfg->keepalive, cfg->is_udp); (*sockfd)[num_addr-1].type = cfg->is_udp ? SOCK_DGRAM : SOCK_STREAM; + (*sockfd)[num_addr-1].family = AF_INET; print_message(msg_config, "%d:\t%s\t[%s] [%s]\n", (*sockfd)[num_addr-1].socketfd, sprintaddr(buf, sizeof(buf), addr), cfg->keepalive ? "keepalive" : "", cfg->is_udp ? "udp" : ""); @@ -186,6 +187,31 @@ static int start_listen_inet(struct listen_endpoint *sockfd[], int num_addr, str return num_addr; } +/* Same, but for UNIX sockets */ +static int start_listen_unix(struct listen_endpoint *sockfd[], int num_addr, struct sslhcfg_listen_item* cfg) +{ + int fd = socket(AF_UNIX, cfg->is_udp ? SOCK_DGRAM : SOCK_STREAM, 0); + CHECK_RES_DIE(fd, "socket(AF_UNIX)"); + + struct sockaddr_un sun; + sun.sun_family = AF_UNIX; + strncpy(sun.sun_path, cfg->host, sizeof(sun.sun_path)-1); + printf("binding [%s]\n", sun.sun_path); + int res = bind(fd, (struct sockaddr*)&sun, sizeof(sun)); + CHECK_RES_DIE(res, "bind(AF_UNIX)"); + + res = listen(fd, 50); + + num_addr++; + *sockfd = realloc(*sockfd, num_addr * sizeof(*sockfd[0])); + (*sockfd)[num_addr-1].socketfd = fd; + (*sockfd)[num_addr-1].type = cfg->is_udp ? SOCK_DGRAM : SOCK_STREAM; + (*sockfd)[num_addr-1].family = AF_INET; + + return num_addr; +} + + /* Starts listening sockets on specified addresses. * OUT: *sockfd[] pointer to newly-allocated array of listen_endpoint objects * Returns number of addresses bound @@ -206,7 +232,11 @@ int start_listen_sockets(struct listen_endpoint *sockfd[]) print_message(msg_config, "Listening to:\n"); for (i = 0; i < cfg.listen_len; i++) { - num_addr = start_listen_inet(sockfd, num_addr, &cfg.listen[i]); + if (cfg.listen[i].is_unix) { + num_addr = start_listen_unix(sockfd, num_addr, &cfg.listen[i]); + } else { + num_addr = start_listen_inet(sockfd, num_addr, &cfg.listen[i]); + } } return num_addr; @@ -425,7 +455,7 @@ static int connect_unix(struct connection *cnx, int fd_from, connect_blocking bl int fd = socket(AF_UNIX, SOCK_STREAM, 0); sun->sun_family = AF_UNIX; - strcpy(sun->sun_path, cnx->proto->host); + strncpy(sun->sun_path, cnx->proto->host, sizeof(sun->sun_path)-1); int res = connect(fd, (struct sockaddr*)sun, sizeof(*sun)); CHECK_RES_RETURN(res, "connect", res); @@ -588,6 +618,9 @@ char* sprintaddr(char* buf, size_t size, struct addrinfo *a) char host[NI_MAXHOST], serv[NI_MAXSERV]; int res; + memset(host, 0, sizeof(host)); + memset(serv, 0, sizeof(serv)); + res = getnameinfo(a->ai_addr, a->ai_addrlen, host, sizeof(host), serv, sizeof(serv), diff --git a/common.h b/common.h index 9dc1c91..02666dc 100644 --- a/common.h +++ b/common.h @@ -132,6 +132,7 @@ struct connection { struct listen_endpoint { int socketfd; /* file descriptor of listening socket */ int type; /* SOCK_DGRAM | SOCK_STREAM */ + int family; /* AF_INET | AF_UNIX */ }; #define FD_CNXCLOSED 0 diff --git a/echosrv-conf.c b/echosrv-conf.c index fc0b3f7..38ca0ed 100644 --- a/echosrv-conf.c +++ b/echosrv-conf.c @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Sun Dec 22 00:05:31 2024. + * on Sun Dec 22 22:40:51 2024. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2024 Yves Rutschle diff --git a/echosrv-conf.h b/echosrv-conf.h index e42361b..3ea2b29 100644 --- a/echosrv-conf.h +++ b/echosrv-conf.h @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Sun Dec 22 00:05:31 2024. + * on Sun Dec 22 22:40:51 2024. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2024 Yves Rutschle diff --git a/example.cfg b/example.cfg index ac727b3..77868af 100644 --- a/example.cfg +++ b/example.cfg @@ -53,7 +53,8 @@ listen: ( { host: "thelonious"; port: "443"; }, { host: "thelonious"; port: "8080"; keepalive: true; }, - { host: "thelonious"; is_udp: true; port: "443" } + { host: "thelonious"; is_udp: true; port: "443"; }, + { host: "/tmp/unix_socket"; is_unix: true; port: ""; } ); # List of protocols diff --git a/sslh-conf.c b/sslh-conf.c index 6602466..e19c74b 100644 --- a/sslh-conf.c +++ b/sslh-conf.c @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Sun Dec 22 16:13:50 2024. + * on Sun Dec 22 22:40:51 2024. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2024 Yves Rutschle @@ -777,7 +777,7 @@ static struct config_desc table_sslhcfg_protocols[] = { }, { 0 } }; - + static struct config_desc table_sslhcfg_listen[] = { @@ -829,6 +829,22 @@ static struct config_desc table_sslhcfg_listen[] = { /* default_val*/ .default_val.def_bool = 0 }, + { + /* name */ "is_unix", + /* type */ CFG_BOOL, + /* sub_group*/ NULL, + /* arg_cl */ NULL, + /* base_addr */ NULL, + /* offset */ offsetof(struct sslhcfg_listen_item, is_unix), + /* offset_len */ 0, + /* offset_present */ 0, + /* size */ sizeof(int), + /* array_type */ -1, + /* mandatory */ 0, + /* optional */ 0, + /* default_val*/ .default_val.def_bool = 0 + }, + { /* name */ "keepalive", /* type */ CFG_BOOL, @@ -2429,6 +2445,9 @@ static void sslhcfg_listen_fprint( fprintf(out, "is_udp: %d", sslhcfg_listen->is_udp); fprintf(out, "\n"); indent(out, depth); + fprintf(out, "is_unix: %d", sslhcfg_listen->is_unix); + fprintf(out, "\n"); + indent(out, depth); fprintf(out, "keepalive: %d", sslhcfg_listen->keepalive); fprintf(out, "\n"); } diff --git a/sslh-conf.h b/sslh-conf.h index b107e04..0abfe8c 100644 --- a/sslh-conf.h +++ b/sslh-conf.h @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Sun Dec 22 16:13:50 2024. + * on Sun Dec 22 22:40:51 2024. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2024 Yves Rutschle @@ -44,6 +44,7 @@ struct sslhcfg_listen_item { char* host; char* port; int is_udp; + int is_unix; int keepalive; }; diff --git a/sslhconf.cfg b/sslhconf.cfg index a5eac71..76eca5d 100644 --- a/sslhconf.cfg +++ b/sslhconf.cfg @@ -98,6 +98,7 @@ config: { { name: "host"; type: "string"; var: true; }, { name: "port"; type: "string"; var: true; }, { name: "is_udp"; type: "bool"; default: false }, + { name: "is_unix"; type: "bool"; default: false }, { name: "keepalive"; type: "bool"; default: false; } ) }, diff --git a/test.cfg b/test.cfg index bd09297..fe8c50e 100644 --- a/test.cfg +++ b/test.cfg @@ -32,7 +32,8 @@ listen: ( { host: "localhost"; port: "8080"; keepalive: true; }, { host: "localhost"; port: "8081"; keepalive: true; }, - { host: "ip4-localhost"; is_udp: true; port: "8086"; } + { host: "ip4-localhost"; is_udp: true; port: "8086"; }, + { host: "/tmp/sslh.sock"; is_unix: true; port: ""; } ); diff --git a/version.h b/version.h index cccb9cd..8b07edb 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #ifndef VERSION_H #define VERSION_H -#define VERSION "v2.1.4-22-g9e6b4fa-dirty" +#define VERSION "v2.1.4-24-g59d89e3-dirty" #endif