Coverage Report

Created: 2025-07-01 06:46

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