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