aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/pop3.c169
1 files changed, 87 insertions, 82 deletions
diff --git a/lib/pop3.c b/lib/pop3.c
index b8bf784be..71873a7cc 100644
--- a/lib/pop3.c
+++ b/lib/pop3.c
@@ -236,7 +236,6 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
int *resp)
{
struct pop3_conn *pop3c = &conn->proto.pop3c;
- size_t wordlen;
/* Do we have an error response? */
if(len >= 4 && !memcmp("-ERR", line, 4)) {
@@ -248,75 +247,12 @@ static bool pop3_endofresp(struct connectdata *conn, char *line, size_t len,
/* Are we processing CAPA command responses? */
if(pop3c->state == POP3_CAPA) {
/* Do we have the terminating line? */
- if(len >= 1 && !memcmp(line, ".", 1)) {
+ if(len >= 1 && !memcmp(line, ".", 1))
*resp = '+';
+ else
+ *resp = '*';
- return TRUE;
- }
-
- /* Does the server support the STLS capability? */
- if(len >= 4 && !memcmp(line, "STLS", 4))
- pop3c->tls_supported = TRUE;
-
- /* Does the server support clear text authentication? */
- 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;
-
- /* Advance past the SASL keyword */
- line += 5;
- len -= 5;
-
- /* Loop through the data line */
- for(;;) {
- while(len &&
- (*line == ' ' || *line == '\t' ||
- *line == '\r' || *line == '\n')) {
-
- line++;
- len--;
- }
-
- if(!len)
- break;
-
- /* Extract the word */
- for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
- line[wordlen] != '\t' && line[wordlen] != '\r' &&
- line[wordlen] != '\n';)
- wordlen++;
-
- /* Test the word for a matching authentication mechanism */
- if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
- pop3c->authmechs |= SASL_MECH_LOGIN;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
- pop3c->authmechs |= SASL_MECH_PLAIN;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
- pop3c->authmechs |= SASL_MECH_CRAM_MD5;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
- pop3c->authmechs |= SASL_MECH_DIGEST_MD5;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
- pop3c->authmechs |= SASL_MECH_GSSAPI;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
- pop3c->authmechs |= SASL_MECH_EXTERNAL;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
- pop3c->authmechs |= SASL_MECH_NTLM;
- else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
- pop3c->authmechs |= SASL_MECH_XOAUTH2;
-
- line += wordlen;
- len -= wordlen;
- }
- }
-
- return FALSE;
+ return TRUE;
}
/* Do we have a command or continuation response? */
@@ -755,26 +691,95 @@ static CURLcode pop3_state_capa_resp(struct connectdata *conn, int pop3code,
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct pop3_conn *pop3c = &conn->proto.pop3c;
+ const char *line = data->state.buffer;
+ size_t len = strlen(line);
+ size_t wordlen;
(void)instate; /* no use for this yet */
- if(pop3code != '+')
- result = pop3_perform_user(conn);
- else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
- /* We don't have a SSL/TLS connection yet, but SSL is requested */
- if(pop3c->tls_supported)
- /* Switch to TLS connection now */
- result = pop3_perform_starttls(conn);
- else if(data->set.use_ssl == CURLUSESSL_TRY)
- /* Fallback and carry on with authentication */
- result = pop3_perform_authentication(conn);
- else {
- failf(data, "STLS not supported.");
- result = CURLE_USE_SSL_FAILED;
+ /* Do we have a untagged response? */
+ if(pop3code == '*') {
+ /* Does the server support the STLS capability? */
+ if(len >= 4 && !memcmp(line, "STLS", 4))
+ pop3c->tls_supported = TRUE;
+
+ /* Does the server support clear text authentication? */
+ 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;
+
+ /* Advance past the SASL keyword */
+ line += 5;
+ len -= 5;
+
+ /* Loop through the data line */
+ for(;;) {
+ while(len &&
+ (*line == ' ' || *line == '\t' ||
+ *line == '\r' || *line == '\n')) {
+
+ line++;
+ len--;
+ }
+
+ if(!len)
+ break;
+
+ /* Extract the word */
+ for(wordlen = 0; wordlen < len && line[wordlen] != ' ' &&
+ line[wordlen] != '\t' && line[wordlen] != '\r' &&
+ line[wordlen] != '\n';)
+ wordlen++;
+
+ /* Test the word for a matching authentication mechanism */
+ if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_LOGIN))
+ pop3c->authmechs |= SASL_MECH_LOGIN;
+ else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_PLAIN))
+ pop3c->authmechs |= SASL_MECH_PLAIN;
+ else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_CRAM_MD5))
+ pop3c->authmechs |= SASL_MECH_CRAM_MD5;
+ else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_DIGEST_MD5))
+ pop3c->authmechs |= SASL_MECH_DIGEST_MD5;
+ else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_GSSAPI))
+ pop3c->authmechs |= SASL_MECH_GSSAPI;
+ else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_EXTERNAL))
+ pop3c->authmechs |= SASL_MECH_EXTERNAL;
+ else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_NTLM))
+ pop3c->authmechs |= SASL_MECH_NTLM;
+ else if(sasl_mech_equal(line, wordlen, SASL_MECH_STRING_XOAUTH2))
+ pop3c->authmechs |= SASL_MECH_XOAUTH2;
+
+ line += wordlen;
+ len -= wordlen;
+ }
+ }
+ }
+ else if(pop3code == '+') {
+ if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
+ /* We don't have a SSL/TLS connection yet, but SSL is requested */
+ if(pop3c->tls_supported)
+ /* Switch to TLS connection now */
+ result = pop3_perform_starttls(conn);
+ else if(data->set.use_ssl == CURLUSESSL_TRY)
+ /* Fallback and carry on with authentication */
+ result = pop3_perform_authentication(conn);
+ else {
+ failf(data, "STLS not supported.");
+ result = CURLE_USE_SSL_FAILED;
+ }
}
+ else
+ result = pop3_perform_authentication(conn);
}
else
- result = pop3_perform_authentication(conn);
+ result = pop3_perform_user(conn);
return result;
}