libwinpr-sspi: add support for querying user+domain and setting NTLM hash
This commit is contained in:
parent
723e9a171b
commit
1b93dca6c0
@ -994,6 +994,29 @@ extern "C" {
|
||||
|
||||
/* Custom API */
|
||||
|
||||
#define SECPKG_ATTR_AUTH_IDENTITY 1001
|
||||
#define SECPKG_ATTR_AUTH_PASSWORD 1002
|
||||
#define SECPKG_ATTR_AUTH_NTLM_HASH 1003
|
||||
|
||||
struct _SecPkgContext_AuthIdentity
|
||||
{
|
||||
char User[256 + 1];
|
||||
char Domain[256 + 1];
|
||||
};
|
||||
typedef struct _SecPkgContext_AuthIdentity SecPkgContext_AuthIdentity;
|
||||
|
||||
struct _SecPkgContext_AuthPassword
|
||||
{
|
||||
char Password[256 + 1];
|
||||
};
|
||||
typedef struct _SecPkgContext_AuthPassword SecPkgContext_AuthPassword;
|
||||
|
||||
struct _SecPkgContext_AuthNtlmHash
|
||||
{
|
||||
BYTE NtlmHash[16];
|
||||
};
|
||||
typedef struct _SecPkgContext_AuthNtlmHash SecPkgContext_AuthNtlmHash;
|
||||
|
||||
#define SSPI_INTERFACE_WINPR 0x00000001
|
||||
#define SSPI_INTERFACE_NATIVE 0x00000002
|
||||
|
||||
|
@ -363,8 +363,10 @@ int ConvertFromUnicode(UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int
|
||||
status = WideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar,
|
||||
*lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar);
|
||||
|
||||
if (status != cbMultiByte)
|
||||
if ((status != cbMultiByte) && allocate)
|
||||
{
|
||||
status = 0;
|
||||
}
|
||||
|
||||
if ((status <= 0) && allocate)
|
||||
{
|
||||
|
@ -609,7 +609,20 @@ SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredenti
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
NTLM_CONTEXT* context;
|
||||
SECURITY_STATUS status = SEC_E_OK;
|
||||
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!context)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (context->server)
|
||||
{
|
||||
status = ntlm_server_AuthenticateComplete(context);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa375354 */
|
||||
@ -632,12 +645,16 @@ SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
NTLM_CONTEXT* context;
|
||||
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (ulAttribute == SECPKG_ATTR_SIZES)
|
||||
{
|
||||
SecPkgContext_Sizes* ContextSizes = (SecPkgContext_Sizes*) pBuffer;
|
||||
@ -649,6 +666,35 @@ SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, UL
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
else if (ulAttribute == SECPKG_ATTR_AUTH_IDENTITY)
|
||||
{
|
||||
int status;
|
||||
char* UserA = NULL;
|
||||
char* DomainA = NULL;
|
||||
SSPI_CREDENTIALS* credentials;
|
||||
SecPkgContext_AuthIdentity* AuthIdentity = (SecPkgContext_AuthIdentity*) pBuffer;
|
||||
|
||||
credentials = context->credentials;
|
||||
ZeroMemory(AuthIdentity, sizeof(SecPkgContext_AuthIdentity));
|
||||
|
||||
UserA = AuthIdentity->User;
|
||||
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) credentials->identity.User,
|
||||
credentials->identity.UserLength,
|
||||
&UserA, 256, NULL, NULL);
|
||||
|
||||
if (status <= 0)
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
DomainA = AuthIdentity->Domain;
|
||||
status = ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) credentials->identity.Domain,
|
||||
credentials->identity.DomainLength,
|
||||
&DomainA, 256, NULL, NULL);
|
||||
|
||||
if (status <= 0)
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
@ -658,6 +704,38 @@ SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, UL
|
||||
return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY ntlm_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer)
|
||||
{
|
||||
NTLM_CONTEXT* context;
|
||||
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INVALID_PARAMETER;
|
||||
|
||||
context = (NTLM_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (ulAttribute == SECPKG_ATTR_AUTH_NTLM_HASH)
|
||||
{
|
||||
SecPkgContext_AuthNtlmHash* AuthNtlmHash = (SecPkgContext_AuthNtlmHash*) pBuffer;
|
||||
|
||||
if (cbBuffer < sizeof(SecPkgContext_AuthNtlmHash))
|
||||
return SEC_E_INVALID_PARAMETER;
|
||||
|
||||
CopyMemory(context->NtlmHash, AuthNtlmHash->NtlmHash, 16);
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
||||
return SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY ntlm_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer)
|
||||
{
|
||||
return ntlm_SetContextAttributesW(phContext, ulAttribute, pBuffer, cbBuffer);
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext(PCtxtHandle phContext)
|
||||
{
|
||||
return SEC_E_OK;
|
||||
@ -883,7 +961,7 @@ const SecurityFunctionTableA NTLM_SecurityFunctionTableA =
|
||||
NULL, /* QuerySecurityContextToken */
|
||||
ntlm_EncryptMessage, /* EncryptMessage */
|
||||
ntlm_DecryptMessage, /* DecryptMessage */
|
||||
NULL, /* SetContextAttributes */
|
||||
ntlm_SetContextAttributesA, /* SetContextAttributes */
|
||||
};
|
||||
|
||||
const SecurityFunctionTableW NTLM_SecurityFunctionTableW =
|
||||
@ -915,7 +993,7 @@ const SecurityFunctionTableW NTLM_SecurityFunctionTableW =
|
||||
NULL, /* QuerySecurityContextToken */
|
||||
ntlm_EncryptMessage, /* EncryptMessage */
|
||||
ntlm_DecryptMessage, /* DecryptMessage */
|
||||
NULL, /* SetContextAttributes */
|
||||
ntlm_SetContextAttributesA, /* SetContextAttributes */
|
||||
};
|
||||
|
||||
const SecPkgInfoA NTLM_SecPkgInfoA =
|
||||
|
@ -80,6 +80,7 @@ enum _NTLM_STATE
|
||||
NTLM_STATE_NEGOTIATE,
|
||||
NTLM_STATE_CHALLENGE,
|
||||
NTLM_STATE_AUTHENTICATE,
|
||||
NTLM_STATE_COMPLETION,
|
||||
NTLM_STATE_FINAL
|
||||
};
|
||||
typedef enum _NTLM_STATE NTLM_STATE;
|
||||
@ -262,6 +263,7 @@ struct _NTLM_CONTEXT
|
||||
SecBuffer TargetName;
|
||||
SecBuffer NtChallengeResponse;
|
||||
SecBuffer LmChallengeResponse;
|
||||
NTLMv2_RESPONSE NTLMv2Response;
|
||||
BYTE Timestamp[8];
|
||||
BYTE ChallengeTimestamp[8];
|
||||
BYTE ServerChallenge[8];
|
||||
@ -276,6 +278,7 @@ struct _NTLM_CONTEXT
|
||||
BYTE ServerSigningKey[16];
|
||||
BYTE ServerSealingKey[16];
|
||||
BYTE MessageIntegrityCheck[16];
|
||||
UINT32 MessageIntegrityCheckOffset;
|
||||
};
|
||||
typedef struct _NTLM_CONTEXT NTLM_CONTEXT;
|
||||
|
||||
|
@ -671,20 +671,16 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
wStream* s;
|
||||
int length;
|
||||
UINT32 flags;
|
||||
UINT32 MicOffset;
|
||||
NTLM_AV_PAIR* AvFlags;
|
||||
NTLMv2_RESPONSE response;
|
||||
UINT32 PayloadBufferOffset;
|
||||
NTLM_AUTHENTICATE_MESSAGE* message;
|
||||
SSPI_CREDENTIALS* credentials = context->credentials;
|
||||
|
||||
flags = 0;
|
||||
MicOffset = 0;
|
||||
AvFlags = NULL;
|
||||
|
||||
message = &context->AUTHENTICATE_MESSAGE;
|
||||
ZeroMemory(message, sizeof(NTLM_AUTHENTICATE_MESSAGE));
|
||||
ZeroMemory(&response, sizeof(NTLMv2_RESPONSE));
|
||||
|
||||
s = Stream_New((BYTE*) buffer->pvBuffer, buffer->cbBuffer);
|
||||
|
||||
@ -759,7 +755,7 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
if (!snt)
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
if (ntlm_read_ntlm_v2_response(snt, &response) < 0)
|
||||
if (ntlm_read_ntlm_v2_response(snt, &(context->NTLMv2Response)) < 0)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
|
||||
Stream_Free(snt, FALSE);
|
||||
@ -768,12 +764,12 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
context->NtChallengeResponse.cbBuffer = message->NtChallengeResponse.Len;
|
||||
|
||||
sspi_SecBufferFree(&(context->ChallengeTargetInfo));
|
||||
context->ChallengeTargetInfo.pvBuffer = (void*) response.Challenge.AvPairs;
|
||||
context->ChallengeTargetInfo.pvBuffer = (void*) context->NTLMv2Response.Challenge.AvPairs;
|
||||
context->ChallengeTargetInfo.cbBuffer = message->NtChallengeResponse.Len - (28 + 16);
|
||||
|
||||
CopyMemory(context->ClientChallenge, response.Challenge.ClientChallenge, 8);
|
||||
CopyMemory(context->ClientChallenge, context->NTLMv2Response.Challenge.ClientChallenge, 8);
|
||||
|
||||
AvFlags = ntlm_av_pair_get(response.Challenge.AvPairs, MsvAvFlags);
|
||||
AvFlags = ntlm_av_pair_get(context->NTLMv2Response.Challenge.AvPairs, MsvAvFlags);
|
||||
|
||||
if (AvFlags)
|
||||
flags = *((UINT32*) ntlm_av_pair_get_value_pointer(AvFlags));
|
||||
@ -796,7 +792,7 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
MicOffset = Stream_GetPosition(s);
|
||||
context->MessageIntegrityCheckOffset = (UINT32) Stream_GetPosition(s);
|
||||
|
||||
if (Stream_GetRemainingLength(s) < 16)
|
||||
return SEC_E_INVALID_TOKEN;
|
||||
@ -851,178 +847,11 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
credentials->identity.DomainLength = message->DomainName.Len / 2;
|
||||
}
|
||||
|
||||
/* Computations beyond this point require the NTLM hash of the password */
|
||||
|
||||
if (credentials->pGetKeyFn)
|
||||
{
|
||||
BYTE* value;
|
||||
void* pKey = NULL;
|
||||
SECURITY_STATUS GetKeyStatus = SEC_E_UNSUPPORTED_FUNCTION;
|
||||
|
||||
if (GetKeyStatus != SEC_E_OK)
|
||||
{
|
||||
pKey = &(credentials->identity);
|
||||
GetKeyStatus = SEC_E_UNSUPPORTED_FUNCTION;
|
||||
|
||||
/* plaintext password */
|
||||
credentials->pGetKeyFn(credentials->pvGetKeyArgument, "NTLM", 0, &pKey, &GetKeyStatus);
|
||||
|
||||
if (GetKeyStatus == SEC_E_OK)
|
||||
{
|
||||
int status;
|
||||
|
||||
value = (BYTE*) pKey;
|
||||
credentials->identity.Password = NULL;
|
||||
|
||||
status = ConvertToUnicode(CP_UTF8, 0, (char*) value, -1,
|
||||
(LPWSTR*) &credentials->identity.Password, 0);
|
||||
|
||||
if (status <= 0)
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
credentials->identity.PasswordLength = (ULONG) (status - 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetKeyStatus != SEC_E_OK)
|
||||
{
|
||||
pKey = &(credentials->identity);
|
||||
GetKeyStatus = SEC_E_UNSUPPORTED_FUNCTION;
|
||||
|
||||
/* NTLMv1 Hash */
|
||||
credentials->pGetKeyFn(credentials->pvGetKeyArgument, "NTLM", 1, &pKey, &GetKeyStatus);
|
||||
|
||||
if (GetKeyStatus == SEC_E_OK)
|
||||
{
|
||||
value = (BYTE*) pKey;
|
||||
CopyMemory(context->NtlmHash, value, 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetKeyStatus != SEC_E_OK)
|
||||
{
|
||||
pKey = &(credentials->identity);
|
||||
GetKeyStatus = SEC_E_UNSUPPORTED_FUNCTION;
|
||||
|
||||
/* NTLMv2 Hash */
|
||||
credentials->pGetKeyFn(credentials->pvGetKeyArgument, "NTLM", 2, &pKey, &GetKeyStatus);
|
||||
|
||||
if (GetKeyStatus == SEC_E_OK)
|
||||
{
|
||||
value = (BYTE*) pKey;
|
||||
CopyMemory(context->NtlmHash, value, 16);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetKeyStatus != SEC_E_OK)
|
||||
{
|
||||
/* no credentials on the server */
|
||||
return SEC_E_LOGON_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
if (ntlm_compute_lm_v2_response(context) < 0) /* LmChallengeResponse */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
if (ntlm_compute_ntlm_v2_response(context) < 0) /* NtChallengeResponse */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
/* KeyExchangeKey */
|
||||
ntlm_generate_key_exchange_key(context);
|
||||
|
||||
/* EncryptedRandomSessionKey */
|
||||
ntlm_decrypt_random_session_key(context);
|
||||
|
||||
/* ExportedSessionKey */
|
||||
ntlm_generate_exported_session_key(context);
|
||||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
ZeroMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[MicOffset], 16);
|
||||
ntlm_compute_message_integrity_check(context);
|
||||
CopyMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[MicOffset], message->MessageIntegrityCheck, 16);
|
||||
|
||||
if (memcmp(context->MessageIntegrityCheck, message->MessageIntegrityCheck, 16) != 0)
|
||||
{
|
||||
fprintf(stderr, "Message Integrity Check (MIC) verification failed!\n");
|
||||
|
||||
fprintf(stderr, "Expected MIC:\n");
|
||||
winpr_HexDump(context->MessageIntegrityCheck, 16);
|
||||
fprintf(stderr, "Actual MIC:\n");
|
||||
winpr_HexDump(message->MessageIntegrityCheck, 16);
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
return SEC_E_MESSAGE_ALTERED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate signing keys */
|
||||
ntlm_generate_client_signing_key(context);
|
||||
ntlm_generate_server_signing_key(context);
|
||||
|
||||
/* Generate sealing keys */
|
||||
ntlm_generate_client_sealing_key(context);
|
||||
ntlm_generate_server_sealing_key(context);
|
||||
|
||||
/* Initialize RC4 seal state */
|
||||
ntlm_init_rc4_seal_states(context);
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
fprintf(stderr, "ClientChallenge\n");
|
||||
winpr_HexDump(context->ClientChallenge, 8);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ServerChallenge\n");
|
||||
winpr_HexDump(context->ServerChallenge, 8);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "SessionBaseKey\n");
|
||||
winpr_HexDump(context->SessionBaseKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "KeyExchangeKey\n");
|
||||
winpr_HexDump(context->KeyExchangeKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ExportedSessionKey\n");
|
||||
winpr_HexDump(context->ExportedSessionKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "RandomSessionKey\n");
|
||||
winpr_HexDump(context->RandomSessionKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ClientSigningKey\n");
|
||||
winpr_HexDump(context->ClientSigningKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ClientSealingKey\n");
|
||||
winpr_HexDump(context->ClientSealingKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ServerSigningKey\n");
|
||||
winpr_HexDump(context->ServerSigningKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ServerSealingKey\n");
|
||||
winpr_HexDump(context->ServerSealingKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Timestamp\n");
|
||||
winpr_HexDump(context->Timestamp, 8);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
context->state = NTLM_STATE_FINAL;
|
||||
|
||||
Stream_Free(s, FALSE);
|
||||
|
||||
ntlm_free_message_fields_buffer(&(message->DomainName));
|
||||
ntlm_free_message_fields_buffer(&(message->UserName));
|
||||
ntlm_free_message_fields_buffer(&(message->Workstation));
|
||||
ntlm_free_message_fields_buffer(&(message->LmChallengeResponse));
|
||||
ntlm_free_message_fields_buffer(&(message->NtChallengeResponse));
|
||||
ntlm_free_message_fields_buffer(&(message->EncryptedRandomSessionKey));
|
||||
/* Computations beyond this point require the NTLM hash of the password */
|
||||
|
||||
context->state = NTLM_STATE_COMPLETION;
|
||||
|
||||
return SEC_I_COMPLETE_NEEDED;
|
||||
}
|
||||
@ -1038,7 +867,6 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
{
|
||||
wStream* s;
|
||||
int length;
|
||||
UINT32 MicOffset = 0;
|
||||
UINT32 PayloadBufferOffset;
|
||||
NTLM_AUTHENTICATE_MESSAGE* message;
|
||||
SSPI_CREDENTIALS* credentials = context->credentials;
|
||||
@ -1148,7 +976,7 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
|
||||
if (context->UseMIC)
|
||||
{
|
||||
MicOffset = Stream_GetPosition(s);
|
||||
context->MessageIntegrityCheckOffset = (UINT32) Stream_GetPosition(s);
|
||||
Stream_Zero(s, 16); /* Message Integrity Check (16 bytes) */
|
||||
}
|
||||
|
||||
@ -1180,7 +1008,7 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
/* Message Integrity Check */
|
||||
ntlm_compute_message_integrity_check(context);
|
||||
|
||||
Stream_SetPosition(s, MicOffset);
|
||||
Stream_SetPosition(s, context->MessageIntegrityCheckOffset);
|
||||
Stream_Write(s, context->MessageIntegrityCheck, 16);
|
||||
Stream_SetPosition(s, length);
|
||||
}
|
||||
@ -1222,3 +1050,125 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
|
||||
return SEC_I_COMPLETE_NEEDED;
|
||||
}
|
||||
|
||||
SECURITY_STATUS ntlm_server_AuthenticateComplete(NTLM_CONTEXT* context)
|
||||
{
|
||||
UINT32 flags = 0;
|
||||
NTLM_AV_PAIR* AvFlags = NULL;
|
||||
NTLM_AUTHENTICATE_MESSAGE* message;
|
||||
|
||||
if (context->state != NTLM_STATE_COMPLETION)
|
||||
return SEC_E_OUT_OF_SEQUENCE;
|
||||
|
||||
message = &context->AUTHENTICATE_MESSAGE;
|
||||
|
||||
AvFlags = ntlm_av_pair_get(context->NTLMv2Response.Challenge.AvPairs, MsvAvFlags);
|
||||
|
||||
if (AvFlags)
|
||||
flags = *((UINT32*) ntlm_av_pair_get_value_pointer(AvFlags));
|
||||
|
||||
if (ntlm_compute_lm_v2_response(context) < 0) /* LmChallengeResponse */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
if (ntlm_compute_ntlm_v2_response(context) < 0) /* NtChallengeResponse */
|
||||
return SEC_E_INTERNAL_ERROR;
|
||||
|
||||
/* KeyExchangeKey */
|
||||
ntlm_generate_key_exchange_key(context);
|
||||
|
||||
/* EncryptedRandomSessionKey */
|
||||
ntlm_decrypt_random_session_key(context);
|
||||
|
||||
/* ExportedSessionKey */
|
||||
ntlm_generate_exported_session_key(context);
|
||||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
ZeroMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[context->MessageIntegrityCheckOffset], 16);
|
||||
|
||||
ntlm_compute_message_integrity_check(context);
|
||||
|
||||
CopyMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[context->MessageIntegrityCheckOffset],
|
||||
message->MessageIntegrityCheck, 16);
|
||||
|
||||
if (memcmp(context->MessageIntegrityCheck, message->MessageIntegrityCheck, 16) != 0)
|
||||
{
|
||||
fprintf(stderr, "Message Integrity Check (MIC) verification failed!\n");
|
||||
|
||||
fprintf(stderr, "Expected MIC:\n");
|
||||
winpr_HexDump(context->MessageIntegrityCheck, 16);
|
||||
fprintf(stderr, "Actual MIC:\n");
|
||||
winpr_HexDump(message->MessageIntegrityCheck, 16);
|
||||
|
||||
return SEC_E_MESSAGE_ALTERED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate signing keys */
|
||||
ntlm_generate_client_signing_key(context);
|
||||
ntlm_generate_server_signing_key(context);
|
||||
|
||||
/* Generate sealing keys */
|
||||
ntlm_generate_client_sealing_key(context);
|
||||
ntlm_generate_server_sealing_key(context);
|
||||
|
||||
/* Initialize RC4 seal state */
|
||||
ntlm_init_rc4_seal_states(context);
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
fprintf(stderr, "ClientChallenge\n");
|
||||
winpr_HexDump(context->ClientChallenge, 8);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ServerChallenge\n");
|
||||
winpr_HexDump(context->ServerChallenge, 8);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "SessionBaseKey\n");
|
||||
winpr_HexDump(context->SessionBaseKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "KeyExchangeKey\n");
|
||||
winpr_HexDump(context->KeyExchangeKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ExportedSessionKey\n");
|
||||
winpr_HexDump(context->ExportedSessionKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "RandomSessionKey\n");
|
||||
winpr_HexDump(context->RandomSessionKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ClientSigningKey\n");
|
||||
winpr_HexDump(context->ClientSigningKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ClientSealingKey\n");
|
||||
winpr_HexDump(context->ClientSealingKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ServerSigningKey\n");
|
||||
winpr_HexDump(context->ServerSigningKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "ServerSealingKey\n");
|
||||
winpr_HexDump(context->ServerSealingKey, 16);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Timestamp\n");
|
||||
winpr_HexDump(context->Timestamp, 8);
|
||||
fprintf(stderr, "\n");
|
||||
#endif
|
||||
|
||||
context->state = NTLM_STATE_FINAL;
|
||||
|
||||
ntlm_free_message_fields_buffer(&(message->DomainName));
|
||||
ntlm_free_message_fields_buffer(&(message->UserName));
|
||||
ntlm_free_message_fields_buffer(&(message->Workstation));
|
||||
ntlm_free_message_fields_buffer(&(message->LmChallengeResponse));
|
||||
ntlm_free_message_fields_buffer(&(message->NtChallengeResponse));
|
||||
ntlm_free_message_fields_buffer(&(message->EncryptedRandomSessionKey));
|
||||
|
||||
return SEC_E_OK;
|
||||
}
|
||||
|
@ -29,4 +29,6 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer buffer);
|
||||
SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer buffer);
|
||||
|
||||
SECURITY_STATUS ntlm_server_AuthenticateComplete(NTLM_CONTEXT* context);
|
||||
|
||||
#endif /* WINPR_SSPI_NTLM_MESSAGE_H */
|
||||
|
@ -178,25 +178,6 @@ SECURITY_STATUS SEC_ENTRY negotiate_DeleteSecurityContext(PCtxtHandle phContext)
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
NEGOTIATE_CONTEXT* context;
|
||||
SECURITY_STATUS status = SEC_E_OK;
|
||||
|
||||
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
if (context->sspiW->QueryContextAttributesW)
|
||||
status = context->sspiW->QueryContextAttributesW(&(context->SubContext), ulAttribute, pBuffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_ImpersonateSecurityContext(PCtxtHandle phContext)
|
||||
{
|
||||
NEGOTIATE_CONTEXT* context;
|
||||
@ -229,6 +210,25 @@ SECURITY_STATUS SEC_ENTRY negotiate_RevertSecurityContext(PCtxtHandle phContext)
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
NEGOTIATE_CONTEXT* context;
|
||||
SECURITY_STATUS status = SEC_E_OK;
|
||||
|
||||
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
if (context->sspiW->QueryContextAttributesW)
|
||||
status = context->sspiW->QueryContextAttributesW(&(context->SubContext), ulAttribute, pBuffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer)
|
||||
{
|
||||
NEGOTIATE_CONTEXT* context;
|
||||
@ -248,6 +248,44 @@ SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesA(PCtxtHandle phContex
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer)
|
||||
{
|
||||
NEGOTIATE_CONTEXT* context;
|
||||
SECURITY_STATUS status = SEC_E_OK;
|
||||
|
||||
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
if (context->sspiW->SetContextAttributesW)
|
||||
status = context->sspiW->SetContextAttributesW(&(context->SubContext), ulAttribute, pBuffer, cbBuffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer)
|
||||
{
|
||||
NEGOTIATE_CONTEXT* context;
|
||||
SECURITY_STATUS status = SEC_E_OK;
|
||||
|
||||
context = (NEGOTIATE_CONTEXT*) sspi_SecureHandleGetLowerPointer(phContext);
|
||||
|
||||
if (!phContext)
|
||||
return SEC_E_INVALID_HANDLE;
|
||||
|
||||
if (!pBuffer)
|
||||
return SEC_E_INSUFFICIENT_MEMORY;
|
||||
|
||||
if (context->sspiA->SetContextAttributesA)
|
||||
status = context->sspiA->SetContextAttributesA(&(context->SubContext), ulAttribute, pBuffer, cbBuffer);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage,
|
||||
ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
|
||||
void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
|
||||
@ -424,7 +462,7 @@ const SecurityFunctionTableA NEGOTIATE_SecurityFunctionTableA =
|
||||
NULL, /* QuerySecurityContextToken */
|
||||
negotiate_EncryptMessage, /* EncryptMessage */
|
||||
negotiate_DecryptMessage, /* DecryptMessage */
|
||||
NULL, /* SetContextAttributes */
|
||||
negotiate_SetContextAttributesA, /* SetContextAttributes */
|
||||
};
|
||||
|
||||
const SecurityFunctionTableW NEGOTIATE_SecurityFunctionTableW =
|
||||
@ -456,7 +494,7 @@ const SecurityFunctionTableW NEGOTIATE_SecurityFunctionTableW =
|
||||
NULL, /* QuerySecurityContextToken */
|
||||
negotiate_EncryptMessage, /* EncryptMessage */
|
||||
negotiate_DecryptMessage, /* DecryptMessage */
|
||||
NULL, /* SetContextAttributes */
|
||||
negotiate_SetContextAttributesW, /* SetContextAttributes */
|
||||
};
|
||||
|
||||
const SecPkgInfoA NEGOTIATE_SecPkgInfoA =
|
||||
|
@ -262,93 +262,6 @@ struct _TEST_NTLM_SERVER
|
||||
};
|
||||
typedef struct _TEST_NTLM_SERVER TEST_NTLM_SERVER;
|
||||
|
||||
void SEC_ENTRY test_ntlm_server_get_key(void* pArg, void* pPrincipal, ULONG KeyVer, void** ppKey, SECURITY_STATUS* pStatus)
|
||||
{
|
||||
char* User = NULL;
|
||||
char* Domain = NULL;
|
||||
TEST_NTLM_SERVER* ntlm;
|
||||
SEC_WINNT_AUTH_IDENTITY* identity;
|
||||
SECURITY_STATUS status = SEC_E_NO_CREDENTIALS;
|
||||
|
||||
if (!pPrincipal || !ppKey)
|
||||
{
|
||||
*pStatus = SEC_E_INVALID_PARAMETER;
|
||||
return;
|
||||
}
|
||||
|
||||
ntlm = (TEST_NTLM_SERVER*) pArg;
|
||||
identity = (SEC_WINNT_AUTH_IDENTITY*) *ppKey;
|
||||
|
||||
if (!ntlm || !identity)
|
||||
{
|
||||
*pStatus = SEC_E_INVALID_PARAMETER;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp((char*) pPrincipal, "NTLM") != 0)
|
||||
{
|
||||
*pStatus = SEC_E_UNSUPPORTED_FUNCTION;
|
||||
return;
|
||||
}
|
||||
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) identity->User, identity->UserLength, &User, 0, NULL, NULL);
|
||||
|
||||
if (identity->Domain)
|
||||
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) identity->Domain, identity->DomainLength, &Domain, 0, NULL, NULL);
|
||||
|
||||
if (KeyVer == 0) /* plaintext password */
|
||||
{
|
||||
#if 0
|
||||
char* password;
|
||||
|
||||
if (strcmp(User, TEST_NTLM_USER) == 0)
|
||||
{
|
||||
password = _strdup(TEST_NTLM_PASSWORD);
|
||||
*ppKey = (void*) password;
|
||||
status = SEC_E_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (KeyVer == 1) /* NTLMv1 Hash */
|
||||
{
|
||||
BYTE* hash;
|
||||
|
||||
status = SEC_E_NO_CREDENTIALS;
|
||||
|
||||
hash = (BYTE*) calloc(1, 16);
|
||||
|
||||
if (!hash)
|
||||
{
|
||||
*pStatus = SEC_E_INTERNAL_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcmp(User, TEST_NTLM_USER) == 0)
|
||||
{
|
||||
CopyMemory(hash, TEST_NTLM_HASH, 16);
|
||||
*ppKey = (void*) hash;
|
||||
status = SEC_E_OK;
|
||||
}
|
||||
}
|
||||
else if (KeyVer == 2) /* NTLMv2 Hash */
|
||||
{
|
||||
status = SEC_E_NO_CREDENTIALS;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unknown */
|
||||
status = SEC_E_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
fprintf(stderr, "SecGetKey %s\\%s status: %s (0x%04X)\n",
|
||||
Domain, User, GetSecurityStatusString(status), status);
|
||||
|
||||
free(User);
|
||||
free(Domain);
|
||||
|
||||
*pStatus = status;
|
||||
}
|
||||
|
||||
int test_ntlm_server_init(TEST_NTLM_SERVER* ntlm)
|
||||
{
|
||||
SECURITY_STATUS status;
|
||||
@ -369,8 +282,7 @@ int test_ntlm_server_init(TEST_NTLM_SERVER* ntlm)
|
||||
ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
|
||||
|
||||
status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME,
|
||||
SECPKG_CRED_INBOUND, NULL, NULL,
|
||||
test_ntlm_server_get_key, (void*) ntlm,
|
||||
SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL,
|
||||
&ntlm->credentials, &ntlm->expiration);
|
||||
|
||||
if (status != SEC_E_OK)
|
||||
@ -446,8 +358,27 @@ int test_ntlm_server_authenticate(TEST_NTLM_SERVER* ntlm)
|
||||
|
||||
if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED))
|
||||
{
|
||||
SecPkgContext_AuthIdentity AuthIdentity;
|
||||
SecPkgContext_AuthNtlmHash AuthNtlmHash;
|
||||
|
||||
ZeroMemory(&AuthIdentity, sizeof(SecPkgContext_AuthIdentity));
|
||||
ZeroMemory(&AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
|
||||
|
||||
status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_AUTH_IDENTITY, &AuthIdentity);
|
||||
|
||||
if (status == SEC_E_OK)
|
||||
{
|
||||
if (strcmp(AuthIdentity.User, TEST_NTLM_USER) == 0)
|
||||
{
|
||||
CopyMemory(AuthNtlmHash.NtlmHash, TEST_NTLM_HASH, 16);
|
||||
|
||||
status = ntlm->table->SetContextAttributes(&ntlm->context,
|
||||
SECPKG_ATTR_AUTH_NTLM_HASH, &AuthNtlmHash, sizeof(SecPkgContext_AuthNtlmHash));
|
||||
}
|
||||
}
|
||||
|
||||
if (ntlm->table->CompleteAuthToken)
|
||||
ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc);
|
||||
status = ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc);
|
||||
|
||||
if (status == SEC_I_COMPLETE_NEEDED)
|
||||
status = SEC_E_OK;
|
||||
|
@ -273,7 +273,7 @@ int schannel_send(PSecurityFunctionTable table, HANDLE hPipe, PCtxtHandle phCont
|
||||
|
||||
printf("EncryptMessage status: 0x%08X\n", status);
|
||||
|
||||
printf("EncryptMessage output: cBuffers: %ld [0]: %lu / %lu [1]: %lu / %lu [2]: %lu / %lu [3]: %lu / %lu\n", Message.cBuffers,
|
||||
printf("EncryptMessage output: cBuffers: %d [0]: %u / %u [1]: %u / %u [2]: %u / %u [3]: %u / %u\n", Message.cBuffers,
|
||||
Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
|
||||
Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
|
||||
Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
|
||||
@ -342,7 +342,7 @@ int schannel_recv(PSecurityFunctionTable table, HANDLE hPipe, PCtxtHandle phCont
|
||||
|
||||
printf("DecryptMessage status: 0x%08X\n", status);
|
||||
|
||||
printf("DecryptMessage output: cBuffers: %ld [0]: %lu / %lu [1]: %lu / %lu [2]: %lu / %lu [3]: %lu / %lu\n", Message.cBuffers,
|
||||
printf("DecryptMessage output: cBuffers: %d [0]: %u / %u [1]: %u / %u [2]: %u / %u [3]: %u / %u\n", Message.cBuffers,
|
||||
Message.pBuffers[0].cbBuffer, Message.pBuffers[0].BufferType,
|
||||
Message.pBuffers[1].cbBuffer, Message.pBuffers[1].BufferType,
|
||||
Message.pBuffers[2].cbBuffer, Message.pBuffers[2].BufferType,
|
||||
@ -351,7 +351,7 @@ int schannel_recv(PSecurityFunctionTable table, HANDLE hPipe, PCtxtHandle phCont
|
||||
if (status != SEC_E_OK)
|
||||
return -1;
|
||||
|
||||
printf("Decrypted Message (%ld)\n", Message.pBuffers[1].cbBuffer);
|
||||
printf("Decrypted Message (%d)\n", Message.pBuffers[1].cbBuffer);
|
||||
winpr_HexDump((BYTE*) Message.pBuffers[1].pvBuffer, Message.pBuffers[1].cbBuffer);
|
||||
|
||||
if (memcmp(Message.pBuffers[1].pvBuffer, test_LastDummyMessage, sizeof(test_LastDummyMessage)) == 0)
|
||||
@ -522,9 +522,9 @@ static void* schannel_test_server_thread(void* arg)
|
||||
else if (status == SEC_E_INCOMPLETE_MESSAGE)
|
||||
printf("AcceptSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
|
||||
|
||||
printf("Server cBuffers: %lu pBuffers[0]: %lu type: %lu\n",
|
||||
printf("Server cBuffers: %u pBuffers[0]: %u type: %u\n",
|
||||
SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
|
||||
printf("Server Input cBuffers: %ld pBuffers[0]: %lu type: %lu pBuffers[1]: %lu type: %lu\n", SecBufferDesc_in.cBuffers,
|
||||
printf("Server Input cBuffers: %d pBuffers[0]: %u type: %u pBuffers[1]: %u type: %u\n", SecBufferDesc_in.cBuffers,
|
||||
SecBufferDesc_in.pBuffers[0].cbBuffer, SecBufferDesc_in.pBuffers[0].BufferType,
|
||||
SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
|
||||
|
||||
@ -543,7 +543,7 @@ static void* schannel_test_server_thread(void* arg)
|
||||
|
||||
if (pSecBuffer->cbBuffer > 0)
|
||||
{
|
||||
printf("Server > Client (%ld)\n", pSecBuffer->cbBuffer);
|
||||
printf("Server > Client (%d)\n", pSecBuffer->cbBuffer);
|
||||
winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
|
||||
|
||||
if (!WriteFile(g_ClientWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer, &NumberOfBytesWritten, NULL))
|
||||
@ -713,7 +713,7 @@ int TestSchannel(int argc, char* argv[])
|
||||
* 0x800C 0x800D 0x800E 0x2400 0xAA02 0xAE06 0x2200 0x2203
|
||||
*/
|
||||
|
||||
printf("SupportedAlgs: %ld\n", SupportedAlgs.cSupportedAlgs);
|
||||
printf("SupportedAlgs: %d\n", SupportedAlgs.cSupportedAlgs);
|
||||
|
||||
for (index = 0; index < SupportedAlgs.cSupportedAlgs; index++)
|
||||
{
|
||||
@ -734,7 +734,7 @@ int TestSchannel(int argc, char* argv[])
|
||||
|
||||
/* CipherStrengths: Minimum: 40 Maximum: 256 */
|
||||
|
||||
printf("CipherStrengths: Minimum: %ld Maximum: %ld\n",
|
||||
printf("CipherStrengths: Minimum: %d Maximum: %d\n",
|
||||
CipherStrengths.dwMinimumCipherStrength, CipherStrengths.dwMaximumCipherStrength);
|
||||
|
||||
ZeroMemory(&SupportedProtocols, sizeof(SecPkgCred_SupportedProtocols));
|
||||
@ -748,7 +748,7 @@ int TestSchannel(int argc, char* argv[])
|
||||
|
||||
/* SupportedProtocols: 0x208A0 */
|
||||
|
||||
printf("SupportedProtocols: 0x%04lX\n", SupportedProtocols.grbitProtocol);
|
||||
printf("SupportedProtocols: 0x%04X\n", SupportedProtocols.grbitProtocol);
|
||||
|
||||
fContextReq = ISC_REQ_STREAM |
|
||||
ISC_REQ_SEQUENCE_DETECT | ISC_REQ_REPLAY_DETECT |
|
||||
@ -781,7 +781,7 @@ int TestSchannel(int argc, char* argv[])
|
||||
}
|
||||
|
||||
g_ClientWait = TRUE;
|
||||
printf("NumberOfBytesRead: %ld\n", NumberOfBytesRead);
|
||||
printf("NumberOfBytesRead: %d\n", NumberOfBytesRead);
|
||||
|
||||
SecBuffer_in[0].BufferType = SECBUFFER_TOKEN;
|
||||
SecBuffer_in[0].pvBuffer = lpTokenIn;
|
||||
@ -821,9 +821,9 @@ int TestSchannel(int argc, char* argv[])
|
||||
else if (status == SEC_E_INCOMPLETE_MESSAGE)
|
||||
printf("InitializeSecurityContext status: SEC_E_INCOMPLETE_MESSAGE\n");
|
||||
|
||||
printf("Client Output cBuffers: %ld pBuffers[0]: %ld type: %ld\n",
|
||||
printf("Client Output cBuffers: %d pBuffers[0]: %d type: %d\n",
|
||||
SecBufferDesc_out.cBuffers, SecBufferDesc_out.pBuffers[0].cbBuffer, SecBufferDesc_out.pBuffers[0].BufferType);
|
||||
printf("Client Input cBuffers: %ld pBuffers[0]: %ld type: %ld pBuffers[1]: %ld type: %ld\n", SecBufferDesc_in.cBuffers,
|
||||
printf("Client Input cBuffers: %d pBuffers[0]: %d type: %d pBuffers[1]: %d type: %d\n", SecBufferDesc_in.cBuffers,
|
||||
SecBufferDesc_in.pBuffers[0].cbBuffer, SecBufferDesc_in.pBuffers[0].BufferType,
|
||||
SecBufferDesc_in.pBuffers[1].cbBuffer, SecBufferDesc_in.pBuffers[1].BufferType);
|
||||
|
||||
@ -833,7 +833,7 @@ int TestSchannel(int argc, char* argv[])
|
||||
|
||||
if (pSecBuffer->cbBuffer > 0)
|
||||
{
|
||||
printf("Client > Server (%ld)\n", pSecBuffer->cbBuffer);
|
||||
printf("Client > Server (%d)\n", pSecBuffer->cbBuffer);
|
||||
winpr_HexDump((BYTE*) pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
|
||||
|
||||
if (!WriteFile(g_ServerWritePipe, pSecBuffer->pvBuffer, pSecBuffer->cbBuffer, &NumberOfBytesWritten, NULL))
|
||||
|
Loading…
Reference in New Issue
Block a user