Ssl OpenLDAP-为LDAP TLS连接启用CRL检查
我有一个使用TLS连接到LDAP服务器的客户端。对于此连接,我希望启用CRL检查,并仅在任何服务器/客户端证书被吊销时拒绝连接。 在特殊情况下(如CRL缺失、CRL过期),我希望忽略错误并建立连接。 因此,我想覆盖默认的SSL验证回调以忽略特定错误 但根本不需要回拨电话。始终只调用默认回拨 这是我的回电:Ssl OpenLDAP-为LDAP TLS连接启用CRL检查,ssl,openssl,ldap,openldap,tls1.2,Ssl,Openssl,Ldap,Openldap,Tls1.2,我有一个使用TLS连接到LDAP服务器的客户端。对于此连接,我希望启用CRL检查,并仅在任何服务器/客户端证书被吊销时拒绝连接。 在特殊情况下(如CRL缺失、CRL过期),我希望忽略错误并建立连接。 因此,我想覆盖默认的SSL验证回调以忽略特定错误 但根本不需要回拨电话。始终只调用默认回拨 这是我的回电: static int verify_callback(int ok, X509_STORE_CTX *ctx) { X509* cert = X509_STORE_CTX_get_cu
static int verify_callback(int ok, X509_STORE_CTX *ctx)
{
X509* cert = X509_STORE_CTX_get_current_cert(ctx);
if (ok)
return ok;
int sslRet = X509_STORE_CTX_get_error(ctx);
const char* err = NULL;
switch (sslRet)
{
case X509_V_ERR_UNABLE_TO_GET_CRL:
case X509_V_ERR_CRL_HAS_EXPIRED:
case X509_V_ERR_CRL_NOT_YET_VALID:
printf( "CRL: Verification failed... but ignored : %d\n", sslRet);
return 1;
default:
err = X509_verify_cert_error_string(sslRet);
if (err)
printf( "CRL: Failed to verify : %s\n",err);
return 0;
}
return sslRet;
}
使用ldap回拨集选项覆盖默认验证回拨:
void ldap_tls_cb(LDAP * ld, SSL * ssl, SSL_CTX * ctx, void * arg)
{
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER , verify_callback);
printf("verify call back is set...\n");
return;
}
主程序:
int main( int argc, char **argv )
{
LDAP *ldap;
int auth_method = LDAP_AUTH_SIMPLE; //LDAP_AUTH_SASL
int ldap_version = LDAP_VERSION3;
char *ldap_host = "10.104.40.35";
int ldap_port = 389;
if ( (ldap = ldap_init(ldap_host, ldap_port)) == NULL ) {
perror( "ldap_init failed" );
return( EXIT_FAILURE );
}
int result = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
if (result != LDAP_OPT_SUCCESS ) {
ldap_perror(ldap, "ldap_set_option failed!");
return(EXIT_FAILURE);
}
int requireCert = LDAP_OPT_X_TLS_DEMAND;
result = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &requireCert);
if (result != LDAP_OPT_SUCCESS ) {
ldap_perror(ldap, "ldap_set_option - req cert -failed!");
return(EXIT_FAILURE);
}
result = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, "/etc/certs/Cert.pem");
if (result != LDAP_OPT_SUCCESS ) {
ldap_perror(ldap, "ldap_set_option - cert file - failed!");
return(EXIT_FAILURE);
}
int crlvalue = LDAP_OPT_X_TLS_CRL_ALL;
result =ldap_set_option(NULL, LDAP_OPT_X_TLS_CRLCHECK, &crlvalue);
if (result != LDAP_OPT_SUCCESS ) {
ldap_perror(ldap, "ldap_set_option failed!");
return(EXIT_FAILURE);
}
int debug = 7;
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &debug);
result = ldap_set_option(ldap, LDAP_OPT_X_TLS_CONNECT_CB, (void *)ldap_tls_cb);
if (result != LDAP_SUCCESS) {
fprintf(stderr, "ldap_set_option(LDAP_OPT_X_TLS_CONNECT_CB): %s\n", ldap_err2string(result));
return(1);
}
int msgidp = 0;
result = ldap_start_tls(ldap,NULL,NULL,&msgidp);
if (result != LDAP_OPT_SUCCESS ) {
ldap_perror(ldap, "start tls failed!");
return result;
} else {
printf("Start tls success.\n");
}
LDAPMessage *resultm;
struct timeval timeout;
result = ldap_result(ldap, msgidp, 0, &timeout, &resultm );
if ( result == -1 || result == 0 ) {
printf("ldap_result failed;retC=%d \n", result);
return result;
}
result = ldap_parse_extended_result(ldap, resultm, NULL, NULL, 0 );
if ( result == LDAP_SUCCESS ) {
result = ldap_install_tls (ldap);
printf("installing tls... %s\n", ldap_err2string(result));
}
int request_id = 0;
result = ldap_sasl_bind(ldap, "", LDAP_SASL_SIMPLE, NULL, 0, 0, &request_id);
if ( result != LDAP_SUCCESS ) {
fprintf(stderr, "ldap_x_bind_s: %s\n", ldap_err2string(result));
printf("LDAP bind error .. %d\n", result);
return(EXIT_FAILURE);
} else {
printf("LDAP connection successful.\n");
}
ldap_unbind(ldap);
return(EXIT_SUCCESS);
}
有人能帮我检查一下为什么不调用我的验证回调吗?我认为您需要直接在
SSL
对象上设置回调,而不是上下文,所以
void ldap\u tls\u cb(ldap*ld、SSL*SSL、SSL\u CTX*CTX、void*arg)
{
SSL\u设置\u验证(SSL、SSL\u验证\u对等、验证\u回调);
printf(“验证已设置回拨…\n”);
返回;
}
原因是在调用connect回调时SSL句柄已经初始化(请参阅),并且
就在那一点上:
如果之前未设置特殊回调,则使用底层ctx的默认回调,该回调在使用ssl_new创建ssl时有效(3)
OpenLDAP可以使用GnuTLS构建,因此在设置回调之前,您可能需要检查它是否使用OpenSSL。LDAP\u OPT\u X\u TLS\u包
选项可用于此目的(请注意,我尚未测试此代码):
char*package=NULL;
int result=ldap\u get\u选项(NULL,ldap\u OPT\u X\u TLS\u包,(void*)和包);
if(结果!=LDAP\u OPT\u成功){
ldap_peror(ldap,“ldap_get_选项失败!”);
返回(退出失败);
}否则{
if(strcmp(包,“OpenSSL”)==0){
//设置回拨
}
ldap_memfree(包);
}
我认为您需要直接在SSL
对象上设置回调,而不是上下文,因此
void ldap\u tls\u cb(ldap*ld、SSL*SSL、SSL\u CTX*CTX、void*arg)
{
SSL\u设置\u验证(SSL、SSL\u验证\u对等、验证\u回调);
printf(“验证已设置回拨…\n”);
返回;
}
原因是在调用connect回调时SSL句柄已经初始化(请参阅),并且
就在那一点上:
如果之前未设置特殊回调,则使用底层ctx的默认回调,该回调在使用ssl_new创建ssl时有效(3)
OpenLDAP可以使用GnuTLS构建,因此在设置回调之前,您可能需要检查它是否使用OpenSSL。LDAP\u OPT\u X\u TLS\u包
选项可用于此目的(请注意,我尚未测试此代码):
char*package=NULL;
int result=ldap\u get\u选项(NULL,ldap\u OPT\u X\u TLS\u包,(void*)和包);
if(结果!=LDAP\u OPT\u成功){
ldap_peror(ldap,“ldap_get_选项失败!”);
返回(退出失败);
}否则{
if(strcmp(包,“OpenSSL”)==0){
//设置回拨
}
ldap_memfree(包);
}