繁体   English   中英

SASL使用带有ldap_sasl_bind_s函数的Kerberos凭证通过GSSAPI进行绑定

[英]SASL bind over GSSAPI using kerberos credentials with ldap_sasl_bind_s function

我正在尝试使用带有ldap_sasl_bind_s函数的kerberos凭据在GSSAPI上实现SASL绑定。 我遵循ldap_sasl_bind_s(GSSAPI)中描述的步骤-凭证BERVAL结构链中应提供什么

我得到了提到的链中描述的所有调用的预期返回值,直到对ldap_sasl_bind_s的最后(第三次)调用为止,该调用失败,并出现LDAP_INVALID_CREDENTIALS错误。 我也看到Windows事件查看器中发生以下错误

Error value:
80090308: LdapErr: DSID-0C0904D1, comment: AcceptSecurityContext error, data 5, v1771

请注意,我有两个应用程序,我们将它们称为客户端和服务器,客户端在某个Active Domain帐户下运行,服务器应用程序从客户端接收凭据,并尝试使用客户端提供的令牌绑定到ldap。 这是我要做的步骤。 客户来电

int res = AcquireCredentialsHandle(NULL, "Kerberos"  , SECPKG_CRED_BOTH,NULL, NULL, NULL, NULL, &credhandle1, &expry1); 

填充credhandle1之后,我再次将其传递给客户端的InitializeSecurityContext的第一个调用

  res = InitializeSecurityContext(&credhandle1,NULL,(SEC_CHAR*)(&spn1[0]),ISC_REQ_INTEGRITY|ISC_REQ_MUTUAL_AUTH|ISC_REQ_SEQUENCE_DETECT|ISC_REQ_CONFIDENTIALITY|ISC_REQ_DELEGATE,0,SECURITY_NATIVE_DREP ,NULL,0,&NewContext2,&sec_buffer_desc1,&contextattr2,&expry2);

我使用活动目录设置中可用的spn-s之一。 此调用返回SEC_I_CONTINUE_NEEDED,并填充sec_buffer_desc1,然后将其传递到我的服务器应用程序,以使用构造的令牌调用ldap_sasl_bind_s。

第一次调用ldap_sasl_bind_s返回LDAP_SUCCESS,并填充struct berval * servresp,这是调用

rc1 = ldap_sasl_bind_s(ld1, "", "GSSAPI", &cred1, NULL, NULL, &servresp);

servresp中的令牌被传递到客户端应用程序,该应用程序按如下所示进行InitializeSecurityContext的第二次调用

res = InitializeSecurityContext(&credhandle1, &NewContext2, (SEC_CHAR*)(&spn1[0]),ISC_REQ_INTEGRITY|ISC_REQ_MUTUAL_AUTH|ISC_REQ_SEQUENCE_DETECT|ISC_REQ_CONFIDENTIALITY|ISC_REQ_DELEGATE,0, 0, &InBuffDesc3, 0, &NewContext3, &sec_buffer_desc3, &contextattr3, &expry3);

InBuffDesc3包含从服务器返回的凭据。 该调用返回SEC_E_OK,并在sec_buffer_desc3中产生了空的输出​​令牌,该令牌传递到服务器,服务器第二次调用ldap_sasl_bind_s

rc1 = ldap_sasl_bind_s(ld1, "", "GSSAPI", &cred2, NULL, NULL, &servresp2);

此调用再次返回LDAP_SUCCESS,并用32字节长的令牌填充servresp2,然后将其传递给客户端。 服务器中的最后一条错误消息是LDAP_SASL_BIND_IN_PROGRESS。

我将第一个参数传递给DecryptMessage NewContext2(在InitSecContext调用中接收到)。 作为第二个参数传递给DecryptMessage的BuffDesc包含指向两个SecBuffer对象的指针,SecBuffer [0]的类型为SECBUFFER_STREAM,并且包含服务器响应(由第二次调用ldap_sasl_bind_s生成的令牌),而SecBuffer [1]的类型为SECBUFFER_DATA。在DecryptMessage调用之后,SecBuffer [1] ]被一些令牌填充(它的大小也正在更改,所以我认为它包含解密的消息)。 解密消息后,DecryptMessage的第三个参数为0,最后一个由SECQOP_WRAP_NO_ENCRYPT值填充。 这是电话

ULONG ulQop;
res = DecryptMessage( &NewContext2, &BuffDesc, 0, &ulQop); 

在传递给DecryptMessage的SECBUFFER_DATA缓冲区中,我收到4个字节长的令牌(似乎是输入SECBUFFER_STREAM缓冲区的最后4个字节)。 “解密的消息(SecBuff [1] .pvBuffer)”的第一个字节为7,然后执行以下操作

    unsigned char * ptr = (unsigned char *)SecBuff[1].pvBuffer;
    int maxsize = (ptr[1]<<16) | (ptr[2]<<8)| (ptr[3]);
    ptr = (unsigned char *) malloc(4);
    ptr[0]= 4;
    ptr[1]= maxsize>>16;
    ptr[2]= maxsize>>8;
    ptr[3]= maxsize; 

我正在使用三个缓冲区构造EncryptMessage的输入SecBufferDesc对象,第一个缓冲区的类型为SECBUFFER_TOKEN,在EncryptMEssage调用后填充(因此,我认为此调用后它包含加密的消息),第二个缓冲区的类型为SECBUFFER_DATA,并且包含我在上面构造的ptr ,以及类型为SECBUFFER_PADDING的第三个缓冲区。 我按如下方式调用EncryptMessage

err = EncryptMessage(&NewContext2,fQOP,&inSecBufDescSecond, 0);

它返回SEC_E_OK,并在缓冲区中生成类型为SECBUFFER_TOKEN的28字节长的令牌,然后将此输出令牌传递到我的服务器应用程序,该应用程序使用此令牌作为客户端凭据来调用ldap_sasl_bind_s,并因无效的凭据错误而失败。

我看着帖子中提到的RFC,它也试图找到具有SASL和kerberos凭据的任何有效示例,但是无法处理此错误。 任何帮助将不胜感激,请您帮助我解决这个问题,或者提供一些工作代码示例,以便我看看。

谢谢 ! -格里高

我遇到了完全相同的问题,我想我找到了解决方案:

您在第三个ldap_sasl_bind_s调用中发送的消息应该是分配给EncryptMessage的所有三个缓冲区的串联(顺序为TOKEN,DATA,PADDING)

当我这样做时,它会起作用!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM