SASL: common URL option and auth capabilities decoders for all protocols

This commit is contained in:
Patrick Monnerat
2015-01-20 15:27:25 +01:00
parent 5f09cbcdbd
commit e1ea18f90e
7 changed files with 208 additions and 199 deletions

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2012 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2012 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -41,6 +41,7 @@
#include "warnless.h" #include "warnless.h"
#include "curl_memory.h" #include "curl_memory.h"
#include "strtok.h" #include "strtok.h"
#include "strequal.h"
#include "rawstr.h" #include "rawstr.h"
#include "non-ascii.h" /* included for Curl_convert_... prototypes */ #include "non-ascii.h" /* included for Curl_convert_... prototypes */
@@ -73,6 +74,24 @@
return result; \ return result; \
} }
/* 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 }
};
/* /*
* Return 0 on success and then the buffers are filled in fine. * Return 0 on success and then the buffers are filled in fine.
* *
@@ -248,7 +267,7 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
* *
* Parameters: * Parameters:
* *
* serivce [in] - The service type such as www, smtp, pop or imap. * service [in] - The service type such as www, smtp, pop or imap.
* host [in] - The host name or realm. * host [in] - The host name or realm.
* *
* Returns a pointer to the newly allocated SPN. * Returns a pointer to the newly allocated SPN.
@@ -1180,3 +1199,83 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
(void)authused; (void)authused;
#endif #endif
} }
/*
* Curl_sasl_decode_mech()
*
* Convert an SASL mechanism name to a token.
*
* Parameters:
*
* ptr [in] - The mechanism string.
* maxlen [in] - Maximum mechanism string length.
* len [out] - If not NULL, effective name length.
*
* Return 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 llen;
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_ANY;
else if((mechbit = Curl_sasl_decode_mech(value, len, &llen)) &&
llen == len)
sasl->prefmech |= mechbit;
else
result = CURLE_URL_MALFORMAT;
return result;
}
/*
* Curl_sasl_init()
*
* Initializes an SASL structure.
*/
void Curl_sasl_init(struct SASL *sasl)
{
sasl->authmechs = SASL_AUTH_NONE; /* No known authentication mechanism yet */
sasl->prefmech = SASL_AUTH_ANY; /* 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) */
}

View File

@@ -73,6 +73,7 @@ struct SASL {
unsigned int authmechs; /* Accepted authentication mechanisms */ unsigned int authmechs; /* Accepted authentication mechanisms */
unsigned int prefmech; /* Preferred authentication mechanism */ unsigned int prefmech; /* Preferred authentication mechanism */
unsigned int authused; /* Auth mechanism used for the connection */ unsigned int authused; /* Auth mechanism used for the connection */
bool resetprefs; /* For URL auth option parsing. */
bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */ bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
}; };
@@ -201,4 +202,15 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
functions */ functions */
void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused); void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused);
/* Convert a mechanism name to a token */
unsigned int Curl_sasl_decode_mech(const char *ptr,
size_t maxlen, size_t *len);
/* Parse the URL login options */
CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
const char *value, size_t len);
/* Initializes an SASL structure */
void Curl_sasl_init(struct SASL *sasl);
#endif /* HEADER_CURL_SASL_H */ #endif /* HEADER_CURL_SASL_H */

View File

@@ -914,26 +914,16 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
/* Do we have a SASL based authentication mechanism? */ /* Do we have a SASL based authentication mechanism? */
else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) { else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
size_t llen;
unsigned int mechbit;
line += 5; line += 5;
wordlen -= 5; wordlen -= 5;
/* Test the word for a matching authentication mechanism */ /* Test the word for a matching authentication mechanism */
if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN)) if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
imapc->sasl.authmechs |= SASL_MECH_LOGIN; llen == wordlen)
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN)) imapc->sasl.authmechs |= mechbit;
imapc->sasl.authmechs |= SASL_MECH_PLAIN;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
imapc->sasl.authmechs |= SASL_MECH_CRAM_MD5;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
imapc->sasl.authmechs |= SASL_MECH_DIGEST_MD5;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
imapc->sasl.authmechs |= SASL_MECH_GSSAPI;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
imapc->sasl.authmechs |= SASL_MECH_EXTERNAL;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
imapc->sasl.authmechs |= SASL_MECH_NTLM;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
imapc->sasl.authmechs |= SASL_MECH_XOAUTH2;
} }
line += wordlen; line += wordlen;
@@ -2061,7 +2051,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
/* Set the default preferred authentication type and mechanism */ /* Set the default preferred authentication type and mechanism */
imapc->preftype = IMAP_TYPE_ANY; imapc->preftype = IMAP_TYPE_ANY;
imapc->sasl.prefmech = SASL_AUTH_ANY; Curl_sasl_init(&imapc->sasl);
/* Initialise the pingpong layer */ /* Initialise the pingpong layer */
Curl_pp_init(pp); Curl_pp_init(pp);
@@ -2548,69 +2538,42 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc; struct imap_conn *imapc = &conn->proto.imapc;
const char *options = conn->options; const char *ptr = conn->options;
const char *ptr = options;
bool reset = TRUE;
while(ptr && *ptr) { imapc->sasl.resetprefs = TRUE;
while(!result && ptr && *ptr) {
const char *key = ptr; const char *key = ptr;
const char *value;
while(*ptr && *ptr != '=') while(*ptr && *ptr != '=')
ptr++; ptr++;
if(strnequal(key, "AUTH", 4)) { value = ptr + 1;
size_t len = 0;
const char *value = ++ptr;
if(reset) { while(*ptr && *ptr != ';')
reset = FALSE;
imapc->preftype = IMAP_TYPE_NONE;
imapc->sasl.prefmech = SASL_AUTH_NONE;
}
while(*ptr && *ptr != ';') {
ptr++; ptr++;
len++;
}
if(strnequal(value, "*", len)) { if(strnequal(key, "AUTH=", 5))
imapc->preftype = IMAP_TYPE_ANY; result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
imapc->sasl.prefmech = SASL_AUTH_ANY; value, ptr - value);
} else
else if(strnequal(value, SASL_MECH_STRING_LOGIN, len)) { result = CURLE_URL_MALFORMAT;
imapc->preftype = IMAP_TYPE_SASL;
imapc->sasl.prefmech |= SASL_MECH_LOGIN;
}
else if(strnequal(value, SASL_MECH_STRING_PLAIN, len)) {
imapc->preftype = IMAP_TYPE_SASL;
imapc->sasl.prefmech |= SASL_MECH_PLAIN;
}
else if(strnequal(value, SASL_MECH_STRING_CRAM_MD5, len)) {
imapc->preftype = IMAP_TYPE_SASL;
imapc->sasl.prefmech |= SASL_MECH_CRAM_MD5;
}
else if(strnequal(value, SASL_MECH_STRING_DIGEST_MD5, len)) {
imapc->preftype = IMAP_TYPE_SASL;
imapc->sasl.prefmech |= SASL_MECH_DIGEST_MD5;
}
else if(strnequal(value, SASL_MECH_STRING_GSSAPI, len)) {
imapc->preftype = IMAP_TYPE_SASL;
imapc->sasl.prefmech |= SASL_MECH_GSSAPI;
}
else if(strnequal(value, SASL_MECH_STRING_NTLM, len)) {
imapc->preftype = IMAP_TYPE_SASL;
imapc->sasl.prefmech |= SASL_MECH_NTLM;
}
else if(strnequal(value, SASL_MECH_STRING_XOAUTH2, len)) {
imapc->preftype = IMAP_TYPE_SASL;
imapc->sasl.prefmech |= SASL_MECH_XOAUTH2;
}
if(*ptr == ';') if(*ptr == ';')
ptr++; ptr++;
} }
else
result = CURLE_URL_MALFORMAT; switch(imapc->sasl.prefmech) {
case SASL_AUTH_NONE:
imapc->preftype = IMAP_TYPE_NONE;
break;
case SASL_AUTH_ANY:
imapc->preftype = IMAP_TYPE_ANY;
break;
default:
imapc->preftype = IMAP_TYPE_SASL;
break;
} }
return result; return result;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -726,6 +726,9 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
/* Loop through the data line */ /* Loop through the data line */
for(;;) { for(;;) {
size_t llen;
unsigned int mechbit;
while(len && while(len &&
(*line == ' ' || *line == '\t' || (*line == ' ' || *line == '\t' ||
*line == '\r' || *line == '\n')) { *line == '\r' || *line == '\n')) {
@@ -744,22 +747,9 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
wordlen++; wordlen++;
/* Test the word for a matching authentication mechanism */ /* Test the word for a matching authentication mechanism */
if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN)) if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
pop3c->sasl.authmechs |= SASL_MECH_LOGIN; llen == wordlen)
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN)) pop3c->sasl.authmechs |= mechbit;
pop3c->sasl.authmechs |= SASL_MECH_PLAIN;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
pop3c->sasl.authmechs |= SASL_MECH_CRAM_MD5;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
pop3c->sasl.authmechs |= SASL_MECH_DIGEST_MD5;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
pop3c->sasl.authmechs |= SASL_MECH_GSSAPI;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
pop3c->sasl.authmechs |= SASL_MECH_EXTERNAL;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
pop3c->sasl.authmechs |= SASL_MECH_NTLM;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
pop3c->sasl.authmechs |= SASL_MECH_XOAUTH2;
line += wordlen; line += wordlen;
len -= wordlen; len -= wordlen;
@@ -1727,7 +1717,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
/* Set the default preferred authentication type and mechanism */ /* Set the default preferred authentication type and mechanism */
pop3c->preftype = POP3_TYPE_ANY; pop3c->preftype = POP3_TYPE_ANY;
pop3c->sasl.prefmech = SASL_AUTH_ANY; Curl_sasl_init(&pop3c->sasl);
/* Initialise the pingpong layer */ /* Initialise the pingpong layer */
Curl_pp_init(pp); Curl_pp_init(pp);
@@ -1994,73 +1984,50 @@ static CURLcode pop3_parse_url_options(struct connectdata *conn)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c; struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *options = conn->options; const char *ptr = conn->options;
const char *ptr = options;
bool reset = TRUE;
while(ptr && *ptr) { pop3c->sasl.resetprefs = TRUE;
while(!result && ptr && *ptr) {
const char *key = ptr; const char *key = ptr;
const char *value;
while(*ptr && *ptr != '=') while(*ptr && *ptr != '=')
ptr++; ptr++;
if(strnequal(key, "AUTH", 4)) { value = ptr + 1;
size_t len = 0;
const char *value = ++ptr;
if(reset) { while(*ptr && *ptr != ';')
reset = FALSE;
pop3c->preftype = POP3_TYPE_NONE;
pop3c->sasl.prefmech = SASL_AUTH_NONE;
}
while(*ptr && *ptr != ';') {
ptr++; ptr++;
len++;
}
if(strnequal(value, "*", len)) { if(strnequal(key, "AUTH=", 5)) {
pop3c->preftype = POP3_TYPE_ANY; result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
pop3c->sasl.prefmech = SASL_AUTH_ANY; value, ptr - value);
}
else if(strnequal(value, "+APOP", len)) { if(result && strnequal(value, "+APOP", ptr - value)) {
pop3c->preftype = POP3_TYPE_APOP; pop3c->preftype = POP3_TYPE_APOP;
pop3c->sasl.prefmech = SASL_AUTH_NONE; pop3c->sasl.prefmech = SASL_AUTH_NONE;
result = CURLE_OK;
} }
else if(strnequal(value, SASL_MECH_STRING_LOGIN, len)) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->sasl.prefmech |= SASL_MECH_LOGIN;
}
else if(strnequal(value, SASL_MECH_STRING_PLAIN, len)) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->sasl.prefmech |= SASL_MECH_PLAIN;
}
else if(strnequal(value, SASL_MECH_STRING_CRAM_MD5, len)) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->sasl.prefmech |= SASL_MECH_CRAM_MD5;
}
else if(strnequal(value, SASL_MECH_STRING_DIGEST_MD5, len)) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->sasl.prefmech |= SASL_MECH_DIGEST_MD5;
}
else if(strnequal(value, SASL_MECH_STRING_GSSAPI, len)) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->sasl.prefmech |= SASL_MECH_GSSAPI;
}
else if(strnequal(value, SASL_MECH_STRING_NTLM, len)) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->sasl.prefmech |= SASL_MECH_NTLM;
}
else if(strnequal(value, SASL_MECH_STRING_XOAUTH2, len)) {
pop3c->preftype = POP3_TYPE_SASL;
pop3c->sasl.prefmech |= SASL_MECH_XOAUTH2;
} }
else
result = CURLE_URL_MALFORMAT;
if(*ptr == ';') if(*ptr == ';')
ptr++; ptr++;
} }
else
result = CURLE_URL_MALFORMAT; if(pop3c->preftype != POP3_TYPE_APOP)
switch(pop3c->sasl.prefmech) {
case SASL_AUTH_NONE:
pop3c->preftype = POP3_TYPE_NONE;
break;
case SASL_AUTH_ANY:
pop3c->preftype = POP3_TYPE_ANY;
break;
default:
pop3c->preftype = POP3_TYPE_SASL;
break;
} }
return result; return result;

View File

@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 2009 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 2009 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms

View File

@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____| * \___|\___/|_| \_\_____|
* *
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al. * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
* *
* This software is licensed as described in the file COPYING, which * This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms * you should have received as part of this distribution. The terms
@@ -753,6 +753,9 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
/* Loop through the data line */ /* Loop through the data line */
for(;;) { for(;;) {
size_t llen;
unsigned int mechbit;
while(len && while(len &&
(*line == ' ' || *line == '\t' || (*line == ' ' || *line == '\t' ||
*line == '\r' || *line == '\n')) { *line == '\r' || *line == '\n')) {
@@ -771,22 +774,9 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
wordlen++; wordlen++;
/* Test the word for a matching authentication mechanism */ /* Test the word for a matching authentication mechanism */
if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN)) if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
smtpc->sasl.authmechs |= SASL_MECH_LOGIN; llen == wordlen)
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN)) smtpc->sasl.authmechs |= mechbit;
smtpc->sasl.authmechs |= SASL_MECH_PLAIN;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
smtpc->sasl.authmechs |= SASL_MECH_CRAM_MD5;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
smtpc->sasl.authmechs |= SASL_MECH_DIGEST_MD5;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
smtpc->sasl.authmechs |= SASL_MECH_GSSAPI;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
smtpc->sasl.authmechs |= SASL_MECH_EXTERNAL;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
smtpc->sasl.authmechs |= SASL_MECH_NTLM;
else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
smtpc->sasl.authmechs |= SASL_MECH_XOAUTH2;
line += wordlen; line += wordlen;
len -= wordlen; len -= wordlen;
@@ -1767,8 +1757,8 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done)
pp->endofresp = smtp_endofresp; pp->endofresp = smtp_endofresp;
pp->conn = conn; pp->conn = conn;
/* Set the default preferred authentication mechanism */ /* Initialize the SASL storage */
smtpc->sasl.prefmech = SASL_AUTH_ANY; Curl_sasl_init(&smtpc->sasl);
/* Initialise the pingpong layer */ /* Initialise the pingpong layer */
Curl_pp_init(pp); Curl_pp_init(pp);
@@ -2107,53 +2097,31 @@ static CURLcode smtp_parse_url_options(struct connectdata *conn)
{ {
CURLcode result = CURLE_OK; CURLcode result = CURLE_OK;
struct smtp_conn *smtpc = &conn->proto.smtpc; struct smtp_conn *smtpc = &conn->proto.smtpc;
const char *options = conn->options; const char *ptr = conn->options;
const char *ptr = options;
bool reset = TRUE;
while(ptr && *ptr) { smtpc->sasl.resetprefs = TRUE;
while(!result && ptr && *ptr) {
const char *key = ptr; const char *key = ptr;
const char *value;
while(*ptr && *ptr != '=') while(*ptr && *ptr != '=')
ptr++; ptr++;
if(strnequal(key, "AUTH", 4)) { value = ptr + 1;
size_t len = 0;
const char *value = ++ptr;
if(reset) { while(*ptr && *ptr != ';')
reset = FALSE;
smtpc->sasl.prefmech = SASL_AUTH_NONE;
}
while(*ptr && *ptr != ';') {
ptr++; ptr++;
len++;
}
if(strnequal(value, "*", len)) if(strnequal(key, "AUTH=", 5))
smtpc->sasl.prefmech = SASL_AUTH_ANY; result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
else if(strnequal(value, SASL_MECH_STRING_LOGIN, len)) value, ptr - value);
smtpc->sasl.prefmech |= SASL_MECH_LOGIN; else
else if(strnequal(value, SASL_MECH_STRING_PLAIN, len)) result = CURLE_URL_MALFORMAT;
smtpc->sasl.prefmech |= SASL_MECH_PLAIN;
else if(strnequal(value, SASL_MECH_STRING_CRAM_MD5, len))
smtpc->sasl.prefmech |= SASL_MECH_CRAM_MD5;
else if(strnequal(value, SASL_MECH_STRING_DIGEST_MD5, len))
smtpc->sasl.prefmech |= SASL_MECH_DIGEST_MD5;
else if(strnequal(value, SASL_MECH_STRING_GSSAPI, len))
smtpc->sasl.prefmech |= SASL_MECH_GSSAPI;
else if(strnequal(value, SASL_MECH_STRING_NTLM, len))
smtpc->sasl.prefmech |= SASL_MECH_NTLM;
else if(strnequal(value, SASL_MECH_STRING_XOAUTH2, len))
smtpc->sasl.prefmech |= SASL_MECH_XOAUTH2;
if(*ptr == ';') if(*ptr == ';')
ptr++; ptr++;
} }
else
result = CURLE_URL_MALFORMAT;
}
return result; return result;
} }