From: Piotr Caban piotr@codeweavers.com
--- dlls/secur32/tests/ntlm.c | 128 +++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 35 deletions(-)
diff --git a/dlls/secur32/tests/ntlm.c b/dlls/secur32/tests/ntlm.c index 72872b5f9e4..ac84ebc8ebd 100644 --- a/dlls/secur32/tests/ntlm.c +++ b/dlls/secur32/tests/ntlm.c @@ -69,39 +69,97 @@ typedef struct _SspiData { ULONG max_token, req_attr; } SspiData;
-static BYTE network_challenge[] = - {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x05, 0x82, 0x82, 0xa0, 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86, - 0x3b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, - 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00, - 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00, - 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00, - 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00, - 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00}; - -static BYTE native_challenge[] = - {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x05, 0x82, 0x82, 0xa0, 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c, - 0xee, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00, - 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00, - 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00, - 0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00, - 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00, - 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00, - 0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00}; +enum negotiate_flags +{ + NTLMSSP_NEGOTIATE_UNICODE = 0x00000001, + NTLM_NEGOTIATE_OEM = 0x00000002, + NTLMSSP_REQUEST_TARGET = 0x00000004, + NTLMSSP_NEGOTIATE_SIGN = 0x00000010, + NTLMSSP_NEGOTIATE_SEAL = 0x00000020, + NTLMSSP_NEGOTIATE_DATAGRAM = 0x00000040, + NTLMSSP_NEGOTIATE_LM_KEY = 0x00000080, + NTLMSSP_NEGOTIATE_NETWARE = 0x00000100, + NTLMSSP_NEGOTIATE_NTLM = 0x00000200, + NTLMSSP_NEGOTIATE_ANONYMOUS = 0x00000800, + NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED = 0x00001000, + NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000, + NTLMSSP_NEGOTIATE_LOCAL_CALL = 0x00004000, + NTLMSSP_NEGOTIATE_ALWAYS_SIGN = 0x00008000, + NTLMSSP_TARGET_TYPE_DOMAIN = 0x00010000, + NTLMSSP_TARGET_TYPE_SERVER = 0x00020000, + NTLMSSP_TARGET_TYPE_SHARE = 0x00040000, + NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000, + NTLMSSP_NEGOTIATE_IDENTIFY = 0x00100000, + NTLMSSP_REQUEST_NON_NT_SESSION_KEY = 0x00400000, + NTLMSSP_NEGOTIATE_TARGET_INFO = 0x00800000, + NTLMSSP_NEGOTIATE_VERSION = 0x02000000, + NTLMSSP_NEGOTIATE_128 = 0x20000000, + NTLMSSP_NEGOTIATE_KEY_EXCH = 0x40000000, + NTLMSSP_NEGOTIATE_56 = 0x80000000, +}; + +struct ntlm_server_challenge +{ + char signature[8]; + int message_type; + unsigned short target_name_len; + unsigned short target_name_max_len; + unsigned int target_name_off; + enum negotiate_flags negotiate_flags; + BYTE challenge[8]; + BYTE reserved[8]; + unsigned short target_info_len; + unsigned short target_info_max_len; + unsigned int target_info_off; +}; + +struct network_challenge +{ + struct ntlm_server_challenge challenge; + WCHAR name[8]; + WCHAR info[42]; + +} network_challenge = +{ + { + "NTLMSSP", 2, + sizeof(network_challenge.name), sizeof(network_challenge.name), + offsetof(struct network_challenge, name), + NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_TARGET_TYPE_SERVER | + NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56, + { 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86, 0x3b, 0x63 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + sizeof(network_challenge.info), sizeof(network_challenge.info), + offsetof(struct network_challenge, info) + }, + L"CASINO01", + L"\002\020CASINO01\001\020CASINO01\004\020casino01\003\020casino01\0" +}; + +struct native_challenge +{ + struct ntlm_server_challenge challenge; + WCHAR name[8]; + WCHAR info[42]; + +} native_challenge = +{ + { + "NTLMSSP", 2, + sizeof(native_challenge.name), sizeof(native_challenge.name), + offsetof(struct native_challenge, name), + NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_TARGET_TYPE_SERVER | + NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56, + { 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c, 0xee, 0x03 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + sizeof(native_challenge.info), sizeof(native_challenge.info), + offsetof(struct native_challenge, info) + }, + L"CASINO01", + L"\002\020CASINO01\001\020CASINO01\004\020casino01\003\020casino01\0" +};
static BYTE message_signature[] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -467,13 +525,13 @@ static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data if(data_rep == SECURITY_NATIVE_DREP) { sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge); - memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge, + memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, &native_challenge, sspi_data->out_buf->pBuffers[0].cbBuffer); } else { sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge); - memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge, + memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, &network_challenge, sspi_data->out_buf->pBuffers[0].cbBuffer); }
From: Piotr Caban piotr@codeweavers.com
The data is identical except of server challenge field. --- dlls/secur32/tests/ntlm.c | 52 +++++++-------------------------------- 1 file changed, 9 insertions(+), 43 deletions(-)
diff --git a/dlls/secur32/tests/ntlm.c b/dlls/secur32/tests/ntlm.c index ac84ebc8ebd..5d318e2e1ed 100644 --- a/dlls/secur32/tests/ntlm.c +++ b/dlls/secur32/tests/ntlm.c @@ -113,49 +113,25 @@ struct ntlm_server_challenge unsigned int target_info_off; };
-struct network_challenge +struct server_challenge { struct ntlm_server_challenge challenge; WCHAR name[8]; WCHAR info[42];
-} network_challenge = +} server_challenge = { { "NTLMSSP", 2, - sizeof(network_challenge.name), sizeof(network_challenge.name), - offsetof(struct network_challenge, name), - NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_TARGET_TYPE_SERVER | - NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56, - { 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86, 0x3b, 0x63 }, - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - sizeof(network_challenge.info), sizeof(network_challenge.info), - offsetof(struct network_challenge, info) - }, - L"CASINO01", - L"\002\020CASINO01\001\020CASINO01\004\020casino01\003\020casino01\0" -}; - -struct native_challenge -{ - struct ntlm_server_challenge challenge; - WCHAR name[8]; - WCHAR info[42]; - -} native_challenge = -{ - { - "NTLMSSP", 2, - sizeof(native_challenge.name), sizeof(native_challenge.name), - offsetof(struct native_challenge, name), + sizeof(server_challenge.name), sizeof(server_challenge.name), + offsetof(struct server_challenge, name), NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_TARGET_TYPE_SERVER | NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56, { 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c, 0xee, 0x03 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - sizeof(native_challenge.info), sizeof(native_challenge.info), - offsetof(struct native_challenge, info) + sizeof(server_challenge.info), sizeof(server_challenge.info), + offsetof(struct server_challenge, info) }, L"CASINO01", L"\002\020CASINO01\001\020CASINO01\004\020casino01\003\020casino01\0" @@ -522,19 +498,9 @@ static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data return SEC_E_OK; }
- if(data_rep == SECURITY_NATIVE_DREP) - { - sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge); - memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, &native_challenge, - sspi_data->out_buf->pBuffers[0].cbBuffer); - } - else - { - sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge); - memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, &network_challenge, - sspi_data->out_buf->pBuffers[0].cbBuffer); - } - + sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(server_challenge); + memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, &server_challenge, + sspi_data->out_buf->pBuffers[0].cbBuffer); return SEC_I_CONTINUE_NEEDED; }
From: Piotr Caban piotr@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58190 --- dlls/secur32/tests/ntlm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/dlls/secur32/tests/ntlm.c b/dlls/secur32/tests/ntlm.c index 5d318e2e1ed..92f0e50b1c2 100644 --- a/dlls/secur32/tests/ntlm.c +++ b/dlls/secur32/tests/ntlm.c @@ -127,7 +127,8 @@ struct server_challenge offsetof(struct server_challenge, name), NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_TARGET_TYPE_SERVER | - NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56, + NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY | NTLMSSP_NEGOTIATE_TARGET_INFO | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56, { 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c, 0xee, 0x03 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, sizeof(server_challenge.info), sizeof(server_challenge.info), @@ -848,9 +849,11 @@ static void testAuth(ULONG data_rep, BOOL fake) ok( sec_status == SEC_E_OK, "QueryContextAttributesA returned %08lx\n", sec_status ); if (fake) { - ok( !strcmp(key.sSignatureAlgorithmName, "RSADSI RC4-CRC32"), "got '%s'\n", key.sSignatureAlgorithmName ); + ok( !strcmp(key.sSignatureAlgorithmName, "RSADSI RC4-CRC32") || + !strcmp(key.sSignatureAlgorithmName, "HMAC-MD5"), "got '%s'\n", key.sSignatureAlgorithmName ); ok( !strcmp(key.sEncryptAlgorithmName, "RSADSI RC4"), "got '%s'\n", key.sEncryptAlgorithmName ); - ok( key.SignatureAlgorithm == 0xffffff7c, "got %#lx\n", key.SignatureAlgorithm ); + ok( key.SignatureAlgorithm == 0xffffff7c || key.SignatureAlgorithm == 0xffffff76, + "got %#lx\n", key.SignatureAlgorithm ); } else {
From: Piotr Caban piotr@codeweavers.com
Native defaults to NTLMv2 since Windows Vista. Even so fake server reports support for both NTLMv1 and NTLMv2 during negotiation mark NTLMv1 reply as broken. --- dlls/secur32/tests/ntlm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/secur32/tests/ntlm.c b/dlls/secur32/tests/ntlm.c index 92f0e50b1c2..ce40212b379 100644 --- a/dlls/secur32/tests/ntlm.c +++ b/dlls/secur32/tests/ntlm.c @@ -849,10 +849,10 @@ static void testAuth(ULONG data_rep, BOOL fake) ok( sec_status == SEC_E_OK, "QueryContextAttributesA returned %08lx\n", sec_status ); if (fake) { - ok( !strcmp(key.sSignatureAlgorithmName, "RSADSI RC4-CRC32") || + todo_wine ok( broken(!strcmp(key.sSignatureAlgorithmName, "RSADSI RC4-CRC32")) || !strcmp(key.sSignatureAlgorithmName, "HMAC-MD5"), "got '%s'\n", key.sSignatureAlgorithmName ); ok( !strcmp(key.sEncryptAlgorithmName, "RSADSI RC4"), "got '%s'\n", key.sEncryptAlgorithmName ); - ok( key.SignatureAlgorithm == 0xffffff7c || key.SignatureAlgorithm == 0xffffff76, + todo_wine ok( broken(key.SignatureAlgorithm == 0xffffff7c) || key.SignatureAlgorithm == 0xffffff76, "got %#lx\n", key.SignatureAlgorithm ); } else