diff --git a/dlls/secur32/ntlm.c b/dlls/secur32/ntlm.c index 79241561eb2..5041892f2de 100644 --- a/dlls/secur32/ntlm.c +++ b/dlls/secur32/ntlm.c @@ -380,6 +380,26 @@ static int ntlm_GetTokenBufferIndex(PSecBufferDesc pMessage) return -1; } +/************************************************************************* + * ntlm_GetDataBufferIndex + * Calculates the index of the first secbuffer with BufferType == SECBUFFER_DATA + * Returns index if found or -1 if not found. + */ +static int ntlm_GetDataBufferIndex(PSecBufferDesc pMessage) +{ + UINT i; + + TRACE("%p\n", pMessage); + + for( i = 0; i < pMessage->cBuffers; ++i ) + { + if(pMessage->pBuffers[i].BufferType == SECBUFFER_DATA) + return i; + } + + return -1; +} + /*********************************************************************** * InitializeSecurityContextW */ @@ -1609,7 +1629,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { PNegoHelper helper; - int token_idx; + int token_idx, data_idx; TRACE("(%p %d %p %d)\n", phContext, fQOP, pMessage, MessageSeqNo); @@ -1628,6 +1648,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1) return SEC_E_INVALID_TOKEN; + if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1 ) + return SEC_E_INVALID_TOKEN; + if(pMessage->pBuffers[token_idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL; @@ -1638,8 +1661,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, { ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, FALSE); SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i, - (BYTE *)pMessage->pBuffers[1].pvBuffer, - pMessage->pBuffers[1].cbBuffer); + (BYTE *)pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); if(helper->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCHANGE) SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i, @@ -1662,8 +1685,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, sig = pMessage->pBuffers[token_idx].pvBuffer; - SECUR32_arc4Process(helper->crypt.ntlm.a4i, pMessage->pBuffers[1].pvBuffer, - pMessage->pBuffers[1].cbBuffer); + SECUR32_arc4Process(helper->crypt.ntlm.a4i, + pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); SECUR32_arc4Process(helper->crypt.ntlm.a4i, sig+4, 12); if(helper->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN || helper->neg_flags == 0) @@ -1683,7 +1707,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, SECURITY_STATUS ret; ULONG ntlmssp_flags_save; PNegoHelper helper; - int token_idx; + int token_idx, data_idx; TRACE("(%p %p %d %p)\n", phContext, pMessage, MessageSeqNo, pfQOP); if(!phContext) @@ -1698,6 +1722,9 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1) return SEC_E_INVALID_TOKEN; + if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1) + return SEC_E_INVALID_TOKEN; + if(pMessage->pBuffers[token_idx].cbBuffer < 16) return SEC_E_BUFFER_TOO_SMALL; @@ -1706,12 +1733,14 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, if(helper->neg_flags & NTLMSSP_NEGOTIATE_NTLM2 && helper->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { SECUR32_arc4Process(helper->crypt.ntlm2.recv_a4i, - pMessage->pBuffers[1].pvBuffer, pMessage->pBuffers[1].cbBuffer); + pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); } else { SECUR32_arc4Process(helper->crypt.ntlm.a4i, - pMessage->pBuffers[1].pvBuffer, pMessage->pBuffers[1].cbBuffer); + pMessage->pBuffers[data_idx].pvBuffer, + pMessage->pBuffers[data_idx].cbBuffer); } /* Make sure we use a session key for the signature check, EncryptMessage