mirror of
https://github.com/postgres/postgres.git
synced 2025-08-28 18:48:04 +03:00
Send ALPN in TLS handshake, require it in direct SSL connections
libpq now always tries to send ALPN. With the traditional negotiated SSL connections, the server accepts the ALPN, and refuses the connection if it's not what we expect, but connecting without ALPN is still OK. With the new direct SSL connections, ALPN is mandatory. NOTE: This uses "TBD-pgsql" as the protocol ID. We must register a proper one with IANA before the release! Author: Greg Stark, Heikki Linnakangas Reviewed-by: Matthias van de Meent, Jacob Champion
This commit is contained in:
@@ -885,6 +885,9 @@ destroy_ssl_system(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* See pqcomm.h comments on OpenSSL implementation of ALPN (RFC 7301) */
|
||||
static unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR;
|
||||
|
||||
/*
|
||||
* Create per-connection SSL object, and load the client certificate,
|
||||
* private key, and trusted CA certs.
|
||||
@@ -1233,6 +1236,22 @@ initialize_SSL(PGconn *conn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Set ALPN */
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = SSL_set_alpn_protos(conn->ssl, alpn_protos, sizeof(alpn_protos));
|
||||
|
||||
if (retval != 0)
|
||||
{
|
||||
char *err = SSLerrmessage(ERR_get_error());
|
||||
|
||||
libpq_append_conn_error(conn, "could not set ssl alpn extension: %s", err);
|
||||
SSLerrfree(err);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the SSL key. If a key is specified, treat it as an engine:key
|
||||
* combination if there is colon present - we don't support files with
|
||||
@@ -1754,6 +1773,7 @@ PQsslAttributeNames(PGconn *conn)
|
||||
"cipher",
|
||||
"compression",
|
||||
"protocol",
|
||||
"alpn",
|
||||
NULL
|
||||
};
|
||||
static const char *const empty_attrs[] = {NULL};
|
||||
@@ -1808,6 +1828,21 @@ PQsslAttribute(PGconn *conn, const char *attribute_name)
|
||||
if (strcmp(attribute_name, "protocol") == 0)
|
||||
return SSL_get_version(conn->ssl);
|
||||
|
||||
if (strcmp(attribute_name, "alpn") == 0)
|
||||
{
|
||||
const unsigned char *data;
|
||||
unsigned int len;
|
||||
static char alpn_str[256]; /* alpn doesn't support longer than 255
|
||||
* bytes */
|
||||
|
||||
SSL_get0_alpn_selected(conn->ssl, &data, &len);
|
||||
if (data == NULL || len == 0 || len > sizeof(alpn_str) - 1)
|
||||
return NULL;
|
||||
memcpy(alpn_str, data, len);
|
||||
alpn_str[len] = 0;
|
||||
return alpn_str;
|
||||
}
|
||||
|
||||
return NULL; /* unknown attribute */
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user