diff options
author | seonah moon <seonah1.moon@samsung.com> | 2016-04-06 19:31:17 -0700 |
---|---|---|
committer | seonah moon <seonah1.moon@samsung.com> | 2016-04-06 19:31:17 -0700 |
commit | f7bbc1c9b6a8e2c815d09612b53f453c90d962e0 (patch) | |
tree | 10a20bd420864ba529d87794b27ebf303ae7c86a /lib/curl_sasl.c | |
parent | 31368b6eac8092a307849518e912b4c475c0238a (diff) | |
download | curl-f7bbc1c9b6a8e2c815d09612b53f453c90d962e0.tar.gz curl-f7bbc1c9b6a8e2c815d09612b53f453c90d962e0.tar.bz2 curl-f7bbc1c9b6a8e2c815d09612b53f453c90d962e0.zip |
Revert "Imported Upstream version 7.44.0"
This reverts commit 31368b6eac8092a307849518e912b4c475c0238a.
Change-Id: I3428294b4931a00ba9684528d3ffb326f92ed4e8
Diffstat (limited to 'lib/curl_sasl.c')
-rw-r--r-- | lib/curl_sasl.c | 597 |
1 files changed, 55 insertions, 542 deletions
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c index 68646bc1a..b944aa2df 100644 --- a/lib/curl_sasl.c +++ b/lib/curl_sasl.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -39,33 +39,16 @@ #include "curl_hmac.h" #include "curl_sasl.h" #include "warnless.h" +#include "curl_memory.h" #include "strtok.h" -#include "strequal.h" #include "rawstr.h" -#include "sendf.h" #include "non-ascii.h" /* included for Curl_convert_... prototypes */ -#include "curl_printf.h" -/* The last #include files should be: */ -#include "curl_memory.h" -#include "memdebug.h" +#define _MPRINTF_REPLACE /* use our functions only */ +#include <curl/mprintf.h> -/* Supported mechanisms */ -const struct { - const char *name; /* Name */ - size_t len; /* Name length */ - unsigned int bit; /* Flag bit */ -} mechtable[] = { - { "LOGIN", 5, SASL_MECH_LOGIN }, - { "PLAIN", 5, SASL_MECH_PLAIN }, - { "CRAM-MD5", 8, SASL_MECH_CRAM_MD5 }, - { "DIGEST-MD5", 10, SASL_MECH_DIGEST_MD5 }, - { "GSSAPI", 6, SASL_MECH_GSSAPI }, - { "EXTERNAL", 8, SASL_MECH_EXTERNAL }, - { "NTLM", 4, SASL_MECH_NTLM }, - { "XOAUTH2", 7, SASL_MECH_XOAUTH2 }, - { ZERO_NULL, 0, 0 } -}; +/* The last #include file should be: */ +#include "memdebug.h" #if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI) #define DIGEST_QOP_VALUE_AUTH (1 << 0) @@ -76,6 +59,9 @@ const struct { #define DIGEST_QOP_VALUE_STRING_AUTH_INT "auth-int" #define DIGEST_QOP_VALUE_STRING_AUTH_CONF "auth-conf" +#define DIGEST_MAX_VALUE_LENGTH 256 +#define DIGEST_MAX_CONTENT_LENGTH 1024 + /* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines. It converts digest text to ASCII so the MD5 will be correct for what ultimately goes over the network. @@ -87,16 +73,13 @@ const struct { return result; \ } -#endif - -#if !defined(CURL_DISABLE_CRYPTO_AUTH) /* - * Returns 0 on success and then the buffers are filled in fine. + * Return 0 on success and then the buffers are filled in fine. * * Non-zero means failure to parse. */ -int Curl_sasl_digest_get_pair(const char *str, char *value, char *content, - const char **endptr) +static int sasl_digest_get_pair(const char *str, char *value, char *content, + const char **endptr) { int c; bool starts_with_quote = FALSE; @@ -157,9 +140,7 @@ int Curl_sasl_digest_get_pair(const char *str, char *value, char *content, return 0; /* all is fine! */ } -#endif -#if !defined(CURL_DISABLE_CRYPTO_AUTH) && !defined(USE_WINDOWS_SSPI) /* Convert md5 chunk to RFC2617 (section 3.1.3) -suitable ascii string*/ static void sasl_digest_md5_to_ascii(unsigned char *source, /* 16 bytes */ unsigned char *dest) /* 33 bytes */ @@ -253,7 +234,7 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value) token = strtok_r(NULL, ",", &tok_buf); } - free(tmp); + Curl_safefree(tmp); return CURLE_OK; } @@ -267,7 +248,7 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value) * * Parameters: * - * service [in] - The service type such as www, smtp, pop or imap. + * serivce [in] - The service type such as www, smtp, pop or imap. * host [in] - The host name or realm. * * Returns a pointer to the newly allocated SPN. @@ -280,7 +261,7 @@ char *Curl_sasl_build_spn(const char *service, const char *host) #endif /* - * sasl_create_plain_message() + * Curl_sasl_create_plain_message() * * This is used to generate an already encoded PLAIN message ready * for sending to the recipient. @@ -296,10 +277,10 @@ char *Curl_sasl_build_spn(const char *service, const char *host) * * Returns CURLE_OK on success. */ -static CURLcode sasl_create_plain_message(struct SessionHandle *data, - const char *userp, - const char *passwdp, - char **outptr, size_t *outlen) +CURLcode Curl_sasl_create_plain_message(struct SessionHandle *data, + const char *userp, + const char *passwdp, + char **outptr, size_t *outlen) { CURLcode result; char *plainauth; @@ -326,12 +307,12 @@ static CURLcode sasl_create_plain_message(struct SessionHandle *data, /* Base64 encode the reply */ result = Curl_base64_encode(data, plainauth, 2 * ulen + plen + 2, outptr, outlen); - free(plainauth); + Curl_safefree(plainauth); return result; } /* - * sasl_create_login_message() + * Curl_sasl_create_login_message() * * This is used to generate an already encoded LOGIN message containing the * user name or password ready for sending to the recipient. @@ -346,9 +327,9 @@ static CURLcode sasl_create_plain_message(struct SessionHandle *data, * * Returns CURLE_OK on success. */ -static CURLcode sasl_create_login_message(struct SessionHandle *data, - const char *valuep, char **outptr, - size_t *outlen) +CURLcode Curl_sasl_create_login_message(struct SessionHandle *data, + const char *valuep, char **outptr, + size_t *outlen) { size_t vlen = strlen(valuep); @@ -368,33 +349,9 @@ static CURLcode sasl_create_login_message(struct SessionHandle *data, return Curl_base64_encode(data, valuep, vlen, outptr, outlen); } -/* - * sasl_create_external_message() - * - * This is used to generate an already encoded EXTERNAL message containing - * the user name ready for sending to the recipient. - * - * Parameters: - * - * data [in] - The session handle. - * user [in] - The user name. - * outptr [in/out] - The address where a pointer to newly allocated memory - * holding the result will be stored upon completion. - * outlen [out] - The length of the output message. - * - * Returns CURLE_OK on success. - */ -static CURLcode sasl_create_external_message(struct SessionHandle *data, - const char *user, char **outptr, - size_t *outlen) -{ - /* This is the same formatting as the login message. */ - return sasl_create_login_message(data, user, outptr, outlen); -} - #ifndef CURL_DISABLE_CRYPTO_AUTH /* - * sasl_decode_cram_md5_message() + * Curl_sasl_decode_cram_md5_message() * * This is used to decode an already encoded CRAM-MD5 challenge message. * @@ -407,8 +364,8 @@ static CURLcode sasl_create_external_message(struct SessionHandle *data, * * Returns CURLE_OK on success. */ -static CURLcode sasl_decode_cram_md5_message(const char *chlg64, char **outptr, - size_t *outlen) +CURLcode Curl_sasl_decode_cram_md5_message(const char *chlg64, char **outptr, + size_t *outlen) { CURLcode result = CURLE_OK; size_t chlg64len = strlen(chlg64); @@ -424,7 +381,7 @@ static CURLcode sasl_decode_cram_md5_message(const char *chlg64, char **outptr, } /* - * sasl_create_cram_md5_message() + * Curl_sasl_create_cram_md5_message() * * This is used to generate an already encoded CRAM-MD5 response message ready * for sending to the recipient. @@ -441,11 +398,11 @@ static CURLcode sasl_decode_cram_md5_message(const char *chlg64, char **outptr, * * Returns CURLE_OK on success. */ -static CURLcode sasl_create_cram_md5_message(struct SessionHandle *data, - const char *chlg, - const char *userp, - const char *passwdp, - char **outptr, size_t *outlen) +CURLcode Curl_sasl_create_cram_md5_message(struct SessionHandle *data, + const char *chlg, + const char *userp, + const char *passwdp, + char **outptr, size_t *outlen) { CURLcode result = CURLE_OK; size_t chlglen = 0; @@ -483,7 +440,7 @@ static CURLcode sasl_create_cram_md5_message(struct SessionHandle *data, /* Base64 encode the response */ result = Curl_base64_encode(data, response, 0, outptr, outlen); - free(response); + Curl_safefree(response); return result; } @@ -533,7 +490,7 @@ static CURLcode sasl_decode_digest_md5_message(const char *chlg64, /* Retrieve nonce string from the challenge */ if(!sasl_digest_get_key_value((char *)chlg, "nonce=\"", nonce, nlen, '\"')) { - free(chlg); + Curl_safefree(chlg); return CURLE_BAD_CONTENT_ENCODING; } @@ -545,17 +502,17 @@ static CURLcode sasl_decode_digest_md5_message(const char *chlg64, /* Retrieve algorithm string from the challenge */ if(!sasl_digest_get_key_value((char *)chlg, "algorithm=", alg, alen, ',')) { - free(chlg); + Curl_safefree(chlg); return CURLE_BAD_CONTENT_ENCODING; } /* Retrieve qop-options string from the challenge */ if(!sasl_digest_get_key_value((char *)chlg, "qop=\"", qop, qlen, '\"')) { - free(chlg); + Curl_safefree(chlg); return CURLE_BAD_CONTENT_ENCODING; } - free(chlg); + Curl_safefree(chlg); return CURLE_OK; } @@ -677,7 +634,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, /* Calculate H(A2) */ ctxt = Curl_MD5_init(Curl_DIGEST_MD5); if(!ctxt) { - free(spn); + Curl_safefree(spn); return CURLE_OUT_OF_MEMORY; } @@ -695,7 +652,7 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, /* Now calculate the response hash */ ctxt = Curl_MD5_init(Curl_DIGEST_MD5); if(!ctxt) { - free(spn); + Curl_safefree(spn); return CURLE_OUT_OF_MEMORY; } @@ -728,14 +685,14 @@ CURLcode Curl_sasl_create_digest_md5_message(struct SessionHandle *data, "qop=%s", userp, realm, nonce, cnonce, nonceCount, spn, resp_hash_hex, qop); - free(spn); + Curl_safefree(spn); if(!response) return CURLE_OUT_OF_MEMORY; /* Base64 encode the response */ result = Curl_base64_encode(data, response, 0, outptr, outlen); - free(response); + Curl_safefree(response); return result; } @@ -778,7 +735,7 @@ CURLcode Curl_sasl_decode_digest_http_message(const char *chlg, chlg++; /* Extract a value=content pair */ - if(!Curl_sasl_digest_get_pair(chlg, value, content, &chlg)) { + if(!sasl_digest_get_pair(chlg, value, content, &chlg)) { if(Curl_raw_equal(value, "nonce")) { digest->nonce = strdup(content); if(!digest->nonce) @@ -949,7 +906,7 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data, CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ Curl_md5it(md5buf, md5this); - free(md5this); + Curl_safefree(md5this); sasl_digest_md5_to_ascii(md5buf, ha1); if(digest->algo == CURLDIGESTALGO_MD5SESS) { @@ -960,7 +917,7 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data, CURL_OUTPUT_DIGEST_CONV(data, tmp); /* convert on non-ASCII machines */ Curl_md5it(md5buf, (unsigned char *)tmp); - free(tmp); + Curl_safefree(tmp); sasl_digest_md5_to_ascii(md5buf, ha1); } @@ -984,7 +941,7 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data, TODO: replace md5 of empty string with entity-body for PUT/POST */ unsigned char *md5this2 = (unsigned char *) aprintf("%s:%s", md5this, "d41d8cd98f00b204e9800998ecf8427e"); - free(md5this); + Curl_safefree(md5this); md5this = md5this2; } @@ -993,7 +950,7 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data, CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ Curl_md5it(md5buf, md5this); - free(md5this); + Curl_safefree(md5this); sasl_digest_md5_to_ascii(md5buf, ha2); if(digest->qop) { @@ -1017,7 +974,7 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data, CURL_OUTPUT_DIGEST_CONV(data, md5this); /* convert on non-ASCII machines */ Curl_md5it(md5buf, md5this); - free(md5this); + Curl_safefree(md5this); sasl_digest_md5_to_ascii(md5buf, request_digest); /* for test case 64 (snooped from a Mozilla 1.3a request) @@ -1072,7 +1029,7 @@ CURLcode Curl_sasl_create_digest_http_message(struct SessionHandle *data, uripath, request_digest); } - free(userp_quoted); + Curl_safefree(userp_quoted); if(!response) return CURLE_OUT_OF_MEMORY; @@ -1153,7 +1110,7 @@ void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm) #endif /* USE_NTLM && !USE_WINDOWS_SSPI*/ /* - * sasl_create_xoauth2_message() + * Curl_sasl_create_xoauth2_message() * * This is used to generate an already encoded OAuth 2.0 message ready for * sending to the recipient. @@ -1169,10 +1126,10 @@ void Curl_sasl_ntlm_cleanup(struct ntlmdata *ntlm) * * Returns CURLE_OK on success. */ -static CURLcode sasl_create_xoauth2_message(struct SessionHandle *data, - const char *user, - const char *bearer, - char **outptr, size_t *outlen) +CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data, + const char *user, + const char *bearer, + char **outptr, size_t *outlen) { CURLcode result = CURLE_OK; char *xoauth = NULL; @@ -1185,7 +1142,7 @@ static CURLcode sasl_create_xoauth2_message(struct SessionHandle *data, /* Base64 encode the reply */ result = Curl_base64_encode(data, xoauth, strlen(xoauth), outptr, outlen); - free(xoauth); + Curl_safefree(xoauth); return result; } @@ -1223,447 +1180,3 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused) (void)authused; #endif } - -/* - * Curl_sasl_decode_mech() - * - * Convert a SASL mechanism name into a token. - * - * Parameters: - * - * ptr [in] - The mechanism string. - * maxlen [in] - Maximum mechanism string length. - * len [out] - If not NULL, effective name length. - * - * Returns the SASL mechanism token or 0 if no match. - */ -unsigned int Curl_sasl_decode_mech(const char *ptr, size_t maxlen, size_t *len) -{ - unsigned int i; - char c; - - for(i = 0; mechtable[i].name; i++) { - if(maxlen >= mechtable[i].len && - !memcmp(ptr, mechtable[i].name, mechtable[i].len)) { - if(len) - *len = mechtable[i].len; - - if(maxlen == mechtable[i].len) - return mechtable[i].bit; - - c = ptr[mechtable[i].len]; - if(!ISUPPER(c) && !ISDIGIT(c) && c != '-' && c != '_') - return mechtable[i].bit; - } - } - - return 0; -} - -/* - * Curl_sasl_parse_url_auth_option() - * - * Parse the URL login options. - */ -CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl, - const char *value, size_t len) -{ - CURLcode result = CURLE_OK; - unsigned int mechbit; - size_t mechlen; - - if(!len) - return CURLE_URL_MALFORMAT; - - if(sasl->resetprefs) { - sasl->resetprefs = FALSE; - sasl->prefmech = SASL_AUTH_NONE; - } - - if(strnequal(value, "*", len)) - sasl->prefmech = SASL_AUTH_DEFAULT; - else if((mechbit = Curl_sasl_decode_mech(value, len, &mechlen)) && - mechlen == len) - sasl->prefmech |= mechbit; - else - result = CURLE_URL_MALFORMAT; - - return result; -} - -/* - * Curl_sasl_init() - * - * Initializes the SASL structure. - */ -void Curl_sasl_init(struct SASL *sasl, const struct SASLproto *params) -{ - sasl->params = params; /* Set protocol dependent parameters */ - sasl->state = SASL_STOP; /* Not yet running */ - sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */ - sasl->prefmech = SASL_AUTH_DEFAULT; /* Prefer all mechanisms */ - sasl->authused = SASL_AUTH_NONE; /* No the authentication mechanism used */ - sasl->resetprefs = TRUE; /* Reset prefmech upon AUTH parsing. */ - sasl->mutual_auth = FALSE; /* No mutual authentication (GSSAPI only) */ - sasl->force_ir = FALSE; /* Respect external option */ -} - -/* - * state() - * - * This is the ONLY way to change SASL state! - */ -static void state(struct SASL *sasl, struct connectdata *conn, - saslstate newstate) -{ -#if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS) - /* for debug purposes */ - static const char * const names[]={ - "STOP", - "PLAIN", - "LOGIN", - "LOGIN_PASSWD", - "EXTERNAL", - "CRAMMD5", - "DIGESTMD5", - "DIGESTMD5_RESP", - "NTLM", - "NTLM_TYPE2MSG", - "GSSAPI", - "GSSAPI_TOKEN", - "GSSAPI_NO_DATA", - "XOAUTH2", - "CANCEL", - "FINAL", - /* LAST */ - }; - - if(sasl->state != newstate) - infof(conn->data, "SASL %p state change from %s to %s\n", - (void *)sasl, names[sasl->state], names[newstate]); -#else - (void) conn; -#endif - - sasl->state = newstate; -} - -/* - * Curl_sasl_can_authenticate() - * - * Check if we have enough auth data and capabilities to authenticate. - */ -bool Curl_sasl_can_authenticate(struct SASL *sasl, struct connectdata *conn) -{ - /* Have credentials been provided? */ - if(conn->bits.user_passwd) - return TRUE; - - /* EXTERNAL can authenticate without a user name and/or password */ - if(sasl->authmechs & sasl->prefmech & SASL_MECH_EXTERNAL) - return TRUE; - - return FALSE; -} - -/* - * Curl_sasl_start() - * - * Calculate the required login details for SASL authentication. - */ -CURLcode Curl_sasl_start(struct SASL *sasl, struct connectdata *conn, - bool force_ir, saslprogress *progress) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - unsigned int enabledmechs; - const char *mech = NULL; - char *resp = NULL; - size_t len = 0; - saslstate state1 = SASL_STOP; - saslstate state2 = SASL_FINAL; - - sasl->force_ir = force_ir; /* Latch for future use */ - sasl->authused = 0; /* No mechanism used yet */ - enabledmechs = sasl->authmechs & sasl->prefmech; - *progress = SASL_IDLE; - - /* Calculate the supported authentication mechanism, by decreasing order of - security, as well as the initial response where appropriate */ - if((enabledmechs & SASL_MECH_EXTERNAL) && !conn->passwd[0]) { - mech = SASL_MECH_STRING_EXTERNAL; - state1 = SASL_EXTERNAL; - sasl->authused = SASL_MECH_EXTERNAL; - - if(force_ir || data->set.sasl_ir) - result = sasl_create_external_message(data, conn->user, &resp, &len); - } - else if(conn->bits.user_passwd) { -#if defined(USE_KERBEROS5) - if(enabledmechs & SASL_MECH_GSSAPI) { - sasl->mutual_auth = FALSE; /* TODO: Calculate mutual authentication */ - mech = SASL_MECH_STRING_GSSAPI; - state1 = SASL_GSSAPI; - state2 = SASL_GSSAPI_TOKEN; - sasl->authused = SASL_MECH_GSSAPI; - - if(force_ir || data->set.sasl_ir) - result = Curl_sasl_create_gssapi_user_message(data, conn->user, - conn->passwd, - sasl->params->service, - sasl->mutual_auth, - NULL, &conn->krb5, - &resp, &len); - } - else -#endif -#ifndef CURL_DISABLE_CRYPTO_AUTH - if(enabledmechs & SASL_MECH_DIGEST_MD5) { - mech = SASL_MECH_STRING_DIGEST_MD5; - state1 = SASL_DIGESTMD5; - sasl->authused = SASL_MECH_DIGEST_MD5; - } - else if(enabledmechs & SASL_MECH_CRAM_MD5) { - mech = SASL_MECH_STRING_CRAM_MD5; - state1 = SASL_CRAMMD5; - sasl->authused = SASL_MECH_CRAM_MD5; - } - else -#endif -#ifdef USE_NTLM - if(enabledmechs & SASL_MECH_NTLM) { - mech = SASL_MECH_STRING_NTLM; - state1 = SASL_NTLM; - state2 = SASL_NTLM_TYPE2MSG; - sasl->authused = SASL_MECH_NTLM; - - if(force_ir || data->set.sasl_ir) - result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd, - &conn->ntlm, &resp, &len); - } - else -#endif - if((enabledmechs & SASL_MECH_XOAUTH2) || conn->xoauth2_bearer) { - mech = SASL_MECH_STRING_XOAUTH2; - state1 = SASL_XOAUTH2; - sasl->authused = SASL_MECH_XOAUTH2; - - if(force_ir || data->set.sasl_ir) - result = sasl_create_xoauth2_message(data, conn->user, - conn->xoauth2_bearer, - &resp, &len); - } - else if(enabledmechs & SASL_MECH_LOGIN) { - mech = SASL_MECH_STRING_LOGIN; - state1 = SASL_LOGIN; - state2 = SASL_LOGIN_PASSWD; - sasl->authused = SASL_MECH_LOGIN; - - if(force_ir || data->set.sasl_ir) - result = sasl_create_login_message(data, conn->user, &resp, &len); - } - else if(enabledmechs & SASL_MECH_PLAIN) { - mech = SASL_MECH_STRING_PLAIN; - state1 = SASL_PLAIN; - sasl->authused = SASL_MECH_PLAIN; - - if(force_ir || data->set.sasl_ir) - result = sasl_create_plain_message(data, conn->user, conn->passwd, - &resp, &len); - } - } - - if(!result) { - if(resp && sasl->params->maxirlen && - strlen(mech) + len > sasl->params->maxirlen) { - free(resp); - resp = NULL; - } - - if(mech) { - result = sasl->params->sendauth(conn, mech, resp); - if(!result) { - *progress = SASL_INPROGRESS; - state(sasl, conn, resp? state2: state1); - } - } - } - - free(resp); - - return result; -} - -/* - * Curl_sasl_continue() - * - * Continue the authentication. - */ -CURLcode Curl_sasl_continue(struct SASL *sasl, struct connectdata *conn, - int code, saslprogress *progress) -{ - CURLcode result = CURLE_OK; - struct SessionHandle *data = conn->data; - saslstate newstate = SASL_FINAL; - char *resp = NULL; -#if !defined(CURL_DISABLE_CRYPTO_AUTH) - char *serverdata; - char *chlg = NULL; - size_t chlglen = 0; -#endif - size_t len = 0; - - *progress = SASL_INPROGRESS; - - if(sasl->state == SASL_FINAL) { - if(code != sasl->params->finalcode) - result = CURLE_LOGIN_DENIED; - *progress = SASL_DONE; - state(sasl, conn, SASL_STOP); - return result; - } - - if(sasl->state != SASL_CANCEL && code != sasl->params->contcode) { - *progress = SASL_DONE; - state(sasl, conn, SASL_STOP); - return CURLE_LOGIN_DENIED; - } - - switch(sasl->state) { - case SASL_STOP: - *progress = SASL_DONE; - return result; - case SASL_PLAIN: - result = sasl_create_plain_message(data, conn->user, conn->passwd, &resp, - &len); - break; - case SASL_LOGIN: - result = sasl_create_login_message(data, conn->user, &resp, &len); - newstate = SASL_LOGIN_PASSWD; - break; - case SASL_LOGIN_PASSWD: - result = sasl_create_login_message(data, conn->passwd, &resp, &len); - break; - case SASL_EXTERNAL: - result = sasl_create_external_message(data, conn->user, &resp, &len); - break; - -#ifndef CURL_DISABLE_CRYPTO_AUTH - case SASL_CRAMMD5: - sasl->params->getmessage(data->state.buffer, &serverdata); - result = sasl_decode_cram_md5_message(serverdata, &chlg, &chlglen); - if(!result) - result = sasl_create_cram_md5_message(data, chlg, conn->user, - conn->passwd, &resp, &len); - free(chlg); - break; - case SASL_DIGESTMD5: - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_sasl_create_digest_md5_message(data, serverdata, - conn->user, conn->passwd, - sasl->params->service, - &resp, &len); - newstate = SASL_DIGESTMD5_RESP; - break; - case SASL_DIGESTMD5_RESP: - if(!(resp = strdup(""))) - result = CURLE_OUT_OF_MEMORY; - break; -#endif - -#ifdef USE_NTLM - case SASL_NTLM: - /* Create the type-1 message */ - result = Curl_sasl_create_ntlm_type1_message(conn->user, conn->passwd, - &conn->ntlm, &resp, &len); - newstate = SASL_NTLM_TYPE2MSG; - break; - case SASL_NTLM_TYPE2MSG: - /* Decode the type-2 message */ - sasl->params->getmessage(data->state.buffer, &serverdata); - result = Curl_sasl_decode_ntlm_type2_message(data, serverdata, - &conn->ntlm); - if(!result) - result = Curl_sasl_create_ntlm_type3_message(data, conn->user, - conn->passwd, &conn->ntlm, - &resp, &len); - break; -#endif - -#if defined(USE_KERBEROS5) - case SASL_GSSAPI: - result = Curl_sasl_create_gssapi_user_message(data, conn->user, - conn->passwd, - sasl->params->service, - sasl->mutual_auth, NULL, - &conn->krb5, - &resp, &len); - newstate = SASL_GSSAPI_TOKEN; - break; - case SASL_GSSAPI_TOKEN: - sasl->params->getmessage(data->state.buffer, &serverdata); - if(sasl->mutual_auth) { - /* Decode the user token challenge and create the optional response - message */ - result = Curl_sasl_create_gssapi_user_message(data, NULL, NULL, NULL, - sasl->mutual_auth, - serverdata, &conn->krb5, - &resp, &len); - newstate = SASL_GSSAPI_NO_DATA; - } - else - /* Decode the security challenge and create the response message */ - result = Curl_sasl_create_gssapi_security_message(data, serverdata, - &conn->krb5, - &resp, &len); - break; - case SASL_GSSAPI_NO_DATA: - sasl->params->getmessage(data->state.buffer, &serverdata); - /* Decode the security challenge and create the response message */ - result = Curl_sasl_create_gssapi_security_message(data, serverdata, - &conn->krb5, - &resp, &len); - break; -#endif - - case SASL_XOAUTH2: - /* Create the authorisation message */ - result = sasl_create_xoauth2_message(data, conn->user, - conn->xoauth2_bearer, &resp, &len); - break; - case SASL_CANCEL: - /* Remove the offending mechanism from the supported list */ - sasl->authmechs ^= sasl->authused; - - /* Start an alternative SASL authentication */ - result = Curl_sasl_start(sasl, conn, sasl->force_ir, progress); - newstate = sasl->state; /* Use state from Curl_sasl_start() */ - break; - default: - failf(data, "Unsupported SASL authentication mechanism"); - result = CURLE_UNSUPPORTED_PROTOCOL; /* Should not happen */ - break; - } - - switch(result) { - case CURLE_BAD_CONTENT_ENCODING: - /* Cancel dialog */ - result = sasl->params->sendcont(conn, "*"); - newstate = SASL_CANCEL; - break; - case CURLE_OK: - if(resp) - result = sasl->params->sendcont(conn, resp); - break; - default: - newstate = SASL_STOP; /* Stop on error */ - *progress = SASL_DONE; - break; - } - - free(resp); - - state(sasl, conn, newstate); - - return result; -} |