SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, uint32 fCredentialUse, void* pvLogonID, void* pAuthData, void* pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { CREDENTIALS* credentials; SEC_WINNT_AUTH_IDENTITY* identity; if (fCredentialUse == SECPKG_CRED_OUTBOUND) { credentials = sspi_CredentialsNew(); identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; memcpy(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); return SEC_E_OK; } else if (fCredentialUse == SECPKG_CRED_INBOUND) { credentials = sspi_CredentialsNew(); identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; memcpy(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); return SEC_E_OK; } return SEC_E_OK; }
SECURITY_STATUS SEC_ENTRY schannel_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) { SECURITY_STATUS status; SCHANNEL_CONTEXT* context; SCHANNEL_CREDENTIALS* credentials; status = SEC_E_OK; context = (SCHANNEL_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = schannel_ContextNew(); if (!context) return SEC_E_INSUFFICIENT_MEMORY; credentials = (SCHANNEL_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); context->server = TRUE; sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) SCHANNEL_PACKAGE_NAME); schannel_openssl_server_init(context->openssl); } status = schannel_openssl_server_process_tokens(context->openssl, pInput, pOutput); return status; }
static SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { CREDSSP_CONTEXT* context; SSPI_CREDENTIALS* credentials; context = (CREDSSP_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = credssp_ContextNew(); if (!context) return SEC_E_INSUFFICIENT_MEMORY; credentials = (SSPI_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); if (!credentials) { credssp_ContextFree(context); return SEC_E_INVALID_HANDLE; } sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) CREDSSP_PACKAGE_NAME); } return SEC_E_OK; }
SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) { SECURITY_STATUS status; NEGOTIATE_CONTEXT* context; context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = negotiate_ContextNew(); if (!context) return SEC_E_INTERNAL_ERROR; sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGO_SSP_NAME); } negotiate_SetSubPackage(context, (const char*) NTLM_SSP_NAME); /* server-side Kerberos not yet implemented */ status = context->sspiA->AcceptSecurityContext(phCredential, &(context->SubContext), pInput, fContextReq, TargetDataRep, &(context->SubContext), pOutput, pfContextAttr, ptsTimeStamp); if (status != SEC_E_OK) { WLog_WARN(TAG, "AcceptSecurityContext status %s [0x%08"PRIX32"]", GetSecurityStatusString(status), status); } return status; }
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS status; NEGOTIATE_CONTEXT* context; context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = negotiate_ContextNew(); if (!context) return SEC_E_INTERNAL_ERROR; sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOTIATE_PACKAGE_NAME); } status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext), pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext), pOutput, pfContextAttr, ptsExpiry); return status; }
SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SSPI_CREDENTIALS* credentials; SEC_WINNT_AUTH_IDENTITY* identity; if ((fCredentialUse != SECPKG_CRED_OUTBOUND) && (fCredentialUse != SECPKG_CRED_INBOUND) && (fCredentialUse != SECPKG_CRED_BOTH)) { return SEC_E_INVALID_PARAMETER; } credentials = sspi_CredentialsNew(); if (!credentials) return SEC_E_INTERNAL_ERROR; credentials->fCredentialUse = fCredentialUse; credentials->pGetKeyFn = pGetKeyFn; credentials->pvGetKeyArgument = pvGetKeyArgument; identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; if (identity) sspi_CopyAuthIdentity(&(credentials->identity), identity); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); return SEC_E_OK; }
SECURITY_STATUS SEC_ENTRY schannel_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) { SECURITY_STATUS status; SCHANNEL_CONTEXT* context; SCHANNEL_CREDENTIALS* credentials; context = sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = schannel_ContextNew(); if (!context) return SEC_E_INSUFFICIENT_MEMORY; credentials = (SCHANNEL_CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); context->server = FALSE; CopyMemory(&context->cred, &credentials->cred, sizeof(SCHANNEL_CRED)); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) SCHANNEL_PACKAGE_NAME); schannel_openssl_client_init(context->openssl); } status = schannel_openssl_client_process_tokens(context->openssl, pInput, pOutput); return status; }
SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp) { SECURITY_STATUS status; NEGOTIATE_CONTEXT* context; context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = negotiate_ContextNew(); if (!context) return SEC_E_INTERNAL_ERROR; sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOTIATE_PACKAGE_NAME); } status = context->sspiA->AcceptSecurityContext(phCredential, &(context->SubContext), pInput, fContextReq, TargetDataRep, &(context->SubContext), pOutput, pfContextAttr, ptsTimeStamp); if (status != SEC_E_OK) { WLog_WARN(TAG, "AcceptSecurityContext status %s [%08X]", GetSecurityStatusString(status), status); } return status; }
SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { SECURITY_STATUS status; NEGOTIATE_CONTEXT* context; context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = negotiate_ContextNew(); if (!context) return SEC_E_INTERNAL_ERROR; sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGO_SSP_NAME); } /* if Kerberos has previously failed or WITH_GSSAPI is not defined, we use NTLM directly */ if (ErrorInitContextKerberos == FALSE) { if (!pInput) { negotiate_SetSubPackage(context, (const char*) KERBEROS_SSP_NAME); } status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext), pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext), pOutput, pfContextAttr, ptsExpiry); if (status == SEC_E_NO_CREDENTIALS) { WLog_WARN(TAG, "No Kerberos credentials. Retry with NTLM"); ErrorInitContextKerberos = TRUE; context->sspiA->DeleteSecurityContext(&(context->SubContext)); negotiate_ContextFree(context); return status; } } else { if (!pInput) { context->sspiA->DeleteSecurityContext(&(context->SubContext)); negotiate_SetSubPackage(context, (const char*) NTLM_SSP_NAME); } status = context->sspiA->InitializeSecurityContextA(phCredential, &(context->SubContext), pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput, Reserved2, &(context->SubContext), pOutput, pfContextAttr, ptsExpiry); } return status; }
SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SCHANNEL_CREDENTIALS* credentials; if (fCredentialUse == SECPKG_CRED_OUTBOUND) { SCHANNEL_CRED* cred; credentials = schannel_CredentialsNew(); credentials->fCredentialUse = fCredentialUse; cred = (SCHANNEL_CRED*) pAuthData; if (cred) { CopyMemory(&credentials->cred, cred, sizeof(SCHANNEL_CRED)); } sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) SCHANNEL_PACKAGE_NAME); return SEC_E_OK; } else if (fCredentialUse == SECPKG_CRED_INBOUND) { credentials = schannel_CredentialsNew(); credentials->fCredentialUse = fCredentialUse; sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) SCHANNEL_PACKAGE_NAME); return SEC_E_OK; } return SEC_E_OK; }
void negotiate_SetSubPackage(NEGOTIATE_CONTEXT* context, const char* name) { if (strcmp(name, KERBEROS_SSP_NAME) == 0) { context->sspiA = (SecurityFunctionTableA*) &KERBEROS_SecurityFunctionTableA; context->sspiW = (SecurityFunctionTableW*) &KERBEROS_SecurityFunctionTableW; context->kerberos = TRUE; } else { context->sspiA = (SecurityFunctionTableA*) &NTLM_SecurityFunctionTableA; context->sspiW = (SecurityFunctionTableW*) &NTLM_SecurityFunctionTableW; context->kerberos = FALSE; } sspi_SecureHandleSetLowerPointer(&(context->SubContext), NULL); sspi_SecureHandleSetUpperPointer(&(context->SubContext), NULL); }
SECURITY_STATUS SEC_ENTRY negotiate_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) { NEGOTIATE_CONTEXT* context; //SECURITY_STATUS status; CREDENTIALS* credentials; //PSecBuffer input_SecBuffer; PSecBuffer output_SecBuffer; //KrbTGTREQ krb_tgtreq; context = sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = negotiate_ContextNew(); credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); negotiate_SetContextIdentity(context, &credentials->identity); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) NEGOTIATE_PACKAGE_NAME); } if((!pInput) && (context->state == NEGOTIATE_STATE_INITIAL)) { if (!pOutput) return SEC_E_INVALID_TOKEN; if (pOutput->cBuffers < 1) return SEC_E_INVALID_TOKEN; output_SecBuffer = &pOutput->pBuffers[0]; if (output_SecBuffer->cbBuffer < 1) return SEC_E_INSUFFICIENT_MEMORY; } return SEC_E_OK; }
SECURITY_STATUS ntlm_AcquireCredentialsHandle(char* pszPrincipal, char* pszPackage, uint32 fCredentialUse, void* pvLogonID, void* pAuthData, void* pGetKeyFn, void* pvGetKeyArgument, CRED_HANDLE* phCredential, SEC_TIMESTAMP* ptsExpiry) { CREDENTIALS* credentials; SEC_AUTH_IDENTITY* identity; if (fCredentialUse == SECPKG_CRED_OUTBOUND) { credentials = sspi_CredentialsNew(); identity = (SEC_AUTH_IDENTITY*) pAuthData; memcpy(&(credentials->identity), identity, sizeof(SEC_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) NTLM_PACKAGE_NAME); return SEC_E_OK; } return SEC_E_OK; }
SECURITY_STATUS SEC_ENTRY schannel_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry) { SCHANNEL_CONTEXT* context; CREDENTIALS* credentials; context = sspi_SecureHandleGetLowerPointer(phContext); if (!context) { context = schannel_ContextNew(); credentials = (CREDENTIALS*) sspi_SecureHandleGetLowerPointer(phCredential); sspi_SecureHandleSetLowerPointer(phNewContext, context); sspi_SecureHandleSetUpperPointer(phNewContext, (void*) SCHANNEL_PACKAGE_NAME); } return SEC_E_OK; }
static SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SSPI_CREDENTIALS* credentials; SEC_WINNT_AUTH_IDENTITY* identity; if (fCredentialUse == SECPKG_CRED_OUTBOUND) { credentials = sspi_CredentialsNew(); if (!credentials) return SEC_E_INSUFFICIENT_MEMORY; identity = (SEC_WINNT_AUTH_IDENTITY*) pAuthData; CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY)); sspi_SecureHandleSetLowerPointer(phCredential, (void*) credentials); sspi_SecureHandleSetUpperPointer(phCredential, (void*) CREDSSP_PACKAGE_NAME); return SEC_E_OK; } return SEC_E_UNSUPPORTED_FUNCTION; }
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; }
/** * @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_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_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; }
PCtxtHandle krbctx_client_init(rdpSettings* settings, SEC_WINNT_AUTH_IDENTITY* identity) { SECURITY_STATUS status; KDCENTRY* kdclist; KDCENTRY* entry; KRB_CONTEXT* krb_ctx; uint32 fContextReq; uint32 pfContextAttr; TimeStamp expiration; if (tcp_is_ipaddr(settings->hostname)) return NULL; kdclist = krb_locate_kdc(settings); /* start the state machine with initialized to zero */ krb_ctx = kerberos_ContextNew(); for (entry = kdclist;entry != NULL; entry = entry->next) { if(!krb_tcp_connect(krb_ctx, entry)) break; } if (entry == NULL) { xfree(krb_ctx); return NULL; } krb_SetContextIdentity(krb_ctx, identity); krb_ctx->realm = xstrtoup(settings->kerberos_realm); krb_ctx->cname = xstrdup((char*)krb_ctx->identity.User); krb_ctx->settings = settings; krb_ctx->passwd.data = freerdp_uniconv_out(krb_ctx->uniconv, (char*) krb_ctx->identity.Password, (size_t*) &(krb_ctx->passwd.length)); fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT | ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE; sspi_SecureHandleSetLowerPointer(&krb_ctx->context, krb_ctx); sspi_SecureHandleSetUpperPointer(&krb_ctx->context, (void*) KRB_PACKAGE_NAME); status = kerberos_InitializeSecurityContextA(NULL, &krb_ctx->context, NULL, fContextReq, 0, SECURITY_NATIVE_DREP, NULL, 0, &krb_ctx->context, NULL, &pfContextAttr, &expiration); if(status == SEC_E_INVALID_HANDLE) { printf("failed to init kerberos\n"); return NULL; } else if(status == SEC_I_COMPLETE_AND_CONTINUE) { printf("successfully obtained ticket for TERMSRV\n"); return &krb_ctx->context; } else if(status == -1) { printf("deadend \n "); return NULL; } else { printf("shit got wrong in state machine\n"); return NULL; } }
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; }