贝贝花花包包店,精品555皮具,钱夹,皮夹

字体: | 推荐给好友 上一篇 | 下一篇

Windows2000 服务器端应用程序开发设计指南-安全连接(3)

发布: 2008-5-01 14:21 | 作者: Jeffrey Richter Jaso | 来源: 网络转载 | 查看: 225次

BOOL SSLClientHandshakeAuth( 

CredHandle* phCredentials,
CredHandle* phCertCredentials,
PULONG plAttributes,
CtxtHandle* phContext,
PTSTR pszServer,
PBYTE pbExtraData,
PULONG pcbExtraData,
ULONG lSizeExtraDataBuf)
{
BOOL fSuccess = FALSE;
__try
{
// 设定我们自己的凭证handle副本
CredHandle credsUse;
CopyMemory(&credsUse, phCredentials, sizeof(credsUse));
// 就区域变数的可读性设定缓冲器
ULONG lEndBufIndex = *pcbExtraData;
ULONG lBufMaxSize = lSizeExtraDataBuf;
PBYTE pbData = pbExtraData;
// 宣告输入及输出缓冲器
SecBuffer secBufferOut;
SecBufferDesc secBufDescriptorOut;
SecBuffer secBufferIn[2];
SecBufferDesc secBufDescriptorIn;
// 设定回圈状态资讯
BOOL fFirstPass = TRUE;
SECURITY_STATUS ss = SEC_I_CONTINUE_NEEDED;
while ((ss == SEC_I_CONTINUE_NEEDED) ||
(ss == SEC_E_INCOMPLETE_MESSAGE)){
// 每次操作可以读取多少资料
ULONG lReadBuffSize;
// 重新设定,假如我们不执行「不完整的」回圈
if (ss !=SEC_E_INCOMPLETE_MESSAGE){
// 为另一个Blob交换重新设定状态
lEndBufIndex = 0;
lReadBuffSize = lBufMaxSize;
}
// 有些东西我们只有在第一次传递后执行
if (!fFirstPass){
// 尽可能接收资料
ReceiveData(pbData+lEndBufIndex, &lReadBuffSize);
// 这是我们目前为止拥有的资料
lEndBufIndex += lReadBuffSize;
// 用我们当前的资料设定里面的缓冲器
secBufferIn[0].BufferType = SECBUFFER_TOKEN;
secBufferIn[0].cbBuffer = lEndBufIndex;
secBufferIn[0].pvBuffer = pbData;
// 变成一个SECBUFFER_EXTRA缓冲器,用来让
// 我们知道其后是否有附加资料
secBufferIn[1].BufferType = SECBUFFER_EMPTY;
secBufferIn[1].cbBuffer = 0;
secBufferIn[1].pvBuffer = NULL;
// 设定输入缓冲器描述项
secBufDescriptorIn.cBuffers = 2;
secBufDescriptorIn.pBuffers = secBufferIn;
secBufDescriptorIn.ulVersion = SECBUFFER_VERSION;
}
// 设定输出缓冲器(由SSPI分配)
secBufferOut.BufferType = SECBUFFER_TOKEN;
secBufferOut.cbBuffer = 0;
secBufferOut.pvBuffer = NULL;
// 设定输出缓冲器描述项
secBufDescriptorOut.cBuffers = 1;
secBufDescriptorOut.pBuffers = &secBufferOut;
secBufDescriptorOut.ulVersion = SECBUFFER_VERSION;
// 这个内部回圈处理那些没有要传送Blob资料的「持续情况」。
// 这种情况下,仍然有更多「区段」在我们最后必须处理的Blob
// 项目。
BOOL fNoOutBuffer;
do {
fNoOutBuffer = FALSE;
// Blob处理程序
ss =
InitializeSecurityContext(
&credsUse,
fFirstPass ? NULL : phContext,
fFirstPass ? pszServer : NULL,
*plAttributes|
ISC_REQ_ALLOCATE_MEMORY|ISC_REQ_STREAM,
0,
SECURITY_NATIVE_DREP,
fFirstPass ? NULL : &secBufDescriptorIn,
0,
phContext,
&secBufDescriptorOut,
plAttributes,
NULL);
// 有更多「区段」要处理吗?
if ((ss == SEC_I_CONTINUE_NEEDED) &&
(secBufferOut.cbBuffer == 0)){
fNoOutBuffer = TRUE; // 设定回圈状态
// 有多少资料被留下
ULONG lExtraData = secBufferIn[1].cbBuffer;
// 我们要把资料移动回缓冲器的开始处
MoveMemory(pbData,
pbData+(lEndBufIndex - lExtraData), lExtraData);
// 现在我们有新的lEndBufIndex
lEndBufIndex = lExtraData;
// 让我们重新设定输入缓冲器
secBufferIn[0].BufferType = SECBUFFER_TOKEN;
secBufferIn[0].cbBuffer = lEndBufIndex;
secBufferIn[0].pvBuffer = pbData;
secBufferIn[1].BufferType = SECBUFFER_EMPTY;
secBufferIn[1].cbBuffer = 0;
secBufferIn[1].pvBuffer = NULL;
}
if (ss == SEC_I_INCOMPLETE_CREDENTIALS){
// 服务器要求凭证
// 用凭证复制凭证
// 通常,我们会在这里呼叫AcquireCredentialsHandle函数
// 以获得新的凭证。
// 然而,我们已经在这个范例函数中传入
// 凭证。
CopyMemory(&credsUse, phCertCredentials, sizeof(credsUse));
// 此操作不需输入
secBufDescriptorIn.cBuffers = 0;
// 继续传输
fNoOutBuffer = TRUE; // 设定回圈状态
}
}while(fNoOutBuffer);
// 下一次从线路上可以读取多少资料进来而不会超出缓冲器范围
lReadBuffSize = lBufMaxSize - lEndBufIndex;
// 有资料要传送吗?
if (secBufferOut.cbBuffer!=0){
// 传送它
ULONG lOut = secBufferOut.cbBuffer;
SendData(secBufferOut.pvBuffer, lOut);
// 然后释放输出缓冲器
FreeContextBuffer(secBufferOut.pvBuffer );
}
if (ss != SEC_E_INCOMPLETE_MESSAGE){
fFirstPass = FALSE;
}
}
if(ss == SEC_E_OK){
int nIndex = 1;
while(secBufferIn[nIndex].BufferType
!= SECBUFFER_EXTRA && (nIndex-- != 0));
if((nIndex !=-1)&&(secBufferIn [nIndex ].cbBuffer !=0)){
*pcbExtraData = secBufferIn[nIndex].cbBuffer;
PBYTE pbTempBuf = pbData;
pbTempBuf += (lEndBufIndex - *pcbExtraData);
MoveMemory(pbExtraData, pbTempBuf, *pcbExtraData);
}
fSuccess = TRUE;
}
}__finally{}
return (fSuccess);
}

这些函数有几个方法与其Kerberos及NTLM副本不同。假如产生这些情形的话,这些函数会检查SEC_E_INCOMPLETE_MESSAGE的传回值,并且持续建立讯息缓冲器。

这些函数也与其副本不同,客户端函数会取得两个凭证handles。一个是匿名的凭证handle,另一个则是用客户端凭证建立的凭证handle(假如您没有客户端凭证,可以传递匿名handle的位址给他们)。这是因为客户端先提出它的匿名凭证,只有在服务器要求彼此验证时才会交换凭证。客户端会经由SEC_I_ INCOMPLETE_CREDENTIALS的回传值得知这个请求。


说明

53/5<12345>
 

评分:0

我来说两句

seccode