From: Heikki Linnakangas Date: Mon, 29 Apr 2024 15:12:24 +0000 (+0300) Subject: libpq: Enforce ALPN in direct SSL connections X-Git-Tag: REL_17_BETA1~146 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=03a0e0d4bb78f23449802463ceea3c5bf8d4838a;p=postgresql.git libpq: Enforce ALPN in direct SSL connections ALPN is mandatory with direct SSL connections. That is documented, and the server checks it, but libpq was missing the check. Reported-by: Jacob Champion Reviewed-by: Michael Paquier Discussion: https://www.postgresql.org/message-id/CAOYmi+=sj+1uydS0NR4nYzw-LRWp3Q-s5speBug5UCLSPMbvGA@mail.gmail.com --- diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 33362000d3c..0de21dc7e45 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1585,6 +1585,34 @@ open_client_SSL(PGconn *conn) } } + /* ALPN is mandatory with direct SSL connections */ + if (conn->current_enc_method == ENC_DIRECT_SSL) + { + const unsigned char *selected; + unsigned int len; + + SSL_get0_alpn_selected(conn->ssl, &selected, &len); + + if (selected == NULL) + { + libpq_append_conn_error(conn, "direct SSL connection was established without ALPN protocol negotiation extension"); + pgtls_close(conn); + return PGRES_POLLING_FAILED; + } + + /* + * We only support one protocol so that's what the negotiation should + * always choose, but doesn't hurt to check. + */ + if (len != strlen(PG_ALPN_PROTOCOL) || + memcmp(selected, PG_ALPN_PROTOCOL, strlen(PG_ALPN_PROTOCOL)) != 0) + { + libpq_append_conn_error(conn, "SSL connection was established with unexpected ALPN protocol"); + pgtls_close(conn); + return PGRES_POLLING_FAILED; + } + } + /* * We already checked the server certificate in initialize_SSL() using * SSL_CTX_set_verify(), if root.crt exists.