Compare commits

..

No commits in common. "imports/c8s/openldap-2.4.46-16.el8" and "c8" have entirely different histories.

7 changed files with 527 additions and 228 deletions

View File

@ -0,0 +1,72 @@
From 840944e26f734bb03d925f26c4ef11a6cedcbb9c Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Thu, 25 Aug 2022 16:13:21 +0100
Subject: [PATCH] ITS#9904 ldap_url_parsehosts: check for strdup failure
Avoid unnecessary strdup in IPv6 addr parsing, check for strdup
failure when dup'ing scheme.
Code present since 2000, 8da110a9e726dbc612b302feafe0109271e6bc59
---
libraries/libldap/url.c | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c
index dcf2aac9e8..493fd7ce47 100644
--- a/libraries/libldap/url.c
+++ b/libraries/libldap/url.c
@@ -1385,24 +1385,22 @@ ldap_url_parsehosts(
}
ludp->lud_port = port;
ludp->lud_host = specs[i];
- specs[i] = NULL;
p = strchr(ludp->lud_host, ':');
if (p != NULL) {
/* more than one :, IPv6 address */
if ( strchr(p+1, ':') != NULL ) {
/* allow [address] and [address]:port */
if ( *ludp->lud_host == '[' ) {
- p = LDAP_STRDUP(ludp->lud_host+1);
- /* copied, make sure we free source later */
- specs[i] = ludp->lud_host;
- ludp->lud_host = p;
- p = strchr( ludp->lud_host, ']' );
+ p = strchr( ludp->lud_host+1, ']' );
if ( p == NULL ) {
LDAP_FREE(ludp);
ldap_charray_free(specs);
return LDAP_PARAM_ERROR;
}
- *p++ = '\0';
+ /* Truncate trailing ']' and shift hostname down 1 char */
+ *p = '\0';
+ AC_MEMCPY( ludp->lud_host, ludp->lud_host+1, p - ludp->lud_host );
+ p++;
if ( *p != ':' ) {
if ( *p != '\0' ) {
LDAP_FREE(ludp);
@@ -1428,14 +1426,19 @@ ldap_url_parsehosts(
}
}
}
- ldap_pvt_hex_unescape(ludp->lud_host);
ludp->lud_scheme = LDAP_STRDUP("ldap");
+ if ( ludp->lud_scheme == NULL ) {
+ LDAP_FREE(ludp);
+ ldap_charray_free(specs);
+ return LDAP_NO_MEMORY;
+ }
+ specs[i] = NULL;
+ ldap_pvt_hex_unescape(ludp->lud_host);
ludp->lud_next = *ludlist;
*ludlist = ludp;
}
/* this should be an array of NULLs now */
- /* except entries starting with [ */
ldap_charray_free(specs);
return LDAP_SUCCESS;
}
--
2.44.0

View File

@ -0,0 +1,26 @@
From c5c8c06a8bd52ea7b843e7d8ca961a7d1800ce5f Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Wed, 24 Aug 2022 14:40:51 +0100
Subject: [PATCH] ITS#9904 ldif_open_url: check for ber_strdup failure
Code present since 1999, df8f7cbb9b79be3be9205d116d1dd0b263d6861a
---
libraries/libldap/fetch.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libraries/libldap/fetch.c b/libraries/libldap/fetch.c
index 9e426dc647..536871bcfe 100644
--- a/libraries/libldap/fetch.c
+++ b/libraries/libldap/fetch.c
@@ -69,6 +69,8 @@ ldif_open_url(
}
p = ber_strdup( urlstr );
+ if ( p == NULL )
+ return NULL;
/* But we should convert to LDAP_DIRSEP before use */
if ( LDAP_DIRSEP[0] != '/' ) {
--
2.44.0

View File

@ -0,0 +1,339 @@
From c8050d1e6eb0f4f3deb187224945ddcfc3baa4d6 Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Fri, 21 Aug 2020 09:15:15 +0100
Subject: [PATCH] ITS#9318 add TLS_REQSAN option
Add an option to specify how subjectAlternativeNames should be
handled when validating the names in a server certificate.
---
doc/man/man3/ldap_get_option.3 | 9 +++++++
doc/man/man5/ldap.conf.5 | 31 +++++++++++++++++++++++
include/ldap.h | 1 +
libraries/libldap/init.c | 2 ++
libraries/libldap/ldap-int.h | 1 +
libraries/libldap/tls2.c | 16 ++++++++++++
libraries/libldap/tls_g.c | 46 ++++++++++++++++++++++++++++++++--
libraries/libldap/tls_o.c | 44 ++++++++++++++++++++++++++++++--
8 files changed, 146 insertions(+), 4 deletions(-)
diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3
index d229ce6e3..7d760136f 100644
--- a/doc/man/man3/ldap_get_option.3
+++ b/doc/man/man3/ldap_get_option.3
@@ -788,6 +788,15 @@ one of
.BR LDAP_OPT_X_TLS_ALLOW ,
.BR LDAP_OPT_X_TLS_TRY .
.TP
+.B LDAP_OPT_X_TLS_REQUIRE_SAN
+Sets/gets the peer certificate subjectAlternativeName checking strategy,
+one of
+.BR LDAP_OPT_X_TLS_NEVER ,
+.BR LDAP_OPT_X_TLS_HARD ,
+.BR LDAP_OPT_X_TLS_DEMAND ,
+.BR LDAP_OPT_X_TLS_ALLOW ,
+.BR LDAP_OPT_X_TLS_TRY .
+.TP
.B LDAP_OPT_X_TLS_SSL_CTX
Gets the TLS session context associated with this handle.
.BR outvalue
diff --git a/doc/man/man5/ldap.conf.5 b/doc/man/man5/ldap.conf.5
index 2f1ee886d..cde2c875f 100644
--- a/doc/man/man5/ldap.conf.5
+++ b/doc/man/man5/ldap.conf.5
@@ -464,6 +464,37 @@ certificate is provided, or a bad certificate is provided, the session
is immediately terminated. This is the default setting.
.RE
.TP
+.B TLS_REQSAN <level>
+Specifies what checks to perform on the subjectAlternativeName
+(SAN) extensions in a server certificate when validating the certificate
+name against the specified hostname of the server. The
+.B <level>
+can be specified as one of the following keywords:
+.RS
+.TP
+.B never
+The client will not check any SAN in the certificate.
+.TP
+.B allow
+The SAN is checked against the specified hostname. If a SAN is
+present but none match the specified hostname, the SANs are ignored
+and the usual check against the certificate DN is used.
+This is the default setting.
+.TP
+.B try
+The SAN is checked against the specified hostname. If no SAN is present
+in the server certificate, the usual check against the certificate DN
+is used. If a SAN is present but doesn't match the specified hostname,
+the session is immediately terminated. This setting may be preferred
+when a mix of certs with and without SANs are in use.
+.TP
+.B demand | hard
+These keywords are equivalent. The SAN is checked against the specified
+hostname. If no SAN is present in the server certificate, or no SANs
+match, the session is immediately terminated. This setting should be
+used when only certificates with SANs are in use.
+.RE
+.TP
.B TLS_CRLCHECK <level>
Specifies if the Certificate Revocation List (CRL) of the CA should be
used to verify if the server certificates have not been revoked. This
diff --git a/include/ldap.h b/include/ldap.h
index 4b81a6841..4877de24a 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -160,6 +160,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_TLS_PACKAGE 0x6011
#define LDAP_OPT_X_TLS_ECNAME 0x6012
#define LDAP_OPT_X_TLS_PEERCERT 0x6015 /* read-only */
+#define LDAP_OPT_X_TLS_REQUIRE_SAN 0x601a
#define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index d503019aa..0d91808ec 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -128,6 +128,7 @@ static const struct ol_attribute {
{0, ATTR_TLS, "TLS_CACERT", NULL, LDAP_OPT_X_TLS_CACERTFILE},
{0, ATTR_TLS, "TLS_CACERTDIR", NULL, LDAP_OPT_X_TLS_CACERTDIR},
{0, ATTR_TLS, "TLS_REQCERT", NULL, LDAP_OPT_X_TLS_REQUIRE_CERT},
+ {0, ATTR_TLS, "TLS_REQSAN", NULL, LDAP_OPT_X_TLS_REQUIRE_SAN},
{0, ATTR_TLS, "TLS_RANDFILE", NULL, LDAP_OPT_X_TLS_RANDOM_FILE},
{0, ATTR_TLS, "TLS_CIPHER_SUITE", NULL, LDAP_OPT_X_TLS_CIPHER_SUITE},
{0, ATTR_TLS, "TLS_PROTOCOL_MIN", NULL, LDAP_OPT_X_TLS_PROTOCOL_MIN},
@@ -624,6 +625,7 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
gopts->ldo_tls_connect_cb = NULL;
gopts->ldo_tls_connect_arg = NULL;
gopts->ldo_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
+ gopts->ldo_tls_require_san = LDAP_OPT_X_TLS_ALLOW;
#endif
gopts->ldo_keepalive_probes = 0;
gopts->ldo_keepalive_interval = 0;
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index 753014ad0..2bf5d4ff6 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -262,6 +262,7 @@ struct ldapoptions {
int ldo_tls_require_cert;
int ldo_tls_impl;
int ldo_tls_crlcheck;
+ int ldo_tls_require_san;
#define LDAP_LDO_TLS_NULLARG ,0,0,0,{0,0,0,0,0,0,0,0,0},0,0,0,0
#else
#define LDAP_LDO_TLS_NULLARG
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index 6a2113255..670292c22 100644
--- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c
@@ -539,6 +539,7 @@ ldap_int_tls_config( LDAP *ld, int option, const char *arg )
return ldap_pvt_tls_set_option( ld, option, (void *) arg );
case LDAP_OPT_X_TLS_REQUIRE_CERT:
+ case LDAP_OPT_X_TLS_REQUIRE_SAN:
case LDAP_OPT_X_TLS:
i = -1;
if ( strcasecmp( arg, "never" ) == 0 ) {
@@ -669,6 +670,9 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
case LDAP_OPT_X_TLS_REQUIRE_CERT:
*(int *)arg = lo->ldo_tls_require_cert;
break;
+ case LDAP_OPT_X_TLS_REQUIRE_SAN:
+ *(int *)arg = lo->ldo_tls_require_san;
+ break;
#ifdef HAVE_OPENSSL_CRL
case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */
*(int *)arg = lo->ldo_tls_crlcheck;
@@ -818,6 +822,18 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
return 0;
}
return -1;
+ case LDAP_OPT_X_TLS_REQUIRE_SAN:
+ if ( !arg ) return -1;
+ switch( *(int *) arg ) {
+ case LDAP_OPT_X_TLS_NEVER:
+ case LDAP_OPT_X_TLS_DEMAND:
+ case LDAP_OPT_X_TLS_ALLOW:
+ case LDAP_OPT_X_TLS_TRY:
+ case LDAP_OPT_X_TLS_HARD:
+ lo->ldo_tls_require_san = * (int *) arg;
+ return 0;
+ }
+ return -1;
#ifdef HAVE_OPENSSL_CRL
case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */
if ( !arg ) return -1;
diff --git a/libraries/libldap/tls_g.c b/libraries/libldap/tls_g.c
index 15ce0bbb8..e3486c9b4 100644
--- a/libraries/libldap/tls_g.c
+++ b/libraries/libldap/tls_g.c
@@ -496,6 +496,7 @@ tlsg_session_chkhost( LDAP *ld, tls_session *session, const char *name_in )
{
tlsg_session *s = (tlsg_session *)session;
int i, ret;
+ int chkSAN = ld->ld_options.ldo_tls_require_san, gotSAN = 0;
const gnutls_datum_t *peer_cert_list;
unsigned int list_size;
char altname[NI_MAXHOST];
@@ -558,12 +559,14 @@ tlsg_session_chkhost( LDAP *ld, tls_session *session, const char *name_in )
}
}
+ if (chkSAN) {
for ( i=0, ret=0; ret >= 0; i++ ) {
altnamesize = sizeof(altname);
ret = gnutls_x509_crt_get_subject_alt_name( cert, i,
altname, &altnamesize, NULL );
if ( ret < 0 ) break;
+ gotSAN = 1;
/* ignore empty */
if ( altnamesize == 0 ) continue;
@@ -599,7 +602,45 @@ tlsg_session_chkhost( LDAP *ld, tls_session *session, const char *name_in )
}
if ( ret >= 0 ) {
ret = LDAP_SUCCESS;
- } else {
+ }
+ }
+ if (ret != LDAP_SUCCESS && chkSAN) {
+ switch(chkSAN) {
+ case LDAP_OPT_X_TLS_DEMAND:
+ case LDAP_OPT_X_TLS_HARD:
+ if (!gotSAN) {
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: unable to get subjectAltName from peer certificate.\n",
+ 0, 0, 0 );
+ ret = LDAP_CONNECT_ERROR;
+ if ( ld->ld_error ) {
+ LDAP_FREE( ld->ld_error );
+ }
+ ld->ld_error = LDAP_STRDUP(
+ _("TLS: unable to get subjectAltName from peer certificate"));
+ goto done;
+ }
+ /* FALLTHRU */
+ case LDAP_OPT_X_TLS_TRY:
+ if (gotSAN) {
+ Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
+ "subjectAltName in certificate.\n",
+ name, 0, 0 );
+ ret = LDAP_CONNECT_ERROR;
+ if ( ld->ld_error ) {
+ LDAP_FREE( ld->ld_error );
+ }
+ ld->ld_error = LDAP_STRDUP(
+ _("TLS: hostname does not match subjectAltName in peer certificate"));
+ goto done;
+ }
+ break;
+ case LDAP_OPT_X_TLS_ALLOW:
+ break;
+ }
+ }
+
+ if ( ret != LDAP_SUCCESS ){
/* find the last CN */
i=0;
do {
@@ -654,9 +695,10 @@ tlsg_session_chkhost( LDAP *ld, tls_session *session, const char *name_in )
LDAP_FREE( ld->ld_error );
}
ld->ld_error = LDAP_STRDUP(
- _("TLS: hostname does not match CN in peer certificate"));
+ _("TLS: hostname does not match name in peer certificate"));
}
}
+done:
gnutls_x509_crt_deinit( cert );
return ret;
}
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
index 4006f7a4f..6f27168e9 100644
--- a/libraries/libldap/tls_o.c
+++ b/libraries/libldap/tls_o.c
@@ -600,6 +600,7 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
{
tlso_session *s = (tlso_session *)sess;
int i, ret = LDAP_LOCAL_ERROR;
+ int chkSAN = ld->ld_options.ldo_tls_require_san, gotSAN = 0;
X509 *x;
const char *name;
char *ptr;
@@ -638,7 +639,8 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
}
-
+
+ if (chkSAN) {
i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
if (i >= 0) {
X509_EXTENSION *ex;
@@ -651,6 +653,7 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
char *domain = NULL;
GENERAL_NAME *gn;
+ gotSAN = 1;
if (ntype == IS_DNS) {
domain = strchr(name, '.');
if (domain) {
@@ -709,6 +712,42 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
}
}
}
+ }
+ if (ret != LDAP_SUCCESS && chkSAN) {
+ switch(chkSAN) {
+ case LDAP_OPT_X_TLS_DEMAND:
+ case LDAP_OPT_X_TLS_HARD:
+ if (!gotSAN) {
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: unable to get subjectAltName from peer certificate.\n",
+ 0, 0, 0 );
+ ret = LDAP_CONNECT_ERROR;
+ if ( ld->ld_error ) {
+ LDAP_FREE( ld->ld_error );
+ }
+ ld->ld_error = LDAP_STRDUP(
+ _("TLS: unable to get subjectAltName from peer certificate"));
+ goto done;
+ }
+ /* FALLTHRU */
+ case LDAP_OPT_X_TLS_TRY:
+ if (gotSAN) {
+ Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
+ "subjectAltName in certificate.\n",
+ name, 0, 0 );
+ ret = LDAP_CONNECT_ERROR;
+ if ( ld->ld_error ) {
+ LDAP_FREE( ld->ld_error );
+ }
+ ld->ld_error = LDAP_STRDUP(
+ _("TLS: hostname does not match subjectAltName in peer certificate"));
+ goto done;
+ }
+ break;
+ case LDAP_OPT_X_TLS_ALLOW:
+ break;
+ }
+ }
if (ret != LDAP_SUCCESS) {
X509_NAME *xn;
@@ -772,9 +811,10 @@ no_cn:
LDAP_FREE( ld->ld_error );
}
ld->ld_error = LDAP_STRDUP(
- _("TLS: hostname does not match CN in peer certificate"));
+ _("TLS: hostname does not match name in peer certificate"));
}
}
+done:
X509_free(x);
return ret;
}
--
2.31.1

View File

@ -0,0 +1,18 @@
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
index 6f27168..eb7b97c 100644
--- a/libraries/libldap/tls_o.c
+++ b/libraries/libldap/tls_o.c
@@ -862,7 +862,12 @@ tlso_session_endpoint( tls_session *sess, struct berval *buf, int is_server )
return 0;
#if OPENSSL_VERSION_NUMBER >= 0x10100000
- md = EVP_get_digestbynid( X509_get_signature_nid( cert ));
+ {
+ int mdnid;
+ if ( !OBJ_find_sigid_algs( X509_get_signature_nid( cert ), &mdnid, NULL ))
+ return 0;
+ md = EVP_get_digestbynid( mdnid );
+ }
#else
md = EVP_get_digestbynid(OBJ_obj2nid( cert->sig_alg->algorithm ));
#endif

View File

@ -0,0 +1,46 @@
From 2dfe3f35c7fef4792f15f0b3f9c9a10e5f9a4692 Mon Sep 17 00:00:00 2001
From: Simon Pichugin <spichugi@rehdat.com>
Date: Thu, 5 Aug 2021 16:15:09 +0200
Subject: [PATCH] Change TLS_REQSAN default to TRY
---
doc/man/man5/ldap.conf.5 | 2 +-
libraries/libldap/init.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/man/man5/ldap.conf.5 b/doc/man/man5/ldap.conf.5
index cde2c875f..9f1aa2c0a 100644
--- a/doc/man/man5/ldap.conf.5
+++ b/doc/man/man5/ldap.conf.5
@@ -479,7 +479,6 @@ The client will not check any SAN in the certificate.
The SAN is checked against the specified hostname. If a SAN is
present but none match the specified hostname, the SANs are ignored
and the usual check against the certificate DN is used.
-This is the default setting.
.TP
.B try
The SAN is checked against the specified hostname. If no SAN is present
@@ -487,6 +486,7 @@ in the server certificate, the usual check against the certificate DN
is used. If a SAN is present but doesn't match the specified hostname,
the session is immediately terminated. This setting may be preferred
when a mix of certs with and without SANs are in use.
+This is the default setting.
.TP
.B demand | hard
These keywords are equivalent. The SAN is checked against the specified
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index 0d91808ec..fa4c176fd 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -625,7 +625,7 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
gopts->ldo_tls_connect_cb = NULL;
gopts->ldo_tls_connect_arg = NULL;
gopts->ldo_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
- gopts->ldo_tls_require_san = LDAP_OPT_X_TLS_ALLOW;
+ gopts->ldo_tls_require_san = LDAP_OPT_X_TLS_TRY;
#endif
gopts->ldo_keepalive_probes = 0;
gopts->ldo_keepalive_interval = 0;
--
2.31.1

View File

@ -1,224 +0,0 @@
From f2978fefa13eb92b73922e49d2f6c12b4f92ea85 Mon Sep 17 00:00:00 2001
From: Christian Heimes <christian@python.org>
Date: Fri, 10 Jan 2020 18:35:02 +0100
Subject: [PATCH] Use OpenSSL API to verify host
Replace custom hostname and IP address verification with OpenSSL 1.0.2
APIs.
---
libraries/libldap/tls_o.c | 184 ++++++--------------------------------
1 file changed, 28 insertions(+), 156 deletions(-)
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
index e52c5507c..5adf7b74f 100644
--- a/libraries/libldap/tls_o.c
+++ b/libraries/libldap/tls_o.c
@@ -660,25 +660,15 @@ tlso_session_peer_dn( tls_session *sess, struct berval *der_dn )
return 0;
}
-/* what kind of hostname were we given? */
-#define IS_DNS 0
-#define IS_IP4 1
-#define IS_IP6 2
-
static int
tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
{
tlso_session *s = (tlso_session *)sess;
- int i, ret = LDAP_LOCAL_ERROR;
+ int ret = LDAP_LOCAL_ERROR;
X509 *x;
const char *name;
- char *ptr;
- int ntype = IS_DNS, nlen;
-#ifdef LDAP_PF_INET6
- struct in6_addr addr;
-#else
- struct in_addr addr;
-#endif
+ int flags = X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS;
+ ASN1_OCTET_STRING *ip;
if( ldap_int_hostname &&
( !name_in || !strcasecmp( name_in, "localhost" ) ) )
@@ -687,7 +677,6 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
} else {
name = name_in;
}
- nlen = strlen(name);
x = tlso_get_cert(s);
if (!x) {
@@ -619,150 +619,32 @@ tlso_session_chkhost( LDAP *ld, tls_session *sess, const char *name_in )
return LDAP_SUCCESS;
}
-#ifdef LDAP_PF_INET6
- if (inet_pton(AF_INET6, name, &addr)) {
- ntype = IS_IP6;
- } else
-#endif
- if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
- if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
- }
-
- i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
- if (i >= 0) {
- X509_EXTENSION *ex;
- STACK_OF(GENERAL_NAME) *alt;
-
- ex = X509_get_ext(x, i);
- alt = X509V3_EXT_d2i(ex);
- if (alt) {
- int n, len2 = 0;
- char *domain = NULL;
- GENERAL_NAME *gn;
-
- if (ntype == IS_DNS) {
- domain = strchr(name, '.');
- if (domain) {
- len2 = nlen - (domain-name);
- }
- }
- n = sk_GENERAL_NAME_num(alt);
- for (i=0; i<n; i++) {
- char *sn;
- int sl;
- gn = sk_GENERAL_NAME_value(alt, i);
- if (gn->type == GEN_DNS) {
- if (ntype != IS_DNS) continue;
-
- sn = (char *) ASN1_STRING_data(gn->d.ia5);
- sl = ASN1_STRING_length(gn->d.ia5);
-
- /* ignore empty */
- if (sl == 0) continue;
-
- /* Is this an exact match? */
- if ((nlen == sl) && !strncasecmp(name, sn, nlen)) {
- break;
- }
-
- /* Is this a wildcard match? */
- if (domain && (sn[0] == '*') && (sn[1] == '.') &&
- (len2 == sl-1) && !strncasecmp(domain, &sn[1], len2))
- {
- break;
- }
-
- } else if (gn->type == GEN_IPADD) {
- if (ntype == IS_DNS) continue;
-
- sn = (char *) ASN1_STRING_data(gn->d.ia5);
- sl = ASN1_STRING_length(gn->d.ia5);
-
-#ifdef LDAP_PF_INET6
- if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) {
- continue;
- } else
-#endif
- if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) {
- continue;
- }
- if (!memcmp(sn, &addr, sl)) {
- break;
- }
- }
- }
-
- GENERAL_NAMES_free(alt);
- if (i < n) { /* Found a match */
- ret = LDAP_SUCCESS;
- }
- }
- }
-
- if (ret != LDAP_SUCCESS) {
- X509_NAME *xn;
- X509_NAME_ENTRY *ne;
- ASN1_OBJECT *obj;
- ASN1_STRING *cn = NULL;
- int navas;
-
- /* find the last CN */
- obj = OBJ_nid2obj( NID_commonName );
- if ( !obj ) goto no_cn; /* should never happen */
-
- xn = X509_get_subject_name(x);
- navas = X509_NAME_entry_count( xn );
- for ( i=navas-1; i>=0; i-- ) {
- ne = X509_NAME_get_entry( xn, i );
- if ( !OBJ_cmp( X509_NAME_ENTRY_get_object(ne), obj )) {
- cn = X509_NAME_ENTRY_get_data( ne );
- break;
- }
+ /* attempt to encode name as IP address */
+ ip = a2i_IPADDRESS(name);
+ if (ip == NULL) {
+ ERR_clear_error();
+ /* it's a hostname */
+ if (X509_check_host(x, name, strlen(name), flags, NULL) == 1) {
+ ret = LDAP_SUCCESS;
}
-
- if( !cn )
- {
-no_cn:
- Debug( LDAP_DEBUG_ANY,
- "TLS: unable to get common name from peer certificate.\n",
- 0, 0, 0 );
- ret = LDAP_CONNECT_ERROR;
- if ( ld->ld_error ) {
- LDAP_FREE( ld->ld_error );
- }
- ld->ld_error = LDAP_STRDUP(
- _("TLS: unable to get CN from peer certificate"));
-
- } else if ( cn->length == nlen &&
- strncasecmp( name, (char *) cn->data, nlen ) == 0 ) {
+ } else {
+ /* It's an IPv4 or IPv6 address */
+ if (X509_check_ip(x, ASN1_STRING_data(ip),
+ ASN1_STRING_length(ip), 0) == 1) {
ret = LDAP_SUCCESS;
-
- } else if (( cn->data[0] == '*' ) && ( cn->data[1] == '.' )) {
- char *domain = strchr(name, '.');
- if( domain ) {
- int dlen;
-
- dlen = nlen - (domain-name);
-
- /* Is this a wildcard match? */
- if ((dlen == cn->length-1) &&
- !strncasecmp(domain, (char *) &cn->data[1], dlen)) {
- ret = LDAP_SUCCESS;
- }
- }
}
+ ASN1_OCTET_STRING_free(ip);
+ }
- if( ret == LDAP_LOCAL_ERROR ) {
- Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
- "common name in certificate (%.*s).\n",
- name, cn->length, cn->data );
- ret = LDAP_CONNECT_ERROR;
- if ( ld->ld_error ) {
- LDAP_FREE( ld->ld_error );
- }
- ld->ld_error = LDAP_STRDUP(
- _("TLS: hostname does not match CN in peer certificate"));
+ if( ret == LDAP_LOCAL_ERROR ) {
+ Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
+ "peer certificate.\n", name, 0, 0);
+ ret = LDAP_CONNECT_ERROR;
+ if ( ld->ld_error ) {
+ LDAP_FREE( ld->ld_error );
}
+ ld->ld_error = LDAP_STRDUP(
+ _("TLS: hostname does not match peer certificate"));
}
X509_free(x);
return ret;

View File

@ -5,7 +5,7 @@
Name: openldap
Version: 2.4.46
Release: 16%{?dist}
Release: 20%{?dist}
Summary: LDAP support libraries
License: OpenLDAP
URL: http://www.openldap.org/
@ -38,7 +38,6 @@ Patch20: openldap-ldapi-sasl.patch
Patch22: openldap-openssl-ITS7595-Add-EC-support-1.patch
Patch23: openldap-openssl-ITS7595-Add-EC-support-2.patch
Patch24: openldap-openssl-manpage-defaultCA.patch
Patch25: openldap-tlso-use-openssl-api-to-verify-host.patch
# The below patches come from upstream master and are necessary for Channel Binding
# (both tls-unique and tls-server-end-point) to work properly.
@ -57,6 +56,11 @@ Patch59: openldap-cbinding-ITS-9189_3-initialize-ldo_sasl_cbinding-in-LDAP_LDO_S
Patch60: openldap-cbinding-Fix-slaptest-in-test077.patch
Patch61: openldap-cbinding-Convert-test077-to-LDIF-config.patch
Patch62: openldap-cbinding-Update-keys-to-RSA-4096.patch
Patch63: openldap-add-TLS_REQSAN-option.patch
Patch64: openldap-change-TLS_REQSAN-default-to-TRY.patch
Patch65: openldap-cbinding-fix-openssl-digest.patch
Patch66: 0001-ITS-9904-ldap_url_parsehosts-check-for-strdup-failur.patch
Patch67: 0001-ITS-9904-ldif_open_url-check-for-ber_strdup-failure.patch
# check-password module specific patches
Patch90: check-password-makefile.patch
@ -137,7 +141,6 @@ AUTOMAKE=%{_bindir}/true autoreconf -fi
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch50 -p1
%patch51 -p1
%patch52 -p1
@ -151,6 +154,11 @@ AUTOMAKE=%{_bindir}/true autoreconf -fi
%patch60 -p1
%patch61 -p1
%patch62 -p1
%patch63 -p1
%patch64 -p1
%patch65 -p1
%patch66 -p1
%patch67 -p1
# build smbk5pwd with other overlays
ln -s ../../../contrib/slapd-modules/smbk5pwd/smbk5pwd.c servers/slapd/overlays
@ -179,7 +187,7 @@ popd
%set_build_flags
# enable experimental support for LDAP over UDP (LDAP_CONNECTIONLESS)
export CFLAGS="${CFLAGS} ${LDFLAGS} -Wl,--as-needed -DLDAP_CONNECTIONLESS -DLDAP_USE_NON_BLOCKING_TLS"
export CFLAGS="${CFLAGS} ${LDFLAGS} -Wl,--as-needed -DLDAP_CONNECTIONLESS -DLDAP_USE_NON_BLOCKING_TLS -DOPENSSL_NO_MD2"
pushd openldap-%{version}
%configure \
@ -520,6 +528,20 @@ exit 0
%{_mandir}/man3/*
%changelog
* Wed Jul 3 2024 Simon Pichugin <spichugi@redhat.com> - 2.4.46-20
- Bump version to 2.4.46-20
- Resolves: RHEL-35538 - Fix OpenSSL channel binding digest
* Tue Apr 30 2024 Simon Pichugin <spichugi@redhat.com> - 2.4.46-19
- Bump version to 2.4.46-19
- Resolves: RHEL-34283 - openldap: null pointer dereference in ber_memalloc_x function
* Thu Aug 5 2021 Simon Pichugin <spichugi@redhat.com> - 2.4.46-18
- Add TLS_REQSAN option and change the default to TRY (#1814674)
* Wed Jun 16 2021 Simon Pichugin <spichugi@redhat.com> - 2.4.46-17
- Rebuild without MP_2 support (#1909037)
* Thu Sep 10 2020 Simon Pichugin <spichugi@redhat.com> - 2.4.46-16
- CLDAP ldap_result hangs if nobody listens on the port (#1875361)