nsiproxy: Introduce IOCTL_NSIPROXY_WINE_GET_ALL_PARAMETERS.
[wine.git] / dlls / secur32 / negotiate.c
blob498ef9ec35af0b290300fc7f19e0582a443c8ad1
1 /*
2 * Copyright 2005 Kai Blin
3 * Copyright 2012 Hans Leidekker for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "sspi.h"
25 #include "rpc.h"
26 #include "wincred.h"
28 #include "wine/debug.h"
29 #include "secur32_priv.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
33 /***********************************************************************
34 * QueryCredentialsAttributesA
36 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA(
37 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
39 FIXME("%p, %u, %p\n", phCredential, ulAttribute, pBuffer);
40 return SEC_E_UNSUPPORTED_FUNCTION;
43 /***********************************************************************
44 * QueryCredentialsAttributesW
46 static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW(
47 PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
49 FIXME("%p, %u, %p\n", phCredential, ulAttribute, pBuffer);
50 return SEC_E_UNSUPPORTED_FUNCTION;
53 struct sec_handle
55 SecureProvider *krb;
56 SecureProvider *ntlm;
57 SecHandle handle_krb;
58 SecHandle handle_ntlm;
61 #define WINE_NO_CACHED_CREDENTIALS 0x10000000
63 /***********************************************************************
64 * AcquireCredentialsHandleW
66 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
67 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
68 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
69 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
71 static SEC_WCHAR ntlmW[] = {'N','T','L','M',0};
72 static SEC_WCHAR kerberosW[] = {'K','e','r','b','e','r','o','s',0};
73 SECURITY_STATUS ret = SEC_E_NO_CREDENTIALS;
74 struct sec_handle *cred;
75 SecurePackage *package;
77 TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
78 debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
79 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
81 if (!pszPackage) return SEC_E_SECPKG_NOT_FOUND;
82 if (!(cred = calloc( 1, sizeof(*cred) ))) return SEC_E_INSUFFICIENT_MEMORY;
84 if ((package = SECUR32_findPackageW( kerberosW )))
86 ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, kerberosW,
87 fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_krb, ptsExpiry );
88 if (ret == SEC_E_OK) cred->krb = package->provider;
91 if ((package = SECUR32_findPackageW( ntlmW )))
93 ULONG cred_use = pAuthData ? fCredentialUse : fCredentialUse | WINE_NO_CACHED_CREDENTIALS;
95 ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, ntlmW,
96 cred_use, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_ntlm, ptsExpiry );
97 if (ret == SEC_E_OK) cred->ntlm = package->provider;
100 if (cred->krb || cred->ntlm)
102 phCredential->dwLower = (ULONG_PTR)cred;
103 phCredential->dwUpper = 0;
104 return SEC_E_OK;
107 free( cred );
108 return ret;
111 /***********************************************************************
112 * AcquireCredentialsHandleA
114 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
115 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
116 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
117 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
119 SECURITY_STATUS ret = SEC_E_INSUFFICIENT_MEMORY;
120 SEC_WCHAR *user = NULL, *domain = NULL, *passwd = NULL, *package = NULL;
121 SEC_WINNT_AUTH_IDENTITY_W *identityW = NULL;
123 TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
124 debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
125 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
127 if (pszPackage)
129 int package_len = MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, NULL, 0 );
130 if (!(package = malloc( package_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY;
131 MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, package, package_len );
133 if (pAuthData)
135 SEC_WINNT_AUTH_IDENTITY_A *identity = pAuthData;
136 int user_len, domain_len, passwd_len;
138 if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
140 if (!(identityW = malloc( sizeof(*identityW) ))) goto done;
142 if (!identity->UserLength) user_len = 0;
143 else
145 user_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User,
146 identity->UserLength, NULL, 0 );
147 if (!(user = malloc( user_len * sizeof(SEC_WCHAR) ))) goto done;
148 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User, identity->UserLength,
149 user, user_len );
151 if (!identity->DomainLength) domain_len = 0;
152 else
154 domain_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain,
155 identity->DomainLength, NULL, 0 );
156 if (!(domain = malloc( domain_len * sizeof(SEC_WCHAR) ))) goto done;
157 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain, identity->DomainLength,
158 domain, domain_len );
160 if (!identity->PasswordLength) passwd_len = 0;
161 else
163 passwd_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password,
164 identity->PasswordLength, NULL, 0 );
165 if (!(passwd = malloc( passwd_len * sizeof(SEC_WCHAR) ))) goto done;
166 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password, identity->PasswordLength,
167 passwd, passwd_len );
169 identityW->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
170 identityW->User = user;
171 identityW->UserLength = user_len;
172 identityW->Domain = domain;
173 identityW->DomainLength = domain_len;
174 identityW->Password = passwd;
175 identityW->PasswordLength = passwd_len;
177 else identityW = (SEC_WINNT_AUTH_IDENTITY_W *)identity;
179 ret = nego_AcquireCredentialsHandleW( NULL, package, fCredentialUse, pLogonID, identityW,
180 pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry );
181 done:
182 free( package );
183 free( user );
184 free( domain );
185 free( passwd );
186 free( identityW );
187 return ret;
190 /***********************************************************************
191 * InitializeSecurityContextW
193 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
194 PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
195 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
196 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
197 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
199 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
200 struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
202 TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
203 phCredential, phContext, debugstr_w(pszTargetName), fContextReq,
204 Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
205 pfContextAttr, ptsExpiry);
207 if (phContext)
209 handle = ctxt = (struct sec_handle *)phContext->dwLower;
211 else if (phCredential)
213 handle = cred = (struct sec_handle *)phCredential->dwLower;
214 if (!(new_ctxt = ctxt = calloc( 1, sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY;
215 ctxt->krb = cred->krb;
216 ctxt->ntlm = cred->ntlm;
218 if (!handle) return SEC_E_INVALID_HANDLE;
220 if (handle->krb)
222 ret = handle->krb->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_krb : NULL,
223 phContext ? &ctxt->handle_krb : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
224 Reserved2, phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry );
225 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
227 ctxt->ntlm = NULL;
228 phNewContext->dwLower = (ULONG_PTR)ctxt;
229 phNewContext->dwUpper = 0;
230 if (new_ctxt == ctxt) new_ctxt = NULL;
234 if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm)
236 ret = handle->ntlm->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_ntlm : NULL,
237 phContext ? &ctxt->handle_ntlm : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
238 Reserved2, phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry );
239 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
241 ctxt->krb = NULL;
242 phNewContext->dwLower = (ULONG_PTR)ctxt;
243 phNewContext->dwUpper = 0;
244 if (new_ctxt == ctxt) new_ctxt = NULL;
248 free( new_ctxt );
249 return ret;
252 /***********************************************************************
253 * InitializeSecurityContextA
255 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
256 PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
257 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
258 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
259 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
261 SECURITY_STATUS ret;
262 SEC_WCHAR *target = NULL;
264 TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
265 phCredential, phContext, debugstr_a(pszTargetName), fContextReq,
266 Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
267 pfContextAttr, ptsExpiry);
269 if (pszTargetName)
271 int target_len = MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, NULL, 0 );
272 if (!(target = malloc( target_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY;
273 MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, target, target_len );
275 ret = nego_InitializeSecurityContextW( phCredential, phContext, target, fContextReq,
276 Reserved1, TargetDataRep, pInput, Reserved2,
277 phNewContext, pOutput, pfContextAttr, ptsExpiry );
278 free( target );
279 return ret;
282 /***********************************************************************
283 * AcceptSecurityContext
285 static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
286 PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
287 ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
288 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
290 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
291 struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
293 TRACE("%p, %p, %p, 0x%08x, %u, %p, %p, %p, %p\n", phCredential, phContext,
294 pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
295 ptsExpiry);
297 if (phContext)
299 handle = ctxt = (struct sec_handle *)phContext->dwLower;
301 else if (phCredential)
303 handle = cred = (struct sec_handle *)phCredential->dwLower;
304 if (!(new_ctxt = ctxt = calloc( 1, sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY;
305 ctxt->krb = cred->krb;
306 ctxt->ntlm = cred->ntlm;
308 if (!handle) return SEC_E_INVALID_HANDLE;
310 if (handle->krb)
312 ret = handle->krb->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_krb : NULL,
313 phContext ? &ctxt->handle_krb : NULL, pInput, fContextReq, TargetDataRep,
314 phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry );
315 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
317 ctxt->ntlm = NULL;
318 phNewContext->dwLower = (ULONG_PTR)ctxt;
319 phNewContext->dwUpper = 0;
320 if (new_ctxt == ctxt) new_ctxt = NULL;
324 if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm)
326 ret = handle->ntlm->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_ntlm : NULL,
327 phContext ? &ctxt->handle_ntlm : NULL, pInput, fContextReq, TargetDataRep,
328 phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry );
329 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
331 ctxt->krb = NULL;
332 phNewContext->dwLower = (ULONG_PTR)ctxt;
333 phNewContext->dwUpper = 0;
334 if (new_ctxt == ctxt) new_ctxt = NULL;
338 free( new_ctxt );
339 return ret;
342 /***********************************************************************
343 * CompleteAuthToken
345 static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
346 PSecBufferDesc pToken)
348 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
350 TRACE("%p %p\n", phContext, pToken);
352 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
353 return ret;
356 /***********************************************************************
357 * DeleteSecurityContext
359 static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
361 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
362 struct sec_handle *ctxt;
364 TRACE("%p\n", phContext);
366 if (!phContext) return SEC_E_INVALID_HANDLE;
368 ctxt = (struct sec_handle *)phContext->dwLower;
369 if (ctxt->krb)
371 ret = ctxt->krb->fnTableW.DeleteSecurityContext( &ctxt->handle_krb );
373 else if (ctxt->ntlm)
375 ret = ctxt->ntlm->fnTableW.DeleteSecurityContext( &ctxt->handle_ntlm );
377 TRACE( "freeing %p\n", ctxt );
378 free( ctxt );
379 return ret;
382 /***********************************************************************
383 * ApplyControlToken
385 static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
386 PSecBufferDesc pInput)
388 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
390 TRACE("%p %p\n", phContext, pInput);
392 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
393 return ret;
396 /***********************************************************************
397 * QueryContextAttributesW
399 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(
400 PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
402 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
403 struct sec_handle *ctxt;
405 TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
407 if (!phContext) return SEC_E_INVALID_HANDLE;
409 ctxt = (struct sec_handle *)phContext->dwLower;
410 if (ctxt->krb)
412 ret = ctxt->krb->fnTableW.QueryContextAttributesW( &ctxt->handle_krb, ulAttribute, pBuffer );
414 else if (ctxt->ntlm)
416 ret = ctxt->ntlm->fnTableW.QueryContextAttributesW( &ctxt->handle_ntlm, ulAttribute, pBuffer );
418 return ret;
421 /***********************************************************************
422 * QueryContextAttributesA
424 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
425 ULONG ulAttribute, void *pBuffer)
427 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
428 struct sec_handle *ctxt;
430 TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
432 if (!phContext) return SEC_E_INVALID_HANDLE;
434 ctxt = (struct sec_handle *)phContext->dwLower;
435 if (ctxt->krb)
437 ret = ctxt->krb->fnTableA.QueryContextAttributesA( &ctxt->handle_krb, ulAttribute, pBuffer );
439 else if (ctxt->ntlm)
441 ret = ctxt->ntlm->fnTableA.QueryContextAttributesA( &ctxt->handle_ntlm, ulAttribute, pBuffer );
443 return ret;
446 /***********************************************************************
447 * ImpersonateSecurityContext
449 static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
451 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
453 TRACE("%p\n", phContext);
455 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
456 return ret;
459 /***********************************************************************
460 * RevertSecurityContext
462 static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
464 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
466 TRACE("%p\n", phContext);
468 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
469 return ret;
472 /***********************************************************************
473 * MakeSignature
475 static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext,
476 ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
478 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
479 struct sec_handle *ctxt;
481 TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
483 if (!phContext) return SEC_E_INVALID_HANDLE;
485 ctxt = (struct sec_handle *)phContext->dwLower;
486 if (ctxt->krb)
488 ret = ctxt->krb->fnTableW.MakeSignature( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo );
490 else if (ctxt->ntlm)
492 ret = ctxt->ntlm->fnTableW.MakeSignature( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo );
494 return ret;
497 /***********************************************************************
498 * VerifySignature
500 static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
501 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
503 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
504 struct sec_handle *ctxt;
506 TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
508 if (!phContext) return SEC_E_INVALID_HANDLE;
510 ctxt = (struct sec_handle *)phContext->dwLower;
511 if (ctxt->krb)
513 ret = ctxt->krb->fnTableW.VerifySignature( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP );
515 else if (ctxt->ntlm)
517 ret = ctxt->ntlm->fnTableW.VerifySignature( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP );
519 return ret;
522 /***********************************************************************
523 * FreeCredentialsHandle
525 static SECURITY_STATUS SEC_ENTRY nego_FreeCredentialsHandle(PCredHandle phCredential)
527 struct sec_handle *cred;
529 TRACE("%p\n", phCredential);
531 if (!phCredential) return SEC_E_INVALID_HANDLE;
533 cred = (struct sec_handle *)phCredential->dwLower;
534 if (cred->krb) cred->krb->fnTableW.FreeCredentialsHandle( &cred->handle_krb );
535 if (cred->ntlm) cred->ntlm->fnTableW.FreeCredentialsHandle( &cred->handle_ntlm );
537 free( cred );
538 return SEC_E_OK;
541 /***********************************************************************
542 * EncryptMessage
544 static SECURITY_STATUS SEC_ENTRY nego_EncryptMessage(PCtxtHandle phContext,
545 ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
547 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
548 struct sec_handle *ctxt;
550 TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
552 if (!phContext) return SEC_E_INVALID_HANDLE;
554 ctxt = (struct sec_handle *)phContext->dwLower;
555 if (ctxt->krb)
557 ret = ctxt->krb->fnTableW.EncryptMessage( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo );
559 else if (ctxt->ntlm)
561 ret = ctxt->ntlm->fnTableW.EncryptMessage( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo );
563 return ret;
566 /***********************************************************************
567 * DecryptMessage
569 static SECURITY_STATUS SEC_ENTRY nego_DecryptMessage(PCtxtHandle phContext,
570 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
572 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
573 struct sec_handle *ctxt;
575 TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
577 if (!phContext) return SEC_E_INVALID_HANDLE;
579 ctxt = (struct sec_handle *)phContext->dwLower;
580 if (ctxt->krb)
582 ret = ctxt->krb->fnTableW.DecryptMessage( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP );
584 else if (ctxt->ntlm)
586 ret = ctxt->ntlm->fnTableW.DecryptMessage( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP );
588 return ret;
591 static const SecurityFunctionTableA negoTableA = {
593 NULL, /* EnumerateSecurityPackagesA */
594 nego_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */
595 nego_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */
596 nego_FreeCredentialsHandle, /* FreeCredentialsHandle */
597 NULL, /* Reserved2 */
598 nego_InitializeSecurityContextA, /* InitializeSecurityContextA */
599 nego_AcceptSecurityContext, /* AcceptSecurityContext */
600 nego_CompleteAuthToken, /* CompleteAuthToken */
601 nego_DeleteSecurityContext, /* DeleteSecurityContext */
602 nego_ApplyControlToken, /* ApplyControlToken */
603 nego_QueryContextAttributesA, /* QueryContextAttributesA */
604 nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
605 nego_RevertSecurityContext, /* RevertSecurityContext */
606 nego_MakeSignature, /* MakeSignature */
607 nego_VerifySignature, /* VerifySignature */
608 FreeContextBuffer, /* FreeContextBuffer */
609 NULL, /* QuerySecurityPackageInfoA */
610 NULL, /* Reserved3 */
611 NULL, /* Reserved4 */
612 NULL, /* ExportSecurityContext */
613 NULL, /* ImportSecurityContextA */
614 NULL, /* AddCredentialsA */
615 NULL, /* Reserved8 */
616 NULL, /* QuerySecurityContextToken */
617 nego_EncryptMessage, /* EncryptMessage */
618 nego_DecryptMessage, /* DecryptMessage */
619 NULL, /* SetContextAttributesA */
622 static const SecurityFunctionTableW negoTableW = {
624 NULL, /* EnumerateSecurityPackagesW */
625 nego_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */
626 nego_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */
627 nego_FreeCredentialsHandle, /* FreeCredentialsHandle */
628 NULL, /* Reserved2 */
629 nego_InitializeSecurityContextW, /* InitializeSecurityContextW */
630 nego_AcceptSecurityContext, /* AcceptSecurityContext */
631 nego_CompleteAuthToken, /* CompleteAuthToken */
632 nego_DeleteSecurityContext, /* DeleteSecurityContext */
633 nego_ApplyControlToken, /* ApplyControlToken */
634 nego_QueryContextAttributesW, /* QueryContextAttributesW */
635 nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
636 nego_RevertSecurityContext, /* RevertSecurityContext */
637 nego_MakeSignature, /* MakeSignature */
638 nego_VerifySignature, /* VerifySignature */
639 FreeContextBuffer, /* FreeContextBuffer */
640 NULL, /* QuerySecurityPackageInfoW */
641 NULL, /* Reserved3 */
642 NULL, /* Reserved4 */
643 NULL, /* ExportSecurityContext */
644 NULL, /* ImportSecurityContextW */
645 NULL, /* AddCredentialsW */
646 NULL, /* Reserved8 */
647 NULL, /* QuerySecurityContextToken */
648 nego_EncryptMessage, /* EncryptMessage */
649 nego_DecryptMessage, /* DecryptMessage */
650 NULL, /* SetContextAttributesW */
653 #define NEGO_MAX_TOKEN 12000
655 static WCHAR nego_name_W[] = {'N','e','g','o','t','i','a','t','e',0};
656 static char nego_name_A[] = "Negotiate";
658 static WCHAR negotiate_comment_W[] =
659 {'M','i','c','r','o','s','o','f','t',' ','P','a','c','k','a','g','e',' ',
660 'N','e','g','o','t','i','a','t','o','r',0};
661 static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
663 #define CAPS ( \
664 SECPKG_FLAG_INTEGRITY | \
665 SECPKG_FLAG_PRIVACY | \
666 SECPKG_FLAG_CONNECTION | \
667 SECPKG_FLAG_MULTI_REQUIRED | \
668 SECPKG_FLAG_EXTENDED_ERROR | \
669 SECPKG_FLAG_IMPERSONATION | \
670 SECPKG_FLAG_ACCEPT_WIN32_NAME | \
671 SECPKG_FLAG_NEGOTIABLE | \
672 SECPKG_FLAG_GSS_COMPATIBLE | \
673 SECPKG_FLAG_LOGON | \
674 SECPKG_FLAG_RESTRICTED_TOKENS )
676 void SECUR32_initNegotiateSP(void)
678 SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, NULL);
680 const SecPkgInfoW infoW = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
681 nego_name_W, negotiate_comment_W};
682 const SecPkgInfoA infoA = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
683 nego_name_A, negotiate_comment_A};
684 SECUR32_addPackages(provider, 1L, &infoA, &infoW);