On Thu, May 26, 2016 at 10:20:36AM -0400, Erik Seres wrote:
> Hi Willy,
> 
> Attached is my updated patch per your styling update request.

Thanks Erik. I'm now CCing Dave and Amos, both of whom worked on this
18 months ago. Amos requested the use of value 0x01 for ALPN and 0x02
for SNI by then, though I don't know if in the end he implemlented
anything. Same for Dave who wanted to implement them in the protocol.

Guys, for a bit of context, Erik proposes a patch to implement SNI on
PP2. If nobody implemented anything yet, maybe it's best to continue with
0x23 and so on for now. Otherwise if anything was already implemented, we'll
stay on what was already done. Please however, do provide patches at least
for the doc if anything was done, as it's quite hard to have to dig through
e-mail archives to find the details :-/

Thus please just check between all of you and tell me if I apply the
attached patch or if we need to change the ID. We absolutely need to work
on this to define how to extend the protocol in the future and to register
new IDs...

Thanks!
Willy

>From ee5b141df994c8fe42f8f2d85aa20a87dc10ca19 Mon Sep 17 00:00:00 2001
From: Erik Seres <erikse...@gmail.com>
Date: Thu, 12 May 2016 11:05:14 +0200
Subject: [PATCH] [RFC]/MINOR: connection: Add server name to proxy protocol v2
 header.

If the client provides the server name it intends to connect to, per RFC3546, 
Section 3.1. Server Name Indication, this patch will pass the server name onto 
the backend server as part of the proxy protocol v2 header.

The patch defines the new SSL subtype PP2_TYPE_SSL_SNI and the corresponding 
flag PP2_CLIENT_SNI to accomplish this in an additional TLV.
---
 doc/proxy-protocol.txt     | 7 +++++++
 include/proto/ssl_sock.h   | 1 +
 include/types/connection.h | 2 ++
 src/connection.c           | 5 +++++
 src/ssl_sock.c             | 9 +++++++++
 5 files changed, 24 insertions(+)

diff --git a/doc/proxy-protocol.txt b/doc/proxy-protocol.txt
index 472dcb2..499a4e2 100644
--- a/doc/proxy-protocol.txt
+++ b/doc/proxy-protocol.txt
@@ -530,6 +530,7 @@ The following types have already been registered for the 
<type> field :
         #define PP2_TYPE_SSL            0x20
         #define PP2_SUBTYPE_SSL_VERSION 0x21
         #define PP2_SUBTYPE_SSL_CN      0x22
+        #define PP2_SUBTYPE_SSL_SNI     0x23
         #define PP2_TYPE_NETNS          0x30
 
 
@@ -552,6 +553,7 @@ indicating which element is present :
        #define PP2_CLIENT_SSL           0x01
        #define PP2_CLIENT_CERT_CONN     0x02
        #define PP2_CLIENT_CERT_SESS     0x04
+       #define PP2_CLIENT_SNI           0x08
 
 Note, that each of these elements may lead to extra data being appended to
 this TLV using a second level of TLV encapsulation. It is thus possible to
@@ -566,6 +568,11 @@ PP2_CLIENT_CERT_CONN indicates that the client provided a 
certificate over the
 current connection. PP2_CLIENT_CERT_SESS indicates that the client provided a
 certificate at least once over the TLS session this connection belongs to.
 
+PP2_CLIENT_SNI flag indicates that the client provided a server name according
+to the Server Name Indication TLS extension. When this field is present, the
+string representation of the intended server name is appended at the end of the
+field in the TLV format using the type PP2_SUBTYPE_SSL_SNI.
+
 In all cases, the string representation (in UTF8) of the Common Name field
 (OID: 2.5.4.3) of the client certificate's DistinguishedName, is appended
 using the TLV format and the type PP2_SUBTYPE_SSL_CN.
diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h
index cb9a1e9..a5a05f0 100644
--- a/include/proto/ssl_sock.h
+++ b/include/proto/ssl_sock.h
@@ -53,6 +53,7 @@ void ssl_sock_free_ca(struct bind_conf *bind_conf);
 const char *ssl_sock_get_cipher_name(struct connection *conn);
 const char *ssl_sock_get_proto_version(struct connection *conn);
 char *ssl_sock_get_version(struct connection *conn);
+char *ssl_sock_get_servername(struct connection *conn);
 void ssl_sock_set_servername(struct connection *conn, const char *hostname);
 int ssl_sock_get_cert_used_sess(struct connection *conn);
 int ssl_sock_get_cert_used_conn(struct connection *conn);
diff --git a/include/types/connection.h b/include/types/connection.h
index dfbff6a..3159085 100644
--- a/include/types/connection.h
+++ b/include/types/connection.h
@@ -335,6 +335,7 @@ struct proxy_hdr_v2 {
 #define PP2_TYPE_SSL           0x20
 #define PP2_TYPE_SSL_VERSION   0x21
 #define PP2_TYPE_SSL_CN        0x22
+#define PP2_TYPE_SSL_SNI       0x23
 #define PP2_TYPE_NETNS         0x30
 
 #define TLV_HEADER_SIZE      3
@@ -355,6 +356,7 @@ struct tlv_ssl {
 #define PP2_CLIENT_SSL           0x01
 #define PP2_CLIENT_CERT_CONN     0x02
 #define PP2_CLIENT_CERT_SESS     0x04
+#define PP2_CLIENT_SNI           0x08
 
 #endif /* _TYPES_CONNECTION_H */
 
diff --git a/src/connection.c b/src/connection.c
index 330f3ef..29c45d6 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -820,6 +820,11 @@ int make_proxy_line_v2(char *buf, int buf_len, struct 
server *srv, struct connec
                                        ssl_tlv_len += 
make_tlv(&buf[ret+ssl_tlv_len], (buf_len - ret - ssl_tlv_len), PP2_TYPE_SSL_CN, 
cn_trash->len, cn_trash->str);
                                }
                        }
+                       value = ssl_sock_get_servername(remote);
+                       if (value) {
+                               tlv->client |= PP2_CLIENT_SNI;
+                               ssl_tlv_len += make_tlv(&buf[ret + 
ssl_tlv_len], (buf_len - ret-ssl_tlv_len), PP2_TYPE_SSL_SNI, strlen(value), 
value);
+                       }
                }
                tlv->tlv.length_hi = (uint16_t)(ssl_tlv_len - sizeof(struct 
tlv)) >> 8;
                tlv->tlv.length_lo = (uint16_t)(ssl_tlv_len - sizeof(struct 
tlv)) & 0x00ff;
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index 0d35c29..41f8f18 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -3973,6 +3973,15 @@ char *ssl_sock_get_version(struct connection *conn)
        return (char *)SSL_get_version(conn->xprt_ctx);
 }
 
+/* returns server name if client passed TLS SNI extension, NULL if not */
+char *ssl_sock_get_servername(struct connection *conn)
+{
+       if (!ssl_sock_is_ssl(conn))
+               return NULL;
+
+       return (char *)SSL_get_servername(conn->xprt_ctx, 
TLSEXT_NAMETYPE_host_name);
+}
+
 void ssl_sock_set_servername(struct connection *conn, const char *hostname)
 {
 #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
-- 
2.7.4 (Apple Git-66)

Reply via email to