diff options
-rw-r--r-- | lib/pop3.c | 169 |
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; } |