Coverage Report

Created: 2026-03-04 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/libwinpr/sspi/sspi.c
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Security Support Provider Interface (SSPI)
4
 *
5
 * Copyright 2012-2014 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
20
#include <winpr/platform.h>
21
#include <winpr/config.h>
22
23
WINPR_PRAGMA_DIAG_PUSH
24
WINPR_PRAGMA_DIAG_IGNORED_RESERVED_ID_MACRO
25
WINPR_PRAGMA_DIAG_IGNORED_UNUSED_MACRO
26
27
#define _NO_KSECDD_IMPORT_ 1 // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp)
28
29
WINPR_PRAGMA_DIAG_POP
30
31
#include <winpr/sspi.h>
32
33
#include <winpr/crt.h>
34
#include <winpr/synch.h>
35
#include <winpr/wlog.h>
36
#include <winpr/library.h>
37
#include <winpr/environment.h>
38
39
#include "sspi.h"
40
41
#if defined(__GNUC__) || defined(__clang__)
42
#define IFCALLRESULT(_default_return, _cb, ...)                             \
43
0
  __extension__({                                                         \
44
0
    if (_cb == nullptr)                                                 \
45
0
    {                                                                   \
46
0
      WLog_VRB("com.winpr.api", "IFCALLRESULT(" #_cb ") == nullptr"); \
47
0
    }                                                                   \
48
0
    ((_cb != nullptr) ? _cb(__VA_ARGS__) : (_default_return));          \
49
0
  })
50
#else
51
#define IFCALLRESULT(_default_return, _cb, ...) \
52
  ((_cb != nullptr) ? _cb(__VA_ARGS__) : (_default_return))
53
#endif
54
55
WINPR_PRAGMA_DIAG_PUSH
56
WINPR_PRAGMA_DIAG_IGNORED_MISSING_PROTOTYPES
57
58
static wLog* g_Log = nullptr;
59
60
static INIT_ONCE g_Initialized = INIT_ONCE_STATIC_INIT;
61
#if defined(WITH_NATIVE_SSPI)
62
static HMODULE g_SspiModule = nullptr;
63
static SecurityFunctionTableW windows_SecurityFunctionTableW = WINPR_C_ARRAY_INIT;
64
static SecurityFunctionTableA windows_SecurityFunctionTableA = WINPR_C_ARRAY_INIT;
65
#endif
66
67
static SecurityFunctionTableW* g_SspiW = nullptr;
68
static SecurityFunctionTableA* g_SspiA = nullptr;
69
70
#if defined(WITH_NATIVE_SSPI)
71
static BOOL ShouldUseNativeSspi(void);
72
static BOOL InitializeSspiModule_Native(void);
73
#endif
74
75
#if defined(WITH_NATIVE_SSPI)
76
BOOL ShouldUseNativeSspi(void)
77
{
78
  BOOL status = FALSE;
79
#ifdef _WIN32
80
  LPCSTR sspi = "WINPR_NATIVE_SSPI";
81
  DWORD nSize;
82
  char* env = nullptr;
83
  nSize = GetEnvironmentVariableA(sspi, nullptr, 0);
84
85
  if (!nSize)
86
    return TRUE;
87
88
  env = (LPSTR)malloc(nSize);
89
90
  if (!env)
91
    return TRUE;
92
93
  if (GetEnvironmentVariableA(sspi, env, nSize) != nSize - 1)
94
  {
95
    free(env);
96
    return TRUE;
97
  }
98
99
  if (strcmp(env, "0") == 0)
100
    status = FALSE;
101
  else
102
    status = TRUE;
103
104
  free(env);
105
#endif
106
  return status;
107
}
108
#endif
109
110
#if defined(WITH_NATIVE_SSPI)
111
BOOL InitializeSspiModule_Native(void)
112
{
113
  SecurityFunctionTableW* pSspiW = nullptr;
114
  SecurityFunctionTableA* pSspiA = nullptr;
115
  INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW;
116
  INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA;
117
  g_SspiModule = LoadLibraryA("secur32.dll");
118
119
  if (!g_SspiModule)
120
    g_SspiModule = LoadLibraryA("sspicli.dll");
121
122
  if (!g_SspiModule)
123
    return FALSE;
124
125
  pInitSecurityInterfaceW =
126
      GetProcAddressAs(g_SspiModule, "InitSecurityInterfaceW", INIT_SECURITY_INTERFACE_W);
127
  pInitSecurityInterfaceA =
128
      GetProcAddressAs(g_SspiModule, "InitSecurityInterfaceA", INIT_SECURITY_INTERFACE_A);
129
130
  if (pInitSecurityInterfaceW)
131
  {
132
    pSspiW = pInitSecurityInterfaceW();
133
134
    if (pSspiW)
135
    {
136
      g_SspiW = &windows_SecurityFunctionTableW;
137
      CopyMemory(g_SspiW, pSspiW,
138
                 FIELD_OFFSET(SecurityFunctionTableW, SetContextAttributesW));
139
140
      g_SspiW->dwVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3;
141
142
      g_SspiW->SetContextAttributesW = GetProcAddressAs(g_SspiModule, "SetContextAttributesW",
143
                                                        SET_CONTEXT_ATTRIBUTES_FN_W);
144
145
      g_SspiW->SetCredentialsAttributesW = GetProcAddressAs(
146
          g_SspiModule, "SetCredentialsAttributesW", SET_CREDENTIALS_ATTRIBUTES_FN_W);
147
    }
148
  }
149
150
  if (pInitSecurityInterfaceA)
151
  {
152
    pSspiA = pInitSecurityInterfaceA();
153
154
    if (pSspiA)
155
    {
156
      g_SspiA = &windows_SecurityFunctionTableA;
157
      CopyMemory(g_SspiA, pSspiA,
158
                 FIELD_OFFSET(SecurityFunctionTableA, SetContextAttributesA));
159
160
      g_SspiA->dwVersion = SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_3;
161
162
      g_SspiA->SetContextAttributesA = GetProcAddressAs(g_SspiModule, "SetContextAttributesA",
163
                                                        SET_CONTEXT_ATTRIBUTES_FN_W);
164
165
      g_SspiA->SetCredentialsAttributesA = GetProcAddressAs(
166
          g_SspiModule, "SetCredentialsAttributesA", SET_CREDENTIALS_ATTRIBUTES_FN_W);
167
    }
168
  }
169
170
  return TRUE;
171
}
172
#endif
173
174
static BOOL CALLBACK InitializeSspiModuleInt(WINPR_ATTR_UNUSED PINIT_ONCE once,
175
                                             WINPR_ATTR_UNUSED PVOID param,
176
                                             WINPR_ATTR_UNUSED PVOID* context)
177
0
{
178
0
  BOOL status = FALSE;
179
#if defined(WITH_NATIVE_SSPI)
180
  DWORD flags = 0;
181
182
  if (param)
183
    flags = *(DWORD*)param;
184
185
#endif
186
0
  sspi_GlobalInit();
187
0
  g_Log = WLog_Get("com.winpr.sspi");
188
#if defined(WITH_NATIVE_SSPI)
189
190
  if (flags && (flags & SSPI_INTERFACE_NATIVE))
191
  {
192
    status = InitializeSspiModule_Native();
193
  }
194
  else if (flags && (flags & SSPI_INTERFACE_WINPR))
195
  {
196
    g_SspiW = winpr_InitSecurityInterfaceW();
197
    g_SspiA = winpr_InitSecurityInterfaceA();
198
    status = TRUE;
199
  }
200
201
  if (!status && ShouldUseNativeSspi())
202
  {
203
    status = InitializeSspiModule_Native();
204
  }
205
206
#endif
207
208
0
  if (!status)
209
0
  {
210
0
    g_SspiW = winpr_InitSecurityInterfaceW();
211
0
    g_SspiA = winpr_InitSecurityInterfaceA();
212
0
  }
213
214
0
  return TRUE;
215
0
}
216
217
const char* GetSecurityStatusString(SECURITY_STATUS status)
218
0
{
219
0
  switch (status)
220
0
  {
221
0
    case SEC_E_OK:
222
0
      return "SEC_E_OK";
223
224
0
    case SEC_E_INSUFFICIENT_MEMORY:
225
0
      return "SEC_E_INSUFFICIENT_MEMORY";
226
227
0
    case SEC_E_INVALID_HANDLE:
228
0
      return "SEC_E_INVALID_HANDLE";
229
230
0
    case SEC_E_UNSUPPORTED_FUNCTION:
231
0
      return "SEC_E_UNSUPPORTED_FUNCTION";
232
233
0
    case SEC_E_TARGET_UNKNOWN:
234
0
      return "SEC_E_TARGET_UNKNOWN";
235
236
0
    case SEC_E_INTERNAL_ERROR:
237
0
      return "SEC_E_INTERNAL_ERROR";
238
239
0
    case SEC_E_SECPKG_NOT_FOUND:
240
0
      return "SEC_E_SECPKG_NOT_FOUND";
241
242
0
    case SEC_E_NOT_OWNER:
243
0
      return "SEC_E_NOT_OWNER";
244
245
0
    case SEC_E_CANNOT_INSTALL:
246
0
      return "SEC_E_CANNOT_INSTALL";
247
248
0
    case SEC_E_INVALID_TOKEN:
249
0
      return "SEC_E_INVALID_TOKEN";
250
251
0
    case SEC_E_CANNOT_PACK:
252
0
      return "SEC_E_CANNOT_PACK";
253
254
0
    case SEC_E_QOP_NOT_SUPPORTED:
255
0
      return "SEC_E_QOP_NOT_SUPPORTED";
256
257
0
    case SEC_E_NO_IMPERSONATION:
258
0
      return "SEC_E_NO_IMPERSONATION";
259
260
0
    case SEC_E_LOGON_DENIED:
261
0
      return "SEC_E_LOGON_DENIED";
262
263
0
    case SEC_E_UNKNOWN_CREDENTIALS:
264
0
      return "SEC_E_UNKNOWN_CREDENTIALS";
265
266
0
    case SEC_E_NO_CREDENTIALS:
267
0
      return "SEC_E_NO_CREDENTIALS";
268
269
0
    case SEC_E_MESSAGE_ALTERED:
270
0
      return "SEC_E_MESSAGE_ALTERED";
271
272
0
    case SEC_E_OUT_OF_SEQUENCE:
273
0
      return "SEC_E_OUT_OF_SEQUENCE";
274
275
0
    case SEC_E_NO_AUTHENTICATING_AUTHORITY:
276
0
      return "SEC_E_NO_AUTHENTICATING_AUTHORITY";
277
278
0
    case SEC_E_BAD_PKGID:
279
0
      return "SEC_E_BAD_PKGID";
280
281
0
    case SEC_E_CONTEXT_EXPIRED:
282
0
      return "SEC_E_CONTEXT_EXPIRED";
283
284
0
    case SEC_E_INCOMPLETE_MESSAGE:
285
0
      return "SEC_E_INCOMPLETE_MESSAGE";
286
287
0
    case SEC_E_INCOMPLETE_CREDENTIALS:
288
0
      return "SEC_E_INCOMPLETE_CREDENTIALS";
289
290
0
    case SEC_E_BUFFER_TOO_SMALL:
291
0
      return "SEC_E_BUFFER_TOO_SMALL";
292
293
0
    case SEC_E_WRONG_PRINCIPAL:
294
0
      return "SEC_E_WRONG_PRINCIPAL";
295
296
0
    case SEC_E_TIME_SKEW:
297
0
      return "SEC_E_TIME_SKEW";
298
299
0
    case SEC_E_UNTRUSTED_ROOT:
300
0
      return "SEC_E_UNTRUSTED_ROOT";
301
302
0
    case SEC_E_ILLEGAL_MESSAGE:
303
0
      return "SEC_E_ILLEGAL_MESSAGE";
304
305
0
    case SEC_E_CERT_UNKNOWN:
306
0
      return "SEC_E_CERT_UNKNOWN";
307
308
0
    case SEC_E_CERT_EXPIRED:
309
0
      return "SEC_E_CERT_EXPIRED";
310
311
0
    case SEC_E_ENCRYPT_FAILURE:
312
0
      return "SEC_E_ENCRYPT_FAILURE";
313
314
0
    case SEC_E_DECRYPT_FAILURE:
315
0
      return "SEC_E_DECRYPT_FAILURE";
316
317
0
    case SEC_E_ALGORITHM_MISMATCH:
318
0
      return "SEC_E_ALGORITHM_MISMATCH";
319
320
0
    case SEC_E_SECURITY_QOS_FAILED:
321
0
      return "SEC_E_SECURITY_QOS_FAILED";
322
323
0
    case SEC_E_UNFINISHED_CONTEXT_DELETED:
324
0
      return "SEC_E_UNFINISHED_CONTEXT_DELETED";
325
326
0
    case SEC_E_NO_TGT_REPLY:
327
0
      return "SEC_E_NO_TGT_REPLY";
328
329
0
    case SEC_E_NO_IP_ADDRESSES:
330
0
      return "SEC_E_NO_IP_ADDRESSES";
331
332
0
    case SEC_E_WRONG_CREDENTIAL_HANDLE:
333
0
      return "SEC_E_WRONG_CREDENTIAL_HANDLE";
334
335
0
    case SEC_E_CRYPTO_SYSTEM_INVALID:
336
0
      return "SEC_E_CRYPTO_SYSTEM_INVALID";
337
338
0
    case SEC_E_MAX_REFERRALS_EXCEEDED:
339
0
      return "SEC_E_MAX_REFERRALS_EXCEEDED";
340
341
0
    case SEC_E_MUST_BE_KDC:
342
0
      return "SEC_E_MUST_BE_KDC";
343
344
0
    case SEC_E_STRONG_CRYPTO_NOT_SUPPORTED:
345
0
      return "SEC_E_STRONG_CRYPTO_NOT_SUPPORTED";
346
347
0
    case SEC_E_TOO_MANY_PRINCIPALS:
348
0
      return "SEC_E_TOO_MANY_PRINCIPALS";
349
350
0
    case SEC_E_NO_PA_DATA:
351
0
      return "SEC_E_NO_PA_DATA";
352
353
0
    case SEC_E_PKINIT_NAME_MISMATCH:
354
0
      return "SEC_E_PKINIT_NAME_MISMATCH";
355
356
0
    case SEC_E_SMARTCARD_LOGON_REQUIRED:
357
0
      return "SEC_E_SMARTCARD_LOGON_REQUIRED";
358
359
0
    case SEC_E_SHUTDOWN_IN_PROGRESS:
360
0
      return "SEC_E_SHUTDOWN_IN_PROGRESS";
361
362
0
    case SEC_E_KDC_INVALID_REQUEST:
363
0
      return "SEC_E_KDC_INVALID_REQUEST";
364
365
0
    case SEC_E_KDC_UNABLE_TO_REFER:
366
0
      return "SEC_E_KDC_UNABLE_TO_REFER";
367
368
0
    case SEC_E_KDC_UNKNOWN_ETYPE:
369
0
      return "SEC_E_KDC_UNKNOWN_ETYPE";
370
371
0
    case SEC_E_UNSUPPORTED_PREAUTH:
372
0
      return "SEC_E_UNSUPPORTED_PREAUTH";
373
374
0
    case SEC_E_DELEGATION_REQUIRED:
375
0
      return "SEC_E_DELEGATION_REQUIRED";
376
377
0
    case SEC_E_BAD_BINDINGS:
378
0
      return "SEC_E_BAD_BINDINGS";
379
380
0
    case SEC_E_MULTIPLE_ACCOUNTS:
381
0
      return "SEC_E_MULTIPLE_ACCOUNTS";
382
383
0
    case SEC_E_NO_KERB_KEY:
384
0
      return "SEC_E_NO_KERB_KEY";
385
386
0
    case SEC_E_CERT_WRONG_USAGE:
387
0
      return "SEC_E_CERT_WRONG_USAGE";
388
389
0
    case SEC_E_DOWNGRADE_DETECTED:
390
0
      return "SEC_E_DOWNGRADE_DETECTED";
391
392
0
    case SEC_E_SMARTCARD_CERT_REVOKED:
393
0
      return "SEC_E_SMARTCARD_CERT_REVOKED";
394
395
0
    case SEC_E_ISSUING_CA_UNTRUSTED:
396
0
      return "SEC_E_ISSUING_CA_UNTRUSTED";
397
398
0
    case SEC_E_REVOCATION_OFFLINE_C:
399
0
      return "SEC_E_REVOCATION_OFFLINE_C";
400
401
0
    case SEC_E_PKINIT_CLIENT_FAILURE:
402
0
      return "SEC_E_PKINIT_CLIENT_FAILURE";
403
404
0
    case SEC_E_SMARTCARD_CERT_EXPIRED:
405
0
      return "SEC_E_SMARTCARD_CERT_EXPIRED";
406
407
0
    case SEC_E_NO_S4U_PROT_SUPPORT:
408
0
      return "SEC_E_NO_S4U_PROT_SUPPORT";
409
410
0
    case SEC_E_CROSSREALM_DELEGATION_FAILURE:
411
0
      return "SEC_E_CROSSREALM_DELEGATION_FAILURE";
412
413
0
    case SEC_E_REVOCATION_OFFLINE_KDC:
414
0
      return "SEC_E_REVOCATION_OFFLINE_KDC";
415
416
0
    case SEC_E_ISSUING_CA_UNTRUSTED_KDC:
417
0
      return "SEC_E_ISSUING_CA_UNTRUSTED_KDC";
418
419
0
    case SEC_E_KDC_CERT_EXPIRED:
420
0
      return "SEC_E_KDC_CERT_EXPIRED";
421
422
0
    case SEC_E_KDC_CERT_REVOKED:
423
0
      return "SEC_E_KDC_CERT_REVOKED";
424
425
0
    case SEC_E_INVALID_PARAMETER:
426
0
      return "SEC_E_INVALID_PARAMETER";
427
428
0
    case SEC_E_DELEGATION_POLICY:
429
0
      return "SEC_E_DELEGATION_POLICY";
430
431
0
    case SEC_E_POLICY_NLTM_ONLY:
432
0
      return "SEC_E_POLICY_NLTM_ONLY";
433
434
0
    case SEC_E_NO_CONTEXT:
435
0
      return "SEC_E_NO_CONTEXT";
436
437
0
    case SEC_E_PKU2U_CERT_FAILURE:
438
0
      return "SEC_E_PKU2U_CERT_FAILURE";
439
440
0
    case SEC_E_MUTUAL_AUTH_FAILED:
441
0
      return "SEC_E_MUTUAL_AUTH_FAILED";
442
443
0
    case SEC_I_CONTINUE_NEEDED:
444
0
      return "SEC_I_CONTINUE_NEEDED";
445
446
0
    case SEC_I_COMPLETE_NEEDED:
447
0
      return "SEC_I_COMPLETE_NEEDED";
448
449
0
    case SEC_I_COMPLETE_AND_CONTINUE:
450
0
      return "SEC_I_COMPLETE_AND_CONTINUE";
451
452
0
    case SEC_I_LOCAL_LOGON:
453
0
      return "SEC_I_LOCAL_LOGON";
454
455
0
    case SEC_I_CONTEXT_EXPIRED:
456
0
      return "SEC_I_CONTEXT_EXPIRED";
457
458
0
    case SEC_I_INCOMPLETE_CREDENTIALS:
459
0
      return "SEC_I_INCOMPLETE_CREDENTIALS";
460
461
0
    case SEC_I_RENEGOTIATE:
462
0
      return "SEC_I_RENEGOTIATE";
463
464
0
    case SEC_I_NO_LSA_CONTEXT:
465
0
      return "SEC_I_NO_LSA_CONTEXT";
466
467
0
    case SEC_I_SIGNATURE_NEEDED:
468
0
      return "SEC_I_SIGNATURE_NEEDED";
469
470
0
    case SEC_I_NO_RENEGOTIATION:
471
0
      return "SEC_I_NO_RENEGOTIATION";
472
0
    default:
473
0
      break;
474
0
  }
475
476
0
  return NtStatus2Tag(status);
477
0
}
478
479
BOOL IsSecurityStatusError(SECURITY_STATUS status)
480
0
{
481
0
  BOOL error = TRUE;
482
483
0
  switch (status)
484
0
  {
485
0
    case SEC_E_OK:
486
0
    case SEC_I_CONTINUE_NEEDED:
487
0
    case SEC_I_COMPLETE_NEEDED:
488
0
    case SEC_I_COMPLETE_AND_CONTINUE:
489
0
    case SEC_I_LOCAL_LOGON:
490
0
    case SEC_I_CONTEXT_EXPIRED:
491
0
    case SEC_I_INCOMPLETE_CREDENTIALS:
492
0
    case SEC_I_RENEGOTIATE:
493
0
    case SEC_I_NO_LSA_CONTEXT:
494
0
    case SEC_I_SIGNATURE_NEEDED:
495
0
    case SEC_I_NO_RENEGOTIATION:
496
0
      error = FALSE;
497
0
      break;
498
0
    default:
499
0
      break;
500
0
  }
501
502
0
  return error;
503
0
}
504
505
SecurityFunctionTableW* SEC_ENTRY InitSecurityInterfaceExW(DWORD flags)
506
0
{
507
0
  if (!InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, nullptr))
508
0
    return nullptr;
509
0
  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceExW");
510
0
  return g_SspiW;
511
0
}
512
513
SecurityFunctionTableA* SEC_ENTRY InitSecurityInterfaceExA(DWORD flags)
514
0
{
515
0
  if (!InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, &flags, nullptr))
516
0
    return nullptr;
517
0
  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceExA");
518
0
  return g_SspiA;
519
0
}
520
521
/**
522
 * Standard SSPI API
523
 */
524
525
static SECURITY_STATUS sspi_init(void)
526
0
{
527
0
  if (!InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, nullptr, nullptr))
528
0
    return SEC_E_INTERNAL_ERROR;
529
530
0
  if (!g_SspiA || !g_SspiW)
531
0
  {
532
0
    WLog_Print(g_Log, WLOG_WARN, "Security module does not provide an implementation");
533
534
0
    return SEC_E_UNSUPPORTED_FUNCTION;
535
0
  }
536
0
  return SEC_E_OK;
537
0
}
538
/* Package Management */
539
540
SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesW(ULONG* pcPackages,
541
                                                          PSecPkgInfoW* ppPackageInfo)
542
0
{
543
0
  SECURITY_STATUS status = sspi_init();
544
0
  if (status != SEC_E_OK)
545
0
    return status;
546
547
0
  status = g_SspiW->EnumerateSecurityPackagesW(pcPackages, ppPackageInfo);
548
0
  WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesW: %s (0x%08" PRIX32 ")",
549
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
550
0
  return status;
551
0
}
552
553
SECURITY_STATUS SEC_ENTRY sspi_EnumerateSecurityPackagesA(ULONG* pcPackages,
554
                                                          PSecPkgInfoA* ppPackageInfo)
555
0
{
556
0
  SECURITY_STATUS status = sspi_init();
557
0
  if (status != SEC_E_OK)
558
0
    return status;
559
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->EnumerateSecurityPackagesA,
560
0
                        pcPackages, ppPackageInfo);
561
0
  WLog_Print(g_Log, WLOG_DEBUG, "EnumerateSecurityPackagesA: %s (0x%08" PRIX32 ")",
562
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
563
0
  return status;
564
0
}
565
566
SecurityFunctionTableW* SEC_ENTRY sspi_InitSecurityInterfaceW(void)
567
0
{
568
0
  if (!InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, nullptr, nullptr))
569
0
    return nullptr;
570
0
  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceW");
571
0
  return g_SspiW;
572
0
}
573
574
SecurityFunctionTableA* SEC_ENTRY sspi_InitSecurityInterfaceA(void)
575
0
{
576
0
  if (!InitOnceExecuteOnce(&g_Initialized, InitializeSspiModuleInt, nullptr, nullptr))
577
0
    return nullptr;
578
0
  WLog_Print(g_Log, WLOG_DEBUG, "InitSecurityInterfaceA");
579
0
  return g_SspiA;
580
0
}
581
582
SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName,
583
                                                         PSecPkgInfoW* ppPackageInfo)
584
0
{
585
0
  SECURITY_STATUS status = sspi_init();
586
0
  if (status != SEC_E_OK)
587
0
    return status;
588
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->QuerySecurityPackageInfoW,
589
0
                        pszPackageName, ppPackageInfo);
590
0
  WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoW: %s (0x%08" PRIX32 ")",
591
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
592
0
  return status;
593
0
}
594
595
SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName,
596
                                                         PSecPkgInfoA* ppPackageInfo)
597
0
{
598
0
  SECURITY_STATUS status = sspi_init();
599
0
  if (status != SEC_E_OK)
600
0
    return status;
601
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->QuerySecurityPackageInfoA,
602
0
                        pszPackageName, ppPackageInfo);
603
0
  WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityPackageInfoA: %s (0x%08" PRIX32 ")",
604
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
605
0
  return status;
606
0
}
607
608
/* Credential Management */
609
610
SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleW(
611
    SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
612
    void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
613
    PTimeStamp ptsExpiry)
614
0
{
615
0
  SECURITY_STATUS status = sspi_init();
616
0
  if (status != SEC_E_OK)
617
0
    return status;
618
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->AcquireCredentialsHandleW,
619
0
                        pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn,
620
0
                        pvGetKeyArgument, phCredential, ptsExpiry);
621
0
  WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleW: %s (0x%08" PRIX32 ")",
622
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
623
0
  return status;
624
0
}
625
626
SECURITY_STATUS SEC_ENTRY sspi_AcquireCredentialsHandleA(
627
    SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, ULONG fCredentialUse, void* pvLogonID,
628
    void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential,
629
    PTimeStamp ptsExpiry)
630
0
{
631
0
  SECURITY_STATUS status = sspi_init();
632
0
  if (status != SEC_E_OK)
633
0
    return status;
634
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->AcquireCredentialsHandleA,
635
0
                        pszPrincipal, pszPackage, fCredentialUse, pvLogonID, pAuthData, pGetKeyFn,
636
0
                        pvGetKeyArgument, phCredential, ptsExpiry);
637
0
  WLog_Print(g_Log, WLOG_DEBUG, "AcquireCredentialsHandleA: %s (0x%08" PRIX32 ")",
638
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
639
0
  return status;
640
0
}
641
642
SECURITY_STATUS SEC_ENTRY sspi_ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags,
643
                                                     PSecBuffer pPackedContext, HANDLE* pToken)
644
0
{
645
0
  SECURITY_STATUS status = sspi_init();
646
0
  if (status != SEC_E_OK)
647
0
    return status;
648
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->ExportSecurityContext, phContext,
649
0
                        fFlags, pPackedContext, pToken);
650
0
  WLog_Print(g_Log, WLOG_DEBUG, "ExportSecurityContext: %s (0x%08" PRIX32 ")",
651
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
652
0
  return status;
653
0
}
654
655
SECURITY_STATUS SEC_ENTRY sspi_FreeCredentialsHandle(PCredHandle phCredential)
656
0
{
657
0
  SECURITY_STATUS status = sspi_init();
658
0
  if (status != SEC_E_OK)
659
0
    return status;
660
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->FreeCredentialsHandle, phCredential);
661
0
  WLog_Print(g_Log, WLOG_DEBUG, "FreeCredentialsHandle: %s (0x%08" PRIX32 ")",
662
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
663
0
  return status;
664
0
}
665
666
SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextW(SEC_WCHAR* pszPackage,
667
                                                      PSecBuffer pPackedContext, HANDLE pToken,
668
                                                      PCtxtHandle phContext)
669
0
{
670
0
  SECURITY_STATUS status = sspi_init();
671
0
  if (status != SEC_E_OK)
672
0
    return status;
673
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->ImportSecurityContextW, pszPackage,
674
0
                        pPackedContext, pToken, phContext);
675
0
  WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextW: %s (0x%08" PRIX32 ")",
676
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
677
0
  return status;
678
0
}
679
680
SECURITY_STATUS SEC_ENTRY sspi_ImportSecurityContextA(SEC_CHAR* pszPackage,
681
                                                      PSecBuffer pPackedContext, HANDLE pToken,
682
                                                      PCtxtHandle phContext)
683
0
{
684
0
  SECURITY_STATUS status = sspi_init();
685
0
  if (status != SEC_E_OK)
686
0
    return status;
687
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->ImportSecurityContextA, pszPackage,
688
0
                        pPackedContext, pToken, phContext);
689
0
  WLog_Print(g_Log, WLOG_DEBUG, "ImportSecurityContextA: %s (0x%08" PRIX32 ")",
690
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
691
0
  return status;
692
0
}
693
694
SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesW(PCredHandle phCredential,
695
                                                           ULONG ulAttribute, void* pBuffer)
696
0
{
697
0
  SECURITY_STATUS status = sspi_init();
698
0
  if (status != SEC_E_OK)
699
0
    return status;
700
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->QueryCredentialsAttributesW,
701
0
                        phCredential, ulAttribute, pBuffer);
702
0
  WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesW: %s (0x%08" PRIX32 ")",
703
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
704
0
  return status;
705
0
}
706
707
SECURITY_STATUS SEC_ENTRY sspi_QueryCredentialsAttributesA(PCredHandle phCredential,
708
                                                           ULONG ulAttribute, void* pBuffer)
709
0
{
710
0
  SECURITY_STATUS status = sspi_init();
711
0
  if (status != SEC_E_OK)
712
0
    return status;
713
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->QueryCredentialsAttributesA,
714
0
                        phCredential, ulAttribute, pBuffer);
715
0
  WLog_Print(g_Log, WLOG_DEBUG, "QueryCredentialsAttributesA: %s (0x%08" PRIX32 ")",
716
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
717
0
  return status;
718
0
}
719
720
/* Context Management */
721
722
SECURITY_STATUS SEC_ENTRY sspi_AcceptSecurityContext(PCredHandle phCredential,
723
                                                     PCtxtHandle phContext, PSecBufferDesc pInput,
724
                                                     ULONG fContextReq, ULONG TargetDataRep,
725
                                                     PCtxtHandle phNewContext,
726
                                                     PSecBufferDesc pOutput, PULONG pfContextAttr,
727
                                                     PTimeStamp ptsTimeStamp)
728
0
{
729
0
  SECURITY_STATUS status = sspi_init();
730
0
  if (status != SEC_E_OK)
731
0
    return status;
732
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->AcceptSecurityContext, phCredential,
733
0
                        phContext, pInput, fContextReq, TargetDataRep, phNewContext, pOutput,
734
0
                        pfContextAttr, ptsTimeStamp);
735
0
  WLog_Print(g_Log, WLOG_DEBUG, "AcceptSecurityContext: %s (0x%08" PRIX32 ")",
736
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
737
0
  return status;
738
0
}
739
740
SECURITY_STATUS SEC_ENTRY sspi_ApplyControlToken(PCtxtHandle phContext, PSecBufferDesc pInput)
741
0
{
742
0
  SECURITY_STATUS status = sspi_init();
743
0
  if (status != SEC_E_OK)
744
0
    return status;
745
0
  status =
746
0
      IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->ApplyControlToken, phContext, pInput);
747
0
  WLog_Print(g_Log, WLOG_DEBUG, "ApplyControlToken: %s (0x%08" PRIX32 ")",
748
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
749
0
  return status;
750
0
}
751
752
SECURITY_STATUS SEC_ENTRY sspi_CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
753
0
{
754
0
  SECURITY_STATUS status = sspi_init();
755
0
  if (status != SEC_E_OK)
756
0
    return status;
757
0
  status =
758
0
      IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->CompleteAuthToken, phContext, pToken);
759
0
  WLog_Print(g_Log, WLOG_DEBUG, "CompleteAuthToken: %s (0x%08" PRIX32 ")",
760
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
761
0
  return status;
762
0
}
763
764
SECURITY_STATUS SEC_ENTRY sspi_DeleteSecurityContext(PCtxtHandle phContext)
765
0
{
766
0
  SECURITY_STATUS status = sspi_init();
767
0
  if (status != SEC_E_OK)
768
0
    return status;
769
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->DeleteSecurityContext, phContext);
770
0
  WLog_Print(g_Log, WLOG_DEBUG, "DeleteSecurityContext: %s (0x%08" PRIX32 ")",
771
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
772
0
  return status;
773
0
}
774
775
SECURITY_STATUS SEC_ENTRY sspi_FreeContextBuffer(void* pvContextBuffer)
776
0
{
777
0
  SECURITY_STATUS status = sspi_init();
778
0
  if (status != SEC_E_OK)
779
0
    return status;
780
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->FreeContextBuffer, pvContextBuffer);
781
0
  WLog_Print(g_Log, WLOG_DEBUG, "FreeContextBuffer: %s (0x%08" PRIX32 ")",
782
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
783
0
  return status;
784
0
}
785
786
SECURITY_STATUS SEC_ENTRY sspi_ImpersonateSecurityContext(PCtxtHandle phContext)
787
0
{
788
0
  SECURITY_STATUS status = sspi_init();
789
0
  if (status != SEC_E_OK)
790
0
    return status;
791
0
  status =
792
0
      IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->ImpersonateSecurityContext, phContext);
793
0
  WLog_Print(g_Log, WLOG_DEBUG, "ImpersonateSecurityContext: %s (0x%08" PRIX32 ")",
794
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
795
0
  return status;
796
0
}
797
798
SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextW(
799
    PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq,
800
    ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
801
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
802
0
{
803
0
  SECURITY_STATUS status = sspi_init();
804
0
  if (status != SEC_E_OK)
805
0
    return status;
806
0
  status =
807
0
      IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->InitializeSecurityContextW, phCredential,
808
0
                   phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
809
0
                   Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
810
0
  WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextW: %s (0x%08" PRIX32 ")",
811
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
812
0
  return status;
813
0
}
814
815
SECURITY_STATUS SEC_ENTRY sspi_InitializeSecurityContextA(
816
    PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, ULONG fContextReq,
817
    ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2,
818
    PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry)
819
0
{
820
0
  SECURITY_STATUS status = sspi_init();
821
0
  if (status != SEC_E_OK)
822
0
    return status;
823
0
  status =
824
0
      IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->InitializeSecurityContextA, phCredential,
825
0
                   phContext, pszTargetName, fContextReq, Reserved1, TargetDataRep, pInput,
826
0
                   Reserved2, phNewContext, pOutput, pfContextAttr, ptsExpiry);
827
0
  WLog_Print(g_Log, WLOG_DEBUG, "InitializeSecurityContextA: %s (0x%08" PRIX32 ")",
828
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
829
0
  return status;
830
0
}
831
832
SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute,
833
                                                       void* pBuffer)
834
0
{
835
0
  SECURITY_STATUS status = sspi_init();
836
0
  if (status != SEC_E_OK)
837
0
    return status;
838
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->QueryContextAttributesW, phContext,
839
0
                        ulAttribute, pBuffer);
840
0
  WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesW: %s (0x%08" PRIX32 ")",
841
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
842
0
  return status;
843
0
}
844
845
SECURITY_STATUS SEC_ENTRY sspi_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute,
846
                                                       void* pBuffer)
847
0
{
848
0
  SECURITY_STATUS status = sspi_init();
849
0
  if (status != SEC_E_OK)
850
0
    return status;
851
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->QueryContextAttributesA, phContext,
852
0
                        ulAttribute, pBuffer);
853
0
  WLog_Print(g_Log, WLOG_DEBUG, "QueryContextAttributesA: %s (0x%08" PRIX32 ")",
854
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
855
0
  return status;
856
0
}
857
858
SECURITY_STATUS SEC_ENTRY sspi_QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken)
859
0
{
860
0
  SECURITY_STATUS status = sspi_init();
861
0
  if (status != SEC_E_OK)
862
0
    return status;
863
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->QuerySecurityContextToken, phContext,
864
0
                        phToken);
865
0
  WLog_Print(g_Log, WLOG_DEBUG, "QuerySecurityContextToken: %s (0x%08" PRIX32 ")",
866
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
867
0
  return status;
868
0
}
869
870
SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute,
871
                                                     void* pBuffer, ULONG cbBuffer)
872
0
{
873
0
  SECURITY_STATUS status = sspi_init();
874
0
  if (status != SEC_E_OK)
875
0
    return status;
876
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->SetContextAttributesW, phContext,
877
0
                        ulAttribute, pBuffer, cbBuffer);
878
0
  WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesW: %s (0x%08" PRIX32 ")",
879
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
880
0
  return status;
881
0
}
882
883
SECURITY_STATUS SEC_ENTRY sspi_SetContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute,
884
                                                     void* pBuffer, ULONG cbBuffer)
885
0
{
886
0
  SECURITY_STATUS status = sspi_init();
887
0
  if (status != SEC_E_OK)
888
0
    return status;
889
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiA->SetContextAttributesA, phContext,
890
0
                        ulAttribute, pBuffer, cbBuffer);
891
0
  WLog_Print(g_Log, WLOG_DEBUG, "SetContextAttributesA: %s (0x%08" PRIX32 ")",
892
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
893
0
  return status;
894
0
}
895
896
SECURITY_STATUS SEC_ENTRY sspi_RevertSecurityContext(PCtxtHandle phContext)
897
0
{
898
0
  SECURITY_STATUS status = sspi_init();
899
0
  if (status != SEC_E_OK)
900
0
    return status;
901
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->RevertSecurityContext, phContext);
902
0
  WLog_Print(g_Log, WLOG_DEBUG, "RevertSecurityContext: %s (0x%08" PRIX32 ")",
903
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
904
0
  return status;
905
0
}
906
907
/* Message Support */
908
909
SECURITY_STATUS SEC_ENTRY sspi_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage,
910
                                              ULONG MessageSeqNo, PULONG pfQOP)
911
0
{
912
0
  SECURITY_STATUS status = sspi_init();
913
0
  if (status != SEC_E_OK)
914
0
    return status;
915
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->DecryptMessage, phContext, pMessage,
916
0
                        MessageSeqNo, pfQOP);
917
0
  WLog_Print(g_Log, WLOG_DEBUG, "DecryptMessage: %s (0x%08" PRIX32 ")",
918
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
919
0
  return status;
920
0
}
921
922
SECURITY_STATUS SEC_ENTRY sspi_EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
923
                                              PSecBufferDesc pMessage, ULONG MessageSeqNo)
924
0
{
925
0
  SECURITY_STATUS status = sspi_init();
926
0
  if (status != SEC_E_OK)
927
0
    return status;
928
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->EncryptMessage, phContext, fQOP,
929
0
                        pMessage, MessageSeqNo);
930
0
  WLog_Print(g_Log, WLOG_DEBUG, "EncryptMessage: %s (0x%08" PRIX32 ")",
931
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
932
0
  return status;
933
0
}
934
935
SECURITY_STATUS SEC_ENTRY sspi_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
936
                                             PSecBufferDesc pMessage, ULONG MessageSeqNo)
937
0
{
938
0
  SECURITY_STATUS status = sspi_init();
939
0
  if (status != SEC_E_OK)
940
0
    return status;
941
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->MakeSignature, phContext, fQOP,
942
0
                        pMessage, MessageSeqNo);
943
0
  WLog_Print(g_Log, WLOG_DEBUG, "MakeSignature: %s (0x%08" PRIX32 ")",
944
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
945
0
  return status;
946
0
}
947
948
SECURITY_STATUS SEC_ENTRY sspi_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage,
949
                                               ULONG MessageSeqNo, PULONG pfQOP)
950
0
{
951
0
  SECURITY_STATUS status = sspi_init();
952
0
  if (status != SEC_E_OK)
953
0
    return status;
954
0
  status = IFCALLRESULT(SEC_E_UNSUPPORTED_FUNCTION, g_SspiW->VerifySignature, phContext, pMessage,
955
0
                        MessageSeqNo, pfQOP);
956
0
  WLog_Print(g_Log, WLOG_DEBUG, "VerifySignature: %s (0x%08" PRIX32 ")",
957
0
             GetSecurityStatusString(status), WINPR_CXX_COMPAT_CAST(UINT32, status));
958
0
  return status;
959
0
}
960
961
WINPR_PRAGMA_DIAG_POP
962
963
static void zfree(WCHAR* str, size_t len, BOOL isWCHAR)
964
0
{
965
0
  if (str)
966
0
    memset(str, 0, len * (isWCHAR ? sizeof(WCHAR) : sizeof(char)));
967
0
  free(str);
968
0
}
969
970
void sspi_FreeAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity)
971
0
{
972
0
  if (!identity)
973
0
    return;
974
975
0
  const BOOL wc = (identity->Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE) != 0;
976
0
  zfree(identity->User, identity->UserLength, wc);
977
0
  zfree(identity->Domain, identity->DomainLength, wc);
978
979
  /* identity->PasswordLength does have a dual use. In Pass The Hash (PTH) mode the maximum
980
   * password length (512) is added to the real length to mark this as a hash. when we free up
981
   * this field without removing these additional bytes we would corrupt the stack.
982
   */
983
0
  size_t len = identity->PasswordLength;
984
0
  if (len > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET)
985
0
    len -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
986
0
  zfree(identity->Password, len, wc);
987
988
0
  const SEC_WINNT_AUTH_IDENTITY empty = WINPR_C_ARRAY_INIT;
989
0
  *identity = empty;
990
0
}