configure: Use --rpath when linking dlls too.
[wine] / dlls / secur32 / negotiate.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 negotiate 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 nego_name_A[] = "Negotiate";
32 static WCHAR nego_name_W[] = {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0};
33
34 static SECURITY_STATUS nego_QueryCredentialsAttributes(PCredHandle phCredential,
35         ULONG ulAttribute, PVOID pBuffer)
36 {
37     SECURITY_STATUS ret;
38
39     /* FIXME: More attributes to be added here. Need to fix the sspi.h header
40      * for that, too.
41      */
42     switch(ulAttribute)
43     {
44         default:
45             ret = SEC_E_UNSUPPORTED_FUNCTION;
46     }
47     return ret;
48 }
49
50 /***********************************************************************
51  *              QueryCredentialsAttributesA
52  */
53 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA(
54         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
55 {
56     SECURITY_STATUS ret;
57
58     TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
59
60     switch(ulAttribute)
61     {
62         case SECPKG_CRED_ATTR_NAMES:
63             FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
64             ret = SEC_E_UNSUPPORTED_FUNCTION;
65             break;
66         default:
67             ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
68                     pBuffer);
69     }
70     return ret;
71 }
72
73 /***********************************************************************
74  *              QueryCredentialsAttributesW
75  */
76 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW(
77         PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
78 {
79     SECURITY_STATUS ret;
80
81     TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
82
83     switch(ulAttribute)
84     {
85         case SECPKG_CRED_ATTR_NAMES:
86             FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
87             ret = SEC_E_UNSUPPORTED_FUNCTION;
88             break;
89         default:
90             ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
91                     pBuffer);
92     }
93     return ret;
94 }
95
96 static SECURITY_STATUS nego_AcquireCredentialsHandle(ULONG fCredentialsUse,
97         PCredHandle phCredential, PTimeStamp ptsExpiry)
98 {
99     SECURITY_STATUS ret;
100
101     if(fCredentialsUse == SECPKG_CRED_BOTH)
102     {
103         ret = SEC_E_NO_CREDENTIALS;
104     }
105     else
106     {
107         /* Ok, just store the direction like schannel does for now.
108          * FIXME: This should probably do something useful later on
109          */
110         phCredential->dwUpper = fCredentialsUse;
111         /* Same here, shamelessly stolen from schannel.c */
112         if (ptsExpiry)
113             ptsExpiry->QuadPart = 0;
114         ret = SEC_E_OK;
115     }
116     return ret;
117 }
118
119 /***********************************************************************
120  *              AcquireCredentialsHandleA
121  */
122 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
123  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
124  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
125  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
126 {
127     TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
128      debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
129      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
130     return nego_AcquireCredentialsHandle(fCredentialUse, phCredential,
131             ptsExpiry);
132 }
133
134 /***********************************************************************
135  *              AcquireCredentialsHandleW
136  */
137 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
138  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
139  PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
140  PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
141 {
142     TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
143      debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
144      pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
145     return nego_AcquireCredentialsHandle(fCredentialUse, phCredential,
146             ptsExpiry);
147 }
148
149 /***********************************************************************
150  *              InitializeSecurityContextA
151  */
152 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
153  PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, 
154  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
155  PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, 
156  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
157 {
158     SECURITY_STATUS ret;
159
160     TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
161      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
162      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
163     if(phCredential){
164         ret = SEC_E_UNSUPPORTED_FUNCTION;
165     }
166     else
167     {
168         ret = SEC_E_INVALID_HANDLE;
169     }
170     return ret;
171 }
172
173 /***********************************************************************
174  *              InitializeSecurityContextW
175  */
176 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
177  PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
178  ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
179  PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext, 
180  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
181 {
182     SECURITY_STATUS ret;
183
184     TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
185      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
186      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
187     if (phCredential)
188     {
189         ret = SEC_E_UNSUPPORTED_FUNCTION;
190     }
191     else
192     {
193         ret = SEC_E_INVALID_HANDLE;
194     }
195     return ret;
196 }
197
198 /***********************************************************************
199  *              AcceptSecurityContext
200  */
201 static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
202  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
203  ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, 
204  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
205 {
206     SECURITY_STATUS ret;
207
208     TRACE("%p %p %p %ld %ld %p %p %p %p\n", phCredential, phContext, pInput,
209      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
210      ptsExpiry);
211     if (phCredential)
212     {
213         ret = SEC_E_UNSUPPORTED_FUNCTION;
214     }
215     else
216     {
217         ret = SEC_E_INVALID_HANDLE;
218     }
219     return ret;
220 }
221
222 /***********************************************************************
223  *              CompleteAuthToken
224  */
225 static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
226  PSecBufferDesc pToken)
227 {
228     SECURITY_STATUS ret;
229
230     TRACE("%p %p\n", phContext, pToken);
231     if (phContext)
232     {
233         ret = SEC_E_UNSUPPORTED_FUNCTION;
234     }
235     else
236     {
237         ret = SEC_E_INVALID_HANDLE;
238     }
239     return ret;
240 }
241
242 /***********************************************************************
243  *              DeleteSecurityContext
244  */
245 static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
246 {
247     SECURITY_STATUS ret;
248
249     TRACE("%p\n", phContext);
250     if (phContext)
251     {
252         ret = SEC_E_UNSUPPORTED_FUNCTION;
253     }
254     else
255     {
256         ret = SEC_E_INVALID_HANDLE;
257     }
258     return ret;
259 }
260
261 /***********************************************************************
262  *              ApplyControlToken
263  */
264 static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
265  PSecBufferDesc pInput)
266 {
267     SECURITY_STATUS ret;
268
269     TRACE("%p %p\n", phContext, pInput);
270     if (phContext)
271     {
272         ret = SEC_E_UNSUPPORTED_FUNCTION;
273     }
274     else
275     {
276         ret = SEC_E_INVALID_HANDLE;
277     }
278     return ret;
279 }
280
281 /***********************************************************************
282  *              QueryContextAttributesW
283  */
284 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phContext,
285  unsigned long ulAttribute, void *pBuffer)
286 {
287     SECURITY_STATUS ret;
288
289     /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is
290      * the SecurePackage part and the dwLower part is the actual context 
291      * handle. It should be easy to extract the context attributes from that.
292      */
293     TRACE("%p %ld %p\n", phContext, ulAttribute, pBuffer);
294     if (phContext)
295     {
296         ret = SEC_E_UNSUPPORTED_FUNCTION;
297     }
298     else
299     {
300         ret = SEC_E_INVALID_HANDLE;
301     }
302     return ret;
303 }
304
305 /***********************************************************************
306  *              QueryContextAttributesA
307  */
308 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
309  unsigned long ulAttribute, void *pBuffer)
310 {
311     return nego_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
312 }
313
314 /***********************************************************************
315  *              ImpersonateSecurityContext
316  */
317 static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
318 {
319     SECURITY_STATUS ret;
320
321     TRACE("%p\n", phContext);
322     if (phContext)
323     {
324         ret = SEC_E_UNSUPPORTED_FUNCTION;
325     }
326     else
327     {
328         ret = SEC_E_INVALID_HANDLE;
329     }
330     return ret;
331 }
332
333 /***********************************************************************
334  *              RevertSecurityContext
335  */
336 static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
337 {
338     SECURITY_STATUS ret;
339
340     TRACE("%p\n", phContext);
341     if (phContext)
342     {
343         ret = SEC_E_UNSUPPORTED_FUNCTION;
344     }
345     else
346     {
347         ret = SEC_E_INVALID_HANDLE;
348     }
349     return ret;
350 }
351
352 /***********************************************************************
353  *              MakeSignature
354  */
355 static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
356  PSecBufferDesc pMessage, ULONG MessageSeqNo)
357 {
358     SECURITY_STATUS ret;
359
360     TRACE("%p %ld %p %ld\n", phContext, fQOP, pMessage, MessageSeqNo);
361     if (phContext)
362     {
363         ret = SEC_E_UNSUPPORTED_FUNCTION;
364     }
365     else
366     {
367         ret = SEC_E_INVALID_HANDLE;
368     }
369     return ret;
370 }
371
372 /***********************************************************************
373  *              VerifySignature
374  */
375 static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
376  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
377 {
378     SECURITY_STATUS ret;
379
380     TRACE("%p %p %ld %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
381     if (phContext)
382     {
383         ret = SEC_E_UNSUPPORTED_FUNCTION;
384     }
385     else
386     {
387         ret = SEC_E_INVALID_HANDLE;
388     }
389     return ret;
390 }
391
392
393
394 static const SecurityFunctionTableA negoTableA = {
395     1,
396     NULL,   /* EnumerateSecurityPackagesA */
397     nego_QueryCredentialsAttributesA,   /* QueryCredentialsAttributesA */
398     nego_AcquireCredentialsHandleA,     /* AcquireCredentialsHandleA */
399     FreeCredentialsHandle,              /* FreeCredentialsHandle */
400     NULL,   /* Reserved2 */
401     nego_InitializeSecurityContextA,    /* InitializeSecurityContextA */
402     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
403     nego_CompleteAuthToken,             /* CompleteAuthToken */
404     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
405     nego_ApplyControlToken,             /* ApplyControlToken */
406     nego_QueryContextAttributesA,       /* QueryContextAttributesA */
407     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
408     nego_RevertSecurityContext,         /* RevertSecurityContext */
409     nego_MakeSignature,                 /* MakeSignature */
410     nego_VerifySignature,               /* VerifySignature */
411     FreeContextBuffer,                  /* FreeContextBuffer */
412     NULL,   /* QuerySecurityPackageInfoA */
413     NULL,   /* Reserved3 */
414     NULL,   /* Reserved4 */
415     NULL,   /* ExportSecurityContext */
416     NULL,   /* ImportSecurityContextA */
417     NULL,   /* AddCredentialsA */
418     NULL,   /* Reserved8 */
419     NULL,   /* QuerySecurityContextToken */
420     NULL,   /* EncryptMessage */
421     NULL,   /* DecryptMessage */
422     NULL,   /* SetContextAttributesA */
423 };
424
425 static const SecurityFunctionTableW negoTableW = {
426     1,
427     NULL,   /* EnumerateSecurityPackagesW */
428     nego_QueryCredentialsAttributesW,   /* QueryCredentialsAttributesW */
429     nego_AcquireCredentialsHandleW,     /* AcquireCredentialsHandleW */
430     FreeCredentialsHandle,              /* FreeCredentialsHandle */
431     NULL,   /* Reserved2 */
432     nego_InitializeSecurityContextW,    /* InitializeSecurityContextW */
433     nego_AcceptSecurityContext,         /* AcceptSecurityContext */
434     nego_CompleteAuthToken,             /* CompleteAuthToken */
435     nego_DeleteSecurityContext,         /* DeleteSecurityContext */
436     nego_ApplyControlToken,             /* ApplyControlToken */
437     nego_QueryContextAttributesW,       /* QueryContextAttributesW */
438     nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
439     nego_RevertSecurityContext,         /* RevertSecurityContext */
440     nego_MakeSignature,                 /* MakeSignature */
441     nego_VerifySignature,               /* VerifySignature */
442     FreeContextBuffer,                  /* FreeContextBuffer */
443     NULL,   /* QuerySecurityPackageInfoW */
444     NULL,   /* Reserved3 */
445     NULL,   /* Reserved4 */
446     NULL,   /* ExportSecurityContext */
447     NULL,   /* ImportSecurityContextW */
448     NULL,   /* AddCredentialsW */
449     NULL,   /* Reserved8 */
450     NULL,   /* QuerySecurityContextToken */
451     NULL,   /* EncryptMessage */
452     NULL,   /* DecryptMessage */
453     NULL,   /* SetContextAttributesW */
454 };
455
456 static WCHAR negotiate_comment_W[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o',
457     'f', 't', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', 'N', 'e', 'g', 'o',
458     't', 'i', 'a', 't', 'o', 'r', 0};
459
460 static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
461
462
463
464 void SECUR32_initNegotiateSP(void)
465 {
466     SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW,
467             NULL);
468     /* According to Windows, Negotiate has the following capabilities. 
469      */
470     
471     static const LONG caps = 
472         SECPKG_FLAG_INTEGRITY |
473             SECPKG_FLAG_PRIVACY |
474             SECPKG_FLAG_CONNECTION |
475         SECPKG_FLAG_MULTI_REQUIRED |
476             SECPKG_FLAG_EXTENDED_ERROR |
477             SECPKG_FLAG_IMPERSONATION |
478             SECPKG_FLAG_ACCEPT_WIN32_NAME |
479             SECPKG_FLAG_READONLY_WITH_CHECKSUM;
480
481     static const USHORT version = 1;
482     static const USHORT rpcid = 15;
483     static const ULONG  max_token = 12000;
484     const SecPkgInfoW infoW = { caps, version, rpcid, max_token, nego_name_W,
485         negotiate_comment_W};
486     const SecPkgInfoA infoA = { caps, version, rpcid, max_token, nego_name_A,
487         negotiate_comment_A};
488
489     SECUR32_addPackages(provider, 1L, &infoA, &infoW);        
490 }