/** * @see http://msdn.microsoft.com/en-us/library/windows/desktop/aa374707 */ SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) { NTLM_CONTEXT* context; SECURITY_STATUS status; SSPI_CREDENTIALS* credentials; PSecBuffer input_buffer; PSecBuffer output_buffer; context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = ntlm_ContextNew(); if (!context) return SEC_E_INSUFFICIENT_MEMORY; context->server = TRUE; if (fContextReq & ASC_REQ_CONFIDENTIALITY) context->confidentiality = TRUE; credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); context->credentials = credentials; ntlm_SetContextTargetName(context, NULL); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME); } if (context->state == NTLM_STATE_INITIAL) { context->state = NTLM_STATE_NEGOTIATE; if (!pInput) return SEC_E_INVALID_TOKEN; if (pInput->cBuffers < 1) return SEC_E_INVALID_TOKEN; input_buffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN); if (!input_buffer) return SEC_E_INVALID_TOKEN; if (input_buffer->cbBuffer < 1) return SEC_E_INVALID_TOKEN; status = ntlm_read_NegotiateMessage(context, input_buffer); if (context->state == NTLM_STATE_CHALLENGE) { if (!pOutput) return SEC_E_INVALID_TOKEN; if (pOutput->cBuffers < 1) return SEC_E_INVALID_TOKEN; output_buffer = sspi_FindSecBuffer(pOutput, SECBUFFER_TOKEN); if (!output_buffer->BufferType) return SEC_E_INVALID_TOKEN; if (output_buffer->cbBuffer < 1) return SEC_E_INSUFFICIENT_MEMORY; return ntlm_write_ChallengeMessage(context, output_buffer); } return SEC_E_OUT_OF_SEQUENCE; } else if (context->state == NTLM_STATE_AUTHENTICATE) { if (!pInput) return SEC_E_INVALID_TOKEN; if (pInput->cBuffers < 1) return SEC_E_INVALID_TOKEN; input_buffer = sspi_FindSecBuffer(pInput, SECBUFFER_TOKEN); if (!input_buffer) return SEC_E_INVALID_TOKEN; if (input_buffer->cbBuffer < 1) return SEC_E_INVALID_TOKEN; status = ntlm_read_AuthenticateMessage(context, input_buffer); if (pOutput) { ULONG i; for (i = 0; i < pOutput->cBuffers; i++) { pOutput->pBuffers[i].cbBuffer = 0; pOutput->pBuffers[i].BufferType = SECBUFFER_TOKEN; } } return status; } return SEC_E_OUT_OF_SEQUENCE; }
SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, uint32 fContextReq, uint32 TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, uint32* pfContextAttr, PTimeStamp ptsTimeStamp) { NTLM_CONTEXT* context; SECURITY_STATUS status; CREDENTIALS* credentials; PSecBuffer input_buffer; PSecBuffer output_buffer; context = sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = ntlm_ContextNew(); context->server = true; credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); ntlm_SetContextIdentity(context, &credentials->identity); ntlm_SetContextTargetName(context, "FreeRDP"); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME); } if (context->state == NTLM_STATE_INITIAL) { context->state = NTLM_STATE_NEGOTIATE; if (!context) return SEC_E_INVALID_HANDLE; if (!pInput) return SEC_E_INVALID_TOKEN; if (pInput->cBuffers < 1) return SEC_E_INVALID_TOKEN; input_buffer = &pInput->pBuffers[0]; if (input_buffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; if (input_buffer->cbBuffer < 1) return SEC_E_INVALID_TOKEN; status = ntlm_read_NegotiateMessage(context, input_buffer); if (context->state == NTLM_STATE_CHALLENGE) { if (!pOutput) return SEC_E_INVALID_TOKEN; if (pOutput->cBuffers < 1) return SEC_E_INVALID_TOKEN; output_buffer = &pOutput->pBuffers[0]; if (output_buffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; if (output_buffer->cbBuffer < 1) return SEC_E_INSUFFICIENT_MEMORY; return ntlm_write_ChallengeMessage(context, output_buffer); } return SEC_E_OUT_OF_SEQUENCE; } else if (context->state == NTLM_STATE_AUTHENTICATE) { if (!context) return SEC_E_INVALID_HANDLE; if (!pInput) return SEC_E_INVALID_TOKEN; if (pInput->cBuffers < 1) return SEC_E_INVALID_TOKEN; input_buffer = &pInput->pBuffers[0]; if (input_buffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; if (input_buffer->cbBuffer < 1) return SEC_E_INVALID_TOKEN; status = ntlm_read_AuthenticateMessage(context, input_buffer); return status; } return SEC_E_OUT_OF_SEQUENCE; }