Added some tests for VerFindFileA.
[wine/wine-gecko.git] / dlls / secur32 / ntlm.c
blob4bad3e8c0024f30ee48e1018f5c0d92fcef377af
1 /*
2 * Copyright 2005 Kai Blin
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * This file implements the NTLM security provider.
19 * FIXME: So far, this beast doesn't do anything.
21 #include <assert.h>
22 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "sspi.h"
26 #include "secur32_priv.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
31 static char ntlm_name_A[] = "NTLM";
32 static WCHAR ntlm_name_W[] = {'N', 'T', 'L', 'M', 0};
35 /***********************************************************************
36 * QueryCredentialsAttributesA
38 static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(
39 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
41 SECURITY_STATUS ret;
43 TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
45 if(ulAttribute == SECPKG_ATTR_NAMES)
47 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
48 ret = SEC_E_UNSUPPORTED_FUNCTION;
50 else
51 ret = SEC_E_UNSUPPORTED_FUNCTION;
53 return ret;
56 /***********************************************************************
57 * QueryCredentialsAttributesW
59 static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW(
60 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
62 SECURITY_STATUS ret;
64 TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
66 if(ulAttribute == SECPKG_ATTR_NAMES)
68 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
69 ret = SEC_E_UNSUPPORTED_FUNCTION;
71 else
72 ret = SEC_E_UNSUPPORTED_FUNCTION;
74 return ret;
77 static SECURITY_STATUS ntlm_AcquireCredentialsHandle(ULONG fCredentialsUse,
78 PCredHandle phCredential, PTimeStamp ptsExpiry)
80 SECURITY_STATUS ret;
82 if(fCredentialsUse == SECPKG_CRED_BOTH)
84 ret = SEC_E_NO_CREDENTIALS;
86 else
88 /* Ok, just store the direction like schannel does for now.
89 * FIXME: This should probably do something useful later on
91 phCredential->dwUpper = fCredentialsUse;
92 phCredential->dwLower = 0;
93 /* Same here, shamelessly stolen from schannel.c */
94 if (ptsExpiry)
95 ptsExpiry->QuadPart = 0;
96 ret = SEC_E_OK;
98 return ret;
101 /***********************************************************************
102 * AcquireCredentialsHandleA
104 static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(
105 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
106 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
107 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
109 TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
110 debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
111 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
112 return ntlm_AcquireCredentialsHandle(fCredentialUse, phCredential,
113 ptsExpiry);
116 /***********************************************************************
117 * AcquireCredentialsHandleW
119 static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(
120 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
121 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
122 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
124 TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
125 debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
126 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
127 return ntlm_AcquireCredentialsHandle(fCredentialUse, phCredential,
128 ptsExpiry);
131 /***********************************************************************
132 * InitializeSecurityContextA
134 static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(
135 PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
136 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
137 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
138 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
140 SECURITY_STATUS ret;
142 TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
143 debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
144 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
145 if(phCredential){
146 ret = SEC_E_UNSUPPORTED_FUNCTION;
148 else
150 ret = SEC_E_INVALID_HANDLE;
152 return ret;
155 /***********************************************************************
156 * InitializeSecurityContextW
158 static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
159 PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
160 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
161 PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext,
162 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
164 SECURITY_STATUS ret;
166 TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
167 debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
168 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
169 if (phCredential)
171 ret = SEC_E_UNSUPPORTED_FUNCTION;
173 else
175 ret = SEC_E_INVALID_HANDLE;
177 return ret;
180 /***********************************************************************
181 * AcceptSecurityContext
183 static SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(
184 PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
185 ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
186 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
188 SECURITY_STATUS ret;
190 TRACE("%p %p %p %ld %ld %p %p %p %p\n", phCredential, phContext, pInput,
191 fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
192 ptsExpiry);
193 if (phCredential)
195 ret = SEC_E_UNSUPPORTED_FUNCTION;
197 else
199 ret = SEC_E_INVALID_HANDLE;
201 return ret;
204 /***********************************************************************
205 * CompleteAuthToken
207 static SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken(PCtxtHandle phContext,
208 PSecBufferDesc pToken)
210 SECURITY_STATUS ret;
212 TRACE("%p %p\n", phContext, pToken);
213 if (phContext)
215 ret = SEC_E_UNSUPPORTED_FUNCTION;
217 else
219 ret = SEC_E_INVALID_HANDLE;
221 return ret;
224 /***********************************************************************
225 * DeleteSecurityContext
227 static SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
229 SECURITY_STATUS ret;
231 TRACE("%p\n", phContext);
232 if (phContext)
234 ret = SEC_E_UNSUPPORTED_FUNCTION;
236 else
238 ret = SEC_E_INVALID_HANDLE;
240 return ret;
243 /***********************************************************************
244 * ApplyControlToken
246 static SECURITY_STATUS SEC_ENTRY ntlm_ApplyControlToken(PCtxtHandle phContext,
247 PSecBufferDesc pInput)
249 SECURITY_STATUS ret;
251 TRACE("%p %p\n", phContext, pInput);
252 if (phContext)
254 ret = SEC_E_UNSUPPORTED_FUNCTION;
256 else
258 ret = SEC_E_INVALID_HANDLE;
260 return ret;
263 /***********************************************************************
264 * QueryContextAttributesW
266 static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext,
267 unsigned long ulAttribute, void *pBuffer)
269 SECURITY_STATUS ret;
271 /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is
272 * the SecurePackage part and the dwLower part is the actual context
273 * handle. It should be easy to extract the context attributes from that.
275 TRACE("%p %ld %p\n", phContext, ulAttribute, pBuffer);
276 if (phContext)
278 ret = SEC_E_UNSUPPORTED_FUNCTION;
280 else
282 ret = SEC_E_INVALID_HANDLE;
284 return ret;
287 /***********************************************************************
288 * QueryContextAttributesA
290 static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext,
291 unsigned long ulAttribute, void *pBuffer)
293 return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
296 /***********************************************************************
297 * ImpersonateSecurityContext
299 static SECURITY_STATUS SEC_ENTRY ntlm_ImpersonateSecurityContext(PCtxtHandle phContext)
301 SECURITY_STATUS ret;
303 TRACE("%p\n", phContext);
304 if (phContext)
306 ret = SEC_E_UNSUPPORTED_FUNCTION;
308 else
310 ret = SEC_E_INVALID_HANDLE;
312 return ret;
315 /***********************************************************************
316 * RevertSecurityContext
318 static SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext(PCtxtHandle phContext)
320 SECURITY_STATUS ret;
322 TRACE("%p\n", phContext);
323 if (phContext)
325 ret = SEC_E_UNSUPPORTED_FUNCTION;
327 else
329 ret = SEC_E_INVALID_HANDLE;
331 return ret;
334 /***********************************************************************
335 * MakeSignature
337 static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
338 PSecBufferDesc pMessage, ULONG MessageSeqNo)
340 SECURITY_STATUS ret;
342 TRACE("%p %ld %p %ld\n", phContext, fQOP, pMessage, MessageSeqNo);
343 if (phContext)
345 ret = SEC_E_UNSUPPORTED_FUNCTION;
347 else
349 ret = SEC_E_INVALID_HANDLE;
351 return ret;
354 /***********************************************************************
355 * VerifySignature
357 static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext,
358 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
360 SECURITY_STATUS ret;
362 TRACE("%p %p %ld %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
363 if (phContext)
365 ret = SEC_E_UNSUPPORTED_FUNCTION;
367 else
369 ret = SEC_E_INVALID_HANDLE;
371 return ret;
376 static SecurityFunctionTableA negoTableA = {
378 NULL, /* EnumerateSecurityPackagesA */
379 ntlm_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */
380 ntlm_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */
381 FreeCredentialsHandle, /* FreeCredentialsHandle */
382 NULL, /* Reserved2 */
383 ntlm_InitializeSecurityContextA, /* InitializeSecurityContextA */
384 ntlm_AcceptSecurityContext, /* AcceptSecurityContext */
385 ntlm_CompleteAuthToken, /* CompleteAuthToken */
386 ntlm_DeleteSecurityContext, /* DeleteSecurityContext */
387 ntlm_ApplyControlToken, /* ApplyControlToken */
388 ntlm_QueryContextAttributesA, /* QueryContextAttributesA */
389 ntlm_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
390 ntlm_RevertSecurityContext, /* RevertSecurityContext */
391 ntlm_MakeSignature, /* MakeSignature */
392 ntlm_VerifySignature, /* VerifySignature */
393 FreeContextBuffer, /* FreeContextBuffer */
394 NULL, /* QuerySecurityPackageInfoA */
395 NULL, /* Reserved3 */
396 NULL, /* Reserved4 */
397 NULL, /* ExportSecurityContext */
398 NULL, /* ImportSecurityContextA */
399 NULL, /* AddCredentialsA */
400 NULL, /* Reserved8 */
401 NULL, /* QuerySecurityContextToken */
402 NULL, /* EncryptMessage */
403 NULL, /* DecryptMessage */
404 NULL, /* SetContextAttributesA */
407 static SecurityFunctionTableW negoTableW = {
409 NULL, /* EnumerateSecurityPackagesW */
410 ntlm_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */
411 ntlm_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */
412 FreeCredentialsHandle, /* FreeCredentialsHandle */
413 NULL, /* Reserved2 */
414 ntlm_InitializeSecurityContextW, /* InitializeSecurityContextW */
415 ntlm_AcceptSecurityContext, /* AcceptSecurityContext */
416 ntlm_CompleteAuthToken, /* CompleteAuthToken */
417 ntlm_DeleteSecurityContext, /* DeleteSecurityContext */
418 ntlm_ApplyControlToken, /* ApplyControlToken */
419 ntlm_QueryContextAttributesW, /* QueryContextAttributesW */
420 ntlm_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
421 ntlm_RevertSecurityContext, /* RevertSecurityContext */
422 ntlm_MakeSignature, /* MakeSignature */
423 ntlm_VerifySignature, /* VerifySignature */
424 FreeContextBuffer, /* FreeContextBuffer */
425 NULL, /* QuerySecurityPackageInfoW */
426 NULL, /* Reserved3 */
427 NULL, /* Reserved4 */
428 NULL, /* ExportSecurityContext */
429 NULL, /* ImportSecurityContextW */
430 NULL, /* AddCredentialsW */
431 NULL, /* Reserved8 */
432 NULL, /* QuerySecurityContextToken */
433 NULL, /* EncryptMessage */
434 NULL, /* DecryptMessage */
435 NULL, /* SetContextAttributesW */
438 static WCHAR ntlm_comment_W[] = { 'N', 'T', 'L', 'M', ' ', 'S', 'e',
439 'c', 'u', 'r', 'i', 't', 'y', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e',0};
441 static CHAR ntlm_comment_A[] = "NTLM Security Package";
443 void SECUR32_initNTLMSP(void)
445 SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW,
446 NULL);
447 /* According to Windows, NTLM has the following capabilities.
450 static const LONG caps =
451 SECPKG_FLAG_INTEGRITY |
452 SECPKG_FLAG_PRIVACY |
453 SECPKG_FLAG_TOKEN_ONLY |
454 SECPKG_FLAG_CONNECTION |
455 SECPKG_FLAG_MULTI_REQUIRED |
456 SECPKG_FLAG_IMPERSONATION |
457 SECPKG_FLAG_ACCEPT_WIN32_NAME |
458 SECPKG_FLAG_READONLY_WITH_CHECKSUM;
460 static const USHORT version = 1;
461 static const USHORT rpcid = 10;
462 static const ULONG max_token = 12000;
463 const SecPkgInfoW infoW = { caps, version, rpcid, max_token, ntlm_name_W,
464 ntlm_comment_W};
465 const SecPkgInfoA infoA = { caps, version, rpcid, max_token, ntlm_name_A,
466 ntlm_comment_A};
468 SECUR32_addPackages(provider, 1L, &infoA, &infoW);