X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Ftls2.c;h=3809e9d8862f19a4df8bb346ccc2e0655c2f169a;hb=e57fa5f7ab8da9b95d5a6ef06d71bd0d70618011;hp=baadb1375d3901a2f7753a576ddd4924f4605eff;hpb=5b34dfcbf69a00bc002cf1f0f3acad91062ebc3f;p=openldap
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index baadb1375d..3809e9d886 100644
--- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c
@@ -2,7 +2,7 @@
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software .
*
- * Copyright 1998-2009 The OpenLDAP Foundation.
+ * Copyright 1998-2012 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,10 +37,6 @@
#include "ldap-tls.h"
-#ifdef LDAP_R_COMPILE
-#include
-#endif
-
static tls_impl *tls_imp = &ldap_int_tls_impl;
#define HAS_TLS( sb ) ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
(void *)tls_imp->ti_sbio )
@@ -143,7 +139,6 @@ void
ldap_pvt_tls_destroy( void )
{
struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
- int i;
ldap_int_tls_destroy( lo );
@@ -179,8 +174,6 @@ tls_init(tls_impl *impl )
int
ldap_pvt_tls_init( void )
{
- struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
-
return tls_init( tls_imp );
}
@@ -190,7 +183,7 @@ ldap_pvt_tls_init( void )
static int
ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
{
- int i, rc = 0;
+ int rc = 0;
tls_impl *ti = tls_imp;
struct ldaptls lts = lo->ldo_tls_info;
@@ -272,13 +265,9 @@ ldap_pvt_tls_init_def_ctx( int is_server )
{
struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
int rc;
-#ifdef LDAP_R_COMPILE
- ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
-#endif
+ LDAP_MUTEX_LOCK( &tls_def_ctx_mutex );
rc = ldap_int_tls_init_ctx( lo, is_server );
-#ifdef LDAP_R_COMPILE
- ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
-#endif
+ LDAP_MUTEX_UNLOCK( &tls_def_ctx_mutex );
return rc;
}
@@ -379,7 +368,7 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
return 1;
}
- msg = tls_imp->ti_session_errmsg( err, buf, sizeof(buf) );
+ msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
if ( msg ) {
if ( ld->ld_error ) {
LDAP_FREE( ld->ld_error );
@@ -437,11 +426,14 @@ ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
if ( err < 0 )
{
- char buf[256];
if ( update_flags( sb, ssl, err )) return 1;
- Debug( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n",
- tls_imp->ti_session_errmsg( err, buf, sizeof(buf) ),0,0 );
+ if ( DebugTest( LDAP_DEBUG_ANY ) ) {
+ char buf[256], *msg;
+ msg = tls_imp->ti_session_errmsg( ssl, err, buf, sizeof(buf) );
+ Debug( LDAP_DEBUG_ANY,"TLS: can't accept: %s.\n",
+ msg ? msg : "(unknown)", 0, 0 );
+ }
ber_sockbuf_remove_io( sb, tls_imp->ti_sbio,
LBER_SBIOD_LEVEL_TRANSPORT );
@@ -562,6 +554,7 @@ ldap_int_tls_config( LDAP *ld, int option, const char *arg )
}
return ldap_pvt_tls_set_option( ld, option, &i );
}
+#ifdef HAVE_OPENSSL_CRL
case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */
i = -1;
if ( strcasecmp( arg, "none" ) == 0 ) {
@@ -575,6 +568,7 @@ ldap_int_tls_config( LDAP *ld, int option, const char *arg )
return ldap_pvt_tls_set_option( ld, option, &i );
}
return -1;
+#endif
}
return -1;
}
@@ -584,6 +578,11 @@ ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
{
struct ldapoptions *lo;
+ if( option == LDAP_OPT_X_TLS_PACKAGE ) {
+ *(char **)arg = LDAP_STRDUP( tls_imp->ti_name );
+ return 0;
+ }
+
if( ld != NULL ) {
assert( LDAP_VALID( ld ) );
@@ -638,9 +637,11 @@ 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;
+#ifdef HAVE_OPENSSL_CRL
case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */
*(int *)arg = lo->ldo_tls_crlcheck;
break;
+#endif
case LDAP_OPT_X_TLS_CIPHER_SUITE:
*(char **)arg = lo->ldo_tls_ciphersuite ?
LDAP_STRDUP( lo->ldo_tls_ciphersuite ) : NULL;
@@ -648,7 +649,7 @@ 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_RANDOM_FILE: /* OpenSSL only */
+ case LDAP_OPT_X_TLS_RANDOM_FILE:
*(char **)arg = lo->ldo_tls_randfile ?
LDAP_STRDUP( lo->ldo_tls_randfile ) : NULL;
break;
@@ -764,6 +765,7 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
return 0;
}
return -1;
+#ifdef HAVE_OPENSSL_CRL
case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */
if ( !arg ) return -1;
switch( *(int *) arg ) {
@@ -774,6 +776,7 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
return 0;
}
return -1;
+#endif
case LDAP_OPT_X_TLS_CIPHER_SUITE:
if ( lo->ldo_tls_ciphersuite ) LDAP_FREE( lo->ldo_tls_ciphersuite );
lo->ldo_tls_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
@@ -783,14 +786,12 @@ 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_RANDOM_FILE: /* OpenSSL only */
+ case LDAP_OPT_X_TLS_RANDOM_FILE:
if ( ld != NULL )
return -1;
if ( lo->ldo_tls_randfile ) LDAP_FREE (lo->ldo_tls_randfile );
lo->ldo_tls_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
break;
-
case LDAP_OPT_X_TLS_NEWCTX:
if ( !arg ) return -1;
if ( lo->ldo_tls_ctx )
@@ -806,10 +807,14 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
int
ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
{
- Sockbuf *sb = conn->lconn_sb;
+ Sockbuf *sb;
char *host;
void *ssl;
+ if ( !conn )
+ return LDAP_PARAM_ERROR;
+
+ sb = conn->lconn_sb;
if( srv ) {
host = srv->lud_host;
} else {
@@ -837,7 +842,8 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
/*
* compare host with name(s) in certificate
*/
- if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER) {
+ if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER &&
+ ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) {
ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
if (ld->ld_errno != LDAP_SUCCESS) {
return ld->ld_errno;
@@ -871,8 +877,9 @@ ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func,
struct berval der_dn;
int rc;
- tls_imp->ti_session_my_dn( session, &der_dn );
- rc = ldap_X509dn2bv(&der_dn, dn, (LDAPDN_rewrite_func *)func, flags );
+ rc = tls_imp->ti_session_my_dn( session, &der_dn );
+ if ( rc == LDAP_SUCCESS )
+ rc = ldap_X509dn2bv(&der_dn, dn, (LDAPDN_rewrite_func *)func, flags );
return rc;
}
#endif /* HAVE_TLS */
@@ -970,6 +977,93 @@ find_oid( struct berval *oid )
return NULL;
}
+/* Converts BER Bitstring value to LDAP BitString value (RFC4517)
+ *
+ * berValue : IN
+ * rfc4517Value: OUT
+ *
+ * berValue and ldapValue should not be NULL
+ */
+
+#define BITS_PER_BYTE 8
+#define SQUOTE_LENGTH 1
+#define B_CHAR_LENGTH 1
+#define STR_OVERHEAD (2*SQUOTE_LENGTH + B_CHAR_LENGTH)
+
+static int
+der_to_ldap_BitString (struct berval *berValue,
+ struct berval *ldapValue)
+{
+ ber_len_t bitPadding=0;
+ ber_len_t bits, maxBits;
+ char *tmpStr;
+ unsigned char byte;
+ ber_len_t bitLength;
+ ber_len_t valLen;
+ unsigned char* valPtr;
+
+ ldapValue->bv_len=0;
+ ldapValue->bv_val=NULL;
+
+ /* Gets padding and points to binary data */
+ valLen=berValue->bv_len;
+ valPtr=(unsigned char*)berValue->bv_val;
+ if (valLen) {
+ bitPadding=(ber_len_t)(valPtr[0]);
+ valLen--;
+ valPtr++;
+ }
+ /* If Block is non DER encoding fixes to DER encoding */
+ if (bitPadding >= BITS_PER_BYTE) {
+ if (valLen*BITS_PER_BYTE > bitPadding ) {
+ valLen-=(bitPadding/BITS_PER_BYTE);
+ bitPadding%=BITS_PER_BYTE;
+ } else {
+ valLen=0;
+ bitPadding=0;
+ }
+ }
+ /* Just in case bad encoding */
+ if (valLen*BITS_PER_BYTE < bitPadding ) {
+ bitPadding=0;
+ valLen=0;
+ }
+
+ /* Gets buffer to hold RFC4517 Bit String format */
+ bitLength=valLen*BITS_PER_BYTE-bitPadding;
+ tmpStr=LDAP_MALLOC(bitLength + STR_OVERHEAD + 1);
+
+ if (!tmpStr)
+ return LDAP_NO_MEMORY;
+
+ ldapValue->bv_val=tmpStr;
+ ldapValue->bv_len=bitLength + STR_OVERHEAD;
+
+ /* Formatting in '*binary-digit'B format */
+ maxBits=BITS_PER_BYTE;
+ *tmpStr++ ='\'';
+ while(valLen) {
+ byte=*valPtr;
+ if (valLen==1)
+ maxBits-=bitPadding;
+ for (bits=0; bitsla_attr = oidname->name;
}
}
+ newAVA->la_private = NULL;
+ newAVA->la_flags = LDAP_AVA_STRING;
tag = ber_get_stringbv( ber, &Val, LBER_BV_NOTERM );
switch(tag) {
case LBER_TAG_UNIVERSAL:
@@ -1124,22 +1220,29 @@ ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
/* This uses 8-bit, assume ISO 8859-1 */
csize = 1;
to_utf8: rc = ldap_ucs_to_utf8s( &Val, csize, &newAVA->la_value );
+ newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
+allocd:
newAVA->la_flags |= LDAP_AVA_FREE_VALUE;
if (rc != LDAP_SUCCESS) goto nomem;
- newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
break;
case LBER_TAG_UTF8:
- newAVA->la_flags = LDAP_AVA_NONPRINTABLE;
+ newAVA->la_flags |= LDAP_AVA_NONPRINTABLE;
/* This is already in UTF-8 encoding */
case LBER_TAG_IA5:
case LBER_TAG_PRINTABLE:
/* These are always 7-bit strings */
newAVA->la_value = Val;
+ break;
+ case LBER_BITSTRING:
+ /* X.690 bitString value converted to RFC4517 Bit String */
+ rc = der_to_ldap_BitString( &Val, &newAVA->la_value );
+ goto allocd;
default:
- ;
+ /* Not a string type at all */
+ newAVA->la_flags = 0;
+ newAVA->la_value = Val;
+ break;
}
- newAVA->la_private = NULL;
- newAVA->la_flags = LDAP_AVA_STRING;
newAVA++;
}
*newRDN++ = NULL;