]> git.ipfire.org Git - thirdparty/squid.git/blame - lib/sspwin32.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / lib / sspwin32.cc
CommitLineData
0545caaa 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
0545caaa
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
1b52df9a 8
f7f3304a 9#include "squid.h"
d6054896
AJ
10#include "base64.h"
11#include "ntlmauth/ntlmauth.h"
6e785d85 12#include "sspwin32.h"
d6054896 13#include "util.h"
6e785d85 14
15typedef struct _AUTH_SEQ {
16 BOOL fInitialized;
17 BOOL fHaveCredHandle;
18 BOOL fHaveCtxtHandle;
19 CredHandle hcred;
20 TimeStamp hcredLifeTime;
21 struct _SecHandle hctxt;
22 TimeStamp hctxtLifeTime;
23} AUTH_SEQ, *PAUTH_SEQ;
24
25BOOL GenClientContext(PAUTH_SEQ, PSEC_WINNT_AUTH_IDENTITY, PVOID, DWORD, PVOID, PDWORD, PBOOL);
26BOOL GenServerContext(PAUTH_SEQ, PVOID, DWORD, PVOID, PDWORD, PBOOL, char *);
27
28static HMODULE hModule;
29static int NTLM_mode = SSP_BASIC;
30static char * SSP_Package_InUse;
31SECURITY_STATUS SecurityStatus = SEC_E_OK;
32
33static DWORD cbMaxToken = 0;
ee244464
FC
34static uint8_t * pClientBuf = NULL;
35static uint8_t * pServerBuf = NULL;
6e785d85 36
37static AUTH_SEQ NTLM_asServer = {0};
38
39BOOL Use_Unicode = FALSE;
40BOOL NTLM_LocalCall = FALSE;
41
42/* Function pointers */
43ACCEPT_SECURITY_CONTEXT_FN _AcceptSecurityContext = NULL;
44ACQUIRE_CREDENTIALS_HANDLE_FN _AcquireCredentialsHandle = NULL;
45COMPLETE_AUTH_TOKEN_FN _CompleteAuthToken = NULL;
46DELETE_SECURITY_CONTEXT_FN _DeleteSecurityContext = NULL;
47FREE_CONTEXT_BUFFER_FN _FreeContextBuffer = NULL;
48FREE_CREDENTIALS_HANDLE_FN _FreeCredentialsHandle = NULL;
49INITIALIZE_SECURITY_CONTEXT_FN _InitializeSecurityContext = NULL;
50QUERY_SECURITY_PACKAGE_INFO_FN _QuerySecurityPackageInfo = NULL;
51#ifdef UNICODE
52QUERY_CONTEXT_ATTRIBUTES_FN_W _QueryContextAttributes = NULL;
53#else
54QUERY_CONTEXT_ATTRIBUTES_FN_A _QueryContextAttributes = NULL;
55#endif
56
57void UnloadSecurityDll(void)
58{
59 if (NTLM_asServer.fHaveCtxtHandle)
26ac0430 60 _DeleteSecurityContext(&NTLM_asServer.hctxt);
6e785d85 61 if (NTLM_asServer.fHaveCredHandle)
62 _FreeCredentialsHandle(&NTLM_asServer.hcred);
63
64 if (hModule)
26ac0430 65 FreeLibrary(hModule);
6e785d85 66
67 xfree(SSP_Package_InUse);
68 xfree(pClientBuf);
69 xfree(pServerBuf);
70
71 _AcceptSecurityContext = NULL;
72 _AcquireCredentialsHandle = NULL;
73 _CompleteAuthToken = NULL;
74 _DeleteSecurityContext = NULL;
75 _FreeContextBuffer = NULL;
76 _FreeCredentialsHandle = NULL;
77 _InitializeSecurityContext = NULL;
78 _QuerySecurityPackageInfo = NULL;
79 _QueryContextAttributes = NULL;
80
81 hModule = NULL;
82}
83
d6054896 84HMODULE LoadSecurityDll(int mode, const char * SSP_Package)
6e785d85 85{
86 TCHAR lpszDLL[MAX_PATH];
87 OSVERSIONINFO VerInfo;
88 PSecPkgInfo pSPI = NULL;
89
26ac0430
AJ
90 /*
91 * Find out which security DLL to use, depending on
92 * whether we are on NT or 2000 or XP or 2003 Server
93 * We have to use security.dll on Windows NT 4.0.
94 * All other operating systems, we have to use Secur32.dll
95 */
6e785d85 96 hModule = NULL;
97 if ((mode != SSP_BASIC) && (mode != SSP_NTLM))
26ac0430 98 return hModule;
6e785d85 99 NTLM_mode = mode;
100 VerInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
101 if (!GetVersionEx (&VerInfo)) { /* If this fails, something has gone wrong */
26ac0430 102 return hModule;
6e785d85 103 }
104 if (VerInfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
26ac0430
AJ
105 VerInfo.dwMajorVersion == 4 &&
106 VerInfo.dwMinorVersion == 0) {
107 lstrcpy (lpszDLL, _T(WINNT_SECURITY_DLL));
6e785d85 108 } else {
26ac0430 109 lstrcpy (lpszDLL, _T(WIN2K_SECURITY_DLL));
6e785d85 110 }
111 hModule = LoadLibrary(lpszDLL);
112 if (!hModule)
26ac0430
AJ
113 return hModule;
114 _AcceptSecurityContext = (ACCEPT_SECURITY_CONTEXT_FN)
115 GetProcAddress(hModule, "AcceptSecurityContext");
6e785d85 116 if (!_AcceptSecurityContext) {
26ac0430
AJ
117 UnloadSecurityDll();
118 hModule = NULL;
119 return hModule;
6e785d85 120 }
121#ifdef UNICODE
122 _AcquireCredentialsHandle = (ACQUIRE_CREDENTIALS_HANDLE_FN)
26ac0430 123 GetProcAddress(hModule, "AcquireCredentialsHandleW");
6e785d85 124#else
125 _AcquireCredentialsHandle = (ACQUIRE_CREDENTIALS_HANDLE_FN)
26ac0430 126 GetProcAddress(hModule, "AcquireCredentialsHandleA");
6e785d85 127#endif
128 if (!_AcquireCredentialsHandle) {
26ac0430
AJ
129 UnloadSecurityDll();
130 hModule = NULL;
131 return hModule;
6e785d85 132 }
26ac0430
AJ
133 _CompleteAuthToken = (COMPLETE_AUTH_TOKEN_FN)
134 GetProcAddress(hModule, "CompleteAuthToken");
6e785d85 135 if (!_CompleteAuthToken) {
26ac0430
AJ
136 UnloadSecurityDll();
137 hModule = NULL;
138 return hModule;
6e785d85 139 }
26ac0430
AJ
140 _DeleteSecurityContext = (DELETE_SECURITY_CONTEXT_FN)
141 GetProcAddress(hModule, "DeleteSecurityContext");
6e785d85 142 if (!_DeleteSecurityContext) {
26ac0430
AJ
143 UnloadSecurityDll();
144 hModule = NULL;
145 return hModule;
6e785d85 146 }
26ac0430
AJ
147 _FreeContextBuffer = (FREE_CONTEXT_BUFFER_FN)
148 GetProcAddress(hModule, "FreeContextBuffer");
6e785d85 149 if (!_FreeContextBuffer) {
26ac0430
AJ
150 UnloadSecurityDll();
151 hModule = NULL;
152 return hModule;
6e785d85 153 }
26ac0430
AJ
154 _FreeCredentialsHandle = (FREE_CREDENTIALS_HANDLE_FN)
155 GetProcAddress(hModule, "FreeCredentialsHandle");
6e785d85 156 if (!_FreeCredentialsHandle) {
26ac0430
AJ
157 UnloadSecurityDll();
158 hModule = NULL;
159 return hModule;
6e785d85 160 }
161#ifdef UNICODE
162 _InitializeSecurityContext = (INITIALIZE_SECURITY_CONTEXT_FN)
26ac0430 163 GetProcAddress(hModule, "InitializeSecurityContextW");
6e785d85 164#else
26ac0430
AJ
165 _InitializeSecurityContext = (INITIALIZE_SECURITY_CONTEXT_FN)
166 GetProcAddress(hModule, "InitializeSecurityContextA");
6e785d85 167#endif
168 if (!_InitializeSecurityContext) {
26ac0430
AJ
169 UnloadSecurityDll();
170 hModule = NULL;
171 return hModule;
6e785d85 172 }
173#ifdef UNICODE
26ac0430
AJ
174 _QuerySecurityPackageInfo = (QUERY_SECURITY_PACKAGE_INFO_FN)
175 GetProcAddress(hModule, "QuerySecurityPackageInfoW");
6e785d85 176#else
177 _QuerySecurityPackageInfo = (QUERY_SECURITY_PACKAGE_INFO_FN)
26ac0430 178 GetProcAddress(hModule, "QuerySecurityPackageInfoA");
6e785d85 179#endif
180 if (!_QuerySecurityPackageInfo) {
26ac0430
AJ
181 UnloadSecurityDll();
182 hModule = NULL;
6e785d85 183 }
184
185#ifdef UNICODE
26ac0430
AJ
186 _QueryContextAttributes = (QUERY_CONTEXT_ATTRIBUTES_FN_W)
187 GetProcAddress(hModule, "QueryContextAttributesW");
6e785d85 188#else
189 _QueryContextAttributes = (QUERY_CONTEXT_ATTRIBUTES_FN_A)
26ac0430 190 GetProcAddress(hModule, "QueryContextAttributesA");
6e785d85 191#endif
192 if (!_QueryContextAttributes) {
26ac0430
AJ
193 UnloadSecurityDll();
194 hModule = NULL;
6e785d85 195 }
196
197 /* Get max token size */
198 _QuerySecurityPackageInfo((SEC_CHAR*)_T(SSP_Package), &pSPI);
199 cbMaxToken = pSPI->cbMaxToken;
200 _FreeContextBuffer(pSPI);
201
202 /* Allocate buffers for client and server messages */
ee244464
FC
203 pClientBuf = static_cast<uint8_t *>(xcalloc(cbMaxToken, sizeof(char)));
204 pServerBuf = static_cast<uint8_t *>(xcalloc(cbMaxToken, sizeof(char)));
6e785d85 205 SSP_Package_InUse = xstrdup(SSP_Package);
206
207 return hModule;
208}
209
6e785d85 210BOOL GenClientContext(PAUTH_SEQ pAS, PSEC_WINNT_AUTH_IDENTITY pAuthIdentity,
26ac0430 211 PVOID pIn, DWORD cbIn, PVOID pOut, PDWORD pcbOut, PBOOL pfDone)
6e785d85 212{
26ac0430
AJ
213 /*
214 * Routine Description:
215 *
216 * Optionally takes an input buffer coming from the server and returns
217 * a buffer of information to send back to the server. Also returns
218 * an indication of whether or not the context is complete.
219 *
220 * Return Value:
221 * Returns TRUE if successful; otherwise FALSE.
222 */
6e785d85 223 TimeStamp tsExpiry;
224 SecBufferDesc sbdOut;
225 SecBuffer sbOut;
226 SecBufferDesc sbdIn;
227 SecBuffer sbIn;
228 ULONG fContextAttr;
229
230 if (!pAS->fInitialized) {
26ac0430
AJ
231 SecurityStatus = _AcquireCredentialsHandle(NULL, (SEC_CHAR*) _T(SSP_Package_InUse),
232 SECPKG_CRED_OUTBOUND, NULL, (NTLM_mode == SSP_NTLM) ? NULL : pAuthIdentity, NULL, NULL,
233 &pAS->hcred, &tsExpiry);
234 if (SecurityStatus < 0)
235 return FALSE;
236 pAS->fHaveCredHandle = TRUE;
6e785d85 237 }
26ac0430 238
6e785d85 239 /* Prepare output buffer */
240 sbdOut.ulVersion = 0;
241 sbdOut.cBuffers = 1;
242 sbdOut.pBuffers = &sbOut;
243 sbOut.cbBuffer = *pcbOut;
244 sbOut.BufferType = SECBUFFER_TOKEN;
245 sbOut.pvBuffer = pOut;
26ac0430 246
6e785d85 247 /* Prepare input buffer */
248 if (pAS->fInitialized) {
26ac0430
AJ
249 sbdIn.ulVersion = 0;
250 sbdIn.cBuffers = 1;
251 sbdIn.pBuffers = &sbIn;
252 sbIn.cbBuffer = cbIn;
253 sbIn.BufferType = SECBUFFER_TOKEN;
254 sbIn.pvBuffer = pIn;
6e785d85 255 }
26ac0430
AJ
256 SecurityStatus = _InitializeSecurityContext(&pAS->hcred,
257 pAS->fInitialized ? &pAS->hctxt : NULL, NULL, 0, 0,
258 SECURITY_NATIVE_DREP, pAS->fInitialized ? &sbdIn : NULL,
259 0, &pAS->hctxt, &sbdOut, &fContextAttr, &tsExpiry);
260 if (SecurityStatus < 0)
261 return FALSE;
6e785d85 262 pAS->fHaveCtxtHandle = TRUE;
26ac0430 263
6e785d85 264 /* If necessary, complete token */
265 if (SecurityStatus == SEC_I_COMPLETE_NEEDED || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE) {
26ac0430
AJ
266 SecurityStatus = _CompleteAuthToken(&pAS->hctxt, &sbdOut);
267 if (SecurityStatus < 0)
268 return FALSE;
6e785d85 269 }
270 *pcbOut = sbOut.cbBuffer;
271 if (!pAS->fInitialized)
26ac0430
AJ
272 pAS->fInitialized = TRUE;
273 *pfDone = !(SecurityStatus == SEC_I_CONTINUE_NEEDED
274 || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE );
6e785d85 275 return TRUE;
276}
277
26ac0430
AJ
278BOOL GenServerContext(PAUTH_SEQ pAS, PVOID pIn, DWORD cbIn, PVOID pOut,
279 PDWORD pcbOut, PBOOL pfDone, char * credentials)
6e785d85 280{
26ac0430
AJ
281 /*
282 * Routine Description:
283 *
284 * Takes an input buffer coming from the client and returns a buffer
285 * to be sent to the client. Also returns an indication of whether or
286 * not the context is complete.
287 *
288 * Return Value:
289 *
290 * Returns TRUE if successful; otherwise FALSE.
291 */
6e785d85 292
293 SecBufferDesc sbdOut;
294 SecBuffer sbOut;
295 SecBufferDesc sbdIn;
296 SecBuffer sbIn;
297 ULONG fContextAttr;
298 SecPkgContext_Names namebuffer;
299
300 if (!pAS->fInitialized) {
26ac0430
AJ
301 SecurityStatus = _AcquireCredentialsHandle(NULL, (SEC_CHAR*) _T(SSP_Package_InUse),
302 SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &pAS->hcred,
303 &pAS->hcredLifeTime);
6e785d85 304#if SSP_DEBUG
305 fprintf(stderr, "AcquireCredentialsHandle returned: %x\n", SecurityStatus);
306#endif
26ac0430 307 if (SecurityStatus < 0) {
6e785d85 308#if SSP_DEBUG
309 fprintf(stderr, "AcquireCredentialsHandle failed: %x\n", SecurityStatus);
310#endif
26ac0430 311 return FALSE;
6e785d85 312 }
26ac0430 313 pAS->fHaveCredHandle = TRUE;
6e785d85 314 }
26ac0430 315
6e785d85 316 /* Prepare output buffer */
317 sbdOut.ulVersion = 0;
318 sbdOut.cBuffers = 1;
319 sbdOut.pBuffers = &sbOut;
320 sbOut.cbBuffer = *pcbOut;
321 sbOut.BufferType = SECBUFFER_TOKEN;
322 sbOut.pvBuffer = pOut;
323
324 /* Prepare input buffer */
325 sbdIn.ulVersion = 0;
326 sbdIn.cBuffers = 1;
327 sbdIn.pBuffers = &sbIn;
328 sbIn.cbBuffer = cbIn;
329 sbIn.BufferType = SECBUFFER_TOKEN;
330 sbIn.pvBuffer = pIn;
26ac0430
AJ
331 SecurityStatus = _AcceptSecurityContext(&pAS->hcred,
332 pAS->fInitialized ? &pAS->hctxt : NULL, &sbdIn, (NTLM_mode == SSP_NTLM) ? ASC_REQ_DELEGATE : 0,
333 SECURITY_NATIVE_DREP, &pAS->hctxt, &sbdOut, &fContextAttr,
334 &pAS->hctxtLifeTime);
6e785d85 335#if SSP_DEBUG
336 fprintf(stderr, "AcceptSecurityContext returned: %x\n", SecurityStatus);
337#endif
338 if (SecurityStatus < 0) {
339#if SSP_DEBUG
340 fprintf(stderr, "AcceptSecurityContext failed: %x\n", SecurityStatus);
341#endif
26ac0430 342 return FALSE;
6e785d85 343 }
344 pAS->fHaveCtxtHandle = TRUE;
26ac0430 345
6e785d85 346 /* If necessary, complete token */
347 if (SecurityStatus == SEC_I_COMPLETE_NEEDED || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE) {
26ac0430 348 SecurityStatus = _CompleteAuthToken(&pAS->hctxt, &sbdOut);
6e785d85 349#if SSP_DEBUG
350 fprintf(stderr, "CompleteAuthToken returned: %x\n", SecurityStatus);
351#endif
352 if (SecurityStatus < 0) {
353#if SSP_DEBUG
354 fprintf(stderr, "CompleteAuthToken failed: %x\n", SecurityStatus);
355#endif
26ac0430 356 return FALSE;
6e785d85 357 }
358 }
359
26ac0430
AJ
360 if ((credentials != NULL) &&
361 !(SecurityStatus == SEC_I_CONTINUE_NEEDED || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE)) {
6e785d85 362 SecurityStatus = _QueryContextAttributes(&pAS->hctxt, SECPKG_ATTR_NAMES, &namebuffer);
363#if SSP_DEBUG
364 fprintf(stderr, "QueryContextAttributes returned: %x\n", SecurityStatus);
365#endif
366 if (SecurityStatus < 0) {
367#if SSP_DEBUG
368 fprintf(stderr, "QueryContextAttributes failed: %x\n", SecurityStatus);
369#endif
26ac0430 370 return FALSE;
6e785d85 371 }
372 strncpy(credentials, namebuffer.sUserName, SSP_MAX_CRED_LEN);
373 }
374
375 *pcbOut = sbOut.cbBuffer;
376 if (!pAS->fInitialized)
26ac0430
AJ
377 pAS->fInitialized = TRUE;
378 *pfDone = !(SecurityStatus == SEC_I_CONTINUE_NEEDED
379 || SecurityStatus == SEC_I_COMPLETE_AND_CONTINUE);
6e785d85 380 return TRUE;
381}
382
26ac0430 383BOOL WINAPI SSP_LogonUser(PTSTR szUser, PTSTR szPassword, PTSTR szDomain)
6e785d85 384{
385 AUTH_SEQ asServer = {0};
386 AUTH_SEQ asClient = {0};
387 BOOL fDone = FALSE;
388 BOOL fResult = FALSE;
389 DWORD cbOut = 0;
390 DWORD cbIn = 0;
26ac0430 391
6e785d85 392 SEC_WINNT_AUTH_IDENTITY ai;
393
394 do {
26ac0430
AJ
395 if (!hModule)
396 break;
6e785d85 397
398 /* Initialize auth identity structure */
26ac0430 399 ZeroMemory(&ai, sizeof(ai));
308f92d7 400 ai.Domain = (unsigned char *)szDomain;
26ac0430 401 ai.DomainLength = lstrlen(szDomain);
308f92d7 402 ai.User = (unsigned char *)szUser;
26ac0430 403 ai.UserLength = lstrlen(szUser);
308f92d7 404 ai.Password = (unsigned char *)szPassword;
26ac0430 405 ai.PasswordLength = lstrlen(szPassword);
6e785d85 406#if defined(UNICODE) || defined(_UNICODE)
26ac0430
AJ
407 ai.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
408#else
409 ai.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
6e785d85 410#endif
411
26ac0430
AJ
412 /* Prepare client message (negotiate) */
413 cbOut = cbMaxToken;
414 if (!GenClientContext(&asClient, &ai, NULL, 0, pClientBuf, &cbOut, &fDone))
415 break;
416
417 /* Prepare server message (challenge) */
418 cbIn = cbOut;
419 cbOut = cbMaxToken;
420 if (!GenServerContext(&asServer, pClientBuf, cbIn, pServerBuf, &cbOut,
421 &fDone, NULL))
422 break;
423 /* Most likely failure: AcceptServerContext fails with SEC_E_LOGON_DENIED
424 * in the case of bad szUser or szPassword.
425 * Unexpected Result: Logon will succeed if you pass in a bad szUser and
426 * the guest account is enabled in the specified domain.
427 */
428
429 /* Prepare client message (authenticate) */
430 cbIn = cbOut;
431 cbOut = cbMaxToken;
432 if (!GenClientContext(&asClient, &ai, pServerBuf, cbIn, pClientBuf, &cbOut,
433 &fDone))
434 break;
6e785d85 435
26ac0430
AJ
436 /* Prepare server message (authentication) */
437 cbIn = cbOut;
438 cbOut = cbMaxToken;
439 if (!GenServerContext(&asServer, pClientBuf, cbIn, pServerBuf, &cbOut,
440 &fDone, NULL))
441 break;
442 fResult = TRUE;
443 } while (0);
6e785d85 444
445 /* Clean up resources */
446 if (asClient.fHaveCtxtHandle)
26ac0430 447 _DeleteSecurityContext(&asClient.hctxt);
6e785d85 448 if (asClient.fHaveCredHandle)
26ac0430 449 _FreeCredentialsHandle(&asClient.hcred);
6e785d85 450 if (asServer.fHaveCtxtHandle)
26ac0430 451 _DeleteSecurityContext(&asServer.hctxt);
6e785d85 452 if (asServer.fHaveCredHandle)
26ac0430 453 _FreeCredentialsHandle(&asServer.hcred);
6e785d85 454
455 return fResult;
456}
457
6e785d85 458const char * WINAPI SSP_MakeChallenge(PVOID PNegotiateBuf, int NegotiateLen)
459{
460 BOOL fDone = FALSE;
ee244464 461 uint8_t * fResult = NULL;
6e785d85 462 DWORD cbOut = 0;
463 DWORD cbIn = 0;
464 ntlm_challenge * challenge;
6e785d85 465
466 if (NTLM_asServer.fHaveCtxtHandle)
26ac0430 467 _DeleteSecurityContext(&NTLM_asServer.hctxt);
6e785d85 468 if (NTLM_asServer.fHaveCredHandle)
469 _FreeCredentialsHandle(&NTLM_asServer.hcred);
470
471 NTLM_LocalCall = FALSE;
472 Use_Unicode = FALSE;
473 memcpy(pClientBuf, PNegotiateBuf, NegotiateLen);
474 ZeroMemory(pServerBuf, cbMaxToken);
475 ZeroMemory(&NTLM_asServer, sizeof(NTLM_asServer));
476 do {
26ac0430
AJ
477 if (!hModule)
478 break;
479
480 /* Prepare server message (challenge) */
481 cbIn = NegotiateLen;
482 cbOut = cbMaxToken;
483 if (!GenServerContext(&NTLM_asServer, pClientBuf, cbIn, pServerBuf, &cbOut,
484 &fDone, NULL))
485 break;
486 fResult = pServerBuf;
487 } while (0);
6e785d85 488 if (fResult != NULL) {
489 challenge = (ntlm_challenge *) fResult;
d6054896
AJ
490 Use_Unicode = NTLM_NEGOTIATE_UNICODE & challenge->flags;
491 NTLM_LocalCall = NTLM_NEGOTIATE_THIS_IS_LOCAL_CALL & challenge->flags;
2dc09715
AJ
492 struct base64_encode_ctx ctx;
493 base64_encode_init(&ctx);
ee244464 494 static char encoded[8192];
6c1219b9 495 size_t dstLen = base64_encode_update(&ctx, encoded, cbOut, reinterpret_cast<const uint8_t*>(fResult));
2dc09715
AJ
496 assert(dstLen < sizeof(encoded));
497 dstLen += base64_encode_final(&ctx, encoded+dstLen);
498 assert(dstLen < sizeof(encoded));
499 encoded[dstLen] = '\0';
6c1219b9 500 return encoded;
6e785d85 501 }
2dc09715 502 return NULL;
6e785d85 503}
504
6e785d85 505BOOL WINAPI SSP_ValidateNTLMCredentials(PVOID PAutenticateBuf, int AutenticateLen, char * credentials)
506{
507 BOOL fDone = FALSE;
508 BOOL fResult = FALSE;
509 DWORD cbOut = 0;
510 DWORD cbIn = 0;
511
512 memcpy(pClientBuf, PAutenticateBuf, AutenticateLen);
513 ZeroMemory(pServerBuf, cbMaxToken);
514 do {
26ac0430
AJ
515 if (!hModule)
516 break;
6e785d85 517
518 /* Prepare server message (authentication) */
519 cbIn = AutenticateLen;
26ac0430
AJ
520 cbOut = cbMaxToken;
521 if (!GenServerContext(&NTLM_asServer, pClientBuf, cbIn, pServerBuf, &cbOut,
522 &fDone, credentials))
523 break;
524 fResult = TRUE;
525 } while (0);
6e785d85 526
527 return fResult;
528}
529
6e785d85 530const char * WINAPI SSP_MakeNegotiateBlob(PVOID PNegotiateBuf, int NegotiateLen, PBOOL fDone, int * Status, char * credentials)
531{
532 DWORD cbOut = 0;
533 DWORD cbIn = 0;
6e785d85 534
535 if (NTLM_asServer.fHaveCtxtHandle)
26ac0430 536 _DeleteSecurityContext(&NTLM_asServer.hctxt);
6e785d85 537 if (NTLM_asServer.fHaveCredHandle)
538 _FreeCredentialsHandle(&NTLM_asServer.hcred);
539
540 memcpy(pClientBuf, PNegotiateBuf, NegotiateLen);
541 ZeroMemory(pServerBuf, cbMaxToken);
542 ZeroMemory(&NTLM_asServer, sizeof(NTLM_asServer));
543 do {
26ac0430
AJ
544 if (!hModule)
545 break;
546
547 /* Prepare server message (challenge) */
548 cbIn = NegotiateLen;
549 cbOut = cbMaxToken;
550 if (!GenServerContext(&NTLM_asServer, pClientBuf, cbIn, pServerBuf, &cbOut,
551 fDone, credentials)) {
552 *Status = SSP_ERROR;
553 break;
6e785d85 554 }
26ac0430
AJ
555 *Status = SSP_OK;
556 } while (0);
2dc09715
AJ
557 if (pServerBuf != NULL && cbOut > 0) {
558 struct base64_encode_ctx ctx;
559 base64_encode_init(&ctx);
ee244464 560 static char encoded[8192];
6c1219b9 561 size_t dstLen = base64_encode_update(&ctx, encoded, cbOut, reinterpret_cast<const uint8_t*>(pServerBuf));
2dc09715
AJ
562 assert(dstLen < sizeof(encoded));
563 dstLen += base64_encode_final(&ctx, encoded+dstLen);
564 assert(dstLen < sizeof(encoded));
565 encoded[dstLen] = '\0';
6c1219b9 566 return encoded;
2dc09715
AJ
567 }
568 return NULL;
6e785d85 569}
570
6e785d85 571const char * WINAPI SSP_ValidateNegotiateCredentials(PVOID PAutenticateBuf, int AutenticateLen, PBOOL fDone, int * Status, char * credentials)
572{
573 DWORD cbOut = 0;
574 DWORD cbIn = 0;
6e785d85 575
576 memcpy(pClientBuf, PAutenticateBuf, AutenticateLen);
577 ZeroMemory(pServerBuf, cbMaxToken);
578 do {
26ac0430
AJ
579 if (!hModule)
580 break;
6e785d85 581
582 /* Prepare server message (authentication) */
583 cbIn = AutenticateLen;
26ac0430
AJ
584 cbOut = cbMaxToken;
585 if (!GenServerContext(&NTLM_asServer, pClientBuf, cbIn, pServerBuf, &cbOut,
586 fDone, credentials)) {
587 *Status = SSP_ERROR;
588 break;
6e785d85 589 }
26ac0430
AJ
590 *Status = SSP_OK;
591 } while (0);
2dc09715
AJ
592 if (pServerBuf != NULL && cbOut > 0) {
593 struct base64_encode_ctx ctx;
594 base64_encode_init(&ctx);
ee244464 595 static char encoded[8192];
6c1219b9 596 size_t dstLen = base64_encode_update(&ctx, encoded, cbOut, reinterpret_cast<const uint8_t*>(pServerBuf));
2dc09715
AJ
597 assert(dstLen < sizeof(encoded));
598 dstLen += base64_encode_final(&ctx, encoded+dstLen);
599 assert(dstLen < sizeof(encoded));
600 encoded[dstLen] = '\0';
6c1219b9 601 return encoded;
2dc09715
AJ
602 }
603 return NULL;
6e785d85 604}
f53969cc 605