From 1a070a1ac821c8eda4d3a2856e2721b2fa97aaa1 Mon Sep 17 00:00:00 2001 From: Jacob Champion Date: Wed, 5 Jan 2022 15:47:03 -0800 Subject: [PATCH v10 3/3] squash! libpq: allow IP address SANs in server certs Per review, provide a pg_inet_pton() interface for IPv6 and refactor the internals accordingly. IPv4 is not yet implemented. The call sites that just want standard addresses without a CIDR mask have been updated to use the new function. Internally, the IPv6 parser now takes an allow_cidr boolean. I've plumbed that all the way down to getbits() in order to minimize the amount of code touched, at the expense of an unnecessary function call in the failing case. --- src/include/port.h | 1 + src/interfaces/libpq/fe-secure-common.c | 7 +-- src/interfaces/libpq/fe-secure-openssl.c | 2 +- src/port/inet_net_pton.c | 66 ++++++++++++++++++------ 4 files changed, 52 insertions(+), 24 deletions(-) diff --git a/src/include/port.h b/src/include/port.h index 2852e5b58b..fd046f4c24 100644 --- a/src/include/port.h +++ b/src/include/port.h @@ -517,6 +517,7 @@ extern char *pg_inet_net_ntop(int af, const void *src, int bits, /* port/inet_net_pton.c */ extern int pg_inet_net_pton(int af, const char *src, void *dst, size_t size); +extern int pg_inet_pton(int af, const char *src, void *dst); /* port/pg_strong_random.c */ extern void pg_strong_random_init(void); diff --git a/src/interfaces/libpq/fe-secure-common.c b/src/interfaces/libpq/fe-secure-common.c index 2c0af62afe..9c408df369 100644 --- a/src/interfaces/libpq/fe-secure-common.c +++ b/src/interfaces/libpq/fe-secure-common.c @@ -211,12 +211,7 @@ pq_verify_peer_name_matches_certificate_ip(PGconn *conn, family = PGSQL_AF_INET6; - /* - * pg_inet_net_pton() will accept CIDR masks, which we don't want to - * match, so skip the comparison if the host string contains a slash. - */ - if (!strchr(host, '/') - && pg_inet_net_pton(PGSQL_AF_INET6, host, addr, -1) == 128) + if (pg_inet_pton(PGSQL_AF_INET6, host, addr) == 1) { if (memcmp(ipdata, addr, iplen) == 0) match = 1; diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 7656c3a75e..b70bd2eb19 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -555,7 +555,7 @@ is_ip_address(const char *host) unsigned char dummy6[16]; return inet_aton(host, &dummy4) - || (pg_inet_net_pton(PGSQL_AF_INET6, host, dummy6, -1) == 128); + || (pg_inet_pton(PGSQL_AF_INET6, host, dummy6) == 1); } /* -- 2.25.1