1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Tests for the NTLM security provider
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright 2005, 2006 Kai Blin
5c2c66affSColin Finck  * Copyright 2006 Dmitry Timoshkov
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  *
21c2c66affSColin Finck  * The code that tests for the behaviour of ISC_REQ_ALLOCATE_MEMORY is based
22c2c66affSColin Finck  * on code written by Dmitry Timoshkov.
23c2c66affSColin Finck 
24c2c66affSColin Finck  */
25c2c66affSColin Finck 
26c2c66affSColin Finck #include <stdarg.h>
27c2c66affSColin Finck #include <stdio.h>
28c2c66affSColin Finck #include <assert.h>
29c2c66affSColin Finck #include <windef.h>
30c2c66affSColin Finck #include <winbase.h>
31c2c66affSColin Finck #define SECURITY_WIN32
32c2c66affSColin Finck #include <sspi.h>
33c2c66affSColin Finck #include <rpc.h>
34c2c66affSColin Finck #include <rpcdce.h>
35c2c66affSColin Finck #include <secext.h>
36c2c66affSColin Finck 
37c2c66affSColin Finck #include "wine/test.h"
38c2c66affSColin Finck 
3946598fe0SAmine Khaldi #define NEGOTIATE_BASE_CAPS ( \
4046598fe0SAmine Khaldi     SECPKG_FLAG_INTEGRITY  | \
4146598fe0SAmine Khaldi     SECPKG_FLAG_PRIVACY    | \
4246598fe0SAmine Khaldi     SECPKG_FLAG_CONNECTION | \
4346598fe0SAmine Khaldi     SECPKG_FLAG_MULTI_REQUIRED | \
4446598fe0SAmine Khaldi     SECPKG_FLAG_EXTENDED_ERROR | \
4546598fe0SAmine Khaldi     SECPKG_FLAG_IMPERSONATION  | \
4646598fe0SAmine Khaldi     SECPKG_FLAG_ACCEPT_WIN32_NAME | \
4746598fe0SAmine Khaldi     SECPKG_FLAG_NEGOTIABLE        | \
4846598fe0SAmine Khaldi     SECPKG_FLAG_GSS_COMPATIBLE    | \
4946598fe0SAmine Khaldi     SECPKG_FLAG_LOGON )
5046598fe0SAmine Khaldi 
5146598fe0SAmine Khaldi #define NTLM_BASE_CAPS ( \
5246598fe0SAmine Khaldi     SECPKG_FLAG_INTEGRITY  | \
5346598fe0SAmine Khaldi     SECPKG_FLAG_PRIVACY    | \
5446598fe0SAmine Khaldi     SECPKG_FLAG_TOKEN_ONLY | \
5546598fe0SAmine Khaldi     SECPKG_FLAG_CONNECTION | \
5646598fe0SAmine Khaldi     SECPKG_FLAG_MULTI_REQUIRED    | \
5746598fe0SAmine Khaldi     SECPKG_FLAG_IMPERSONATION     | \
5846598fe0SAmine Khaldi     SECPKG_FLAG_ACCEPT_WIN32_NAME | \
5946598fe0SAmine Khaldi     SECPKG_FLAG_NEGOTIABLE        | \
6046598fe0SAmine Khaldi     SECPKG_FLAG_LOGON )
6146598fe0SAmine Khaldi 
62c2c66affSColin Finck static HMODULE secdll;
63c2c66affSColin Finck static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
64c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
65c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
66c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
67c2c66affSColin Finck                             ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
68c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleW)(SEC_CHAR*, SEC_WCHAR*,
69c2c66affSColin Finck                             ULONG, PLUID, void*, SEC_GET_KEY_FN, void*, CredHandle*, TimeStamp*);
70c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
71c2c66affSColin Finck                             SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG,
72c2c66affSColin Finck                             PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
73c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
74c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
75c2c66affSColin Finck                             PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
76c2c66affSColin Finck                             PULONG, PTimeStamp);
77c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
78c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
79c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
80c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pMakeSignature)(PCtxtHandle, ULONG,
81c2c66affSColin Finck                             PSecBufferDesc, ULONG);
82c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pVerifySignature)(PCtxtHandle, PSecBufferDesc,
83c2c66affSColin Finck                             ULONG, PULONG);
84c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pEncryptMessage)(PCtxtHandle, ULONG,
85c2c66affSColin Finck                             PSecBufferDesc, ULONG);
86c2c66affSColin Finck static SECURITY_STATUS (SEC_ENTRY * pDecryptMessage)(PCtxtHandle, PSecBufferDesc,
87c2c66affSColin Finck                             ULONG, PULONG);
88c2c66affSColin Finck static BOOLEAN (WINAPI * pGetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG);
89c2c66affSColin Finck 
90c2c66affSColin Finck typedef struct _SspiData {
91c2c66affSColin Finck     CredHandle cred;
92c2c66affSColin Finck     CtxtHandle ctxt;
93c2c66affSColin Finck     PSecBufferDesc in_buf;
94c2c66affSColin Finck     PSecBufferDesc out_buf;
95c2c66affSColin Finck     PSEC_WINNT_AUTH_IDENTITY_A id;
96c2c66affSColin Finck     ULONG max_token;
97c2c66affSColin Finck } SspiData;
98c2c66affSColin Finck 
99c2c66affSColin Finck static BYTE network_challenge[] =
100c2c66affSColin Finck    {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
101c2c66affSColin Finck     0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
102c2c66affSColin Finck     0x05, 0x82, 0x82, 0xa0, 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86,
103c2c66affSColin Finck     0x3b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104c2c66affSColin Finck     0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
105c2c66affSColin Finck     0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
106c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
107c2c66affSColin Finck     0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
108c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
109c2c66affSColin Finck     0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
110c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
111c2c66affSColin Finck     0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
112c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
113c2c66affSColin Finck     0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
114c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
115c2c66affSColin Finck 
116c2c66affSColin Finck static BYTE native_challenge[] =
117c2c66affSColin Finck    {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
118c2c66affSColin Finck     0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
119c2c66affSColin Finck     0x05, 0x82, 0x82, 0xa0, 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c,
120c2c66affSColin Finck     0xee, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121c2c66affSColin Finck     0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
122c2c66affSColin Finck     0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
123c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
124c2c66affSColin Finck     0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
125c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
126c2c66affSColin Finck     0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
127c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
128c2c66affSColin Finck     0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
129c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
130c2c66affSColin Finck     0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
131c2c66affSColin Finck     0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};
132c2c66affSColin Finck 
133c2c66affSColin Finck static BYTE message_signature[] =
134c2c66affSColin Finck    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135c2c66affSColin Finck     0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
136c2c66affSColin Finck 
137c2c66affSColin Finck static BYTE message_binary[] =
138c2c66affSColin Finck    {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72,
139c2c66affSColin Finck     0x6c, 0x64, 0x21};
140c2c66affSColin Finck 
141c2c66affSColin Finck static const char message[] = "Hello, world!";
142c2c66affSColin Finck 
143c2c66affSColin Finck static char message_header[] = "Header Test";
144c2c66affSColin Finck 
145c2c66affSColin Finck static BYTE crypt_trailer_client[] =
146c2c66affSColin Finck    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7,
147c2c66affSColin Finck     0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e};
148c2c66affSColin Finck 
149c2c66affSColin Finck static BYTE crypt_message_client[] =
150c2c66affSColin Finck    {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15,
151c2c66affSColin Finck     0xa0, 0x31, 0xd9};
152c2c66affSColin Finck 
153c2c66affSColin Finck static BYTE crypt_trailer_client2[] =
154c2c66affSColin Finck    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xa7,
155c2c66affSColin Finck     0xf7, 0x0f, 0x5b, 0x25, 0xbe, 0xa4};
156c2c66affSColin Finck 
157c2c66affSColin Finck static BYTE crypt_message_client2[] =
158c2c66affSColin Finck    {0x20, 0x6c, 0x01, 0xab, 0xb0, 0x4c, 0x93, 0xe4, 0x1e, 0xfc,
159c2c66affSColin Finck     0xe1, 0xfa, 0xfe};
160c2c66affSColin Finck 
161c2c66affSColin Finck static BYTE crypt_trailer_server[] =
162c2c66affSColin Finck    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46,
163c2c66affSColin Finck     0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e};
164c2c66affSColin Finck 
165c2c66affSColin Finck static BYTE crypt_message_server[] =
166c2c66affSColin Finck    {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0,
167c2c66affSColin Finck     0x29, 0x66, 0xfd};
168c2c66affSColin Finck 
169c2c66affSColin Finck static BYTE crypt_trailer_server2[] =
170c2c66affSColin Finck    {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x4e,
171c2c66affSColin Finck     0x46, 0xb7, 0xca, 0xf7, 0x7f, 0xb3};
172c2c66affSColin Finck 
173c2c66affSColin Finck static BYTE crypt_message_server2[] =
174c2c66affSColin Finck    {0xc8, 0xf2, 0x39, 0x7f, 0x0c, 0xaf, 0xf5, 0x5d, 0xef, 0x0c,
175c2c66affSColin Finck     0x8b, 0x5f, 0x82};
176c2c66affSColin Finck 
177c2c66affSColin Finck static char test_user[] = "testuser",
178c2c66affSColin Finck             workgroup[] = "WORKGROUP",
179c2c66affSColin Finck             test_pass[] = "testpass",
180c2c66affSColin Finck             sec_pkg_name[] = "NTLM";
181c2c66affSColin Finck 
InitFunctionPtrs(void)182c2c66affSColin Finck static void InitFunctionPtrs(void)
183c2c66affSColin Finck {
184c2c66affSColin Finck     secdll = LoadLibraryA("secur32.dll");
185c2c66affSColin Finck     if(!secdll)
186c2c66affSColin Finck         secdll = LoadLibraryA("security.dll");
187c2c66affSColin Finck     if(secdll)
188c2c66affSColin Finck     {
189c2c66affSColin Finck         pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
190c2c66affSColin Finck         pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
191c2c66affSColin Finck         pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
192c2c66affSColin Finck         pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
193c2c66affSColin Finck         pAcquireCredentialsHandleW = (void*)GetProcAddress(secdll, "AcquireCredentialsHandleW");
194c2c66affSColin Finck         pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
195c2c66affSColin Finck         pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
196c2c66affSColin Finck         pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
197c2c66affSColin Finck         pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
198c2c66affSColin Finck         pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
199c2c66affSColin Finck         pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
200c2c66affSColin Finck         pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature");
201c2c66affSColin Finck         pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature");
202c2c66affSColin Finck         pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage");
203c2c66affSColin Finck         pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage");
204c2c66affSColin Finck         pGetUserNameExA = (PVOID)GetProcAddress(secdll, "GetUserNameExA");
205c2c66affSColin Finck     }
206c2c66affSColin Finck }
207c2c66affSColin Finck 
getSecError(SECURITY_STATUS status)208c2c66affSColin Finck static const char* getSecError(SECURITY_STATUS status)
209c2c66affSColin Finck {
210c2c66affSColin Finck     static char buf[20];
211c2c66affSColin Finck 
212c2c66affSColin Finck #define _SEC_ERR(x) case (x): return #x;
213c2c66affSColin Finck     switch(status)
214c2c66affSColin Finck     {
215c2c66affSColin Finck         _SEC_ERR(SEC_E_OK);
216c2c66affSColin Finck         _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
217c2c66affSColin Finck         _SEC_ERR(SEC_E_INVALID_HANDLE);
218c2c66affSColin Finck         _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
219c2c66affSColin Finck         _SEC_ERR(SEC_E_TARGET_UNKNOWN);
220c2c66affSColin Finck         _SEC_ERR(SEC_E_INTERNAL_ERROR);
221c2c66affSColin Finck         _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
222c2c66affSColin Finck         _SEC_ERR(SEC_E_NOT_OWNER);
223c2c66affSColin Finck         _SEC_ERR(SEC_E_CANNOT_INSTALL);
224c2c66affSColin Finck         _SEC_ERR(SEC_E_INVALID_TOKEN);
225c2c66affSColin Finck         _SEC_ERR(SEC_E_CANNOT_PACK);
226c2c66affSColin Finck         _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
227c2c66affSColin Finck         _SEC_ERR(SEC_E_NO_IMPERSONATION);
228c2c66affSColin Finck         _SEC_ERR(SEC_I_CONTINUE_NEEDED);
229c2c66affSColin Finck         _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
230c2c66affSColin Finck         _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
231c2c66affSColin Finck         _SEC_ERR(SEC_E_LOGON_DENIED);
232c2c66affSColin Finck         _SEC_ERR(SEC_E_NO_CREDENTIALS);
233c2c66affSColin Finck         _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
234c2c66affSColin Finck         _SEC_ERR(SEC_E_MESSAGE_ALTERED);
235c2c66affSColin Finck         default:
236c2c66affSColin Finck             sprintf(buf, "%08x\n", status);
237c2c66affSColin Finck             return buf;
238c2c66affSColin Finck     }
239c2c66affSColin Finck #undef _SEC_ERR
240c2c66affSColin Finck }
241c2c66affSColin Finck 
242c2c66affSColin Finck /**********************************************************************/
243c2c66affSColin Finck 
setupBuffers(SspiData * sspi_data,SecPkgInfoA * sec_pkg_info)244c2c66affSColin Finck static SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
245c2c66affSColin Finck {
246c2c66affSColin Finck 
247c2c66affSColin Finck     sspi_data->in_buf  = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
248c2c66affSColin Finck     sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
249c2c66affSColin Finck     sspi_data->max_token = sec_pkg_info->cbMaxToken;
250c2c66affSColin Finck 
251c2c66affSColin Finck     if(sspi_data->in_buf != NULL)
252c2c66affSColin Finck     {
253c2c66affSColin Finck         PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
254c2c66affSColin Finck                 sizeof(SecBuffer));
255c2c66affSColin Finck         if(sec_buffer == NULL){
256c2c66affSColin Finck             trace("in_buf: sec_buffer == NULL\n");
257c2c66affSColin Finck             return SEC_E_INSUFFICIENT_MEMORY;
258c2c66affSColin Finck         }
259c2c66affSColin Finck 
260c2c66affSColin Finck         sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
261c2c66affSColin Finck         sspi_data->in_buf->cBuffers = 1;
262c2c66affSColin Finck         sspi_data->in_buf->pBuffers = sec_buffer;
263c2c66affSColin Finck 
264c2c66affSColin Finck         sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
265c2c66affSColin Finck         sec_buffer->BufferType = SECBUFFER_TOKEN;
266c2c66affSColin Finck         if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
267c2c66affSColin Finck                         sec_pkg_info->cbMaxToken)) == NULL)
268c2c66affSColin Finck         {
269c2c66affSColin Finck             trace("in_buf: sec_buffer->pvBuffer == NULL\n");
270c2c66affSColin Finck             return SEC_E_INSUFFICIENT_MEMORY;
271c2c66affSColin Finck         }
272c2c66affSColin Finck     }
273c2c66affSColin Finck     else
274c2c66affSColin Finck     {
275c2c66affSColin Finck         trace("HeapAlloc in_buf returned NULL\n");
276c2c66affSColin Finck         return SEC_E_INSUFFICIENT_MEMORY;
277c2c66affSColin Finck     }
278c2c66affSColin Finck 
279c2c66affSColin Finck     if(sspi_data->out_buf != NULL)
280c2c66affSColin Finck     {
281c2c66affSColin Finck         PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
282c2c66affSColin Finck                 sizeof(SecBuffer));
283c2c66affSColin Finck 
284c2c66affSColin Finck         if(sec_buffer == NULL){
285c2c66affSColin Finck             trace("out_buf: sec_buffer == NULL\n");
286c2c66affSColin Finck             return SEC_E_INSUFFICIENT_MEMORY;
287c2c66affSColin Finck         }
288c2c66affSColin Finck 
289c2c66affSColin Finck         sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
290c2c66affSColin Finck         sspi_data->out_buf->cBuffers = 1;
291c2c66affSColin Finck         sspi_data->out_buf->pBuffers = sec_buffer;
292c2c66affSColin Finck 
293c2c66affSColin Finck         sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
294c2c66affSColin Finck         sec_buffer->BufferType = SECBUFFER_TOKEN;
295c2c66affSColin Finck         if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0,
296c2c66affSColin Finck                         sec_pkg_info->cbMaxToken)) == NULL){
297c2c66affSColin Finck             trace("out_buf: sec_buffer->pvBuffer == NULL\n");
298c2c66affSColin Finck             return SEC_E_INSUFFICIENT_MEMORY;
299c2c66affSColin Finck         }
300c2c66affSColin Finck     }
301c2c66affSColin Finck     else
302c2c66affSColin Finck     {
303c2c66affSColin Finck         trace("HeapAlloc out_buf returned NULL\n");
304c2c66affSColin Finck         return SEC_E_INSUFFICIENT_MEMORY;
305c2c66affSColin Finck     }
306c2c66affSColin Finck 
307c2c66affSColin Finck     return SEC_E_OK;
308c2c66affSColin Finck }
309c2c66affSColin Finck 
310c2c66affSColin Finck /**********************************************************************/
311c2c66affSColin Finck 
cleanupBuffers(SspiData * sspi_data)312c2c66affSColin Finck static void cleanupBuffers(SspiData *sspi_data)
313c2c66affSColin Finck {
314c2c66affSColin Finck     ULONG i;
315c2c66affSColin Finck 
316c2c66affSColin Finck     if(sspi_data->in_buf != NULL)
317c2c66affSColin Finck     {
318c2c66affSColin Finck         for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
319c2c66affSColin Finck         {
320c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
321c2c66affSColin Finck         }
322c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
323c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
324c2c66affSColin Finck     }
325c2c66affSColin Finck 
326c2c66affSColin Finck     if(sspi_data->out_buf != NULL)
327c2c66affSColin Finck     {
328c2c66affSColin Finck         for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
329c2c66affSColin Finck         {
330c2c66affSColin Finck             HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
331c2c66affSColin Finck         }
332c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
333c2c66affSColin Finck         HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
334c2c66affSColin Finck     }
335c2c66affSColin Finck }
336c2c66affSColin Finck 
337c2c66affSColin Finck /**********************************************************************/
338c2c66affSColin Finck 
setupClient(SspiData * sspi_data,SEC_CHAR * provider)339c2c66affSColin Finck static SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
340c2c66affSColin Finck {
341c2c66affSColin Finck     SECURITY_STATUS ret;
342c2c66affSColin Finck     TimeStamp ttl;
343c2c66affSColin Finck     SecPkgInfoA *sec_pkg_info;
344c2c66affSColin Finck 
345c2c66affSColin Finck     trace("Running setupClient\n");
346c2c66affSColin Finck 
347c2c66affSColin Finck     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
348c2c66affSColin Finck 
349c2c66affSColin Finck     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
350c2c66affSColin Finck 
351c2c66affSColin Finck     setupBuffers(sspi_data, sec_pkg_info);
352c2c66affSColin Finck     pFreeContextBuffer(sec_pkg_info);
353c2c66affSColin Finck 
354c2c66affSColin Finck     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
355c2c66affSColin Finck             NULL, sspi_data->id, NULL, NULL, &sspi_data->cred, &ttl))
356c2c66affSColin Finck             != SEC_E_OK)
357c2c66affSColin Finck     {
358c2c66affSColin Finck         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
359c2c66affSColin Finck     }
360c2c66affSColin Finck 
361c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
362c2c66affSColin Finck             getSecError(ret));
363c2c66affSColin Finck 
364c2c66affSColin Finck     return ret;
365c2c66affSColin Finck }
366c2c66affSColin Finck /**********************************************************************/
367c2c66affSColin Finck 
setupServer(SspiData * sspi_data,SEC_CHAR * provider)368c2c66affSColin Finck static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
369c2c66affSColin Finck {
370c2c66affSColin Finck     SECURITY_STATUS ret;
371c2c66affSColin Finck     TimeStamp ttl;
372c2c66affSColin Finck     SecPkgInfoA *sec_pkg_info;
373c2c66affSColin Finck 
374c2c66affSColin Finck     trace("Running setupServer\n");
375c2c66affSColin Finck 
376c2c66affSColin Finck     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
377c2c66affSColin Finck 
378c2c66affSColin Finck     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
379c2c66affSColin Finck 
380c2c66affSColin Finck     setupBuffers(sspi_data, sec_pkg_info);
381c2c66affSColin Finck     pFreeContextBuffer(sec_pkg_info);
382c2c66affSColin Finck 
383c2c66affSColin Finck     if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND,
384c2c66affSColin Finck             NULL, NULL, NULL, NULL, &sspi_data->cred, &ttl)) != SEC_E_OK)
385c2c66affSColin Finck     {
386c2c66affSColin Finck         trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
387c2c66affSColin Finck     }
388c2c66affSColin Finck 
389c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
390c2c66affSColin Finck             getSecError(ret));
391c2c66affSColin Finck 
392c2c66affSColin Finck     return ret;
393c2c66affSColin Finck }
394c2c66affSColin Finck 
395c2c66affSColin Finck /**********************************************************************/
396c2c66affSColin Finck 
setupFakeServer(SspiData * sspi_data,SEC_CHAR * provider)397c2c66affSColin Finck static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider)
398c2c66affSColin Finck {
399c2c66affSColin Finck     SECURITY_STATUS ret;
400c2c66affSColin Finck     SecPkgInfoA *sec_pkg_info;
401c2c66affSColin Finck 
402c2c66affSColin Finck     trace("Running setupFakeServer\n");
403c2c66affSColin Finck 
404c2c66affSColin Finck     ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);
405c2c66affSColin Finck 
406c2c66affSColin Finck     ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));
407c2c66affSColin Finck 
408c2c66affSColin Finck     ret = setupBuffers(sspi_data, sec_pkg_info);
409c2c66affSColin Finck     pFreeContextBuffer(sec_pkg_info);
410c2c66affSColin Finck 
411c2c66affSColin Finck     return ret;
412c2c66affSColin Finck }
413c2c66affSColin Finck 
414c2c66affSColin Finck 
415c2c66affSColin Finck /**********************************************************************/
416c2c66affSColin Finck 
runClient(SspiData * sspi_data,BOOL first,ULONG data_rep)417c2c66affSColin Finck static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
418c2c66affSColin Finck {
419c2c66affSColin Finck     SECURITY_STATUS ret;
420c2c66affSColin Finck     ULONG req_attr = 0;
421c2c66affSColin Finck     ULONG ctxt_attr;
422c2c66affSColin Finck     TimeStamp ttl;
423c2c66affSColin Finck     PSecBufferDesc in_buf = sspi_data->in_buf;
424c2c66affSColin Finck     PSecBufferDesc out_buf = sspi_data->out_buf;
425c2c66affSColin Finck 
426c2c66affSColin Finck     assert(in_buf->cBuffers >= 1);
427c2c66affSColin Finck     assert(in_buf->pBuffers[0].pvBuffer != NULL);
428c2c66affSColin Finck     assert(in_buf->pBuffers[0].cbBuffer != 0);
429c2c66affSColin Finck 
430c2c66affSColin Finck     assert(out_buf->cBuffers >= 1);
431c2c66affSColin Finck     assert(out_buf->pBuffers[0].pvBuffer != NULL);
432c2c66affSColin Finck     assert(out_buf->pBuffers[0].cbBuffer != 0);
433c2c66affSColin Finck 
434c2c66affSColin Finck     trace("Running the client the %s time.\n", first?"first":"second");
435c2c66affSColin Finck 
436c2c66affSColin Finck     /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
437c2c66affSColin Finck      * always allocate output buffers for us, or initialize cbBuffer
438c2c66affSColin Finck      * before each call because the API changes it to represent actual
439c2c66affSColin Finck      * amount of data in the buffer.
440c2c66affSColin Finck      */
441c2c66affSColin Finck 
442c2c66affSColin Finck     /* test a failing call only the first time, otherwise we get
443c2c66affSColin Finck      * SEC_E_OUT_OF_SEQUENCE
444c2c66affSColin Finck      */
445c2c66affSColin Finck     if (first)
446c2c66affSColin Finck     {
447c2c66affSColin Finck         void *old_buf;
448c2c66affSColin Finck 
449c2c66affSColin Finck         /* pass NULL as an output buffer */
450c2c66affSColin Finck         ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
451c2c66affSColin Finck             0, data_rep, NULL, 0, &sspi_data->ctxt, NULL,
452c2c66affSColin Finck             &ctxt_attr, &ttl);
453c2c66affSColin Finck 
454c2c66affSColin Finck         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
455c2c66affSColin Finck 
456c2c66affSColin Finck         /* pass NULL as an output buffer */
457c2c66affSColin Finck         old_buf = out_buf->pBuffers[0].pvBuffer;
458c2c66affSColin Finck         out_buf->pBuffers[0].pvBuffer = NULL;
459c2c66affSColin Finck 
460c2c66affSColin Finck         ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
461c2c66affSColin Finck             0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf,
462c2c66affSColin Finck             &ctxt_attr, &ttl);
463c2c66affSColin Finck 
464c2c66affSColin Finck         ok(ret == SEC_E_INTERNAL_ERROR || ret == SEC_I_CONTINUE_NEEDED,
465c2c66affSColin Finck            "expected SEC_E_INTERNAL_ERROR or SEC_I_CONTINUE_NEEDED, got %s\n", getSecError(ret));
466c2c66affSColin Finck 
467c2c66affSColin Finck         out_buf->pBuffers[0].pvBuffer = old_buf;
468c2c66affSColin Finck 
469c2c66affSColin Finck         /* pass an output buffer of 0 size */
470c2c66affSColin Finck         out_buf->pBuffers[0].cbBuffer = 0;
471c2c66affSColin Finck 
472c2c66affSColin Finck         ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
473c2c66affSColin Finck             0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf,
474c2c66affSColin Finck             &ctxt_attr, &ttl);
475c2c66affSColin Finck 
476c2c66affSColin Finck         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
477c2c66affSColin Finck 
478c2c66affSColin Finck         ok(out_buf->pBuffers[0].cbBuffer == 0,
479c2c66affSColin Finck            "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
480c2c66affSColin Finck 
481c2c66affSColin Finck         out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
482c2c66affSColin Finck         out_buf->pBuffers[0].BufferType = SECBUFFER_DATA;
483c2c66affSColin Finck 
484c2c66affSColin Finck         ret = pInitializeSecurityContextA(&sspi_data->cred, NULL, NULL, req_attr,
485c2c66affSColin Finck             0, data_rep, NULL, 0, &sspi_data->ctxt, out_buf,
486c2c66affSColin Finck             &ctxt_attr, &ttl);
487c2c66affSColin Finck 
488c2c66affSColin Finck         ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
489c2c66affSColin Finck         out_buf->pBuffers[0].BufferType = SECBUFFER_TOKEN;
490c2c66affSColin Finck     }
491c2c66affSColin Finck 
492c2c66affSColin Finck     out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
493c2c66affSColin Finck 
494c2c66affSColin Finck     ret = pInitializeSecurityContextA(first?&sspi_data->cred:NULL, first?NULL:&sspi_data->ctxt, NULL, req_attr,
495c2c66affSColin Finck             0, data_rep, first?NULL:in_buf, 0, &sspi_data->ctxt, out_buf,
496c2c66affSColin Finck             &ctxt_attr, &ttl);
497c2c66affSColin Finck 
498c2c66affSColin Finck     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
499c2c66affSColin Finck     {
500c2c66affSColin Finck         pCompleteAuthToken(&sspi_data->ctxt, out_buf);
501c2c66affSColin Finck         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
502c2c66affSColin Finck             ret = SEC_I_CONTINUE_NEEDED;
503c2c66affSColin Finck         else if(ret == SEC_I_COMPLETE_NEEDED)
504c2c66affSColin Finck             ret = SEC_E_OK;
505c2c66affSColin Finck     }
506c2c66affSColin Finck 
507c2c66affSColin Finck     ok(out_buf->pBuffers[0].BufferType == SECBUFFER_TOKEN,
508c2c66affSColin Finck        "buffer type was changed from SECBUFFER_TOKEN to %d\n", out_buf->pBuffers[0].BufferType);
509c2c66affSColin Finck     ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
510c2c66affSColin Finck        "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);
511c2c66affSColin Finck 
512c2c66affSColin Finck     return ret;
513c2c66affSColin Finck }
514c2c66affSColin Finck 
515c2c66affSColin Finck /**********************************************************************/
516c2c66affSColin Finck 
runServer(SspiData * sspi_data,BOOL first,ULONG data_rep)517c2c66affSColin Finck static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
518c2c66affSColin Finck {
519c2c66affSColin Finck     SECURITY_STATUS ret;
520c2c66affSColin Finck     ULONG ctxt_attr;
521c2c66affSColin Finck     TimeStamp ttl;
522c2c66affSColin Finck 
523c2c66affSColin Finck     trace("Running the server the %s time\n", first?"first":"second");
524c2c66affSColin Finck 
525c2c66affSColin Finck     ret = pAcceptSecurityContext(&sspi_data->cred, first?NULL:&sspi_data->ctxt,
526c2c66affSColin Finck             sspi_data->in_buf, 0, data_rep, &sspi_data->ctxt,
527c2c66affSColin Finck             sspi_data->out_buf, &ctxt_attr, &ttl);
528c2c66affSColin Finck 
529c2c66affSColin Finck     if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
530c2c66affSColin Finck     {
531c2c66affSColin Finck         pCompleteAuthToken(&sspi_data->ctxt, sspi_data->out_buf);
532c2c66affSColin Finck         if(ret == SEC_I_COMPLETE_AND_CONTINUE)
533c2c66affSColin Finck             ret = SEC_I_CONTINUE_NEEDED;
534c2c66affSColin Finck         else if(ret == SEC_I_COMPLETE_NEEDED)
535c2c66affSColin Finck             ret = SEC_E_OK;
536c2c66affSColin Finck     }
537c2c66affSColin Finck 
538c2c66affSColin Finck     return ret;
539c2c66affSColin Finck }
540c2c66affSColin Finck 
541c2c66affSColin Finck /**********************************************************************/
542c2c66affSColin Finck 
runFakeServer(SspiData * sspi_data,BOOL first,ULONG data_rep)543c2c66affSColin Finck static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
544c2c66affSColin Finck {
545c2c66affSColin Finck     trace("Running the fake server the %s time\n", first?"first":"second");
546c2c66affSColin Finck 
547c2c66affSColin Finck     if(!first)
548c2c66affSColin Finck     {
549c2c66affSColin Finck         sspi_data->out_buf->pBuffers[0].cbBuffer = 0;
550c2c66affSColin Finck         return SEC_E_OK;
551c2c66affSColin Finck     }
552c2c66affSColin Finck 
553c2c66affSColin Finck     if(data_rep == SECURITY_NATIVE_DREP)
554c2c66affSColin Finck     {
555c2c66affSColin Finck         sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge);
556c2c66affSColin Finck         memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge,
557c2c66affSColin Finck                 sspi_data->out_buf->pBuffers[0].cbBuffer);
558c2c66affSColin Finck     }
559c2c66affSColin Finck     else
560c2c66affSColin Finck     {
561c2c66affSColin Finck         sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge);
562c2c66affSColin Finck         memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge,
563c2c66affSColin Finck                 sspi_data->out_buf->pBuffers[0].cbBuffer);
564c2c66affSColin Finck     }
565c2c66affSColin Finck 
566c2c66affSColin Finck     return SEC_I_CONTINUE_NEEDED;
567c2c66affSColin Finck }
568c2c66affSColin Finck 
569c2c66affSColin Finck /**********************************************************************/
570c2c66affSColin Finck 
communicate(SspiData * from,SspiData * to)571c2c66affSColin Finck static void communicate(SspiData *from, SspiData *to)
572c2c66affSColin Finck {
573c2c66affSColin Finck     if(from->out_buf != NULL && to->in_buf != NULL)
574c2c66affSColin Finck     {
575c2c66affSColin Finck         trace("Running communicate.\n");
576c2c66affSColin Finck         if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
577c2c66affSColin Finck         {
578c2c66affSColin Finck             if((from->out_buf->pBuffers[0].pvBuffer != NULL) &&
579c2c66affSColin Finck                     (to->in_buf->pBuffers[0].pvBuffer != NULL))
580c2c66affSColin Finck             {
581c2c66affSColin Finck                 memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
582c2c66affSColin Finck 
583c2c66affSColin Finck                 memcpy(to->in_buf->pBuffers[0].pvBuffer,
584c2c66affSColin Finck                     from->out_buf->pBuffers[0].pvBuffer,
585c2c66affSColin Finck                     from->out_buf->pBuffers[0].cbBuffer);
586c2c66affSColin Finck 
587c2c66affSColin Finck                 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
588c2c66affSColin Finck 
589c2c66affSColin Finck                 memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
590c2c66affSColin Finck             }
591c2c66affSColin Finck         }
592c2c66affSColin Finck     }
593c2c66affSColin Finck }
594c2c66affSColin Finck 
595c2c66affSColin Finck /**********************************************************************/
testInitializeSecurityContextFlags(void)596c2c66affSColin Finck static void testInitializeSecurityContextFlags(void)
597c2c66affSColin Finck {
598c2c66affSColin Finck     SECURITY_STATUS         sec_status;
599c2c66affSColin Finck     PSecPkgInfoA            pkg_info = NULL;
600c2c66affSColin Finck     SspiData                client = {{0}};
601c2c66affSColin Finck     SEC_WINNT_AUTH_IDENTITY_A id;
602c2c66affSColin Finck     ULONG                   req_attr, ctxt_attr;
603c2c66affSColin Finck     TimeStamp               ttl;
604c2c66affSColin Finck     PBYTE                   packet;
605c2c66affSColin Finck 
606c2c66affSColin Finck     if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
607c2c66affSColin Finck     {
608c2c66affSColin Finck         ok(0, "NTLM package not installed, skipping test.\n");
609c2c66affSColin Finck         return;
610c2c66affSColin Finck     }
611c2c66affSColin Finck 
612c2c66affSColin Finck     pFreeContextBuffer(pkg_info);
613c2c66affSColin Finck     id.User = (unsigned char*) test_user;
614c2c66affSColin Finck     id.UserLength = strlen((char *) id.User);
615c2c66affSColin Finck     id.Domain = (unsigned char *) workgroup;
616c2c66affSColin Finck     id.DomainLength = strlen((char *) id.Domain);
617c2c66affSColin Finck     id.Password = (unsigned char*) test_pass;
618c2c66affSColin Finck     id.PasswordLength = strlen((char *) id.Password);
619c2c66affSColin Finck     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
620c2c66affSColin Finck 
621c2c66affSColin Finck     client.id = &id;
622c2c66affSColin Finck 
623c2c66affSColin Finck     if((sec_status = setupClient(&client, sec_pkg_name)) != SEC_E_OK)
624c2c66affSColin Finck     {
625c2c66affSColin Finck         skip("Setting up the client returned %s, skipping test!\n",
626c2c66affSColin Finck                 getSecError(sec_status));
627c2c66affSColin Finck         return;
628c2c66affSColin Finck     }
629c2c66affSColin Finck 
630c2c66affSColin Finck     packet = client.out_buf->pBuffers[0].pvBuffer;
631c2c66affSColin Finck 
632c2c66affSColin Finck     /* Due to how the requesting of the flags is implemented in ntlm_auth,
633c2c66affSColin Finck      * the tests need to be in this order, as there is no way to specify
634c2c66affSColin Finck      * "I request no special features" in ntlm_auth */
635c2c66affSColin Finck 
636c2c66affSColin Finck     /* Without any flags, the lowest byte should not have bits 0x20 or 0x10 set*/
637c2c66affSColin Finck     req_attr = 0;
638c2c66affSColin Finck 
639c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
640c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
641c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
642c2c66affSColin Finck     {
643c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
644c2c66affSColin Finck                 getSecError(sec_status));
645c2c66affSColin Finck         goto tISCFend;
646c2c66affSColin Finck     }
647c2c66affSColin Finck 
648c2c66affSColin Finck     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
649c2c66affSColin Finck             "With req_attr == 0, flags are 0x%02x%02x%02x%02x.\n",
650c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
651c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
652c2c66affSColin Finck 
653c2c66affSColin Finck     /* With ISC_REQ_CONNECTION, the lowest byte should not have bits 0x20 or 0x10 set*/
654c2c66affSColin Finck     req_attr = ISC_REQ_CONNECTION;
655c2c66affSColin Finck 
656c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
657c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
658c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
659c2c66affSColin Finck     {
660c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
661c2c66affSColin Finck                 getSecError(sec_status));
662c2c66affSColin Finck         goto tISCFend;
663c2c66affSColin Finck     }
664c2c66affSColin Finck 
665c2c66affSColin Finck     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
666c2c66affSColin Finck             "For ISC_REQ_CONNECTION, flags are 0x%02x%02x%02x%02x.\n",
667c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
668c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
669c2c66affSColin Finck 
670c2c66affSColin Finck     /* With ISC_REQ_EXTENDED_ERROR, the lowest byte should not have bits 0x20 or 0x10 set*/
671c2c66affSColin Finck     req_attr = ISC_REQ_EXTENDED_ERROR;
672c2c66affSColin Finck 
673c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
674c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
675c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
676c2c66affSColin Finck     {
677c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
678c2c66affSColin Finck                 getSecError(sec_status));
679c2c66affSColin Finck         goto tISCFend;
680c2c66affSColin Finck     }
681c2c66affSColin Finck 
682c2c66affSColin Finck     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
683c2c66affSColin Finck             "For ISC_REQ_EXTENDED_ERROR, flags are 0x%02x%02x%02x%02x.\n",
684c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
685c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
686c2c66affSColin Finck 
687c2c66affSColin Finck     /* With ISC_REQ_MUTUAL_AUTH, the lowest byte should not have bits 0x20 or 0x10 set*/
688c2c66affSColin Finck     req_attr = ISC_REQ_MUTUAL_AUTH;
689c2c66affSColin Finck 
690c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
691c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
692c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
693c2c66affSColin Finck     {
694c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
695c2c66affSColin Finck                 getSecError(sec_status));
696c2c66affSColin Finck         goto tISCFend;
697c2c66affSColin Finck     }
698c2c66affSColin Finck 
699c2c66affSColin Finck     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
700c2c66affSColin Finck             "For ISC_REQ_MUTUAL_AUTH, flags are 0x%02x%02x%02x%02x.\n",
701c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
702c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
703c2c66affSColin Finck 
704c2c66affSColin Finck     /* With ISC_REQ_USE_DCE_STYLE, the lowest byte should not have bits 0x20 or 0x10 set*/
705c2c66affSColin Finck     req_attr = ISC_REQ_USE_DCE_STYLE;
706c2c66affSColin Finck 
707c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
708c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
709c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
710c2c66affSColin Finck     {
711c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
712c2c66affSColin Finck                 getSecError(sec_status));
713c2c66affSColin Finck         goto tISCFend;
714c2c66affSColin Finck     }
715c2c66affSColin Finck 
716c2c66affSColin Finck     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
717c2c66affSColin Finck             "For ISC_REQ_USE_DCE_STYLE, flags are 0x%02x%02x%02x%02x.\n",
718c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
719c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
720c2c66affSColin Finck 
721c2c66affSColin Finck     /* With ISC_REQ_DELEGATE, the lowest byte should not have bits 0x20 or 0x10 set*/
722c2c66affSColin Finck     req_attr = ISC_REQ_DELEGATE;
723c2c66affSColin Finck 
724c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
725c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
726c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
727c2c66affSColin Finck     {
728c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
729c2c66affSColin Finck                 getSecError(sec_status));
730c2c66affSColin Finck         goto tISCFend;
731c2c66affSColin Finck     }
732c2c66affSColin Finck 
733c2c66affSColin Finck     ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
734c2c66affSColin Finck             "For ISC_REQ_DELEGATE, flags are 0x%02x%02x%02x%02x.\n",
735c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
736c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
737c2c66affSColin Finck 
738c2c66affSColin Finck     /* With ISC_REQ_INTEGRITY, the lowest byte should have bit 0x10 set */
739c2c66affSColin Finck     req_attr = ISC_REQ_INTEGRITY;
740c2c66affSColin Finck 
741c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
742c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
743c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
744c2c66affSColin Finck     {
745c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
746c2c66affSColin Finck                 getSecError(sec_status));
747c2c66affSColin Finck         goto tISCFend;
748c2c66affSColin Finck     }
749c2c66affSColin Finck 
750c2c66affSColin Finck     ok((packet[12] & 0x10) != 0,
751c2c66affSColin Finck             "For ISC_REQ_INTEGRITY, flags are 0x%02x%02x%02x%02x.\n",
752c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
753c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
754c2c66affSColin Finck 
755c2c66affSColin Finck     /* With ISC_REQ_REPLAY_DETECT, the lowest byte should have bit 0x10 set */
756c2c66affSColin Finck     req_attr = ISC_REQ_REPLAY_DETECT;
757c2c66affSColin Finck 
758c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
759c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
760c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
761c2c66affSColin Finck     {
762c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
763c2c66affSColin Finck                 getSecError(sec_status));
764c2c66affSColin Finck         goto tISCFend;
765c2c66affSColin Finck     }
766c2c66affSColin Finck 
767c2c66affSColin Finck     ok((packet[12] & 0x10) != 0,
768c2c66affSColin Finck             "For ISC_REQ_REPLAY_DETECT, flags are 0x%02x%02x%02x%02x.\n",
769c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
770c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
771c2c66affSColin Finck 
772c2c66affSColin Finck     /* With ISC_REQ_SEQUENCE_DETECT, the lowest byte should have bit 0x10 set */
773c2c66affSColin Finck     req_attr = ISC_REQ_SEQUENCE_DETECT;
774c2c66affSColin Finck 
775c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
776c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
777c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
778c2c66affSColin Finck     {
779c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
780c2c66affSColin Finck                 getSecError(sec_status));
781c2c66affSColin Finck         goto tISCFend;
782c2c66affSColin Finck     }
783c2c66affSColin Finck 
784c2c66affSColin Finck     ok((packet[12] & 0x10) != 0,
785c2c66affSColin Finck             "For ISC_REQ_SEQUENCE_DETECT, flags are 0x%02x%02x%02x%02x.\n",
786c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
787c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
788c2c66affSColin Finck 
789c2c66affSColin Finck     /* With ISC_REQ_CONFIDENTIALITY, the lowest byte should have bit 0x20 set */
790c2c66affSColin Finck     req_attr = ISC_REQ_CONFIDENTIALITY;
791c2c66affSColin Finck 
792c2c66affSColin Finck     if((sec_status = pInitializeSecurityContextA(&client.cred, NULL, NULL, req_attr,
793c2c66affSColin Finck         0, SECURITY_NETWORK_DREP, NULL, 0, &client.ctxt, client.out_buf,
794c2c66affSColin Finck         &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
795c2c66affSColin Finck     {
796c2c66affSColin Finck         trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
797c2c66affSColin Finck                 getSecError(sec_status));
798c2c66affSColin Finck         goto tISCFend;
799c2c66affSColin Finck     }
800c2c66affSColin Finck 
801c2c66affSColin Finck     ok((packet[12] & 0x20) != 0,
802c2c66affSColin Finck             "For ISC_REQ_CONFIDENTIALITY, flags are 0x%02x%02x%02x%02x.\n",
803c2c66affSColin Finck             packet[15], packet[14], packet[13], packet[12]);
804c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
805c2c66affSColin Finck 
806c2c66affSColin Finck tISCFend:
807c2c66affSColin Finck     cleanupBuffers(&client);
808c2c66affSColin Finck     pFreeCredentialsHandle(&client.cred);
809c2c66affSColin Finck }
810c2c66affSColin Finck 
811c2c66affSColin Finck /**********************************************************************/
812c2c66affSColin Finck 
testAuth(ULONG data_rep,BOOL fake)813c2c66affSColin Finck static void testAuth(ULONG data_rep, BOOL fake)
814c2c66affSColin Finck {
815c2c66affSColin Finck     SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
816c2c66affSColin Finck     SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
817c2c66affSColin Finck     SECURITY_STATUS         sec_status;
818c2c66affSColin Finck     PSecPkgInfoA            pkg_info = NULL;
819c2c66affSColin Finck     BOOL                    first = TRUE;
820c2c66affSColin Finck     SspiData                client = {{0}}, server = {{0}};
821c2c66affSColin Finck     SEC_WINNT_AUTH_IDENTITY_A id;
822c2c66affSColin Finck     SecPkgContext_Sizes     ctxt_sizes;
82346598fe0SAmine Khaldi     SecPkgContext_NegotiationInfoA info;
82446598fe0SAmine Khaldi     SecPkgInfoA *pi;
825c2c66affSColin Finck 
826c2c66affSColin Finck     if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK)
827c2c66affSColin Finck     {
828c2c66affSColin Finck         ok(0, "NTLM package not installed, skipping test.\n");
829c2c66affSColin Finck         return;
830c2c66affSColin Finck     }
831c2c66affSColin Finck 
832c2c66affSColin Finck     pFreeContextBuffer(pkg_info);
833c2c66affSColin Finck     id.User = (unsigned char*) test_user;
834c2c66affSColin Finck     id.UserLength = strlen((char *) id.User);
835c2c66affSColin Finck     id.Domain = (unsigned char *) workgroup;
836c2c66affSColin Finck     id.DomainLength = strlen((char *) id.Domain);
837c2c66affSColin Finck     id.Password = (unsigned char*) test_pass;
838c2c66affSColin Finck     id.PasswordLength = strlen((char *) id.Password);
839c2c66affSColin Finck     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
840c2c66affSColin Finck 
841c2c66affSColin Finck     client.id = &id;
842c2c66affSColin Finck 
843c2c66affSColin Finck     sec_status = setupClient(&client, sec_pkg_name);
844c2c66affSColin Finck 
845c2c66affSColin Finck     if(sec_status != SEC_E_OK)
846c2c66affSColin Finck     {
847c2c66affSColin Finck         skip("Error: Setting up the client returned %s, exiting test!\n",
848c2c66affSColin Finck                 getSecError(sec_status));
849c2c66affSColin Finck         pFreeCredentialsHandle(&client.cred);
850c2c66affSColin Finck         return;
851c2c66affSColin Finck     }
852c2c66affSColin Finck 
853c2c66affSColin Finck     if(fake)
854c2c66affSColin Finck         sec_status = setupFakeServer(&server, sec_pkg_name);
855c2c66affSColin Finck     else
856c2c66affSColin Finck         sec_status = setupServer(&server, sec_pkg_name);
857c2c66affSColin Finck 
858c2c66affSColin Finck     if(sec_status != SEC_E_OK)
859c2c66affSColin Finck     {
860c2c66affSColin Finck         skip("Error: Setting up the server returned %s, exiting test!\n",
861c2c66affSColin Finck                 getSecError(sec_status));
862c2c66affSColin Finck         pFreeCredentialsHandle(&server.cred);
863c2c66affSColin Finck         pFreeCredentialsHandle(&client.cred);
864c2c66affSColin Finck         return;
865c2c66affSColin Finck     }
866c2c66affSColin Finck 
867c2c66affSColin Finck     while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
868c2c66affSColin Finck     {
869c2c66affSColin Finck         client_stat = runClient(&client, first, data_rep);
870c2c66affSColin Finck 
871c2c66affSColin Finck         ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
872c2c66affSColin Finck                 "Running the client returned %s, more tests will fail.\n",
873c2c66affSColin Finck                 getSecError(client_stat));
874c2c66affSColin Finck 
875c2c66affSColin Finck         communicate(&client, &server);
876c2c66affSColin Finck 
877c2c66affSColin Finck         if(fake)
878c2c66affSColin Finck             server_stat = runFakeServer(&server, first, data_rep);
879c2c66affSColin Finck         else
880c2c66affSColin Finck             server_stat = runServer(&server, first, data_rep);
881c2c66affSColin Finck 
882c2c66affSColin Finck         ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
883c2c66affSColin Finck                 server_stat == SEC_E_LOGON_DENIED,
884c2c66affSColin Finck                 "Running the server returned %s, more tests will fail from now.\n",
885c2c66affSColin Finck                 getSecError(server_stat));
886c2c66affSColin Finck 
887c2c66affSColin Finck         communicate(&server, &client);
888c2c66affSColin Finck         trace("Looping\n");
889c2c66affSColin Finck         first = FALSE;
890c2c66affSColin Finck     }
891c2c66affSColin Finck 
892c2c66affSColin Finck     if(client_stat != SEC_E_OK)
893c2c66affSColin Finck     {
894c2c66affSColin Finck         skip("Authentication failed, skipping test.\n");
895c2c66affSColin Finck         goto tAuthend;
896c2c66affSColin Finck     }
897c2c66affSColin Finck 
898c2c66affSColin Finck     sec_status = pQueryContextAttributesA(&client.ctxt,
899c2c66affSColin Finck             SECPKG_ATTR_SIZES, &ctxt_sizes);
900c2c66affSColin Finck 
901c2c66affSColin Finck     ok(sec_status == SEC_E_OK,
902c2c66affSColin Finck             "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
903c2c66affSColin Finck             getSecError(sec_status));
904c2c66affSColin Finck     ok((ctxt_sizes.cbMaxToken == 1904) || (ctxt_sizes.cbMaxToken == 2888),
905c2c66affSColin Finck             "cbMaxToken should be 1904 or 2888 but is %u\n",
906c2c66affSColin Finck             ctxt_sizes.cbMaxToken);
907c2c66affSColin Finck     ok(ctxt_sizes.cbMaxSignature == 16,
908c2c66affSColin Finck             "cbMaxSignature should be 16 but is %u\n",
909c2c66affSColin Finck             ctxt_sizes.cbMaxSignature);
910c2c66affSColin Finck     ok(ctxt_sizes.cbSecurityTrailer == 16,
911c2c66affSColin Finck             "cbSecurityTrailer should be 16 but is  %u\n",
912c2c66affSColin Finck             ctxt_sizes.cbSecurityTrailer);
913c2c66affSColin Finck     ok(ctxt_sizes.cbBlockSize == 0,
914c2c66affSColin Finck             "cbBlockSize should be 0 but is %u\n",
915c2c66affSColin Finck             ctxt_sizes.cbBlockSize);
916c2c66affSColin Finck 
91746598fe0SAmine Khaldi     memset(&info, 0, sizeof(info));
91846598fe0SAmine Khaldi     sec_status = QueryContextAttributesA(&client.ctxt, SECPKG_ATTR_NEGOTIATION_INFO, &info);
91946598fe0SAmine Khaldi     ok(sec_status == SEC_E_OK, "QueryContextAttributesA returned %08x\n", sec_status);
92046598fe0SAmine Khaldi 
92146598fe0SAmine Khaldi     pi = info.PackageInfo;
92246598fe0SAmine Khaldi     ok(info.NegotiationState == SECPKG_NEGOTIATION_COMPLETE, "got %u\n", info.NegotiationState);
92346598fe0SAmine Khaldi     ok(pi != NULL, "expected non-NULL PackageInfo\n");
92446598fe0SAmine Khaldi     if (pi)
92546598fe0SAmine Khaldi     {
92646598fe0SAmine Khaldi         UINT expected, got;
92746598fe0SAmine Khaldi         char *eob;
92846598fe0SAmine Khaldi 
92946598fe0SAmine Khaldi         ok(pi->fCapabilities == NTLM_BASE_CAPS ||
93046598fe0SAmine Khaldi            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_READONLY_WITH_CHECKSUM) ||
93146598fe0SAmine Khaldi            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_RESTRICTED_TOKENS) ||
932*2b5283b7SAmine Khaldi            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_RESTRICTED_TOKENS|SECPKG_FLAG_APPCONTAINER_CHECKS) ||
933*2b5283b7SAmine Khaldi            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_RESTRICTED_TOKENS|SECPKG_FLAG_APPLY_LOOPBACK) ||
934*2b5283b7SAmine Khaldi            pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_RESTRICTED_TOKENS|SECPKG_FLAG_APPLY_LOOPBACK|
93546598fe0SAmine Khaldi                                  SECPKG_FLAG_APPCONTAINER_CHECKS),
93646598fe0SAmine Khaldi            "got %08x\n", pi->fCapabilities);
93746598fe0SAmine Khaldi         ok(pi->wVersion == 1, "got %u\n", pi->wVersion);
93846598fe0SAmine Khaldi         ok(pi->wRPCID == RPC_C_AUTHN_WINNT, "got %u\n", pi->wRPCID);
93946598fe0SAmine Khaldi         ok(!lstrcmpA( pi->Name, "NTLM" ), "got %s\n", pi->Name);
94046598fe0SAmine Khaldi 
94146598fe0SAmine Khaldi         expected = sizeof(*pi) + lstrlenA(pi->Name) + 1 + lstrlenA(pi->Comment) + 1;
94246598fe0SAmine Khaldi         got = HeapSize(GetProcessHeap(), 0, pi);
94346598fe0SAmine Khaldi         ok(got == expected, "got %u, expected %u\n", got, expected);
94446598fe0SAmine Khaldi         eob = (char *)pi + expected;
94546598fe0SAmine Khaldi         ok(pi->Name + lstrlenA(pi->Name) < eob, "Name doesn't fit into allocated block\n");
94646598fe0SAmine Khaldi         ok(pi->Comment + lstrlenA(pi->Comment) < eob, "Comment doesn't fit into allocated block\n");
94746598fe0SAmine Khaldi 
94846598fe0SAmine Khaldi         sec_status = FreeContextBuffer(pi);
94946598fe0SAmine Khaldi         ok(sec_status == SEC_E_OK, "FreeContextBuffer error %#x\n", sec_status);
95046598fe0SAmine Khaldi     }
95146598fe0SAmine Khaldi 
952c2c66affSColin Finck tAuthend:
953c2c66affSColin Finck     cleanupBuffers(&client);
954c2c66affSColin Finck     cleanupBuffers(&server);
955c2c66affSColin Finck 
956c2c66affSColin Finck     if(!fake)
957c2c66affSColin Finck     {
958c2c66affSColin Finck         sec_status = pDeleteSecurityContext(&server.ctxt);
959c2c66affSColin Finck         ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
960c2c66affSColin Finck             getSecError(sec_status));
961c2c66affSColin Finck     }
962c2c66affSColin Finck 
963c2c66affSColin Finck     sec_status = pDeleteSecurityContext(&client.ctxt);
964c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
965c2c66affSColin Finck             getSecError(sec_status));
966c2c66affSColin Finck 
967c2c66affSColin Finck     if(!fake)
968c2c66affSColin Finck     {
969c2c66affSColin Finck         sec_status = pFreeCredentialsHandle(&server.cred);
970c2c66affSColin Finck         ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
971c2c66affSColin Finck             getSecError(sec_status));
972c2c66affSColin Finck     }
973c2c66affSColin Finck 
974c2c66affSColin Finck     sec_status = pFreeCredentialsHandle(&client.cred);
975c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
976c2c66affSColin Finck             getSecError(sec_status));
977c2c66affSColin Finck }
978c2c66affSColin Finck 
testSignSeal(void)979c2c66affSColin Finck static void testSignSeal(void)
980c2c66affSColin Finck {
981c2c66affSColin Finck     SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
982c2c66affSColin Finck     SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
983c2c66affSColin Finck     SECURITY_STATUS         sec_status;
984c2c66affSColin Finck     PSecPkgInfoA            pkg_info = NULL;
985c2c66affSColin Finck     BOOL                    first = TRUE;
986c2c66affSColin Finck     SspiData                client = {{0}}, server = {{0}};
987c2c66affSColin Finck     SEC_WINNT_AUTH_IDENTITY_A id;
988c2c66affSColin Finck     static char             sec_pkg_name[] = "NTLM";
989c2c66affSColin Finck     SecBufferDesc           crypt;
990c2c66affSColin Finck     SecBuffer               data[2], fake_data[2], complex_data[4];
991c2c66affSColin Finck     ULONG                   qop = 0xdeadbeef;
992c2c66affSColin Finck     SecPkgContext_Sizes     ctxt_sizes;
993c2c66affSColin Finck 
994c2c66affSColin Finck     complex_data[1].pvBuffer = complex_data[3].pvBuffer = NULL;
995c2c66affSColin Finck 
996c2c66affSColin Finck     /****************************************************************
997c2c66affSColin Finck      * This is basically the same as in testAuth with a fake server,
998c2c66affSColin Finck      * as we need a valid, authenticated context.
999c2c66affSColin Finck      */
1000c2c66affSColin Finck     if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
1001c2c66affSColin Finck     {
1002c2c66affSColin Finck         ok(0, "NTLM package not installed, skipping test.\n");
1003c2c66affSColin Finck         return;
1004c2c66affSColin Finck     }
1005c2c66affSColin Finck 
1006c2c66affSColin Finck     pFreeContextBuffer(pkg_info);
1007c2c66affSColin Finck     id.User = (unsigned char*) test_user;
1008c2c66affSColin Finck     id.UserLength = strlen((char *) id.User);
1009c2c66affSColin Finck     id.Domain = (unsigned char *) workgroup;
1010c2c66affSColin Finck     id.DomainLength = strlen((char *) id.Domain);
1011c2c66affSColin Finck     id.Password = (unsigned char*) test_pass;
1012c2c66affSColin Finck     id.PasswordLength = strlen((char *) id.Password);
1013c2c66affSColin Finck     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1014c2c66affSColin Finck 
1015c2c66affSColin Finck     client.id = &id;
1016c2c66affSColin Finck 
1017c2c66affSColin Finck     sec_status = setupClient(&client, sec_pkg_name);
1018c2c66affSColin Finck 
1019c2c66affSColin Finck     if(sec_status != SEC_E_OK)
1020c2c66affSColin Finck     {
1021c2c66affSColin Finck         skip("Error: Setting up the client returned %s, exiting test!\n",
1022c2c66affSColin Finck                 getSecError(sec_status));
1023c2c66affSColin Finck         pFreeCredentialsHandle(&client.cred);
1024c2c66affSColin Finck         return;
1025c2c66affSColin Finck     }
1026c2c66affSColin Finck 
1027c2c66affSColin Finck     sec_status = setupFakeServer(&server, sec_pkg_name);
1028c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "setupFakeServer returned %s\n", getSecError(sec_status));
1029c2c66affSColin Finck 
1030c2c66affSColin Finck     while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
1031c2c66affSColin Finck     {
1032c2c66affSColin Finck         client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);
1033c2c66affSColin Finck 
1034c2c66affSColin Finck         ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
1035c2c66affSColin Finck                 "Running the client returned %s, more tests will fail.\n",
1036c2c66affSColin Finck                 getSecError(client_stat));
1037c2c66affSColin Finck 
1038c2c66affSColin Finck         communicate(&client, &server);
1039c2c66affSColin Finck 
1040c2c66affSColin Finck         server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);
1041c2c66affSColin Finck 
1042c2c66affSColin Finck         communicate(&server, &client);
1043c2c66affSColin Finck         trace("Looping\n");
1044c2c66affSColin Finck         first = FALSE;
1045c2c66affSColin Finck     }
1046c2c66affSColin Finck 
1047c2c66affSColin Finck     if(client_stat != SEC_E_OK)
1048c2c66affSColin Finck     {
1049c2c66affSColin Finck 	skip("Authentication failed, skipping test.\n");
1050c2c66affSColin Finck 	goto end;
1051c2c66affSColin Finck     }
1052c2c66affSColin Finck 
1053c2c66affSColin Finck     /********************************************
1054c2c66affSColin Finck      *    Now start with the actual testing     *
1055c2c66affSColin Finck      ********************************************/
1056c2c66affSColin Finck 
1057c2c66affSColin Finck     if(pQueryContextAttributesA(&client.ctxt, SECPKG_ATTR_SIZES,
1058c2c66affSColin Finck                 &ctxt_sizes) != SEC_E_OK)
1059c2c66affSColin Finck     {
1060c2c66affSColin Finck         skip("Failed to get context sizes, aborting test.\n");
1061c2c66affSColin Finck         goto end;
1062c2c66affSColin Finck     }
1063c2c66affSColin Finck 
1064c2c66affSColin Finck     crypt.ulVersion = SECBUFFER_VERSION;
1065c2c66affSColin Finck     crypt.cBuffers = 2;
1066c2c66affSColin Finck 
1067c2c66affSColin Finck     crypt.pBuffers = fake_data;
1068c2c66affSColin Finck 
1069c2c66affSColin Finck     fake_data[0].BufferType = SECBUFFER_DATA;
1070c2c66affSColin Finck     fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1071c2c66affSColin Finck     fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);
1072c2c66affSColin Finck 
1073c2c66affSColin Finck     fake_data[1].BufferType = SECBUFFER_DATA;
1074c2c66affSColin Finck     fake_data[1].cbBuffer = lstrlenA(message);
1075c2c66affSColin Finck     fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);
1076c2c66affSColin Finck 
1077c2c66affSColin Finck     sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1078c2c66affSColin Finck     ok(sec_status == SEC_E_INVALID_TOKEN,
1079c2c66affSColin Finck             "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
1080c2c66affSColin Finck             getSecError(sec_status));
1081c2c66affSColin Finck 
1082c2c66affSColin Finck     crypt.pBuffers = data;
1083c2c66affSColin Finck 
1084c2c66affSColin Finck     data[0].BufferType = SECBUFFER_TOKEN;
1085c2c66affSColin Finck     data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1086c2c66affSColin Finck     data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);
1087c2c66affSColin Finck 
1088c2c66affSColin Finck     data[1].BufferType = SECBUFFER_DATA;
1089c2c66affSColin Finck     data[1].cbBuffer = lstrlenA(message);
1090c2c66affSColin Finck     data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1091c2c66affSColin Finck     memcpy(data[1].pvBuffer, message, data[1].cbBuffer);
1092c2c66affSColin Finck 
1093c2c66affSColin Finck     /* As we forced NTLM to fall back to a password-derived session key,
1094c2c66affSColin Finck      * we should get the same signature for our data, no matter if
1095c2c66affSColin Finck      * it is sent by the client or the server
1096c2c66affSColin Finck      */
1097c2c66affSColin Finck     sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1098c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1099c2c66affSColin Finck             getSecError(sec_status));
1100c2c66affSColin Finck     ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
1101c2c66affSColin Finck                crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");
1102c2c66affSColin Finck 
1103c2c66affSColin Finck     data[0].cbBuffer = sizeof(message_signature);
1104c2c66affSColin Finck 
1105c2c66affSColin Finck     memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);
1106c2c66affSColin Finck 
1107c2c66affSColin Finck     sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1108c2c66affSColin Finck     ok(sec_status == SEC_E_MESSAGE_ALTERED,
1109c2c66affSColin Finck             "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
1110c2c66affSColin Finck             getSecError(sec_status));
1111c2c66affSColin Finck     ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);
1112c2c66affSColin Finck 
1113c2c66affSColin Finck     memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);
1114c2c66affSColin Finck     sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1115c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
1116c2c66affSColin Finck             getSecError(sec_status));
1117c2c66affSColin Finck     ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);
1118c2c66affSColin Finck 
1119c2c66affSColin Finck     sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0);
1120c2c66affSColin Finck     if (sec_status == SEC_E_UNSUPPORTED_FUNCTION)
1121c2c66affSColin Finck     {
1122c2c66affSColin Finck         skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. "
1123c2c66affSColin Finck              "Expected on Vista.\n");
1124c2c66affSColin Finck         goto end;
1125c2c66affSColin Finck     }
1126c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1127c2c66affSColin Finck             getSecError(sec_status));
1128c2c66affSColin Finck 
1129c2c66affSColin Finck     /* first 8 bytes must always be the same */
1130c2c66affSColin Finck     ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, 8), "Crypt trailer not as expected.\n");
1131c2c66affSColin Finck 
1132c2c66affSColin Finck     /* the rest depends on the session key */
1133c2c66affSColin Finck     if (!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, crypt.pBuffers[0].cbBuffer))
1134c2c66affSColin Finck     {
1135c2c66affSColin Finck         ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
1136c2c66affSColin Finck                    crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
1137c2c66affSColin Finck         ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1138c2c66affSColin Finck                    crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1139c2c66affSColin Finck         if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
1140c2c66affSColin Finck                    crypt.pBuffers[1].cbBuffer))
1141c2c66affSColin Finck         {
1142c2c66affSColin Finck             int i;
1143c2c66affSColin Finck             for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1144c2c66affSColin Finck             {
1145c2c66affSColin Finck                 if (i % 8 == 0) printf("     ");
1146c2c66affSColin Finck                 printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1147c2c66affSColin Finck                 if (i % 8 == 7) printf("\n");
1148c2c66affSColin Finck             }
1149c2c66affSColin Finck             printf("\n");
1150c2c66affSColin Finck         }
1151c2c66affSColin Finck 
1152c2c66affSColin Finck         data[0].cbBuffer = sizeof(crypt_trailer_server);
1153c2c66affSColin Finck         data[1].cbBuffer = sizeof(crypt_message_server);
1154c2c66affSColin Finck         memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
1155c2c66affSColin Finck         memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);
1156c2c66affSColin Finck 
1157c2c66affSColin Finck         sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1158c2c66affSColin Finck 
1159c2c66affSColin Finck         ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1160c2c66affSColin Finck            getSecError(sec_status));
1161c2c66affSColin Finck         ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
1162c2c66affSColin Finck                    crypt.pBuffers[1].cbBuffer),
1163c2c66affSColin Finck            "Failed to decrypt message correctly.\n");
1164c2c66affSColin Finck         ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);
1165c2c66affSColin Finck     }
1166c2c66affSColin Finck     else trace( "A different session key is being used\n" );
1167c2c66affSColin Finck 
1168c2c66affSColin Finck     trace("Testing with more than one buffer.\n");
1169c2c66affSColin Finck 
1170739fc06fSAmine Khaldi     crypt.cBuffers = ARRAY_SIZE(complex_data);
1171c2c66affSColin Finck     crypt.pBuffers = complex_data;
1172c2c66affSColin Finck 
1173c2c66affSColin Finck     complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1174c2c66affSColin Finck     complex_data[0].cbBuffer = sizeof(message_header);
1175c2c66affSColin Finck     complex_data[0].pvBuffer = message_header;
1176c2c66affSColin Finck 
1177c2c66affSColin Finck     complex_data[1].BufferType = SECBUFFER_DATA;
1178c2c66affSColin Finck     complex_data[1].cbBuffer = lstrlenA(message);
1179c2c66affSColin Finck     complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
1180c2c66affSColin Finck     memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);
1181c2c66affSColin Finck 
1182c2c66affSColin Finck     complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
1183c2c66affSColin Finck     complex_data[2].cbBuffer = sizeof(message_header);
1184c2c66affSColin Finck     complex_data[2].pvBuffer = message_header;
1185c2c66affSColin Finck 
1186c2c66affSColin Finck     complex_data[3].BufferType = SECBUFFER_TOKEN;
1187c2c66affSColin Finck     complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
1188c2c66affSColin Finck     complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);
1189c2c66affSColin Finck 
1190c2c66affSColin Finck     /* We should get a dummy signature again. */
1191c2c66affSColin Finck     sec_status = pMakeSignature(&client.ctxt, 0, &crypt, 0);
1192c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
1193c2c66affSColin Finck             getSecError(sec_status));
1194c2c66affSColin Finck     ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
1195c2c66affSColin Finck                crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");
1196c2c66affSColin Finck 
1197c2c66affSColin Finck     /* Being a dummy signature, it will verify right away, as if the server
1198c2c66affSColin Finck      * sent it */
1199c2c66affSColin Finck     sec_status = pVerifySignature(&client.ctxt, &crypt, 0, &qop);
1200c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
1201c2c66affSColin Finck             getSecError(sec_status));
1202c2c66affSColin Finck     ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);
1203c2c66affSColin Finck 
1204c2c66affSColin Finck     sec_status = pEncryptMessage(&client.ctxt, 0, &crypt, 0);
1205c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
1206c2c66affSColin Finck             getSecError(sec_status));
1207c2c66affSColin Finck 
1208c2c66affSColin Finck     ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2, 8), "Crypt trailer not as expected.\n");
1209c2c66affSColin Finck 
1210c2c66affSColin Finck     if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
1211c2c66affSColin Finck                crypt.pBuffers[3].cbBuffer)) goto end;
1212c2c66affSColin Finck 
1213c2c66affSColin Finck     ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1214c2c66affSColin Finck                crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
1215c2c66affSColin Finck     if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
1216c2c66affSColin Finck                crypt.pBuffers[1].cbBuffer))
1217c2c66affSColin Finck     {
1218c2c66affSColin Finck         int i;
1219c2c66affSColin Finck         for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
1220c2c66affSColin Finck         {
1221c2c66affSColin Finck             if (i % 8 == 0) printf("     ");
1222c2c66affSColin Finck             printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
1223c2c66affSColin Finck             if (i % 8 == 7) printf("\n");
1224c2c66affSColin Finck         }
1225c2c66affSColin Finck         printf("\n");
1226c2c66affSColin Finck     }
1227c2c66affSColin Finck 
1228c2c66affSColin Finck     memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
1229c2c66affSColin Finck     memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);
1230c2c66affSColin Finck 
1231c2c66affSColin Finck     sec_status = pDecryptMessage(&client.ctxt, &crypt, 0, &qop);
1232c2c66affSColin Finck     ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
1233c2c66affSColin Finck             getSecError(sec_status));
1234c2c66affSColin Finck     ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);
1235c2c66affSColin Finck 
1236c2c66affSColin Finck 
1237c2c66affSColin Finck end:
1238c2c66affSColin Finck     cleanupBuffers(&client);
1239c2c66affSColin Finck     cleanupBuffers(&server);
1240c2c66affSColin Finck 
1241c2c66affSColin Finck     pDeleteSecurityContext(&client.ctxt);
1242c2c66affSColin Finck     pFreeCredentialsHandle(&client.cred);
1243c2c66affSColin Finck 
1244c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
1245c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
1246c2c66affSColin Finck }
1247c2c66affSColin Finck 
testAcquireCredentialsHandle(void)1248c2c66affSColin Finck static BOOL testAcquireCredentialsHandle(void)
1249c2c66affSColin Finck {
1250c2c66affSColin Finck     CredHandle cred;
1251c2c66affSColin Finck     TimeStamp ttl;
1252c2c66affSColin Finck     SECURITY_STATUS ret;
1253c2c66affSColin Finck     SEC_WINNT_AUTH_IDENTITY_A id;
1254c2c66affSColin Finck     PSecPkgInfoA pkg_info = NULL;
1255c2c66affSColin Finck 
1256c2c66affSColin Finck     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1257c2c66affSColin Finck     {
1258c2c66affSColin Finck         ok(0, "NTLM package not installed, skipping test\n");
1259c2c66affSColin Finck         return FALSE;
1260c2c66affSColin Finck     }
1261c2c66affSColin Finck     pFreeContextBuffer(pkg_info);
1262c2c66affSColin Finck 
1263c2c66affSColin Finck     id.User = (unsigned char*) test_user;
1264c2c66affSColin Finck     id.UserLength = strlen((char *) id.User);
1265c2c66affSColin Finck     id.Domain = (unsigned char *) workgroup;
1266c2c66affSColin Finck     id.DomainLength = strlen((char *) id.Domain);
1267c2c66affSColin Finck     id.Password = (unsigned char*) test_pass;
1268c2c66affSColin Finck     id.PasswordLength = strlen((char *) id.Password);
1269c2c66affSColin Finck     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1270c2c66affSColin Finck 
1271c2c66affSColin Finck     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1272c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1273c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
1274c2c66affSColin Finck             getSecError(ret));
1275c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1276c2c66affSColin Finck 
1277c2c66affSColin Finck     id.DomainLength = 0;
1278c2c66affSColin Finck     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1279c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1280c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
1281c2c66affSColin Finck             getSecError(ret));
1282c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1283c2c66affSColin Finck 
1284c2c66affSColin Finck     id.Domain = NULL;
1285c2c66affSColin Finck     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1286c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1287c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
1288c2c66affSColin Finck             getSecError(ret));
1289c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1290c2c66affSColin Finck 
1291c2c66affSColin Finck     id.Domain = (unsigned char *) workgroup;
1292c2c66affSColin Finck     id.DomainLength = strlen((char *) id.Domain);
1293c2c66affSColin Finck     id.UserLength = 0;
1294c2c66affSColin Finck     id.User = NULL;
1295c2c66affSColin Finck     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1296c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1297c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
1298c2c66affSColin Finck             getSecError(ret));
1299c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1300c2c66affSColin Finck 
1301c2c66affSColin Finck     id.User = (unsigned char*) test_user;
1302c2c66affSColin Finck     id.UserLength = strlen((char *) id.User);
1303c2c66affSColin Finck     id.Password = NULL;
1304c2c66affSColin Finck     id.PasswordLength = 0;
1305c2c66affSColin Finck     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1306c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1307c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
1308c2c66affSColin Finck             getSecError(ret));
1309c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1310c2c66affSColin Finck     return TRUE;
1311c2c66affSColin Finck }
1312c2c66affSColin Finck 
testAcquireCredentialsHandleW(void)1313c2c66affSColin Finck static void testAcquireCredentialsHandleW(void)
1314c2c66affSColin Finck {
1315c2c66affSColin Finck     CredHandle cred;
1316c2c66affSColin Finck     TimeStamp ttl;
1317c2c66affSColin Finck     static WCHAR sec_pkg_nameW[] = {'N','T','L','M',0 };
1318c2c66affSColin Finck     static WCHAR test_userW[]    = {'t','e','s','t','u','s','e','r',0 };
1319c2c66affSColin Finck     static WCHAR workgroupW[]    = {'W','O','R','K','G','R','O','U','P',0};
1320c2c66affSColin Finck     static WCHAR test_passW[]    = {'t','e','s','t','p','a','s','s',0};
1321c2c66affSColin Finck     SECURITY_STATUS ret;
1322c2c66affSColin Finck     SEC_WINNT_AUTH_IDENTITY_A idA;
1323c2c66affSColin Finck     SEC_WINNT_AUTH_IDENTITY_W id;
1324c2c66affSColin Finck     PSecPkgInfoA pkg_info = NULL;
1325c2c66affSColin Finck 
1326c2c66affSColin Finck     if(!pAcquireCredentialsHandleW)
1327c2c66affSColin Finck     {
1328c2c66affSColin Finck         win_skip("AcquireCredentialsHandleW not available\n");
1329c2c66affSColin Finck         return;
1330c2c66affSColin Finck     }
1331c2c66affSColin Finck 
1332c2c66affSColin Finck     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1333c2c66affSColin Finck     {
1334c2c66affSColin Finck         ok(0, "NTLM package not installed, skipping test\n");
1335c2c66affSColin Finck         return;
1336c2c66affSColin Finck     }
1337c2c66affSColin Finck     pFreeContextBuffer(pkg_info);
1338c2c66affSColin Finck 
1339c2c66affSColin Finck     id.User = test_userW;
1340c2c66affSColin Finck     id.UserLength = lstrlenW(test_userW);
1341c2c66affSColin Finck     id.Domain = workgroupW;
1342c2c66affSColin Finck     id.DomainLength = lstrlenW(workgroupW);
1343c2c66affSColin Finck     id.Password = test_passW;
1344c2c66affSColin Finck     id.PasswordLength = lstrlenW(test_passW);
1345c2c66affSColin Finck     id.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
1346c2c66affSColin Finck 
1347c2c66affSColin Finck     ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
1348c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1349c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
1350c2c66affSColin Finck             getSecError(ret));
1351c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1352c2c66affSColin Finck 
1353c2c66affSColin Finck     id.DomainLength = 0;
1354c2c66affSColin Finck     ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
1355c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1356c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
1357c2c66affSColin Finck             getSecError(ret));
1358c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1359c2c66affSColin Finck 
1360c2c66affSColin Finck     id.Domain = NULL;
1361c2c66affSColin Finck     ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
1362c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1363c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
1364c2c66affSColin Finck             getSecError(ret));
1365c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1366c2c66affSColin Finck 
1367c2c66affSColin Finck     id.Domain = workgroupW;
1368c2c66affSColin Finck     id.DomainLength = lstrlenW(workgroupW);
1369c2c66affSColin Finck     id.UserLength = 0;
1370c2c66affSColin Finck     id.User = NULL;
1371c2c66affSColin Finck     ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
1372c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1373c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
1374c2c66affSColin Finck             getSecError(ret));
1375c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1376c2c66affSColin Finck 
1377c2c66affSColin Finck     id.User = test_userW;
1378c2c66affSColin Finck     id.UserLength = lstrlenW(test_userW);
1379c2c66affSColin Finck     id.Password = test_passW;    /* NULL string causes a crash. */
1380c2c66affSColin Finck     id.PasswordLength = 0;
1381c2c66affSColin Finck     ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
1382c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1383c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
1384c2c66affSColin Finck             getSecError(ret));
1385c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1386c2c66affSColin Finck 
1387c2c66affSColin Finck     /* Test using the ASCII structure. */
1388c2c66affSColin Finck     idA.User = (unsigned char*) test_user;
1389c2c66affSColin Finck     idA.UserLength = strlen(test_user);
1390c2c66affSColin Finck     idA.Domain = (unsigned char *) workgroup;
1391c2c66affSColin Finck     idA.DomainLength = strlen(workgroup);
1392c2c66affSColin Finck     idA.Password = (unsigned char*) test_pass;
1393c2c66affSColin Finck     idA.PasswordLength = strlen(test_pass);
1394c2c66affSColin Finck     idA.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1395c2c66affSColin Finck 
1396c2c66affSColin Finck     ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
1397c2c66affSColin Finck             NULL, &idA, NULL, NULL, &cred, &ttl);
1398c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
1399c2c66affSColin Finck             getSecError(ret));
1400c2c66affSColin Finck     pFreeCredentialsHandle(&cred);
1401c2c66affSColin Finck }
1402c2c66affSColin Finck 
test_cred_multiple_use(void)1403c2c66affSColin Finck static void test_cred_multiple_use(void)
1404c2c66affSColin Finck {
1405c2c66affSColin Finck     SECURITY_STATUS ret;
1406c2c66affSColin Finck     SEC_WINNT_AUTH_IDENTITY_A id;
1407c2c66affSColin Finck     PSecPkgInfoA            pkg_info = NULL;
1408c2c66affSColin Finck     CredHandle              cred;
1409c2c66affSColin Finck     CtxtHandle              ctxt1 = {0};
1410c2c66affSColin Finck     CtxtHandle              ctxt2 = {0};
1411c2c66affSColin Finck     SecBufferDesc           buffer_desc;
1412c2c66affSColin Finck     SecBuffer               buffers[1];
1413c2c66affSColin Finck     ULONG                   ctxt_attr;
1414c2c66affSColin Finck     TimeStamp               ttl;
1415c2c66affSColin Finck 
1416c2c66affSColin Finck     if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
1417c2c66affSColin Finck     {
1418c2c66affSColin Finck         ok(0, "NTLM package not installed, skipping test\n");
1419c2c66affSColin Finck         return;
1420c2c66affSColin Finck     }
1421c2c66affSColin Finck     buffers[0].cbBuffer = pkg_info->cbMaxToken;
1422c2c66affSColin Finck     buffers[0].BufferType = SECBUFFER_TOKEN;
1423c2c66affSColin Finck     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1424c2c66affSColin Finck 
1425c2c66affSColin Finck     pFreeContextBuffer(pkg_info);
1426c2c66affSColin Finck 
1427c2c66affSColin Finck     id.User = (unsigned char*) test_user;
1428c2c66affSColin Finck     id.UserLength = strlen((char *) id.User);
1429c2c66affSColin Finck     id.Domain = (unsigned char *) workgroup;
1430c2c66affSColin Finck     id.DomainLength = strlen((char *) id.Domain);
1431c2c66affSColin Finck     id.Password = (unsigned char*) test_pass;
1432c2c66affSColin Finck     id.PasswordLength = strlen((char *) id.Password);
1433c2c66affSColin Finck     id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
1434c2c66affSColin Finck 
1435c2c66affSColin Finck     ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
1436c2c66affSColin Finck             NULL, &id, NULL, NULL, &cred, &ttl);
1437c2c66affSColin Finck     ok(ret == SEC_E_OK, "AcquireCredentialsHandle() returned %s\n",
1438c2c66affSColin Finck             getSecError(ret));
1439c2c66affSColin Finck 
1440c2c66affSColin Finck     buffer_desc.ulVersion = SECBUFFER_VERSION;
1441739fc06fSAmine Khaldi     buffer_desc.cBuffers = ARRAY_SIZE(buffers);
1442c2c66affSColin Finck     buffer_desc.pBuffers = buffers;
1443c2c66affSColin Finck 
1444c2c66affSColin Finck     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1445c2c66affSColin Finck             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
1446c2c66affSColin Finck             &ctxt_attr, &ttl);
1447c2c66affSColin Finck     ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);
1448c2c66affSColin Finck 
1449c2c66affSColin Finck     ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
1450c2c66affSColin Finck             0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
1451c2c66affSColin Finck             &ctxt_attr, &ttl);
1452c2c66affSColin Finck     ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);
1453c2c66affSColin Finck 
1454c2c66affSColin Finck     ret = pDeleteSecurityContext(&ctxt1);
1455c2c66affSColin Finck     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1456c2c66affSColin Finck     ret = pDeleteSecurityContext(&ctxt2);
1457c2c66affSColin Finck     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1458c2c66affSColin Finck     ret = pFreeCredentialsHandle(&cred);
1459c2c66affSColin Finck     ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1460c2c66affSColin Finck 
1461c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1462c2c66affSColin Finck }
1463c2c66affSColin Finck 
test_null_auth_data(void)1464c2c66affSColin Finck static void test_null_auth_data(void)
1465c2c66affSColin Finck {
1466c2c66affSColin Finck     SECURITY_STATUS status;
1467c2c66affSColin Finck     PSecPkgInfoA info;
1468c2c66affSColin Finck     CredHandle cred;
1469c2c66affSColin Finck     CtxtHandle ctx = {0};
1470c2c66affSColin Finck     SecBufferDesc buffer_desc;
1471c2c66affSColin Finck     SecBuffer buffers[1];
1472c2c66affSColin Finck     char user[256];
1473c2c66affSColin Finck     TimeStamp ttl;
1474c2c66affSColin Finck     ULONG attr, size;
1475c2c66affSColin Finck     BOOLEAN ret;
1476c2c66affSColin Finck 
1477c2c66affSColin Finck     if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
1478c2c66affSColin Finck     {
1479c2c66affSColin Finck         ok(0, "NTLM package not installed, skipping test\n");
1480c2c66affSColin Finck         return;
1481c2c66affSColin Finck     }
1482c2c66affSColin Finck 
1483c2c66affSColin Finck     status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
1484c2c66affSColin Finck                                         NULL, NULL, NULL, NULL, &cred, &ttl);
1485c2c66affSColin Finck     ok(status == SEC_E_OK, "AcquireCredentialsHandle() failed %s\n", getSecError(status));
1486c2c66affSColin Finck 
1487c2c66affSColin Finck     buffers[0].cbBuffer = info->cbMaxToken;
1488c2c66affSColin Finck     buffers[0].BufferType = SECBUFFER_TOKEN;
1489c2c66affSColin Finck     buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);
1490c2c66affSColin Finck 
1491c2c66affSColin Finck     buffer_desc.ulVersion = SECBUFFER_VERSION;
1492739fc06fSAmine Khaldi     buffer_desc.cBuffers = ARRAY_SIZE(buffers);
1493c2c66affSColin Finck     buffer_desc.pBuffers = buffers;
1494c2c66affSColin Finck 
1495c2c66affSColin Finck     size = sizeof(user);
1496c2c66affSColin Finck     ret = pGetUserNameExA(NameSamCompatible, user, &size);
1497c2c66affSColin Finck     ok(ret, "GetUserNameExA failed %u\n", GetLastError());
1498c2c66affSColin Finck 
1499c2c66affSColin Finck     status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
1500c2c66affSColin Finck                                          ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
1501c2c66affSColin Finck                                          NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
1502c2c66affSColin Finck     ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));
1503c2c66affSColin Finck 
1504c2c66affSColin Finck     ret = pDeleteSecurityContext(&ctx);
1505c2c66affSColin Finck     ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
1506c2c66affSColin Finck     ret = pFreeCredentialsHandle(&cred);
1507c2c66affSColin Finck     ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
1508c2c66affSColin Finck 
1509c2c66affSColin Finck     pFreeContextBuffer(info);
1510c2c66affSColin Finck     HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
1511c2c66affSColin Finck }
1512c2c66affSColin Finck 
START_TEST(ntlm)1513c2c66affSColin Finck START_TEST(ntlm)
1514c2c66affSColin Finck {
1515c2c66affSColin Finck     InitFunctionPtrs();
1516c2c66affSColin Finck 
1517c2c66affSColin Finck     if(pFreeCredentialsHandle && pDeleteSecurityContext &&
1518c2c66affSColin Finck        pAcquireCredentialsHandleA && pInitializeSecurityContextA &&
1519c2c66affSColin Finck        pCompleteAuthToken && pQuerySecurityPackageInfoA)
1520c2c66affSColin Finck     {
1521c2c66affSColin Finck         testAcquireCredentialsHandleW();
1522c2c66affSColin Finck 
1523c2c66affSColin Finck         if(!testAcquireCredentialsHandle())
1524c2c66affSColin Finck             goto cleanup;
1525c2c66affSColin Finck         testInitializeSecurityContextFlags();
1526c2c66affSColin Finck         if(pAcceptSecurityContext)
1527c2c66affSColin Finck         {
1528c2c66affSColin Finck             testAuth(SECURITY_NATIVE_DREP, TRUE);
1529c2c66affSColin Finck             testAuth(SECURITY_NETWORK_DREP, TRUE);
1530c2c66affSColin Finck             testAuth(SECURITY_NATIVE_DREP, FALSE);
1531c2c66affSColin Finck             testAuth(SECURITY_NETWORK_DREP, FALSE);
1532c2c66affSColin Finck         }
1533c2c66affSColin Finck         if(pMakeSignature && pVerifySignature && pEncryptMessage &&
1534c2c66affSColin Finck            pDecryptMessage)
1535c2c66affSColin Finck             testSignSeal();
1536c2c66affSColin Finck 
1537c2c66affSColin Finck         test_cred_multiple_use();
1538c2c66affSColin Finck         if (pGetUserNameExA) test_null_auth_data();
1539c2c66affSColin Finck     }
1540c2c66affSColin Finck     else
1541c2c66affSColin Finck         win_skip("Needed functions are not available\n");
1542c2c66affSColin Finck 
1543c2c66affSColin Finck cleanup:
1544c2c66affSColin Finck     if(secdll)
1545c2c66affSColin Finck         FreeLibrary(secdll);
1546c2c66affSColin Finck }
1547