pop3: Added support for ;auth=<mech> in the URL
Added support for specifying the preferred authentication type and SASL mechanism in the URL as per RFC-2384.
This commit is contained in:
Родитель
00045a3009
Коммит
b3a01be2f3
99
lib/pop3.c
99
lib/pop3.c
|
@ -101,6 +101,7 @@ static int pop3_getsock(struct connectdata *conn, curl_socket_t *socks,
|
||||||
int numsocks);
|
int numsocks);
|
||||||
static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
|
static CURLcode pop3_doing(struct connectdata *conn, bool *dophase_done);
|
||||||
static CURLcode pop3_setup_connection(struct connectdata *conn);
|
static CURLcode pop3_setup_connection(struct connectdata *conn);
|
||||||
|
static CURLcode pop3_parse_url_options(struct connectdata *conn);
|
||||||
static CURLcode pop3_parse_url_path(struct connectdata *conn);
|
static CURLcode pop3_parse_url_path(struct connectdata *conn);
|
||||||
static CURLcode pop3_parse_custom_request(struct connectdata *conn);
|
static CURLcode pop3_parse_custom_request(struct connectdata *conn);
|
||||||
|
|
||||||
|
@ -514,12 +515,14 @@ static CURLcode pop3_authenticate(struct connectdata *conn)
|
||||||
security */
|
security */
|
||||||
if(pop3c->authtypes & POP3_TYPE_SASL) {
|
if(pop3c->authtypes & POP3_TYPE_SASL) {
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
if(pop3c->authmechs & SASL_MECH_DIGEST_MD5) {
|
if((pop3c->authmechs & SASL_MECH_DIGEST_MD5) &&
|
||||||
|
(pop3c->prefmech & SASL_MECH_DIGEST_MD5)) {
|
||||||
mech = "DIGEST-MD5";
|
mech = "DIGEST-MD5";
|
||||||
authstate = POP3_AUTH_DIGESTMD5;
|
authstate = POP3_AUTH_DIGESTMD5;
|
||||||
pop3c->authused = SASL_MECH_DIGEST_MD5;
|
pop3c->authused = SASL_MECH_DIGEST_MD5;
|
||||||
}
|
}
|
||||||
else if(pop3c->authmechs & SASL_MECH_CRAM_MD5) {
|
else if((pop3c->authmechs & SASL_MECH_CRAM_MD5) &&
|
||||||
|
(pop3c->prefmech & SASL_MECH_CRAM_MD5)) {
|
||||||
mech = "CRAM-MD5";
|
mech = "CRAM-MD5";
|
||||||
authstate = POP3_AUTH_CRAMMD5;
|
authstate = POP3_AUTH_CRAMMD5;
|
||||||
pop3c->authused = SASL_MECH_CRAM_MD5;
|
pop3c->authused = SASL_MECH_CRAM_MD5;
|
||||||
|
@ -527,26 +530,29 @@ static CURLcode pop3_authenticate(struct connectdata *conn)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_NTLM
|
#ifdef USE_NTLM
|
||||||
if(pop3c->authmechs & SASL_MECH_NTLM) {
|
if((pop3c->authmechs & SASL_MECH_NTLM) &&
|
||||||
|
(pop3c->prefmech & SASL_MECH_NTLM)) {
|
||||||
mech = "NTLM";
|
mech = "NTLM";
|
||||||
authstate = POP3_AUTH_NTLM;
|
authstate = POP3_AUTH_NTLM;
|
||||||
pop3c->authused = SASL_MECH_NTLM;
|
pop3c->authused = SASL_MECH_NTLM;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if(pop3c->authmechs & SASL_MECH_LOGIN) {
|
if((pop3c->authmechs & SASL_MECH_LOGIN) &&
|
||||||
|
(pop3c->prefmech & SASL_MECH_LOGIN)) {
|
||||||
mech = "LOGIN";
|
mech = "LOGIN";
|
||||||
authstate = POP3_AUTH_LOGIN;
|
authstate = POP3_AUTH_LOGIN;
|
||||||
pop3c->authused = SASL_MECH_LOGIN;
|
pop3c->authused = SASL_MECH_LOGIN;
|
||||||
}
|
}
|
||||||
else if(pop3c->authmechs & SASL_MECH_PLAIN) {
|
else if((pop3c->authmechs & SASL_MECH_PLAIN) &&
|
||||||
|
(pop3c->prefmech & SASL_MECH_PLAIN)) {
|
||||||
mech = "PLAIN";
|
mech = "PLAIN";
|
||||||
authstate = POP3_AUTH_PLAIN;
|
authstate = POP3_AUTH_PLAIN;
|
||||||
pop3c->authused = SASL_MECH_PLAIN;
|
pop3c->authused = SASL_MECH_PLAIN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mech) {
|
if(mech && (pop3c->preftype & POP3_TYPE_SASL)) {
|
||||||
/* Perform SASL based authentication */
|
/* Perform SASL based authentication */
|
||||||
result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
|
result = Curl_pp_sendf(&pop3c->pp, "AUTH %s", mech);
|
||||||
|
|
||||||
|
@ -554,11 +560,13 @@ static CURLcode pop3_authenticate(struct connectdata *conn)
|
||||||
state(conn, authstate);
|
state(conn, authstate);
|
||||||
}
|
}
|
||||||
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
#ifndef CURL_DISABLE_CRYPTO_AUTH
|
||||||
else if(pop3c->authtypes & POP3_TYPE_APOP)
|
else if((pop3c->authtypes & POP3_TYPE_APOP) &&
|
||||||
|
(pop3c->preftype & POP3_TYPE_APOP))
|
||||||
/* Perform APOP authentication */
|
/* Perform APOP authentication */
|
||||||
result = pop3_state_apop(conn);
|
result = pop3_state_apop(conn);
|
||||||
#endif
|
#endif
|
||||||
else if(pop3c->authtypes & POP3_TYPE_CLEARTEXT)
|
else if((pop3c->authtypes & POP3_TYPE_CLEARTEXT) &&
|
||||||
|
(pop3c->preftype & POP3_TYPE_CLEARTEXT))
|
||||||
/* Perform clear text authentication */
|
/* Perform clear text authentication */
|
||||||
result = pop3_state_user(conn);
|
result = pop3_state_user(conn);
|
||||||
else {
|
else {
|
||||||
|
@ -1332,9 +1340,18 @@ static CURLcode pop3_connect(struct connectdata *conn, bool *done)
|
||||||
pp->endofresp = pop3_endofresp;
|
pp->endofresp = pop3_endofresp;
|
||||||
pp->conn = conn;
|
pp->conn = conn;
|
||||||
|
|
||||||
|
/* Set the default preferred authentication type and mechanism */
|
||||||
|
pop3c->preftype = POP3_TYPE_ANY;
|
||||||
|
pop3c->prefmech = SASL_AUTH_ANY;
|
||||||
|
|
||||||
/* Initialise the pingpong layer */
|
/* Initialise the pingpong layer */
|
||||||
Curl_pp_init(pp);
|
Curl_pp_init(pp);
|
||||||
|
|
||||||
|
/* Parse the URL options */
|
||||||
|
result = pop3_parse_url_options(conn);
|
||||||
|
if(result)
|
||||||
|
return result;
|
||||||
|
|
||||||
/* Start off waiting for the server greeting response */
|
/* Start off waiting for the server greeting response */
|
||||||
state(conn, POP3_SERVERGREET);
|
state(conn, POP3_SERVERGREET);
|
||||||
|
|
||||||
|
@ -1608,6 +1625,72 @@ static CURLcode pop3_setup_connection(struct connectdata *conn)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
*
|
||||||
|
* pop3_parse_url_options()
|
||||||
|
*
|
||||||
|
* Parse the URL login options.
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
if(options) {
|
||||||
|
const char *key = ptr;
|
||||||
|
|
||||||
|
while(*ptr && *ptr != '=')
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
if(strnequal(key, "AUTH", 4)) {
|
||||||
|
const char *value = ptr + 1;
|
||||||
|
|
||||||
|
if(strequal(value, "*")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_ANY;
|
||||||
|
pop3c->prefmech = SASL_AUTH_ANY;
|
||||||
|
}
|
||||||
|
else if(strequal(value, "+APOP")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_APOP;
|
||||||
|
pop3c->prefmech = SASL_AUTH_NONE;
|
||||||
|
}
|
||||||
|
else if(strequal(value, "LOGIN")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_SASL;
|
||||||
|
pop3c->prefmech = SASL_MECH_LOGIN;
|
||||||
|
}
|
||||||
|
else if(strequal(value, "PLAIN")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_SASL;
|
||||||
|
pop3c->prefmech = SASL_MECH_PLAIN;
|
||||||
|
}
|
||||||
|
else if(strequal(value, "CRAM-MD5")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_SASL;
|
||||||
|
pop3c->prefmech = SASL_MECH_CRAM_MD5;
|
||||||
|
}
|
||||||
|
else if(strequal(value, "DIGEST-MD5")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_SASL;
|
||||||
|
pop3c->prefmech = SASL_MECH_DIGEST_MD5;
|
||||||
|
}
|
||||||
|
else if(strequal(value, "GSSAPI")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_SASL;
|
||||||
|
pop3c->prefmech = SASL_MECH_GSSAPI;
|
||||||
|
}
|
||||||
|
else if(strequal(value, "NTLM")) {
|
||||||
|
pop3c->preftype = POP3_TYPE_SASL;
|
||||||
|
pop3c->prefmech = SASL_MECH_NTLM;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pop3c->preftype = POP3_TYPE_NONE;
|
||||||
|
pop3c->prefmech = SASL_AUTH_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = CURLE_URL_MALFORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* pop3_parse_url_path()
|
* pop3_parse_url_path()
|
||||||
|
|
|
@ -74,6 +74,8 @@ struct pop3_conn {
|
||||||
non-body */
|
non-body */
|
||||||
unsigned int authtypes; /* Supported authentication types */
|
unsigned int authtypes; /* Supported authentication types */
|
||||||
unsigned int authmechs; /* Accepted SASL authentication mechanisms */
|
unsigned int authmechs; /* Accepted SASL authentication mechanisms */
|
||||||
|
unsigned int preftype; /* Preferred authentication type */
|
||||||
|
unsigned int prefmech; /* Preferred SASL authentication mechanism */
|
||||||
unsigned int authused; /* SASL auth mechanism used for the connection */
|
unsigned int authused; /* SASL auth mechanism used for the connection */
|
||||||
char *apoptimestamp; /* APOP timestamp from the server greeting */
|
char *apoptimestamp; /* APOP timestamp from the server greeting */
|
||||||
bool tls_supported; /* StartTLS capability supported by server */
|
bool tls_supported; /* StartTLS capability supported by server */
|
||||||
|
@ -87,6 +89,10 @@ extern const struct Curl_handler Curl_handler_pop3s;
|
||||||
#define POP3_TYPE_APOP 0x0002
|
#define POP3_TYPE_APOP 0x0002
|
||||||
#define POP3_TYPE_SASL 0x0004
|
#define POP3_TYPE_SASL 0x0004
|
||||||
|
|
||||||
|
/* Authentication type values */
|
||||||
|
#define POP3_TYPE_NONE 0
|
||||||
|
#define POP3_TYPE_ANY ~0
|
||||||
|
|
||||||
/* This is the 5-bytes End-Of-Body marker for POP3 */
|
/* This is the 5-bytes End-Of-Body marker for POP3 */
|
||||||
#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
|
#define POP3_EOB "\x0d\x0a\x2e\x0d\x0a"
|
||||||
#define POP3_EOB_LEN 5
|
#define POP3_EOB_LEN 5
|
||||||
|
|
Загрузка…
Ссылка в новой задаче