SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, uint32 fContextReq, uint32 Reserved1, uint32 TargetDataRep, PSecBufferDesc pInput, uint32 Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, uint32* pfContextAttr, PTimeStamp ptsExpiry) { NTLM_CONTEXT* context; SECURITY_STATUS status; CREDENTIALS* credentials; PSecBuffer input_buffer; PSecBuffer output_buffer; context = sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = ntlm_ContextNew(); if (fContextReq & ISC_REQ_CONFIDENTIALITY) context->confidentiality = true; credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); ntlm_SetContextIdentity(context, &credentials->identity); ntlm_SetContextWorkstation(context, "WORKSTATION"); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME); } if ((!pInput) || (context->state == NTLM_STATE_AUTHENTICATE)) { 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; if (context->state == NTLM_STATE_INITIAL) context->state = NTLM_STATE_NEGOTIATE; if (context->state == NTLM_STATE_NEGOTIATE) return ntlm_write_NegotiateMessage(context, output_buffer); return SEC_E_OUT_OF_SEQUENCE; } else { 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; if (context->state == NTLM_STATE_CHALLENGE) { status = ntlm_read_ChallengeMessage(context, input_buffer); 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; if (context->state == NTLM_STATE_AUTHENTICATE) return ntlm_write_AuthenticateMessage(context, output_buffer); } return SEC_E_OUT_OF_SEQUENCE; } return SEC_E_OUT_OF_SEQUENCE; }
SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { NTLM_CONTEXT* context; SECURITY_STATUS status; SSPI_CREDENTIALS* credentials; PSecBuffer input_buffer = NULL; PSecBuffer output_buffer = NULL; PSecBuffer channel_bindings = NULL; context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = ntlm_ContextNew(); if (!context) return SEC_E_INSUFFICIENT_MEMORY; if (fContextReq & ISC_REQ_CONFIDENTIALITY) context->confidentiality = TRUE; credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); context->credentials = credentials; if (context->Workstation.Length < 1) { if (ntlm_SetContextWorkstation(context, NULL) < 0) return SEC_E_INTERNAL_ERROR; } if (ntlm_SetContextServicePrincipalNameW(context, pszTargetName) < 0) return SEC_E_INTERNAL_ERROR; sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME); } if ((!pInput) || (context->state == NTLM_STATE_AUTHENTICATE)) { 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) return SEC_E_INVALID_TOKEN; if (output_buffer->cbBuffer < 1) return SEC_E_INVALID_TOKEN; if (context->state == NTLM_STATE_INITIAL) context->state = NTLM_STATE_NEGOTIATE; if (context->state == NTLM_STATE_NEGOTIATE) return ntlm_write_NegotiateMessage(context, output_buffer); return SEC_E_OUT_OF_SEQUENCE; } else { 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; channel_bindings = sspi_FindSecBuffer(pInput, SECBUFFER_CHANNEL_BINDINGS); if (channel_bindings) { context->Bindings.BindingsLength = channel_bindings->cbBuffer; context->Bindings.Bindings = (SEC_CHANNEL_BINDINGS*) channel_bindings->pvBuffer; } if (context->state == NTLM_STATE_CHALLENGE) { status = ntlm_read_ChallengeMessage(context, input_buffer); 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) return SEC_E_INVALID_TOKEN; if (output_buffer->cbBuffer < 1) return SEC_E_INSUFFICIENT_MEMORY; if (context->state == NTLM_STATE_AUTHENTICATE) return ntlm_write_AuthenticateMessage(context, output_buffer); } return SEC_E_OUT_OF_SEQUENCE; } return SEC_E_OUT_OF_SEQUENCE; }
SECURITY_STATUS ntlm_InitializeSecurityContext(CRED_HANDLE* phCredential, CTXT_HANDLE* phContext, char* pszTargetName, uint32 fContextReq, uint32 Reserved1, uint32 TargetDataRep, SEC_BUFFER_DESC* pInput, uint32 Reserved2, CTXT_HANDLE* phNewContext, SEC_BUFFER_DESC* pOutput, uint32* pfContextAttr, SEC_TIMESTAMP* ptsExpiry) { NTLM_CONTEXT* context; SECURITY_STATUS status; CREDENTIALS* credentials; SEC_BUFFER* input_sec_buffer; SEC_BUFFER* output_sec_buffer; context = sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = ntlm_ContextNew(); credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); ntlm_SetContextIdentity(context, &credentials->identity); ntlm_SetContextWorkstation(context, "WORKSTATION"); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NTLM_PACKAGE_NAME); } if ((!pInput) || (context->state == NTLM_STATE_AUTHENTICATE)) { if (!pOutput) return SEC_E_INVALID_TOKEN; if (pOutput->cBuffers < 1) return SEC_E_INVALID_TOKEN; output_sec_buffer = &pOutput->pBuffers[0]; if (output_sec_buffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; if (output_sec_buffer->cbBuffer < 1) return SEC_E_INSUFFICIENT_MEMORY; if (context->state == NTLM_STATE_INITIAL) context->state = NTLM_STATE_NEGOTIATE; if (context->state == NTLM_STATE_NEGOTIATE) return ntlm_write_NegotiateMessage(context, output_sec_buffer); return SEC_E_OUT_OF_SEQUENCE; } else { context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) return SEC_E_INVALID_HANDLE; if (!pInput) return SEC_E_INVALID_TOKEN; if (pInput->cBuffers < 1) return SEC_E_INVALID_TOKEN; input_sec_buffer = &pInput->pBuffers[0]; if (input_sec_buffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; if (input_sec_buffer->cbBuffer < 1) return SEC_E_INVALID_TOKEN; if (context->state == NTLM_STATE_CHALLENGE) { status = ntlm_read_ChallengeMessage(context, input_sec_buffer); if (!pOutput) return SEC_E_INVALID_TOKEN; if (pOutput->cBuffers < 1) return SEC_E_INVALID_TOKEN; output_sec_buffer = &pOutput->pBuffers[0]; if (output_sec_buffer->BufferType != SECBUFFER_TOKEN) return SEC_E_INVALID_TOKEN; if (output_sec_buffer->cbBuffer < 1) return SEC_E_INSUFFICIENT_MEMORY; if (context->state == NTLM_STATE_AUTHENTICATE) return ntlm_write_AuthenticateMessage(context, output_sec_buffer); } return SEC_E_OUT_OF_SEQUENCE; } return SEC_E_OK; }