From aa17061e26a06624d7bb375baeffe4a905842a02 Mon Sep 17 00:00:00 2001 From: Toni Uhlig Date: Thu, 11 Aug 2022 17:05:57 +0200 Subject: [PATCH] add openvpn udp probe Signed-off-by: Toni Uhlig --- probe.c | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/probe.c b/probe.c index aa9db03..4f704a0 100644 --- a/probe.c +++ b/probe.c @@ -137,15 +137,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 * 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) { int packet_len; - if (len < 2) - return PROBE_AGAIN; + if (proto->is_udp == 0) + { + if (len < 2) + return PROBE_AGAIN; - packet_len = ntohs(*(uint16_t*)p); - return packet_len == len - 2; + packet_len = ntohs(*(uint16_t*)p); + 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?