ReactOS 0.4.15-dev-7906-g1b85a5f
negotiate.c
Go to the documentation of this file.
1/*
2 * Tests for the Negotiate security provider
3 *
4 * Copyright 2005, 2006 Kai Blin
5 * Copyright 2012 Hans Leidekker for CodeWeavers
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <stdarg.h>
23#include <stdio.h>
24#include <windef.h>
25#include <winbase.h>
26#define SECURITY_WIN32
27#include <sspi.h>
28#include <rpc.h>
29#include <rpcdce.h>
30#include <secext.h>
31
32#include "wine/test.h"
33
34#define NEGOTIATE_BASE_CAPS ( \
35 SECPKG_FLAG_INTEGRITY | \
36 SECPKG_FLAG_PRIVACY | \
37 SECPKG_FLAG_CONNECTION | \
38 SECPKG_FLAG_MULTI_REQUIRED | \
39 SECPKG_FLAG_EXTENDED_ERROR | \
40 SECPKG_FLAG_IMPERSONATION | \
41 SECPKG_FLAG_ACCEPT_WIN32_NAME | \
42 SECPKG_FLAG_NEGOTIABLE | \
43 SECPKG_FLAG_GSS_COMPATIBLE | \
44 SECPKG_FLAG_LOGON )
45
46#define NTLM_BASE_CAPS ( \
47 SECPKG_FLAG_INTEGRITY | \
48 SECPKG_FLAG_PRIVACY | \
49 SECPKG_FLAG_TOKEN_ONLY | \
50 SECPKG_FLAG_CONNECTION | \
51 SECPKG_FLAG_MULTI_REQUIRED | \
52 SECPKG_FLAG_IMPERSONATION | \
53 SECPKG_FLAG_ACCEPT_WIN32_NAME | \
54 SECPKG_FLAG_NEGOTIABLE | \
55 SECPKG_FLAG_LOGON )
56
58{
65};
66
67static void cleanup_buffers( struct sspi_data *data )
68{
69 unsigned int i;
70
71 if (data->in_buf)
72 {
73 for (i = 0; i < data->in_buf->cBuffers; ++i)
74 HeapFree( GetProcessHeap(), 0, data->in_buf->pBuffers[i].pvBuffer );
75 HeapFree( GetProcessHeap(), 0, data->in_buf->pBuffers );
76 HeapFree( GetProcessHeap(), 0, data->in_buf );
77 }
78 if (data->out_buf)
79 {
80 for (i = 0; i < data->out_buf->cBuffers; ++i)
81 HeapFree( GetProcessHeap(), 0, data->out_buf->pBuffers[i].pvBuffer );
82 HeapFree( GetProcessHeap(), 0, data->out_buf->pBuffers );
83 HeapFree( GetProcessHeap(), 0, data->out_buf );
84 }
85}
86
88{
90
91 data->in_buf = HeapAlloc( GetProcessHeap(), 0, sizeof(SecBufferDesc) );
92 data->out_buf = HeapAlloc( GetProcessHeap(), 0, sizeof(SecBufferDesc) );
93 data->max_token = info->cbMaxToken;
94
95 data->in_buf->ulVersion = SECBUFFER_VERSION;
96 data->in_buf->cBuffers = 1;
97 data->in_buf->pBuffers = buffer;
98
99 buffer->cbBuffer = info->cbMaxToken;
100 buffer->BufferType = SECBUFFER_TOKEN;
101 buffer->pvBuffer = HeapAlloc( GetProcessHeap(), 0, info->cbMaxToken );
102
103 buffer = HeapAlloc( GetProcessHeap(), 0, sizeof(SecBuffer) );
104
105 data->out_buf->ulVersion = SECBUFFER_VERSION;
106 data->out_buf->cBuffers = 1;
107 data->out_buf->pBuffers = buffer;
108
109 buffer->cbBuffer = info->cbMaxToken;
110 buffer->BufferType = SECBUFFER_TOKEN;
111 buffer->pvBuffer = HeapAlloc( GetProcessHeap(), 0, info->cbMaxToken );
112}
113
115{
118 TimeStamp ttl;
119
120 trace( "setting up client\n" );
121
122 ret = QuerySecurityPackageInfoA( provider, &info );
123 ok( ret == SEC_E_OK, "QuerySecurityPackageInfo returned %08x\n", ret );
124
127
129 data->id, NULL, NULL, &data->cred, &ttl );
130 ok( ret == SEC_E_OK, "AcquireCredentialsHandleA returned %08x\n", ret );
131 return ret;
132}
133
135{
138 TimeStamp ttl;
139
140 trace( "setting up server\n" );
141
142 ret = QuerySecurityPackageInfoA( provider, &info );
143 ok( ret == SEC_E_OK, "QuerySecurityPackageInfo returned %08x\n", ret );
144
147
149 NULL, NULL, NULL, &data->cred, &ttl );
150 ok( ret == SEC_E_OK, "AcquireCredentialsHandleA returned %08x\n", ret );
151 return ret;
152}
153
155{
157 TimeStamp ttl;
158 ULONG attr;
159
160 trace( "running client for the %s time\n", first ? "first" : "second" );
161
162 data->out_buf->pBuffers[0].cbBuffer = data->max_token;
163 data->out_buf->pBuffers[0].BufferType = SECBUFFER_TOKEN;
164
165 ret = InitializeSecurityContextA( first ? &data->cred : NULL, first ? NULL : &data->ctxt,
166 NULL, 0, 0, SECURITY_NETWORK_DREP, first ? NULL : data->in_buf,
167 0, &data->ctxt, data->out_buf, &attr, &ttl );
169 {
170 CompleteAuthToken( &data->ctxt, data->out_buf );
173 else if (ret == SEC_I_COMPLETE_NEEDED)
174 ret = SEC_E_OK;
175 }
176 ok( data->out_buf->pBuffers[0].BufferType == SECBUFFER_TOKEN,
177 "buffer type changed from SECBUFFER_TOKEN to %u\n", data->out_buf->pBuffers[0].BufferType );
178 ok( data->out_buf->pBuffers[0].cbBuffer < data->max_token,
179 "InitializeSecurityContext didn't change buffer size\n" );
180 return ret;
181}
182
184{
186 TimeStamp ttl;
187 ULONG attr;
188
189 trace( "running server for the %s time\n", first ? "first" : "second" );
190
191 ret = AcceptSecurityContext( &data->cred, first ? NULL : &data->ctxt,
192 data->in_buf, 0, SECURITY_NETWORK_DREP,
193 &data->ctxt, data->out_buf, &attr, &ttl );
195 {
196 CompleteAuthToken( &data->ctxt, data->out_buf );
199 else if (ret == SEC_I_COMPLETE_NEEDED)
200 ret = SEC_E_OK;
201 }
202 return ret;
203}
204
205static void communicate( struct sspi_data *from, struct sspi_data *to )
206{
207 trace( "running communicate\n" );
208 memset( to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token );
209 memcpy( to->in_buf->pBuffers[0].pvBuffer, from->out_buf->pBuffers[0].pvBuffer,
210 from->out_buf->pBuffers[0].cbBuffer );
211 to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
212 memset( from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token );
213}
214
215static void test_authentication(void)
216{
218 status_s = SEC_I_CONTINUE_NEEDED, status;
219 struct sspi_data client, server;
224 BOOL first = TRUE;
225
226 memset(&client, 0, sizeof(client));
227 memset(&server, 0, sizeof(server));
228
229 id.User = (unsigned char *)"user";
230 id.UserLength = strlen( "user" );
231 id.Domain = (unsigned char *)"domain";
232 id.DomainLength = strlen( "domain" );
233 id.Password = (unsigned char *)"password";
234 id.PasswordLength = strlen( "password" );
236
237 client.id = &id;
238 if ((status = setup_client( &client, (SEC_CHAR *)"Negotiate" )))
239 {
240 skip( "setup_client returned %08x, skipping test\n", status );
241 return;
242 }
243 if ((status = setup_server( &server, (SEC_CHAR *)"Negotiate" )))
244 {
245 skip( "setup_server returned %08x, skipping test\n", status );
247 return;
248 }
249
250 while (status_c == SEC_I_CONTINUE_NEEDED && status_s == SEC_I_CONTINUE_NEEDED)
251 {
252 status_c = run_client( &client, first );
253 ok( status_c == SEC_E_OK || status_c == SEC_I_CONTINUE_NEEDED,
254 "client returned %08x, more tests will fail\n", status_c );
255
257
258 status_s = run_server( &server, first );
259 ok( status_s == SEC_E_OK || status_s == SEC_I_CONTINUE_NEEDED ||
260 status_s == SEC_E_LOGON_DENIED,
261 "server returned %08x, more tests will fail\n", status_s );
262
264 trace( "looping\n");
265 first = FALSE;
266 }
267 if (status_c != SEC_E_OK)
268 {
269 skip( "authentication failed, skipping remaining tests\n" );
270 goto done;
271 }
272
273 sizes.cbMaxToken = 0xdeadbeef;
274 sizes.cbMaxSignature = 0xdeadbeef;
275 sizes.cbSecurityTrailer = 0xdeadbeef;
276 sizes.cbBlockSize = 0xdeadbeef;
278 ok( status_c == SEC_E_OK, "pQueryContextAttributesA returned %08x\n", status_c );
279 ok( sizes.cbMaxToken == 2888 || sizes.cbMaxToken == 1904,
280 "expected 2888 or 1904, got %u\n", sizes.cbMaxToken );
281 ok( sizes.cbMaxSignature == 16, "expected 16, got %u\n", sizes.cbMaxSignature );
282 ok( sizes.cbSecurityTrailer == 16, "expected 16, got %u\n", sizes.cbSecurityTrailer );
283 ok( !sizes.cbBlockSize, "expected 0, got %u\n", sizes.cbBlockSize );
284
285 memset( &info, 0, sizeof(info) );
287 ok( status_c == SEC_E_OK, "QueryContextAttributesA returned %08x\n", status_c );
288
289 pi = info.PackageInfo;
290 ok( info.NegotiationState == SECPKG_NEGOTIATION_COMPLETE, "got %u\n", info.NegotiationState );
291 ok( pi != NULL, "expected non-NULL PackageInfo\n" );
292 if (pi)
293 {
294 UINT expected, got;
295 char *eob;
296
297 ok( pi->fCapabilities == NTLM_BASE_CAPS ||
299 pi->fCapabilities == (NTLM_BASE_CAPS|SECPKG_FLAG_RESTRICTED_TOKENS) ||
304 "got %08x\n", pi->fCapabilities );
305 ok( pi->wVersion == 1, "got %u\n", pi->wVersion );
306 ok( pi->wRPCID == RPC_C_AUTHN_WINNT, "got %u\n", pi->wRPCID );
307 ok( !lstrcmpA( pi->Name, "NTLM" ), "got %s\n", pi->Name );
308
309 expected = sizeof(*pi) + lstrlenA(pi->Name) + 1 + lstrlenA(pi->Comment) + 1;
310 got = HeapSize(GetProcessHeap(), 0, pi);
311 ok( got == expected, "got %u, expected %u\n", got, expected );
312 eob = (char *)pi + expected;
313 ok( pi->Name + lstrlenA(pi->Name) < eob, "Name doesn't fit into allocated block\n" );
314 ok( pi->Comment + lstrlenA(pi->Comment) < eob, "Comment doesn't fit into allocated block\n" );
315
317 ok( status == SEC_E_OK, "FreeContextBuffer error %#x\n", status );
318 }
319
320done:
323
324 if (client.ctxt.dwLower || client.ctxt.dwUpper)
325 {
326 status_c = DeleteSecurityContext( &client.ctxt );
327 ok( status_c == SEC_E_OK, "DeleteSecurityContext returned %08x\n", status_c );
328 }
329
330 if (server.ctxt.dwLower || server.ctxt.dwUpper)
331 {
332 status_s = DeleteSecurityContext( &server.ctxt );
333 ok( status_s == SEC_E_OK, "DeleteSecurityContext returned %08x\n", status_s );
334 }
335
336 if (client.cred.dwLower || client.cred.dwUpper)
337 {
338 status_c = FreeCredentialsHandle( &client.cred );
339 ok( status_c == SEC_E_OK, "FreeCredentialsHandle returned %08x\n", status_c );
340 }
341
342 if (server.cred.dwLower || server.cred.dwUpper)
343 {
344 status_s = FreeCredentialsHandle(&server.cred);
345 ok( status_s == SEC_E_OK, "FreeCredentialsHandle returned %08x\n", status_s );
346 }
347}
348
349START_TEST(negotiate)
350{
352
353 if (QuerySecurityPackageInfoA( (SEC_CHAR *)"Negotiate", &info ))
354 {
355 ok( 0, "Negotiate package not installed, skipping test\n" );
356 return;
357 }
358 ok( info->fCapabilities == NEGOTIATE_BASE_CAPS ||
363 "got %08x\n", info->fCapabilities );
364 ok( info->wVersion == 1, "got %u\n", info->wVersion );
365 ok( info->wRPCID == RPC_C_AUTHN_GSS_NEGOTIATE, "got %u\n", info->wRPCID );
366 ok( !lstrcmpA( info->Name, "Negotiate" ), "got %s\n", info->Name );
368
370}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint buffer
Definition: glext.h:5915
const GLint * first
Definition: glext.h:5794
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
BOOL expected
Definition: store.c:2063
static refpint_t pi[]
Definition: server.c:96
static void test_authentication(void)
Definition: negotiate.c:215
static SECURITY_STATUS run_server(struct sspi_data *data, BOOL first)
Definition: negotiate.c:183
static void cleanup_buffers(struct sspi_data *data)
Definition: negotiate.c:67
static SECURITY_STATUS setup_client(struct sspi_data *data, SEC_CHAR *provider)
Definition: negotiate.c:114
#define NTLM_BASE_CAPS
Definition: negotiate.c:46
#define NEGOTIATE_BASE_CAPS
Definition: negotiate.c:34
static void setup_buffers(struct sspi_data *data, SecPkgInfoA *info)
Definition: negotiate.c:87
static SECURITY_STATUS run_client(struct sspi_data *data, BOOL first)
Definition: negotiate.c:154
static void communicate(struct sspi_data *from, struct sspi_data *to)
Definition: negotiate.c:205
static SECURITY_STATUS setup_server(struct sspi_data *data, SEC_CHAR *provider)
Definition: negotiate.c:134
static const struct @542 sizes[]
unsigned int UINT
Definition: ndis.h:50
#define SECPKG_FLAG_APPCONTAINER_CHECKS
Definition: sspi.h:149
LONG SECURITY_STATUS
Definition: sspi.h:34
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:291
#define SECBUFFER_TOKEN
Definition: sspi.h:161
#define SECURITY_NETWORK_DREP
Definition: sspi.h:474
CHAR SEC_CHAR
Definition: sspi.h:30
#define SECPKG_FLAG_RESTRICTED_TOKENS
Definition: sspi.h:145
#define SECPKG_ATTR_NEGOTIATION_INFO
Definition: sspi.h:533
#define SECPKG_FLAG_APPLY_LOOPBACK
Definition: sspi.h:150
#define SECPKG_CRED_INBOUND
Definition: sspi.h:290
#define SECPKG_ATTR_SIZES
Definition: sspi.h:521
#define SECPKG_NEGOTIATION_COMPLETE
Definition: sspi.h:701
#define SECPKG_FLAG_READONLY_WITH_CHECKSUM
Definition: sspi.h:144
#define SECBUFFER_VERSION
Definition: sspi.h:187
#define SEC_WINNT_AUTH_IDENTITY_ANSI
Definition: rpcdce.h:309
#define RPC_C_AUTHN_WINNT
Definition: rpcdce.h:158
#define RPC_C_AUTHN_GSS_NEGOTIATE
Definition: rpcdce.h:157
#define memset(x, y, z)
Definition: compat.h:39
static FILE * client
Definition: client.c:41
CardRegion * from
Definition: spigame.cpp:19
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
Definition: cookie.c:202
PSecBufferDesc in_buf
Definition: negotiate.c:61
ULONG max_token
Definition: negotiate.c:64
CtxtHandle ctxt
Definition: negotiate.c:60
CredHandle cred
Definition: negotiate.c:59
PSEC_WINNT_AUTH_IDENTITY_A id
Definition: negotiate.c:63
PSecBufferDesc out_buf
Definition: negotiate.c:62
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
static rfbScreenInfoPtr server
Definition: vnc.c:74
int ret
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
#define SEC_E_OK
Definition: winerror.h:2356
#define SEC_E_LOGON_DENIED
Definition: winerror.h:2921
#define SEC_I_COMPLETE_NEEDED
Definition: winerror.h:2928
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
#define SEC_I_COMPLETE_AND_CONTINUE
Definition: winerror.h:2929
SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
Definition: wrapper.c:420
SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:505
SECURITY_STATUS WINAPI AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:365
SECURITY_STATUS WINAPI AcquireCredentialsHandleA(SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse, PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
Definition: wrapper.c:59
SECURITY_STATUS WINAPI InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:237
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName, PSecPkgInfoA *ppPackageInfo)
Definition: wrapper.c:683