1 /**
2 * WinPR: Windows Portable Runtime
3 * Negotiate Security Package
4 *
5 * Copyright 2011-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 * Copyright 2017 Dorian Ducournau <dorian.ducournau@gmail.com>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <winpr/crt.h>
26 #include <winpr/sspi.h>
27 #include <winpr/tchar.h>
28
29 #include "negotiate.h"
30
31 #include "../sspi.h"
32 #include "../log.h"
33 #define TAG WINPR_TAG("negotiate")
34
35 extern const SecurityFunctionTableA NTLM_SecurityFunctionTableA;
36 extern const SecurityFunctionTableW NTLM_SecurityFunctionTableW;
37
38 extern const SecurityFunctionTableA KERBEROS_SecurityFunctionTableA;
39 extern const SecurityFunctionTableW KERBEROS_SecurityFunctionTableW;
40
41 #ifdef WITH_GSSAPI
42 static BOOL ErrorInitContextKerberos = FALSE;
43 #else
44 static BOOL ErrorInitContextKerberos = TRUE;
45 #endif
46
47 const SecPkgInfoA NEGOTIATE_SecPkgInfoA = {
48 0x00083BB3, /* fCapabilities */
49 1, /* wVersion */
50 0x0009, /* wRPCID */
51 0x00002FE0, /* cbMaxToken */
52 "Negotiate", /* Name */
53 "Microsoft Package Negotiator" /* Comment */
54 };
55
56 static WCHAR NEGOTIATE_SecPkgInfoW_Name[] = { 'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', '\0' };
57
58 static WCHAR NEGOTIATE_SecPkgInfoW_Comment[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ',
59 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', 'N', 'e',
60 'g', 'o', 't', 'i', 'a', 't', 'o', 'r', '\0' };
61
62 const SecPkgInfoW NEGOTIATE_SecPkgInfoW = {
63 0x00083BB3, /* fCapabilities */
64 1, /* wVersion */
65 0x0009, /* wRPCID */
66 0x00002FE0, /* cbMaxToken */
67 NEGOTIATE_SecPkgInfoW_Name, /* Name */
68 NEGOTIATE_SecPkgInfoW_Comment /* Comment */
69 };
70
negotiate_SetSubPackage(NEGOTIATE_CONTEXT * context,const TCHAR * name)71 static void negotiate_SetSubPackage(NEGOTIATE_CONTEXT* context, const TCHAR* name)
72 {
73 if (_tcsnccmp(name, KERBEROS_SSP_NAME, ARRAYSIZE(KERBEROS_SSP_NAME)) == 0)
74 {
75 context->sspiA = (SecurityFunctionTableA*)&KERBEROS_SecurityFunctionTableA;
76 context->sspiW = (SecurityFunctionTableW*)&KERBEROS_SecurityFunctionTableW;
77 context->kerberos = TRUE;
78 }
79 else
80 {
81 context->sspiA = (SecurityFunctionTableA*)&NTLM_SecurityFunctionTableA;
82 context->sspiW = (SecurityFunctionTableW*)&NTLM_SecurityFunctionTableW;
83 context->kerberos = FALSE;
84 }
85 }
86
negotiate_ContextNew(void)87 static NEGOTIATE_CONTEXT* negotiate_ContextNew(void)
88 {
89 NEGOTIATE_CONTEXT* context;
90 context = (NEGOTIATE_CONTEXT*)calloc(1, sizeof(NEGOTIATE_CONTEXT));
91
92 if (!context)
93 return NULL;
94
95 context->NegotiateFlags = 0;
96 context->state = NEGOTIATE_STATE_INITIAL;
97 SecInvalidateHandle(&(context->SubContext));
98 negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
99 return context;
100 }
101
negotiate_ContextFree(NEGOTIATE_CONTEXT * context)102 static void negotiate_ContextFree(NEGOTIATE_CONTEXT* context)
103 {
104 free(context);
105 }
106
negotiate_InitializeSecurityContextW(PCredHandle phCredential,PCtxtHandle phContext,SEC_WCHAR * pszTargetName,ULONG fContextReq,ULONG Reserved1,ULONG TargetDataRep,PSecBufferDesc pInput,ULONG Reserved2,PCtxtHandle phNewContext,PSecBufferDesc pOutput,PULONG pfContextAttr,PTimeStamp ptsExpiry)107 static SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextW(
108 PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq,
109 ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
110 PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
111 {
112 SECURITY_STATUS status;
113 NEGOTIATE_CONTEXT* context;
114 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
115
116 if (!context)
117 {
118 context = negotiate_ContextNew();
119
120 if (!context)
121 return SEC_E_INTERNAL_ERROR;
122
123 sspi_SecureHandleSetLowerPointer(phNewContext, context);
124 sspi_SecureHandleSetUpperPointer(phNewContext, (void*)NEGO_SSP_NAME);
125 }
126
127 /* if Kerberos has previously failed or WITH_GSSAPI is not defined, we use NTLM directly */
128 if (ErrorInitContextKerberos == FALSE)
129 {
130 if (!pInput)
131 {
132 negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
133 }
134
135 status = context->sspiW->InitializeSecurityContextW(
136 phCredential, &(context->SubContext), pszTargetName, fContextReq, Reserved1,
137 TargetDataRep, pInput, Reserved2, &(context->SubContext), pOutput, pfContextAttr,
138 ptsExpiry);
139
140 if (status == SEC_E_NO_CREDENTIALS)
141 {
142 WLog_WARN(TAG, "No Kerberos credentials. Retry with NTLM");
143 ErrorInitContextKerberos = TRUE;
144 context->sspiA->DeleteSecurityContext(&(context->SubContext));
145 negotiate_ContextFree(context);
146 return status;
147 }
148 }
149 else
150 {
151 if (!pInput)
152 {
153 context->sspiA->DeleteSecurityContext(&(context->SubContext));
154 negotiate_SetSubPackage(context, NTLM_SSP_NAME);
155 }
156
157 status = context->sspiW->InitializeSecurityContextW(
158 phCredential, &(context->SubContext), pszTargetName, fContextReq, Reserved1,
159 TargetDataRep, pInput, Reserved2, &(context->SubContext), pOutput, pfContextAttr,
160 ptsExpiry);
161 }
162
163 return status;
164 }
165
negotiate_InitializeSecurityContextA(PCredHandle phCredential,PCtxtHandle phContext,SEC_CHAR * pszTargetName,ULONG fContextReq,ULONG Reserved1,ULONG TargetDataRep,PSecBufferDesc pInput,ULONG Reserved2,PCtxtHandle phNewContext,PSecBufferDesc pOutput,PULONG pfContextAttr,PTimeStamp ptsExpiry)166 static SECURITY_STATUS SEC_ENTRY negotiate_InitializeSecurityContextA(
167 PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq,
168 ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
169 PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
170 {
171 SECURITY_STATUS status;
172 NEGOTIATE_CONTEXT* context;
173 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
174
175 if (!context)
176 {
177 context = negotiate_ContextNew();
178
179 if (!context)
180 return SEC_E_INTERNAL_ERROR;
181
182 sspi_SecureHandleSetLowerPointer(phNewContext, context);
183 sspi_SecureHandleSetUpperPointer(phNewContext, (void*)NEGO_SSP_NAME);
184 }
185
186 /* if Kerberos has previously failed or WITH_GSSAPI is not defined, we use NTLM directly */
187 if (ErrorInitContextKerberos == FALSE)
188 {
189 if (!pInput)
190 {
191 negotiate_SetSubPackage(context, KERBEROS_SSP_NAME);
192 }
193
194 status = context->sspiA->InitializeSecurityContextA(
195 phCredential, &(context->SubContext), pszTargetName, fContextReq, Reserved1,
196 TargetDataRep, pInput, Reserved2, &(context->SubContext), pOutput, pfContextAttr,
197 ptsExpiry);
198
199 if (status == SEC_E_NO_CREDENTIALS)
200 {
201 WLog_WARN(TAG, "No Kerberos credentials. Retry with NTLM");
202 ErrorInitContextKerberos = TRUE;
203 context->sspiA->DeleteSecurityContext(&(context->SubContext));
204 negotiate_ContextFree(context);
205 return status;
206 }
207 }
208 else
209 {
210 if (!pInput)
211 {
212 context->sspiA->DeleteSecurityContext(&(context->SubContext));
213 negotiate_SetSubPackage(context, NTLM_SSP_NAME);
214 }
215
216 status = context->sspiA->InitializeSecurityContextA(
217 phCredential, &(context->SubContext), pszTargetName, fContextReq, Reserved1,
218 TargetDataRep, pInput, Reserved2, &(context->SubContext), pOutput, pfContextAttr,
219 ptsExpiry);
220 }
221
222 return status;
223 }
224
negotiate_AcceptSecurityContext(PCredHandle phCredential,PCtxtHandle phContext,PSecBufferDesc pInput,ULONG fContextReq,ULONG TargetDataRep,PCtxtHandle phNewContext,PSecBufferDesc pOutput,PULONG pfContextAttr,PTimeStamp ptsTimeStamp)225 static SECURITY_STATUS SEC_ENTRY negotiate_AcceptSecurityContext(
226 PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq,
227 ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr,
228 PTimeStamp ptsTimeStamp)
229 {
230 SECURITY_STATUS status;
231 NEGOTIATE_CONTEXT* context;
232 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
233
234 if (!context)
235 {
236 context = negotiate_ContextNew();
237
238 if (!context)
239 return SEC_E_INTERNAL_ERROR;
240
241 sspi_SecureHandleSetLowerPointer(phNewContext, context);
242 sspi_SecureHandleSetUpperPointer(phNewContext, (void*)NEGO_SSP_NAME);
243 }
244
245 negotiate_SetSubPackage(context, NTLM_SSP_NAME); /* server-side Kerberos not yet implemented */
246 status = context->sspiA->AcceptSecurityContext(
247 phCredential, &(context->SubContext), pInput, fContextReq, TargetDataRep,
248 &(context->SubContext), pOutput, pfContextAttr, ptsTimeStamp);
249
250 if (status != SEC_E_OK)
251 {
252 WLog_WARN(TAG, "AcceptSecurityContext status %s [0x%08" PRIX32 "]",
253 GetSecurityStatusString(status), status);
254 }
255
256 return status;
257 }
258
negotiate_CompleteAuthToken(PCtxtHandle phContext,PSecBufferDesc pToken)259 static SECURITY_STATUS SEC_ENTRY negotiate_CompleteAuthToken(PCtxtHandle phContext,
260 PSecBufferDesc pToken)
261 {
262 NEGOTIATE_CONTEXT* context;
263 SECURITY_STATUS status = SEC_E_OK;
264 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
265
266 if (!context)
267 return SEC_E_INVALID_HANDLE;
268
269 if (context->sspiW->CompleteAuthToken)
270 status = context->sspiW->CompleteAuthToken(&(context->SubContext), pToken);
271
272 return status;
273 }
274
negotiate_DeleteSecurityContext(PCtxtHandle phContext)275 static SECURITY_STATUS SEC_ENTRY negotiate_DeleteSecurityContext(PCtxtHandle phContext)
276 {
277 NEGOTIATE_CONTEXT* context;
278 SECURITY_STATUS status = SEC_E_OK;
279 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
280
281 if (!context)
282 return SEC_E_INVALID_HANDLE;
283
284 if (context->sspiW->DeleteSecurityContext)
285 status = context->sspiW->DeleteSecurityContext(&(context->SubContext));
286
287 negotiate_ContextFree(context);
288 return status;
289 }
290
negotiate_ImpersonateSecurityContext(PCtxtHandle phContext)291 static SECURITY_STATUS SEC_ENTRY negotiate_ImpersonateSecurityContext(PCtxtHandle phContext)
292 {
293 NEGOTIATE_CONTEXT* context;
294 SECURITY_STATUS status = SEC_E_OK;
295 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
296
297 if (!phContext)
298 return SEC_E_INVALID_HANDLE;
299
300 if (context->sspiW->ImpersonateSecurityContext)
301 status = context->sspiW->ImpersonateSecurityContext(&(context->SubContext));
302
303 return status;
304 }
305
negotiate_RevertSecurityContext(PCtxtHandle phContext)306 static SECURITY_STATUS SEC_ENTRY negotiate_RevertSecurityContext(PCtxtHandle phContext)
307 {
308 NEGOTIATE_CONTEXT* context;
309 SECURITY_STATUS status = SEC_E_OK;
310 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
311
312 if (!phContext)
313 return SEC_E_INVALID_HANDLE;
314
315 if (context->sspiW->RevertSecurityContext)
316 status = context->sspiW->RevertSecurityContext(&(context->SubContext));
317
318 return status;
319 }
320
negotiate_QueryContextAttributesW(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer)321 static SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesW(PCtxtHandle phContext,
322 ULONG ulAttribute, void* pBuffer)
323 {
324 NEGOTIATE_CONTEXT* context;
325 SECURITY_STATUS status = SEC_E_OK;
326 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
327
328 if (!phContext)
329 return SEC_E_INVALID_HANDLE;
330
331 if (!pBuffer)
332 return SEC_E_INSUFFICIENT_MEMORY;
333
334 if (context->sspiW->QueryContextAttributesW)
335 status =
336 context->sspiW->QueryContextAttributesW(&(context->SubContext), ulAttribute, pBuffer);
337
338 return status;
339 }
340
negotiate_QueryContextAttributesA(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer)341 static SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributesA(PCtxtHandle phContext,
342 ULONG ulAttribute, void* pBuffer)
343 {
344 NEGOTIATE_CONTEXT* context;
345 SECURITY_STATUS status = SEC_E_OK;
346 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
347
348 if (!phContext)
349 return SEC_E_INVALID_HANDLE;
350
351 if (!pBuffer)
352 return SEC_E_INSUFFICIENT_MEMORY;
353
354 if (context->sspiA->QueryContextAttributesA)
355 status =
356 context->sspiA->QueryContextAttributesA(&(context->SubContext), ulAttribute, pBuffer);
357
358 return status;
359 }
360
negotiate_SetContextAttributesW(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer,ULONG cbBuffer)361 static SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesW(PCtxtHandle phContext,
362 ULONG ulAttribute, void* pBuffer,
363 ULONG cbBuffer)
364 {
365 NEGOTIATE_CONTEXT* context;
366 SECURITY_STATUS status = SEC_E_OK;
367 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
368
369 if (!phContext)
370 return SEC_E_INVALID_HANDLE;
371
372 if (!pBuffer)
373 return SEC_E_INSUFFICIENT_MEMORY;
374
375 if (context->sspiW->SetContextAttributesW)
376 status = context->sspiW->SetContextAttributesW(&(context->SubContext), ulAttribute, pBuffer,
377 cbBuffer);
378
379 return status;
380 }
381
negotiate_SetContextAttributesA(PCtxtHandle phContext,ULONG ulAttribute,void * pBuffer,ULONG cbBuffer)382 static SECURITY_STATUS SEC_ENTRY negotiate_SetContextAttributesA(PCtxtHandle phContext,
383 ULONG ulAttribute, void* pBuffer,
384 ULONG cbBuffer)
385 {
386 NEGOTIATE_CONTEXT* context;
387 SECURITY_STATUS status = SEC_E_OK;
388 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
389
390 if (!phContext)
391 return SEC_E_INVALID_HANDLE;
392
393 if (!pBuffer)
394 return SEC_E_INSUFFICIENT_MEMORY;
395
396 if (context->sspiA->SetContextAttributesA)
397 status = context->sspiA->SetContextAttributesA(&(context->SubContext), ulAttribute, pBuffer,
398 cbBuffer);
399
400 return status;
401 }
402
negotiate_AcquireCredentialsHandleW(SEC_WCHAR * pszPrincipal,SEC_WCHAR * pszPackage,ULONG fCredentialUse,void * pvLogonID,void * pAuthData,SEC_GET_KEY_FN pGetKeyFn,void * pvGetKeyArgument,PCredHandle phCredential,PTimeStamp ptsExpiry)403 static SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW(
404 SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
405 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
406 PTimeStamp ptsExpiry)
407 {
408 SSPI_CREDENTIALS* credentials;
409 SEC_WINNT_AUTH_IDENTITY* identity;
410
411 if ((fCredentialUse != SECPKG_CRED_OUTBOUND) && (fCredentialUse != SECPKG_CRED_INBOUND) &&
412 (fCredentialUse != SECPKG_CRED_BOTH))
413 {
414 return SEC_E_INVALID_PARAMETER;
415 }
416
417 credentials = sspi_CredentialsNew();
418
419 if (!credentials)
420 return SEC_E_INTERNAL_ERROR;
421
422 credentials->fCredentialUse = fCredentialUse;
423 credentials->pGetKeyFn = pGetKeyFn;
424 credentials->pvGetKeyArgument = pvGetKeyArgument;
425 identity = (SEC_WINNT_AUTH_IDENTITY*)pAuthData;
426
427 if (identity)
428 sspi_CopyAuthIdentity(&(credentials->identity), identity);
429
430 sspi_SecureHandleSetLowerPointer(phCredential, (void*)credentials);
431 sspi_SecureHandleSetUpperPointer(phCredential, (void*)NEGO_SSP_NAME);
432 return SEC_E_OK;
433 }
434
negotiate_AcquireCredentialsHandleA(SEC_CHAR * pszPrincipal,SEC_CHAR * pszPackage,ULONG fCredentialUse,void * pvLogonID,void * pAuthData,SEC_GET_KEY_FN pGetKeyFn,void * pvGetKeyArgument,PCredHandle phCredential,PTimeStamp ptsExpiry)435 static SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA(
436 SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
437 void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
438 PTimeStamp ptsExpiry)
439 {
440 SSPI_CREDENTIALS* credentials;
441 SEC_WINNT_AUTH_IDENTITY* identity;
442
443 if ((fCredentialUse != SECPKG_CRED_OUTBOUND) && (fCredentialUse != SECPKG_CRED_INBOUND) &&
444 (fCredentialUse != SECPKG_CRED_BOTH))
445 {
446 return SEC_E_INVALID_PARAMETER;
447 }
448
449 credentials = sspi_CredentialsNew();
450
451 if (!credentials)
452 return SEC_E_INTERNAL_ERROR;
453
454 credentials->fCredentialUse = fCredentialUse;
455 credentials->pGetKeyFn = pGetKeyFn;
456 credentials->pvGetKeyArgument = pvGetKeyArgument;
457 identity = (SEC_WINNT_AUTH_IDENTITY*)pAuthData;
458
459 if (identity)
460 sspi_CopyAuthIdentity(&(credentials->identity), identity);
461
462 sspi_SecureHandleSetLowerPointer(phCredential, (void*)credentials);
463 sspi_SecureHandleSetUpperPointer(phCredential, (void*)NEGO_SSP_NAME);
464 return SEC_E_OK;
465 }
466
negotiate_QueryCredentialsAttributesW(PCredHandle phCredential,ULONG ulAttribute,void * pBuffer)467 static SECURITY_STATUS SEC_ENTRY negotiate_QueryCredentialsAttributesW(PCredHandle phCredential,
468 ULONG ulAttribute,
469 void* pBuffer)
470 {
471 WLog_ERR(TAG, "[%s]: TODO: Implement", __FUNCTION__);
472 return SEC_E_UNSUPPORTED_FUNCTION;
473 }
474
negotiate_QueryCredentialsAttributesA(PCredHandle phCredential,ULONG ulAttribute,void * pBuffer)475 static SECURITY_STATUS SEC_ENTRY negotiate_QueryCredentialsAttributesA(PCredHandle phCredential,
476 ULONG ulAttribute,
477 void* pBuffer)
478 {
479 WLog_ERR(TAG, "[%s]: TODO: Implement", __FUNCTION__);
480 return SEC_E_UNSUPPORTED_FUNCTION;
481 }
482
negotiate_FreeCredentialsHandle(PCredHandle phCredential)483 static SECURITY_STATUS SEC_ENTRY negotiate_FreeCredentialsHandle(PCredHandle phCredential)
484 {
485 SSPI_CREDENTIALS* credentials;
486
487 if (!phCredential)
488 return SEC_E_INVALID_HANDLE;
489
490 credentials = (SSPI_CREDENTIALS*)sspi_SecureHandleGetLowerPointer(phCredential);
491
492 if (!credentials)
493 return SEC_E_INVALID_HANDLE;
494
495 sspi_CredentialsFree(credentials);
496 sspi_SecureHandleInvalidate(phCredential);
497 return SEC_E_OK;
498 }
499
negotiate_EncryptMessage(PCtxtHandle phContext,ULONG fQOP,PSecBufferDesc pMessage,ULONG MessageSeqNo)500 static SECURITY_STATUS SEC_ENTRY negotiate_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
501 PSecBufferDesc pMessage,
502 ULONG MessageSeqNo)
503 {
504 NEGOTIATE_CONTEXT* context;
505 SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
506 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
507
508 if (context->sspiW->EncryptMessage)
509 status =
510 context->sspiW->EncryptMessage(&(context->SubContext), fQOP, pMessage, MessageSeqNo);
511 else
512 WLog_WARN(TAG, "[%s] SSPI implementation of function is missing", __FUNCTION__);
513 return status;
514 }
515
negotiate_DecryptMessage(PCtxtHandle phContext,PSecBufferDesc pMessage,ULONG MessageSeqNo,ULONG * pfQOP)516 static SECURITY_STATUS SEC_ENTRY negotiate_DecryptMessage(PCtxtHandle phContext,
517 PSecBufferDesc pMessage,
518 ULONG MessageSeqNo, ULONG* pfQOP)
519 {
520 NEGOTIATE_CONTEXT* context;
521 SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
522 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
523
524 if (context->sspiW->DecryptMessage)
525 status =
526 context->sspiW->DecryptMessage(&(context->SubContext), pMessage, MessageSeqNo, pfQOP);
527 else
528 WLog_WARN(TAG, "[%s] SSPI implementation of function is missing", __FUNCTION__);
529 return status;
530 }
531
negotiate_MakeSignature(PCtxtHandle phContext,ULONG fQOP,PSecBufferDesc pMessage,ULONG MessageSeqNo)532 static SECURITY_STATUS SEC_ENTRY negotiate_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
533 PSecBufferDesc pMessage,
534 ULONG MessageSeqNo)
535 {
536 NEGOTIATE_CONTEXT* context;
537 SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
538 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
539
540 if (context->sspiW->MakeSignature)
541 status =
542 context->sspiW->MakeSignature(&(context->SubContext), fQOP, pMessage, MessageSeqNo);
543 else
544 WLog_WARN(TAG, "[%s] SSPI implementation of function is missing", __FUNCTION__);
545 return status;
546 }
547
negotiate_VerifySignature(PCtxtHandle phContext,PSecBufferDesc pMessage,ULONG MessageSeqNo,ULONG * pfQOP)548 static SECURITY_STATUS SEC_ENTRY negotiate_VerifySignature(PCtxtHandle phContext,
549 PSecBufferDesc pMessage,
550 ULONG MessageSeqNo, ULONG* pfQOP)
551 {
552 NEGOTIATE_CONTEXT* context;
553 SECURITY_STATUS status = SEC_E_UNSUPPORTED_FUNCTION;
554 context = (NEGOTIATE_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
555
556 if (context->sspiW->VerifySignature)
557 status =
558 context->sspiW->VerifySignature(&(context->SubContext), pMessage, MessageSeqNo, pfQOP);
559 else
560 WLog_WARN(TAG, "[%s] SSPI implementation of function is missing", __FUNCTION__);
561 return status;
562 }
563
564 const SecurityFunctionTableA NEGOTIATE_SecurityFunctionTableA = {
565 1, /* dwVersion */
566 NULL, /* EnumerateSecurityPackages */
567 negotiate_QueryCredentialsAttributesA, /* QueryCredentialsAttributes */
568 negotiate_AcquireCredentialsHandleA, /* AcquireCredentialsHandle */
569 negotiate_FreeCredentialsHandle, /* FreeCredentialsHandle */
570 NULL, /* Reserved2 */
571 negotiate_InitializeSecurityContextA, /* InitializeSecurityContext */
572 negotiate_AcceptSecurityContext, /* AcceptSecurityContext */
573 negotiate_CompleteAuthToken, /* CompleteAuthToken */
574 negotiate_DeleteSecurityContext, /* DeleteSecurityContext */
575 NULL, /* ApplyControlToken */
576 negotiate_QueryContextAttributesA, /* QueryContextAttributes */
577 negotiate_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
578 negotiate_RevertSecurityContext, /* RevertSecurityContext */
579 negotiate_MakeSignature, /* MakeSignature */
580 negotiate_VerifySignature, /* VerifySignature */
581 NULL, /* FreeContextBuffer */
582 NULL, /* QuerySecurityPackageInfo */
583 NULL, /* Reserved3 */
584 NULL, /* Reserved4 */
585 NULL, /* ExportSecurityContext */
586 NULL, /* ImportSecurityContext */
587 NULL, /* AddCredentials */
588 NULL, /* Reserved8 */
589 NULL, /* QuerySecurityContextToken */
590 negotiate_EncryptMessage, /* EncryptMessage */
591 negotiate_DecryptMessage, /* DecryptMessage */
592 negotiate_SetContextAttributesA, /* SetContextAttributes */
593 };
594
595 const SecurityFunctionTableW NEGOTIATE_SecurityFunctionTableW = {
596 1, /* dwVersion */
597 NULL, /* EnumerateSecurityPackages */
598 negotiate_QueryCredentialsAttributesW, /* QueryCredentialsAttributes */
599 negotiate_AcquireCredentialsHandleW, /* AcquireCredentialsHandle */
600 negotiate_FreeCredentialsHandle, /* FreeCredentialsHandle */
601 NULL, /* Reserved2 */
602 negotiate_InitializeSecurityContextW, /* InitializeSecurityContext */
603 negotiate_AcceptSecurityContext, /* AcceptSecurityContext */
604 negotiate_CompleteAuthToken, /* CompleteAuthToken */
605 negotiate_DeleteSecurityContext, /* DeleteSecurityContext */
606 NULL, /* ApplyControlToken */
607 negotiate_QueryContextAttributesW, /* QueryContextAttributes */
608 negotiate_ImpersonateSecurityContext, /* ImpersonateSecurityContext */
609 negotiate_RevertSecurityContext, /* RevertSecurityContext */
610 negotiate_MakeSignature, /* MakeSignature */
611 negotiate_VerifySignature, /* VerifySignature */
612 NULL, /* FreeContextBuffer */
613 NULL, /* QuerySecurityPackageInfo */
614 NULL, /* Reserved3 */
615 NULL, /* Reserved4 */
616 NULL, /* ExportSecurityContext */
617 NULL, /* ImportSecurityContext */
618 NULL, /* AddCredentials */
619 NULL, /* Reserved8 */
620 NULL, /* QuerySecurityContextToken */
621 negotiate_EncryptMessage, /* EncryptMessage */
622 negotiate_DecryptMessage, /* DecryptMessage */
623 negotiate_SetContextAttributesW, /* SetContextAttributes */
624 };
625