/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * 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
#include "ldap-tls.h"
-#ifdef LDAP_R_COMPILE
-#include <ldap_pvt_thread.h>
-#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 )
{
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;
}
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 );
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 );
}
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 ) {
return ldap_pvt_tls_set_option( ld, option, &i );
}
return -1;
+#endif
}
return -1;
}
{
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 ) );
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;
return 0;
}
return -1;
+#ifdef HAVE_OPENSSL_CRL
case LDAP_OPT_X_TLS_CRLCHECK: /* OpenSSL only */
if ( !arg ) return -1;
switch( *(int *) 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;
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 )
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 {
/*
* 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;
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 */
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; bits<maxBits; bits++) {
+ if (0x80 & byte)
+ *tmpStr='1';
+ else
+ *tmpStr='0';
+ tmpStr++;
+ byte<<=1;
+ }
+ valPtr++;
+ valLen--;
+ }
+ *tmpStr++ ='\'';
+ *tmpStr++ ='B';
+ *tmpStr=0;
+
+ return LDAP_SUCCESS;
+}
+
/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
* x509_name must be raw DER. If func is non-NULL, the
* constructed DN will use numeric OIDs to identify attributeTypes,
newAVA->la_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:
/* 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;