ReactOS  0.4.14-dev-77-gd9e7c48
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 
57 struct sspi_data
58 {
65 };
66 
67 static 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 
87 static void setup_buffers( struct sspi_data *data, SecPkgInfoA *info )
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 
114 static SECURITY_STATUS setup_client( struct sspi_data *data, SEC_CHAR *provider )
115 {
117  SecPkgInfoA *info;
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 
125  setup_buffers( data, info );
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 
134 static SECURITY_STATUS setup_server( struct sspi_data *data, SEC_CHAR *provider )
135 {
137  SecPkgInfoA *info;
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 
145  setup_buffers( data, info );
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 
205 static 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 
215 static void test_authentication(void)
216 {
218  status_s = SEC_I_CONTINUE_NEEDED, status;
219  struct sspi_data client, server;
223  SecPkgInfoA *pi;
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" );
235  id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
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 );
246  FreeCredentialsHandle( &client.cred );
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 
256  communicate( &client, &server );
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 
263  communicate( &server, &client );
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;
277  status_c = QueryContextAttributesA( &client.ctxt, SECPKG_ATTR_SIZES, &sizes );
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) ||
302  "got %08x\n", pi->fCapabilities );
303  ok( pi->wVersion == 1, "got %u\n", pi->wVersion );
304  ok( pi->wRPCID == RPC_C_AUTHN_WINNT, "got %u\n", pi->wRPCID );
305  ok( !lstrcmpA( pi->Name, "NTLM" ), "got %s\n", pi->Name );
306 
307  expected = sizeof(*pi) + lstrlenA(pi->Name) + 1 + lstrlenA(pi->Comment) + 1;
308  got = HeapSize(GetProcessHeap(), 0, pi);
309  ok( got == expected, "got %u, expected %u\n", got, expected );
310  eob = (char *)pi + expected;
311  ok( pi->Name + lstrlenA(pi->Name) < eob, "Name doesn't fit into allocated block\n" );
312  ok( pi->Comment + lstrlenA(pi->Comment) < eob, "Comment doesn't fit into allocated block\n" );
313 
315  ok( status == SEC_E_OK, "FreeContextBuffer error %#x\n", status );
316  }
317 
318 done:
321 
322  if (client.ctxt.dwLower || client.ctxt.dwUpper)
323  {
324  status_c = DeleteSecurityContext( &client.ctxt );
325  ok( status_c == SEC_E_OK, "DeleteSecurityContext returned %08x\n", status_c );
326  }
327 
328  if (server.ctxt.dwLower || server.ctxt.dwUpper)
329  {
330  status_s = DeleteSecurityContext( &server.ctxt );
331  ok( status_s == SEC_E_OK, "DeleteSecurityContext returned %08x\n", status_s );
332  }
333 
334  if (client.cred.dwLower || client.cred.dwUpper)
335  {
336  status_c = FreeCredentialsHandle( &client.cred );
337  ok( status_c == SEC_E_OK, "FreeCredentialsHandle returned %08x\n", status_c );
338  }
339 
340  if (server.cred.dwLower || server.cred.dwUpper)
341  {
342  status_s = FreeCredentialsHandle(&server.cred);
343  ok( status_s == SEC_E_OK, "FreeCredentialsHandle returned %08x\n", status_s );
344  }
345 }
346 
347 START_TEST(negotiate)
348 {
349  SecPkgInfoA *info;
350 
351  if (QuerySecurityPackageInfoA( (SEC_CHAR *)"Negotiate", &info ))
352  {
353  ok( 0, "Negotiate package not installed, skipping test\n" );
354  return;
355  }
356  ok( info->fCapabilities == NEGOTIATE_BASE_CAPS ||
361  "got %08x\n", info->fCapabilities );
362  ok( info->wVersion == 1, "got %u\n", info->wVersion );
363  ok( info->wRPCID == RPC_C_AUTHN_GSS_NEGOTIATE, "got %u\n", info->wRPCID );
364  ok( !lstrcmpA( info->Name, "Negotiate" ), "got %s\n", info->Name );
366 
368 }
#define RPC_C_AUTHN_WINNT
Definition: rpcdce.h:158
#define TRUE
Definition: types.h:120
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:277
static rfbScreenInfoPtr server
Definition: vnc.c:74
#define SECPKG_NEGOTIATION_COMPLETE
Definition: sspi.h:687
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
static void cleanup_buffers(struct sspi_data *data)
Definition: negotiate.c:67
static void communicate(struct sspi_data *from, struct sspi_data *to)
Definition: negotiate.c:205
const GLint * first
Definition: glext.h:5794
PSecBufferDesc out_buf
Definition: negotiate.c:62
#define SECPKG_FLAG_RESTRICTED_TOKENS
Definition: sspi.h:132
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
static SECURITY_STATUS setup_client(struct sspi_data *data, SEC_CHAR *provider)
Definition: negotiate.c:114
GLuint buffer
Definition: glext.h:5915
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
#define NTLM_BASE_CAPS
Definition: negotiate.c:46
#define NEGOTIATE_BASE_CAPS
Definition: negotiate.c:34
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
#define SECPKG_FLAG_READONLY_WITH_CHECKSUM
Definition: sspi.h:131
struct _test_info info[]
Definition: SetCursorPos.c:19
#define SEC_E_LOGON_DENIED
Definition: winerror.h:2921
CtxtHandle ctxt
Definition: negotiate.c:60
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
#define SECPKG_ATTR_SIZES
Definition: sspi.h:507
unsigned int BOOL
Definition: ntddk_ex.h:94
SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
Definition: wrapper.c:420
#define SECPKG_CRED_INBOUND
Definition: sspi.h:276
smooth NULL
Definition: ftsmooth.c:416
#define SEC_I_COMPLETE_NEEDED
Definition: winerror.h:2928
#define SECPKG_ATTR_NEGOTIATION_INFO
Definition: sspi.h:519
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
LONG SECURITY_STATUS
Definition: sspi.h:34
ULONG max_token
Definition: negotiate.c:64
static void test_authentication(void)
Definition: negotiate.c:215
#define RPC_C_AUTHN_GSS_NEGOTIATE
Definition: rpcdce.h:157
#define GetProcessHeap()
Definition: compat.h:395
#define trace
Definition: atltest.h:70
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static SECURITY_STATUS run_server(struct sspi_data *data, BOOL first)
Definition: negotiate.c:183
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
CredHandle cred
Definition: negotiate.c:59
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 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
static FILE * client
Definition: client.c:41
static void setup_buffers(struct sspi_data *data, SecPkgInfoA *info)
Definition: negotiate.c:87
Definition: cookie.c:170
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static DWORD pi
Definition: protocol.c:150
int ret
static const struct @514 sizes[]
__u8 attr
Definition: mkdosfs.c:359
SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: wrapper.c:505
#define SECBUFFER_TOKEN
Definition: sspi.h:147
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define SECURITY_NETWORK_DREP
Definition: sspi.h:460
#define SEC_E_OK
Definition: winerror.h:2356
static SECURITY_STATUS run_client(struct sspi_data *data, BOOL first)
Definition: negotiate.c:154
#define SEC_WINNT_AUTH_IDENTITY_ANSI
Definition: rpcdce.h:309
START_TEST(negotiate)
Definition: negotiate.c:347
PSecBufferDesc in_buf
Definition: negotiate.c:61
static SECURITY_STATUS setup_server(struct sspi_data *data, SEC_CHAR *provider)
Definition: negotiate.c:134
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define SECBUFFER_VERSION
Definition: sspi.h:173
SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName, PSecPkgInfoA *ppPackageInfo)
Definition: wrapper.c:683
PSEC_WINNT_AUTH_IDENTITY_A id
Definition: negotiate.c:63
#define ok(value,...)
Definition: atltest.h:57
unsigned int UINT
Definition: ndis.h:50
CHAR SEC_CHAR
Definition: sspi.h:30
#define SECPKG_FLAG_APPCONTAINER_CHECKS
Definition: sspi.h:136
#define skip(...)
Definition: atltest.h:64
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
CardRegion * from
Definition: spigame.cpp:19
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
#define HeapFree(x, y, z)
Definition: compat.h:394
BOOL expected
Definition: store.c:2063
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
#define SEC_I_COMPLETE_AND_CONTINUE
Definition: winerror.h:2929
Definition: ps.c:97