]> git.sur5r.net Git - openldap/commitdiff
ITS#5655 TLS_PROTOCOL_MIN from Philip Guenther
authorHoward Chu <hyc@openldap.org>
Sat, 24 Jan 2009 03:34:49 +0000 (03:34 +0000)
committerHoward Chu <hyc@openldap.org>
Sat, 24 Jan 2009 03:34:49 +0000 (03:34 +0000)
include/ldap.h
libraries/libldap/init.c
libraries/libldap/ldap-int.h
libraries/libldap/tls.c
servers/slapd/bconfig.c
servers/slapd/config.c
servers/slapd/slap.h

index 3dff72ad683bf1ca9383de443612441a3ed12743..19e25fb7a7c2824396586efa23622248b071d5e2 100644 (file)
@@ -144,7 +144,7 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_X_TLS_CERTFILE                0x6004
 #define LDAP_OPT_X_TLS_KEYFILE         0x6005
 #define LDAP_OPT_X_TLS_REQUIRE_CERT    0x6006
-/* #define LDAP_OPT_X_TLS_PROTOCOL             0x6007 */
+#define LDAP_OPT_X_TLS_PROTOCOL_MIN    0x6007
 #define LDAP_OPT_X_TLS_CIPHER_SUITE    0x6008
 #define LDAP_OPT_X_TLS_RANDOM_FILE     0x6009
 #define LDAP_OPT_X_TLS_SSL_CTX         0x600a  /* OpenSSL SSL* */
@@ -165,6 +165,14 @@ 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 */
+#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)
+#define LDAP_OPT_X_TLS_PROTOCOL_TLS1_0         ((3 << 8) + 1)
+#define LDAP_OPT_X_TLS_PROTOCOL_TLS1_1         ((3 << 8) + 2)
+#define LDAP_OPT_X_TLS_PROTOCOL_TLS1_2         ((3 << 8) + 3)
+
 /* OpenLDAP SASL options */
 #define LDAP_OPT_X_SASL_MECH                   0x6100
 #define LDAP_OPT_X_SASL_REALM                  0x6101
index eb5ff66f591008267a7d91d17a10e5514a15d8c8..8cf2530b399144872389dcbe80c40dd139c76421 100644 (file)
@@ -123,6 +123,7 @@ static const struct ol_attribute {
        {0, ATTR_TLS,   "TLS_REQCERT",          NULL,   LDAP_OPT_X_TLS_REQUIRE_CERT},
        {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},
 
 #ifdef HAVE_OPENSSL_CRL
        {0, ATTR_TLS,   "TLS_CRLCHECK",         NULL,   LDAP_OPT_X_TLS_CRLCHECK},
index f3d64a92395429f37cc2bffa22ea2e807082aa36..6b6cf08af4f59e8024b8e686e038f88672ff8f48 100644 (file)
@@ -157,6 +157,7 @@ struct ldaptls {
        char            *lt_ciphersuite;
        char            *lt_crlfile;
        char            *lt_randfile;   /* OpenSSL only */
+       int             lt_protocol_min;
 };
 #endif
 
@@ -204,6 +205,7 @@ struct ldapoptions {
 #define ldo_tls_cacertfile     ldo_tls_info.lt_cacertfile
 #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_crlfile        ldo_tls_info.lt_crlfile
 #define ldo_tls_randfile       ldo_tls_info.lt_randfile
        int                     ldo_tls_mode;
index 3579351bd1dd581c7e5bb303a09980027d19ff6e..31504ec28279d3295c230203d7afad5e1f52008b 100644 (file)
@@ -772,6 +772,12 @@ ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
                        (const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 );
        }
 
+       if (lo->ldo_tls_protocol_min > LDAP_OPT_X_TLS_PROTOCOL_SSL3)
+               SSL_CTX_set_options( lo->ldo_tls_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( lo->ldo_tls_ctx, SSL_OP_NO_SSLv2 );
+
        if ( lo->ldo_tls_ciphersuite &&
                !SSL_CTX_set_cipher_list( lo->ldo_tls_ctx, ciphersuite ) )
        {
@@ -2146,6 +2152,23 @@ 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_MIN: {
+               char *next;
+               long l;
+               l = strtol( arg, &next, 10 );
+               if ( l < 0 || l > 0xff || next == arg ||
+                       ( *next != '\0' && *next != '.' ) )
+                       return -1;
+               i = l << 8;
+               if (*next == '.') {
+                       arg = next + 1;
+                       l = strtol( arg, &next, 10 );
+                       if ( l < 0 || l > 0xff || next == arg || *next != '\0' )
+                               return -1;
+                       i += l;
+               }
+               return ldap_pvt_tls_set_option( ld, option, &i );
+               }
 #ifdef HAVE_OPENSSL_CRL
        case LDAP_OPT_X_TLS_CRLCHECK:
                i = -1;
@@ -2235,6 +2258,9 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
                *(char **)arg = lo->ldo_tls_ciphersuite ?
                        LDAP_STRDUP( lo->ldo_tls_ciphersuite ) : NULL;
                break;
+       case LDAP_OPT_X_TLS_PROTOCOL_MIN:
+               *(int *)arg = lo->ldo_tls_protocol_min;
+               break;
        case LDAP_OPT_X_TLS_RANDOM_FILE:
 #ifdef HAVE_OPENSSL
                *(char **)arg = tls_opt_randfile ?
@@ -2373,7 +2399,10 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
                if ( lo->ldo_tls_ciphersuite ) LDAP_FREE( lo->ldo_tls_ciphersuite );
                lo->ldo_tls_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
                return 0;
-
+       case LDAP_OPT_X_TLS_PROTOCOL_MIN:
+               if ( !arg ) return -1;
+               lo->ldo_tls_protocol_min = * (int *) arg;
+               return 0;
        case LDAP_OPT_X_TLS_RANDOM_FILE:
                if ( ld != NULL )
                        return -1;
index b7237c7c0fdddb8e4755c7ad666611ac00259e17..2d23b9e2a3044213cbf010c51c461df1f556f139 100644 (file)
@@ -145,6 +145,7 @@ enum {
        CFG_DATABASE,
        CFG_TLS_RAND,
        CFG_TLS_CIPHER,
+       CFG_TLS_PROTOCOL_MIN,
        CFG_TLS_CERT_FILE,
        CFG_TLS_CERT_KEY,
        CFG_TLS_CA_PATH,
@@ -685,6 +686,14 @@ static ConfigTable config_back_cf_table[] = {
 #endif
                "( OLcfgGlAt:77 NAME 'olcTLSDHParamFile' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+       { "TLSProtocolMin",     NULL, 0, 0, 0,
+#ifdef HAVE_TLS
+               CFG_TLS_PROTOCOL_MIN|ARG_STRING|ARG_MAGIC, &config_tls_config,
+#else
+               ARG_IGNORED, NULL,
+#endif
+               "( OLcfgGlAt:85 NAME 'olcTLSProtocolMin' "
+                       "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
        { "tool-threads", "count", 2, 2, 0, ARG_INT|ARG_MAGIC|CFG_TTHREADS,
                &config_generic, "( OLcfgGlAt:80 NAME 'olcToolThreads' "
                        "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },
@@ -3207,6 +3216,7 @@ config_tls_config(ConfigArgs *c) {
        switch(c->type) {
        case CFG_TLS_CRLCHECK:  flag = LDAP_OPT_X_TLS_CRLCHECK; break;
        case CFG_TLS_VERIFY:    flag = LDAP_OPT_X_TLS_REQUIRE_CERT; break;
+       case CFG_TLS_PROTOCOL_MIN: flag = LDAP_OPT_X_TLS_PROTOCOL_MIN; break;
        default:
                Debug(LDAP_DEBUG_ANY, "%s: "
                                "unknown tls_option <0x%x>\n",
index de0e5badc24773eaa7b86085912f640f5613f76d..16e335e4047fccdc5afc67eb39daff59e438428c 100644 (file)
@@ -1200,6 +1200,7 @@ static slap_cf_aux_table bindkey[] = {
        { BER_BVC("tls_cacertdir="), offsetof(slap_bindconf, sb_tls_cacertdir), 's', 1, NULL },
        { BER_BVC("tls_reqcert="), offsetof(slap_bindconf, sb_tls_reqcert), 's', 1, NULL },
        { BER_BVC("tls_cipher_suite="), offsetof(slap_bindconf, sb_tls_cipher_suite), 's', 1, NULL },
+       { BER_BVC("tls_protocol_min="), offsetof(slap_bindconf, sb_tls_protocol_min), 's', 1, NULL },
 #ifdef HAVE_OPENSSL_CRL
        { BER_BVC("tls_crlcheck="), offsetof(slap_bindconf, sb_tls_crlcheck), 's', 1, NULL },
 #endif
@@ -1408,6 +1409,14 @@ slap_tls_get_config( LDAP *ld, int opt, char **val )
        case LDAP_OPT_X_TLS_REQUIRE_CERT:
                keys = vfykeys;
                break;
+       case LDAP_OPT_X_TLS_PROTOCOL_MIN: {
+               char buf[8];
+               ldap_pvt_tls_get_option( ld, opt, &ival );
+               snprintf( buf, sizeof( buf ), "%d.%d",
+                       ( ival >> 8 ) & 0xff, ival & 0xff );
+               *val = ch_strdup( buf );
+               return 0;
+               }
        default:
                return -1;
        }
@@ -1519,6 +1528,10 @@ void bindconf_free( slap_bindconf *bc ) {
                ch_free( bc->sb_tls_cipher_suite );
                bc->sb_tls_cipher_suite = NULL;
        }
+       if ( bc->sb_tls_protocol_min ) {
+               ch_free( bc->sb_tls_protocol_min );
+               bc->sb_tls_protocol_min = NULL;
+       }
 #ifdef HAVE_OPENSSL_CRL
        if ( bc->sb_tls_crlcheck ) {
                ch_free( bc->sb_tls_crlcheck );
@@ -1570,6 +1583,7 @@ static struct {
        { "tls_cacert", offsetof(slap_bindconf, sb_tls_cacert), LDAP_OPT_X_TLS_CACERTFILE },
        { "tls_cacertdir", offsetof(slap_bindconf, sb_tls_cacertdir), LDAP_OPT_X_TLS_CACERTDIR },
        { "tls_cipher_suite", offsetof(slap_bindconf, sb_tls_cipher_suite), LDAP_OPT_X_TLS_CIPHER_SUITE },
+       { "tls_protocol_min", offsetof(slap_bindconf, sb_tls_protocol_min), LDAP_OPT_X_TLS_PROTOCOL_MIN },
        {0, 0}
 };
 
@@ -1604,6 +1618,17 @@ int bindconf_tls_set( slap_bindconf *bc, LDAP *ld )
                } else
                        newctx = 1;
        }
+       if ( bc->sb_tls_protocol_min ) {
+               rc = ldap_int_tls_config( ld, LDAP_OPT_X_TLS_PROTOCOL_MIN,
+                       bc->sb_tls_protocol_min );
+               if ( rc ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "bindconf_tls_set: failed to set tls_protocol_min to %s\n",
+                                       bc->sb_tls_protocol_min, 0, 0 );
+                       res = -1;
+               } else
+                       newctx = 1;
+       }
 #ifdef HAVE_OPENSSL_CRL
        if ( bc->sb_tls_crlcheck ) {
                rc = ldap_int_tls_config( ld, LDAP_OPT_X_TLS_CRLCHECK,
index 6bd3af7c48e2e428943186df2aa6be7dd49a43cf..2439156a48f86fbc4143a3529ad3d427b0033145 100644 (file)
@@ -1607,6 +1607,7 @@ typedef struct slap_bindconf {
        char *sb_tls_cacertdir;
        char *sb_tls_reqcert;
        char *sb_tls_cipher_suite;
+       char *sb_tls_protocol_min;
 #ifdef HAVE_OPENSSL_CRL
        char *sb_tls_crlcheck;
 #endif