openldap2/0240-ITS-9518-add-LDAP_OPT_X_TLS_PROTOCOL_MAX-option.patch
2024-02-28 21:00:53 +08:00

216 lines
7.5 KiB
Diff

From e2b25e6e935253ad1d8b834cadebb7277770b336 Mon Sep 17 00:00:00 2001
From: Howard Chu <hyc@openldap.org>
Date: Fri, 9 Apr 2021 18:09:15 +0100
Subject: [PATCH 240/241] ITS#9518 add LDAP_OPT_X_TLS_PROTOCOL_MAX option
OpenSSL only
---
doc/man/man3/ldap_get_option.3 | 9 +++++
include/ldap.h | 3 +-
libraries/libldap/init.c | 1 +
libraries/libldap/ldap-int.h | 5 ++-
libraries/libldap/tls2.c | 8 +++++
libraries/libldap/tls_o.c | 64 ++++++++++++++++++++++------------
6 files changed, 66 insertions(+), 24 deletions(-)
diff --git a/doc/man/man3/ldap_get_option.3 b/doc/man/man3/ldap_get_option.3
index af5ede141e..ab4fe5d934 100644
--- a/doc/man/man3/ldap_get_option.3
+++ b/doc/man/man3/ldap_get_option.3
@@ -730,6 +730,15 @@ A non-zero value pointed to by
.BR invalue
tells the library to create a context for a server.
.TP
+.B LDAP_OPT_X_TLS_PROTOCOL_MAX
+Sets/gets the maximum protocol version.
+.BR invalue
+must be
+.BR "const int *" ;
+.BR outvalue
+must be
+.BR "int *" .
+.TP
.B LDAP_OPT_X_TLS_PROTOCOL_MIN
Sets/gets the minimum protocol version.
.BR invalue
diff --git a/include/ldap.h b/include/ldap.h
index 149b9ea725..02de148661 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -158,6 +158,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_TLS_NEWCTX 0x600f
#define LDAP_OPT_X_TLS_CRLFILE 0x6010 /* GNUtls only */
#define LDAP_OPT_X_TLS_PACKAGE 0x6011
+#define LDAP_OPT_X_TLS_PROTOCOL_MAX 0x601b
#define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1
@@ -169,7 +170,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_TLS_CRL_PEER 1
#define LDAP_OPT_X_TLS_CRL_ALL 2
-/* for LDAP_OPT_X_TLS_PROTOCOL_MIN */
+/* for LDAP_OPT_X_TLS_PROTOCOL_MIN/MAX */
#define LDAP_OPT_X_TLS_PROTOCOL(maj,min) (((maj) << 8) + (min))
#define LDAP_OPT_X_TLS_PROTOCOL_SSL2 (2 << 8)
#define LDAP_OPT_X_TLS_PROTOCOL_SSL3 (3 << 8)
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index 9b877a92f5..77e3139b9e 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -130,6 +130,7 @@ static const struct ol_attribute {
{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},
+ {0, ATTR_TLS, "TLS_PROTOCOL_MAX", NULL, LDAP_OPT_X_TLS_PROTOCOL_MAX},
#ifdef HAVE_OPENSSL_CRL
{0, ATTR_TLS, "TLS_CRLCHECK", NULL, LDAP_OPT_X_TLS_CRLCHECK},
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index 66e04ae805..b0d8858a8e 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -166,6 +166,7 @@ struct ldaptls {
char *lt_crlfile;
char *lt_randfile; /* OpenSSL only */
int lt_protocol_min;
+ int lt_protocol_max;
};
#endif
@@ -254,13 +255,15 @@ struct ldapoptions {
#define ldo_tls_cacertdir ldo_tls_info.lt_cacertdir
#define ldo_tls_ciphersuite ldo_tls_info.lt_ciphersuite
#define ldo_tls_protocol_min ldo_tls_info.lt_protocol_min
+#define ldo_tls_protocol_max ldo_tls_info.lt_protocol_max
#define ldo_tls_crlfile ldo_tls_info.lt_crlfile
#define ldo_tls_randfile ldo_tls_info.lt_randfile
int ldo_tls_mode;
int ldo_tls_require_cert;
int ldo_tls_impl;
int ldo_tls_crlcheck;
-#define LDAP_LDO_TLS_NULLARG ,0,0,0,{0,0,0,0,0,0,0,0,0},0,0,0,0
+#define LDAP_LDO_TLS_NULLARG ,0,0,0,{0,0,0,0,0,0,0,0,0,\
+ LDAP_OPT_X_TLS_PROTOCOL(255,255)},0,0,0,0
#else
#define LDAP_LDO_TLS_NULLARG
#endif
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index 16c9d0487e..e932938ff0 100644
--- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c
@@ -553,6 +553,7 @@ ldap_int_tls_config( LDAP *ld, int option, const char *arg )
return ldap_pvt_tls_set_option( ld, option, &i );
}
return -1;
+ case LDAP_OPT_X_TLS_PROTOCOL_MAX:
case LDAP_OPT_X_TLS_PROTOCOL_MIN: {
char *next;
long l;
@@ -665,6 +666,9 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
case LDAP_OPT_X_TLS_PROTOCOL_MIN:
*(int *)arg = lo->ldo_tls_protocol_min;
break;
+ case LDAP_OPT_X_TLS_PROTOCOL_MAX:
+ *(int *)arg = lo->ldo_tls_protocol_max;
+ break;
case LDAP_OPT_X_TLS_RANDOM_FILE:
*(char **)arg = lo->ldo_tls_randfile ?
LDAP_STRDUP( lo->ldo_tls_randfile ) : NULL;
@@ -802,6 +806,10 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
if ( !arg ) return -1;
lo->ldo_tls_protocol_min = *(int *)arg;
return 0;
+ case LDAP_OPT_X_TLS_PROTOCOL_MAX:
+ if ( !arg ) return -1;
+ lo->ldo_tls_protocol_max = *(int *)arg;
+ return 0;
case LDAP_OPT_X_TLS_RANDOM_FILE:
if ( ld != NULL )
return -1;
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
index 41d34a94bb..f02b7ca53a 100644
--- a/libraries/libldap/tls_o.c
+++ b/libraries/libldap/tls_o.c
@@ -276,36 +276,56 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
(const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 );
}
+ if ( lo->ldo_tls_protocol_min ) {
+ int opt = 0;
+ if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL2 ) {
+ opt |= SSL_OP_NO_SSLv2;
+ SSL_CTX_clear_options( ctx, SSL_OP_NO_SSLv3 );
+ }
+ if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL3 )
+ opt |= SSL_OP_NO_SSLv3;
#ifdef SSL_OP_NO_TLSv1
+ if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_0 )
+ opt |= SSL_OP_NO_TLSv1;
+#endif
#ifdef SSL_OP_NO_TLSv1_1
+ if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 )
+ opt |= SSL_OP_NO_TLSv1_1;
+#endif
#ifdef SSL_OP_NO_TLSv1_2
+ if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 )
+ opt |= SSL_OP_NO_TLSv1_2;
+#endif
#ifdef SSL_OP_NO_TLSv1_3
- if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_3)
- SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
- SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
- SSL_OP_NO_TLSv1_2 | SSL_OP_NO_TLSv1_3 );
- else
+ if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 )
+ opt |= SSL_OP_NO_TLSv1_3;
#endif
- if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_2)
- SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
- SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 |
- SSL_OP_NO_TLSv1_2 );
- else
+ if ( opt )
+ SSL_CTX_set_options( ctx, opt );
+ }
+ if ( lo->ldo_tls_protocol_max ) {
+ int opt = 0;
+#ifdef SSL_OP_NO_TLSv1_3
+ if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 )
+ opt |= SSL_OP_NO_TLSv1_3;
#endif
- if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_1)
- SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
- SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 );
- else
+#ifdef SSL_OP_NO_TLSv1_2
+ if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 )
+ opt |= SSL_OP_NO_TLSv1_2;
#endif
- if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_TLS1_0)
- SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 |
- SSL_OP_NO_TLSv1);
- else
+#ifdef SSL_OP_NO_TLSv1_1
+ if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 )
+ opt |= SSL_OP_NO_TLSv1_1;
+#endif
+#ifdef SSL_OP_NO_TLSv1
+ if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_TLS1_0 )
+ opt |= SSL_OP_NO_TLSv1;
#endif
- if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL3 )
- SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 );
- else if ( lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL2 )
- SSL_CTX_set_options( ctx, SSL_OP_NO_SSLv2 );
+ if ( lo->ldo_tls_protocol_max < LDAP_OPT_X_TLS_PROTOCOL_SSL3 )
+ opt |= SSL_OP_NO_SSLv3;
+ if ( opt )
+ SSL_CTX_set_options( ctx, opt );
+ }
if ( lo->ldo_tls_ciphersuite &&
!SSL_CTX_set_cipher_list( ctx, lt->lt_ciphersuite ) )
--
2.35.1