[master] 9260dbe Parse proxy-protocol-v2 tlv and ssl sub tlv.

Emmanuel Hocdet manu at gandi.net
Wed Mar 14 16:10:09 UTC 2018


commit 9260dbe0e3f90c79268cd3a073da063d3e8e1fd8
Author: Emmanuel Hocdet <manu at gandi.net>
Date:   Thu Feb 8 16:30:07 2018 +0100

    Parse proxy-protocol-v2 tlv and ssl sub tlv.
    
    Parse and check tlv and ssl sub tlv as described in:
    https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt

diff --git a/bin/varnishd/proxy/cache_proxy.h b/bin/varnishd/proxy/cache_proxy.h
new file mode 100644
index 0000000..c3cfcb1
--- /dev/null
+++ b/bin/varnishd/proxy/cache_proxy.h
@@ -0,0 +1,39 @@
+/*-
+ * Copyright (c) 2018 GANDI SAS
+ * All rights reserved.
+ *
+ * Author: Emmanuel Hocdet <manu at gandi.net>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define PP2_TYPE_ALPN           0x01
+#define PP2_TYPE_AUTHORITY      0x02
+#define PP2_TYPE_CRC32C         0x03
+#define PP2_TYPE_NOOP           0x04
+#define PP2_TYPE_SSL            0x20
+#define PP2_SUBTYPE_SSL_VERSION 0x21
+#define PP2_SUBTYPE_SSL_CN      0x22
+#define PP2_SUBTYPE_SSL_CIPHER  0x23
+#define PP2_SUBTYPE_SSL_SIG_ALG 0x24
+#define PP2_SUBTYPE_SSL_KEY_ALG 0x25
+#define PP2_SUBTYPE_SSL_MAX     0x25
diff --git a/bin/varnishd/proxy/cache_proxy_proto.c b/bin/varnishd/proxy/cache_proxy_proto.c
index a0f76fe..b16f971 100644
--- a/bin/varnishd/proxy/cache_proxy_proto.c
+++ b/bin/varnishd/proxy/cache_proxy_proto.c
@@ -1,8 +1,10 @@
 /*-
  * Copyright (c) 2015 Varnish Software AS
+ * Copyright (c) 2018 GANDI SAS
  * All rights reserved.
  *
- * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Authors: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *          Emmanuel Hocdet <manu at gandi.net>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,6 +36,7 @@
 
 #include "cache/cache_varnishd.h"
 #include "cache/cache_transport.h"
+#include "proxy/cache_proxy.h"
 
 #include "vend.h"
 #include "vsa.h"
@@ -153,6 +156,19 @@ vpx_proto1(const struct worker *wrk, const struct req *req)
  * PROXY 2 protocol
  */
 
+struct pp2_tlv {
+	uint8_t type;
+	uint8_t length_hi;
+	uint8_t length_lo;
+	uint8_t value[0];
+}__attribute__((packed));
+
+struct pp2_tlv_ssl {
+	uint8_t  client;
+	uint32_t verify;
+	struct pp2_tlv sub_tlv[0];
+}__attribute__((packed));
+
 static const char vpx2_sig[] = {
 	'\r', '\n', '\r', '\n', '\0', '\r', '\n',
 	'Q', 'U', 'I', 'T', '\n',
@@ -161,8 +177,9 @@ static const char vpx2_sig[] = {
 static int
 vpx_proto2(const struct worker *wrk, struct req *req)
 {
-	int l;
+	int l, hdr_len;
 	const uint8_t *p;
+	char *d;
 	sa_family_t pfam = 0xff;
 	struct sockaddr_in sin4;
 	struct sockaddr_in6 sin6;
@@ -178,10 +195,12 @@ vpx_proto2(const struct worker *wrk, struct req *req)
 
 	assert(req->htc->rxbuf_e - req->htc->rxbuf_b >= 16L);
 	l = vbe16dec(req->htc->rxbuf_b + 14);
-	assert(req->htc->rxbuf_e - req->htc->rxbuf_b >= 16L + l);
-	HTC_RxPipeline(req->htc, req->htc->rxbuf_b + 16L + l);
+	hdr_len = l + 16L;
+	assert(req->htc->rxbuf_e - req->htc->rxbuf_b >= hdr_len);
+	HTC_RxPipeline(req->htc, req->htc->rxbuf_b + hdr_len);
 	WS_Reset(req->ws, 0);
 	p = (const void *)req->htc->rxbuf_b;
+	d = req->htc->rxbuf_b + 16L;
 
 	/* Version @12 top half */
 	if ((p[12] >> 4) != 2) {
@@ -219,6 +238,8 @@ vpx_proto2(const struct worker *wrk, struct req *req)
 			    "PROXY2: Ignoring short IPv4 addresses (%d)", l);
 			return (0);
 		}
+		l -= 12;
+		d += 12;
 		break;
 	case 0x21:
 		/* IPv6|TCP */
@@ -228,6 +249,8 @@ vpx_proto2(const struct worker *wrk, struct req *req)
 			    "PROXY2: Ignoring short IPv6 addresses (%d)", l);
 			return (0);
 		}
+		l -= 36;
+		d += 36;
 		break;
 	default:
 		/* Ignore proxy header */
@@ -281,6 +304,39 @@ vpx_proto2(const struct worker *wrk, struct req *req)
 	SES_Set_String_Attr(req->sp, SA_CLIENT_PORT, pb);
 
 	VSL(SLT_Proxy, req->sp->vxid, "2 %s %s %s %s", hb, pb, ha, pa);
+
+	while (l > sizeof(struct pp2_tlv)) {
+		int el = vbe16dec(d + 1) + 3;
+		if (el > l) {
+			VSL(SLT_ProxyGarbage, req->sp->vxid, "PROXY2: Ignoring TLV");
+			return (0);
+		}
+		switch(d[0]) {
+		case PP2_TYPE_SSL:
+	        {
+			const char *sd;
+			int sl;
+			sd = d + sizeof(struct pp2_tlv) + sizeof(struct pp2_tlv_ssl);
+			sl = l - sizeof(struct pp2_tlv) - sizeof(struct pp2_tlv_ssl);
+			while (sl > sizeof(struct pp2_tlv)) {
+				int esl = vbe16dec(sd + 1) + 3;
+				if (esl > sl) {
+					VSL(SLT_ProxyGarbage, req->sp->vxid, "PROXY2: Ignoring SSL TLV");
+					return (0);
+				}
+				sd += esl;
+				sl -= esl;
+			}
+			break;
+		}
+		}
+		d += el;
+		l -= el;
+	}
+	if (l) {
+		VSL(SLT_ProxyGarbage, req->sp->vxid, "PROXY2: header length mismatch");
+		return (0);
+	}
 	return (0);
 }
 


More information about the varnish-commit mailing list