evr/mixer: Use hex format for message type.
[wine.git] / dlls / secur32 / negotiate.c
blob6767790d09f1cec06974f226ad35392fc0a058e6
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 /* matches layout from msv1_0 */
62 struct ntlm_cred
64 int mode;
65 char *username_arg;
66 char *domain_arg;
67 char *password;
68 int password_len;
69 int no_cached_credentials; /* don't try to use cached Samba credentials */
72 /***********************************************************************
73 * AcquireCredentialsHandleW
75 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
76 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
77 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
78 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
80 static SEC_WCHAR ntlmW[] = {'N','T','L','M',0};
81 static SEC_WCHAR kerberosW[] = {'K','e','r','b','e','r','o','s',0};
82 SECURITY_STATUS ret = SEC_E_NO_CREDENTIALS;
83 struct sec_handle *cred;
84 SecurePackage *package;
86 TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
87 debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
88 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
90 if (!pszPackage) return SEC_E_SECPKG_NOT_FOUND;
91 if (!(cred = heap_alloc_zero( sizeof(*cred) ))) return SEC_E_INSUFFICIENT_MEMORY;
93 if ((package = SECUR32_findPackageW( kerberosW )))
95 ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, kerberosW,
96 fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_krb, ptsExpiry );
97 if (ret == SEC_E_OK) cred->krb = package->provider;
100 if ((package = SECUR32_findPackageW( ntlmW )))
102 ret = package->provider->fnTableW.AcquireCredentialsHandleW( pszPrincipal, ntlmW,
103 fCredentialUse, pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, &cred->handle_ntlm, ptsExpiry );
104 if (ret == SEC_E_OK)
106 struct ntlm_cred *ntlm_cred = (struct ntlm_cred *)cred->handle_ntlm.dwLower;
107 ntlm_cred->no_cached_credentials = (pAuthData == NULL);
108 cred->ntlm = package->provider;
112 if (cred->krb || cred->ntlm)
114 phCredential->dwLower = (ULONG_PTR)cred;
115 phCredential->dwUpper = 0;
116 return SEC_E_OK;
119 heap_free( cred );
120 return ret;
123 /***********************************************************************
124 * AcquireCredentialsHandleA
126 static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
127 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
128 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
129 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry )
131 SECURITY_STATUS ret = SEC_E_INSUFFICIENT_MEMORY;
132 SEC_WCHAR *user = NULL, *domain = NULL, *passwd = NULL, *package = NULL;
133 SEC_WINNT_AUTH_IDENTITY_W *identityW = NULL;
135 TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n",
136 debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
137 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
139 if (pszPackage)
141 int package_len = MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, NULL, 0 );
142 if (!(package = heap_alloc( package_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY;
143 MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, package, package_len );
145 if (pAuthData)
147 SEC_WINNT_AUTH_IDENTITY_A *identity = pAuthData;
148 int user_len, domain_len, passwd_len;
150 if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
152 if (!(identityW = heap_alloc( sizeof(*identityW) ))) goto done;
154 if (!identity->UserLength) user_len = 0;
155 else
157 user_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User,
158 identity->UserLength, NULL, 0 );
159 if (!(user = heap_alloc( user_len * sizeof(SEC_WCHAR) ))) goto done;
160 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User, identity->UserLength,
161 user, user_len );
163 if (!identity->DomainLength) domain_len = 0;
164 else
166 domain_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain,
167 identity->DomainLength, NULL, 0 );
168 if (!(domain = heap_alloc( domain_len * sizeof(SEC_WCHAR) ))) goto done;
169 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain, identity->DomainLength,
170 domain, domain_len );
172 if (!identity->PasswordLength) passwd_len = 0;
173 else
175 passwd_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password,
176 identity->PasswordLength, NULL, 0 );
177 if (!(passwd = heap_alloc( passwd_len * sizeof(SEC_WCHAR) ))) goto done;
178 MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password, identity->PasswordLength,
179 passwd, passwd_len );
181 identityW->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
182 identityW->User = user;
183 identityW->UserLength = user_len;
184 identityW->Domain = domain;
185 identityW->DomainLength = domain_len;
186 identityW->Password = passwd;
187 identityW->PasswordLength = passwd_len;
189 else identityW = (SEC_WINNT_AUTH_IDENTITY_W *)identity;
191 ret = nego_AcquireCredentialsHandleW( NULL, package, fCredentialUse, pLogonID, identityW,
192 pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry );
193 done:
194 heap_free( package );
195 heap_free( user );
196 heap_free( domain );
197 heap_free( passwd );
198 heap_free( identityW );
199 return ret;
202 /***********************************************************************
203 * InitializeSecurityContextW
205 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
206 PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
207 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
208 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
209 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
211 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
212 struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
214 TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
215 phCredential, phContext, debugstr_w(pszTargetName), fContextReq,
216 Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
217 pfContextAttr, ptsExpiry);
219 if (phContext)
221 handle = ctxt = (struct sec_handle *)phContext->dwLower;
223 else if (phCredential)
225 handle = cred = (struct sec_handle *)phCredential->dwLower;
226 if (!(new_ctxt = ctxt = heap_alloc_zero( sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY;
227 ctxt->krb = cred->krb;
228 ctxt->ntlm = cred->ntlm;
230 if (!handle) return SEC_E_INVALID_HANDLE;
232 if (handle->krb)
234 ret = handle->krb->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_krb : NULL,
235 phContext ? &ctxt->handle_krb : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
236 Reserved2, phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry );
237 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
239 ctxt->ntlm = NULL;
240 phNewContext->dwLower = (ULONG_PTR)ctxt;
241 phNewContext->dwUpper = 0;
242 if (new_ctxt == ctxt) new_ctxt = NULL;
246 if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm)
248 ret = handle->ntlm->fnTableW.InitializeSecurityContextW( phCredential ? &cred->handle_ntlm : NULL,
249 phContext ? &ctxt->handle_ntlm : NULL, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
250 Reserved2, phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry );
251 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
253 ctxt->krb = NULL;
254 phNewContext->dwLower = (ULONG_PTR)ctxt;
255 phNewContext->dwUpper = 0;
256 if (new_ctxt == ctxt) new_ctxt = NULL;
260 heap_free( new_ctxt );
261 return ret;
264 /***********************************************************************
265 * InitializeSecurityContextA
267 static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
268 PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
269 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep,
270 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext,
271 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry )
273 SECURITY_STATUS ret;
274 SEC_WCHAR *target = NULL;
276 TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n",
277 phCredential, phContext, debugstr_a(pszTargetName), fContextReq,
278 Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput,
279 pfContextAttr, ptsExpiry);
281 if (pszTargetName)
283 int target_len = MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, NULL, 0 );
284 if (!(target = heap_alloc( target_len * sizeof(SEC_WCHAR) ))) return SEC_E_INSUFFICIENT_MEMORY;
285 MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, target, target_len );
287 ret = nego_InitializeSecurityContextW( phCredential, phContext, target, fContextReq,
288 Reserved1, TargetDataRep, pInput, Reserved2,
289 phNewContext, pOutput, pfContextAttr, ptsExpiry );
290 heap_free( target );
291 return ret;
294 /***********************************************************************
295 * AcceptSecurityContext
297 static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
298 PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
299 ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
300 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
302 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
303 struct sec_handle *handle = NULL, *ctxt, *new_ctxt = NULL, *cred = NULL;
305 TRACE("%p, %p, %p, 0x%08x, %u, %p, %p, %p, %p\n", phCredential, phContext,
306 pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
307 ptsExpiry);
309 if (phContext)
311 handle = ctxt = (struct sec_handle *)phContext->dwLower;
313 else if (phCredential)
315 handle = cred = (struct sec_handle *)phCredential->dwLower;
316 if (!(new_ctxt = ctxt = heap_alloc_zero( sizeof(*ctxt) ))) return SEC_E_INSUFFICIENT_MEMORY;
317 ctxt->krb = cred->krb;
318 ctxt->ntlm = cred->ntlm;
320 if (!handle) return SEC_E_INVALID_HANDLE;
322 if (handle->krb)
324 ret = handle->krb->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_krb : NULL,
325 phContext ? &ctxt->handle_krb : NULL, pInput, fContextReq, TargetDataRep,
326 phNewContext ? &ctxt->handle_krb : NULL, pOutput, pfContextAttr, ptsExpiry );
327 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
329 ctxt->ntlm = NULL;
330 phNewContext->dwLower = (ULONG_PTR)ctxt;
331 phNewContext->dwUpper = 0;
332 if (new_ctxt == ctxt) new_ctxt = NULL;
336 if (ret != SEC_E_OK && ret != SEC_I_CONTINUE_NEEDED && handle->ntlm)
338 ret = handle->ntlm->fnTableW.AcceptSecurityContext( phCredential ? &cred->handle_ntlm : NULL,
339 phContext ? &ctxt->handle_ntlm : NULL, pInput, fContextReq, TargetDataRep,
340 phNewContext ? &ctxt->handle_ntlm : NULL, pOutput, pfContextAttr, ptsExpiry );
341 if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && phNewContext)
343 ctxt->krb = NULL;
344 phNewContext->dwLower = (ULONG_PTR)ctxt;
345 phNewContext->dwUpper = 0;
346 if (new_ctxt == ctxt) new_ctxt = NULL;
350 heap_free( new_ctxt );
351 return ret;
354 /***********************************************************************
355 * CompleteAuthToken
357 static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
358 PSecBufferDesc pToken)
360 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
362 TRACE("%p %p\n", phContext, pToken);
364 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
365 return ret;
368 /***********************************************************************
369 * DeleteSecurityContext
371 static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
373 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
374 struct sec_handle *ctxt;
376 TRACE("%p\n", phContext);
378 if (!phContext) return SEC_E_INVALID_HANDLE;
380 ctxt = (struct sec_handle *)phContext->dwLower;
381 if (ctxt->krb)
383 ret = ctxt->krb->fnTableW.DeleteSecurityContext( &ctxt->handle_krb );
385 else if (ctxt->ntlm)
387 ret = ctxt->ntlm->fnTableW.DeleteSecurityContext( &ctxt->handle_ntlm );
389 TRACE( "freeing %p\n", ctxt );
390 heap_free( ctxt );
391 return ret;
394 /***********************************************************************
395 * ApplyControlToken
397 static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
398 PSecBufferDesc pInput)
400 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
402 TRACE("%p %p\n", phContext, pInput);
404 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
405 return ret;
408 /***********************************************************************
409 * QueryContextAttributesW
411 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(
412 PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
414 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
415 struct sec_handle *ctxt;
417 TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
419 if (!phContext) return SEC_E_INVALID_HANDLE;
421 ctxt = (struct sec_handle *)phContext->dwLower;
422 if (ctxt->krb)
424 ret = ctxt->krb->fnTableW.QueryContextAttributesW( &ctxt->handle_krb, ulAttribute, pBuffer );
426 else if (ctxt->ntlm)
428 ret = ctxt->ntlm->fnTableW.QueryContextAttributesW( &ctxt->handle_ntlm, ulAttribute, pBuffer );
430 return ret;
433 /***********************************************************************
434 * QueryContextAttributesA
436 static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
437 ULONG ulAttribute, void *pBuffer)
439 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
440 struct sec_handle *ctxt;
442 TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer);
444 if (!phContext) return SEC_E_INVALID_HANDLE;
446 ctxt = (struct sec_handle *)phContext->dwLower;
447 if (ctxt->krb)
449 ret = ctxt->krb->fnTableA.QueryContextAttributesA( &ctxt->handle_krb, ulAttribute, pBuffer );
451 else if (ctxt->ntlm)
453 ret = ctxt->ntlm->fnTableA.QueryContextAttributesA( &ctxt->handle_ntlm, ulAttribute, pBuffer );
455 return ret;
458 /***********************************************************************
459 * ImpersonateSecurityContext
461 static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
463 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
465 TRACE("%p\n", phContext);
467 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
468 return ret;
471 /***********************************************************************
472 * RevertSecurityContext
474 static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
476 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
478 TRACE("%p\n", phContext);
480 if (phContext) ret = SEC_E_UNSUPPORTED_FUNCTION;
481 return ret;
484 /***********************************************************************
485 * MakeSignature
487 static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext,
488 ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
490 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
491 struct sec_handle *ctxt;
493 TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
495 if (!phContext) return SEC_E_INVALID_HANDLE;
497 ctxt = (struct sec_handle *)phContext->dwLower;
498 if (ctxt->krb)
500 ret = ctxt->krb->fnTableW.MakeSignature( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo );
502 else if (ctxt->ntlm)
504 ret = ctxt->ntlm->fnTableW.MakeSignature( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo );
506 return ret;
509 /***********************************************************************
510 * VerifySignature
512 static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
513 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
515 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
516 struct sec_handle *ctxt;
518 TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
520 if (!phContext) return SEC_E_INVALID_HANDLE;
522 ctxt = (struct sec_handle *)phContext->dwLower;
523 if (ctxt->krb)
525 ret = ctxt->krb->fnTableW.VerifySignature( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP );
527 else if (ctxt->ntlm)
529 ret = ctxt->ntlm->fnTableW.VerifySignature( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP );
531 return ret;
534 /***********************************************************************
535 * FreeCredentialsHandle
537 static SECURITY_STATUS SEC_ENTRY nego_FreeCredentialsHandle(PCredHandle phCredential)
539 struct sec_handle *cred;
541 TRACE("%p\n", phCredential);
543 if (!phCredential) return SEC_E_INVALID_HANDLE;
545 cred = (struct sec_handle *)phCredential->dwLower;
546 if (cred->krb) cred->krb->fnTableW.FreeCredentialsHandle( &cred->handle_krb );
547 if (cred->ntlm) cred->ntlm->fnTableW.FreeCredentialsHandle( &cred->handle_ntlm );
549 heap_free( cred );
550 return SEC_E_OK;
553 /***********************************************************************
554 * EncryptMessage
556 static SECURITY_STATUS SEC_ENTRY nego_EncryptMessage(PCtxtHandle phContext,
557 ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
559 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
560 struct sec_handle *ctxt;
562 TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo);
564 if (!phContext) return SEC_E_INVALID_HANDLE;
566 ctxt = (struct sec_handle *)phContext->dwLower;
567 if (ctxt->krb)
569 ret = ctxt->krb->fnTableW.EncryptMessage( &ctxt->handle_krb, fQOP, pMessage, MessageSeqNo );
571 else if (ctxt->ntlm)
573 ret = ctxt->ntlm->fnTableW.EncryptMessage( &ctxt->handle_ntlm, fQOP, pMessage, MessageSeqNo );
575 return ret;
578 /***********************************************************************
579 * DecryptMessage
581 static SECURITY_STATUS SEC_ENTRY nego_DecryptMessage(PCtxtHandle phContext,
582 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
584 SECURITY_STATUS ret = SEC_E_INVALID_HANDLE;
585 struct sec_handle *ctxt;
587 TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
589 if (!phContext) return SEC_E_INVALID_HANDLE;
591 ctxt = (struct sec_handle *)phContext->dwLower;
592 if (ctxt->krb)
594 ret = ctxt->krb->fnTableW.DecryptMessage( &ctxt->handle_krb, pMessage, MessageSeqNo, pfQOP );
596 else if (ctxt->ntlm)
598 ret = ctxt->ntlm->fnTableW.DecryptMessage( &ctxt->handle_ntlm, pMessage, MessageSeqNo, pfQOP );
600 return ret;
603 static const SecurityFunctionTableA negoTableA = {
605 NULL, /* EnumerateSecurityPackagesA */
606 nego_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */
607 nego_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */
608 nego_FreeCredentialsHandle, /* FreeCredentialsHandle */
609 NULL, /* Reserved2 */
610 nego_InitializeSecurityContextA, /* InitializeSecurityContextA */
611 nego_AcceptSecurityContext, /* AcceptSecurityContext */
612 nego_CompleteAuthToken, /* CompleteAuthToken */
613 nego_DeleteSecurityContext, /* DeleteSecurityContext */
614 nego_ApplyControlToken, /* ApplyControlToken */
615 nego_QueryContextAttributesA, /* QueryContextAttributesA */
616 nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
617 nego_RevertSecurityContext, /* RevertSecurityContext */
618 nego_MakeSignature, /* MakeSignature */
619 nego_VerifySignature, /* VerifySignature */
620 FreeContextBuffer, /* FreeContextBuffer */
621 NULL, /* QuerySecurityPackageInfoA */
622 NULL, /* Reserved3 */
623 NULL, /* Reserved4 */
624 NULL, /* ExportSecurityContext */
625 NULL, /* ImportSecurityContextA */
626 NULL, /* AddCredentialsA */
627 NULL, /* Reserved8 */
628 NULL, /* QuerySecurityContextToken */
629 nego_EncryptMessage, /* EncryptMessage */
630 nego_DecryptMessage, /* DecryptMessage */
631 NULL, /* SetContextAttributesA */
634 static const SecurityFunctionTableW negoTableW = {
636 NULL, /* EnumerateSecurityPackagesW */
637 nego_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */
638 nego_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */
639 nego_FreeCredentialsHandle, /* FreeCredentialsHandle */
640 NULL, /* Reserved2 */
641 nego_InitializeSecurityContextW, /* InitializeSecurityContextW */
642 nego_AcceptSecurityContext, /* AcceptSecurityContext */
643 nego_CompleteAuthToken, /* CompleteAuthToken */
644 nego_DeleteSecurityContext, /* DeleteSecurityContext */
645 nego_ApplyControlToken, /* ApplyControlToken */
646 nego_QueryContextAttributesW, /* QueryContextAttributesW */
647 nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
648 nego_RevertSecurityContext, /* RevertSecurityContext */
649 nego_MakeSignature, /* MakeSignature */
650 nego_VerifySignature, /* VerifySignature */
651 FreeContextBuffer, /* FreeContextBuffer */
652 NULL, /* QuerySecurityPackageInfoW */
653 NULL, /* Reserved3 */
654 NULL, /* Reserved4 */
655 NULL, /* ExportSecurityContext */
656 NULL, /* ImportSecurityContextW */
657 NULL, /* AddCredentialsW */
658 NULL, /* Reserved8 */
659 NULL, /* QuerySecurityContextToken */
660 nego_EncryptMessage, /* EncryptMessage */
661 nego_DecryptMessage, /* DecryptMessage */
662 NULL, /* SetContextAttributesW */
665 #define NEGO_MAX_TOKEN 12000
667 static WCHAR nego_name_W[] = {'N','e','g','o','t','i','a','t','e',0};
668 static char nego_name_A[] = "Negotiate";
670 static WCHAR negotiate_comment_W[] =
671 {'M','i','c','r','o','s','o','f','t',' ','P','a','c','k','a','g','e',' ',
672 'N','e','g','o','t','i','a','t','o','r',0};
673 static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
675 #define CAPS ( \
676 SECPKG_FLAG_INTEGRITY | \
677 SECPKG_FLAG_PRIVACY | \
678 SECPKG_FLAG_CONNECTION | \
679 SECPKG_FLAG_MULTI_REQUIRED | \
680 SECPKG_FLAG_EXTENDED_ERROR | \
681 SECPKG_FLAG_IMPERSONATION | \
682 SECPKG_FLAG_ACCEPT_WIN32_NAME | \
683 SECPKG_FLAG_NEGOTIABLE | \
684 SECPKG_FLAG_GSS_COMPATIBLE | \
685 SECPKG_FLAG_LOGON | \
686 SECPKG_FLAG_RESTRICTED_TOKENS )
688 void SECUR32_initNegotiateSP(void)
690 SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, NULL);
692 const SecPkgInfoW infoW = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
693 nego_name_W, negotiate_comment_W};
694 const SecPkgInfoA infoA = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN,
695 nego_name_A, negotiate_comment_A};
696 SECUR32_addPackages(provider, 1L, &infoA, &infoW);