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