Implement real LOGIN auth method for IMAP.
[claws.git] / src / prefs_account.c
index 7740264f80a656d6bc775fa4f341f04d5d62da5c..6bd3716220e3f490cc6ebf2238ab8039b2afcd51 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2013 Hiroyuki Yamamoto and the Claws Mail team
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2015 Hiroyuki Yamamoto and the Claws Mail team
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,7 +14,6 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
- * 
  */
 
 #ifdef HAVE_CONFIG_H
@@ -57,7 +56,6 @@
 #include "smtp.h"
 #include "imap.h"
 #include "remotefolder.h"
-#include "base64.h"
 #include "combobox.h"
 #include "setup.h"
 #include "quote_fmt.h"
@@ -269,6 +267,7 @@ typedef struct SSLPage
        GtkWidget *entry_out_cert_file;
        GtkWidget *entry_out_cert_pass;
 
+       GtkWidget *ssl_certs_auto_accept_checkbtn;
        GtkWidget *use_nonblocking_ssl_checkbtn;
 } SSLPage;
 
@@ -729,6 +728,10 @@ static PrefParam ssl_param[] = {
         prefs_account_enum_set_data_from_radiobtn,
         prefs_account_enum_set_radiobtn},
 
+       {"ssl_certs_auto_accept", "0", &tmp_ac_prefs.ssl_certs_auto_accept, P_BOOL,
+        &ssl_page.ssl_certs_auto_accept_checkbtn,
+        prefs_set_data_from_toggle, prefs_set_toggle},
+
        {"use_nonblocking_ssl", "1", &tmp_ac_prefs.use_nonblocking_ssl, P_BOOL,
         &ssl_page.use_nonblocking_ssl_checkbtn,
         prefs_set_data_from_toggle, prefs_set_toggle},
@@ -769,6 +772,9 @@ static PrefParam ssl_param[] = {
        {"out_ssl_client_cert_pass", "", &tmp_ac_prefs.out_ssl_client_cert_pass, P_PASSWORD,
         NULL, NULL, NULL},
 
+       {"ssl_certs_auto_accept", "0", &tmp_ac_prefs.ssl_certs_auto_accept, P_BOOL,
+        NULL, NULL, NULL},
+
        {"use_nonblocking_ssl", "1", &tmp_ac_prefs.use_nonblocking_ssl, P_BOOL,
         NULL, NULL, NULL},
 #endif /* USE_GNUTLS */
@@ -1124,7 +1130,7 @@ static void basic_create_widget_func(PrefsPage * _page,
        auto_configure_cancel_btn = gtk_button_new_with_label(_("Cancel"));
        gtk_box_pack_start(GTK_BOX (optmenubox), auto_configure_cancel_btn, FALSE, FALSE, 0);
        auto_configure_lbl = gtk_label_new("");
-       gtk_label_set_justify(GTK_LABEL(optlabel), GTK_JUSTIFY_LEFT);
+       gtk_label_set_justify(GTK_LABEL(auto_configure_lbl), GTK_JUSTIFY_LEFT);
        gtk_box_pack_start(GTK_BOX (optmenubox), auto_configure_lbl, FALSE, FALSE, 0);
 #if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
        gtk_widget_show(auto_configure_btn);
@@ -1137,8 +1143,9 @@ static void basic_create_widget_func(PrefsPage * _page,
 
        no_imap_warn_icon = gtk_image_new_from_stock
                         (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
-       no_imap_warn_label = gtk_label_new(_("<span weight=\"bold\">Warning: this version of Claws Mail\n"
-                         "has been built without IMAP and News support.</span>"));
+       no_imap_warn_label = gtk_label_new(g_strconcat("<span weight=\"bold\">",
+                       _("Warning: this version of Claws Mail\n"
+                         "has been built without IMAP and News support."), "</span>", NULL));
        gtk_label_set_use_markup(GTK_LABEL(no_imap_warn_label), TRUE);
 
        gtk_box_pack_start(GTK_BOX (optmenubox), no_imap_warn_icon, FALSE, FALSE, 0);
@@ -1571,11 +1578,14 @@ static void receive_create_widget_func(PrefsPage * _page,
 
        COMBOBOX_ADD (menu, _("Automatic"), 0);
        COMBOBOX_ADD (menu, NULL, 0);
-       COMBOBOX_ADD (menu, "LOGIN", IMAP_AUTH_LOGIN);
+       COMBOBOX_ADD (menu, _("Plain text"), IMAP_AUTH_PLAINTEXT);
        COMBOBOX_ADD (menu, "CRAM-MD5", IMAP_AUTH_CRAM_MD5);
        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);
+       COMBOBOX_ADD (menu, "PLAIN", IMAP_AUTH_PLAIN);
+       COMBOBOX_ADD (menu, "LOGIN", IMAP_AUTH_LOGIN);
 
        hbox1 = gtk_hbox_new (FALSE, 8);
        gtk_widget_show (hbox1);
@@ -2413,6 +2423,7 @@ static void ssl_create_widget_func(PrefsPage * _page,
        GtkWidget *entry_out_cert_pass;
 
        GtkWidget *vbox7;
+       GtkWidget *ssl_certs_auto_accept_checkbtn;
        GtkWidget *use_nonblocking_ssl_checkbtn;
        GtkWidget *hbox;
        GtkWidget *hbox_spc;
@@ -2545,6 +2556,9 @@ static void ssl_create_widget_func(PrefsPage * _page,
        gtk_widget_show (vbox7);
        gtk_box_pack_start (GTK_BOX (vbox1), vbox7, FALSE, FALSE, 0);
 
+       PACK_CHECK_BUTTON(vbox7, ssl_certs_auto_accept_checkbtn,
+                         _("Automatically accept valid SSL certificates"));
+
        PACK_CHECK_BUTTON(vbox7, use_nonblocking_ssl_checkbtn,
                          _("Use non-blocking SSL"));
 
@@ -2587,6 +2601,7 @@ static void ssl_create_widget_func(PrefsPage * _page,
        page->entry_out_cert_file     = entry_out_cert_file;
        page->entry_out_cert_pass     = entry_out_cert_pass;
 
+       page->ssl_certs_auto_accept_checkbtn = ssl_certs_auto_accept_checkbtn;
        page->use_nonblocking_ssl_checkbtn = use_nonblocking_ssl_checkbtn;
 
        tmp_ac_prefs = *ac_prefs;
@@ -3349,7 +3364,7 @@ static gboolean sslcert_get_client_cert_hook(gpointer source, gpointer data)
        hookdata->password = NULL;
 
        if (!g_list_find(account_get_list(), account)) {
-               g_warning("can't find sock account\n");
+               g_warning("can't find account");
                return TRUE;
        }
        
@@ -3390,6 +3405,7 @@ static gboolean sslcert_get_password(gpointer source, gpointer data)
 #if !GLIB_CHECK_VERSION(2,32,0)
        pass_data.cond = g_cond_new();
 #else
+       pass_data.cond = g_new0(GCond, 1);
        g_cond_init(pass_data.cond);
 #endif
        pass_data.mutex = cm_mutex_new();
@@ -3404,6 +3420,7 @@ static gboolean sslcert_get_password(gpointer source, gpointer data)
        g_cond_free(pass_data.cond);
 #else
        g_cond_clear(pass_data.cond);
+       g_free(pass_data.cond);
 #endif
        g_mutex_unlock(pass_data.mutex);
        cm_mutex_free(pass_data.mutex);
@@ -3474,6 +3491,7 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
        gchar *rcpath;
        gint id;
        gchar **strv, **cur;
+       gsize len;
 
        cm_return_if_fail(ac_prefs != NULL);
        cm_return_if_fail(label != NULL);
@@ -3495,7 +3513,7 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
        *ac_prefs = tmp_ac_prefs;
        while (*p && !g_ascii_isdigit(*p)) p++;
        id = atoi(p);
-       if (id < 0) g_warning("wrong account id: %d\n", id);
+       if (id < 0) g_warning("wrong account id: %d", id);
        ac_prefs->account_id = id;
 
        if (ac_prefs->protocol == A_APOP) {
@@ -3507,7 +3525,7 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
        if (privacy_prefs != NULL) {
                strv = g_strsplit(privacy_prefs, ",", 0);
                for (cur = strv; *cur != NULL; cur++) {
-                       gchar *encvalue, *value;
+                       gchar *encvalue, *tmp;
 
                        encvalue = strchr(*cur, '=');
                        if (encvalue == NULL)
@@ -3515,10 +3533,11 @@ void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
                        encvalue[0] = '\0';
                        encvalue++;
 
-                       value = g_malloc0(strlen(encvalue));
-                       if (base64_decode(value, encvalue, strlen(encvalue)) > 0)
-                               g_hash_table_insert(ac_prefs->privacy_prefs, g_strdup(*cur), g_strdup(value));
-                       g_free(value);
+                       tmp = g_base64_decode_zero(encvalue, &len);
+                       if (len > 0)
+                               g_hash_table_insert(ac_prefs->privacy_prefs, g_strdup(*cur), tmp);
+                       else
+                               g_free(tmp);
                }
                g_strfreev(strv);
                g_free(privacy_prefs);
@@ -3539,15 +3558,14 @@ static void create_privacy_prefs(gpointer key, gpointer _value, gpointer user_da
        if (str->len > 0)
                g_string_append_c(str, ',');
 
-       encvalue = g_malloc0(B64LEN(strlen(value)) + 1);
-       base64_encode(encvalue, (gchar *) value, strlen(value));
+       encvalue = g_base64_encode(value, strlen(value));
        g_string_append_printf(str, "%s=%s", (gchar *) key, encvalue);
        g_free(encvalue);
 }
 
 #define WRITE_PARAM(PARAM_TABLE) \
                if (prefs_write_param(PARAM_TABLE, pfile->fp) < 0) { \
-                       g_warning("failed to write configuration to file\n"); \
+                       g_warning("failed to write configuration to file"); \
                        prefs_file_close_revert(pfile); \
                        g_free(privacy_prefs); \
                        privacy_prefs = NULL; \
@@ -3602,7 +3620,7 @@ void prefs_account_write_config_all(GList *account_list)
        }
 
        if (prefs_file_close(pfile) < 0)
-               g_warning("failed to write configuration to file\n");
+               g_warning("failed to write configuration to file");
 }
 #undef WRITE_PARAM
 
@@ -3714,7 +3732,7 @@ PrefsAccount *prefs_account_open(PrefsAccount *ac_prefs, gboolean *dirty)
 
        prefswindow_open_full(title, prefs_pages, ac_prefs, destroy_dialog,
                        &prefs_common.editaccountwin_width, &prefs_common.editaccountwin_height,
-                       TRUE, NULL, NULL);
+                       TRUE, NULL, NULL, NULL);
        g_free(title);
        gtk_main();
 
@@ -3800,7 +3818,6 @@ static void prefs_account_select_folder_cb(GtkWidget *widget, gpointer data)
 static void auto_configure_cb (GtkWidget *widget, gpointer data)
 {
        gchar *address = NULL;
-       const gchar *domain = NULL;
        AutoConfigureData *recv_data;
        AutoConfigureData *send_data;
        static GCancellable *recv_cancel = NULL;
@@ -3828,12 +3845,12 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
 
        address = gtk_editable_get_chars(GTK_EDITABLE(basic_page.addr_entry), 0, -1);
 
-       if (strchr(address, '@') < 0) {
+       if (strchr(address, '@') == NULL) {
                g_free(address);
                gtk_label_set_text(GTK_LABEL(basic_page.auto_configure_lbl),
                           _("Failed (wrong address)"));
+               return;
        }
-       domain = strchr(address, '@') + 1;
 
        if (protocol == A_POP3 || protocol == A_IMAP4) {
                recv_data = g_new0(AutoConfigureData, 1);
@@ -3845,7 +3862,7 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
                case A_POP3:
                        recv_data->ssl_service = "pop3s";
                        recv_data->tls_service = "pop3";
-                       recv_data->domain = g_strdup(domain);
+                       recv_data->address = g_strdup(address);
                        recv_data->hostname_entry = GTK_ENTRY(basic_page.recvserv_entry);
                        recv_data->set_port = GTK_TOGGLE_BUTTON(advanced_page.popport_checkbtn);
                        recv_data->port = GTK_SPIN_BUTTON(advanced_page.popport_spinbtn);
@@ -3853,11 +3870,12 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
                        recv_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(ssl_page.pop_ssltunnel_radiobtn);
                        recv_data->default_port = 110;
                        recv_data->default_ssl_port = 995;
+                       recv_data->uid_entry = GTK_ENTRY(basic_page.uid_entry);
                        break;
                case A_IMAP4:
                        recv_data->ssl_service = "imaps";
                        recv_data->tls_service = "imap";
-                       recv_data->domain = g_strdup(domain);
+                       recv_data->address = g_strdup(address);
                        recv_data->hostname_entry = GTK_ENTRY(basic_page.recvserv_entry);
                        recv_data->set_port = GTK_TOGGLE_BUTTON(advanced_page.imapport_checkbtn);
                        recv_data->port = GTK_SPIN_BUTTON(advanced_page.imapport_spinbtn);
@@ -3865,22 +3883,23 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
                        recv_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(ssl_page.imap_ssltunnel_radiobtn);
                        recv_data->default_port = 143;
                        recv_data->default_ssl_port = 993;
+                       recv_data->uid_entry = GTK_ENTRY(basic_page.uid_entry);
                        break;
                default:
                        cm_return_if_fail(FALSE);
                }
                auto_configure_service(recv_data);
        }
-       
+
        send_data = g_new0(AutoConfigureData, 1);
        send_data->configure_button = GTK_BUTTON(basic_page.auto_configure_btn);
        send_data->cancel_button = GTK_BUTTON(basic_page.auto_configure_cancel_btn);
        send_data->info_label = GTK_LABEL(basic_page.auto_configure_lbl);
        send_data->cancel = send_cancel;
 
-       send_data->ssl_service = "submissions";
+       send_data->ssl_service = NULL;
        send_data->tls_service = "submission";
-       send_data->domain = g_strdup(domain);
+       send_data->address = g_strdup(address);
        send_data->hostname_entry = GTK_ENTRY(basic_page.smtpserv_entry);
        send_data->set_port = GTK_TOGGLE_BUTTON(advanced_page.smtpport_checkbtn);
        send_data->port = GTK_SPIN_BUTTON(advanced_page.smtpport_spinbtn);
@@ -3888,6 +3907,8 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
        send_data->ssl_checkbtn = NULL;
        send_data->default_port = 25;
        send_data->default_ssl_port = -1;
+       send_data->uid_entry = NULL;
+       send_data->auth_checkbtn = GTK_TOGGLE_BUTTON(send_page.smtp_auth_checkbtn);
 
        auto_configure_service(send_data);