Coverage Report

Created: 2026-04-12 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/winpr/libwinpr/sspi/CredSSP/credssp.c
Line
Count
Source
1
/**
2
 * WinPR: Windows Portable Runtime
3
 * Credential Security Support Provider (CredSSP)
4
 *
5
 * Copyright 2010-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/config.h>
21
22
#include <winpr/crt.h>
23
#include <winpr/sspi.h>
24
25
#include "credssp.h"
26
27
#include "../sspi.h"
28
#include "../../log.h"
29
30
#define TAG WINPR_TAG("sspi.CredSSP")
31
32
static const char* CREDSSP_PACKAGE_NAME = "CredSSP";
33
34
static SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextW(
35
    WINPR_ATTR_UNUSED PCredHandle phCredential, WINPR_ATTR_UNUSED PCtxtHandle phContext,
36
    WINPR_ATTR_UNUSED SEC_WCHAR* pszTargetName, WINPR_ATTR_UNUSED ULONG fContextReq,
37
    WINPR_ATTR_UNUSED ULONG Reserved1, WINPR_ATTR_UNUSED ULONG TargetDataRep,
38
    WINPR_ATTR_UNUSED PSecBufferDesc pInput, WINPR_ATTR_UNUSED ULONG Reserved2,
39
    WINPR_ATTR_UNUSED PCtxtHandle phNewContext, WINPR_ATTR_UNUSED PSecBufferDesc pOutput,
40
    WINPR_ATTR_UNUSED PULONG pfContextAttr, WINPR_ATTR_UNUSED PTimeStamp ptsExpiry)
41
0
{
42
0
  WLog_ERR(TAG, "TODO: Implement");
43
0
  return SEC_E_UNSUPPORTED_FUNCTION;
44
0
}
45
46
static SECURITY_STATUS SEC_ENTRY credssp_InitializeSecurityContextA(
47
    PCredHandle phCredential, PCtxtHandle phContext, WINPR_ATTR_UNUSED SEC_CHAR* pszTargetName,
48
    WINPR_ATTR_UNUSED ULONG fContextReq, WINPR_ATTR_UNUSED ULONG Reserved1,
49
    WINPR_ATTR_UNUSED ULONG TargetDataRep, WINPR_ATTR_UNUSED PSecBufferDesc pInput,
50
    WINPR_ATTR_UNUSED ULONG Reserved2, PCtxtHandle phNewContext,
51
    WINPR_ATTR_UNUSED PSecBufferDesc pOutput, WINPR_ATTR_UNUSED PULONG pfContextAttr,
52
    WINPR_ATTR_UNUSED PTimeStamp ptsExpiry)
53
0
{
54
0
  CREDSSP_CONTEXT* context = nullptr;
55
0
  SSPI_CREDENTIALS* credentials = nullptr;
56
57
  /* behave like windows SSPIs that don't want empty context */
58
0
  if (phContext && !phContext->dwLower && !phContext->dwUpper)
59
0
    return SEC_E_INVALID_HANDLE;
60
61
0
  context = (CREDSSP_CONTEXT*)sspi_SecureHandleGetLowerPointer(phContext);
62
63
0
  if (!context)
64
0
  {
65
0
    union
66
0
    {
67
0
      const void* cpv;
68
0
      void* pv;
69
0
    } cnv;
70
0
    context = credssp_ContextNew();
71
72
0
    if (!context)
73
0
      return SEC_E_INSUFFICIENT_MEMORY;
74
75
0
    credentials = (SSPI_CREDENTIALS*)sspi_SecureHandleGetLowerPointer(phCredential);
76
77
0
    if (!credentials)
78
0
    {
79
0
      credssp_ContextFree(context);
80
0
      return SEC_E_INVALID_HANDLE;
81
0
    }
82
83
0
    sspi_SecureHandleSetLowerPointer(phNewContext, context);
84
85
0
    cnv.cpv = CREDSSP_PACKAGE_NAME;
86
0
    sspi_SecureHandleSetUpperPointer(phNewContext, cnv.pv);
87
0
  }
88
89
0
  return SEC_E_OK;
90
0
}
91
92
CREDSSP_CONTEXT* credssp_ContextNew(void)
93
0
{
94
0
  CREDSSP_CONTEXT* context = nullptr;
95
0
  context = (CREDSSP_CONTEXT*)calloc(1, sizeof(CREDSSP_CONTEXT));
96
97
0
  if (!context)
98
0
    return nullptr;
99
100
0
  return context;
101
0
}
102
103
void credssp_ContextFree(CREDSSP_CONTEXT* context)
104
0
{
105
0
  free(context);
106
0
}
107
108
static SECURITY_STATUS SEC_ENTRY credssp_QueryContextAttributes(PCtxtHandle phContext,
109
                                                                WINPR_ATTR_UNUSED ULONG ulAttribute,
110
                                                                void* pBuffer)
111
0
{
112
0
  if (!phContext)
113
0
    return SEC_E_INVALID_HANDLE;
114
115
0
  if (!pBuffer)
116
0
    return SEC_E_INSUFFICIENT_MEMORY;
117
118
0
  WLog_ERR(TAG, "TODO: Implement");
119
0
  return SEC_E_UNSUPPORTED_FUNCTION;
120
0
}
121
122
static SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleW(
123
    WINPR_ATTR_UNUSED SEC_WCHAR* pszPrincipal, WINPR_ATTR_UNUSED SEC_WCHAR* pszPackage,
124
    WINPR_ATTR_UNUSED ULONG fCredentialUse, WINPR_ATTR_UNUSED void* pvLogonID,
125
    WINPR_ATTR_UNUSED void* pAuthData, WINPR_ATTR_UNUSED SEC_GET_KEY_FN pGetKeyFn,
126
    WINPR_ATTR_UNUSED void* pvGetKeyArgument, WINPR_ATTR_UNUSED PCredHandle phCredential,
127
    WINPR_ATTR_UNUSED PTimeStamp ptsExpiry)
128
0
{
129
0
  WLog_ERR(TAG, "TODO: Implement");
130
0
  return SEC_E_UNSUPPORTED_FUNCTION;
131
0
}
132
133
static SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleA(
134
    WINPR_ATTR_UNUSED SEC_CHAR* pszPrincipal, WINPR_ATTR_UNUSED SEC_CHAR* pszPackage,
135
    WINPR_ATTR_UNUSED ULONG fCredentialUse, WINPR_ATTR_UNUSED void* pvLogonID,
136
    WINPR_ATTR_UNUSED void* pAuthData, WINPR_ATTR_UNUSED SEC_GET_KEY_FN pGetKeyFn,
137
    WINPR_ATTR_UNUSED void* pvGetKeyArgument, WINPR_ATTR_UNUSED PCredHandle phCredential,
138
    WINPR_ATTR_UNUSED PTimeStamp ptsExpiry)
139
0
{
140
0
  SSPI_CREDENTIALS* credentials = nullptr;
141
0
  SEC_WINNT_AUTH_IDENTITY* identity = nullptr;
142
143
0
  if (fCredentialUse == SECPKG_CRED_OUTBOUND)
144
0
  {
145
0
    union
146
0
    {
147
0
      const void* cpv;
148
0
      void* pv;
149
0
    } cnv;
150
0
    credentials = sspi_CredentialsNew();
151
152
0
    if (!credentials)
153
0
      return SEC_E_INSUFFICIENT_MEMORY;
154
155
0
    identity = (SEC_WINNT_AUTH_IDENTITY*)pAuthData;
156
0
    CopyMemory(&(credentials->identity), identity, sizeof(SEC_WINNT_AUTH_IDENTITY));
157
0
    sspi_SecureHandleSetLowerPointer(phCredential, (void*)credentials);
158
159
0
    cnv.cpv = CREDSSP_PACKAGE_NAME;
160
0
    sspi_SecureHandleSetUpperPointer(phCredential, cnv.pv);
161
0
    return SEC_E_OK;
162
0
  }
163
164
0
  WLog_ERR(TAG, "TODO: Implement");
165
0
  return SEC_E_UNSUPPORTED_FUNCTION;
166
0
}
167
168
static SECURITY_STATUS SEC_ENTRY credssp_QueryCredentialsAttributesW(
169
    WINPR_ATTR_UNUSED PCredHandle phCredential, WINPR_ATTR_UNUSED ULONG ulAttribute,
170
    WINPR_ATTR_UNUSED void* pBuffer)
171
0
{
172
0
  WLog_ERR(TAG, "TODO: Implement");
173
0
  return SEC_E_UNSUPPORTED_FUNCTION;
174
0
}
175
176
static SECURITY_STATUS SEC_ENTRY credssp_QueryCredentialsAttributesA(
177
    WINPR_ATTR_UNUSED PCredHandle phCredential, WINPR_ATTR_UNUSED ULONG ulAttribute,
178
    WINPR_ATTR_UNUSED void* pBuffer)
179
0
{
180
0
  if (ulAttribute == SECPKG_CRED_ATTR_NAMES)
181
0
  {
182
0
    SSPI_CREDENTIALS* credentials =
183
0
        (SSPI_CREDENTIALS*)sspi_SecureHandleGetLowerPointer(phCredential);
184
185
0
    if (!credentials)
186
0
      return SEC_E_INVALID_HANDLE;
187
188
0
    return SEC_E_OK;
189
0
  }
190
191
0
  WLog_ERR(TAG, "TODO: Implement");
192
0
  return SEC_E_UNSUPPORTED_FUNCTION;
193
0
}
194
195
static SECURITY_STATUS SEC_ENTRY credssp_FreeCredentialsHandle(PCredHandle phCredential)
196
0
{
197
0
  if (!phCredential)
198
0
    return SEC_E_INVALID_HANDLE;
199
200
0
  SSPI_CREDENTIALS* credentials =
201
0
      (SSPI_CREDENTIALS*)sspi_SecureHandleGetLowerPointer(phCredential);
202
0
  sspi_SecureHandleInvalidate(phCredential);
203
0
  if (!credentials)
204
0
    return SEC_E_INVALID_HANDLE;
205
206
0
  sspi_CredentialsFree(credentials);
207
0
  return SEC_E_OK;
208
0
}
209
210
static SECURITY_STATUS SEC_ENTRY credssp_EncryptMessage(WINPR_ATTR_UNUSED PCtxtHandle phContext,
211
                                                        WINPR_ATTR_UNUSED ULONG fQOP,
212
                                                        WINPR_ATTR_UNUSED PSecBufferDesc pMessage,
213
                                                        WINPR_ATTR_UNUSED ULONG MessageSeqNo)
214
0
{
215
0
  WLog_ERR(TAG, "TODO: Implement");
216
0
  return SEC_E_UNSUPPORTED_FUNCTION;
217
0
}
218
219
static SECURITY_STATUS SEC_ENTRY credssp_DecryptMessage(WINPR_ATTR_UNUSED PCtxtHandle phContext,
220
                                                        WINPR_ATTR_UNUSED PSecBufferDesc pMessage,
221
                                                        WINPR_ATTR_UNUSED ULONG MessageSeqNo,
222
                                                        WINPR_ATTR_UNUSED ULONG* pfQOP)
223
0
{
224
0
  WLog_ERR(TAG, "TODO: Implement");
225
0
  return SEC_E_UNSUPPORTED_FUNCTION;
226
0
}
227
228
static SECURITY_STATUS SEC_ENTRY credssp_MakeSignature(WINPR_ATTR_UNUSED PCtxtHandle phContext,
229
                                                       WINPR_ATTR_UNUSED ULONG fQOP,
230
                                                       WINPR_ATTR_UNUSED PSecBufferDesc pMessage,
231
                                                       WINPR_ATTR_UNUSED ULONG MessageSeqNo)
232
0
{
233
0
  WLog_ERR(TAG, "TODO: Implement");
234
0
  return SEC_E_UNSUPPORTED_FUNCTION;
235
0
}
236
237
static SECURITY_STATUS SEC_ENTRY credssp_VerifySignature(WINPR_ATTR_UNUSED PCtxtHandle phContext,
238
                                                         WINPR_ATTR_UNUSED PSecBufferDesc pMessage,
239
                                                         WINPR_ATTR_UNUSED ULONG MessageSeqNo,
240
                                                         WINPR_ATTR_UNUSED ULONG* pfQOP)
241
0
{
242
0
  WLog_ERR(TAG, "TODO: Implement");
243
0
  return SEC_E_UNSUPPORTED_FUNCTION;
244
0
}
245
246
const SecurityFunctionTableA CREDSSP_SecurityFunctionTableA = {
247
  3,                                   /* dwVersion */
248
  nullptr,                             /* EnumerateSecurityPackages */
249
  credssp_QueryCredentialsAttributesA, /* QueryCredentialsAttributes */
250
  credssp_AcquireCredentialsHandleA,   /* AcquireCredentialsHandle */
251
  credssp_FreeCredentialsHandle,       /* FreeCredentialsHandle */
252
  nullptr,                             /* Reserved2 */
253
  credssp_InitializeSecurityContextA,  /* InitializeSecurityContext */
254
  nullptr,                             /* AcceptSecurityContext */
255
  nullptr,                             /* CompleteAuthToken */
256
  nullptr,                             /* DeleteSecurityContext */
257
  nullptr,                             /* ApplyControlToken */
258
  credssp_QueryContextAttributes,      /* QueryContextAttributes */
259
  nullptr,                             /* ImpersonateSecurityContext */
260
  nullptr,                             /* RevertSecurityContext */
261
  credssp_MakeSignature,               /* MakeSignature */
262
  credssp_VerifySignature,             /* VerifySignature */
263
  nullptr,                             /* FreeContextBuffer */
264
  nullptr,                             /* QuerySecurityPackageInfo */
265
  nullptr,                             /* Reserved3 */
266
  nullptr,                             /* Reserved4 */
267
  nullptr,                             /* ExportSecurityContext */
268
  nullptr,                             /* ImportSecurityContext */
269
  nullptr,                             /* AddCredentials */
270
  nullptr,                             /* Reserved8 */
271
  nullptr,                             /* QuerySecurityContextToken */
272
  credssp_EncryptMessage,              /* EncryptMessage */
273
  credssp_DecryptMessage,              /* DecryptMessage */
274
  nullptr,                             /* SetContextAttributes */
275
  nullptr,                             /* SetCredentialsAttributes */
276
};
277
278
const SecurityFunctionTableW CREDSSP_SecurityFunctionTableW = {
279
  3,                                   /* dwVersion */
280
  nullptr,                             /* EnumerateSecurityPackages */
281
  credssp_QueryCredentialsAttributesW, /* QueryCredentialsAttributes */
282
  credssp_AcquireCredentialsHandleW,   /* AcquireCredentialsHandle */
283
  credssp_FreeCredentialsHandle,       /* FreeCredentialsHandle */
284
  nullptr,                             /* Reserved2 */
285
  credssp_InitializeSecurityContextW,  /* InitializeSecurityContext */
286
  nullptr,                             /* AcceptSecurityContext */
287
  nullptr,                             /* CompleteAuthToken */
288
  nullptr,                             /* DeleteSecurityContext */
289
  nullptr,                             /* ApplyControlToken */
290
  credssp_QueryContextAttributes,      /* QueryContextAttributes */
291
  nullptr,                             /* ImpersonateSecurityContext */
292
  nullptr,                             /* RevertSecurityContext */
293
  credssp_MakeSignature,               /* MakeSignature */
294
  credssp_VerifySignature,             /* VerifySignature */
295
  nullptr,                             /* FreeContextBuffer */
296
  nullptr,                             /* QuerySecurityPackageInfo */
297
  nullptr,                             /* Reserved3 */
298
  nullptr,                             /* Reserved4 */
299
  nullptr,                             /* ExportSecurityContext */
300
  nullptr,                             /* ImportSecurityContext */
301
  nullptr,                             /* AddCredentials */
302
  nullptr,                             /* Reserved8 */
303
  nullptr,                             /* QuerySecurityContextToken */
304
  credssp_EncryptMessage,              /* EncryptMessage */
305
  credssp_DecryptMessage,              /* DecryptMessage */
306
  nullptr,                             /* SetContextAttributes */
307
  nullptr,                             /* SetCredentialsAttributes */
308
};
309
310
const SecPkgInfoA CREDSSP_SecPkgInfoA = {
311
  0x000110733,                          /* fCapabilities */
312
  1,                                    /* wVersion */
313
  0xFFFF,                               /* wRPCID */
314
  0x000090A8,                           /* cbMaxToken */
315
  "CREDSSP",                            /* Name */
316
  "Microsoft CredSSP Security Provider" /* Comment */
317
};
318
319
static WCHAR CREDSSP_SecPkgInfoW_NameBuffer[128] = WINPR_C_ARRAY_INIT;
320
static WCHAR CREDSSP_SecPkgInfoW_CommentBuffer[128] = WINPR_C_ARRAY_INIT;
321
322
const SecPkgInfoW CREDSSP_SecPkgInfoW = {
323
  0x000110733,                      /* fCapabilities */
324
  1,                                /* wVersion */
325
  0xFFFF,                           /* wRPCID */
326
  0x000090A8,                       /* cbMaxToken */
327
  CREDSSP_SecPkgInfoW_NameBuffer,   /* Name */
328
  CREDSSP_SecPkgInfoW_CommentBuffer /* Comment */
329
};
330
331
BOOL CREDSSP_init(void)
332
0
{
333
0
  InitializeConstWCharFromUtf8(CREDSSP_SecPkgInfoA.Name, CREDSSP_SecPkgInfoW_NameBuffer,
334
0
                               ARRAYSIZE(CREDSSP_SecPkgInfoW_NameBuffer));
335
0
  InitializeConstWCharFromUtf8(CREDSSP_SecPkgInfoA.Comment, CREDSSP_SecPkgInfoW_CommentBuffer,
336
0
                               ARRAYSIZE(CREDSSP_SecPkgInfoW_CommentBuffer));
337
0
  return TRUE;
338
0
}