[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