mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-27 03:20:22 +08:00
Add channel binding support
Currently only implemented for OpenSSL. Needs an option to set the criticality flag.
This commit is contained in:
parent
50ab5bb1ed
commit
ca310ebff4
@ -430,6 +430,7 @@ LDAP_F (int) ldap_pvt_tls_get_my_dn LDAP_P(( void *ctx, struct berval *dn,
|
||||
LDAP_F (int) ldap_pvt_tls_get_peer_dn LDAP_P(( void *ctx, struct berval *dn,
|
||||
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_unique LDAP_P(( void *ctx, struct berval *buf, int is_server ));
|
||||
|
||||
LDAP_END_DECL
|
||||
|
||||
|
@ -369,6 +369,10 @@ int ldap_int_sasl_close( LDAP *ld, LDAPConn *lc )
|
||||
lc->lconn_sasl_sockctx = NULL;
|
||||
lc->lconn_sasl_authctx = NULL;
|
||||
}
|
||||
if( lc->lconn_sasl_cbind ) {
|
||||
ldap_memfree( lc->lconn_sasl_cbind );
|
||||
lc->lconn_sasl_cbind = NULL;
|
||||
}
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
@ -482,6 +486,24 @@ ldap_int_sasl_bind(
|
||||
|
||||
(void) ldap_int_sasl_external( ld, ld->ld_defconn, authid.bv_val, fac );
|
||||
LDAP_FREE( authid.bv_val );
|
||||
#ifdef SASL_CHANNEL_BINDING /* 2.1.25+ */
|
||||
{
|
||||
char cbinding[64];
|
||||
struct berval cbv = { sizeof(cbinding), cbinding };
|
||||
if ( ldap_pvt_tls_get_unique( ssl, &cbv, 0 )) {
|
||||
sasl_channel_binding_t *cb = ldap_memalloc( sizeof(*cb) +
|
||||
cbv.bv_len);
|
||||
cb->name = "ldap";
|
||||
cb->critical = 0;
|
||||
cb->data = (char *)(cb+1);
|
||||
cb->len = cbv.bv_len;
|
||||
memcpy( cb->data, cbv.bv_val, cbv.bv_len );
|
||||
sasl_setprop( ld->ld_defconn->lconn_sasl_authctx,
|
||||
SASL_CHANNEL_BINDING, cb );
|
||||
ld->ld_defconn->lconn_sasl_cbind = cb;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -305,6 +305,7 @@ typedef struct ldap_conn {
|
||||
#ifdef HAVE_CYRUS_SASL
|
||||
void *lconn_sasl_authctx; /* context for bind */
|
||||
void *lconn_sasl_sockctx; /* for security layer */
|
||||
void *lconn_sasl_cbind; /* for channel binding */
|
||||
#endif
|
||||
#ifdef HAVE_GSSAPI
|
||||
void *lconn_gss_ctx; /* gss_ctx_id_t */
|
||||
|
@ -41,6 +41,7 @@ typedef char *(TI_session_errmsg)(tls_session *s, int rc, char *buf, size_t len
|
||||
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_strength)(tls_session *sess);
|
||||
typedef int (TI_session_unique)(tls_session *sess, struct berval *buf, int is_server);
|
||||
|
||||
typedef void (TI_thr_init)(void);
|
||||
|
||||
@ -64,6 +65,7 @@ typedef struct tls_impl {
|
||||
TI_session_dn *ti_session_peer_dn;
|
||||
TI_session_chkhost *ti_session_chkhost;
|
||||
TI_session_strength *ti_session_strength;
|
||||
TI_session_unique *ti_session_unique;
|
||||
|
||||
Sockbuf_IO *ti_sbio;
|
||||
|
||||
|
@ -981,6 +981,13 @@ ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func,
|
||||
rc = ldap_X509dn2bv(&der_dn, dn, (LDAPDN_rewrite_func *)func, flags );
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ldap_pvt_tls_get_unique( void *s, struct berval *buf, int is_server )
|
||||
{
|
||||
tls_session *session = s;
|
||||
return tls_imp->ti_session_unique( session, buf, is_server );
|
||||
}
|
||||
#endif /* HAVE_TLS */
|
||||
|
||||
int
|
||||
|
@ -780,6 +780,12 @@ tlsg_session_strength( tls_session *session )
|
||||
return gnutls_cipher_get_key_size( c ) * 8;
|
||||
}
|
||||
|
||||
static int
|
||||
tlsg_session_unique( tls_session *sess, struct berval *buf, int is_server)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* suites is a string of colon-separated cipher suite names. */
|
||||
static int
|
||||
tlsg_parse_ciphers( tlsg_ctx *ctx, char *suites )
|
||||
@ -1110,6 +1116,7 @@ tls_impl ldap_int_tls_impl = {
|
||||
tlsg_session_peer_dn,
|
||||
tlsg_session_chkhost,
|
||||
tlsg_session_strength,
|
||||
tlsg_session_unique,
|
||||
|
||||
&tlsg_sbio,
|
||||
|
||||
|
@ -2838,6 +2838,12 @@ tlsm_session_strength( tls_session *session )
|
||||
return rc ? 0 : keySize;
|
||||
}
|
||||
|
||||
static int
|
||||
tlsm_session_unique( tls_session *sess, struct berval *buf, int is_server)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS support for LBER Sockbufs
|
||||
*/
|
||||
@ -3266,6 +3272,7 @@ tls_impl ldap_int_tls_impl = {
|
||||
tlsm_session_peer_dn,
|
||||
tlsm_session_chkhost,
|
||||
tlsm_session_strength,
|
||||
tlsm_session_unique,
|
||||
|
||||
&tlsm_sbio,
|
||||
|
||||
|
@ -676,6 +676,21 @@ tlso_session_strength( tls_session *sess )
|
||||
return SSL_CIPHER_get_bits(SSL_get_current_cipher(s), NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
tlso_session_unique( tls_session *sess, struct berval *buf, int is_server)
|
||||
{
|
||||
tlso_session *s = (tlso_session *)sess;
|
||||
|
||||
/* Usually the client sends the finished msg. But if the
|
||||
* session was resumed, the server sent the msg.
|
||||
*/
|
||||
if (SSL_session_reused(s) ^ !is_server)
|
||||
buf->bv_len = SSL_get_finished(s, buf->bv_val, buf->bv_len);
|
||||
else
|
||||
buf->bv_len = SSL_get_peer_finished(s, buf->bv_val, buf->bv_len);
|
||||
return buf->bv_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* TLS support for LBER Sockbufs
|
||||
*/
|
||||
@ -1283,6 +1298,7 @@ tls_impl ldap_int_tls_impl = {
|
||||
tlso_session_peer_dn,
|
||||
tlso_session_chkhost,
|
||||
tlso_session_strength,
|
||||
tlso_session_unique,
|
||||
|
||||
&tlso_sbio,
|
||||
|
||||
|
@ -406,6 +406,7 @@ Connection * connection_init(
|
||||
c->c_sasl_sockctx = NULL;
|
||||
c->c_sasl_extra = NULL;
|
||||
c->c_sasl_bindop = NULL;
|
||||
c->c_sasl_cbind = NULL;
|
||||
|
||||
c->c_sb = ber_sockbuf_alloc( );
|
||||
|
||||
@ -451,6 +452,7 @@ Connection * connection_init(
|
||||
assert( c->c_sasl_sockctx == NULL );
|
||||
assert( c->c_sasl_extra == NULL );
|
||||
assert( c->c_sasl_bindop == NULL );
|
||||
assert( c->c_sasl_cbind == NULL );
|
||||
assert( c->c_currentber == NULL );
|
||||
assert( c->c_writewaiter == 0);
|
||||
assert( c->c_writers == 0);
|
||||
@ -1408,6 +1410,12 @@ connection_read( ber_socket_t s, conn_readinfo *cri )
|
||||
c->c_connid, (int) s, c->c_tls_ssf, c->c_ssf, 0 );
|
||||
slap_sasl_external( c, c->c_tls_ssf, &authid );
|
||||
if ( authid.bv_val ) free( authid.bv_val );
|
||||
{
|
||||
char cbinding[64];
|
||||
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,
|
||||
LBER_SB_OPT_NEEDS_WRITE, NULL )) { /* need to retry */
|
||||
slapd_set_write( s, 1 );
|
||||
|
@ -1503,6 +1503,21 @@ int slap_sasl_external(
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int slap_sasl_cbinding( Connection *conn, struct berval *cbv )
|
||||
{
|
||||
#ifdef SASL_CHANNEL_BINDING
|
||||
sasl_channel_binding_t *cb = ch_malloc( sizeof(*cb) + cbv->bv_len );;
|
||||
cb->name = "ldap";
|
||||
cb->critical = 0;
|
||||
cb->data = (char *)(cb+1);
|
||||
cb->len = cbv->bv_len;
|
||||
memcpy( cb->data, cbv->bv_val, cbv->bv_len );
|
||||
sasl_setprop( conn->c_sasl_authctx, SASL_CHANNEL_BINDING, cb );
|
||||
conn->c_sasl_cbind = cb;
|
||||
#endif
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
int slap_sasl_reset( Connection *conn )
|
||||
{
|
||||
return LDAP_SUCCESS;
|
||||
@ -1568,6 +1583,9 @@ int slap_sasl_close( Connection *conn )
|
||||
free( conn->c_sasl_extra );
|
||||
conn->c_sasl_extra = NULL;
|
||||
|
||||
free( conn->c_sasl_cbind );
|
||||
conn->c_sasl_cbind = NULL;
|
||||
|
||||
#elif defined(SLAP_BUILTIN_SASL)
|
||||
SASL_CTX *ctx = conn->c_sasl_authctx;
|
||||
if( ctx ) {
|
||||
|
@ -2910,6 +2910,7 @@ struct Connection {
|
||||
void *c_sasl_authctx; /* SASL authentication context */
|
||||
void *c_sasl_sockctx; /* SASL security layer context */
|
||||
void *c_sasl_extra; /* SASL session extra stuff */
|
||||
void *c_sasl_cbind; /* SASL channel binding */
|
||||
Operation *c_sasl_bindop; /* set to current op if it's a bind */
|
||||
|
||||
#ifdef LDAP_X_TXN
|
||||
|
Loading…
Reference in New Issue
Block a user