#define LDAP_OPT_X_TLS 0x6007
#define LDAP_OPT_X_TLS_PROTOCOL 0x6008
#define LDAP_OPT_X_TLS_CIPHER_SUITE 0x6009
+#define LDAP_OPT_X_TLS_RANDOM_FILE 0x600a
#define LDAP_OPT_X_TLS_NEVER 0
#define LDAP_OPT_X_TLS_HARD 1
offsetof(struct ldapoptions, ldo_defbinddn)},
{0, ATTR_STRING, "BASE", NULL,
offsetof(struct ldapoptions, ldo_defbase)},
- {0, ATTR_INT, "PORT", NULL,
+ {0, ATTR_INT, "PORT", NULL, /* deprecated */
offsetof(struct ldapoptions, ldo_defport)},
- /* **** keep this around for backward compatibility */
- {0, ATTR_URIS, "HOST", NULL, 1},
- /* **** */
- {0, ATTR_URIS, "URI", NULL, 0},
+ {0, ATTR_URIS, "HOST", NULL, 1}, /* deprecated */
+ {0, ATTR_URIS, "URI", NULL, 0}, /* replaces HOST/URI */
{0, ATTR_BOOL, "REFERRALS", NULL, LDAP_BOOL_REFERRALS},
{0, ATTR_BOOL, "RESTART", NULL, LDAP_BOOL_RESTART},
+
+#ifdef HAVE_TLS
{0, ATTR_TLS, "TLS", NULL, LDAP_OPT_X_TLS},
{0, ATTR_TLS, "TLS_CERT", NULL, LDAP_OPT_X_TLS_CERTFILE},
{0, ATTR_TLS, "TLS_KEY", NULL, LDAP_OPT_X_TLS_KEYFILE},
{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_RANDFILE", NULL, LDAP_OPT_X_TLS_RANDOM_FILE},
+#endif
+
#ifdef HAVE_CYRUS_SASL
{0, ATTR_INT, "SASL_MINSSF", NULL,
offsetof(struct ldapoptions, ldo_sasl_minssf)},
{0, ATTR_INT, "SASL_MAXSSF", NULL,
offsetof(struct ldapoptions, ldo_sasl_maxssf)},
#endif
+
{0, ATTR_NONE, NULL, NULL, 0}
};
#include <openssl/ssl.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
+#include <openssl/rand.h>
#elif defined( HAVE_SSL_H )
#include <ssl.h>
#endif
static char *tls_opt_cacertdir = NULL;
static int tls_opt_require_cert = 0;
static char *tls_opt_ciphersuite = NULL;
+static char *tls_opt_randfile = NULL;
#define HAS_TLS( sb ) ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
(void *)&ldap_pvt_sockbuf_io_tls )
{
static int tls_initialized = 0;
- if ( tls_initialized )
- return 0;
+ if ( tls_initialized ) return 0;
+
+ (void) tls_seed_PRNG( tls_opt_randfile );
+
tls_initialized = 1;
#ifdef LDAP_R_COMPILE
tls_init_threads();
case LDAP_OPT_X_TLS_CACERTDIR:
case LDAP_OPT_X_TLS_CERTFILE:
case LDAP_OPT_X_TLS_KEYFILE:
+ case LDAP_OPT_X_TLS_RANDOM_FILE:
return ldap_pvt_tls_set_option( NULL, option, (void *) arg );
case LDAP_OPT_X_TLS_REQUIRE_CERT:
i = ( ( strcasecmp( arg, "on" ) == 0 ) ||
case LDAP_OPT_X_TLS_REQUIRE_CERT:
*(int *)arg = tls_opt_require_cert;
break;
+ case LDAP_OPT_X_TLS_RANDOM_FILE:
+ *(char **)arg = tls_opt_randfile;
+ break;
default:
return -1;
}
if ( tls_opt_ciphersuite ) free( tls_opt_ciphersuite );
tls_opt_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
+ case LDAP_OPT_X_TLS_RANDOM_FILE:
+ if (tls_opt_randfile ) free (tls_opt_randfile );
+ tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
+ break;
default:
return -1;
}
int
ldap_pvt_tls_start ( LDAP *ld, Sockbuf *sb, void *ctx_arg )
{
+ /* Make sure tls is initialized, including PRNG properly seeded. */
+ ldap_pvt_tls_init();
+
/*
* Fortunately, the lib uses blocking io...
*/
tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL );
if ( !tmp_rsa ) {
- Debug( LDAP_DEBUG_ANY, "TLS: Failed to generate temporary %d-bit %s RSA key\n",
- key_length, is_export ? "export" : "domestic", 0 );
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: Failed to generate temporary %d-bit %s RSA key\n",
+ key_length, is_export ? "export" : "domestic", 0 );
return NULL;
}
return tmp_rsa;
}
+static int
+tls_seed_PRNG( const char *randfile )
+{
+#ifndef URANDOM_DEVICE
+ /* no /dev/urandom (or equiv) */
+
+ char buffer[1024];
+ static int egdsocket = 0;
+
+ if (randfile == NULL) {
+ /* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
+ * If $HOME is not set or buffer too small to hold the pathname,
+ * an error occurs. - From RAND_file_name() man page.
+ * The fact is that when $HOME is NULL, .rnd is used.
+ */
+ randfile = RAND_file_name(buffer, sizeof( buffer ));
+
+ } else if (RAND_egd(randfile) > 0) {
+ /* EGD socket */
+ egdsocket = 1;
+ return 0;
+ }
+
+ if (randfile == NULL) {
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: Use configuration file or $RANDFILE to define seed file",
+ 0, 0, 0);
+ return -1;
+ }
+
+ RAND_load_file(randfile, -1);
+
+ if (RAND_status() == 0) {
+ Debug( LDAP_DEBUG_ANY,
+ "TLS: PRNG has not been seeded with enough data",
+ 0, 0, 0);
+ return -1;
+ }
+#endif
+
+ return 0;
+}
+
#if 0
static DH *
tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )