aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPatrick Monnerat <pm@datasphere.ch>2015-01-20 15:27:25 +0100
committerPatrick Monnerat <pm@datasphere.ch>2015-01-20 15:27:25 +0100
commite1ea18f90e93d50fc999c46c53685fbdd9508659 (patch)
treebd269f8ebae1d7f5fc1d127c73e7d194d6a9de6e /lib
parent5f09cbcdbd0e0ac4e44a32d06122b5e58d575679 (diff)
SASL: common URL option and auth capabilities decoders for all protocols
Diffstat (limited to 'lib')
-rw-r--r--lib/curl_sasl.c103
-rw-r--r--lib/curl_sasl.h12
-rw-r--r--lib/imap.c103
-rw-r--r--lib/imap.h2
-rw-r--r--lib/pop3.c107
-rw-r--r--lib/pop3.h2
-rw-r--r--lib/smtp.c78
7 files changed, 208 insertions, 199 deletions
diff --git a/lib/curl_sasl.c b/lib/curl_sasl.c
index b944aa2df..7cb575b33 100644
--- a/lib/curl_sasl.c
+++ b/lib/curl_sasl.c
@@ -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
* you should have received as part of this distribution. The terms
@@ -41,6 +41,7 @@
#include "warnless.h"
#include "curl_memory.h"
#include "strtok.h"
+#include "strequal.h"
#include "rawstr.h"
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
@@ -73,6 +74,24 @@
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.
*
@@ -248,7 +267,7 @@ static CURLcode sasl_digest_get_qop_values(const char *options, int *value)
*
* 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.
*
* Returns a pointer to the newly allocated SPN.
@@ -1180,3 +1199,83 @@ void Curl_sasl_cleanup(struct connectdata *conn, unsigned int authused)
(void)authused;
#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) */
+}
diff --git a/lib/curl_sasl.h b/lib/curl_sasl.h
index a83a326a4..e043449db 100644
--- a/lib/curl_sasl.h
+++ b/lib/curl_sasl.h
@@ -73,6 +73,7 @@ struct SASL {
unsigned int authmechs; /* Accepted authentication mechanisms */
unsigned int prefmech; /* Preferred authentication mechanism */
unsigned int authused; /* Auth mechanism used for the connection */
+ bool resetprefs; /* For URL auth option parsing. */
bool mutual_auth; /* Mutual authentication enabled (GSSAPI only) */
};
@@ -201,4 +202,15 @@ CURLcode Curl_sasl_create_xoauth2_message(struct SessionHandle *data,
functions */
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 */
diff --git a/lib/imap.c b/lib/imap.c
index 4087fa66a..965efdf8a 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -914,26 +914,16 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
/* Do we have a SASL based authentication mechanism? */
else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
+ size_t llen;
+ unsigned int mechbit;
+
line += 5;
wordlen -= 5;
/* Test the word for a matching authentication mechanism */
- if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
- imapc->sasl.authmechs |= SASL_MECH_LOGIN;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
- 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;
+ if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+ llen == wordlen)
+ imapc->sasl.authmechs |= mechbit;
}
line += wordlen;
@@ -2061,7 +2051,7 @@ static CURLcode imap_connect(struct connectdata *conn, bool *done)
/* Set the default preferred authentication type and mechanism */
imapc->preftype = IMAP_TYPE_ANY;
- imapc->sasl.prefmech = SASL_AUTH_ANY;
+ Curl_sasl_init(&imapc->sasl);
/* Initialise the pingpong layer */
Curl_pp_init(pp);
@@ -2548,69 +2538,42 @@ static CURLcode imap_parse_url_options(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct imap_conn *imapc = &conn->proto.imapc;
- const char *options = conn->options;
- const char *ptr = options;
- bool reset = TRUE;
+ const char *ptr = conn->options;
+
+ imapc->sasl.resetprefs = TRUE;
- while(ptr && *ptr) {
+ while(!result && ptr && *ptr) {
const char *key = ptr;
+ const char *value;
while(*ptr && *ptr != '=')
ptr++;
- if(strnequal(key, "AUTH", 4)) {
- size_t len = 0;
- const char *value = ++ptr;
-
- if(reset) {
- reset = FALSE;
- imapc->preftype = IMAP_TYPE_NONE;
- imapc->sasl.prefmech = SASL_AUTH_NONE;
- }
+ value = ptr + 1;
- while(*ptr && *ptr != ';') {
- ptr++;
- len++;
- }
-
- if(strnequal(value, "*", len)) {
- imapc->preftype = IMAP_TYPE_ANY;
- imapc->sasl.prefmech = SASL_AUTH_ANY;
- }
- else if(strnequal(value, SASL_MECH_STRING_LOGIN, len)) {
- 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;
- }
+ while(*ptr && *ptr != ';')
+ ptr++;
- if(*ptr == ';')
- ptr++;
- }
+ if(strnequal(key, "AUTH=", 5))
+ result = Curl_sasl_parse_url_auth_option(&imapc->sasl,
+ value, ptr - value);
else
result = CURLE_URL_MALFORMAT;
+
+ if(*ptr == ';')
+ ptr++;
+ }
+
+ 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;
diff --git a/lib/imap.h b/lib/imap.h
index 81af6a290..22e6ada1c 100644
--- a/lib/imap.h
+++ b/lib/imap.h
@@ -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
* you should have received as part of this distribution. The terms
diff --git a/lib/pop3.c b/lib/pop3.c
index f40c9218b..f5828e515 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -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
* 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 */
for(;;) {
+ size_t llen;
+ unsigned int mechbit;
+
while(len &&
(*line == ' ' || *line == '\t' ||
*line == '\r' || *line == '\n')) {
@@ -744,22 +747,9 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
wordlen++;
/* Test the word for a matching authentication mechanism */
- if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
- pop3c->sasl.authmechs |= SASL_MECH_LOGIN;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
- 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;
+ if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+ llen == wordlen)
+ pop3c->sasl.authmechs |= mechbit;
line += wordlen;
len -= wordlen;
@@ -1727,7 +1717,7 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
/* Set the default preferred authentication type and mechanism */
pop3c->preftype = POP3_TYPE_ANY;
- pop3c->sasl.prefmech = SASL_AUTH_ANY;
+ Curl_sasl_init(&pop3c->sasl);
/* Initialise the pingpong layer */
Curl_pp_init(pp);
@@ -1994,75 +1984,52 @@ static CURLcode pop3_parse_url_options(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct pop3_conn *pop3c = &conn->proto.pop3c;
- const char *options = conn->options;
- const char *ptr = options;
- bool reset = TRUE;
+ const char *ptr = conn->options;
+
+ pop3c->sasl.resetprefs = TRUE;
- while(ptr && *ptr) {
+ while(!result && ptr && *ptr) {
const char *key = ptr;
+ const char *value;
while(*ptr && *ptr != '=')
ptr++;
- if(strnequal(key, "AUTH", 4)) {
- size_t len = 0;
- const char *value = ++ptr;
+ value = ptr + 1;
- if(reset) {
- reset = FALSE;
- pop3c->preftype = POP3_TYPE_NONE;
- pop3c->sasl.prefmech = SASL_AUTH_NONE;
- }
+ while(*ptr && *ptr != ';')
+ ptr++;
- while(*ptr && *ptr != ';') {
- ptr++;
- len++;
- }
+ if(strnequal(key, "AUTH=", 5)) {
+ result = Curl_sasl_parse_url_auth_option(&pop3c->sasl,
+ value, ptr - value);
- if(strnequal(value, "*", len)) {
- pop3c->preftype = POP3_TYPE_ANY;
- pop3c->sasl.prefmech = SASL_AUTH_ANY;
- }
- else if(strnequal(value, "+APOP", len)) {
+ if(result && strnequal(value, "+APOP", ptr - value)) {
pop3c->preftype = POP3_TYPE_APOP;
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;
- }
-
- if(*ptr == ';')
- ptr++;
}
else
result = CURLE_URL_MALFORMAT;
+
+ if(*ptr == ';')
+ ptr++;
}
+ 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;
}
diff --git a/lib/pop3.h b/lib/pop3.h
index 7b4d21f03..0cb5852d8 100644
--- a/lib/pop3.h
+++ b/lib/pop3.h
@@ -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
* you should have received as part of this distribution. The terms
diff --git a/lib/smtp.c b/lib/smtp.c
index 5f75f524b..e5ddedb02 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -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
* 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 */
for(;;) {
+ size_t llen;
+ unsigned int mechbit;
+
while(len &&
(*line == ' ' || *line == '\t' ||
*line == '\r' || *line == '\n')) {
@@ -771,22 +774,9 @@ static CURLcode smtp_state_ehlo_resp(struct connectdata *conn, int smtpcode,
wordlen++;
/* Test the word for a matching authentication mechanism */
- if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
- smtpc->sasl.authmechs |= SASL_MECH_LOGIN;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
- 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;
+ if((mechbit = Curl_sasl_decode_mech(line, wordlen, &llen)) &&
+ llen == wordlen)
+ smtpc->sasl.authmechs |= mechbit;
line += wordlen;
len -= wordlen;
@@ -1767,8 +1757,8 @@ static CURLcode smtp_connect(struct connectdata *conn, bool *done)
pp->endofresp = smtp_endofresp;
pp->conn = conn;
- /* Set the default preferred authentication mechanism */
- smtpc->sasl.prefmech = SASL_AUTH_ANY;
+ /* Initialize the SASL storage */
+ Curl_sasl_init(&smtpc->sasl);
/* Initialise the pingpong layer */
Curl_pp_init(pp);
@@ -2107,52 +2097,30 @@ static CURLcode smtp_parse_url_options(struct connectdata *conn)
{
CURLcode result = CURLE_OK;
struct smtp_conn *smtpc = &conn->proto.smtpc;
- const char *options = conn->options;
- const char *ptr = options;
- bool reset = TRUE;
+ const char *ptr = conn->options;
+
+ smtpc->sasl.resetprefs = TRUE;
- while(ptr && *ptr) {
+ while(!result && ptr && *ptr) {
const char *key = ptr;
+ const char *value;
while(*ptr && *ptr != '=')
ptr++;
- if(strnequal(key, "AUTH", 4)) {
- size_t len = 0;
- const char *value = ++ptr;
+ value = ptr + 1;
- if(reset) {
- reset = FALSE;
- smtpc->sasl.prefmech = SASL_AUTH_NONE;
- }
+ while(*ptr && *ptr != ';')
+ ptr++;
- while(*ptr && *ptr != ';') {
- ptr++;
- len++;
- }
-
- if(strnequal(value, "*", len))
- smtpc->sasl.prefmech = SASL_AUTH_ANY;
- else if(strnequal(value, SASL_MECH_STRING_LOGIN, len))
- smtpc->sasl.prefmech |= SASL_MECH_LOGIN;
- else if(strnequal(value, SASL_MECH_STRING_PLAIN, len))
- 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 == ';')
- ptr++;
- }
+ if(strnequal(key, "AUTH=", 5))
+ result = Curl_sasl_parse_url_auth_option(&smtpc->sasl,
+ value, ptr - value);
else
result = CURLE_URL_MALFORMAT;
+
+ if(*ptr == ';')
+ ptr++;
}
return result;