mirror of
https://github.com/yrutschle/sslh.git
synced 2025-04-13 07:37:15 +03:00
code cleanup and adaptation of regex probe
This commit is contained in:
parent
d3d4fd657a
commit
33ab9d535d
2
common.c
2
common.c
@ -33,7 +33,7 @@
|
||||
/*
|
||||
* Settings that depend on the command line or the config file
|
||||
*/
|
||||
struct config_item cfg;
|
||||
struct sslhcfg_item cfg;
|
||||
|
||||
struct addrinfo *addr_listen = NULL; /* what addresses do we listen to? */
|
||||
|
||||
|
4
common.h
4
common.h
@ -87,7 +87,7 @@ struct queue {
|
||||
struct connection {
|
||||
enum connection_state state;
|
||||
time_t probe_timeout;
|
||||
struct config_protocols_item* proto;
|
||||
struct sslhcfg_protocols_item* proto;
|
||||
|
||||
/* q[0]: queue for external connection (client);
|
||||
* q[1]: queue for internal connection (httpd or sshd);
|
||||
@ -123,7 +123,7 @@ int flush_deferred(struct queue *q);
|
||||
|
||||
extern int probing_timeout, verbose, inetd, foreground,
|
||||
background, transparent, numeric;
|
||||
extern struct config_item cfg;
|
||||
extern struct sslhcfg_item cfg;
|
||||
extern struct sockaddr_storage addr_ssl, addr_ssh, addr_openvpn;
|
||||
extern struct addrinfo *addr_listen;
|
||||
extern const char* USAGE_STRING;
|
||||
|
48
probe.c
48
probe.c
@ -33,15 +33,15 @@
|
||||
|
||||
|
||||
|
||||
static int is_ssh_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_openvpn_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_tinc_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_xmpp_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_http_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_tls_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_adb_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_socks5_protocol(const char *p, int len, struct config_protocols_item*);
|
||||
static int is_true(const char *p, int len, struct config_protocols_item* proto) { return 1; }
|
||||
static int is_ssh_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_openvpn_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_tinc_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_xmpp_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_http_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_tls_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_adb_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_socks5_protocol(const char *p, int len, struct sslhcfg_protocols_item*);
|
||||
static int is_true(const char *p, int len, struct sslhcfg_protocols_item* proto) { return 1; }
|
||||
|
||||
struct protocol_probe_desc {
|
||||
const char* name;
|
||||
@ -64,11 +64,11 @@ static struct protocol_probe_desc builtins[] = {
|
||||
{ "anyprot", is_true }
|
||||
};
|
||||
|
||||
static struct config_protocols_item *protocols;
|
||||
static struct sslhcfg_protocols_item *protocols;
|
||||
static char* on_timeout = "ssh";
|
||||
|
||||
/* TODO I think this has to go */
|
||||
struct config_protocols_item* get_builtins(void) {
|
||||
struct sslhcfg_protocols_item* get_builtins(void) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ void set_ontimeout(const char* name)
|
||||
/* Returns the protocol to connect to in case of timeout;
|
||||
* if not found, return the first protocol specified
|
||||
*/
|
||||
struct config_protocols_item* timeout_protocol(void)
|
||||
struct sslhcfg_protocols_item* timeout_protocol(void)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < cfg.protocols_len; i++) {
|
||||
@ -97,12 +97,12 @@ struct config_protocols_item* timeout_protocol(void)
|
||||
}
|
||||
|
||||
/* returns the first protocol (caller can then follow the *next pointers) */
|
||||
struct config_protocols_item* get_first_protocol(void)
|
||||
struct sslhcfg_protocols_item* get_first_protocol(void)
|
||||
{
|
||||
return protocols;
|
||||
}
|
||||
|
||||
void set_protocol_list(struct config_protocols_item* prots)
|
||||
void set_protocol_list(struct sslhcfg_protocols_item* prots)
|
||||
{
|
||||
#if 0
|
||||
protocols = prots;
|
||||
@ -143,7 +143,7 @@ void hexdump(const char *mem, unsigned int len)
|
||||
}
|
||||
|
||||
/* Is the buffer the beginning of an SSH connection? */
|
||||
static int is_ssh_protocol(const char *p, int len, struct config_protocols_item* proto)
|
||||
static int is_ssh_protocol(const char *p, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
if (len < 4)
|
||||
return PROBE_AGAIN;
|
||||
@ -161,7 +161,7 @@ static int is_ssh_protocol(const char *p, int len, struct config_protocols_item*
|
||||
* http://www.fengnet.com/book/vpns%20illustrated%20tunnels%20%20vpnsand%20ipsec/ch08lev1sec5.html
|
||||
* and OpenVPN ssl.c, ssl.h and options.c
|
||||
*/
|
||||
static int is_openvpn_protocol (const char*p,int len, struct config_protocols_item* proto)
|
||||
static int is_openvpn_protocol (const char*p,int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
int packet_len;
|
||||
|
||||
@ -176,7 +176,7 @@ static int is_openvpn_protocol (const char*p,int len, struct config_protocols_it
|
||||
* Protocol is documented here: http://www.tinc-vpn.org/documentation/tinc.pdf
|
||||
* First connection starts with "0 " in 1.0.15)
|
||||
* */
|
||||
static int is_tinc_protocol( const char *p, int len, struct config_protocols_item* proto)
|
||||
static int is_tinc_protocol( const char *p, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
if (len < 2)
|
||||
return PROBE_AGAIN;
|
||||
@ -188,7 +188,7 @@ static int is_tinc_protocol( const char *p, int len, struct config_protocols_ite
|
||||
* (Protocol is documented (http://tools.ietf.org/html/rfc6120) but for lazy
|
||||
* clients, just checking first frame containing "jabber" in xml entity)
|
||||
* */
|
||||
static int is_xmpp_protocol( const char *p, int len, struct config_protocols_item* proto)
|
||||
static int is_xmpp_protocol( const char *p, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
if (memmem(p, len, "jabber", 6))
|
||||
return PROBE_MATCH;
|
||||
@ -211,7 +211,7 @@ static int probe_http_method(const char *p, int len, const char *opt)
|
||||
}
|
||||
|
||||
/* Is the buffer the beginning of an HTTP connection? */
|
||||
static int is_http_protocol(const char *p, int len, struct config_protocols_item* proto)
|
||||
static int is_http_protocol(const char *p, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
int res;
|
||||
/* If it's got HTTP in the request (HTTP/1.1) then it's HTTP */
|
||||
@ -237,7 +237,7 @@ static int is_http_protocol(const char *p, int len, struct config_protocols_item
|
||||
}
|
||||
|
||||
/* Says if it's TLS, optionally with SNI and ALPN lists in proto->data */
|
||||
static int is_tls_protocol(const char *p, int len, struct config_protocols_item* proto)
|
||||
static int is_tls_protocol(const char *p, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
switch (parse_tls_header(proto->data, p, len)) {
|
||||
case TLS_MATCH: return PROBE_MATCH;
|
||||
@ -257,7 +257,7 @@ static int probe_adb_cnxn_message(const char *p)
|
||||
return !memcmp(&p[0], "CNXN", 4) && !memcmp(&p[24], "host:", 5);
|
||||
}
|
||||
|
||||
static int is_adb_protocol(const char *p, int len, struct config_protocols_item* proto)
|
||||
static int is_adb_protocol(const char *p, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
/* amessage.data_length is not being checked, under the assumption that
|
||||
* a packet >= 30 bytes will have "something" in the payload field.
|
||||
@ -296,7 +296,7 @@ static int is_adb_protocol(const char *p, int len, struct config_protocols_item*
|
||||
return probe_adb_cnxn_message(&p[sizeof(empty_message)]);
|
||||
}
|
||||
|
||||
static int is_socks5_protocol(const char *p_in, int len, struct config_protocols_item* proto)
|
||||
static int is_socks5_protocol(const char *p_in, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
unsigned char* p = (unsigned char*)p_in;
|
||||
int i;
|
||||
@ -329,7 +329,7 @@ static int is_socks5_protocol(const char *p_in, int len, struct config_protocols
|
||||
return PROBE_MATCH;
|
||||
}
|
||||
|
||||
static int regex_probe(const char *p, int len, struct config_protocols_item* proto)
|
||||
static int regex_probe(const char *p, int len, struct sslhcfg_protocols_item* proto)
|
||||
{
|
||||
#ifdef ENABLE_REGEX
|
||||
regex_t **probe = proto->data;
|
||||
@ -355,7 +355,7 @@ static int regex_probe(const char *p, int len, struct config_protocols_item* pro
|
||||
int probe_client_protocol(struct connection *cnx)
|
||||
{
|
||||
char buffer[BUFSIZ];
|
||||
struct config_protocols_item* p, *last_p = cnx->proto;
|
||||
struct sslhcfg_protocols_item* p, *last_p = cnx->proto;
|
||||
int i, n, res, again = 0;
|
||||
|
||||
n = read(cnx->q[0].fd, buffer, sizeof(buffer));
|
||||
|
12
probe.h
12
probe.h
@ -12,8 +12,8 @@ typedef enum {
|
||||
PROBE_AGAIN, /* Not enough data for this probe, try again with more data */
|
||||
} probe_result;
|
||||
|
||||
struct config_protocols_item;
|
||||
typedef int T_PROBE(const char*, int, struct config_protocols_item*);
|
||||
struct sslhcfg_protocols_item;
|
||||
typedef int T_PROBE(const char*, int, struct sslhcfg_protocols_item*);
|
||||
|
||||
#include "sslh-conf.h"
|
||||
|
||||
@ -39,7 +39,7 @@ struct proto {
|
||||
#endif
|
||||
|
||||
/* Returns a pointer to the array of builtin protocols */
|
||||
struct config_protocols_item* get_builtins(void);
|
||||
struct sslhcfg_protocols_item* get_builtins(void);
|
||||
|
||||
/* Returns the number of builtin protocols */
|
||||
int get_num_builtins(void);
|
||||
@ -48,10 +48,10 @@ int get_num_builtins(void);
|
||||
T_PROBE* get_probe(const char* description);
|
||||
|
||||
/* Returns the head of the configured protocols */
|
||||
struct config_protocols_item* get_first_protocol(void);
|
||||
struct sslhcfg_protocols_item* get_first_protocol(void);
|
||||
|
||||
/* Set the list of configured protocols */
|
||||
void set_protocol_list(struct config_protocols_item*);
|
||||
void set_protocol_list(struct sslhcfg_protocols_item*);
|
||||
|
||||
/* probe_client_protocol
|
||||
*
|
||||
@ -69,7 +69,7 @@ void set_ontimeout(const char* name);
|
||||
*
|
||||
* Returns the protocol to connect to in case of timeout
|
||||
*/
|
||||
struct config_protocols_item* timeout_protocol(void);
|
||||
struct sslhcfg_protocols_item* timeout_protocol(void);
|
||||
|
||||
void hexdump(const char*, unsigned int);
|
||||
|
||||
|
263
sslh-conf.c
263
sslh-conf.c
@ -1,5 +1,5 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct)
|
||||
* on Mon Dec 3 10:48:52 2018. */
|
||||
* on Tue Dec 4 21:49:45 2018. */
|
||||
|
||||
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
#include <stdlib.h>
|
||||
#include "sslh-conf.h"
|
||||
|
||||
static int config_protocols_parser(
|
||||
static int sslhcfg_protocols_parser(
|
||||
config_setting_t* cfg,
|
||||
struct config_protocols_item* config_protocols,
|
||||
struct sslhcfg_protocols_item* sslhcfg_protocols,
|
||||
const char** errmsg)
|
||||
{
|
||||
config_setting_t* setting;
|
||||
@ -19,112 +19,112 @@ static int config_protocols_parser(
|
||||
*errmsg = NULL;
|
||||
|
||||
if (config_setting_lookup(cfg, "name")) {
|
||||
if (config_setting_lookup_string(cfg, "name", &config_protocols->name) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "name", &sslhcfg_protocols->name) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"name\" failed";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
*errmsg = "Mandatory option \"name\" is missing";
|
||||
*errmsg = "Mandatory option \"sslhcfg_protocols.name\" is missing";
|
||||
return 0;
|
||||
}
|
||||
if (config_setting_lookup(cfg, "host")) {
|
||||
if (config_setting_lookup_string(cfg, "host", &config_protocols->host) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "host", &sslhcfg_protocols->host) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"host\" failed";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
*errmsg = "Mandatory option \"host\" is missing";
|
||||
*errmsg = "Mandatory option \"sslhcfg_protocols.host\" is missing";
|
||||
return 0;
|
||||
}
|
||||
if (asprintf(&tmp, "%s", config_protocols->host) == -1) {
|
||||
if (asprintf(&tmp, "%s", sslhcfg_protocols->host) == -1) {
|
||||
*errmsg = "asprintf: cannot allocate memory";
|
||||
return 0;
|
||||
}
|
||||
config_protocols->host = tmp;
|
||||
sslhcfg_protocols->host = tmp;
|
||||
if (config_setting_lookup(cfg, "port")) {
|
||||
if (config_setting_lookup_string(cfg, "port", &config_protocols->port) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "port", &sslhcfg_protocols->port) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"port\" failed";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
*errmsg = "Mandatory option \"port\" is missing";
|
||||
*errmsg = "Mandatory option \"sslhcfg_protocols.port\" is missing";
|
||||
return 0;
|
||||
}
|
||||
if (asprintf(&tmp, "%s", config_protocols->port) == -1) {
|
||||
if (asprintf(&tmp, "%s", sslhcfg_protocols->port) == -1) {
|
||||
*errmsg = "asprintf: cannot allocate memory";
|
||||
return 0;
|
||||
}
|
||||
config_protocols->port = tmp;
|
||||
config_protocols->service = NULL;
|
||||
sslhcfg_protocols->port = tmp;
|
||||
sslhcfg_protocols->service = NULL;
|
||||
if (config_setting_lookup(cfg, "service")) {
|
||||
if (config_setting_lookup_string(cfg, "service", &config_protocols->service) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "service", &sslhcfg_protocols->service) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"service\" failed";
|
||||
return 0;
|
||||
} else {
|
||||
config_protocols->service_is_present = 1;
|
||||
sslhcfg_protocols->service_is_present = 1;
|
||||
}
|
||||
;
|
||||
}
|
||||
config_protocols->fork = 0;
|
||||
sslhcfg_protocols->fork = 0;
|
||||
if (config_setting_lookup(cfg, "fork")) {
|
||||
if (config_setting_lookup_bool(cfg, "fork", &config_protocols->fork) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_bool(cfg, "fork", &sslhcfg_protocols->fork) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"fork\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config_protocols->log_level = 1;
|
||||
sslhcfg_protocols->log_level = 1;
|
||||
if (config_setting_lookup(cfg, "log_level")) {
|
||||
if (config_setting_lookup_int(cfg, "log_level", &config_protocols->log_level) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_int(cfg, "log_level", &sslhcfg_protocols->log_level) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"log_level\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config_protocols->keepalive = 0;
|
||||
sslhcfg_protocols->keepalive = 0;
|
||||
if (config_setting_lookup(cfg, "keepalive")) {
|
||||
if (config_setting_lookup_bool(cfg, "keepalive", &config_protocols->keepalive) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_bool(cfg, "keepalive", &sslhcfg_protocols->keepalive) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"keepalive\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config_protocols->sni_hostnames = NULL;
|
||||
config_protocols->sni_hostnames_len = 0;
|
||||
sslhcfg_protocols->sni_hostnames = NULL;
|
||||
sslhcfg_protocols->sni_hostnames_len = 0;
|
||||
if ((setting = config_setting_lookup(cfg, "sni_hostnames"))) {
|
||||
int len = config_setting_length(setting);
|
||||
config_protocols->sni_hostnames = malloc(len * sizeof(*config_protocols->sni_hostnames));
|
||||
config_protocols->sni_hostnames_len = len;
|
||||
sslhcfg_protocols->sni_hostnames = malloc(len * sizeof(*sslhcfg_protocols->sni_hostnames));
|
||||
sslhcfg_protocols->sni_hostnames_len = len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
config_setting_t* s = config_setting_get_elem(setting, i);
|
||||
config_protocols->sni_hostnames[i] = config_setting_get_string(s);
|
||||
sslhcfg_protocols->sni_hostnames[i] = config_setting_get_string(s);
|
||||
}
|
||||
}
|
||||
config_protocols->alpn_protocols = NULL;
|
||||
config_protocols->alpn_protocols_len = 0;
|
||||
sslhcfg_protocols->alpn_protocols = NULL;
|
||||
sslhcfg_protocols->alpn_protocols_len = 0;
|
||||
if ((setting = config_setting_lookup(cfg, "alpn_protocols"))) {
|
||||
int len = config_setting_length(setting);
|
||||
config_protocols->alpn_protocols = malloc(len * sizeof(*config_protocols->alpn_protocols));
|
||||
config_protocols->alpn_protocols_len = len;
|
||||
sslhcfg_protocols->alpn_protocols = malloc(len * sizeof(*sslhcfg_protocols->alpn_protocols));
|
||||
sslhcfg_protocols->alpn_protocols_len = len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
config_setting_t* s = config_setting_get_elem(setting, i);
|
||||
config_protocols->alpn_protocols[i] = config_setting_get_string(s);
|
||||
sslhcfg_protocols->alpn_protocols[i] = config_setting_get_string(s);
|
||||
}
|
||||
}
|
||||
config_protocols->regex_patterns = NULL;
|
||||
config_protocols->regex_patterns_len = 0;
|
||||
sslhcfg_protocols->regex_patterns = NULL;
|
||||
sslhcfg_protocols->regex_patterns_len = 0;
|
||||
if ((setting = config_setting_lookup(cfg, "regex_patterns"))) {
|
||||
int len = config_setting_length(setting);
|
||||
config_protocols->regex_patterns = malloc(len * sizeof(*config_protocols->regex_patterns));
|
||||
config_protocols->regex_patterns_len = len;
|
||||
sslhcfg_protocols->regex_patterns = malloc(len * sizeof(*sslhcfg_protocols->regex_patterns));
|
||||
sslhcfg_protocols->regex_patterns_len = len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
config_setting_t* s = config_setting_get_elem(setting, i);
|
||||
config_protocols->regex_patterns[i] = config_setting_get_string(s);
|
||||
sslhcfg_protocols->regex_patterns[i] = config_setting_get_string(s);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_listen_parser(
|
||||
static int sslhcfg_listen_parser(
|
||||
config_setting_t* cfg,
|
||||
struct config_listen_item* config_listen,
|
||||
struct sslhcfg_listen_item* sslhcfg_listen,
|
||||
const char** errmsg)
|
||||
{
|
||||
config_setting_t* setting;
|
||||
@ -132,36 +132,36 @@ static int config_listen_parser(
|
||||
*errmsg = NULL;
|
||||
|
||||
if (config_setting_lookup(cfg, "host")) {
|
||||
if (config_setting_lookup_string(cfg, "host", &config_listen->host) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "host", &sslhcfg_listen->host) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"host\" failed";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
*errmsg = "Mandatory option \"host\" is missing";
|
||||
*errmsg = "Mandatory option \"sslhcfg_listen.host\" is missing";
|
||||
return 0;
|
||||
}
|
||||
if (asprintf(&tmp, "%s", config_listen->host) == -1) {
|
||||
if (asprintf(&tmp, "%s", sslhcfg_listen->host) == -1) {
|
||||
*errmsg = "asprintf: cannot allocate memory";
|
||||
return 0;
|
||||
}
|
||||
config_listen->host = tmp;
|
||||
sslhcfg_listen->host = tmp;
|
||||
if (config_setting_lookup(cfg, "port")) {
|
||||
if (config_setting_lookup_string(cfg, "port", &config_listen->port) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "port", &sslhcfg_listen->port) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"port\" failed";
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
*errmsg = "Mandatory option \"port\" is missing";
|
||||
*errmsg = "Mandatory option \"sslhcfg_listen.port\" is missing";
|
||||
return 0;
|
||||
}
|
||||
if (asprintf(&tmp, "%s", config_listen->port) == -1) {
|
||||
if (asprintf(&tmp, "%s", sslhcfg_listen->port) == -1) {
|
||||
*errmsg = "asprintf: cannot allocate memory";
|
||||
return 0;
|
||||
}
|
||||
config_listen->port = tmp;
|
||||
config_listen->keepalive = 0;
|
||||
sslhcfg_listen->port = tmp;
|
||||
sslhcfg_listen->keepalive = 0;
|
||||
if (config_setting_lookup(cfg, "keepalive")) {
|
||||
if (config_setting_lookup_bool(cfg, "keepalive", &config_listen->keepalive) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_bool(cfg, "keepalive", &sslhcfg_listen->keepalive) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"keepalive\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
@ -169,124 +169,124 @@ static int config_listen_parser(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int config_parser(
|
||||
static int sslhcfg_parser(
|
||||
config_setting_t* cfg,
|
||||
struct config_item* config,
|
||||
struct sslhcfg_item* sslhcfg,
|
||||
const char** errmsg)
|
||||
{
|
||||
config_setting_t* setting;
|
||||
char* tmp;
|
||||
*errmsg = NULL;
|
||||
|
||||
config->verbose = 0;
|
||||
sslhcfg->verbose = 0;
|
||||
if (config_setting_lookup(cfg, "verbose")) {
|
||||
if (config_setting_lookup_int(cfg, "verbose", &config->verbose) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_int(cfg, "verbose", &sslhcfg->verbose) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"verbose\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config->foreground = 0;
|
||||
sslhcfg->foreground = 0;
|
||||
if (config_setting_lookup(cfg, "foreground")) {
|
||||
if (config_setting_lookup_bool(cfg, "foreground", &config->foreground) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_bool(cfg, "foreground", &sslhcfg->foreground) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"foreground\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config->inetd = 0;
|
||||
sslhcfg->inetd = 0;
|
||||
if (config_setting_lookup(cfg, "inetd")) {
|
||||
if (config_setting_lookup_bool(cfg, "inetd", &config->inetd) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_bool(cfg, "inetd", &sslhcfg->inetd) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"inetd\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config->numeric = 0;
|
||||
sslhcfg->numeric = 0;
|
||||
if (config_setting_lookup(cfg, "numeric")) {
|
||||
if (config_setting_lookup_bool(cfg, "numeric", &config->numeric) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_bool(cfg, "numeric", &sslhcfg->numeric) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"numeric\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config->transparent = 0;
|
||||
sslhcfg->transparent = 0;
|
||||
if (config_setting_lookup(cfg, "transparent")) {
|
||||
if (config_setting_lookup_bool(cfg, "transparent", &config->transparent) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_bool(cfg, "transparent", &sslhcfg->transparent) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"transparent\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config->timeout = 2;
|
||||
sslhcfg->timeout = 2;
|
||||
if (config_setting_lookup(cfg, "timeout")) {
|
||||
if (config_setting_lookup_int(cfg, "timeout", &config->timeout) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_int(cfg, "timeout", &sslhcfg->timeout) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"timeout\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config->user = NULL;
|
||||
sslhcfg->user = NULL;
|
||||
if (config_setting_lookup(cfg, "user")) {
|
||||
if (config_setting_lookup_string(cfg, "user", &config->user) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "user", &sslhcfg->user) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"user\" failed";
|
||||
return 0;
|
||||
} else {
|
||||
config->user_is_present = 1;
|
||||
sslhcfg->user_is_present = 1;
|
||||
}
|
||||
;
|
||||
}
|
||||
config->pidfile = NULL;
|
||||
sslhcfg->pidfile = NULL;
|
||||
if (config_setting_lookup(cfg, "pidfile")) {
|
||||
if (config_setting_lookup_string(cfg, "pidfile", &config->pidfile) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "pidfile", &sslhcfg->pidfile) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"pidfile\" failed";
|
||||
return 0;
|
||||
} else {
|
||||
config->pidfile_is_present = 1;
|
||||
sslhcfg->pidfile_is_present = 1;
|
||||
}
|
||||
;
|
||||
}
|
||||
config->chroot = NULL;
|
||||
sslhcfg->chroot = NULL;
|
||||
if (config_setting_lookup(cfg, "chroot")) {
|
||||
if (config_setting_lookup_string(cfg, "chroot", &config->chroot) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "chroot", &sslhcfg->chroot) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"chroot\" failed";
|
||||
return 0;
|
||||
} else {
|
||||
config->chroot_is_present = 1;
|
||||
sslhcfg->chroot_is_present = 1;
|
||||
}
|
||||
;
|
||||
}
|
||||
config->syslog_facility = "auth";
|
||||
sslhcfg->syslog_facility = "auth";
|
||||
if (config_setting_lookup(cfg, "syslog_facility")) {
|
||||
if (config_setting_lookup_string(cfg, "syslog_facility", &config->syslog_facility) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "syslog_facility", &sslhcfg->syslog_facility) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"syslog_facility\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
config->on_timeout = "ssh";
|
||||
sslhcfg->on_timeout = "ssh";
|
||||
if (config_setting_lookup(cfg, "on_timeout")) {
|
||||
if (config_setting_lookup_string(cfg, "on_timeout", &config->on_timeout) == CONFIG_FALSE) {
|
||||
if (config_setting_lookup_string(cfg, "on_timeout", &sslhcfg->on_timeout) == CONFIG_FALSE) {
|
||||
*errmsg = "Parsing of option \"on_timeout\" failed";
|
||||
return 0;
|
||||
} ;
|
||||
}
|
||||
|
||||
config->listen = NULL;
|
||||
config->listen_len = 0;
|
||||
sslhcfg->listen = NULL;
|
||||
sslhcfg->listen_len = 0;
|
||||
if ((setting = config_setting_lookup(cfg, "listen"))) {
|
||||
int len = config_setting_length(setting);
|
||||
config->listen = malloc(len * sizeof(*config->listen));
|
||||
config->listen_len = len;
|
||||
sslhcfg->listen = malloc(len * sizeof(*sslhcfg->listen));
|
||||
sslhcfg->listen_len = len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
config_setting_t* s = config_setting_get_elem(setting, i);
|
||||
int res = config_listen_parser(s, &config->listen[i], errmsg);
|
||||
int res = sslhcfg_listen_parser(s, &sslhcfg->listen[i], errmsg);
|
||||
if (!res) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
config->protocols = NULL;
|
||||
config->protocols_len = 0;
|
||||
sslhcfg->protocols = NULL;
|
||||
sslhcfg->protocols_len = 0;
|
||||
if ((setting = config_setting_lookup(cfg, "protocols"))) {
|
||||
int len = config_setting_length(setting);
|
||||
config->protocols = malloc(len * sizeof(*config->protocols));
|
||||
config->protocols_len = len;
|
||||
sslhcfg->protocols = malloc(len * sizeof(*sslhcfg->protocols));
|
||||
sslhcfg->protocols_len = len;
|
||||
for (int i = 0; i < len; i++) {
|
||||
config_setting_t* s = config_setting_get_elem(setting, i);
|
||||
int res = config_protocols_parser(s, &config->protocols[i], errmsg);
|
||||
int res = sslhcfg_protocols_parser(s, &sslhcfg->protocols[i], errmsg);
|
||||
if (!res) return 0;
|
||||
}
|
||||
}
|
||||
@ -294,7 +294,7 @@ static int config_parser(
|
||||
}
|
||||
|
||||
/* Public parser API: returns 0 on failure, 1 on success */
|
||||
int config_parse_file(const char* filename, struct config_item* cfg, const char**errmsg)
|
||||
int sslhcfg_parse_file(const char* filename, struct sslhcfg_item* cfg, const char**errmsg)
|
||||
{
|
||||
config_t c;
|
||||
|
||||
@ -310,7 +310,7 @@ int config_parse_file(const char* filename, struct config_item* cfg, const char*
|
||||
asprintf(errmsg, "%s:%s", filename, config_error_text(&c));
|
||||
return 0;
|
||||
}
|
||||
return config_parser(config_lookup(&c, "/"), cfg, errmsg);
|
||||
return sslhcfg_parser(config_lookup(&c, "/"), cfg, errmsg);
|
||||
}
|
||||
|
||||
static void indent(int depth)
|
||||
@ -320,98 +320,95 @@ static void indent(int depth)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static void config_protocols_print(
|
||||
struct config_protocols_item* config_protocols,
|
||||
static void sslhcfg_protocols_print(
|
||||
struct sslhcfg_protocols_item* sslhcfg_protocols,
|
||||
int depth)
|
||||
{
|
||||
int i;
|
||||
indent(depth);
|
||||
printf("name: %s\n", config_protocols->name);
|
||||
printf("name: %s\n", sslhcfg_protocols->name);
|
||||
indent(depth);
|
||||
printf("host: %s\n", config_protocols->host);
|
||||
printf("host: %s\n", sslhcfg_protocols->host);
|
||||
indent(depth);
|
||||
printf("port: %s\n", config_protocols->port);
|
||||
printf("port: %s\n", sslhcfg_protocols->port);
|
||||
indent(depth);
|
||||
printf("service: %s\n", config_protocols->service);
|
||||
printf("service: %s\n", sslhcfg_protocols->service);
|
||||
indent(depth);
|
||||
printf("fork: %d\n", config_protocols->fork);
|
||||
printf("fork: %d\n", sslhcfg_protocols->fork);
|
||||
indent(depth);
|
||||
printf("log_level: %d\n", config_protocols->log_level);
|
||||
printf("log_level: %d\n", sslhcfg_protocols->log_level);
|
||||
indent(depth);
|
||||
printf("keepalive: %d\n", config_protocols->keepalive);
|
||||
printf("keepalive: %d\n", sslhcfg_protocols->keepalive);
|
||||
indent(depth);
|
||||
printf("sni_hostnames [%d]:\n", config_protocols->sni_hostnames_len);
|
||||
for (i = 0; i < config_protocols->sni_hostnames_len; i++) {
|
||||
printf("sni_hostnames [%d]:\n", sslhcfg_protocols->sni_hostnames_len);
|
||||
for (i = 0; i < sslhcfg_protocols->sni_hostnames_len; i++) {
|
||||
indent(depth+1);
|
||||
printf("%d:\t%s\n", i, config_protocols->sni_hostnames[i]);
|
||||
printf("%d:\t%s\n", i, sslhcfg_protocols->sni_hostnames[i]);
|
||||
}
|
||||
indent(depth);
|
||||
printf("alpn_protocols [%d]:\n", config_protocols->alpn_protocols_len);
|
||||
for (i = 0; i < config_protocols->alpn_protocols_len; i++) {
|
||||
printf("alpn_protocols [%d]:\n", sslhcfg_protocols->alpn_protocols_len);
|
||||
for (i = 0; i < sslhcfg_protocols->alpn_protocols_len; i++) {
|
||||
indent(depth+1);
|
||||
printf("%d:\t%s\n", i, config_protocols->alpn_protocols[i]);
|
||||
printf("%d:\t%s\n", i, sslhcfg_protocols->alpn_protocols[i]);
|
||||
}
|
||||
indent(depth);
|
||||
printf("regex_patterns [%d]:\n", config_protocols->regex_patterns_len);
|
||||
for (i = 0; i < config_protocols->regex_patterns_len; i++) {
|
||||
printf("regex_patterns [%d]:\n", sslhcfg_protocols->regex_patterns_len);
|
||||
for (i = 0; i < sslhcfg_protocols->regex_patterns_len; i++) {
|
||||
indent(depth+1);
|
||||
printf("%d:\t%s\n", i, config_protocols->regex_patterns[i]);
|
||||
printf("%d:\t%s\n", i, sslhcfg_protocols->regex_patterns[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static void config_listen_print(
|
||||
struct config_listen_item* config_listen,
|
||||
static void sslhcfg_listen_print(
|
||||
struct sslhcfg_listen_item* sslhcfg_listen,
|
||||
int depth)
|
||||
{
|
||||
int i;
|
||||
indent(depth);
|
||||
printf("host: %s\n", config_listen->host);
|
||||
printf("host: %s\n", sslhcfg_listen->host);
|
||||
indent(depth);
|
||||
printf("port: %s\n", config_listen->port);
|
||||
printf("port: %s\n", sslhcfg_listen->port);
|
||||
indent(depth);
|
||||
printf("keepalive: %d\n", config_listen->keepalive);
|
||||
printf("\n");
|
||||
printf("keepalive: %d\n", sslhcfg_listen->keepalive);
|
||||
}
|
||||
|
||||
void config_print(
|
||||
struct config_item* config,
|
||||
void sslhcfg_print(
|
||||
struct sslhcfg_item* sslhcfg,
|
||||
int depth)
|
||||
{
|
||||
int i;
|
||||
indent(depth);
|
||||
printf("verbose: %d\n", config->verbose);
|
||||
printf("verbose: %d\n", sslhcfg->verbose);
|
||||
indent(depth);
|
||||
printf("foreground: %d\n", config->foreground);
|
||||
printf("foreground: %d\n", sslhcfg->foreground);
|
||||
indent(depth);
|
||||
printf("inetd: %d\n", config->inetd);
|
||||
printf("inetd: %d\n", sslhcfg->inetd);
|
||||
indent(depth);
|
||||
printf("numeric: %d\n", config->numeric);
|
||||
printf("numeric: %d\n", sslhcfg->numeric);
|
||||
indent(depth);
|
||||
printf("transparent: %d\n", config->transparent);
|
||||
printf("transparent: %d\n", sslhcfg->transparent);
|
||||
indent(depth);
|
||||
printf("timeout: %d\n", config->timeout);
|
||||
printf("timeout: %d\n", sslhcfg->timeout);
|
||||
indent(depth);
|
||||
printf("user: %s\n", config->user);
|
||||
printf("user: %s\n", sslhcfg->user);
|
||||
indent(depth);
|
||||
printf("pidfile: %s\n", config->pidfile);
|
||||
printf("pidfile: %s\n", sslhcfg->pidfile);
|
||||
indent(depth);
|
||||
printf("chroot: %s\n", config->chroot);
|
||||
printf("chroot: %s\n", sslhcfg->chroot);
|
||||
indent(depth);
|
||||
printf("syslog_facility: %s\n", config->syslog_facility);
|
||||
printf("syslog_facility: %s\n", sslhcfg->syslog_facility);
|
||||
indent(depth);
|
||||
printf("on_timeout: %s\n", config->on_timeout);
|
||||
printf("on_timeout: %s\n", sslhcfg->on_timeout);
|
||||
|
||||
indent(depth);
|
||||
printf("listen [%d]:\n", config->listen_len);
|
||||
for (int i = 0; i < config->listen_len; i++) {
|
||||
config_listen_print(&config->listen[i], depth+1);
|
||||
printf("listen [%d]:\n", sslhcfg->listen_len);
|
||||
for (int i = 0; i < sslhcfg->listen_len; i++) {
|
||||
sslhcfg_listen_print(&sslhcfg->listen[i], depth+1);
|
||||
}
|
||||
|
||||
indent(depth);
|
||||
printf("protocols [%d]:\n", config->protocols_len);
|
||||
for (int i = 0; i < config->protocols_len; i++) {
|
||||
config_protocols_print(&config->protocols[i], depth+1);
|
||||
printf("protocols [%d]:\n", sslhcfg->protocols_len);
|
||||
for (int i = 0; i < sslhcfg->protocols_len; i++) {
|
||||
sslhcfg_protocols_print(&sslhcfg->protocols[i], depth+1);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
24
sslh-conf.h
24
sslh-conf.h
@ -1,9 +1,9 @@
|
||||
/* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct)
|
||||
* on Mon Dec 3 10:48:52 2018. */
|
||||
* on Tue Dec 4 21:49:45 2018. */
|
||||
|
||||
|
||||
#ifndef C2S_CONFIG_H
|
||||
#define C2S_CONFIG_H
|
||||
#ifndef C2S_SSLHCFG_H
|
||||
#define C2S_SSLHCFG_H
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "probe.h"
|
||||
@ -11,13 +11,13 @@
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
struct config_listen_item {
|
||||
struct sslhcfg_listen_item {
|
||||
char* host;
|
||||
char* port;
|
||||
int keepalive;
|
||||
};
|
||||
|
||||
struct config_protocols_item {
|
||||
struct sslhcfg_protocols_item {
|
||||
const char* name;
|
||||
char* host;
|
||||
char* port;
|
||||
@ -37,7 +37,7 @@ struct config_protocols_item {
|
||||
void* data;
|
||||
};
|
||||
|
||||
struct config_item {
|
||||
struct sslhcfg_item {
|
||||
int verbose;
|
||||
int foreground;
|
||||
int inetd;
|
||||
@ -53,18 +53,18 @@ struct config_item {
|
||||
const char* syslog_facility;
|
||||
const char* on_timeout;
|
||||
size_t listen_len;
|
||||
struct config_listen_item* listen;
|
||||
struct sslhcfg_listen_item* listen;
|
||||
size_t protocols_len;
|
||||
struct config_protocols_item* protocols;
|
||||
struct sslhcfg_protocols_item* protocols;
|
||||
};
|
||||
|
||||
int config_parse_file(
|
||||
int sslhcfg_parse_file(
|
||||
const char* filename,
|
||||
struct config_item* config,
|
||||
struct sslhcfg_item* sslhcfg,
|
||||
const char** errmsg);
|
||||
|
||||
void config_print(
|
||||
struct config_item *config,
|
||||
void sslhcfg_print(
|
||||
struct sslhcfg_item *sslhcfg,
|
||||
int depth);
|
||||
|
||||
#endif
|
||||
|
268
sslh-main.c
268
sslh-main.c
@ -81,16 +81,14 @@ static struct option const_options[] = {
|
||||
};
|
||||
*/
|
||||
static struct option* all_options;
|
||||
#if 0
|
||||
static struct config_protocols_item* builtins;
|
||||
#endif
|
||||
static struct sslhcfg_protocols_item* builtins;
|
||||
static const char *optstr = "vt:T:p:VP:C:F::";
|
||||
|
||||
|
||||
|
||||
static void print_usage(void)
|
||||
{
|
||||
struct config_protocols_item *p;
|
||||
struct sslhcfg_protocols_item *p;
|
||||
int i;
|
||||
int res;
|
||||
char *prots = "";
|
||||
@ -126,7 +124,7 @@ static void printsettings(void)
|
||||
char buf[NI_MAXHOST];
|
||||
struct addrinfo *a;
|
||||
int i;
|
||||
struct config_protocols_item *p;
|
||||
struct sslhcfg_protocols_item *p;
|
||||
|
||||
for (i = 0; i < cfg.protocols_len; i++ ) {
|
||||
p = &cfg.protocols[i];
|
||||
@ -201,164 +199,40 @@ static int config_resolve_listen(struct addrinfo **listen)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int config_listen(config_t *config, struct addrinfo **listen)
|
||||
{
|
||||
config_setting_t *setting, *addr;
|
||||
int len, i, keepalive;
|
||||
const char *hostname, *port;
|
||||
|
||||
setting = config_lookup(config, "listen");
|
||||
if (setting) {
|
||||
len = config_setting_length(setting);
|
||||
for (i = 0; i < len; i++) {
|
||||
addr = config_setting_get_elem(setting, i);
|
||||
if (! (config_setting_lookup_string(addr, "host", &hostname) &&
|
||||
config_setting_lookup_string(addr, "port", &port))) {
|
||||
fprintf(stderr,
|
||||
"line %d:Incomplete specification (hostname and port required)\n",
|
||||
config_setting_source_line(addr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
keepalive = 0;
|
||||
config_setting_lookup_bool(addr, "keepalive", &keepalive);
|
||||
|
||||
resolve_split_name(listen, hostname, port);
|
||||
|
||||
/* getaddrinfo returned a list of addresses corresponding to the
|
||||
* specification; move the pointer to the end of that list before
|
||||
* processing the next specification, while setting flags for
|
||||
* start_listen_sockets() through ai_flags (which is not meant for
|
||||
* that, but is only used as hint in getaddrinfo, so it's OK) */
|
||||
for (; *listen; listen = &((*listen)->ai_next)) {
|
||||
if (keepalive)
|
||||
(*listen)->ai_flags = SO_KEEPALIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef LIBCONFIG
|
||||
static void setup_regex_probe(struct config_protocols_item *p, config_setting_t* probes)
|
||||
static void setup_regex_probe(struct sslhcfg_protocols_item *p)
|
||||
{
|
||||
#ifdef ENABLE_REGEX
|
||||
int num_probes, errsize, i, res;
|
||||
char *err;
|
||||
const char * expr;
|
||||
regex_t** probe_list;
|
||||
int num_patterns, i, res;
|
||||
regex_t** pattern_list;
|
||||
size_t errsize;
|
||||
char* err;
|
||||
|
||||
num_probes = config_setting_length(probes);
|
||||
if (!num_probes) {
|
||||
fprintf(stderr, "%s: no probes specified\n", p->name);
|
||||
exit(1);
|
||||
}
|
||||
num_patterns = p->regex_patterns_len;
|
||||
|
||||
p->probe = get_probe("regex");
|
||||
probe_list = calloc(num_probes + 1, sizeof(*probe_list));
|
||||
CHECK_ALLOC(probe_list, "calloc");
|
||||
p->data = (void*)probe_list;
|
||||
pattern_list = calloc(num_patterns + 1, sizeof(*pattern_list));
|
||||
CHECK_ALLOC(pattern_list, "calloc");
|
||||
p->data = (void*)pattern_list;
|
||||
|
||||
for (i = 0; i < num_probes; i++) {
|
||||
probe_list[i] = malloc(sizeof(*(probe_list[i])));
|
||||
CHECK_ALLOC(probe_list[i], "malloc");
|
||||
expr = config_setting_get_string_elem(probes, i);
|
||||
if (expr == NULL) {
|
||||
fprintf(stderr, "%s: invalid probe specified\n", p->name);
|
||||
exit(1);
|
||||
}
|
||||
res = regcomp(probe_list[i], expr, REG_EXTENDED);
|
||||
for (i = 0; i < num_patterns; i++) {
|
||||
pattern_list[i] = malloc(sizeof(*(pattern_list[i])));
|
||||
CHECK_ALLOC(pattern_list[i], "malloc");
|
||||
res = regcomp(pattern_list[i], p->regex_patterns[i], REG_EXTENDED);
|
||||
if (res) {
|
||||
err = malloc(errsize = regerror(res, probe_list[i], NULL, 0));
|
||||
err = malloc(errsize = regerror(res, pattern_list[i], NULL, 0));
|
||||
CHECK_ALLOC(err, "malloc");
|
||||
regerror(res, probe_list[i], err, errsize);
|
||||
fprintf(stderr, "%s:%s\n", expr, err);
|
||||
regerror(res, pattern_list[i], err, errsize);
|
||||
fprintf(stderr, "%s:%s\n", pattern_list[i], err);
|
||||
free(err);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "line %d: regex probe specified but not compiled in\n", config_setting_source_line(probes));
|
||||
exit(5);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LIBCONFIG
|
||||
#if 0
|
||||
static void setup_sni_alpn_list(
|
||||
struct config_protocols_item *p,
|
||||
config_setting_t* config_items,
|
||||
const char* name,
|
||||
int alpn)
|
||||
{
|
||||
int num_probes, i, max_server_name_len, server_name_len;
|
||||
const char * config_item, *server_name;
|
||||
char** sni_hostname_list;
|
||||
|
||||
num_probes = config_setting_length(config_items);
|
||||
if (!num_probes) {
|
||||
fprintf(stderr, "%s: no %s specified\n", p->description, name);
|
||||
return;
|
||||
}
|
||||
|
||||
max_server_name_len = 0;
|
||||
for (i = 0; i < num_probes; i++) {
|
||||
server_name = config_setting_get_string_elem(config_items, i);
|
||||
if (server_name == NULL) {
|
||||
fprintf(stderr, "%s: invalid %s specified\n", p->description, name);
|
||||
exit(1);
|
||||
}
|
||||
server_name_len = strlen(server_name);
|
||||
if(server_name_len > max_server_name_len)
|
||||
max_server_name_len = server_name_len;
|
||||
}
|
||||
|
||||
sni_hostname_list = calloc(num_probes + 1, ++max_server_name_len);
|
||||
CHECK_ALLOC(sni_hostname_list, "calloc");
|
||||
|
||||
for (i = 0; i < num_probes; i++) {
|
||||
config_item = config_setting_get_string_elem(config_items, i);
|
||||
if (config_item == NULL) {
|
||||
fprintf(stderr, "%s: invalid %s specified\n", p->description, name);
|
||||
exit(1);
|
||||
}
|
||||
sni_hostname_list[i] = malloc(max_server_name_len);
|
||||
CHECK_ALLOC(sni_hostname_list[i], "malloc");
|
||||
strcpy (sni_hostname_list[i], config_item);
|
||||
if(verbose) fprintf(stderr, "%s: %s[%d]: %s\n", p->description, name, i, sni_hostname_list[i]);
|
||||
}
|
||||
|
||||
p->data = (void*)tls_data_set_list(p->data, alpn, sni_hostname_list);
|
||||
}
|
||||
|
||||
static void setup_sni_alpn(struct config_protocols_item *p, config_setting_t* prot)
|
||||
{
|
||||
config_setting_t *sni_hostnames, *alpn_protocols;
|
||||
|
||||
p->data = (void*)new_tls_data();
|
||||
sni_hostnames = config_setting_get_member(prot, "sni_hostnames");
|
||||
alpn_protocols = config_setting_get_member(prot, "alpn_protocols");
|
||||
|
||||
if(sni_hostnames && config_setting_is_array(sni_hostnames)) {
|
||||
setup_sni_alpn_list(p, sni_hostnames, "sni_hostnames", 0);
|
||||
}
|
||||
if(alpn_protocols && config_setting_is_array(alpn_protocols)) {
|
||||
setup_sni_alpn_list(p, alpn_protocols, "alpn_protocols", 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
static void setup_sni_alpn(struct config_protocols_item *p, config_setting_t* prot)
|
||||
{}
|
||||
#endif
|
||||
|
||||
/* For each protocol in the configuration, resolve address and set up protocol
|
||||
* options if required
|
||||
*/
|
||||
@ -367,7 +241,7 @@ static int config_protocols()
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < cfg.protocols_len; i++) {
|
||||
struct config_protocols_item* p = &(cfg.protocols[i]);
|
||||
struct sslhcfg_protocols_item* p = &(cfg.protocols[i]);
|
||||
if (resolve_split_name(&(p->saddr), p->host, p->port)) {
|
||||
fprintf(stderr, "cannot resolve %s:%s\n", p->host, p->port);
|
||||
exit(1);
|
||||
@ -379,6 +253,10 @@ static int config_protocols()
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!strcmp(cfg.protocols[i].name, "regex")) {
|
||||
setup_regex_probe(&cfg.protocols[i]);
|
||||
}
|
||||
|
||||
if (!strcmp(cfg.protocols[i].name, "tls")) {
|
||||
cfg.protocols[i].data = (void*)new_tls_data();
|
||||
if (cfg.protocols[i].sni_hostnames_len)
|
||||
@ -392,93 +270,20 @@ static int config_protocols()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int config_protocols(config_t *config, struct proto **prots)
|
||||
{
|
||||
config_setting_t *setting, *prot, *patterns;
|
||||
const char *hostname, *port, *cfg_name;
|
||||
char* name;
|
||||
int i, num_prots;
|
||||
struct proto *p, *prev = NULL;
|
||||
|
||||
setting = config_lookup(config, "protocols");
|
||||
if (setting) {
|
||||
num_prots = config_setting_length(setting);
|
||||
for (i = 0; i < num_prots; i++) {
|
||||
p = calloc(1, sizeof(*p));
|
||||
CHECK_ALLOC(p, "calloc");
|
||||
if (i == 0) *prots = p;
|
||||
if (prev) prev->next = p;
|
||||
prev = p;
|
||||
|
||||
prot = config_setting_get_elem(setting, i);
|
||||
if ((config_setting_lookup_string(prot, "name", &cfg_name) &&
|
||||
config_setting_lookup_string(prot, "host", &hostname) &&
|
||||
config_setting_lookup_string(prot, "port", &port)
|
||||
)) {
|
||||
/* To removed in v1.21 */
|
||||
name = strdup(cfg_name);
|
||||
ssl_to_tls(name);
|
||||
/* /remove */
|
||||
p->description = name;
|
||||
config_setting_lookup_string(prot, "service", &(p->service));
|
||||
config_setting_lookup_bool(prot, "keepalive", &p->keepalive);
|
||||
config_setting_lookup_bool(prot, "fork", &p->fork);
|
||||
|
||||
if (config_setting_lookup_int(prot, "log_level", &p->log_level) == CONFIG_FALSE) {
|
||||
p->log_level = 1;
|
||||
}
|
||||
|
||||
if (resolve_split_name(&(p->saddr), hostname, port)) {
|
||||
fprintf(stderr, "line %d: cannot resolve %s:%s\n", config_setting_source_line(prot), hostname, port);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
p->probe = get_probe(name);
|
||||
if (!p->probe) {
|
||||
fprintf(stderr, "line %d: %s: probe unknown\n", config_setting_source_line(prot), name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Probe-specific options: regex patterns */
|
||||
if (!strcmp(name, "regex")) {
|
||||
patterns = config_setting_get_member(prot, "regex_patterns");
|
||||
if (patterns && config_setting_is_array(patterns)) {
|
||||
setup_regex_probe(p, patterns);
|
||||
}
|
||||
}
|
||||
|
||||
/* Probe-specific options: SNI/ALPN */
|
||||
if (!strcmp(name, "tls")) {
|
||||
setup_sni_alpn(p, prot);
|
||||
}
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "line %d: Illegal protocol description (missing name, host or port)\n", config_setting_source_line(prot));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Parses a config file
|
||||
* in: *filename
|
||||
* out: *listen, a newly-allocated linked list of listen addrinfo
|
||||
* *prots, a newly-allocated linked list of protocols
|
||||
* 1 on error, 0 on success
|
||||
*/
|
||||
#ifdef LIBCONFIG
|
||||
static int config_parse(char *filename, struct addrinfo **listen, struct config_protocols_item **prots)
|
||||
static int config_parse(char *filename, struct addrinfo **listen)
|
||||
{
|
||||
int res;
|
||||
const char* err;
|
||||
|
||||
if (!config_parse_file(filename, &cfg, &err)) {
|
||||
if (!sslhcfg_parse_file(filename, &cfg, &err)) {
|
||||
fprintf(stderr, err);
|
||||
return 1;
|
||||
}
|
||||
@ -486,11 +291,6 @@ static int config_parse(char *filename, struct addrinfo **listen, struct config_
|
||||
config_resolve_listen(listen);
|
||||
config_protocols();
|
||||
|
||||
/*
|
||||
config_listen(&config, listen);
|
||||
config_protocols(&config, prots);
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -502,7 +302,7 @@ static int config_parse(char *filename, struct addrinfo **listen, struct config_
|
||||
* prot: array of protocols
|
||||
* n_prots: number of protocols in *prot
|
||||
* */
|
||||
static void append_protocols(struct option *options, int n_opts, struct config_protocols_item *prot , int n_prots)
|
||||
static void append_protocols(struct option *options, int n_opts, struct sslhcfg_protocols_item *prot , int n_prots)
|
||||
{
|
||||
int o, p;
|
||||
|
||||
@ -534,7 +334,7 @@ static void make_alloptions(void)
|
||||
*
|
||||
* prots: newly-allocated list of configured protocols, if any.
|
||||
*/
|
||||
static void cmdline_config(int argc, char* argv[], struct config_protocols_item** prots)
|
||||
static void cmdline_config(int argc, char* argv[], struct sslhcfg_protocols_item** prots)
|
||||
{
|
||||
#ifdef LIBCONFIG
|
||||
int c, res;
|
||||
@ -555,13 +355,13 @@ static void cmdline_config(int argc, char* argv[], struct config_protocols_item*
|
||||
if (c == 'F') {
|
||||
config_filename = optarg;
|
||||
if (config_filename) {
|
||||
res = config_parse(config_filename, &addr_listen, prots);
|
||||
res = config_parse(config_filename, &addr_listen);
|
||||
} else {
|
||||
/* No configuration file specified -- try default file locations */
|
||||
res = config_parse("/etc/sslh/sslh.cfg", &addr_listen, prots);
|
||||
res = config_parse("/etc/sslh/sslh.cfg", &addr_listen);
|
||||
if (!res && cfg.verbose) fprintf(stderr, "Using /etc/sslh/sslh.cfg\n");
|
||||
if (res) {
|
||||
res = config_parse("/etc/sslh.cfg", &addr_listen, prots);
|
||||
res = config_parse("/etc/sslh.cfg", &addr_listen);
|
||||
if (!res && cfg.verbose) fprintf(stderr, "Using /etc/sslh.cfg\n");
|
||||
}
|
||||
}
|
||||
@ -576,12 +376,12 @@ static void cmdline_config(int argc, char* argv[], struct config_protocols_item*
|
||||
|
||||
/* Parse command-line options. prots points to a list of configured protocols,
|
||||
* potentially non-allocated */
|
||||
static void parse_cmdline(int argc, char* argv[], struct config_protocols_item* prots)
|
||||
static void parse_cmdline(int argc, char* argv[], struct sslhcfg_protocols_item* prots)
|
||||
{
|
||||
#if 0
|
||||
int c;
|
||||
struct addrinfo **a;
|
||||
struct config_protocols_item *p;
|
||||
struct sslhcfg_protocols_item *p;
|
||||
int background;
|
||||
|
||||
optind = 1;
|
||||
@ -700,7 +500,7 @@ int main(int argc, char *argv[])
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
int res, num_addr_listen;
|
||||
struct config_protocols_item* protocols = NULL;
|
||||
struct sslhcfg_protocols_item* protocols = NULL;
|
||||
|
||||
int *listen_sockets;
|
||||
|
||||
|
@ -12,7 +12,7 @@ includes: (
|
||||
);
|
||||
|
||||
config: {
|
||||
name : "config",
|
||||
name : "sslhcfg",
|
||||
type: "list",
|
||||
items: (
|
||||
{ name: "verbose"; type: "int"; default: 0; },
|
||||
@ -26,7 +26,7 @@ config: {
|
||||
{ name: "chroot"; type: "string"; optional: true; },
|
||||
{ name: "syslog_facility"; type: "string"; default: "auth"; },
|
||||
|
||||
{name: "on_timeout"; type: "string"; default: "ssh"; },
|
||||
{name: "on-timeout"; type: "string"; default: "ssh"; },
|
||||
|
||||
{ name: "listen",
|
||||
type: "list",
|
||||
|
28
t
28
t
@ -21,21 +21,21 @@ my $sslh_port = $conf->fetch_array("listen")->[0]->{port};
|
||||
my $user = (getpwuid $<)[0]; # Run under current username
|
||||
|
||||
# Which tests do we run
|
||||
my $SSH_SHY_CNX = 1;
|
||||
my $SSH_SHY_CNX = 0;
|
||||
my $PROBES_NOFRAG = 1;
|
||||
my $PROBES_AGAIN = 1;
|
||||
my $SSL_MIX_SSH = 1;
|
||||
my $SSH_MIX_SSL = 1;
|
||||
my $PROBES_AGAIN = 0;
|
||||
my $SSL_MIX_SSH = 0;
|
||||
my $SSH_MIX_SSL = 0;
|
||||
|
||||
# Robustness tests. These are mostly to achieve full test
|
||||
# coverage, but do not necessarily result in an actual test
|
||||
# (e.g. some tests need to be run with valgrind to check all
|
||||
# memory management code).
|
||||
my $RB_CNX_NOSERVER = 1;
|
||||
my $RB_PARAM_NOHOST = 1;
|
||||
my $RB_WRONG_USERNAME = 1;
|
||||
my $RB_OPEN_PID_FILE = 1;
|
||||
my $RB_RESOLVE_ADDRESS = 1;
|
||||
my $RB_CNX_NOSERVER = 0;
|
||||
my $RB_PARAM_NOHOST = 0;
|
||||
my $RB_WRONG_USERNAME = 0;
|
||||
my $RB_OPEN_PID_FILE = 0;
|
||||
my $RB_RESOLVE_ADDRESS = 0;
|
||||
|
||||
`lcov --directory . --zerocounters`;
|
||||
|
||||
@ -161,6 +161,16 @@ sub test_probes {
|
||||
);
|
||||
}
|
||||
}
|
||||
} elsif ($p->{name} eq 'regex') {
|
||||
foreach my $pattern (@{$p->{regex_patterns}}) {
|
||||
$pattern =~ /(\w+)/;
|
||||
my $out = $1;
|
||||
test_probe(
|
||||
data => $out,
|
||||
expected => $p->{name},
|
||||
%opts
|
||||
);
|
||||
}
|
||||
} else {
|
||||
test_probe(
|
||||
data => $pattern,
|
||||
|
3
test.cfg
3
test.cfg
@ -30,6 +30,9 @@ protocols:
|
||||
{ name: "openvpn"; host: "localhost"; port: "9004"; },
|
||||
{ name: "xmpp"; host: "localhost"; port: "9009"; },
|
||||
{ name: "adb"; host: "localhost"; port: "9010"; },
|
||||
{ name: "regex"; host: "localhost"; port: "9011";
|
||||
regex_patterns: [ "^foo", "^bar" ];
|
||||
},
|
||||
{ name: "tls"; host: "localhost"; port: "9021"; alpn_protocols: [ "alpn1", "alpn2" ]; sni_hostnames: [ "sni1" ]; },
|
||||
{ name: "tls"; host: "localhost"; port: "9022"; alpn_protocols: [ "alpn1", "alpn2" ]; sni_hostnames: [ "sni2", "sni3" ]; },
|
||||
{ name: "tls"; host: "localhost"; port: "9023"; alpn_protocols: [ "alpn3" ]; },
|
||||
|
Loading…
x
Reference in New Issue
Block a user