VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/curl_sasl.c@ 97138

最後變更 在這個檔案從97138是 95312,由 vboxsync 提交於 3 年 前

libs/{curl,libxml2}: OSE export fixes, bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 23.9 KB
 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2022, Daniel Stenberg, <[email protected]>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * RFC2195 CRAM-MD5 authentication
22 * RFC2617 Basic and Digest Access Authentication
23 * RFC2831 DIGEST-MD5 authentication
24 * RFC4422 Simple Authentication and Security Layer (SASL)
25 * RFC4616 PLAIN authentication
26 * RFC5802 SCRAM-SHA-1 authentication
27 * RFC7677 SCRAM-SHA-256 authentication
28 * RFC6749 OAuth 2.0 Authorization Framework
29 * RFC7628 A Set of SASL Mechanisms for OAuth
30 * Draft LOGIN SASL Mechanism <draft-murchison-sasl-login-00.txt>
31 *
32 ***************************************************************************/
33
34#include "curl_setup.h"
35
36#if !defined(CURL_DISABLE_IMAP) || !defined(CURL_DISABLE_SMTP) || \
37 !defined(CURL_DISABLE_POP3)
38
39#include <curl/curl.h>
40#include "urldata.h"
41
42#include "curl_base64.h"
43#include "curl_md5.h"
44#include "vauth/vauth.h"
45#include "vtls/vtls.h"
46#include "curl_hmac.h"
47#include "curl_sasl.h"
48#include "warnless.h"
49#include "strtok.h"
50#include "sendf.h"
51/* The last 3 #include files should be in this order */
52#include "curl_printf.h"
53#include "curl_memory.h"
54#include "memdebug.h"
55
56/* Supported mechanisms */
57static const struct {
58 const char *name; /* Name */
59 size_t len; /* Name length */
60 unsigned short bit; /* Flag bit */
61} mechtable[] = {
62 { "LOGIN", 5, SASL_MECH_LOGIN },
63 { "PLAIN", 5, SASL_MECH_PLAIN },
64 { "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 },
65 { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 },
66 { "GSSAPI", 6, SASL_MECH_GSSAPI },
67 { "EXTERNAL", 8, SASL_MECH_EXTERNAL },
68 { "NTLM", 4, SASL_MECH_NTLM },
69 { "XOAUTH2", 7, SASL_MECH_XOAUTH2 },
70 { "OAUTHBEARER", 11, SASL_MECH_OAUTHBEARER },
71 { "SCRAM-SHA-1", 11, SASL_MECH_SCRAM_SHA_1 },
72 { "SCRAM-SHA-256",13, SASL_MECH_SCRAM_SHA_256 },
73 { ZERO_NULL, 0, 0 }
74};
75
76/*
77 * Curl_sasl_cleanup()
78 *
79 * This is used to cleanup any libraries or curl modules used by the sasl
80 * functions.
81 *
82 * Parameters:
83 *
84 * conn [in] - The connection data.
85 * authused [in] - The authentication mechanism used.
86 */
87void Curl_sasl_cleanup(struct connectdata *conn, unsigned short authused)
88{
89 (void)conn;
90 (void)authused;
91
92#if defined(USE_KERBEROS5)
93 /* Cleanup the gssapi structure */
94 if(authused == SASL_MECH_GSSAPI) {
95 Curl_auth_cleanup_gssapi(&conn->krb5);
96 }
97#endif
98
99#if defined(USE_GSASL)
100 /* Cleanup the GSASL structure */
101 if(authused & (SASL_MECH_SCRAM_SHA_1 | SASL_MECH_SCRAM_SHA_256)) {
102 Curl_auth_gsasl_cleanup(&conn->gsasl);
103 }
104#endif
105
106#if defined(USE_NTLM)
107 /* Cleanup the NTLM structure */
108 if(authused == SASL_MECH_NTLM) {
109 Curl_auth_cleanup_ntlm(&conn->ntlm);
110 }
111#endif
112}
113
114/*
115 * Curl_sasl_decode_mech()
116 *
117 * Convert a SASL mechanism name into a token.
118 *
119 * Parameters:
120 *
121 * ptr [in] - The mechanism string.
122 * maxlen [in] - Maximum mechanism string length.
123 * len [out] - If not NULL, effective name length.
124 *
125 * Returns the SASL mechanism token or 0 if no match.
126 */
127unsigned short Curl_sasl_decode_mech(const char *ptr, size_t maxlen,
128 size_t *len)
129{
130 unsigned int i;
131 char c;
132
133 for(i = 0; mechtable[i].name; i++) {
134 if(maxlen >= mechtable[i].len &&
135 !memcmp(ptr, mechtable[i].name, mechtable[i].len)) {
136 if(len)
137 *len = mechtable[i].len;
138
139 if(maxlen == mechtable[i].len)
140 return mechtable[i].bit;
141
142 c = ptr[mechtable[i].len];
143 if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_')
144 return mechtable[i].bit;
145 }
146 }
147
148 return 0;
149}
150
151/*
152 * Curl_sasl_parse_url_auth_option()
153 *
154 * Parse the URL login options.
155 */
156CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
157 const char *value, size_t len)
158{
159 CURLcode result = CURLE_OK;
160 size_t mechlen;
161
162 if(!len)
163 return CURLE_URL_MALFORMAT;
164
165 if(sasl->resetprefs) {
166 sasl->resetprefs = FALSE;
167 sasl->prefmech = SASL_AUTH_NONE;
168 }
169
170 if(!strncmp(value, "*", len))
171 sasl->prefmech = SASL_AUTH_DEFAULT;
172 else {
173 unsigned short mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
174 if(mechbit && mechlen == len)
175 sasl->prefmech |= mechbit;
176 else
177 result = CURLE_URL_MALFORMAT;
178 }
179
180 return result;
181}
182
183/*
184 * Curl_sasl_init()
185 *
186 * Initializes the SASL structure.
187 */
188void Curl_sasl_init(struct SASL *sasl, struct Curl_easy *data,
189 const struct SASLproto *params)
190{
191 unsigned long auth = data->set.httpauth;
192
193 sasl->params = params; /* Set protocol dependent parameters */
194 sasl->state = SASL_STOP; /* Not yet running */
195 sasl->curmech = NULL; /* No mechanism yet. */
196 sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
197 sasl->prefmech = params->defmechs; /* Default preferred mechanisms */
198 sasl->authused = SASL_AUTH_NONE; /* The authentication mechanism used */
199 sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */
200 sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */
201 sasl->force_ir = FALSE; /* Respect external option */
202
203 if(auth != CURLAUTH_BASIC) {
204 sasl->resetprefs = FALSE;
205 sasl->prefmech = SASL_AUTH_NONE;
206 if(auth & CURLAUTH_BASIC)
207 sasl->prefmech |= SASL_MECH_PLAIN | SASL_MECH_LOGIN;
208 if(auth & CURLAUTH_DIGEST)
209 sasl->prefmech |= SASL_MECH_DIGEST_MD5;
210 if(auth & CURLAUTH_NTLM)
211 sasl->prefmech |= SASL_MECH_NTLM;
212 if(auth & CURLAUTH_BEARER)
213 sasl->prefmech |= SASL_MECH_OAUTHBEARER | SASL_MECH_XOAUTH2;
214 if(auth & CURLAUTH_GSSAPI)
215 sasl->prefmech |= SASL_MECH_GSSAPI;
216 }
217}
218
219/*
220 * state()
221 *
222 * This is the ONLY way to change SASL state!
223 */
224static void state(struct SASL *sasl, struct Curl_easy *data,
225 saslstate newstate)
226{
227#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
228 /* for debug purposes */
229 static const char * const names[]={
230 "STOP",
231 "PLAIN",
232 "LOGIN",
233 "LOGIN_PASSWD",
234 "EXTERNAL",
235 "CRAMMD5",
236 "DIGESTMD5",
237 "DIGESTMD5_RESP",
238 "NTLM",
239 "NTLM_TYPE2MSG",
240 "GSSAPI",
241 "GSSAPI_TOKEN",
242 "GSSAPI_NO_DATA",
243 "OAUTH2",
244 "OAUTH2_RESP",
245 "GSASL",
246 "CANCEL",
247 "FINAL",
248 /* LAST */
249 };
250
251 if(sasl->state != newstate)
252 infof(data, "SASL %p state change from %s to %s",
253 (void *)sasl, names[sasl->state], names[newstate]);
254#else
255 (void) data;
256#endif
257
258 sasl->state = newstate;
259}
260
261/* Get the SASL server message and convert it to binary. */
262static CURLcode get_server_message(struct SASL *sasl, struct Curl_easy *data,
263 struct bufref *out)
264{
265 CURLcode result = CURLE_OK;
266
267 result = sasl->params->getmessage(data, out);
268 if(!result && (sasl->params->flags & SASL_FLAG_BASE64)) {
269 unsigned char *msg;
270 size_t msglen;
271 const char *serverdata = (const char *) Curl_bufref_ptr(out);
272
273 if(!*serverdata || *serverdata == '=')
274 Curl_bufref_set(out, NULL, 0, NULL);
275 else {
276 result = Curl_base64_decode(serverdata, &msg, &msglen);
277 if(!result)
278 Curl_bufref_set(out, msg, msglen, curl_free);
279 }
280 }
281 return result;
282}
283
284/* Encode the outgoing SASL message. */
285static CURLcode build_message(struct SASL *sasl, struct bufref *msg)
286{
287 CURLcode result = CURLE_OK;
288
289 if(sasl->params->flags & SASL_FLAG_BASE64) {
290 if(!Curl_bufref_ptr(msg)) /* Empty message. */
291 Curl_bufref_set(msg, "", 0, NULL);
292 else if(!Curl_bufref_len(msg)) /* Explicit empty response. */
293 Curl_bufref_set(msg, "=", 1, NULL);
294 else {
295 char *base64;
296 size_t base64len;
297
298 result = Curl_base64_encode((const char *) Curl_bufref_ptr(msg),
299 Curl_bufref_len(msg), &base64, &base64len);
300 if(!result)
301 Curl_bufref_set(msg, base64, base64len, curl_free);
302 }
303 }
304
305 return result;
306}
307
308/*
309 * Curl_sasl_can_authenticate()
310 *
311 * Check if we have enough auth data and capabilities to authenticate.
312 */
313bool Curl_sasl_can_authenticate(struct SASL *sasl, struct Curl_easy *data)
314{
315 /* Have credentials been provided? */
316 if(data->state.aptr.user)
317 return TRUE;
318
319 /* EXTERNAL can authenticate without a user name and/or password */
320 if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL)
321 return TRUE;
322
323 return FALSE;
324}
325
326/*
327 * Curl_sasl_start()
328 *
329 * Calculate the required login details for SASL authentication.
330 */
331CURLcode Curl_sasl_start(struct SASL *sasl, struct Curl_easy *data,
332 bool force_ir, saslprogress *progress)
333{
334 CURLcode result = CURLE_OK;
335 struct connectdata *conn = data->conn;
336 unsigned short enabledmechs;
337 const char *mech = NULL;
338 struct bufref resp;
339 saslstate state1 = SASL_STOP;
340 saslstate state2 = SASL_FINAL;
341 const char * const hostname = SSL_HOST_NAME();
342 const long int port = SSL_HOST_PORT();
343#if defined(USE_KERBEROS5) || defined(USE_NTLM)
344 const char *service = data->set.str[STRING_SERVICE_NAME] ?
345 data->set.str[STRING_SERVICE_NAME] :
346 sasl->params->service;
347#endif
348 const char *oauth_bearer = data->set.str[STRING_BEARER];
349 struct bufref nullmsg;
350
351 Curl_bufref_init(&nullmsg);
352 Curl_bufref_init(&resp);
353 sasl->force_ir = force_ir; /* Latch for future use */
354 sasl->authused = 0; /* No mechanism used yet */
355 enabledmechs = sasl->authmechs & sasl->prefmech;
356 *progress = SASL_IDLE;
357
358 /* Calculate the supported authentication mechanism, by decreasing order of
359 security, as well as the initial response where appropriate */
360 if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) {
361 mech = SASL_MECH_STRING_EXTERNAL;
362 state1 = SASL_EXTERNAL;
363 sasl->authused = SASL_MECH_EXTERNAL;
364
365 if(force_ir || data->set.sasl_ir)
366 result = Curl_auth_create_external_message(conn->user, &resp);
367 }
368 else if(data->state.aptr.user) {
369#if defined(USE_KERBEROS5)
370 if((enabledmechs & SASL_MECH_GSSAPI) && Curl_auth_is_gssapi_supported() &&
371 Curl_auth_user_contains_domain(conn->user)) {
372 sasl->mutual_auth = FALSE;
373 mech = SASL_MECH_STRING_GSSAPI;
374 state1 = SASL_GSSAPI;
375 state2 = SASL_GSSAPI_TOKEN;
376 sasl->authused = SASL_MECH_GSSAPI;
377
378 if(force_ir || data->set.sasl_ir)
379 result = Curl_auth_create_gssapi_user_message(data, conn->user,
380 conn->passwd,
381 service,
382 conn->host.name,
383 sasl->mutual_auth,
384 NULL, &conn->krb5,
385 &resp);
386 }
387 else
388#endif
389#ifdef USE_GSASL
390 if((enabledmechs & SASL_MECH_SCRAM_SHA_256) &&
391 Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_256,
392 &conn->gsasl)) {
393 mech = SASL_MECH_STRING_SCRAM_SHA_256;
394 sasl->authused = SASL_MECH_SCRAM_SHA_256;
395 state1 = SASL_GSASL;
396 state2 = SASL_GSASL;
397
398 result = Curl_auth_gsasl_start(data, conn->user,
399 conn->passwd, &conn->gsasl);
400 if(result == CURLE_OK && (force_ir || data->set.sasl_ir))
401 result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp);
402 }
403 else if((enabledmechs & SASL_MECH_SCRAM_SHA_1) &&
404 Curl_auth_gsasl_is_supported(data, SASL_MECH_STRING_SCRAM_SHA_1,
405 &conn->gsasl)) {
406 mech = SASL_MECH_STRING_SCRAM_SHA_1;
407 sasl->authused = SASL_MECH_SCRAM_SHA_1;
408 state1 = SASL_GSASL;
409 state2 = SASL_GSASL;
410
411 result = Curl_auth_gsasl_start(data, conn->user,
412 conn->passwd, &conn->gsasl);
413 if(result == CURLE_OK && (force_ir || data->set.sasl_ir))
414 result = Curl_auth_gsasl_token(data, &nullmsg, &conn->gsasl, &resp);
415 }
416 else
417#endif
418#ifndef CURL_DISABLE_CRYPTO_AUTH
419 if((enabledmechs & SASL_MECH_DIGEST_MD5) &&
420 Curl_auth_is_digest_supported()) {
421 mech = SASL_MECH_STRING_DIGEST_MD5;
422 state1 = SASL_DIGESTMD5;
423 sasl->authused = SASL_MECH_DIGEST_MD5;
424 }
425 else if(enabledmechs & SASL_MECH_CRAM_MD5) {
426 mech = SASL_MECH_STRING_CRAM_MD5;
427 state1 = SASL_CRAMMD5;
428 sasl->authused = SASL_MECH_CRAM_MD5;
429 }
430 else
431#endif
432#ifdef USE_NTLM
433 if((enabledmechs & SASL_MECH_NTLM) && Curl_auth_is_ntlm_supported()) {
434 mech = SASL_MECH_STRING_NTLM;
435 state1 = SASL_NTLM;
436 state2 = SASL_NTLM_TYPE2MSG;
437 sasl->authused = SASL_MECH_NTLM;
438
439 if(force_ir || data->set.sasl_ir)
440 result = Curl_auth_create_ntlm_type1_message(data,
441 conn->user, conn->passwd,
442 service,
443 hostname,
444 &conn->ntlm, &resp);
445 }
446 else
447#endif
448 if((enabledmechs & SASL_MECH_OAUTHBEARER) && oauth_bearer) {
449 mech = SASL_MECH_STRING_OAUTHBEARER;
450 state1 = SASL_OAUTH2;
451 state2 = SASL_OAUTH2_RESP;
452 sasl->authused = SASL_MECH_OAUTHBEARER;
453
454 if(force_ir || data->set.sasl_ir)
455 result = Curl_auth_create_oauth_bearer_message(conn->user,
456 hostname,
457 port,
458 oauth_bearer,
459 &resp);
460 }
461 else if((enabledmechs & SASL_MECH_XOAUTH2) && oauth_bearer) {
462 mech = SASL_MECH_STRING_XOAUTH2;
463 state1 = SASL_OAUTH2;
464 sasl->authused = SASL_MECH_XOAUTH2;
465
466 if(force_ir || data->set.sasl_ir)
467 result = Curl_auth_create_xoauth_bearer_message(conn->user,
468 oauth_bearer,
469 &resp);
470 }
471 else if(enabledmechs & SASL_MECH_PLAIN) {
472 mech = SASL_MECH_STRING_PLAIN;
473 state1 = SASL_PLAIN;
474 sasl->authused = SASL_MECH_PLAIN;
475
476 if(force_ir || data->set.sasl_ir)
477 result = Curl_auth_create_plain_message(conn->sasl_authzid,
478 conn->user, conn->passwd,
479 &resp);
480 }
481 else if(enabledmechs & SASL_MECH_LOGIN) {
482 mech = SASL_MECH_STRING_LOGIN;
483 state1 = SASL_LOGIN;
484 state2 = SASL_LOGIN_PASSWD;
485 sasl->authused = SASL_MECH_LOGIN;
486
487 if(force_ir || data->set.sasl_ir)
488 result = Curl_auth_create_login_message(conn->user, &resp);
489 }
490 }
491
492 if(!result && mech) {
493 sasl->curmech = mech;
494 if(Curl_bufref_ptr(&resp))
495 result = build_message(sasl, &resp);
496
497 if(sasl->params->maxirlen &&
498 strlen(mech) + Curl_bufref_len(&resp) > sasl->params->maxirlen)
499 Curl_bufref_free(&resp);
500
501 if(!result)
502 result = sasl->params->sendauth(data, mech, &resp);
503
504 if(!result) {
505 *progress = SASL_INPROGRESS;
506 state(sasl, data, Curl_bufref_ptr(&resp) ? state2 : state1);
507 }
508 }
509
510 Curl_bufref_free(&resp);
511 return result;
512}
513
514/*
515 * Curl_sasl_continue()
516 *
517 * Continue the authentication.
518 */
519CURLcode Curl_sasl_continue(struct SASL *sasl, struct Curl_easy *data,
520 int code, saslprogress *progress)
521{
522 CURLcode result = CURLE_OK;
523 struct connectdata *conn = data->conn;
524 saslstate newstate = SASL_FINAL;
525 struct bufref resp;
526 const char * const hostname = SSL_HOST_NAME();
527 const long int port = SSL_HOST_PORT();
528#if !defined(CURL_DISABLE_CRYPTO_AUTH) || defined(USE_KERBEROS5) || \
529 defined(USE_NTLM)
530 const char *service = data->set.str[STRING_SERVICE_NAME] ?
531 data->set.str[STRING_SERVICE_NAME] :
532 sasl->params->service;
533#endif
534 const char *oauth_bearer = data->set.str[STRING_BEARER];
535 struct bufref serverdata;
536
537 Curl_bufref_init(&serverdata);
538 Curl_bufref_init(&resp);
539 *progress = SASL_INPROGRESS;
540
541 if(sasl->state == SASL_FINAL) {
542 if(code != sasl->params->finalcode)
543 result = CURLE_LOGIN_DENIED;
544 *progress = SASL_DONE;
545 state(sasl, data, SASL_STOP);
546 return result;
547 }
548
549 if(sasl->state != SASL_CANCEL && sasl->state != SASL_OAUTH2_RESP &&
550 code != sasl->params->contcode) {
551 *progress = SASL_DONE;
552 state(sasl, data, SASL_STOP);
553 return CURLE_LOGIN_DENIED;
554 }
555
556 switch(sasl->state) {
557 case SASL_STOP:
558 *progress = SASL_DONE;
559 return result;
560 case SASL_PLAIN:
561 result = Curl_auth_create_plain_message(conn->sasl_authzid,
562 conn->user, conn->passwd, &resp);
563 break;
564 case SASL_LOGIN:
565 result = Curl_auth_create_login_message(conn->user, &resp);
566 newstate = SASL_LOGIN_PASSWD;
567 break;
568 case SASL_LOGIN_PASSWD:
569 result = Curl_auth_create_login_message(conn->passwd, &resp);
570 break;
571 case SASL_EXTERNAL:
572 result = Curl_auth_create_external_message(conn->user, &resp);
573 break;
574#ifndef CURL_DISABLE_CRYPTO_AUTH
575#ifdef USE_GSASL
576 case SASL_GSASL:
577 result = get_server_message(sasl, data, &serverdata);
578 if(!result)
579 result = Curl_auth_gsasl_token(data, &serverdata, &conn->gsasl, &resp);
580 if(!result && Curl_bufref_len(&resp) > 0)
581 newstate = SASL_GSASL;
582 break;
583#endif
584 case SASL_CRAMMD5:
585 result = get_server_message(sasl, data, &serverdata);
586 if(!result)
587 result = Curl_auth_create_cram_md5_message(&serverdata, conn->user,
588 conn->passwd, &resp);
589 break;
590 case SASL_DIGESTMD5:
591 result = get_server_message(sasl, data, &serverdata);
592 if(!result)
593 result = Curl_auth_create_digest_md5_message(data, &serverdata,
594 conn->user, conn->passwd,
595 service, &resp);
596 if(!result && (sasl->params->flags & SASL_FLAG_BASE64))
597 newstate = SASL_DIGESTMD5_RESP;
598 break;
599 case SASL_DIGESTMD5_RESP:
600 /* Keep response NULL to output an empty line. */
601 break;
602#endif
603
604#ifdef USE_NTLM
605 case SASL_NTLM:
606 /* Create the type-1 message */
607 result = Curl_auth_create_ntlm_type1_message(data,
608 conn->user, conn->passwd,
609 service, hostname,
610 &conn->ntlm, &resp);
611 newstate = SASL_NTLM_TYPE2MSG;
612 break;
613 case SASL_NTLM_TYPE2MSG:
614 /* Decode the type-2 message */
615 result = get_server_message(sasl, data, &serverdata);
616 if(!result)
617 result = Curl_auth_decode_ntlm_type2_message(data, &serverdata,
618 &conn->ntlm);
619 if(!result)
620 result = Curl_auth_create_ntlm_type3_message(data, conn->user,
621 conn->passwd, &conn->ntlm,
622 &resp);
623 break;
624#endif
625
626#if defined(USE_KERBEROS5)
627 case SASL_GSSAPI:
628 result = Curl_auth_create_gssapi_user_message(data, conn->user,
629 conn->passwd,
630 service,
631 conn->host.name,
632 sasl->mutual_auth, NULL,
633 &conn->krb5,
634 &resp);
635 newstate = SASL_GSSAPI_TOKEN;
636 break;
637 case SASL_GSSAPI_TOKEN:
638 result = get_server_message(sasl, data, &serverdata);
639 if(!result) {
640 if(sasl->mutual_auth) {
641 /* Decode the user token challenge and create the optional response
642 message */
643 result = Curl_auth_create_gssapi_user_message(data, NULL, NULL,
644 NULL, NULL,
645 sasl->mutual_auth,
646 &serverdata,
647 &conn->krb5,
648 &resp);
649 newstate = SASL_GSSAPI_NO_DATA;
650 }
651 else
652 /* Decode the security challenge and create the response message */
653 result = Curl_auth_create_gssapi_security_message(data,
654 conn->sasl_authzid,
655 &serverdata,
656 &conn->krb5,
657 &resp);
658 }
659 break;
660 case SASL_GSSAPI_NO_DATA:
661 /* Decode the security challenge and create the response message */
662 result = get_server_message(sasl, data, &serverdata);
663 if(!result)
664 result = Curl_auth_create_gssapi_security_message(data,
665 conn->sasl_authzid,
666 &serverdata,
667 &conn->krb5,
668 &resp);
669 break;
670#endif
671
672 case SASL_OAUTH2:
673 /* Create the authorization message */
674 if(sasl->authused == SASL_MECH_OAUTHBEARER) {
675 result = Curl_auth_create_oauth_bearer_message(conn->user,
676 hostname,
677 port,
678 oauth_bearer,
679 &resp);
680
681 /* Failures maybe sent by the server as continuations for OAUTHBEARER */
682 newstate = SASL_OAUTH2_RESP;
683 }
684 else
685 result = Curl_auth_create_xoauth_bearer_message(conn->user,
686 oauth_bearer,
687 &resp);
688 break;
689
690 case SASL_OAUTH2_RESP:
691 /* The continuation is optional so check the response code */
692 if(code == sasl->params->finalcode) {
693 /* Final response was received so we are done */
694 *progress = SASL_DONE;
695 state(sasl, data, SASL_STOP);
696 return result;
697 }
698 else if(code == sasl->params->contcode) {
699 /* Acknowledge the continuation by sending a 0x01 response. */
700 Curl_bufref_set(&resp, "\x01", 1, NULL);
701 break;
702 }
703 else {
704 *progress = SASL_DONE;
705 state(sasl, data, SASL_STOP);
706 return CURLE_LOGIN_DENIED;
707 }
708
709 case SASL_CANCEL:
710 /* Remove the offending mechanism from the supported list */
711 sasl->authmechs ^= sasl->authused;
712
713 /* Start an alternative SASL authentication */
714 return Curl_sasl_start(sasl, data, sasl->force_ir, progress);
715 default:
716 failf(data, "Unsupported SASL authentication mechanism");
717 result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */
718 break;
719 }
720
721 Curl_bufref_free(&serverdata);
722
723 switch(result) {
724 case CURLE_BAD_CONTENT_ENCODING:
725 /* Cancel dialog */
726 result = sasl->params->cancelauth(data, sasl->curmech);
727 newstate = SASL_CANCEL;
728 break;
729 case CURLE_OK:
730 result = build_message(sasl, &resp);
731 if(!result)
732 result = sasl->params->contauth(data, sasl->curmech, &resp);
733 break;
734 default:
735 newstate = SASL_STOP; /* Stop on error */
736 *progress = SASL_DONE;
737 break;
738 }
739
740 Curl_bufref_free(&resp);
741
742 state(sasl, data, newstate);
743
744 return result;
745}
746#endif /* protocols are enabled that use SASL */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette