mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-17 14:00:30 +08:00
Added ldap_X509dn2bv()
deleted ldap_pvt_tls_get_peer() changed ldap_pvt_tls_get_peer_dn() to use ldap_X509dn2bv() added ldap_pvt_tls_get_my_dn()
This commit is contained in:
parent
8a5423ea8d
commit
17ae956518
@ -1273,6 +1273,12 @@ ldap_explode_rdn LDAP_P(( /* deprecated */
|
||||
LDAP_CONST char *rdn,
|
||||
int notypes ));
|
||||
|
||||
typedef int LDAPDN_rewrite_func LDAP_P(( LDAPDN *dn, unsigned flags ));
|
||||
|
||||
LDAP_F( int )
|
||||
ldap_X509dn2bv LDAP_P(( void *x509_name, struct berval *dn,
|
||||
LDAPDN_rewrite_func *func, unsigned flags ));
|
||||
|
||||
LDAP_F( char * )
|
||||
ldap_dn2dcedn LDAP_P(( LDAP_CONST char *dn )); /* deprecated */
|
||||
|
||||
|
@ -179,8 +179,12 @@ LDAP_F (void *) ldap_pvt_tls_sb_ctx LDAP_P(( Sockbuf *sb ));
|
||||
|
||||
LDAP_F (int) ldap_pvt_tls_init_default_ctx LDAP_P(( void ));
|
||||
|
||||
LDAP_F (char *) ldap_pvt_tls_get_peer LDAP_P(( void *ctx ));
|
||||
LDAP_F (char *) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx ));
|
||||
typedef int LDAPDN_rewrite_dummy LDAP_P (( void *dn, unsigned flags ));
|
||||
|
||||
LDAP_F (char *) ldap_pvt_tls_get_my_dn LDAP_P(( void *ctx,
|
||||
LDAPDN_rewrite_dummy *func, unsigned flags ));
|
||||
LDAP_F (char *) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx,
|
||||
LDAPDN_rewrite_dummy *func, unsigned flags ));
|
||||
LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *ctx ));
|
||||
|
||||
LDAP_END_DECL
|
||||
|
@ -3291,3 +3291,108 @@ return_results:;
|
||||
return( rc );
|
||||
}
|
||||
|
||||
#ifdef HAVE_TLS
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
/* Convert a structured DN from an X.509 certificate into an LDAPV3 DN.
|
||||
* x509_name must be an (X509_NAME *). If func is non-NULL, the
|
||||
* constructed DN will use numeric OIDs to identify attributeTypes,
|
||||
* and the func() will be invoked to rewrite the DN with the given
|
||||
* flags.
|
||||
*
|
||||
* Otherwise the DN will use shortNames as defined in the OpenSSL
|
||||
* library.
|
||||
*
|
||||
* It's preferable to let slapd do the OID to attributeType mapping,
|
||||
* because the OpenSSL tables are known to have many typos in versions
|
||||
* up to (at least) 0.9.6c. However, the LDAP client has no schema tables,
|
||||
* so we're forced to use OpenSSL's mapping there.
|
||||
* -- Howard Chu 2002-04-18
|
||||
*/
|
||||
|
||||
int
|
||||
ldap_X509dn2bv( void *x509_name, struct berval *bv, LDAPDN_rewrite_func *func,
|
||||
unsigned flags )
|
||||
{
|
||||
LDAPDN *newDN = NULL;
|
||||
LDAPRDN *newRDN = NULL;
|
||||
X509_NAME_ENTRY *ne;
|
||||
ASN1_OBJECT *obj;
|
||||
ASN1_STRING *str;
|
||||
char oidbuf[2048];
|
||||
int i, j, nrdns, rc = LDAP_NO_MEMORY;
|
||||
|
||||
struct berval Type;
|
||||
struct berval Val;
|
||||
|
||||
assert( bv );
|
||||
bv->bv_len = 0;
|
||||
bv->bv_val = NULL;
|
||||
|
||||
nrdns = X509_NAME_entry_count( x509_name );
|
||||
newDN = (LDAPDN *)LDAP_MALLOC( sizeof(LDAPDN) + sizeof(LDAPRDN *)
|
||||
* (nrdns+1) );
|
||||
if ( newDN == NULL )
|
||||
return LDAP_NO_MEMORY;
|
||||
|
||||
newDN[0] = (LDAPRDN**)(newDN+1);
|
||||
|
||||
/* Retrieve RDNs in reverse order; LDAP is backwards from X.500.
|
||||
* The OpenSSL library appears to allow only 1 AVA per RDN.
|
||||
*/
|
||||
for ( i = nrdns - 1, j = 0; i >= 0; i--, j++ ) {
|
||||
newDN[0][j] = NULL;
|
||||
ne = X509_NAME_get_entry( x509_name, i );
|
||||
obj = X509_NAME_ENTRY_get_object( ne );
|
||||
str = X509_NAME_ENTRY_get_data( ne );
|
||||
|
||||
if ( !func ) {
|
||||
int n = OBJ_obj2nid( obj );
|
||||
|
||||
if (n == NID_undef)
|
||||
goto get_oid;
|
||||
Type.bv_val = (char *)OBJ_nid2sn( n );
|
||||
Type.bv_len = strlen( Type.bv_val );
|
||||
} else {
|
||||
get_oid: Type.bv_val = oidbuf;
|
||||
Type.bv_len = OBJ_obj2txt( oidbuf, sizeof( oidbuf ), obj, 1 );
|
||||
}
|
||||
Val.bv_len = str->length;
|
||||
Val.bv_val = str->data;
|
||||
|
||||
newRDN = (LDAPRDN *)LDAP_MALLOC( sizeof(LDAPRDN) + sizeof(LDAPAVA *) * 2);
|
||||
if ( newRDN == NULL )
|
||||
goto nomem;
|
||||
|
||||
newRDN[0] = (LDAPAVA**)(newRDN+1);
|
||||
newRDN[0][0] = ldapava_new( &Type, &Val, LDAP_AVA_STRING );
|
||||
if ( newRDN[0][0] == NULL )
|
||||
goto nomem;
|
||||
|
||||
newRDN[0][1] = NULL;
|
||||
newDN[0][j] = newRDN;
|
||||
newRDN = NULL;
|
||||
}
|
||||
newDN[0][j] = NULL;
|
||||
|
||||
if ( func ) {
|
||||
rc = func( newDN, flags );
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
goto nomem;
|
||||
}
|
||||
|
||||
rc = ldap_dn2bv( newDN, bv, LDAP_DN_FORMAT_LDAPV3 );
|
||||
ldap_dnfree( newDN );
|
||||
|
||||
return rc;
|
||||
|
||||
nomem:
|
||||
if ( newRDN )
|
||||
LDAP_FREE( newRDN );
|
||||
if ( newDN )
|
||||
ldap_dnfree( newDN );
|
||||
return rc;
|
||||
}
|
||||
#endif /* HAVE_TLS */
|
||||
|
||||
|
@ -788,6 +788,23 @@ ldap_pvt_tls_get_strength( void *s )
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ldap_pvt_tls_get_my_dn( void *s, LDAPDN_rewrite_dummy *func, unsigned flags )
|
||||
{
|
||||
X509 *x;
|
||||
X509_NAME *xn;
|
||||
struct berval dn;
|
||||
|
||||
x = SSL_get_certificate((SSL *)s);
|
||||
|
||||
if (!x) return NULL;
|
||||
|
||||
xn = X509_get_subject_name(x);
|
||||
ldap_X509dn2bv(xn, &dn, (LDAPDN_rewrite_func *)func, flags );
|
||||
X509_free(x);
|
||||
return dn.bv_val;
|
||||
}
|
||||
|
||||
static X509 *
|
||||
tls_get_cert( SSL *s )
|
||||
{
|
||||
@ -803,42 +820,20 @@ tls_get_cert( SSL *s )
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_pvt_tls_get_peer( void *s )
|
||||
{
|
||||
X509 *x;
|
||||
X509_NAME *xn;
|
||||
char buf[2048], *p;
|
||||
|
||||
|
||||
x = tls_get_cert((SSL *)s);
|
||||
|
||||
if (!x)
|
||||
return NULL;
|
||||
|
||||
xn = X509_get_subject_name(x);
|
||||
p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
|
||||
X509_free(x);
|
||||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_pvt_tls_get_peer_dn( void *s )
|
||||
ldap_pvt_tls_get_peer_dn( void *s, LDAPDN_rewrite_dummy *func, unsigned flags )
|
||||
{
|
||||
X509 *x;
|
||||
X509_NAME *xn;
|
||||
char buf[2048], *p, *dn;
|
||||
struct berval dn;
|
||||
|
||||
x = tls_get_cert((SSL *)s);
|
||||
|
||||
if (!x) return NULL;
|
||||
|
||||
xn = X509_get_subject_name(x);
|
||||
p = X509_NAME_oneline(xn, buf, sizeof(buf));
|
||||
|
||||
dn = ldap_dcedn2dn( p );
|
||||
|
||||
ldap_X509dn2bv(xn, &dn, (LDAPDN_rewrite_func *)func, flags);
|
||||
X509_free(x);
|
||||
return dn;
|
||||
return dn.bv_val;
|
||||
}
|
||||
|
||||
char *
|
||||
@ -983,7 +978,7 @@ ldap_pvt_tls_check_hostname( void *s, const char *name_in )
|
||||
const char *
|
||||
ldap_pvt_tls_get_peer_issuer( void *s )
|
||||
{
|
||||
#if 0 /* currently unused; see ldap_pvt_tls_get_peer() if needed */
|
||||
#if 0 /* currently unused; see ldap_pvt_tls_get_peer_dn() if needed */
|
||||
X509 *x;
|
||||
X509_NAME *xn;
|
||||
char buf[2048], *p;
|
||||
@ -1256,7 +1251,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
|
||||
|
||||
/* we need to let SASL know */
|
||||
ssf = ldap_pvt_tls_get_strength( ssl );
|
||||
authid = ldap_pvt_tls_get_peer( ssl );
|
||||
authid = ldap_pvt_tls_get_my_dn( ssl, NULL, 0 );
|
||||
|
||||
(void) ldap_int_sasl_external( ld, conn, authid, ssf );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user