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