ITS#9189 rework sasl-cbinding support

Add LDAP_OPT_X_SASL_CBINDING option to define the binding type to use,
defaults to "none".

Add "tls-endpoint" binding type implementing "tls-server-end-point" from
RCF 5929, which is compatible with Windows.

Fix "tls-unique" to include the prefix in the bindings as per RFC 5056.
This commit is contained in:
Isaac Boukris 2020-04-14 16:10:48 +03:00
parent 96fedda628
commit 3cd50fa8b3
18 changed files with 274 additions and 32 deletions

View file

@ -563,6 +563,22 @@ must be a
.BR "char **" . .BR "char **" .
Its content needs to be freed by the caller using Its content needs to be freed by the caller using
.BR ldap_memfree (3). .BR ldap_memfree (3).
.B LDAP_OPT_X_SASL_CBINDING
Sets/gets the channel-binding type to use in SASL,
one of
.BR LDAP_OPT_X_SASL_CBINDING_NONE
(the default),
.BR LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE
the "tls-unique" type from RCF 5929.
.BR LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT
the "tls-server-end-point" from RCF 5929, compatible with Windows.
.BR invalue
must be
.BR "const int *" ;
.BR outvalue
must be
.BR "int *" .
.TP
.SH TCP OPTIONS .SH TCP OPTIONS
The TCP options are OpenLDAP specific. The TCP options are OpenLDAP specific.
Mainly intended for use with Linux, they may not be portable. Mainly intended for use with Linux, they may not be portable.

View file

@ -286,6 +286,9 @@ size allowed. 0 disables security layers. The default is 65536.
.TP .TP
.B SASL_NOCANON <on/true/yes/off/false/no> .B SASL_NOCANON <on/true/yes/off/false/no>
Do not perform reverse DNS lookups to canonicalize SASL host names. The default is off. Do not perform reverse DNS lookups to canonicalize SASL host names. The default is off.
.TP
.B SASL_CBINDING <none/tls-unique/tls-endpoint>
The channel-binding type to use, see also LDAP_OPT_X_SASL_CBINDING. The default is none.
.SH GSSAPI OPTIONS .SH GSSAPI OPTIONS
If OpenLDAP is built with Generic Security Services Application Programming Interface support, If OpenLDAP is built with Generic Security Services Application Programming Interface support,
there are more options you can specify. there are more options you can specify.

View file

@ -720,6 +720,10 @@ Used to specify the fully qualified domain name used for SASL processing.
.B olcSaslRealm: <realm> .B olcSaslRealm: <realm>
Specify SASL realm. Default is empty. Specify SASL realm. Default is empty.
.TP .TP
.B olcSaslCbinding: none | tls-unique | tls-endpoint
Specify the channel-binding type, see also LDAP_OPT_X_SASL_CBINDING.
Default is none.
.TP
.B olcSaslSecProps: <properties> .B olcSaslSecProps: <properties>
Used to specify Cyrus SASL security properties. Used to specify Cyrus SASL security properties.
The The

View file

@ -914,6 +914,9 @@ The
property specifies the maximum security layer receive buffer property specifies the maximum security layer receive buffer
size allowed. 0 disables security layers. The default is 65536. size allowed. 0 disables security layers. The default is 65536.
.TP .TP
.B sasl\-cbinding none | tls-unique | tls-endpoint
Specify the channel-binding type, see also LDAP_OPT_X_SASL_CBINDING.
.TP
.B schemadn <dn> .B schemadn <dn>
Specify the distinguished name for the subschema subentry that Specify the distinguished name for the subschema subentry that
controls the entries on this server. The default is "cn=Subschema". controls the entries on this server. The default is "cn=Subschema".

View file

@ -186,6 +186,10 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 ((3 << 8) + 2) #define LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 ((3 << 8) + 2)
#define LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 ((3 << 8) + 3) #define LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 ((3 << 8) + 3)
#define LDAP_OPT_X_SASL_CBINDING_NONE 0
#define LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE 1
#define LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT 2
/* OpenLDAP SASL options */ /* OpenLDAP SASL options */
#define LDAP_OPT_X_SASL_MECH 0x6100 #define LDAP_OPT_X_SASL_MECH 0x6100
#define LDAP_OPT_X_SASL_REALM 0x6101 #define LDAP_OPT_X_SASL_REALM 0x6101
@ -201,6 +205,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_X_SASL_NOCANON 0x610b #define LDAP_OPT_X_SASL_NOCANON 0x610b
#define LDAP_OPT_X_SASL_USERNAME 0x610c /* read-only */ #define LDAP_OPT_X_SASL_USERNAME 0x610c /* read-only */
#define LDAP_OPT_X_SASL_GSS_CREDS 0x610d #define LDAP_OPT_X_SASL_GSS_CREDS 0x610d
#define LDAP_OPT_X_SASL_CBINDING 0x610e
/* /*
* OpenLDAP per connection tcp-keepalive settings * OpenLDAP per connection tcp-keepalive settings

View file

@ -262,6 +262,10 @@ LDAP_F (void *) ldap_pvt_sasl_mutex_new LDAP_P((void));
LDAP_F (int) ldap_pvt_sasl_mutex_lock LDAP_P((void *mutex)); LDAP_F (int) ldap_pvt_sasl_mutex_lock LDAP_P((void *mutex));
LDAP_F (int) ldap_pvt_sasl_mutex_unlock LDAP_P((void *mutex)); LDAP_F (int) ldap_pvt_sasl_mutex_unlock LDAP_P((void *mutex));
LDAP_F (void) ldap_pvt_sasl_mutex_dispose LDAP_P((void *mutex)); LDAP_F (void) ldap_pvt_sasl_mutex_dispose LDAP_P((void *mutex));
LDAP_F (int) ldap_pvt_sasl_cbinding_parse LDAP_P(( const char *arg ));
LDAP_F (void *) ldap_pvt_sasl_cbinding LDAP_P(( void *ssl, int type,
int is_server ));
#endif /* HAVE_CYRUS_SASL */ #endif /* HAVE_CYRUS_SASL */
struct sockbuf; /* avoid pulling in <lber.h> */ struct sockbuf; /* avoid pulling in <lber.h> */
@ -438,6 +442,7 @@ LDAP_F (int) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx, struct berval *dn,
LDAPDN_rewrite_dummy *func, unsigned flags )); LDAPDN_rewrite_dummy *func, unsigned flags ));
LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *ctx )); LDAP_F (int) ldap_pvt_tls_get_strength LDAP_P(( void *ctx ));
LDAP_F (int) ldap_pvt_tls_get_unique LDAP_P(( void *ctx, struct berval *buf, int is_server )); LDAP_F (int) ldap_pvt_tls_get_unique LDAP_P(( void *ctx, struct berval *buf, int is_server ));
LDAP_F (int) ldap_pvt_tls_get_endpoint LDAP_P(( void *ctx, struct berval *buf, int is_server ));
LDAP_F (const char *) ldap_pvt_tls_get_version LDAP_P(( void *ctx )); LDAP_F (const char *) ldap_pvt_tls_get_version LDAP_P(( void *ctx ));
LDAP_F (const char *) ldap_pvt_tls_get_cipher LDAP_P(( void *ctx )); LDAP_F (const char *) ldap_pvt_tls_get_cipher LDAP_P(( void *ctx ));

View file

@ -368,6 +368,65 @@ int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
int ldap_pvt_sasl_cbinding_parse( const char *arg )
{
int i = -1;
if ( strcasecmp(arg, "none") == 0 )
i = LDAP_OPT_X_SASL_CBINDING_NONE;
else if ( strcasecmp(arg, "tls-unique") == 0 )
i = LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE;
else if ( strcasecmp(arg, "tls-endpoint") == 0 )
i = LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT;
return i;
}
void *ldap_pvt_sasl_cbinding( void *ssl, int type, int is_server )
{
#if defined(SASL_CHANNEL_BINDING) && defined(HAVE_TLS)
char unique_prefix[] = "tls-unique:";
char endpoint_prefix[] = "tls-server-end-point:";
char cbinding[ 64 ];
struct berval cbv = { 64, cbinding };
void *cb_data; /* used since cb->data is const* */
sasl_channel_binding_t *cb;
char *prefix;
int plen;
switch (type) {
case LDAP_OPT_X_SASL_CBINDING_NONE:
return NULL;
case LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE:
if ( !ldap_pvt_tls_get_unique( ssl, &cbv, is_server ))
return NULL;
prefix = unique_prefix;
plen = sizeof(unique_prefix) -1;
break;
case LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT:
if ( !ldap_pvt_tls_get_endpoint( ssl, &cbv, is_server ))
return NULL;
prefix = endpoint_prefix;
plen = sizeof(endpoint_prefix) -1;
break;
default:
return NULL;
}
cb = ldap_memalloc( sizeof(*cb) + plen + cbv.bv_len );
cb->len = plen + cbv.bv_len;
cb->data = cb_data = cb+1;
memcpy( cb_data, prefix, plen );
memcpy( cb_data + plen, cbv.bv_val, cbv.bv_len );
cb->name = "ldap";
cb->critical = 0;
return cb;
#else
return NULL;
#endif
}
int int
ldap_int_sasl_bind( ldap_int_sasl_bind(
LDAP *ld, LDAP *ld,
@ -497,19 +556,12 @@ ldap_int_sasl_bind(
(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac ); (void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac );
LDAP_FREE( authid.bv_val ); LDAP_FREE( authid.bv_val );
#ifdef SASL_CHANNEL_BINDING /* 2.1.25+ */ #ifdef SASL_CHANNEL_BINDING /* 2.1.25+ */
{ if ( ld->ld_defconn->lconn_sasl_cbind == NULL ) {
char cbinding[64]; void *cb;
struct berval cbv = { sizeof(cbinding), cbinding }; cb = ldap_pvt_sasl_cbinding( ssl,
if ( ld->ld_defconn->lconn_sasl_cbind == NULL && ld->ld_options.ldo_sasl_cbinding,
ldap_pvt_tls_get_unique( ssl, &cbv, 0 )) { 0 );
sasl_channel_binding_t *cb = ldap_memalloc( sizeof(*cb) + if ( cb != NULL ) {
cbv.bv_len);
void *cb_data; /* used since cb->data is const* */
cb->name = "ldap";
cb->critical = 0;
cb->len = cbv.bv_len;
cb->data = cb_data = cb+1;
memcpy( cb_data, cbv.bv_val, cbv.bv_len );
sasl_setprop( ld->ld_defconn->lconn_sasl_authctx, sasl_setprop( ld->ld_defconn->lconn_sasl_authctx,
SASL_CHANNEL_BINDING, cb ); SASL_CHANNEL_BINDING, cb );
ld->ld_defconn->lconn_sasl_cbind = cb; ld->ld_defconn->lconn_sasl_cbind = cb;
@ -931,12 +983,20 @@ int ldap_pvt_sasl_secprops(
int int
ldap_int_sasl_config( struct ldapoptions *lo, int option, const char *arg ) ldap_int_sasl_config( struct ldapoptions *lo, int option, const char *arg )
{ {
int rc; int rc, i;
switch( option ) { switch( option ) {
case LDAP_OPT_X_SASL_SECPROPS: case LDAP_OPT_X_SASL_SECPROPS:
rc = ldap_pvt_sasl_secprops( arg, &lo->ldo_sasl_secprops ); rc = ldap_pvt_sasl_secprops( arg, &lo->ldo_sasl_secprops );
if( rc == LDAP_SUCCESS ) return 0; if( rc == LDAP_SUCCESS ) return 0;
break;
case LDAP_OPT_X_SASL_CBINDING:
i = ldap_pvt_sasl_cbinding_parse( arg );
if ( i >= 0 ) {
lo->ldo_sasl_cbinding = i;
return 0;
}
break;
} }
return -1; return -1;
@ -1042,6 +1102,10 @@ ldap_int_sasl_get_option( LDAP *ld, int option, void *arg )
/* this option is write only */ /* this option is write only */
return -1; return -1;
case LDAP_OPT_X_SASL_CBINDING:
*(int *)arg = ld->ld_options.ldo_sasl_cbinding;
break;
#ifdef SASL_GSS_CREDS #ifdef SASL_GSS_CREDS
case LDAP_OPT_X_SASL_GSS_CREDS: { case LDAP_OPT_X_SASL_GSS_CREDS: {
sasl_conn_t *ctx; sasl_conn_t *ctx;
@ -1143,6 +1207,17 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
return sc == LDAP_SUCCESS ? 0 : -1; return sc == LDAP_SUCCESS ? 0 : -1;
} }
case LDAP_OPT_X_SASL_CBINDING:
if ( !arg ) return -1;
switch( *(int *) arg ) {
case LDAP_OPT_X_SASL_CBINDING_NONE:
case LDAP_OPT_X_SASL_CBINDING_TLS_UNIQUE:
case LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT:
ld->ld_options.ldo_sasl_cbinding = *(int *) arg;
return 0;
}
return -1;
#ifdef SASL_GSS_CREDS #ifdef SASL_GSS_CREDS
case LDAP_OPT_X_SASL_GSS_CREDS: { case LDAP_OPT_X_SASL_GSS_CREDS: {
sasl_conn_t *ctx; sasl_conn_t *ctx;

View file

@ -110,6 +110,7 @@ static const struct ol_attribute {
offsetof(struct ldapoptions, ldo_def_sasl_authzid)}, offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
{0, ATTR_SASL, "SASL_SECPROPS", NULL, LDAP_OPT_X_SASL_SECPROPS}, {0, ATTR_SASL, "SASL_SECPROPS", NULL, LDAP_OPT_X_SASL_SECPROPS},
{0, ATTR_BOOL, "SASL_NOCANON", NULL, LDAP_BOOL_SASL_NOCANON}, {0, ATTR_BOOL, "SASL_NOCANON", NULL, LDAP_BOOL_SASL_NOCANON},
{0, ATTR_SASL, "SASL_CBINDING", NULL, LDAP_OPT_X_SASL_CBINDING},
#endif #endif
#ifdef HAVE_TLS #ifdef HAVE_TLS

View file

@ -300,6 +300,7 @@ struct ldapoptions {
/* SASL Security Properties */ /* SASL Security Properties */
struct sasl_security_properties ldo_sasl_secprops; struct sasl_security_properties ldo_sasl_secprops;
int ldo_sasl_cbinding;
#define LDAP_LDO_SASL_NULLARG ,0,0,0,0,{0} #define LDAP_LDO_SASL_NULLARG ,0,0,0,0,{0}
#else #else
#define LDAP_LDO_SASL_NULLARG #define LDAP_LDO_SASL_NULLARG

View file

@ -42,6 +42,7 @@ typedef int (TI_session_dn)(tls_session *sess, struct berval *dn);
typedef int (TI_session_chkhost)(LDAP *ld, tls_session *s, const char *name_in); typedef int (TI_session_chkhost)(LDAP *ld, tls_session *s, const char *name_in);
typedef int (TI_session_strength)(tls_session *sess); typedef int (TI_session_strength)(tls_session *sess);
typedef int (TI_session_unique)(tls_session *sess, struct berval *buf, int is_server); typedef int (TI_session_unique)(tls_session *sess, struct berval *buf, int is_server);
typedef int (TI_session_endpoint)(tls_session *sess, struct berval *buf, int is_server);
typedef const char *(TI_session_name)(tls_session *s); typedef const char *(TI_session_name)(tls_session *s);
typedef int (TI_session_peercert)(tls_session *s, struct berval *der); typedef int (TI_session_peercert)(tls_session *s, struct berval *der);
typedef int (TI_session_pinning)(LDAP *ld, tls_session *s, char *hashalg, struct berval *hash); typedef int (TI_session_pinning)(LDAP *ld, tls_session *s, char *hashalg, struct berval *hash);
@ -69,6 +70,7 @@ typedef struct tls_impl {
TI_session_chkhost *ti_session_chkhost; TI_session_chkhost *ti_session_chkhost;
TI_session_strength *ti_session_strength; TI_session_strength *ti_session_strength;
TI_session_unique *ti_session_unique; TI_session_unique *ti_session_unique;
TI_session_endpoint *ti_session_endpoint;
TI_session_name *ti_session_version; TI_session_name *ti_session_version;
TI_session_name *ti_session_cipher; TI_session_name *ti_session_cipher;
TI_session_peercert *ti_session_peercert; TI_session_peercert *ti_session_peercert;

View file

@ -1200,6 +1200,13 @@ ldap_pvt_tls_get_unique( void *s, struct berval *buf, int is_server )
return tls_imp->ti_session_unique( session, buf, is_server ); return tls_imp->ti_session_unique( session, buf, is_server );
} }
int
ldap_pvt_tls_get_endpoint( void *s, struct berval *buf, int is_server )
{
tls_session *session = s;
return tls_imp->ti_session_endpoint( session, buf, is_server );
}
const char * const char *
ldap_pvt_tls_get_version( void *s ) ldap_pvt_tls_get_version( void *s )
{ {

View file

@ -729,6 +729,64 @@ tlsg_session_unique( tls_session *sess, struct berval *buf, int is_server)
return 0; return 0;
} }
static int
tlsg_session_endpoint( tls_session *sess, struct berval *buf, int is_server )
{
tlsg_session *s = (tlsg_session *)sess;
const gnutls_datum_t *cert_data;
gnutls_x509_crt_t server_cert;
gnutls_digest_algorithm_t md;
int sign_algo, md_len, rc;
if ( is_server )
cert_data = gnutls_certificate_get_ours( s->session );
else
cert_data = gnutls_certificate_get_peers( s->session, NULL );
if ( cert_data == NULL )
return 0;
rc = gnutls_x509_crt_init( &server_cert );
if ( rc != GNUTLS_E_SUCCESS )
return 0;
rc = gnutls_x509_crt_import( server_cert, cert_data, GNUTLS_X509_FMT_DER );
if ( rc != GNUTLS_E_SUCCESS ) {
gnutls_x509_crt_deinit( server_cert );
return 0;
}
sign_algo = gnutls_x509_crt_get_signature_algorithm( server_cert );
gnutls_x509_crt_deinit( server_cert );
if ( sign_algo <= GNUTLS_SIGN_UNKNOWN )
return 0;
md = gnutls_sign_get_hash_algorithm( sign_algo );
if ( md == GNUTLS_DIG_UNKNOWN )
return 0;
/* See RFC 5929 */
switch (md) {
case GNUTLS_DIG_NULL:
case GNUTLS_DIG_MD2:
case GNUTLS_DIG_MD5:
case GNUTLS_DIG_SHA1:
md = GNUTLS_DIG_SHA256;
}
md_len = gnutls_hash_get_len( md );
if ( md_len == 0 || md_len > buf->bv_len )
return 0;
rc = gnutls_hash_fast( md, cert_data->data, cert_data->size, buf->bv_val );
if ( rc != GNUTLS_E_SUCCESS )
return 0;
buf->bv_len = md_len;
return md_len;
}
static const char * static const char *
tlsg_session_version( tls_session *sess ) tlsg_session_version( tls_session *sess )
{ {
@ -1117,6 +1175,7 @@ tls_impl ldap_int_tls_impl = {
tlsg_session_chkhost, tlsg_session_chkhost,
tlsg_session_strength, tlsg_session_strength,
tlsg_session_unique, tlsg_session_unique,
tlsg_session_endpoint,
tlsg_session_version, tlsg_session_version,
tlsg_session_cipher, tlsg_session_cipher,
tlsg_session_peercert, tlsg_session_peercert,

View file

@ -858,6 +858,50 @@ tlso_session_unique( tls_session *sess, struct berval *buf, int is_server)
return buf->bv_len; return buf->bv_len;
} }
static int
tlso_session_endpoint( tls_session *sess, struct berval *buf, int is_server )
{
tlso_session *s = (tlso_session *)sess;
const EVP_MD *md;
unsigned int md_len;
X509 *cert;
if ( buf->bv_len < EVP_MAX_MD_SIZE )
return 0;
if ( is_server )
cert = SSL_get_certificate( s );
else
cert = SSL_get_peer_certificate( s );
if ( cert == NULL )
return 0;
#if OPENSSL_VERSION_NUMBER >= 0x10100000
md = EVP_get_digestbynid( X509_get_signature_nid( cert ));
#else
md = EVP_get_digestbynid(OBJ_obj2nid( cert->sig_alg->algorithm ));
#endif
/* See RFC 5929 */
if ( md == NULL ||
md == EVP_md_null() ||
#ifndef OPENSSL_NO_MD2
md == EVP_md2() ||
#endif
md == EVP_md4() ||
md == EVP_md5() ||
md == EVP_sha1() )
md = EVP_sha256();
if ( !X509_digest( cert, md, buf->bv_val, &md_len ))
return 0;
buf->bv_len = md_len;
return md_len;
}
static const char * static const char *
tlso_session_version( tls_session *sess ) tlso_session_version( tls_session *sess )
{ {
@ -1474,6 +1518,7 @@ tls_impl ldap_int_tls_impl = {
tlso_session_chkhost, tlso_session_chkhost,
tlso_session_strength, tlso_session_strength,
tlso_session_unique, tlso_session_unique,
tlso_session_endpoint,
tlso_session_version, tlso_session_version,
tlso_session_cipher, tlso_session_cipher,
tlso_session_peercert, tlso_session_peercert,

View file

@ -630,6 +630,15 @@ static ConfigTable config_back_cf_table[] = {
"( OLcfgGlAt:92 NAME 'olcSaslAuxpropsDontUseCopyIgnore' " "( OLcfgGlAt:92 NAME 'olcSaslAuxpropsDontUseCopyIgnore' "
"EQUALITY booleanMatch " "EQUALITY booleanMatch "
"SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL }, "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "sasl-cbinding", NULL, 2, 2, 0,
#ifdef HAVE_CYRUS_SASL
ARG_STRING, &sasl_cbinding,
#else
ARG_IGNORED, NULL,
#endif
"( OLcfgGlAt:100 NAME 'olcSaslCBinding' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "sasl-host", "host", 2, 2, 0, { "sasl-host", "host", 2, 2, 0,
#ifdef HAVE_CYRUS_SASL #ifdef HAVE_CYRUS_SASL
ARG_STRING|ARG_UNIQUE, &sasl_host, ARG_STRING|ARG_UNIQUE, &sasl_host,
@ -948,7 +957,7 @@ static ConfigOCs cf_ocs[] = {
"olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ " "olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
"olcRootDSE $ " "olcRootDSE $ "
"olcSaslAuxprops $ olcSaslAuxpropsDontUseCopy $ olcSaslAuxpropsDontUseCopyIgnore $ " "olcSaslAuxprops $ olcSaslAuxpropsDontUseCopy $ olcSaslAuxpropsDontUseCopyIgnore $ "
"olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ " "olcSaslCBinding $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
"olcSecurity $ olcServerID $ olcSizeLimit $ " "olcSecurity $ olcServerID $ olcSizeLimit $ "
"olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ " "olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
"olcTCPBuffer $ " "olcTCPBuffer $ "

View file

@ -73,6 +73,7 @@ char *global_host = NULL;
struct berval global_host_bv = BER_BVNULL; struct berval global_host_bv = BER_BVNULL;
char *global_realm = NULL; char *global_realm = NULL;
char *sasl_host = NULL; char *sasl_host = NULL;
char *sasl_cbinding = NULL;
char **default_passwd_hash = NULL; char **default_passwd_hash = NULL;
struct berval default_search_base = BER_BVNULL; struct berval default_search_base = BER_BVNULL;
struct berval default_search_nbase = BER_BVNULL; struct berval default_search_nbase = BER_BVNULL;

View file

@ -1440,12 +1440,9 @@ connection_read( ber_socket_t s, conn_readinfo *cri )
msgbuf, ldap_pvt_tls_get_version( ssl ), ldap_pvt_tls_get_cipher( ssl )); msgbuf, ldap_pvt_tls_get_version( ssl ), ldap_pvt_tls_get_cipher( ssl ));
slap_sasl_external( c, c->c_tls_ssf, &authid ); slap_sasl_external( c, c->c_tls_ssf, &authid );
if ( authid.bv_val ) free( authid.bv_val ); if ( authid.bv_val ) free( authid.bv_val );
{
char cbinding[64]; slap_sasl_cbinding( c, ssl );
struct berval cbv = { sizeof(cbinding), cbinding };
if ( ldap_pvt_tls_get_unique( ssl, &cbv, 1 ))
slap_sasl_cbinding( c, &cbv );
}
} else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb, } else if ( rc == 1 && ber_sockbuf_ctrl( c->c_sb,
LBER_SB_OPT_NEEDS_WRITE, NULL )) { /* need to retry */ LBER_SB_OPT_NEEDS_WRITE, NULL )) { /* need to retry */
slapd_set_write( s, 1 ); slapd_set_write( s, 1 );

View file

@ -1681,8 +1681,7 @@ LDAP_SLAPD_F (int) slap_sasl_external( Connection *c,
slap_ssf_t ssf, /* relative strength of external security */ slap_ssf_t ssf, /* relative strength of external security */
struct berval *authid ); /* asserted authentication id */ struct berval *authid ); /* asserted authentication id */
LDAP_SLAPD_F (int) slap_sasl_cbinding( Connection *c, LDAP_SLAPD_F (int) slap_sasl_cbinding( Connection *c, void *ssl );
struct berval *cbv );
LDAP_SLAPD_F (int) slap_sasl_reset( Connection *c ); LDAP_SLAPD_F (int) slap_sasl_reset( Connection *c );
LDAP_SLAPD_F (int) slap_sasl_close( Connection *c ); LDAP_SLAPD_F (int) slap_sasl_close( Connection *c );
@ -2072,6 +2071,7 @@ LDAP_SLAPD_V (char *) global_host;
LDAP_SLAPD_V (struct berval) global_host_bv; LDAP_SLAPD_V (struct berval) global_host_bv;
LDAP_SLAPD_V (char *) global_realm; LDAP_SLAPD_V (char *) global_realm;
LDAP_SLAPD_V (char *) sasl_host; LDAP_SLAPD_V (char *) sasl_host;
LDAP_SLAPD_V (char *) sasl_cbinding;
LDAP_SLAPD_V (char *) slap_sasl_auxprops; LDAP_SLAPD_V (char *) slap_sasl_auxprops;
#ifdef SLAP_AUXPROP_DONTUSECOPY #ifdef SLAP_AUXPROP_DONTUSECOPY
LDAP_SLAPD_V (int) slap_dontUseCopy_ignore; LDAP_SLAPD_V (int) slap_dontUseCopy_ignore;

View file

@ -1320,6 +1320,8 @@ int slap_sasl_destroy( void )
#endif #endif
free( sasl_host ); free( sasl_host );
sasl_host = NULL; sasl_host = NULL;
free( sasl_cbinding );
sasl_cbinding = NULL;
return 0; return 0;
} }
@ -1506,17 +1508,24 @@ int slap_sasl_external(
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
int slap_sasl_cbinding( Connection *conn, struct berval *cbv ) int slap_sasl_cbinding( Connection *conn, void *ssl )
{ {
#ifdef SASL_CHANNEL_BINDING #ifdef SASL_CHANNEL_BINDING
sasl_channel_binding_t *cb = ch_malloc( sizeof(*cb) + cbv->bv_len );; void *cb;
cb->name = "ldap"; int i;
cb->critical = 0;
cb->data = (char *)(cb+1); if ( sasl_cbinding == NULL )
cb->len = cbv->bv_len; return LDAP_SUCCESS;
memcpy( (void *)cb->data, cbv->bv_val, cbv->bv_len );
i = ldap_pvt_sasl_cbinding_parse( sasl_cbinding );
if ( i < 0 )
return LDAP_SUCCESS;
cb = ldap_pvt_sasl_cbinding( ssl, i, 1 );
if ( cb != NULL ) {
sasl_setprop( conn->c_sasl_authctx, SASL_CHANNEL_BINDING, cb ); sasl_setprop( conn->c_sasl_authctx, SASL_CHANNEL_BINDING, cb );
conn->c_sasl_cbind = cb; conn->c_sasl_cbind = cb;
}
#endif #endif
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }