mirror of
https://github.com/yrutschle/sslh.git
synced 2025-06-16 07:12:26 +03:00
Merge branch 'master' of https://github.com/yrutschle/sslh
This commit is contained in:
commit
e690cb5622
@ -123,7 +123,7 @@ protocols:
|
|||||||
udp_timeout: 20; # Time after which the "connection" is forgotten
|
udp_timeout: 20; # Time after which the "connection" is forgotten
|
||||||
regex_patterns: [ "hello" ]; },
|
regex_patterns: [ "hello" ]; },
|
||||||
# Forward Teamspeak3 (Voice only)
|
# Forward Teamspeak3 (Voice only)
|
||||||
{ name: "regex"; host: "localhost"; is_udp: true; port: "9987"; regex_patterns: [ "TS3INIT1" ]; },
|
{ name: "teamspeak"; host: "localhost"; is_udp: true; port: "9987"; },
|
||||||
# Forward IETF QUIC-50 ("Q050" -> "\x51\x30\x35\x30")
|
# Forward IETF QUIC-50 ("Q050" -> "\x51\x30\x35\x30")
|
||||||
# Remember that the regex needs to be adjusted for every supported QUIC version.
|
# Remember that the regex needs to be adjusted for every supported QUIC version.
|
||||||
{ name: "regex"; host: "localhost"; is_udp: true; port: "4433"; regex_patterns: [ "\x51\x30\x35\x30" ]; },
|
{ name: "regex"; host: "localhost"; is_udp: true; port: "4433"; regex_patterns: [ "\x51\x30\x35\x30" ]; },
|
||||||
|
53
probe.c
53
probe.c
@ -40,6 +40,7 @@ static int is_tls_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_
|
|||||||
static int is_adb_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item*);
|
static int is_adb_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item*);
|
||||||
static int is_socks5_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item*);
|
static int is_socks5_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item*);
|
||||||
static int is_syslog_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item*);
|
static int is_syslog_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item*);
|
||||||
|
static int is_teamspeak_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item*);
|
||||||
static int is_true(const char *p, ssize_t len, struct sslhcfg_protocols_item* proto) { return 1; }
|
static int is_true(const char *p, ssize_t len, struct sslhcfg_protocols_item* proto) { return 1; }
|
||||||
|
|
||||||
/* Table of protocols that have a built-in probe
|
/* Table of protocols that have a built-in probe
|
||||||
@ -55,6 +56,7 @@ static struct protocol_probe_desc builtins[] = {
|
|||||||
{ "adb", is_adb_protocol },
|
{ "adb", is_adb_protocol },
|
||||||
{ "socks5", is_socks5_protocol },
|
{ "socks5", is_socks5_protocol },
|
||||||
{ "syslog", is_syslog_protocol },
|
{ "syslog", is_syslog_protocol },
|
||||||
|
{ "teamspeak", is_teamspeak_protocol },
|
||||||
{ "anyprot", is_true }
|
{ "anyprot", is_true }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,15 +139,50 @@ static int is_ssh_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_
|
|||||||
* http://www.fengnet.com/book/vpns%20illustrated%20tunnels%20%20vpnsand%20ipsec/ch08lev1sec5.html
|
* http://www.fengnet.com/book/vpns%20illustrated%20tunnels%20%20vpnsand%20ipsec/ch08lev1sec5.html
|
||||||
* and OpenVPN ssl.c, ssl.h and options.c
|
* and OpenVPN ssl.c, ssl.h and options.c
|
||||||
*/
|
*/
|
||||||
|
#define OVPN_OPCODE_MASK 0xF8
|
||||||
|
#define OVPN_CONTROL_HARD_RESET_CLIENT_V1 (0x01 << 3)
|
||||||
|
#define OVPN_CONTROL_HARD_RESET_CLIENT_V2 (0x07 << 3)
|
||||||
|
#define OVPN_HMAC_128 16
|
||||||
|
#define OVPN_HMAC_160 20
|
||||||
|
#define OVPN_HARD_RESET_PACKET_ID_OFFSET(hmac_size) (9 + hmac_size)
|
||||||
static int is_openvpn_protocol (const char*p,ssize_t len, struct sslhcfg_protocols_item* proto)
|
static int is_openvpn_protocol (const char*p,ssize_t len, struct sslhcfg_protocols_item* proto)
|
||||||
{
|
{
|
||||||
int packet_len;
|
int packet_len;
|
||||||
|
|
||||||
if (len < 2)
|
if (proto->is_udp == 0)
|
||||||
return PROBE_AGAIN;
|
{
|
||||||
|
if (len < 2)
|
||||||
|
return PROBE_AGAIN;
|
||||||
|
|
||||||
packet_len = ntohs(*(uint16_t*)p);
|
packet_len = ntohs(*(uint16_t*)p);
|
||||||
return packet_len == len - 2;
|
return packet_len == len - 2;
|
||||||
|
} else {
|
||||||
|
if (len < 1)
|
||||||
|
return PROBE_NEXT;
|
||||||
|
|
||||||
|
if ((p[0] & OVPN_OPCODE_MASK) != OVPN_CONTROL_HARD_RESET_CLIENT_V1 &&
|
||||||
|
(p[0] & OVPN_OPCODE_MASK) != OVPN_CONTROL_HARD_RESET_CLIENT_V2)
|
||||||
|
return PROBE_NEXT;
|
||||||
|
|
||||||
|
/* The detection pattern above may not be reliable enough.
|
||||||
|
* Check the packet id: OpenVPN sents five initial packets
|
||||||
|
* whereas the packet id is increased with every transmitted datagram.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (len <= OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_128))
|
||||||
|
return PROBE_NEXT;
|
||||||
|
|
||||||
|
if (ntohl(*(uint32_t*)(p + OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_128))) <= 5u)
|
||||||
|
return PROBE_MATCH;
|
||||||
|
|
||||||
|
if (len <= OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_160))
|
||||||
|
return PROBE_NEXT;
|
||||||
|
|
||||||
|
if (ntohl(*(uint32_t*)(p + OVPN_HARD_RESET_PACKET_ID_OFFSET(OVPN_HMAC_160))) <= 5u)
|
||||||
|
return PROBE_MATCH;
|
||||||
|
|
||||||
|
return PROBE_NEXT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is the buffer the beginning of a tinc connections?
|
/* Is the buffer the beginning of a tinc connections?
|
||||||
@ -318,6 +355,14 @@ static int is_syslog_protocol(const char *p, ssize_t len, struct sslhcfg_protoco
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_teamspeak_protocol(const char *p, ssize_t len, struct sslhcfg_protocols_item* proto)
|
||||||
|
{
|
||||||
|
if (len < 8)
|
||||||
|
return PROBE_NEXT;
|
||||||
|
|
||||||
|
return !strncmp(p, "TS3INIT1", len);
|
||||||
|
}
|
||||||
|
|
||||||
static int regex_probe(const char *p, ssize_t len, struct sslhcfg_protocols_item* proto)
|
static int regex_probe(const char *p, ssize_t len, struct sslhcfg_protocols_item* proto)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_REGEX
|
#ifdef ENABLE_REGEX
|
||||||
|
31
sslh-main.c
31
sslh-main.c
@ -167,7 +167,10 @@ static void config_protocols()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void config_sanity_check(struct sslhcfg_item* cfg) {
|
void config_sanity_check(struct sslhcfg_item* cfg)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
/* If compiling with systemd socket support no need to require listen address */
|
/* If compiling with systemd socket support no need to require listen address */
|
||||||
#ifndef SYSTEMD
|
#ifndef SYSTEMD
|
||||||
if (!cfg->listen_len && !cfg->inetd) {
|
if (!cfg->listen_len && !cfg->inetd) {
|
||||||
@ -175,6 +178,32 @@ void config_sanity_check(struct sslhcfg_item* cfg) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < cfg->protocols_len; ++i) {
|
||||||
|
if (strcmp(cfg->protocols[i].name, "tls")) {
|
||||||
|
if (cfg->protocols[i].sni_hostnames_len) {
|
||||||
|
print_message(msg_config_error, "name: \"%s\"; host: \"%s\"; port: \"%s\": "
|
||||||
|
"Config option sni_hostnames is only applicable for tls\n",
|
||||||
|
cfg->protocols[i].name, cfg->protocols[i].host, cfg->protocols[i].port);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (cfg->protocols[i].alpn_protocols_len) {
|
||||||
|
print_message(msg_config_error, "name: \"%s\"; host: \"%s\"; port: \"%s\": "
|
||||||
|
"Config option alpn_protocols is only applicable for tls\n",
|
||||||
|
cfg->protocols[i].name, cfg->protocols[i].host, cfg->protocols[i].port);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg->protocols[i].is_udp) {
|
||||||
|
if (cfg->protocols[i].tfo_ok) {
|
||||||
|
print_message(msg_config_error, "name: \"%s\"; host: \"%s\"; port: \"%s\": "
|
||||||
|
"Config option tfo_ok is not applicable for udp connections\n",
|
||||||
|
cfg->protocols[i].name, cfg->protocols[i].host, cfg->protocols[i].port);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ void main_loop(struct listen_endpoint listen_sockets[], int num_addr_listen)
|
|||||||
|
|
||||||
print_message(msg_fd, "selecting... max_fd=%d num_probing=%d\n",
|
print_message(msg_fd, "selecting... max_fd=%d num_probing=%d\n",
|
||||||
fd_info.watchers->max_fd, fd_info.num_probing);
|
fd_info.watchers->max_fd, fd_info.num_probing);
|
||||||
res = select(fd_info.watchers->max_fd, &readfds, &writefds,
|
res = select(fd_info.watchers->max_fd + 1, &readfds, &writefds,
|
||||||
NULL, fd_info.num_probing ? &tv : NULL);
|
NULL, fd_info.num_probing ? &tv : NULL);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
perror("select");
|
perror("select");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user