【问题标题】:ldap_set_option() is not setting the option "LDAP_OPT_SSL"ldap_set_option() 未设置选项“LDAP_OPT_SSL”
【发布时间】:2013-05-14 09:48:15
【问题描述】:

我有一个 Windows 应用程序正在尝试连接到运行在安全端口 10636 上的 ldap 服务器。

来源:

#include "windows.h"
#include "ntldap.h"
#include "winldap.h"
#include "schnlsp.h"
#include "stdio.h"
#include "tchar.h"
const size_t newsize = 100;

//  Entry point for your application
int main(int argc, char* argv[])
{
    LDAP* pLdapConnection = NULL;
    INT returnCode = 0; 
    INT connectSuccess = 0;
    ULONG version = LDAP_VERSION3;
    SecPkgContext_ConnectionInfo sslInfo;
    LONG lv = 0;

    //  Initialize an LDAP session using SSL.
    pLdapConnection = ldap_sslinit("localhost",10636,1);
    if (pLdapConnection == NULL)
    {
        printf( "ldap_sslinit failed.\n");
        return -1;
    }

    //  Specify version 3; the default is version 2.
    printf("Setting Protocol version to 3.\n");
    returnCode = ldap_set_option(pLdapConnection,
        LDAP_OPT_PROTOCOL_VERSION,
        (void*)&version);
    if (returnCode != LDAP_SUCCESS)
        goto FatalExit;

    //  Verify that SSL is enabled on the connection.
    printf("Checking if SSL is enabled\n");
    returnCode = ldap_get_option(pLdapConnection,LDAP_OPT_SSL,(void*)&lv);
    if (returnCode != LDAP_SUCCESS)
        goto FatalExit;

    //  If SSL is not enabled, enable it.
    if ((void*)lv == LDAP_OPT_ON)
        printf("SSL is enabled\n");
    else
    {
        printf("SSL not enabled.\n SSL being enabled...\n");
        returnCode = ldap_set_option(pLdapConnection,LDAP_OPT_SSL,LDAP_OPT_ON);
        if (returnCode != LDAP_SUCCESS)
            goto FatalExit;
    }

    //  Connect to the server.
    connectSuccess = ldap_connect(pLdapConnection, NULL);

    if(connectSuccess == LDAP_SUCCESS)
        printf("ldap_connect succeeded \n");
    else
    {
        printf("ldap_connect failed with 0x%x.\n",connectSuccess);
        goto FatalExit;
    }

    //  Bind with current credentials. 
    printf("Binding ...\n");
    returnCode = ldap_bind_s(pLdapConnection,NULL,NULL,LDAP_AUTH_NEGOTIATE);
    if (returnCode != LDAP_SUCCESS)
        goto FatalExit;

    //  Retrieve the SSL cipher strength.
    printf("Getting SSL info\n");
    returnCode = ldap_get_option(pLdapConnection,LDAP_OPT_SSL_INFO,&sslInfo);
    if (returnCode != LDAP_SUCCESS)
        goto FatalExit;

    printf("SSL cipher strength = %d bits\n",sslInfo.dwCipherStrength);

    goto NormalExit;

    //  Perform cleanup.
NormalExit:
    if (pLdapConnection != NULL)
        ldap_unbind_s(pLdapConnection);
    return 0;

    //  Perform cleanup after an error.
FatalExit:
    if( pLdapConnection != NULL )
        ldap_unbind_s(pLdapConnection);
    printf( "\n\nERROR: 0x%x\n", returnCode);
    return returnCode;
}

设置ldap_set_option(pLdapConnection,LDAP_OPT_SSL,LDAP_OPT_ON); 后,应用程序仍然无法设置选项。因此,连接失败并返回代码LDAP_SERVER_DOWN

有人能指出为什么它不能设置选项吗?服务器确实支持ldaps:// 连接。

更新: 当我在 ldap 服务器上做 ldapsearch 时

ldapsearch -x -H ldaps://localhost -p 10636 -d 1

我得到了错误:

ldap_url_parse_ext(ldaps://localhost:10636)
ldap_create
ldap_url_parse_ext(ldaps://localhost:10636/??base)
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP localhost:10636
ldap_new_socket: 472
ldap_prepare_socket: 472
ldap_connect_to_host: Trying ::1 10636
ldap_pvt_connect: fd: 472 tm: -1 async: 0
attempting to connect:
connect errno: 10061
ldap_close_socket: 472
ldap_new_socket: 472
ldap_prepare_socket: 472
ldap_connect_to_host: Trying 127.0.0.1:10636
ldap_pvt_connect: fd: 472 tm: -1 async: 0
attempting to connect:
connect success
TLS trace: SSL_connect:before/connect initialization
TLS trace: SSL_connect:SSLv2/v3 write client hello A
TLS trace: SSL_connect:SSLv3 read server hello A
TLS certificate verification: depth: 0, err: 18, subject: /C=US/O=ASF/OU=ApacheD
S/CN=zanzibar, issuer: /C=US/O=ASF/OU=ApacheDS/CN=zanzibar
TLS certificate verification: Error, self signed certificate
TLS trace: SSL3 alert write:fatal:unknown CA
TLS trace: SSL_connect:error in SSLv3 read server certificate B
TLS trace: SSL_connect:error in SSLv3 read server certificate B
TLS: can't connect: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:cert
ificate verify failed (self signed certificate).
ldap_err2string
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)

但是,在向 ldap.conf 添加“TLS_REQCERT never”之后,一切都开始工作了。

现在, 如何让我的示例程序跳过“TLS 证书验证”?

【问题讨论】:

  • 验证服务器是否能够接受 SSL 连接: 1. 使用 openssl s_client -connect host:port 2. 使用已知的好工具,例如 ldapsearch,尝试使用为安全连接指定的端口连接到服务器.
  • 谢谢。 ldapsearch 也没有工作,因为证书验证失败。我正在更新我的帖子以提供更多详细信息

标签: c++ c windows ldap


【解决方案1】:

使用ldap_set_optionLDAP_OPT_SERVER_CERTIFICATE,您可以设置自定义callback-handler-function。此函数的结果决定您是否要接受/拒绝指定的证书。

static BOOLEAN IgnoreCertificateErrorsCallback (PLDAP /*pLdapConnection*/, PCCERT_CONTEXT* pServerCert) 
{
   CertFreeCertificateContext(*pServerCert);
   return true;
}

// snip
ldap_set_option(pLdapConnection, LDAP_OPT_SERVER_CERTIFICATE, &IgnoreCertificateErrorsCallback);

最好的建议是将证书放在 Windows 信任库 (certmgr.msc) 中,并且根本不要禁用任何安全功能。

【讨论】:

    【解决方案2】:

    尝试将以下环境变量传递给您的代码:

    LDAPTLS_REQCERT=never
    

    忽略可能过期或无效的服务器证书。

    【讨论】:

      猜你喜欢
      • 2013-08-31
      • 2014-02-23
      • 1970-01-01
      • 1970-01-01
      • 2012-09-24
      • 1970-01-01
      • 2017-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多