]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
imapc: Don't use AUTHENTICATE PLAIN if server doesn't advertise AUTH=PLAIN capability.
authorTimo Sirainen <tss@iki.fi>
Mon, 31 Jan 2011 17:01:58 +0000 (19:01 +0200)
committerTimo Sirainen <tss@iki.fi>
Mon, 31 Jan 2011 17:01:58 +0000 (19:01 +0200)
src/lib-storage/index/imapc/imapc-client.c
src/lib-storage/index/imapc/imapc-client.h
src/lib-storage/index/imapc/imapc-connection.c

index 4939560cb018ae09159af2ed4ba3fd7fbbe33455..babfc69a029d1c3f063fb8b273e28c6fdba4a09c 100644 (file)
@@ -25,6 +25,7 @@ const struct imapc_capability_name imapc_capability_names[] = {
        { "QRESYNC", IMAPC_CAPABILITY_QRESYNC },
        { "IDLE", IMAPC_CAPABILITY_IDLE },
        { "UIDPLUS", IMAPC_CAPABILITY_UIDPLUS },
+       { "AUTH=PLAIN", IMAPC_CAPABILITY_AUTH_PLAIN },
 
        { "IMAP4REV1", IMAPC_CAPABILITY_IMAP4REV1 },
        { NULL, 0 }
index 79026011c5b58f758fad35ff02b46fbd03454138..10b811af0e69a071ba847aeb701168d51efe2231 100644 (file)
@@ -14,6 +14,7 @@ enum imapc_capability {
        IMAPC_CAPABILITY_QRESYNC        = 0x04,
        IMAPC_CAPABILITY_IDLE           = 0x08,
        IMAPC_CAPABILITY_UIDPLUS        = 0x10,
+       IMAPC_CAPABILITY_AUTH_PLAIN     = 0x20,
 
        IMAPC_CAPABILITY_IMAP4REV1      = 0x400000000
 };
index 9f9bb1c7c9bf9a64050eaed4b1e5b52afc4cea5e..af96dbcd225c1ac3aaf5d768856c003519244836 100644 (file)
@@ -514,24 +514,6 @@ static int imapc_connection_skip_line(struct imapc_connection *conn)
        return ret;
 }
 
-static void
-imapc_connection_capability_cb(const struct imapc_command_reply *reply,
-                              void *context)
-{
-       struct imapc_connection *conn = context;
-
-       if (reply->state != IMAPC_COMMAND_STATE_OK) {
-               imapc_connection_input_error(conn,
-                       "Failed to get capabilities: %s", reply->text_full);
-       } else if (conn->capabilities == 0) {
-               imapc_connection_input_error(conn,
-                       "Capabilities not returned by server");
-       } else {
-               timeout_remove(&conn->to);
-               imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DONE);
-       }
-}
-
 static void imapc_connection_login_cb(const struct imapc_command_reply *reply,
                                      void *context)
 {
@@ -543,14 +525,6 @@ static void imapc_connection_login_cb(const struct imapc_command_reply *reply,
                return;
        }
 
-       if (conn->capabilities == 0) {
-               /* server didn't send capabilities automatically.
-                  request them manually before we're done. */
-               imapc_connection_cmd(conn, "CAPABILITY",
-                                    imapc_connection_capability_cb, conn);
-               return;
-       }
-
        timeout_remove(&conn->to);
        imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_DONE);
 }
@@ -578,23 +552,14 @@ imapc_connection_get_sasl_plain_request(struct imapc_connection *conn)
        return str_c(out);
 }
 
-static int imapc_connection_input_banner(struct imapc_connection *conn)
+static void imapc_connection_authenticate(struct imapc_connection *conn)
 {
        const struct imapc_client_settings *set = &conn->client->set;
-       const struct imap_arg *imap_args;
-       const char *cmd, *key, *value;
-       int ret;
-
-       if ((ret = imapc_connection_read_line(conn, &imap_args)) <= 0)
-               return ret;
+       const char *cmd;
 
-       if (imapc_connection_handle_imap_resp_text(conn, imap_args,
-                                                  &key, &value) < 0)
-               return -1;
-       imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_AUTHENTICATING);
-
-       if (set->master_user == NULL &&
-           need_literal(set->username) && need_literal(set->password)) {
+       if ((set->master_user == NULL &&
+            need_literal(set->username) && need_literal(set->password)) ||
+           (conn->capabilities & IMAPC_CAPABILITY_AUTH_PLAIN) == 0) {
                /* We can use LOGIN command */
                imapc_connection_cmdf(conn, imapc_connection_login_cb, conn,
                                      "LOGIN %s %s",
@@ -610,6 +575,46 @@ static int imapc_connection_input_banner(struct imapc_connection *conn)
                imapc_connection_cmd(conn, cmd,
                                     imapc_connection_login_cb, conn);
        }
+}
+
+static void
+imapc_connection_capability_cb(const struct imapc_command_reply *reply,
+                              void *context)
+{
+       struct imapc_connection *conn = context;
+
+       if (reply->state != IMAPC_COMMAND_STATE_OK) {
+               imapc_connection_input_error(conn,
+                       "Failed to get capabilities: %s", reply->text_full);
+       } else if (conn->capabilities == 0) {
+               imapc_connection_input_error(conn,
+                       "Capabilities not returned by server");
+       } else {
+               imapc_connection_authenticate(conn);
+       }
+}
+
+static int imapc_connection_input_banner(struct imapc_connection *conn)
+{
+       const struct imap_arg *imap_args;
+       const char *key, *value;
+       int ret;
+
+       if ((ret = imapc_connection_read_line(conn, &imap_args)) <= 0)
+               return ret;
+
+       if (imapc_connection_handle_imap_resp_text(conn, imap_args,
+                                                  &key, &value) < 0)
+               return -1;
+       imapc_connection_set_state(conn, IMAPC_CONNECTION_STATE_AUTHENTICATING);
+
+       if (conn->capabilities == 0) {
+               /* capabilities weren't sent in the banner. ask for them. */
+               imapc_connection_cmd(conn, "CAPABILITY",
+                                    imapc_connection_capability_cb, conn);
+       } else {
+               imapc_connection_authenticate(conn);
+       }
        conn->input_callback = NULL;
        imapc_connection_input_reset(conn);
        return 1;
@@ -618,7 +623,7 @@ static int imapc_connection_input_banner(struct imapc_connection *conn)
 static int imapc_connection_input_untagged(struct imapc_connection *conn)
 {
        const struct imap_arg *imap_args;
-       const char *name;
+       const char *name, *value;
        struct imapc_untagged_reply reply;
        int ret;
 
@@ -663,6 +668,10 @@ static int imapc_connection_input_untagged(struct imapc_connection *conn)
                                                &reply.resp_text_key,
                                                &reply.resp_text_value) < 0)
                        return -1;
+       } else if (strcasecmp(name, "CAPABILITY") == 0) {
+               value = imap_args_to_str(imap_args);
+               if (imapc_connection_parse_capability(conn, value) < 0)
+                       return -1;
        }
 
        reply.name = name;