Skip to content

Commit

Permalink
new is_unix field to connect to unix socket target servers
Browse files Browse the repository at this point in the history
  • Loading branch information
yrutschle committed Dec 22, 2024
1 parent 9e6b4fa commit cac7f48
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 34 deletions.
27 changes: 26 additions & 1 deletion common.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <sys/un.h>

#include "common.h"
#include "probe.h"
Expand Down Expand Up @@ -404,14 +405,38 @@ static int connect_inet(struct connection *cnx, int fd_from, connect_blocking bl
return -1;
}

/* Connects to AF_UNIX domain sockets */
static int connect_unix(struct connection *cnx, int fd_from, connect_blocking blocking)
{
struct sockaddr_storage ss;
struct sockaddr_un* sun = (struct sockaddr_un*)&ss;

int fd = socket(AF_UNIX, SOCK_STREAM, 0);
sun->sun_family = AF_UNIX;
strcpy(sun->sun_path, cnx->proto->host);

int res = connect(fd, (struct sockaddr*)sun, sizeof(*sun));
CHECK_RES_RETURN(res, "connect", res);

if (blocking == NON_BLOCKING) {
set_nonblock(fd);
}
return fd;
}

/* Connect to first address that works and returns a file descriptor, or -1 if
* none work.
* If transparent proxying is on, use fd_from peer address on external address
* of new file descriptor. */
int connect_addr(struct connection *cnx, int fd_from, connect_blocking blocking)
{
int fd = connect_inet(cnx, fd_from, blocking);
int fd;

if (cnx->proto->is_unix) {
fd = connect_unix(cnx, fd_from, blocking);
} else {
fd = connect_inet(cnx, fd_from, blocking);
}

return fd;
}
Expand Down
7 changes: 6 additions & 1 deletion example.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ listen:
# transparent: Set to true to proxy this protocol
# transparently (server sees the remote client IP
# address). Same as the global option, but per-protocol
# is_unix: [true|false] connect to a UNIX socket. The host
# field becomes the pathname to the socket, and the port
# field is unused (but necessary).
#
# Probe-specific options:
# (sslh will try each probe in order they are declared, and
Expand Down Expand Up @@ -109,7 +112,9 @@ protocols:
(
{ name: "ssh"; service: "ssh"; host: "localhost"; port: "22";
keepalive: true; fork: true; tfo_ok: true },
{ name: "http"; host: "localhost"; port: "80"; },

# UNIX socket to a local NGINX. The socket name is in 'host'; 'port' is necessary but not used.
{ name: "http"; is_unix: true; host: "/tmp/nginx.sock"; port: ""; },

# match BOTH ALPN/SNI
{ name: "tls"; host: "localhost"; port: "5223"; alpn_protocols: [ "xmpp-client" ]; sni_hostnames: [ "im.somethingelse.net" ]; log_level: 0; tfo_ok: true },
Expand Down
61 changes: 40 additions & 21 deletions sslh-conf.c
Original file line number Diff line number Diff line change
@@ -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 16:13:50 2024.
# conf2struct: generate libconf parsers that read to structs
# Copyright (C) 2018-2024 Yves Rutschle
Expand Down Expand Up @@ -500,7 +500,7 @@ struct arg_file* sslhcfg_conffile;
struct arg_str* sslhcfg_anyprot;
struct arg_end* sslhcfg_end;


static struct config_desc table_sslhcfg_protocols[] = {


Expand Down Expand Up @@ -568,6 +568,22 @@ static struct config_desc table_sslhcfg_protocols[] = {
/* default_val*/ .default_val.def_string = NULL
},

{
/* name */ "is_unix",
/* type */ CFG_BOOL,
/* sub_group*/ NULL,
/* arg_cl */ NULL,
/* base_addr */ NULL,
/* offset */ offsetof(struct sslhcfg_protocols_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 */ "is_udp",
/* type */ CFG_BOOL,
Expand Down Expand Up @@ -1287,110 +1303,110 @@ static struct compound_cl_target sslhcfg_anyprot_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "anyprot" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_msrdp_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "msrdp" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_syslog_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "syslog" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_socks5_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "socks5" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_adb_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "adb" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_http_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "http" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_xmpp_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "xmpp" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_wireguard_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "wireguard" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[7], 0, .value.def_bool = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[8], 0, .value.def_bool = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_tinc_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "tinc" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[7], 0, .value.def_bool = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[8], 0, .value.def_bool = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_openvpn_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "openvpn" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[7], 0, .value.def_bool = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[8], 0, .value.def_bool = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_ssl_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "tls" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[7], 0, .value.def_bool = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[8], 0, .value.def_bool = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_tls_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "tls" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[7], 0, .value.def_bool = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[8], 0, .value.def_bool = 1 },
{ 0 }
};

static struct compound_cl_target sslhcfg_ssh_targets [] = {
{ & table_sslhcfg_protocols[0], 0, .value.def_string = "ssh" },
{ & table_sslhcfg_protocols[1], 1, .value.def_string = "0" },
{ & table_sslhcfg_protocols[2], 2, .value.def_string = "0" },
{ & table_sslhcfg_protocols[6], 0, .value.def_bool = 1 },
{ & table_sslhcfg_protocols[10], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[7], 0, .value.def_bool = 1 },
{ & table_sslhcfg_protocols[11], 0, .value.def_int = 1 },
{ & table_sslhcfg_protocols[8], 0, .value.def_bool = 1 },
{ 0 }
};

Expand Down Expand Up @@ -2346,6 +2362,9 @@ static void sslhcfg_protocols_fprint(
fprintf(out, " <unset>");
fprintf(out, "\n");
indent(out, depth);
fprintf(out, "is_unix: %d", sslhcfg_protocols->is_unix);
fprintf(out, "\n");
indent(out, depth);
fprintf(out, "is_udp: %d", sslhcfg_protocols->is_udp);
fprintf(out, "\n");
indent(out, depth);
Expand Down
3 changes: 2 additions & 1 deletion sslh-conf.h
Original file line number Diff line number Diff line change
@@ -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 16:13:50 2024.
# conf2struct: generate libconf parsers that read to structs
# Copyright (C) 2018-2024 Yves Rutschle
Expand Down Expand Up @@ -53,6 +53,7 @@ struct sslhcfg_protocols_item {
char* port;
int service_is_present;
char* service;
int is_unix;
int is_udp;
int udp_timeout;
int fork;
Expand Down
31 changes: 23 additions & 8 deletions sslh-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,17 @@ static void printsettings(void)

for (i = 0; i < cfg.protocols_len; i++ ) {
p = &cfg.protocols[i];
strcpy(buf, "resolve on forward");
if (!p->resolve_on_forward) {
sprintaddr(buf, sizeof(buf), p->saddr);
size_t len = strlen(buf);
sprintf(buf+len, " family %d %d",
p->saddr->ai_family,
p->saddr->ai_addr->sa_family);
if (p->is_unix) {
sprintf(buf, "unix socket: %s", p->host);
} else {
strcpy(buf, "resolve on forward");
if (!p->resolve_on_forward) {
sprintaddr(buf, sizeof(buf), p->saddr);
size_t len = strlen(buf);
sprintf(buf+len, " family %d %d",
p->saddr->ai_family,
p->saddr->ai_addr->sa_family);
}
}
print_message(msg_config,
"%s addr: %s. libwrap service: %s log_level: %d [%s] [%s] [%s]\n",
Expand Down Expand Up @@ -149,6 +153,15 @@ void config_finish(struct sslhcfg_item* cfg)
}
}

/* Checks that the UNIX socket specified exists and is accessible
* Dies otherwise
*/
static void check_access_unix_socket(struct sslhcfg_protocols_item* p)
{
/* TODO */
return;
}


/* For each protocol in the configuration, resolve address and set up protocol
* options if required
Expand All @@ -159,7 +172,9 @@ static void config_protocols()
for (i = 0; i < cfg.protocols_len; i++) {
struct sslhcfg_protocols_item* p = &(cfg.protocols[i]);

if (
if (p->is_unix) {
check_access_unix_socket(p);
} else if (
!p->resolve_on_forward &&
resolve_split_name(&(p->saddr), p->host, p->port)
) {
Expand Down
1 change: 1 addition & 0 deletions sslhconf.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ config: {
{ name: "host"; type: "string"; var: true; },
{ name: "port"; type: "string"; var: true; },
{ name: "service"; type: "string"; optional: true; },
{ name: "is_unix"; type: "bool"; default: false },
{ name: "is_udp"; type: "bool"; default: false },
{ name: "udp_timeout"; type: "int"; default: 60 },
{ name: "fork"; type: "bool"; default: false },
Expand Down
2 changes: 1 addition & 1 deletion test.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ protocols:
(
{ name: "ssh"; host: "localhost"; port: "9000"; fork: true; transparent: true; resolve_on_forward: true; },
{ name: "socks5"; host: "localhost"; port: "9001"; },
{ name: "http"; host: "localhost"; port: "9002"; },
{ name: "http"; is_unix: true; host: "/tmp/nginx.sock"; port: ""; },
{ name: "tinc"; host: "localhost"; port: "9003"; },
{ name: "openvpn"; host: "localhost"; port: "9004"; },
{ name: "xmpp"; host: "localhost"; port: "9009"; },
Expand Down
2 changes: 1 addition & 1 deletion version.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#ifndef VERSION_H
#define VERSION_H

#define VERSION "v2.1.4-21-g16ef412-dirty"
#define VERSION "v2.1.4-22-g9e6b4fa-dirty"
#endif

0 comments on commit cac7f48

Please sign in to comment.