aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/imap.c149
1 files changed, 75 insertions, 74 deletions
diff --git a/lib/imap.c b/lib/imap.c
index 845d7dd4c..7738e63e2 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -323,16 +323,14 @@ static char* imap_atom(const char* str)
return newstr;
}
-/* Function that checks for an ending IMAP status code at the start of the
- given string but also detects various capabilities from the CAPABILITY
- response including the supported authentication mechanisms. */
+/* Function that checks whether the given string is a valid tagged, untagged
+ or continuation response which can be processed by the response handler. */
static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
int *resp)
{
struct imap_conn *imapc = &conn->proto.imapc;
const char *id = imapc->resptag;
size_t id_len = strlen(id);
- size_t wordlen;
/* Do we have a tagged command response? */
if(len >= id_len + 1 && !memcmp(id, line, id_len) && line[id_len] == ' ') {
@@ -355,77 +353,19 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
/* Do we have an untagged command response */
if(len >= 2 && !memcmp("* ", line, 2)) {
- /* Are we processing CAPABILITY command data? */
- if(imapc->state == IMAP_CAPABILITY) {
- line += 2;
- len -= 2;
-
- /* 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++;
-
- /* Does the server support the STARTTLS capability? */
- if(wordlen == 8 && !memcmp(line, "STARTTLS", 8))
- imapc->tls_supported = TRUE;
-
- /* Has the server explicitly disabled clear text authentication? */
- else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13))
- imapc->login_disabled = TRUE;
-
- /* Does the server support the SASL-IR capability? */
- else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7))
- imapc->ir_supported = TRUE;
-
- /* Do we have a SASL based authentication mechanism? */
- else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
- line += 5;
- len -= 5;
- wordlen -= 5;
-
- /* Test the word for a matching authentication mechanism */
- if(wordlen == 5 && !memcmp(line, "LOGIN", 5))
- imapc->authmechs |= SASL_MECH_LOGIN;
- if(wordlen == 5 && !memcmp(line, "PLAIN", 5))
- imapc->authmechs |= SASL_MECH_PLAIN;
- else if(wordlen == 8 && !memcmp(line, "CRAM-MD5", 8))
- imapc->authmechs |= SASL_MECH_CRAM_MD5;
- else if(wordlen == 10 && !memcmp(line, "DIGEST-MD5", 10))
- imapc->authmechs |= SASL_MECH_DIGEST_MD5;
- else if(wordlen == 6 && !memcmp(line, "GSSAPI", 6))
- imapc->authmechs |= SASL_MECH_GSSAPI;
- else if(wordlen == 8 && !memcmp(line, "EXTERNAL", 8))
- imapc->authmechs |= SASL_MECH_EXTERNAL;
- else if(wordlen == 4 && !memcmp(line, "NTLM", 4))
- imapc->authmechs |= SASL_MECH_NTLM;
- }
-
- line += wordlen;
- len -= wordlen;
- }
-
- return FALSE;
+ switch(imapc->state) {
+ /* States which are interested in untagged responses */
+ case IMAP_CAPABILITY:
+ case IMAP_FETCH:
+ *resp = '*';
+ break;
+
+ /* Ignore other untagged responses */
+ default:
+ return FALSE;
}
- /* Are we processing FETCH command responses? */
- else if(imapc->state == IMAP_FETCH) {
- *resp = '*';
- return TRUE;
- }
+ return TRUE;
}
/* Do we have a continuation response? */
@@ -755,10 +695,71 @@ static CURLcode imap_state_capability_resp(struct connectdata *conn,
CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
struct imap_conn *imapc = &conn->proto.imapc;
+ const char *line = data->state.buffer;
+ size_t wordlen;
(void)instate; /* no use for this yet */
- if(imapcode != 'O')
+ /* Do we have a untagged response? */
+ if(imapcode == '*') {
+ line += 2;
+
+ /* Loop through the data line */
+ for(;;) {
+ while(*line &&
+ (*line == ' ' || *line == '\t' ||
+ *line == '\r' || *line == '\n')) {
+
+ line++;
+ }
+
+ if(!*line)
+ break;
+
+ /* Extract the word */
+ for(wordlen = 0; line[wordlen] && line[wordlen] != ' ' &&
+ line[wordlen] != '\t' && line[wordlen] != '\r' &&
+ line[wordlen] != '\n';)
+ wordlen++;
+
+ /* Does the server support the STARTTLS capability? */
+ if(wordlen == 8 && !memcmp(line, "STARTTLS", 8))
+ imapc->tls_supported = TRUE;
+
+ /* Has the server explicitly disabled clear text authentication? */
+ else if(wordlen == 13 && !memcmp(line, "LOGINDISABLED", 13))
+ imapc->login_disabled = TRUE;
+
+ /* Does the server support the SASL-IR capability? */
+ else if(wordlen == 7 && !memcmp(line, "SASL-IR", 7))
+ imapc->ir_supported = TRUE;
+
+ /* Do we have a SASL based authentication mechanism? */
+ else if(wordlen > 5 && !memcmp(line, "AUTH=", 5)) {
+ line += 5;
+ wordlen -= 5;
+
+ /* Test the word for a matching authentication mechanism */
+ if(wordlen == 5 && !memcmp(line, "LOGIN", 5))
+ imapc->authmechs |= SASL_MECH_LOGIN;
+ if(wordlen == 5 && !memcmp(line, "PLAIN", 5))
+ imapc->authmechs |= SASL_MECH_PLAIN;
+ else if(wordlen == 8 && !memcmp(line, "CRAM-MD5", 8))
+ imapc->authmechs |= SASL_MECH_CRAM_MD5;
+ else if(wordlen == 10 && !memcmp(line, "DIGEST-MD5", 10))
+ imapc->authmechs |= SASL_MECH_DIGEST_MD5;
+ else if(wordlen == 6 && !memcmp(line, "GSSAPI", 6))
+ imapc->authmechs |= SASL_MECH_GSSAPI;
+ else if(wordlen == 8 && !memcmp(line, "EXTERNAL", 8))
+ imapc->authmechs |= SASL_MECH_EXTERNAL;
+ else if(wordlen == 4 && !memcmp(line, "NTLM", 4))
+ imapc->authmechs |= SASL_MECH_NTLM;
+ }
+
+ line += wordlen;
+ }
+ }
+ else if(imapcode != 'O')
result = imap_state_login(conn);
else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) {
/* We don't have a SSL/TLS connection yet, but SSL is requested */