Add support for SCRAM-SHA-1 authentication mechanism (via libetpan) to IMAP.
authorAndrej Kacian <ticho@claws-mail.org>
Sat, 3 Jan 2015 02:42:30 +0000 (03:42 +0100)
committerAndrej Kacian <ticho@claws-mail.org>
Tue, 13 Jan 2015 12:42:05 +0000 (13:42 +0100)
src/etpan/imap-thread.c
src/imap.c
src/imap.h
src/prefs_account.c

index 5f79cdb00d789d9767b372f460d5f68ba321f2b1..f1c555d3ebe43adf188e77bab30be4229c9ad96d 100644 (file)
@@ -902,7 +902,16 @@ static void login_run(struct etpan_thread_op * op)
                        param->type, param->server, NULL, NULL,
                        param->login, param->login,
                        param->password, NULL);
-       else 
+       else if (!strcmp(param->type, "SCRAM-SHA-1"))
+               /* 7th argument has to be NULL here, to stop libetpan sending the
+                * a= attribute in its initial SCRAM-SHA-1 message to server. At least
+                * Dovecot 2.2 doesn't seem to like that, and will not authenticate
+                * succesfully. */
+               r = mailimap_authenticate(param->imap,
+                       param->type, NULL, NULL, NULL,
+                       NULL, param->login,
+                       param->password, NULL);
+       else
                r = mailimap_authenticate(param->imap,
                        param->type, NULL, NULL, NULL,
                        param->login, param->login,
index 35fb47f78e02d3495f58717a715ff3beb17b3d42..6a3e1ce304617e1b3a1a61d9a52a72c1edbae096 100644 (file)
@@ -898,6 +898,9 @@ static gint imap_auth(IMAPSession *session, const gchar *user, const gchar *pass
        case IMAP_AUTH_DIGEST_MD5:
                ok = imap_cmd_login(session, user, pass, "DIGEST-MD5");
                break;
+       case IMAP_AUTH_SCRAM_SHA1:
+               ok = imap_cmd_login(session, user, pass, "SCRAM-SHA-1");
+               break;
        case IMAP_AUTH_LOGIN:
                ok = imap_cmd_login(session, user, pass, "LOGIN");
                break;
@@ -909,17 +912,21 @@ static gint imap_auth(IMAPSession *session, const gchar *user, const gchar *pass
                                "\t ANONYMOUS %d\n"
                                "\t CRAM-MD5 %d\n"
                                "\t DIGEST-MD5 %d\n"
+                               "\t SCRAM-SHA-1 %d\n"
                                "\t LOGIN %d\n"
                                "\t GSSAPI %d\n", 
                        imap_has_capability(session, "ANONYMOUS"),
                        imap_has_capability(session, "CRAM-MD5"),
                        imap_has_capability(session, "DIGEST-MD5"),
+                       imap_has_capability(session, "SCRAM-SHA-1"),
                        imap_has_capability(session, "LOGIN"),
                        imap_has_capability(session, "GSSAPI"));
                if (imap_has_capability(session, "CRAM-MD5"))
                        ok = imap_cmd_login(session, user, pass, "CRAM-MD5");
                if (ok == MAILIMAP_ERROR_LOGIN && imap_has_capability(session, "DIGEST-MD5"))
                        ok = imap_cmd_login(session, user, pass, "DIGEST-MD5");
+               if (ok == MAILIMAP_ERROR_LOGIN && imap_has_capability(session, "SCRAM-SHA-1"))
+                       ok = imap_cmd_login(session, user, pass, "SCRAM-SHA-1");
                if (ok == MAILIMAP_ERROR_LOGIN && imap_has_capability(session, "GSSAPI"))
                        ok = imap_cmd_login(session, user, pass, "GSSAPI");
                if (ok == MAILIMAP_ERROR_LOGIN) /* we always try LOGIN before giving up */
@@ -941,6 +948,12 @@ static gint imap_auth(IMAPSession *session, const gchar *user, const gchar *pass
                                     "DIGEST-MD5 SASL plugin is installed.");
                } 
 
+               if (type == IMAP_AUTH_SCRAM_SHA1) {
+                       ext_info = _("\n\nSCRAM-SHA-1 logins only work if libetpan has been "
+                                    "compiled with SASL support and the "
+                                    "SCRAM SASL plugin is installed.");
+               }
+
                if (time(NULL) - last_login_err > 10) {
                        if (!prefs_common.no_recv_err_panel) {
                                alertpanel_error_log(_("Connection to %s failed: "
index 3c84eef47bba50fb8e04423935da4b6105bf747b..a776867971ad4ae1d68e42da32204ef350053ed9 100644 (file)
@@ -28,7 +28,8 @@ typedef enum
        IMAP_AUTH_CRAM_MD5      = 1 << 1,
        IMAP_AUTH_ANON          = 1 << 2,
        IMAP_AUTH_GSSAPI        = 1 << 3,
-       IMAP_AUTH_DIGEST_MD5    = 1 << 4
+       IMAP_AUTH_DIGEST_MD5    = 1 << 4,
+       IMAP_AUTH_SCRAM_SHA1    = 1 << 5
 } IMAPAuthType;
 
 FolderClass *imap_get_class            (void);
index 181be457e2df25991dfb26089c86ec753fef6f81..934a1cf6d562ba3d51332ee9363a3f029878ccb4 100644 (file)
@@ -1583,6 +1583,7 @@ static void receive_create_widget_func(PrefsPage * _page,
        COMBOBOX_ADD (menu, "ANONYMOUS", IMAP_AUTH_ANON);
        COMBOBOX_ADD (menu, "GSSAPI", IMAP_AUTH_GSSAPI);
        COMBOBOX_ADD (menu, "DIGEST-MD5", IMAP_AUTH_DIGEST_MD5);
+       COMBOBOX_ADD (menu, "SCRAM-SHA-1", IMAP_AUTH_SCRAM_SHA1);
 
        hbox1 = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox1);