wmp: Add seeking and duration.
[wine.git] / dlls / secur32 / negotiate.c
blob0df950093e4ce741a805cf737cd1c41e419497e6
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 "windef.h"
22 #include "winbase.h"
23 #include "sspi.h"
24 #include "rpc.h"
25 #include "wincred.h"
26 #include "secur32_priv.h"
28 #include "wine/debug.h"
29 #include "wine/unicode.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 /***********************************************************************
62 * AcquireCredentialsHandleW
64 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
65 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
66 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
67 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
69 static SEC_WCHAR ntlmW[] = {'N','T','L','M',0};
70 static SEC_WCHAR kerberosW[] = {'K','e','r','b','e','r','o','s',0};
71 SECURITY_STATUS ret = SEC_E_NO_CREDENTIALS;
72 struct sec_handle *cred;
73 SecurePackage *package;
75 TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
76 debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
77 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
79 if (!pszPackage) return SEC_E_SECPKG_NOT_FOUND;
80 if (!(cred = heap_alloc_zero( sizeof(*cred) ))) return SEC_E_INSUFFICIENT_MEMORY;
82 if ((package = SECUR32_findPackageW( kerberosW )))
84 ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, kerberosW,
85 fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_krb, ptsExpiry );
86 if (ret == SEC_E_OK) cred->krb = package->provider;
89 if ((package = SECUR32_findPackageW( ntlmW )))
91 ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, ntlmW,
92 fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_ntlm, ptsExpiry );
93 if (ret == SEC_E_OK)
95 NtlmCredentials *ntlm_cred = (NtlmCredentials *)cred->handle_ntlm.dwLower;
96 ntlm_cred->no_cached_credentials = (pAuthData == NULL);
97 cred->ntlm = package->provider;
101 if (cred->krb || cred->ntlm)
103 phCredential->dwLower = (ULONG_PTR)cred;
104 phCredential->dwUpper = 0;
105 return SEC_E_OK;
108 heap_free( cred );
109 return ret;
112 /***********************************************************************
113 * AcquireCredentialsHandleA
115 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
116 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
117 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
118 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
120 SECURITY_STATUS ret = SEC_E_INSUFFICIENT_MEMORY;
121 SEC_WCHAR *user = NULL, *domain = NULL, *passwd = NULL, *package = NULL;
122 SEC_WINNT_AUTH_IDENTITY_W *identityW = NULL;
124 TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
125 debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
126 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
128 if (pszPackage)
130 int package_len = MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, NULL, 0 );
131 if (!(package = heap_alloc( package_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY;
132 MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, package, package_len );
134 if (pAuthData)
136 SEC_WINNT_AUTH_IDENTITY_A *identity = pAuthData;
137 int user_len, domain_len, passwd_len;
139 if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
141 if (!(identityW = heap_alloc( sizeof(*identityW) ))) goto done;
143 if (!identity->UserLength) user_len = 0;
144 else
146 user_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User,
147 identity->UserLength, NULL, 0 );
148 if (!(user = heap_alloc( user_len * sizeof(SEC_WCHAR) ))) goto done;
149 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User, identity->UserLength,
150 user, user_len );
152 if (!identity->DomainLength) domain_len = 0;
153 else
155 domain_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain,
156 identity->DomainLength, NULL, 0 );
157 if (!(domain = heap_alloc( domain_len * sizeof(SEC_WCHAR) ))) goto done;
158 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain, identity->DomainLength,
159 domain, domain_len );
161 if (!identity->PasswordLength) passwd_len = 0;
162 else
164 passwd_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password,
165 identity->PasswordLength, NULL, 0 );
166 if (!(passwd = heap_alloc( passwd_len * sizeof(SEC_WCHAR) ))) goto done;
167 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password, identity->PasswordLength,
168 passwd, passwd_len );
170 identityW->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
171 identityW->User = user;
172 identityW->UserLength = user_len;
173 identityW->Domain = domain;
174 identityW->DomainLength = domain_len;
175 identityW->Password = passwd;
176 identityW->PasswordLength = passwd_len;
178 else identityW = (SEC_WINNT_AUTH_IDENTITY_W *)identity;
180 ret = nego_AcquireCredentialsHandleW( NULL, package, fCredentialUse, pLogonID, identityW,
181 pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry );
182 done:
183 heap_free( package );
184 heap_free( user );
185 heap_free( domain );
186 heap_free( passwd );
187 heap_free( identityW );
188 return ret;
191 /***********************************************************************
192 * InitializeSecurityContextW
194 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
195 PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
196 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
197 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
198 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
200 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
201 struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
203 TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
204 phCredential, phContext, debugstr_w(pszTargetName), fContextReq,
205 Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
206 pfContextAttr, ptsExpiry);
208 if (phContext)
210 handle = ctxt = (struct sec_handle *)phContext->dwLower;
212 else if (phCredential)
214 handle = cred = (struct sec_handle *)phCredential->dwLower;
215 if (!(new_ctxt = ctxt = heap_alloc_zero( sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY;
216 ctxt->krb = cred->krb;
217 ctxt->ntlm = cred->ntlm;
219 if (!handle) return SEC_E_INVALID_HANDLE;
221 if (handle->krb)
223 ret = handle->krb->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_krb : NULL,
224 phContext ? &ctxt->handle_krb : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
225 Reserved2, phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry );
226 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
228 ctxt->ntlm = NULL;
229 phNewContext->dwLower = (ULONG_PTR)ctxt;
230 phNewContext->dwUpper = 0;
231 if (new_ctxt == ctxt) new_ctxt = NULL;
235 if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm)
237 ret = handle->ntlm->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_ntlm : NULL,
238 phContext ? &ctxt->handle_ntlm : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
239 Reserved2, phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry );
240 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
242 ctxt->krb = NULL;
243 phNewContext->dwLower = (ULONG_PTR)ctxt;
244 phNewContext->dwUpper = 0;
245 if (new_ctxt == ctxt) new_ctxt = NULL;
249 heap_free( new_ctxt );
250 return ret;
253 /***********************************************************************
254 * InitializeSecurityContextA
256 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
257 PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
258 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
259 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
260 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
262 SECURITY_STATUS ret;
263 SEC_WCHAR *target = NULL;
265 TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
266 phCredential, phContext, debugstr_a(pszTargetName), fContextReq,
267 Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
268 pfContextAttr, ptsExpiry);
270 if (pszTargetName)
272 int target_len = MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, NULL, 0 );
273 if (!(target = heap_alloc( target_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY;
274 MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, target, target_len );
276 ret = nego_InitializeSecurityContextW( phCredential, phContext, target, fContextReq,
277 Reserved1, TargetDataRep, pInput, Reserved2,
278 phNewContext, pOutput, pfContextAttr, ptsExpiry );
279 heap_free( target );
280 return ret;
283 /***********************************************************************
284 * AcceptSecurityContext
286 static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
287 PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
288 ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
289 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
291 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
292 struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
294 TRACE("%p, %p, %p, 0x%08x, %u, %p, %p, %p, %p\n", phCredential, phContext,
295 pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
296 ptsExpiry);
298 if (phContext)
300 handle = ctxt = (struct sec_handle *)phContext->dwLower;
302 else if (phCredential)
304 handle = cred = (struct sec_handle *)phCredential->dwLower;
305 if (!(new_ctxt = ctxt = heap_alloc_zero( sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY;
306 ctxt->krb = cred->krb;
307 ctxt->ntlm = cred->ntlm;
309 if (!handle) return SEC_E_INVALID_HANDLE;
311 if (handle->krb)
313 ret = handle->krb->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_krb : NULL,
314 phContext ? &ctxt->handle_krb : NULL, pInput, fContextReq, TargetDataRep,
315 phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry );
316 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
318 ctxt->ntlm = NULL;
319 phNewContext->dwLower = (ULONG_PTR)ctxt;
320 phNewContext->dwUpper = 0;
321 if (new_ctxt == ctxt) new_ctxt = NULL;
325 if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm)
327 ret = handle->ntlm->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_ntlm : NULL,
328 phContext ? &ctxt->handle_ntlm : NULL, pInput, fContextReq, TargetDataRep,
329 phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry );
330 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
332 ctxt->krb = NULL;
333 phNewContext->dwLower = (ULONG_PTR)ctxt;
334 phNewContext->dwUpper = 0;
335 if (new_ctxt == ctxt) new_ctxt = NULL;
339 heap_free( new_ctxt );
340 return ret;
343 /***********************************************************************
344 * CompleteAuthToken
346 static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
347 PSecBufferDesc pToken)
349 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
351 TRACE("%p %p\n", phContext, pToken);
353 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
354 return ret;
357 /***********************************************************************
358 * DeleteSecurityContext
360 static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
362 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
363 struct sec_handle *ctxt;
365 TRACE("%p\n", phContext);
367 if (!phContext) return SEC_E_INVALID_HANDLE;
369 ctxt = (struct sec_handle *)phContext->dwLower;
370 if (ctxt->krb)
372 ret = ctxt->krb->fnTableW.DeleteSecurityContext( &ctxt->handle_krb );
374 else if (ctxt->ntlm)
376 ret = ctxt->ntlm->fnTableW.DeleteSecurityContext( &ctxt->handle_ntlm );
378 TRACE( "freeing %p\n", ctxt );
379 heap_free( ctxt );
380 return ret;
383 /***********************************************************************
384 * ApplyControlToken
386 static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
387 PSecBufferDesc pInput)
389 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
391 TRACE("%p %p\n", phContext, pInput);
393 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
394 return ret;
397 /***********************************************************************
398 * QueryContextAttributesW
400 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(
401 PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
403 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
404 struct sec_handle *ctxt;
406 TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
408 if (!phContext) return SEC_E_INVALID_HANDLE;
410 ctxt = (struct sec_handle *)phContext->dwLower;
411 if (ctxt->krb)
413 ret = ctxt->krb->fnTableW.QueryContextAttributesW( &ctxt->handle_krb, ulAttribute, pBuffer );
415 else if (ctxt->ntlm)
417 ret = ctxt->ntlm->fnTableW.QueryContextAttributesW( &ctxt->handle_ntlm, ulAttribute, pBuffer );
419 return ret;
422 /***********************************************************************
423 * QueryContextAttributesA
425 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
426 ULONG ulAttribute, void *pBuffer)
428 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
429 struct sec_handle *ctxt;
431 TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
433 if (!phContext) return SEC_E_INVALID_HANDLE;
435 ctxt = (struct sec_handle *)phContext->dwLower;
436 if (ctxt->krb)
438 ret = ctxt->krb->fnTableA.QueryContextAttributesA( &ctxt->handle_krb, ulAttribute, pBuffer );
440 else if (ctxt->ntlm)
442 ret = ctxt->ntlm->fnTableA.QueryContextAttributesA( &ctxt->handle_ntlm, ulAttribute, pBuffer );
444 return ret;
447 /***********************************************************************
448 * ImpersonateSecurityContext
450 static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
452 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
454 TRACE("%p\n", phContext);
456 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
457 return ret;
460 /***********************************************************************
461 * RevertSecurityContext
463 static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
465 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
467 TRACE("%p\n", phContext);
469 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
470 return ret;
473 /***********************************************************************
474 * MakeSignature
476 static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext,
477 ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
479 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
480 struct sec_handle *ctxt;
482 TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
484 if (!phContext) return SEC_E_INVALID_HANDLE;
486 ctxt = (struct sec_handle *)phContext->dwLower;
487 if (ctxt->krb)
489 ret = ctxt->krb->fnTableW.MakeSignature( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo );
491 else if (ctxt->ntlm)
493 ret = ctxt->ntlm->fnTableW.MakeSignature( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo );
495 return ret;
498 /***********************************************************************
499 * VerifySignature
501 static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
502 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
504 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
505 struct sec_handle *ctxt;
507 TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
509 if (!phContext) return SEC_E_INVALID_HANDLE;
511 ctxt = (struct sec_handle *)phContext->dwLower;
512 if (ctxt->krb)
514 ret = ctxt->krb->fnTableW.VerifySignature( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP );
516 else if (ctxt->ntlm)
518 ret = ctxt->ntlm->fnTableW.VerifySignature( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP );
520 return ret;
523 /***********************************************************************
524 * FreeCredentialsHandle
526 static SECURITY_STATUS SEC_ENTRY nego_FreeCredentialsHandle(PCredHandle phCredential)
528 struct sec_handle *cred;
530 TRACE("%p\n", phCredential);
532 if (!phCredential) return SEC_E_INVALID_HANDLE;
534 cred = (struct sec_handle *)phCredential->dwLower;
535 if (cred->krb) cred->krb->fnTableW.FreeCredentialsHandle( &cred->handle_krb );
536 if (cred->ntlm) cred->ntlm->fnTableW.FreeCredentialsHandle( &cred->handle_ntlm );
538 heap_free( cred );
539 return SEC_E_OK;
542 /***********************************************************************
543 * EncryptMessage
545 static SECURITY_STATUS SEC_ENTRY nego_EncryptMessage(PCtxtHandle phContext,
546 ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
548 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
549 struct sec_handle *ctxt;
551 TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
553 if (!phContext) return SEC_E_INVALID_HANDLE;
555 ctxt = (struct sec_handle *)phContext->dwLower;
556 if (ctxt->krb)
558 ret = ctxt->krb->fnTableW.EncryptMessage( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo );
560 else if (ctxt->ntlm)
562 ret = ctxt->ntlm->fnTableW.EncryptMessage( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo );
564 return ret;
567 /***********************************************************************
568 * DecryptMessage
570 static SECURITY_STATUS SEC_ENTRY nego_DecryptMessage(PCtxtHandle phContext,
571 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
573 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
574 struct sec_handle *ctxt;
576 TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
578 if (!phContext) return SEC_E_INVALID_HANDLE;
580 ctxt = (struct sec_handle *)phContext->dwLower;
581 if (ctxt->krb)
583 ret = ctxt->krb->fnTableW.DecryptMessage( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP );
585 else if (ctxt->ntlm)
587 ret = ctxt->ntlm->fnTableW.DecryptMessage( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP );
589 return ret;
592 static const SecurityFunctionTableA negoTableA = {
594 NULL, /* EnumerateSecurityPackagesA */
595 nego_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */
596 nego_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */
597 nego_FreeCredentialsHandle, /* FreeCredentialsHandle */
598 NULL, /* Reserved2 */
599 nego_InitializeSecurityContextA, /* InitializeSecurityContextA */
600 nego_AcceptSecurityContext, /* AcceptSecurityContext */
601 nego_CompleteAuthToken, /* CompleteAuthToken */
602 nego_DeleteSecurityContext, /* DeleteSecurityContext */
603 nego_ApplyControlToken, /* ApplyControlToken */
604 nego_QueryContextAttributesA, /* QueryContextAttributesA */
605 nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
606 nego_RevertSecurityContext, /* RevertSecurityContext */
607 nego_MakeSignature, /* MakeSignature */
608 nego_VerifySignature, /* VerifySignature */
609 FreeContextBuffer, /* FreeContextBuffer */
610 NULL, /* QuerySecurityPackageInfoA */
611 NULL, /* Reserved3 */
612 NULL, /* Reserved4 */
613 NULL, /* ExportSecurityContext */
614 NULL, /* ImportSecurityContextA */
615 NULL, /* AddCredentialsA */
616 NULL, /* Reserved8 */
617 NULL, /* QuerySecurityContextToken */
618 nego_EncryptMessage, /* EncryptMessage */
619 nego_DecryptMessage, /* DecryptMessage */
620 NULL, /* SetContextAttributesA */
623 static const SecurityFunctionTableW negoTableW = {
625 NULL, /* EnumerateSecurityPackagesW */
626 nego_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */
627 nego_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */
628 nego_FreeCredentialsHandle, /* FreeCredentialsHandle */
629 NULL, /* Reserved2 */
630 nego_InitializeSecurityContextW, /* InitializeSecurityContextW */
631 nego_AcceptSecurityContext, /* AcceptSecurityContext */
632 nego_CompleteAuthToken, /* CompleteAuthToken */
633 nego_DeleteSecurityContext, /* DeleteSecurityContext */
634 nego_ApplyControlToken, /* ApplyControlToken */
635 nego_QueryContextAttributesW, /* QueryContextAttributesW */
636 nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
637 nego_RevertSecurityContext, /* RevertSecurityContext */
638 nego_MakeSignature, /* MakeSignature */
639 nego_VerifySignature, /* VerifySignature */
640 FreeContextBuffer, /* FreeContextBuffer */
641 NULL, /* QuerySecurityPackageInfoW */
642 NULL, /* Reserved3 */
643 NULL, /* Reserved4 */
644 NULL, /* ExportSecurityContext */
645 NULL, /* ImportSecurityContextW */
646 NULL, /* AddCredentialsW */
647 NULL, /* Reserved8 */
648 NULL, /* QuerySecurityContextToken */
649 nego_EncryptMessage, /* EncryptMessage */
650 nego_DecryptMessage, /* DecryptMessage */
651 NULL, /* SetContextAttributesW */
654 #define NEGO_MAX_TOKEN 12000
656 static WCHAR nego_name_W[] = {'N','e','g','o','t','i','a','t','e',0};
657 static char nego_name_A[] = "Negotiate";
659 static WCHAR negotiate_comment_W[] =
660 {'M','i','c','r','o','s','o','f','t',' ','P','a','c','k','a','g','e',' ',
661 'N','e','g','o','t','i','a','t','o','r',0};
662 static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
664 #define CAPS ( \
665 SECPKG_FLAG_INTEGRITY | \
666 SECPKG_FLAG_PRIVACY | \
667 SECPKG_FLAG_CONNECTION | \
668 SECPKG_FLAG_MULTI_REQUIRED | \
669 SECPKG_FLAG_EXTENDED_ERROR | \
670 SECPKG_FLAG_IMPERSONATION | \
671 SECPKG_FLAG_ACCEPT_WIN32_NAME | \
672 SECPKG_FLAG_NEGOTIABLE | \
673 SECPKG_FLAG_GSS_COMPATIBLE | \
674 SECPKG_FLAG_LOGON | \
675 SECPKG_FLAG_RESTRICTED_TOKENS )
677 void SECUR32_initNegotiateSP(void)
679 SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, NULL);
681 const SecPkgInfoW infoW = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
682 nego_name_W, negotiate_comment_W};
683 const SecPkgInfoA infoA = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
684 nego_name_A, negotiate_comment_A};
685 SECUR32_addPackages(provider, 1L, &infoA, &infoW);