From: Willy Tarreau Date: Mon, 11 Apr 2022 08:43:28 +0000 (+0200) Subject: MEDIUM: ssl: improve retrieval of ssl_sock_ctx and SSL detection X-Git-Tag: v2.6-dev6~128 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=de827958a2d1f727cdae752427134d0873af3e94;p=thirdparty%2Fhaproxy.git MEDIUM: ssl: improve retrieval of ssl_sock_ctx and SSL detection 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. --- diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 634452b1f5..9a03e9b81d 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -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 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 */ }; diff --git a/include/haproxy/connection.h b/include/haproxy/connection.h index 1d200308f0..7f1004826c 100644 --- a/include/haproxy/connection.h +++ b/include/haproxy/connection.h @@ -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 */ diff --git a/src/ssl_sock.c b/src/ssl_sock.c index 00c35d857c..232d1ce728 100644 --- a/src/ssl_sock.c +++ b/src/ssl_sock.c @@ -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, };