- Remove redunant braces.
[wine] / dlls / secur32 / ntlm.c
1 /*
2  * Copyright 2005 Kai Blin
3  *
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.
8  *
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.
13  *
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
17  *
18  * This file implements the NTLM security provider.
19  * FIXME: So far, this beast doesn't do anything.
20  */
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"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
30
31 static char ntlm_name_A[] = "NTLM";
32 static WCHAR ntlm_name_W[] = {'N', 'T', 'L', 'M', 0};
33
34
35 /***********************************************************************
36  *              QueryCredentialsAttributesA
37  */
38 static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(
39         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
40 {
41     SECURITY_STATUS ret;
42
43     TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
44
45     if(ulAttribute == SECPKG_ATTR_NAMES)
46     {
47         FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
48         ret = SEC_E_UNSUPPORTED_FUNCTION;
49     }
50     else
51         ret = SEC_E_UNSUPPORTED_FUNCTION;
52     
53     return ret;
54 }
55
56 /***********************************************************************
57  *              QueryCredentialsAttributesW
58  */
59 static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW(
60         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
61 {
62     SECURITY_STATUS ret;
63
64     TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
65
66     if(ulAttribute == SECPKG_ATTR_NAMES)
67     {
68         FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
69         ret = SEC_E_UNSUPPORTED_FUNCTION;
70     }
71     else
72         ret = SEC_E_UNSUPPORTED_FUNCTION;
73     
74     return ret;
75 }
76
77 static SECURITY_STATUS ntlm_AcquireCredentialsHandle(ULONG fCredentialsUse,
78         PCredHandle phCredential, PTimeStamp ptsExpiry)
79 {
80     SECURITY_STATUS ret;
81
82     if(fCredentialsUse == SECPKG_CRED_BOTH)
83     {
84         ret = SEC_E_NO_CREDENTIALS;
85     }
86     else
87     {
88         /* Ok, just store the direction like schannel does for now.
89          * FIXME: This should probably do something useful later on
90          */
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;
97     }
98     return ret;
99 }
100
101 /***********************************************************************
102  *              AcquireCredentialsHandleA
103  */
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)
108 {
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);
114 }
115
116 /***********************************************************************
117  *              AcquireCredentialsHandleW
118  */
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)
123 {
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);
129 }
130
131 /***********************************************************************
132  *              InitializeSecurityContextA
133  */
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)
139 {
140     SECURITY_STATUS ret;
141
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;
147     }
148     else
149     {
150         ret = SEC_E_INVALID_HANDLE;
151     }
152     return ret;
153 }
154
155 /***********************************************************************
156  *              InitializeSecurityContextW
157  */
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)
163 {
164     SECURITY_STATUS ret;
165
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)
170     {
171         ret = SEC_E_UNSUPPORTED_FUNCTION;
172     }
173     else
174     {
175         ret = SEC_E_INVALID_HANDLE;
176     }
177     return ret;
178 }
179
180 /***********************************************************************
181  *              AcceptSecurityContext
182  */
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)
187 {
188     SECURITY_STATUS ret;
189
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)
194     {
195         ret = SEC_E_UNSUPPORTED_FUNCTION;
196     }
197     else
198     {
199         ret = SEC_E_INVALID_HANDLE;
200     }
201     return ret;
202 }
203
204 /***********************************************************************
205  *              CompleteAuthToken
206  */
207 static SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken(PCtxtHandle phContext,
208  PSecBufferDesc pToken)
209 {
210     SECURITY_STATUS ret;
211
212     TRACE("%p %p\n", phContext, pToken);
213     if (phContext)
214     {
215         ret = SEC_E_UNSUPPORTED_FUNCTION;
216     }
217     else
218     {
219         ret = SEC_E_INVALID_HANDLE;
220     }
221     return ret;
222 }
223
224 /***********************************************************************
225  *              DeleteSecurityContext
226  */
227 static SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
228 {
229     SECURITY_STATUS ret;
230
231     TRACE("%p\n", phContext);
232     if (phContext)
233     {
234         ret = SEC_E_UNSUPPORTED_FUNCTION;
235     }
236     else
237     {
238         ret = SEC_E_INVALID_HANDLE;
239     }
240     return ret;
241 }
242
243 /***********************************************************************
244  *              ApplyControlToken
245  */
246 static SECURITY_STATUS SEC_ENTRY ntlm_ApplyControlToken(PCtxtHandle phContext,
247  PSecBufferDesc pInput)
248 {
249     SECURITY_STATUS ret;
250
251     TRACE("%p %p\n", phContext, pInput);
252     if (phContext)
253     {
254         ret = SEC_E_UNSUPPORTED_FUNCTION;
255     }
256     else
257     {
258         ret = SEC_E_INVALID_HANDLE;
259     }
260     return ret;
261 }
262
263 /***********************************************************************
264  *              QueryContextAttributesW
265  */
266 static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext,
267  unsigned long ulAttribute, void *pBuffer)
268 {
269     SECURITY_STATUS ret;
270
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.
274      */
275     TRACE("%p %ld %p\n", phContext, ulAttribute, pBuffer);
276     if (phContext)
277     {
278         ret = SEC_E_UNSUPPORTED_FUNCTION;
279     }
280     else
281     {
282         ret = SEC_E_INVALID_HANDLE;
283     }
284     return ret;
285 }
286
287 /***********************************************************************
288  *              QueryContextAttributesA
289  */
290 static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext,
291  unsigned long ulAttribute, void *pBuffer)
292 {
293     return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
294 }
295
296 /***********************************************************************
297  *              ImpersonateSecurityContext
298  */
299 static SECURITY_STATUS SEC_ENTRY ntlm_ImpersonateSecurityContext(PCtxtHandle phContext)
300 {
301     SECURITY_STATUS ret;
302
303     TRACE("%p\n", phContext);
304     if (phContext)
305     {
306         ret = SEC_E_UNSUPPORTED_FUNCTION;
307     }
308     else
309     {
310         ret = SEC_E_INVALID_HANDLE;
311     }
312     return ret;
313 }
314
315 /***********************************************************************
316  *              RevertSecurityContext
317  */
318 static SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext(PCtxtHandle phContext)
319 {
320     SECURITY_STATUS ret;
321
322     TRACE("%p\n", phContext);
323     if (phContext)
324     {
325         ret = SEC_E_UNSUPPORTED_FUNCTION;
326     }
327     else
328     {
329         ret = SEC_E_INVALID_HANDLE;
330     }
331     return ret;
332 }
333
334 /***********************************************************************
335  *              MakeSignature
336  */
337 static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
338  PSecBufferDesc pMessage, ULONG MessageSeqNo)
339 {
340     SECURITY_STATUS ret;
341
342     TRACE("%p %ld %p %ld\n", phContext, fQOP, pMessage, MessageSeqNo);
343     if (phContext)
344     {
345         ret = SEC_E_UNSUPPORTED_FUNCTION;
346     }
347     else
348     {
349         ret = SEC_E_INVALID_HANDLE;
350     }
351     return ret;
352 }
353
354 /***********************************************************************
355  *              VerifySignature
356  */
357 static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext,
358  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
359 {
360     SECURITY_STATUS ret;
361
362     TRACE("%p %p %ld %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
363     if (phContext)
364     {
365         ret = SEC_E_UNSUPPORTED_FUNCTION;
366     }
367     else
368     {
369         ret = SEC_E_INVALID_HANDLE;
370     }
371     return ret;
372 }
373
374
375
376 static SecurityFunctionTableA negoTableA = {
377     1,
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 */
405 };
406
407 static SecurityFunctionTableW negoTableW = {
408     1,
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 */
436 };
437
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};
440
441 static CHAR ntlm_comment_A[] = "NTLM Security Package";
442
443 void SECUR32_initNTLMSP(void)
444 {
445     SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW,
446             NULL);
447     /* According to Windows, NTLM has the following capabilities. 
448      */
449     
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;
459
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};
467
468     SECUR32_addPackages(provider, 1L, &infoA, &infoW);        
469     
470 }