]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: ssl: improve retrieval of ssl_sock_ctx and SSL detection
authorWilly Tarreau <w@1wt.eu>
Mon, 11 Apr 2022 08:43:28 +0000 (10:43 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 11 Apr 2022 17:33:04 +0000 (19:33 +0200)
Historically there was a single way to have an SSL transport on a
connection, so detecting if the transport layer was SSL and a context
was present was sufficient to detect SSL. With QUIC, things have changed
because QUIC also relies on SSL, but the context is embedded inside the
quic_conn and the transport layer doesn't match expectations outside,
making it difficult to detect that SSL is in use over the connection.

The approach taken here to improve this consists in adding a new method
at the transport layer, get_ssl_sock_ctx(), to retrieve this often needed
ssl_sock_ctx, and to use this to detect the presence of SSL. This will
even allow some simplifications and cleanups to be made in the SSL code
itself, and QUIC will be able to provide one to export its ssl_sock_ctx.

include/haproxy/connection-t.h
include/haproxy/connection.h
src/ssl_sock.c

index 634452b1f56727814d5573f660d6ae57dede5153..9a03e9b81d212e3ff79e99f317287da3f6cd02aa 100644 (file)
@@ -51,6 +51,7 @@ struct pipe;
 struct quic_conn;
 struct bind_conf;
 struct qcs;
+struct ssl_sock_ctx;
 
 /* Note: subscribing to these events is only valid after the caller has really
  * attempted to perform the operation, and failed to proceed or complete.
@@ -360,6 +361,7 @@ struct xprt_ops {
        int (*unsubscribe)(struct connection *conn, void *xprt_ctx, int event_type, struct wait_event *es); /* Unsubscribe <es> from events */
        int (*remove_xprt)(struct connection *conn, void *xprt_ctx, void *toremove_ctx, const struct xprt_ops *newops, void *newctx); /* Remove an xprt from the connection, used by temporary xprt such as the handshake one */
        int (*add_xprt)(struct connection *conn, void *xprt_ctx, void *toadd_ctx, const struct xprt_ops *toadd_ops, void **oldxprt_ctx, const struct xprt_ops **oldxprt_ops); /* Add a new XPRT as the new xprt, and return the old one */
+       struct ssl_sock_ctx *(*get_ssl_sock_ctx)(struct connection *); /* retrieve the ssl_sock_ctx in use, or NULL if none */
        int (*show_fd)(struct buffer *, const struct connection *, const void *ctx); /* append some data about xprt for "show fd"; returns non-zero if suspicious */
 };
 
index 1d200308f0bd0e8169498e798031e7f9779a0325..7f1004826ccc237df8b319c97dbdc91943b957c6 100644 (file)
@@ -648,15 +648,18 @@ static inline struct proxy *conn_get_proxy(const struct connection *conn)
        return objt_proxy(conn->target);
 }
 
+/* retrieves the ssl_sock_ctx for this connection otherwise NULL */
+static inline struct ssl_sock_ctx *conn_get_ssl_sock_ctx(struct connection *conn)
+{
+       if (!conn || !conn->xprt || !conn->xprt->get_ssl_sock_ctx)
+               return NULL;
+       return conn->xprt->get_ssl_sock_ctx(conn);
+}
 
 /* boolean, returns true if connection is over SSL */
-static inline
-int conn_is_ssl(struct connection *conn)
+static inline int conn_is_ssl(struct connection *conn)
 {
-       if (!conn || conn->xprt != xprt_get(XPRT_SSL) || !conn->xprt_ctx)
-               return 0;
-       else
-               return 1;
+       return !!conn_get_ssl_sock_ctx(conn);
 }
 
 #endif /* _HAPROXY_CONNECTION_H */
index 00c35d857cf19393b34f81e264b9f0c18956f1e6..232d1ce728d4d3690cde8297ca04b82a8144aa8b 100644 (file)
@@ -595,6 +595,14 @@ static void ssl_sock_unregister_msg_callbacks(void)
        }
 }
 
+static struct ssl_sock_ctx *ssl_sock_get_ctx(struct connection *conn)
+{
+       if (!conn || conn->xprt != xprt_get(XPRT_SSL) || !conn->xprt_ctx)
+               return NULL;
+
+       return (struct ssl_sock_ctx *)conn->xprt_ctx;
+}
+
 SSL *ssl_sock_get_ssl_object(struct connection *conn)
 {
        if (!conn_is_ssl(conn))
@@ -7729,6 +7737,7 @@ struct xprt_ops ssl_sock = {
        .takeover = ssl_takeover,
        .set_idle = ssl_set_idle,
        .set_used = ssl_set_used,
+       .get_ssl_sock_ctx = ssl_sock_get_ctx,
        .name     = "SSL",
        .show_fd  = ssl_sock_show_fd,
 };