SASL: common URL option and auth capabilities decoders for all protocols
This commit is contained in:
103
lib/curl_sasl.c
103
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
|
* 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) */
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
97
lib/imap.c
97
lib/imap.c
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
103
lib/pop3.c
103
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
|
* 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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
74
lib/smtp.c
74
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
|
* 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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user