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