[Commits] [SCM] claws branch, master, updated. 3.9.3-140-g3dc522b
colin at claws-mail.org
colin at claws-mail.org
Fri May 2 09:24:54 CEST 2014
The branch master of project "claws" (Claws Mail) has been updated
via 3dc522b3ecbe48cf25f9d315b9ef123b2ebc226b (commit)
via 6e2e1c8bcd096d117dc22dfd9989c5c922d64f8f (commit)
via 94ec77b15d34079fa6752fcd1a6a687782b07f9c (commit)
via a3b08204f9687fcf35d833bd46b61059bf6bd2b7 (commit)
via 73088e2d091346b9770dbbb98a61e76620417f44 (commit)
via 868bbb342eb035f62c003daaef076cdaedb84539 (commit)
from 594f864375dd7441081db52aac3edcc68e18ce8d (commit)
- Log -----------------------------------------------------------------
commit 3dc522b3ecbe48cf25f9d315b9ef123b2ebc226b
Author: Colin Leroy <colin at colino.net>
Date: Wed Apr 30 13:06:58 2014 +0200
Implement saving of the certificate chain, making the offline status
check correct.
diff --git a/src/common/ssl.c b/src/common/ssl.c
index b64ab5e..28ba896 100644
--- a/src/common/ssl.c
+++ b/src/common/ssl.c
@@ -260,14 +260,56 @@ gboolean ssl_init_socket(SockInfo *sockinfo)
return ssl_init_socket_with_method(sockinfo, SSL_METHOD_SSLv23);
}
+gnutls_x509_crt_t *ssl_get_certificate_chain(gnutls_session_t session, gint *list_len)
+{
+ const gnutls_datum *raw_cert_list;
+ gnutls_x509_crt_t *certs = NULL;
+ gboolean result = TRUE;
+
+ *list_len = -1;
+ if (!session)
+ return NULL;
+
+ raw_cert_list = gnutls_certificate_get_peers(session, list_len);
+
+ if (raw_cert_list && gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) {
+ int i = 0;
+
+ certs = g_malloc(sizeof(gnutls_x509_crt_t) * (*list_len));
+
+ for(i = 0 ; i < (*list_len) ; i++) {
+ int r;
+
+ gnutls_x509_crt_init(&certs[i]);
+ r = gnutls_x509_crt_import(certs[i], &raw_cert_list[i], GNUTLS_X509_FMT_DER);
+ if (r < 0) {
+ g_warning("cert get failure: %d %s\n", r, gnutls_strerror(r));
+
+ result = FALSE;
+ i--;
+ break;
+ }
+ }
+ if (!result) {
+ for (; i >= 0; i--)
+ gnutls_x509_crt_deinit(certs[i]);
+
+ g_free(certs);
+ *list_len = -1;
+
+ return NULL;
+ }
+ }
+
+ return certs;
+}
+
gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method)
{
gnutls_session_t session;
- int r;
- const gnutls_datum_t *raw_cert_list;
- unsigned int raw_cert_list_length;
- gnutls_x509_crt_t cert = NULL;
- guint status;
+ int r, i;
+ unsigned int cert_list_length;
+ gnutls_x509_crt_t *certs = NULL;
gnutls_certificate_credentials_t xcred;
if (gnutls_certificate_allocate_credentials (&xcred) != 0)
@@ -321,28 +363,26 @@ gboolean ssl_init_socket_with_method(SockInfo *sockinfo, SSLMethod method)
}
/* Get server's certificate (note: beware of dynamic allocation) */
- raw_cert_list = gnutls_certificate_get_peers(session, &raw_cert_list_length);
+ certs = ssl_get_certificate_chain(session, &cert_list_length);
- if (!raw_cert_list
- || gnutls_certificate_type_get(session) != GNUTLS_CRT_X509
- || (r = gnutls_x509_crt_init(&cert)) < 0
- || (r = gnutls_x509_crt_import(cert, &raw_cert_list[0], GNUTLS_X509_FMT_DER)) < 0) {
- g_warning("cert get failure: %d %s\n", r, gnutls_strerror(r));
+ if (!certs) {
gnutls_certificate_free_credentials(xcred);
gnutls_deinit(session);
return FALSE;
}
- r = gnutls_certificate_verify_peers2(session, &status);
-
- if (r < 0 || !ssl_certificate_check(cert, status, sockinfo->hostname, sockinfo->port)) {
- gnutls_x509_crt_deinit(cert);
+ if (!ssl_certificate_check_chain(certs, cert_list_length, sockinfo->hostname, sockinfo->port)) {
+ for (i = 0; i < cert_list_length; i++)
+ gnutls_x509_crt_deinit(certs[i]);
+ g_free(certs);
gnutls_certificate_free_credentials(xcred);
gnutls_deinit(session);
return FALSE;
}
- gnutls_x509_crt_deinit(cert);
+ for (i = 0; i < cert_list_length; i++)
+ gnutls_x509_crt_deinit(certs[i]);
+ g_free(certs);
sockinfo->ssl = session;
sockinfo->xcred = xcred;
diff --git a/src/common/ssl_certificate.c b/src/common/ssl_certificate.c
index 1381aa1..b48d4d4 100644
--- a/src/common/ssl_certificate.c
+++ b/src/common/ssl_certificate.c
@@ -65,6 +65,16 @@ static gchar *get_certificate_path(const gchar *host, const gchar *port, const g
host, ".", port, ".cert", NULL);
}
+static gchar *get_certificate_chain_path(const gchar *host, const gchar *port, const gchar *fp)
+{
+ gchar *tmp = get_certificate_path(host, port, fp);
+ gchar *result = g_strconcat(tmp, ".chain", NULL);
+
+ g_free(tmp);
+
+ return result;
+}
+
char * readable_fingerprint(unsigned char *src, int len)
{
int i=0;
@@ -393,6 +403,9 @@ void ssl_certificate_delete_from_disk(SSLCertificate *cert)
file = get_certificate_path(cert->host, buf, cert->fingerprint);
claws_unlink (file);
g_free(file);
+ file = get_certificate_chain_path(cert->host, buf, cert->fingerprint);
+ claws_unlink (file);
+ g_free(file);
g_free(buf);
}
@@ -507,13 +520,15 @@ static gboolean ssl_certificate_compare (SSLCertificate *cert_a, SSLCertificate
return TRUE;
}
-static guint check_cert(gnutls_x509_crt_t cert)
+static guint check_cert(SSLCertificate *cert)
{
- gnutls_x509_crt_t *ca_list;
- unsigned int max = 512;
+ gnutls_x509_crt_t *ca_list = NULL;
+ gnutls_x509_crt_t *chain = NULL;
+ unsigned int max_ca = 512, max_certs;
unsigned int flags = 0;
int r, i;
unsigned int status;
+ gchar *chain_file = NULL, *buf = NULL;
FILE *fp;
if (claws_ssl_get_cert_file())
@@ -521,16 +536,63 @@ static guint check_cert(gnutls_x509_crt_t cert)
else
return (guint)-1;
- if ((r = gnutls_import_X509_list_fp(fp, GNUTLS_X509_FMT_PEM, &ca_list, &max)) < 0) {
- debug_print("cert import failed: %s\n", gnutls_strerror(r));
+ if ((r = gnutls_import_X509_list_fp(fp, GNUTLS_X509_FMT_PEM, &ca_list, &max_ca)) < 0) {
+ debug_print("CA import failed: %s\n", gnutls_strerror(r));
fclose(fp);
return (guint)-1;
}
-
- r = gnutls_x509_crt_verify(cert, ca_list, max, flags, &status);
fclose(fp);
+ fp = NULL;
+
+ buf = g_strdup_printf("%d", cert->port);
+ chain_file = get_certificate_chain_path(cert->host, buf, cert->fingerprint);
+ g_free(buf);
+ if (is_file_exist(chain_file)) {
+ unsigned char md[128];
+ size_t n;
+ char *fingerprint;
+
+ fp = g_fopen(chain_file, "r");
+ if ((r = gnutls_import_X509_list_fp(fp, GNUTLS_X509_FMT_PEM, &chain, &max_certs)) < 0) {
+ debug_print("chain import failed: %s\n", gnutls_strerror(r));
+ fclose(fp);
+ g_free(chain_file);
+ return (guint)-1;
+ }
+ g_free(chain_file);
+ fclose(fp);
+ fp = NULL;
+
+ gnutls_x509_crt_get_fingerprint(chain[0], GNUTLS_DIG_MD5, md, &n);
+ fingerprint = readable_fingerprint(md, n);
+ if (!fingerprint || strcmp(fingerprint, cert->fingerprint)) {
+ debug_print("Saved chain fingerprint does not match current : %s / %s",
+ cert->fingerprint, fingerprint);
+
+ return (guint)-1;
+ }
+ g_free(fingerprint);
+
+ r = gnutls_x509_crt_list_verify (chain,
+ max_certs,
+ ca_list, max_ca,
+ NULL, 0,
+ GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT,
+ &status);
+ if (r < 0)
+ debug_print("chain check failed: %s\n", gnutls_strerror(r));
+
+ for (i = 0; i < max_certs; i++)
+ gnutls_x509_crt_deinit(chain[i]);
+ free(chain);
- for (i = 0; i < max; i++)
+ } else {
+ r = gnutls_x509_crt_verify(cert->x509_cert, ca_list, max_ca, flags, &status);
+ if (r < 0)
+ debug_print("cert check failed: %s\n", gnutls_strerror(r));
+ }
+
+ for (i = 0; i < max_ca; i++)
gnutls_x509_crt_deinit(ca_list[i]);
free(ca_list);
@@ -541,15 +603,20 @@ static guint check_cert(gnutls_x509_crt_t cert)
}
-char *ssl_certificate_check_signer (gnutls_x509_crt_t cert, guint status)
+char *ssl_certificate_check_signer (SSLCertificate *cert, guint status)
{
+ gnutls_x509_crt_t x509_cert = cert ? cert->x509_cert : NULL;
+
+ if (!cert)
+ return g_strdup(_("Internal error"));
+
if (status == (guint)-1) {
status = check_cert(cert);
if (status == -1)
return g_strdup(_("Uncheckable"));
}
if (status & GNUTLS_CERT_INVALID) {
- if (gnutls_x509_crt_check_issuer(cert, cert))
+ if (gnutls_x509_crt_check_issuer(x509_cert, x509_cert))
return g_strdup(_("Self-signed certificate"));
}
if (status & GNUTLS_CERT_REVOKED)
@@ -563,6 +630,43 @@ char *ssl_certificate_check_signer (gnutls_x509_crt_t cert, guint status)
return NULL;
}
+static void ssl_certificate_save_chain(gnutls_x509_crt_t *certs, gint len, const gchar *host, gushort port)
+{
+ gint i;
+ gchar *file = NULL;
+ FILE *fp = NULL;
+
+ for (i = 0; i < len; i++) {
+ size_t n;
+ unsigned char md[128];
+ gnutls_x509_crt_t cert = certs[i];
+ gchar *fingerprint;
+
+ if (i == 0) {
+ gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, md, &n);
+ fingerprint = readable_fingerprint(md, n);
+ gchar *buf = g_strdup_printf("%d", port);
+
+ file = get_certificate_chain_path(host, buf, fingerprint);
+
+ g_free(buf);
+
+ fp = g_fopen(file, "wb");
+ if (fp == NULL) {
+ g_free(file);
+ debug_print("Can't save certificate !\n");
+ return;
+ }
+ g_free(file);
+ }
+
+ gnutls_export_X509_fp(fp, cert, GNUTLS_X509_FMT_PEM);
+
+ }
+ if (fp)
+ fclose(fp);
+}
+
gboolean ssl_certificate_check (gnutls_x509_crt_t x509_cert, guint status, const gchar *host, gushort port)
{
SSLCertificate *current_cert = NULL;
@@ -663,9 +767,8 @@ gboolean ssl_certificate_check (gnutls_x509_crt_t x509_cert, guint status, const
gboolean ssl_certificate_check_chain(gnutls_x509_crt_t *certs, gint chain_len, const gchar *host, gushort port)
{
- int ncas = 0, ncrls = 0;
+ int ncas = 0;
gnutls_x509_crt_t *cas = NULL;
- gnutls_x509_crl_t *crls = NULL;
gboolean result = FALSE;
int i;
gint status;
@@ -697,6 +800,10 @@ gboolean ssl_certificate_check_chain(gnutls_x509_crt_t *certs, gint chain_len, c
result = ssl_certificate_check(certs[0], status, host, port);
+ if (result == TRUE) {
+ ssl_certificate_save_chain(certs, chain_len, host, port);
+ }
+
for (i = 0; i < ncas; i++)
gnutls_x509_crt_deinit(cas[i]);
free(cas);
diff --git a/src/common/ssl_certificate.h b/src/common/ssl_certificate.h
index fd8822a..9f4ecf0 100644
--- a/src/common/ssl_certificate.h
+++ b/src/common/ssl_certificate.h
@@ -62,7 +62,7 @@ gboolean ssl_certificate_check_chain(gnutls_x509_crt_t *certs, gint chain_len, c
void ssl_certificate_destroy(SSLCertificate *cert);
void ssl_certificate_delete_from_disk(SSLCertificate *cert);
char * readable_fingerprint(unsigned char *src, int len);
-char *ssl_certificate_check_signer (gnutls_x509_crt_t cert, guint status);
+char *ssl_certificate_check_signer (SSLCertificate *cert, guint status);
gnutls_x509_crt_t ssl_certificate_get_x509_from_pem_file(const gchar *file);
gnutls_x509_privkey_t ssl_certificate_get_pkey_from_pem_file(const gchar *file);
diff --git a/src/gtk/sslcertwindow.c b/src/gtk/sslcertwindow.c
index b03463f..c6fe7e4 100644
--- a/src/gtk/sslcertwindow.c
+++ b/src/gtk/sslcertwindow.c
@@ -151,7 +151,7 @@ static GtkWidget *cert_presenter(SSLCertificate *cert)
sha1_fingerprint = readable_fingerprint(md, (int)n);
/* signature */
- sig_status = ssl_certificate_check_signer(cert->x509_cert, cert->status);
+ sig_status = ssl_certificate_check_signer(cert, cert->status);
if (sig_status==NULL)
sig_status = g_strdup(_("Correct"));
@@ -343,7 +343,7 @@ static gboolean sslcertwindow_ask_new_cert(SSLCertificate *cert)
gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
g_free(buf);
- sig_status = ssl_certificate_check_signer(cert->x509_cert, cert->status);
+ sig_status = ssl_certificate_check_signer(cert, cert->status);
if (sig_status==NULL)
sig_status = g_strdup(_("Correct"));
@@ -392,7 +392,7 @@ static gboolean sslcertwindow_ask_expired_cert(SSLCertificate *cert)
gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0);
g_free(buf);
- sig_status = ssl_certificate_check_signer(cert->x509_cert, cert->status);
+ sig_status = ssl_certificate_check_signer(cert, cert->status);
if (sig_status==NULL)
sig_status = g_strdup(_("Correct"));
@@ -456,7 +456,7 @@ static gboolean sslcertwindow_ask_changed_cert(SSLCertificate *old_cert, SSLCert
gtk_box_pack_start(GTK_BOX(vbox2), label, TRUE, TRUE, 0);
g_free(buf);
- sig_status = ssl_certificate_check_signer(new_cert->x509_cert, new_cert->status);
+ sig_status = ssl_certificate_check_signer(new_cert, new_cert->status);
if (sig_status==NULL)
sig_status = g_strdup(_("Correct"));
diff --git a/src/ssl_manager.c b/src/ssl_manager.c
index 6cc058c..6b2f665 100644
--- a/src/ssl_manager.c
+++ b/src/ssl_manager.c
@@ -341,7 +341,7 @@ static void ssl_manager_load_certs (void)
gchar *server, *port, *fp;
SSLCertificate *cert;
- if(!strstr(d->d_name, ".cert"))
+ if(strstr(d->d_name, ".cert") != d->d_name + (strlen(d->d_name) - strlen(".cert")))
continue;
server = get_server(d->d_name);
commit 6e2e1c8bcd096d117dc22dfd9989c5c922d64f8f
Author: Colin Leroy <colin at colino.net>
Date: Wed Apr 30 11:37:05 2014 +0200
Check smtp auth if autoconfig works. This is probably required.
diff --git a/src/gtk/gtkutils.c b/src/gtk/gtkutils.c
index 9ec493c..e2c0a71 100644
--- a/src/gtk/gtkutils.c
+++ b/src/gtk/gtkutils.c
@@ -1906,6 +1906,12 @@ static void auto_configure_done(const gchar *hostname, gint port, gboolean ssl,
gtk_toggle_button_set_active(data->tls_checkbtn, TRUE);
}
+ /* Check authentication by default. This is probably required if
+ * auto-configuration worked.
+ */
+ if (data->auth_checkbtn)
+ gtk_toggle_button_set_active(data->auth_checkbtn, TRUE);
+
gtk_label_set_text(data->info_label, _("Done."));
} else {
gtk_label_set_text(data->info_label, _("Failed."));
diff --git a/src/gtk/gtkutils.h b/src/gtk/gtkutils.h
index 43649a2..8c3849f 100644
--- a/src/gtk/gtkutils.h
+++ b/src/gtk/gtkutils.h
@@ -222,6 +222,7 @@ typedef struct _AutoConfigureData {
gint default_ssl_port;
GtkToggleButton *tls_checkbtn;
GtkToggleButton *ssl_checkbtn;
+ GtkToggleButton *auth_checkbtn;
GtkLabel *info_label;
GtkButton *configure_button;
GtkButton *cancel_button;
diff --git a/src/prefs_account.c b/src/prefs_account.c
index 65c7d81..d9d52bb 100644
--- a/src/prefs_account.c
+++ b/src/prefs_account.c
@@ -3888,6 +3888,7 @@ 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->auth_checkbtn = send_page.smtp_auth_checkbtn;
auto_configure_service(send_data);
diff --git a/src/wizard.c b/src/wizard.c
index 1c05f27..c17e13d 100644
--- a/src/wizard.c
+++ b/src/wizard.c
@@ -1429,6 +1429,7 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
send_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(wizard->smtp_use_ssl);
send_data->default_port = 25;
send_data->default_ssl_port = -1;
+ send_data->auth_checkbtn = wizard->smtp_auth;
auto_configure_service(send_data);
commit 94ec77b15d34079fa6752fcd1a6a687782b07f9c
Author: Colin Leroy <colin at colino.net>
Date: Wed Apr 30 11:19:05 2014 +0200
Implement autoconfiguration in wizard
diff --git a/src/gtk/gtkutils.c b/src/gtk/gtkutils.c
index 07b8b31..9ec493c 100644
--- a/src/gtk/gtkutils.c
+++ b/src/gtk/gtkutils.c
@@ -1895,10 +1895,16 @@ static void auto_configure_done(const gchar *hostname, gint port, gboolean ssl,
g_free(tmp);
}
- if (ssl && data->ssl_checkbtn)
+ if (ssl && data->ssl_checkbtn) {
gtk_toggle_button_set_active(data->ssl_checkbtn, TRUE);
- else if (data->tls_checkbtn)
+ gtk_toggle_button_set_active(data->tls_checkbtn, FALSE);
+ } else if (data->tls_checkbtn) {
+ if (!GTK_IS_RADIO_BUTTON(data->ssl_checkbtn)) {
+ /* Wizard where TLS is [x]SSL + [x]TLS */
+ gtk_toggle_button_set_active(data->ssl_checkbtn, TRUE);
+ }
gtk_toggle_button_set_active(data->tls_checkbtn, TRUE);
+ }
gtk_label_set_text(data->info_label, _("Done."));
} else {
@@ -1943,7 +1949,7 @@ static void resolve_done(GObject *source, GAsyncResult *result, gpointer user_da
}
if (found) {
- auto_configure_done(hostname, port, TRUE, data);
+ auto_configure_done(hostname, port, data->ssl_service != NULL, data);
} else if (data->ssl_service && !abort) {
/* Fallback to TLS */
data->ssl_service = NULL;
diff --git a/src/prefs_account.c b/src/prefs_account.c
index 7740264..65c7d81 100644
--- a/src/prefs_account.c
+++ b/src/prefs_account.c
@@ -1124,7 +1124,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);
@@ -3871,14 +3871,14 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
}
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->hostname_entry = GTK_ENTRY(basic_page.smtpserv_entry);
diff --git a/src/wizard.c b/src/wizard.c
index fb677a8..1c05f27 100644
--- a/src/wizard.c
+++ b/src/wizard.c
@@ -112,6 +112,11 @@ typedef struct
GtkWidget *smtp_cert_table;
GtkWidget *recv_cert_table;
#endif
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+ GtkWidget *auto_configure_lbl;
+ GtkWidget *auto_configure_btn;
+ GtkWidget *auto_configure_cancel_btn;
+#endif
gboolean create_mailbox;
gboolean finished;
gboolean result;
@@ -1234,6 +1239,11 @@ static void wizard_protocol_change(WizardWindow *wizard, RecvProtocol protocol)
gtk_widget_show(wizard->recv_use_tls);
gtk_widget_show(wizard->recv_cert_table);
#endif
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+ gtk_widget_show(wizard->auto_configure_btn);
+ gtk_widget_hide(wizard->auto_configure_cancel_btn);
+ gtk_widget_show(wizard->auto_configure_lbl);
+#endif
gtk_label_set_text(GTK_LABEL(wizard->recv_label), _("<span weight=\"bold\">Server address:</span>"));
gtk_label_set_use_markup(GTK_LABEL(wizard->recv_label), TRUE);
gtk_dialog_set_response_sensitive (GTK_DIALOG(wizard->window), GO_FORWARD, TRUE);
@@ -1259,6 +1269,11 @@ static void wizard_protocol_change(WizardWindow *wizard, RecvProtocol protocol)
gtk_widget_show(wizard->recv_use_tls);
gtk_widget_show(wizard->recv_cert_table);
#endif
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+ gtk_widget_show(wizard->auto_configure_btn);
+ gtk_widget_hide(wizard->auto_configure_cancel_btn);
+ gtk_widget_show(wizard->auto_configure_lbl);
+#endif
gtk_label_set_text(GTK_LABEL(wizard->recv_label), _("<span weight=\"bold\">Server address:</span>"));
gtk_label_set_use_markup(GTK_LABEL(wizard->recv_label), TRUE);
gtk_dialog_set_response_sensitive (GTK_DIALOG(wizard->window), GO_FORWARD, TRUE);
@@ -1299,6 +1314,11 @@ static void wizard_protocol_change(WizardWindow *wizard, RecvProtocol protocol)
gtk_widget_hide(wizard->recv_password);
gtk_widget_hide(wizard->recv_username_label);
gtk_widget_hide(wizard->recv_password_label);
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+ gtk_widget_hide(wizard->auto_configure_btn);
+ gtk_widget_hide(wizard->auto_configure_cancel_btn);
+ gtk_widget_hide(wizard->auto_configure_lbl);
+#endif
#ifdef USE_GNUTLS
gtk_widget_hide(wizard->recv_use_ssl);
gtk_widget_hide(wizard->recv_use_tls);
@@ -1320,6 +1340,102 @@ static void wizard_protocol_changed(GtkComboBox *combo, gpointer data)
wizard_protocol_change(wizard, protocol);
}
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+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;
+ static GCancellable *send_cancel = NULL;
+ WizardWindow *wizard = (WizardWindow *)data;
+ RecvProtocol protocol = combobox_get_active_data(GTK_COMBO_BOX(wizard->recv_type));
+
+ if (!recv_cancel) {
+ recv_cancel = g_cancellable_new();
+ send_cancel = g_cancellable_new();
+ }
+
+ if (widget == wizard->auto_configure_cancel_btn) {
+ g_cancellable_cancel(recv_cancel);
+ g_cancellable_cancel(send_cancel);
+ g_object_unref(recv_cancel);
+ g_object_unref(send_cancel);
+ recv_cancel = NULL;
+ send_cancel = NULL;
+ return;
+ }
+
+ address = gtk_editable_get_chars(GTK_EDITABLE(wizard->email), 0, -1);
+
+ if (strchr(address, '@') < 0) {
+ g_free(address);
+ gtk_label_set_text(GTK_LABEL(wizard->auto_configure_lbl),
+ _("Failed (wrong address)"));
+ }
+ domain = strchr(address, '@') + 1;
+
+ if (protocol == A_POP3 || protocol == A_IMAP4) {
+ recv_data = g_new0(AutoConfigureData, 1);
+ recv_data->configure_button = GTK_BUTTON(wizard->auto_configure_btn);
+ recv_data->cancel_button = GTK_BUTTON(wizard->auto_configure_cancel_btn);
+ recv_data->info_label = GTK_LABEL(wizard->auto_configure_lbl);
+ recv_data->cancel = recv_cancel;
+ switch(protocol) {
+ case A_POP3:
+ recv_data->ssl_service = "pop3s";
+ recv_data->tls_service = "pop3";
+ recv_data->domain = g_strdup(domain);
+ recv_data->hostname_entry = GTK_ENTRY(wizard->recv_server);
+ recv_data->set_port = NULL;
+ recv_data->port = NULL;
+ recv_data->tls_checkbtn = GTK_TOGGLE_BUTTON(wizard->recv_use_tls);
+ recv_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(wizard->recv_use_ssl);
+ recv_data->default_port = 110;
+ recv_data->default_ssl_port = 995;
+ break;
+ case A_IMAP4:
+ recv_data->ssl_service = "imaps";
+ recv_data->tls_service = "imap";
+ recv_data->domain = g_strdup(domain);
+ recv_data->hostname_entry = GTK_ENTRY(wizard->recv_server);
+ recv_data->set_port = NULL;
+ recv_data->port = NULL;
+ recv_data->tls_checkbtn = GTK_TOGGLE_BUTTON(wizard->recv_use_tls);
+ recv_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(wizard->recv_use_ssl);
+ recv_data->default_port = 143;
+ recv_data->default_ssl_port = 993;
+ break;
+ default:
+ cm_return_if_fail(FALSE);
+ }
+ auto_configure_service(recv_data);
+ }
+
+ send_data = g_new0(AutoConfigureData, 1);
+ send_data->configure_button = GTK_BUTTON(wizard->auto_configure_btn);
+ send_data->cancel_button = GTK_BUTTON(wizard->auto_configure_cancel_btn);
+ send_data->info_label = GTK_LABEL(wizard->auto_configure_lbl);
+ send_data->cancel = send_cancel;
+
+ send_data->ssl_service = NULL;
+ send_data->tls_service = "submission";
+ send_data->domain = g_strdup(domain);
+ send_data->hostname_entry = GTK_ENTRY(wizard->smtp_server);
+ send_data->set_port = NULL;
+ send_data->port = NULL;
+ send_data->tls_checkbtn = GTK_TOGGLE_BUTTON(wizard->smtp_use_tls);
+ send_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(wizard->smtp_use_ssl);
+ send_data->default_port = 25;
+ send_data->default_ssl_port = -1;
+
+ auto_configure_service(send_data);
+
+ g_free(address);
+}
+#endif
+
static GtkWidget* recv_page (WizardWindow * wizard)
{
GtkWidget *table = gtk_table_new(1,1, FALSE);
@@ -1332,6 +1448,11 @@ static GtkWidget* recv_page (WizardWindow * wizard)
GtkWidget *button;
GtkWidget *recv_cert_table;
#endif
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+ GtkWidget *auto_configure_btn;
+ GtkWidget *auto_configure_cancel_btn;
+ GtkWidget *auto_configure_lbl;
+#endif
GtkListStore *store;
GtkTreeIter iter;
gchar *text;
@@ -1347,8 +1468,31 @@ static GtkWidget* recv_page (WizardWindow * wizard)
GTK_EXPAND|GTK_FILL, 0, 0, 0);
recv_table = gtk_table_new(4, 2, FALSE);
+
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+ hbox = gtk_hbox_new(FALSE, VSPACING_NARROW);
+ auto_configure_btn = gtk_button_new_with_label(_("Auto-configure"));
+ gtk_box_pack_start(GTK_BOX (hbox), auto_configure_btn, FALSE, FALSE, 0);
+ auto_configure_cancel_btn = gtk_button_new_with_label(_("Cancel"));
+ gtk_box_pack_start(GTK_BOX (hbox), auto_configure_cancel_btn, FALSE, FALSE, 0);
+ auto_configure_lbl = gtk_label_new("");
+ gtk_label_set_justify(GTK_LABEL(auto_configure_lbl), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start(GTK_BOX (hbox), auto_configure_lbl, FALSE, FALSE, 0);
+ gtk_widget_show(auto_configure_btn);
+ gtk_widget_show(auto_configure_lbl);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ wizard->auto_configure_lbl = auto_configure_lbl;
+ wizard->auto_configure_btn = auto_configure_btn;
+ wizard->auto_configure_cancel_btn = auto_configure_cancel_btn;
+ g_signal_connect (G_OBJECT (auto_configure_btn), "clicked",
+ G_CALLBACK (auto_configure_cb), wizard);
+ g_signal_connect (G_OBJECT (auto_configure_cancel_btn), "clicked",
+ G_CALLBACK (auto_configure_cb), wizard);
+#endif
gtk_box_pack_start(GTK_BOX(vbox), recv_table, FALSE, FALSE, 0);
+
label = gtk_label_new(_("<span weight=\"bold\">Server type:</span>"));
gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
@@ -1769,7 +1913,9 @@ gboolean run_wizard(MainWindow *mainwin, gboolean create_mailbox) {
gtk_widget_hide(wizard->recv_imap_label);
gtk_widget_hide(wizard->recv_imap_subdir);
gtk_widget_hide(wizard->subsonly_checkbtn);
-
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+ gtk_widget_hide(wizard->auto_configure_cancel_btn);
+#endif
wizard_protocol_change(wizard, tmpl.recvtype);
while (!wizard->finished)
commit a3b08204f9687fcf35d833bd46b61059bf6bd2b7
Author: Colin Leroy <colin at colino.net>
Date: Wed Apr 30 10:48:20 2014 +0200
Make autoconfiguration non-blocking
diff --git a/src/common/utils.c b/src/common/utils.c
index 52f6bac..472b1cc 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -5515,45 +5515,3 @@ int cm_canonicalize_filename(const gchar *filename, gchar **canonical_name) {
slist_free_strings_full(canonical_parts);
return 0;
}
-
-#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
-gboolean auto_configure_service(const gchar *service, const gchar *domain, gchar **srvhost, guint16 *srvport)
-{
- GResolver *resolver;
- GList *answers, *cur;
- GError *error = NULL;
- gboolean result = FALSE;
-
- cm_return_val_if_fail(service != NULL, FALSE);
- cm_return_val_if_fail(domain != NULL, FALSE);
-
- resolver = g_resolver_get_default();
- if (resolver == NULL)
- return FALSE;
-
- answers = g_resolver_lookup_service(resolver, service, "tcp", domain, NULL, &error);
-
- *srvhost = NULL;
- *srvport = 0;
-
- if (answers) {
- for (cur = g_srv_target_list_sort(answers); cur; cur = cur->next) {
- GSrvTarget *target = (GSrvTarget *)cur->data;
- const gchar *hostname = g_srv_target_get_hostname(target);
- guint16 port = g_srv_target_get_port(target);
- if (hostname && strcmp(hostname,"") && port > 0) {
- result = TRUE;
- *srvhost = g_strdup(hostname);
- *srvport = port;
- break;
- }
- }
- g_resolver_free_targets(answers);
- } else if (error) {
- g_error_free(error);
- }
-
- g_object_unref(resolver);
- return result;
-}
-#endif
\ No newline at end of file
diff --git a/src/common/utils.h b/src/common/utils.h
index d15c66a..434b684 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -599,10 +599,6 @@ void cm_mutex_free(GMutex *mutex);
int cm_canonicalize_filename(const gchar *filename, gchar **canonical_name);
-#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
-gboolean auto_configure_service(const gchar *service, const gchar *domain, gchar **srvhost, guint16 *srvport);
-#endif
-
#ifdef __cplusplus
}
#endif
diff --git a/src/gtk/gtkutils.c b/src/gtk/gtkutils.c
index 1f05268..07b8b31 100644
--- a/src/gtk/gtkutils.c
+++ b/src/gtk/gtkutils.c
@@ -1877,3 +1877,99 @@ GdkPixbuf *claws_load_pixbuf_fitting(GdkPixbuf *src_pixbuf, int box_width,
return pixbuf;
}
+
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+static void auto_configure_done(const gchar *hostname, gint port, gboolean ssl, AutoConfigureData *data)
+{
+ if (hostname != NULL) {
+ if (data->hostname_entry)
+ gtk_entry_set_text(data->hostname_entry, hostname);
+ if (data->set_port)
+ gtk_toggle_button_set_active(data->set_port,
+ (ssl && port == data->default_ssl_port) || (!ssl && port == data->default_port));
+ if (data->port)
+ gtk_spin_button_set_value(data->port, port);
+ else if (data->hostname_entry) {
+ gchar *tmp = g_strdup_printf("%s:%d", hostname, port);
+ gtk_entry_set_text(data->hostname_entry, tmp);
+ g_free(tmp);
+ }
+
+ if (ssl && data->ssl_checkbtn)
+ gtk_toggle_button_set_active(data->ssl_checkbtn, TRUE);
+ else if (data->tls_checkbtn)
+ gtk_toggle_button_set_active(data->tls_checkbtn, TRUE);
+
+ gtk_label_set_text(data->info_label, _("Done."));
+ } else {
+ gtk_label_set_text(data->info_label, _("Failed."));
+ }
+ gtk_widget_show(GTK_WIDGET(data->configure_button));
+ gtk_widget_hide(GTK_WIDGET(data->cancel_button));
+ g_free(data->domain);
+ g_free(data);
+}
+
+static void resolve_done(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+ AutoConfigureData *data = (AutoConfigureData *)user_data;
+ GResolver *resolver = (GResolver *)source;
+ GError *error = NULL;
+ gchar *hostname = NULL;
+ guint16 port;
+ GList *answers, *cur;
+ gboolean found = FALSE;
+ gboolean abort = FALSE;
+
+ answers = g_resolver_lookup_service_finish(resolver, result, &error);
+
+ if (answers) {
+ for (cur = g_srv_target_list_sort(answers); cur; cur = cur->next) {
+ GSrvTarget *target = (GSrvTarget *)cur->data;
+ const gchar *h = g_srv_target_get_hostname(target);
+ port = g_srv_target_get_port(target);
+ if (h && strcmp(h,"") && port > 0) {
+ hostname = g_strdup(h);
+ found = TRUE;
+ break;
+ }
+ }
+ g_resolver_free_targets(answers);
+ } else if (error) {
+ if (error->code == G_IO_ERROR_CANCELLED)
+ abort = TRUE;
+ debug_print("error %s\n", error->message);
+ g_error_free(error);
+ }
+
+ if (found) {
+ auto_configure_done(hostname, port, TRUE, data);
+ } else if (data->ssl_service && !abort) {
+ /* Fallback to TLS */
+ data->ssl_service = NULL;
+ auto_configure_service(data);
+ } else {
+ auto_configure_done(NULL, 0, FALSE, data);
+ }
+ g_free(hostname);
+ g_object_unref(resolver);
+}
+
+void auto_configure_service(AutoConfigureData *data)
+{
+ GResolver *resolver;
+ const gchar *cur_service = data->ssl_service != NULL ? data->ssl_service : data->tls_service;
+
+ cm_return_if_fail(cur_service != NULL);
+ cm_return_if_fail(data->domain != NULL);
+
+ resolver = g_resolver_get_default();
+ if (resolver != NULL) {
+ gtk_label_set_text(data->info_label, _("Configuring..."));
+ gtk_widget_hide(GTK_WIDGET(data->configure_button));
+ gtk_widget_show(GTK_WIDGET(data->cancel_button));
+ g_resolver_lookup_service_async(resolver, cur_service, "tcp", data->domain,
+ data->cancel, resolve_done, data);
+ }
+}
+#endif
\ No newline at end of file
diff --git a/src/gtk/gtkutils.h b/src/gtk/gtkutils.h
index a961dd8..43649a2 100644
--- a/src/gtk/gtkutils.h
+++ b/src/gtk/gtkutils.h
@@ -209,6 +209,30 @@ claws_input_add (gint source,
gtk_widget_set_has_tooltip(GTK_WIDGET(widget), FALSE); \
}
+#if (defined USE_GNUTLS && GLIB_CHECK_VERSION(2,22,0))
+typedef struct _AutoConfigureData {
+ const gchar *ssl_service;
+ const gchar *tls_service;
+ gchar *domain;
+
+ GtkEntry *hostname_entry;
+ GtkToggleButton *set_port;
+ GtkSpinButton *port;
+ gint default_port;
+ gint default_ssl_port;
+ GtkToggleButton *tls_checkbtn;
+ GtkToggleButton *ssl_checkbtn;
+ GtkLabel *info_label;
+ GtkButton *configure_button;
+ GtkButton *cancel_button;
+ GCancellable *cancel;
+ GMainLoop *main_loop;
+} AutoConfigureData;
+
+void auto_configure_service(AutoConfigureData *data);
+#endif
+
+
#if GTK_CHECK_VERSION (3, 2, 0)
#define GTK_TYPE_VBOX GTK_TYPE_BOX
#define GtkVBox GtkBox
diff --git a/src/prefs_account.c b/src/prefs_account.c
index d539f35..7740264 100644
--- a/src/prefs_account.c
+++ b/src/prefs_account.c
@@ -120,6 +120,7 @@ typedef struct BasicPage
GtkWidget *uid_entry;
GtkWidget *pass_entry;
GtkWidget *auto_configure_btn;
+ GtkWidget *auto_configure_cancel_btn;
GtkWidget *auto_configure_lbl;
} BasicPage;
@@ -1007,6 +1008,7 @@ static void basic_create_widget_func(PrefsPage * _page,
GtkWidget *uid_entry;
GtkWidget *pass_entry;
GtkWidget *auto_configure_btn;
+ GtkWidget *auto_configure_cancel_btn;
GtkWidget *auto_configure_lbl;
GtkListStore *menu;
GtkTreeIter iter;
@@ -1119,6 +1121,8 @@ static void basic_create_widget_func(PrefsPage * _page,
auto_configure_btn = gtk_button_new_with_label(_("Auto-configure"));
gtk_box_pack_start(GTK_BOX (optmenubox), auto_configure_btn, FALSE, FALSE, 0);
+ 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_box_pack_start(GTK_BOX (optmenubox), auto_configure_lbl, FALSE, FALSE, 0);
@@ -1127,6 +1131,8 @@ static void basic_create_widget_func(PrefsPage * _page,
gtk_widget_show(auto_configure_lbl);
g_signal_connect (G_OBJECT (auto_configure_btn), "clicked",
G_CALLBACK (auto_configure_cb), NULL);
+ g_signal_connect (G_OBJECT (auto_configure_cancel_btn), "clicked",
+ G_CALLBACK (auto_configure_cb), NULL);
#endif
no_imap_warn_icon = gtk_image_new_from_stock
@@ -1314,6 +1320,7 @@ static void basic_create_widget_func(PrefsPage * _page,
page->uid_entry = uid_entry;
page->pass_entry = pass_entry;
page->auto_configure_btn = auto_configure_btn;
+ page->auto_configure_cancel_btn = auto_configure_cancel_btn;
page->auto_configure_lbl = auto_configure_lbl;
if (new_account) {
@@ -3793,17 +3800,30 @@ 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 *service = NULL;
- const gchar *secure_service = NULL;
const gchar *domain = NULL;
- gchar *hostname;
- guint16 port = 0;
- gboolean r = FALSE;
- gboolean ssl = FALSE;
+ AutoConfigureData *recv_data;
+ AutoConfigureData *send_data;
+ static GCancellable *recv_cancel = NULL;
+ static GCancellable *send_cancel = NULL;
RecvProtocol protocol;
struct BasicProtocol *protocol_optmenu = (struct BasicProtocol *) basic_page.protocol_optmenu;
GtkWidget *optmenu = protocol_optmenu->combobox;
+ if (!recv_cancel) {
+ recv_cancel = g_cancellable_new();
+ send_cancel = g_cancellable_new();
+ }
+
+ if (widget == basic_page.auto_configure_cancel_btn) {
+ g_cancellable_cancel(recv_cancel);
+ g_cancellable_cancel(send_cancel);
+ g_object_unref(recv_cancel);
+ g_object_unref(send_cancel);
+ recv_cancel = NULL;
+ send_cancel = NULL;
+ return;
+ }
+
protocol = combobox_get_active_data(GTK_COMBO_BOX(optmenu));
address = gtk_editable_get_chars(GTK_EDITABLE(basic_page.addr_entry), 0, -1);
@@ -3815,74 +3835,62 @@ static void auto_configure_cb (GtkWidget *widget, gpointer data)
}
domain = strchr(address, '@') + 1;
- switch(protocol) {
- case A_POP3:
- secure_service = "pop3s";
- service = "pop3";
- break;
- case A_IMAP4:
- secure_service = "imaps";
- service = "imap";
- break;
- default:
- secure_service = NULL;
- service = NULL;
- }
-
- gtk_label_set_text(GTK_LABEL(basic_page.auto_configure_lbl),
- _("Configuring..."));
- GTK_EVENTS_FLUSH();
-
- if (service) {
- r = auto_configure_service(secure_service, domain, &hostname, &port);
- if (r)
- ssl = TRUE;
- else
- r = auto_configure_service(service, domain, &hostname, &port);
- }
-
- if (r) {
+ if (protocol == A_POP3 || protocol == A_IMAP4) {
+ recv_data = g_new0(AutoConfigureData, 1);
+ recv_data->configure_button = GTK_BUTTON(basic_page.auto_configure_btn);
+ recv_data->cancel_button = GTK_BUTTON(basic_page.auto_configure_cancel_btn);
+ recv_data->info_label = GTK_LABEL(basic_page.auto_configure_lbl);
+ recv_data->cancel = recv_cancel;
switch(protocol) {
case A_POP3:
- gtk_entry_set_text(GTK_ENTRY(basic_page.recvserv_entry), hostname);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(advanced_page.popport_checkbtn),
- (ssl && port == 995) || (!ssl && port == 110));
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(advanced_page.popport_spinbtn), port);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
- ssl ? ssl_page.pop_ssltunnel_radiobtn : ssl_page.pop_starttls_radiobtn),
- TRUE);
+ recv_data->ssl_service = "pop3s";
+ recv_data->tls_service = "pop3";
+ recv_data->domain = g_strdup(domain);
+ 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);
+ recv_data->tls_checkbtn = GTK_TOGGLE_BUTTON(ssl_page.pop_starttls_radiobtn);
+ recv_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(ssl_page.pop_ssltunnel_radiobtn);
+ recv_data->default_port = 110;
+ recv_data->default_ssl_port = 995;
break;
case A_IMAP4:
- gtk_entry_set_text(GTK_ENTRY(basic_page.recvserv_entry), hostname);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(advanced_page.imapport_checkbtn),
- (ssl && port == 993) || (!ssl && port == 143));
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(advanced_page.imapport_spinbtn), port);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(
- ssl ? ssl_page.imap_ssltunnel_radiobtn : ssl_page.imap_starttls_radiobtn),
- TRUE);
+ recv_data->ssl_service = "imaps";
+ recv_data->tls_service = "imap";
+ recv_data->domain = g_strdup(domain);
+ 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);
+ recv_data->tls_checkbtn = GTK_TOGGLE_BUTTON(ssl_page.imap_starttls_radiobtn);
+ recv_data->ssl_checkbtn = GTK_TOGGLE_BUTTON(ssl_page.imap_ssltunnel_radiobtn);
+ recv_data->default_port = 143;
+ recv_data->default_ssl_port = 993;
break;
default:
- secure_service = NULL;
- service = NULL;
+ cm_return_if_fail(FALSE);
}
- g_free(hostname);
- }
-
- r = auto_configure_service("submission", domain, &hostname, &port);
-
- if (r) {
- gtk_entry_set_text(GTK_ENTRY(basic_page.smtpserv_entry), hostname);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(advanced_page.smtpport_checkbtn),
- port == 25);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(advanced_page.smtpport_spinbtn), port);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ssl_page.smtp_starttls_radiobtn), TRUE);
- gtk_label_set_text(GTK_LABEL(basic_page.auto_configure_lbl),
- _("Done."));
- } else {
- gtk_label_set_text(GTK_LABEL(basic_page.auto_configure_lbl),
- _("Auto-configuration failed."));
+ 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->tls_service = "submission";
+ send_data->domain = g_strdup(domain);
+ 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);
+ send_data->tls_checkbtn = GTK_TOGGLE_BUTTON(ssl_page.smtp_starttls_radiobtn);
+ send_data->ssl_checkbtn = NULL;
+ send_data->default_port = 25;
+ send_data->default_ssl_port = -1;
+
+ auto_configure_service(send_data);
+
g_free(address);
}
#endif
commit 73088e2d091346b9770dbbb98a61e76620417f44
Author: Colin Leroy <colin at colino.net>
Date: Wed Apr 30 10:47:53 2014 +0200
Have a way for folder klasses to register specific prefs pages
diff --git a/src/folder.c b/src/folder.c
index 6fa6d78..1bd7d98 100644
--- a/src/folder.c
+++ b/src/folder.c
@@ -169,6 +169,9 @@ void folder_unregister_class(FolderClass *klass)
}
}
g_list_free(folderlist);
+
+ if (klass->prefs_pages)
+ g_slist_free(klass->prefs_pages);
}
Folder *folder_new(FolderClass *klass, const gchar *name, const gchar *path)
diff --git a/src/folder.h b/src/folder.h
index 6ba032d..b54c9f4 100644
--- a/src/folder.h
+++ b/src/folder.h
@@ -200,7 +200,12 @@ struct _FolderClass
*/
gboolean supports_server_search;
+ /**
+ * Klass-specific prefs pages
+ */
+ GSList *prefs_pages;
+
/* virtual functions */
/* Folder funtions */
diff --git a/src/prefs_folder_item.c b/src/prefs_folder_item.c
index 3402d0f..7997ab5 100644
--- a/src/prefs_folder_item.c
+++ b/src/prefs_folder_item.c
@@ -61,8 +61,6 @@
string = (value); \
}
-static void prefs_folder_item_register_page (PrefsPage *page);
-
typedef struct _FolderItemGeneralPage FolderItemGeneralPage;
typedef struct _FolderItemComposePage FolderItemComposePage;
typedef struct _FolderItemTemplatesPage FolderItemTemplatesPage;
@@ -1822,7 +1820,7 @@ static void register_general_page()
folder_item_general_page.page.destroy_widget = prefs_folder_item_general_destroy_widget_func;
folder_item_general_page.page.save_page = prefs_folder_item_general_save_func;
- prefs_folder_item_register_page((PrefsPage *) &folder_item_general_page);
+ prefs_folder_item_register_page((PrefsPage *) &folder_item_general_page, NULL);
}
@@ -1839,7 +1837,7 @@ static void register_compose_page(void)
folder_item_compose_page.page.destroy_widget = prefs_folder_item_compose_destroy_widget_func;
folder_item_compose_page.page.save_page = prefs_folder_item_compose_save_func;
- prefs_folder_item_register_page((PrefsPage *) &folder_item_compose_page);
+ prefs_folder_item_register_page((PrefsPage *) &folder_item_compose_page, NULL);
}
static void register_templates_page(void)
@@ -1855,7 +1853,7 @@ static void register_templates_page(void)
folder_item_templates_page.page.destroy_widget = prefs_folder_item_templates_destroy_widget_func;
folder_item_templates_page.page.save_page = prefs_folder_item_templates_save_func;
- prefs_folder_item_register_page((PrefsPage *) &folder_item_templates_page);
+ prefs_folder_item_register_page((PrefsPage *) &folder_item_templates_page, NULL);
}
static GSList *prefs_pages = NULL;
@@ -1873,6 +1871,8 @@ static void prefs_folder_item_address_completion_end(GtkWindow * window)
void prefs_folder_item_open(FolderItem *item)
{
gchar *id, *title;
+ GSList *pages;
+
if (prefs_pages == NULL) {
register_general_page();
register_compose_page();
@@ -1886,17 +1886,34 @@ void prefs_folder_item_open(FolderItem *item)
id = g_strdup(item->name);
can_save = FALSE;
}
+
+ pages = g_slist_concat(
+ g_slist_copy(prefs_pages),
+ g_slist_copy(item->folder->klass->prefs_pages));
+
title = g_strdup_printf (_("Properties for folder %s"), id);
g_free (id);
- prefswindow_open(title, prefs_pages, item,
+ prefswindow_open(title, pages, item,
&prefs_common.folderitemwin_width, &prefs_common.folderitemwin_height,
prefs_folder_item_address_completion_start,
prefs_folder_item_address_completion_end);
+ g_slist_free(pages);
g_free (title);
}
-static void prefs_folder_item_register_page(PrefsPage *page)
+void prefs_folder_item_register_page(PrefsPage *page, FolderClass *klass)
{
- prefs_pages = g_slist_append(prefs_pages, page);
+ if (klass != NULL)
+ klass->prefs_pages = g_slist_append(klass->prefs_pages, page);
+ else
+ prefs_pages = g_slist_append(prefs_pages, page);
}
+
+void prefs_folder_item_unregister_page(PrefsPage *page, FolderClass *klass)
+{
+ if (klass != NULL)
+ klass->prefs_pages = g_slist_remove(klass->prefs_pages, page);
+ else
+ prefs_pages = g_slist_remove(prefs_pages, page);
+}
\ No newline at end of file
diff --git a/src/prefs_folder_item.h b/src/prefs_folder_item.h
index bfe7790..189ae29 100644
--- a/src/prefs_folder_item.h
+++ b/src/prefs_folder_item.h
@@ -32,4 +32,7 @@ void prefs_folder_item_create(FolderView *folderview, FolderItem *item);
void prefs_folder_item_open (FolderItem *item);
+void prefs_folder_item_register_page(PrefsPage *page, FolderClass *klass);
+void prefs_folder_item_unregister_page(PrefsPage *page, FolderClass *klass);
+
#endif /* PREFS_FOLDER_ITEM_H */
commit 868bbb342eb035f62c003daaef076cdaedb84539
Author: Colin Leroy <colin at colino.net>
Date: Tue Apr 29 15:31:16 2014 +0200
Fix wrong free, and fix useless g_slist_concat
diff --git a/src/imap.c b/src/imap.c
index 5764922..e2eee5e 100644
--- a/src/imap.c
+++ b/src/imap.c
@@ -95,7 +95,7 @@ struct _IMAPFolder
gchar last_seen_separator;
guint refcnt;
guint max_set_size;
- const gchar *search_charset;
+ gchar *search_charset;
gboolean search_charset_supported;
};
@@ -779,7 +779,7 @@ static void imap_folder_init(Folder *folder, const gchar *name,
folder_remote_folder_init((Folder *)folder, name, path);
IMAP_FOLDER(folder)->max_set_size = IMAP_SET_MAX_COUNT;
IMAP_FOLDER(folder)->search_charset_supported = TRUE;
- IMAP_FOLDER(folder)->search_charset = conv_get_locale_charset_str_no_utf8();
+ IMAP_FOLDER(folder)->search_charset = g_strdup(conv_get_locale_charset_str_no_utf8());
}
static FolderItem *imap_folder_item_new(Folder *folder)
@@ -4434,11 +4434,8 @@ static gint get_list_of_uids(IMAPSession *session, Folder *folder, IMAPFolderIte
}
if (r == MAILIMAP_NO_ERROR) {
- GSList * fetchuid_list =
- imap_uid_list_from_lep(lep_uidlist, NULL);
+ uidlist = imap_uid_list_from_lep(lep_uidlist, NULL);
mailimap_search_result_free(lep_uidlist);
-
- uidlist = g_slist_concat(fetchuid_list, uidlist);
} else {
carray * lep_uidtab;
if (r != -1) { /* inited */
@@ -4449,10 +4446,8 @@ static gint get_list_of_uids(IMAPSession *session, Folder *folder, IMAPFolderIte
r = imap_threaded_fetch_uid(folder, 1,
&lep_uidtab);
if (r == MAILIMAP_NO_ERROR) {
- GSList * fetchuid_list =
- imap_uid_list_from_lep_tab(lep_uidtab);
+ uidlist = imap_uid_list_from_lep_tab(lep_uidtab);
imap_fetch_uid_list_free(lep_uidtab);
- uidlist = g_slist_concat(fetchuid_list, uidlist);
}
}
-----------------------------------------------------------------------
Summary of changes:
src/common/ssl.c | 72 +++++++++++++++-----
src/common/ssl_certificate.c | 131 +++++++++++++++++++++++++++++++++----
src/common/ssl_certificate.h | 2 +-
src/common/utils.c | 42 ------------
src/common/utils.h | 4 --
src/folder.c | 3 +
src/folder.h | 5 ++
src/gtk/gtkutils.c | 108 ++++++++++++++++++++++++++++++
src/gtk/gtkutils.h | 25 +++++++
src/gtk/sslcertwindow.c | 8 +--
src/imap.c | 13 ++--
src/prefs_account.c | 143 +++++++++++++++++++++-------------------
src/prefs_folder_item.c | 33 +++++++---
src/prefs_folder_item.h | 3 +
src/ssl_manager.c | 2 +-
src/wizard.c | 149 +++++++++++++++++++++++++++++++++++++++++-
16 files changed, 578 insertions(+), 165 deletions(-)
hooks/post-receive
--
Claws Mail
More information about the Commits
mailing list