* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 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
pop3_disconnect, /* disconnect */
ZERO_NULL, /* readwrite */
PORT_POP3S, /* defport */
- CURLPROTO_POP3 | CURLPROTO_POP3S, /* protocol */
+ CURLPROTO_POP3S, /* protocol */
PROTOPT_CLOSEACTION | PROTOPT_SSL
| PROTOPT_NOURLQUERY /* flags */
};
}
#ifndef CURL_DISABLE_CRYPTO_AUTH
else if((pop3c->authtypes & POP3_TYPE_APOP) &&
- (pop3c->preftype & POP3_TYPE_APOP) &&
- (pop3c->apoptimestamp))
+ (pop3c->preftype & POP3_TYPE_APOP))
/* Perform APOP authentication */
result = pop3_perform_apop(conn);
#endif
result = CURLE_FTP_WEIRD_SERVER_REPLY;
}
else {
- /* Look for the APOP timestamp */
+ /* Does the server support APOP authentication? */
if(len >= 4 && line[len - 2] == '>') {
+ /* Look for the APOP timestamp */
for(i = 3; i < len - 2; ++i) {
if(line[i] == '<') {
/* Calculate the length of the timestamp */
/* Copy the timestamp */
memcpy(pop3c->apoptimestamp, line + i, timestamplen);
pop3c->apoptimestamp[timestamplen] = '\0';
+
+ /* Store the APOP capability */
+ pop3c->authtypes |= POP3_TYPE_APOP;
break;
}
}
else if(len >= 4 && !memcmp(line, "USER", 4))
pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
- /* Does the server support APOP authentication? */
- else if(len >= 4 && !memcmp(line, "APOP", 4))
- pop3c->authtypes |= POP3_TYPE_APOP;
-
/* Does the server support SASL based authentication? */
else if(len >= 5 && !memcmp(line, "SASL ", 5)) {
pop3c->authtypes |= POP3_TYPE_SASL;
else
result = pop3_perform_authentication(conn);
}
- else
- result = pop3_perform_user(conn);
+ else {
+ /* Clear text is supported when CAPA isn't recognised */
+ pop3c->authtypes |= POP3_TYPE_CLEARTEXT;
+
+ result = pop3_perform_authentication(conn);
+ }
return result;
}
char *rplyb64 = NULL;
size_t len = 0;
- char nonce[64];
- char realm[128];
- char algorithm[64];
-
(void)instate; /* no use for this yet */
if(pop3code != '+') {
/* Get the challenge message */
pop3_get_message(data->state.buffer, &chlg64);
- /* Decode the challange message */
- result = Curl_sasl_decode_digest_md5_message(chlg64, nonce, sizeof(nonce),
- realm, sizeof(realm),
- algorithm, sizeof(algorithm));
- if(result || strcmp(algorithm, "md5-sess") != 0) {
- /* Send the cancellation */
- result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
+ /* Create the response message */
+ result = Curl_sasl_create_digest_md5_message(data, chlg64,
+ conn->user, conn->passwd,
+ "pop", &rplyb64, &len);
+ if(result) {
+ if(result == CURLE_BAD_CONTENT_ENCODING) {
+ /* Send the cancellation */
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", "*");
- if(!result)
- state(conn, POP3_AUTH_CANCEL);
+ if(!result)
+ state(conn, POP3_AUTH_CANCEL);
+ }
}
else {
- /* Create the response message */
- result = Curl_sasl_create_digest_md5_message(data, nonce, realm,
- conn->user, conn->passwd,
- "pop", &rplyb64, &len);
- if(!result && rplyb64) {
- /* Send the response */
- result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
+ /* Send the response */
+ result = Curl_pp_sendf(&conn->proto.pop3c.pp, "%s", rplyb64);
- if(!result)
- state(conn, POP3_AUTH_DIGESTMD5_RESP);
- }
+ if(!result)
+ state(conn, POP3_AUTH_DIGESTMD5_RESP);
}
Curl_safefree(rplyb64);
}
#ifndef CURL_DISABLE_CRYPTO_AUTH
else if((pop3c->authtypes & POP3_TYPE_APOP) &&
- (pop3c->preftype & POP3_TYPE_APOP) &&
- (pop3c->apoptimestamp))
+ (pop3c->preftype & POP3_TYPE_APOP))
/* Perform APOP authentication */
result = pop3_perform_apop(conn);
#endif
*done = FALSE; /* default to not done yet */
/* We always support persistent connections in POP3 */
- conn->bits.close = FALSE;
+ connkeep(conn, "POP3 default");
/* Set the default response time-out */
pp->response_time = RESP_TIMEOUT;
return CURLE_OK;
if(status) {
- conn->bits.close = TRUE; /* marked for closure */
+ connclose(conn, "POP3 done with bad status");
result = status; /* use the already set error code */
}
struct pop3_conn *pop3c = &conn->proto.pop3c;
const char *options = conn->options;
const char *ptr = options;
+ bool reset = TRUE;
- if(options) {
+ while(ptr && *ptr) {
const char *key = ptr;
while(*ptr && *ptr != '=')
ptr++;
if(strnequal(key, "AUTH", 4)) {
- const char *value = ptr + 1;
+ size_t len = 0;
+ const char *value = ++ptr;
+
+ if(reset) {
+ reset = FALSE;
+ pop3c->preftype = POP3_TYPE_NONE;
+ pop3c->prefmech = SASL_AUTH_NONE;
+ }
- if(strequal(value, "*")) {
+ while(*ptr && *ptr != ';') {
+ ptr++;
+ len++;
+ }
+
+ if(strnequal(value, "*", len)) {
pop3c->preftype = POP3_TYPE_ANY;
pop3c->prefmech = SASL_AUTH_ANY;
}
- else if(strequal(value, "+APOP")) {
+ else if(strnequal(value, "+APOP", len)) {
pop3c->preftype = POP3_TYPE_APOP;
pop3c->prefmech = SASL_AUTH_NONE;
}
- else if(strequal(value, SASL_MECH_STRING_LOGIN)) {
+ else if(strnequal(value, SASL_MECH_STRING_LOGIN, len)) {
pop3c->preftype = POP3_TYPE_SASL;
- pop3c->prefmech = SASL_MECH_LOGIN;
+ pop3c->prefmech |= SASL_MECH_LOGIN;
}
- else if(strequal(value, SASL_MECH_STRING_PLAIN)) {
+ else if(strnequal(value, SASL_MECH_STRING_PLAIN, len)) {
pop3c->preftype = POP3_TYPE_SASL;
- pop3c->prefmech = SASL_MECH_PLAIN;
+ pop3c->prefmech |= SASL_MECH_PLAIN;
}
- else if(strequal(value, SASL_MECH_STRING_CRAM_MD5)) {
+ else if(strnequal(value, SASL_MECH_STRING_CRAM_MD5, len)) {
pop3c->preftype = POP3_TYPE_SASL;
- pop3c->prefmech = SASL_MECH_CRAM_MD5;
+ pop3c->prefmech |= SASL_MECH_CRAM_MD5;
}
- else if(strequal(value, SASL_MECH_STRING_DIGEST_MD5)) {
+ else if(strnequal(value, SASL_MECH_STRING_DIGEST_MD5, len)) {
pop3c->preftype = POP3_TYPE_SASL;
- pop3c->prefmech = SASL_MECH_DIGEST_MD5;
+ pop3c->prefmech |= SASL_MECH_DIGEST_MD5;
}
- else if(strequal(value, SASL_MECH_STRING_GSSAPI)) {
+ else if(strnequal(value, SASL_MECH_STRING_GSSAPI, len)) {
pop3c->preftype = POP3_TYPE_SASL;
- pop3c->prefmech = SASL_MECH_GSSAPI;
+ pop3c->prefmech |= SASL_MECH_GSSAPI;
}
- else if(strequal(value, SASL_MECH_STRING_NTLM)) {
+ else if(strnequal(value, SASL_MECH_STRING_NTLM, len)) {
pop3c->preftype = POP3_TYPE_SASL;
- pop3c->prefmech = SASL_MECH_NTLM;
+ pop3c->prefmech |= SASL_MECH_NTLM;
}
- else if(strequal(value, SASL_MECH_STRING_XOAUTH2)) {
+ else if(strnequal(value, SASL_MECH_STRING_XOAUTH2, len)) {
pop3c->preftype = POP3_TYPE_SASL;
- pop3c->prefmech = SASL_MECH_XOAUTH2;
- }
- else {
- pop3c->preftype = POP3_TYPE_NONE;
- pop3c->prefmech = SASL_AUTH_NONE;
+ pop3c->prefmech |= SASL_MECH_XOAUTH2;
}
+
+ if(*ptr == ';')
+ ptr++;
}
else
result = CURLE_URL_MALFORMAT;