[balsa] Password dialogue improvements
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa] Password dialogue improvements
- Date: Tue, 27 Nov 2018 19:35:28 +0000 (UTC)
commit 968eebea01df1d5403d64f1ee9ed68520719f675
Author: Albrecht Dreß <albrecht dress arcor de>
Date: Tue Nov 27 14:10:35 2018 -0500
Password dialogue improvements
* libbalsa/imap-server.c, libbalsa/server-config.c, libinit_balsa/assistant_page_user.c,
src/save-restore.c: use changed libbalsa_server_set_password() api
* libbalsa/libbalsa.[c]: implement GTK_DIALOG_USE_HEADER_BAR detection as boolean for GCR dialogue
* libbalsa/server.[ch]: clean up signal definitions (remove obsolete marshallers); remove unused class
method; adjust api's for libbalsa_server_set_password(), libbalsa_server_get_password() and
libbalsa_server_get_cert_pass()
* libnetclient/net-client.[ch]: pass cert subject only instead of full binary data in the passphrase
signal
* src/balsa-app.[ch]: use GCR password dialogue if available; drop set_passwd_from_matching_server()
which is never used
Signed-off-by: Peter Bloomfield <PeterBloomfield bellsouth net>
ChangeLog | 18 +++
libbalsa/imap-server.c | 2 +-
libbalsa/libbalsa.c | 16 ++-
libbalsa/libbalsa.h | 2 +
libbalsa/server-config.c | 5 +-
libbalsa/server.c | 67 +++++-----
libbalsa/server.h | 12 +-
libinit_balsa/assistant_page_user.c | 4 +-
libnetclient/net-client.c | 29 +++--
libnetclient/net-client.h | 4 +-
src/balsa-app.c | 240 +++++++++++++++++++-----------------
src/balsa-app.h | 4 +-
src/save-restore.c | 11 +-
13 files changed, 226 insertions(+), 188 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 4c6be8749..914a2bc13 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2018-11-27 Albrecht Dreß <albrecht dress arcor de>
+
+ Password dialogue improvements
+
+ * libbalsa/imap-server.c, libbalsa/server-config.c,
+ libinit_balsa/assistant_page_user.c, src/save-restore.c: use
+ changed libbalsa_server_set_password() api
+ * libbalsa/libbalsa.[c]: implement GTK_DIALOG_USE_HEADER_BAR
+ detection as boolean for GCR dialogue
+ * libbalsa/server.[ch]: clean up signal definitions (remove
+ obsolete marshallers); remove unused class method;
+ adjust api's for libbalsa_server_set_password(),
+ libbalsa_server_get_password() and libbalsa_server_get_cert_pass()
+ * libnetclient/net-client.[ch]: pass cert subject only
+ instead of full binary data in the passphrase signal
+ * src/balsa-app.[ch]: use GCR password dialogue if available;
+ drop set_passwd_from_matching_server() which is never used
+
2018-11-04 Albrecht Dreß <albrecht dress arcor de>
Unified server configuration GUI
diff --git a/libbalsa/imap-server.c b/libbalsa/imap-server.c
index 61067c553..7f4a4ca1b 100644
--- a/libbalsa/imap-server.c
+++ b/libbalsa/imap-server.c
@@ -491,7 +491,7 @@ handle_connection_error(int rc, struct handle_info *info,
gchar *msg = imap_mbox_handle_get_last_msg(info->handle);
switch(rc) {
case IMAP_AUTH_FAILURE:
- libbalsa_server_set_password(server, NULL); break;
+ libbalsa_server_set_password(server, NULL, FALSE); break;
case IMAP_CONNECT_FAILED:
g_set_error(err, LIBBALSA_MAILBOX_ERROR,
LIBBALSA_MAILBOX_NETWORK_ERROR,
diff --git a/libbalsa/libbalsa.c b/libbalsa/libbalsa.c
index fabdcaa6e..38096642c 100644
--- a/libbalsa/libbalsa.c
+++ b/libbalsa/libbalsa.c
@@ -947,10 +947,10 @@ libbalsa_image_error_quark(void)
}
#if GTK_CHECK_VERSION(3, 12, 0)
-GtkDialogFlags
-libbalsa_dialog_flags(void)
+gboolean
+libbalsa_use_headerbar(void)
{
- static GtkDialogFlags dialog_flags = GTK_DIALOG_USE_HEADER_BAR;
+ static gboolean use_headerbar = TRUE;
static gint check_done = 0;
if (g_atomic_int_get(&check_done) == 0) {
@@ -958,10 +958,16 @@ libbalsa_dialog_flags(void)
dialog_env = g_getenv("BALSA_DIALOG_HEADERBAR");
if ((dialog_env != NULL) && (atoi(dialog_env) == 0)) {
- dialog_flags = (GtkDialogFlags) 0;
+ use_headerbar = FALSE;
}
g_atomic_int_set(&check_done, 1);
}
- return dialog_flags;
+ return use_headerbar;
+}
+
+GtkDialogFlags
+libbalsa_dialog_flags(void)
+{
+ return libbalsa_use_headerbar() ? GTK_DIALOG_USE_HEADER_BAR : (GtkDialogFlags) 0;
}
#endif
diff --git a/libbalsa/libbalsa.h b/libbalsa/libbalsa.h
index 2ce1e62be..6471340b7 100644
--- a/libbalsa/libbalsa.h
+++ b/libbalsa/libbalsa.h
@@ -191,8 +191,10 @@ enum LibBalsaImageError {
};
#if GTK_CHECK_VERSION(3, 12, 0)
+gboolean libbalsa_use_headerbar(void);
GtkDialogFlags libbalsa_dialog_flags(void);
#else
+#define libbalsa_use_headerbar() (FALSE)
#define libbalsa_dialog_flags() (GtkDialogFlags) (0)
#endif
diff --git a/libbalsa/server-config.c b/libbalsa/server-config.c
index 3c23110c7..1e00927b6 100644
--- a/libbalsa/server-config.c
+++ b/libbalsa/server-config.c
@@ -284,15 +284,14 @@ libbalsa_server_cfg_assign_server(LibBalsaServerCfg *server_cfg, LibBalsaServer
server->try_anonymous = FALSE;
}
libbalsa_server_set_username(server, gtk_entry_get_text(GTK_ENTRY(priv->username)));
- libbalsa_server_set_password(server, gtk_entry_get_text(GTK_ENTRY(priv->password)));
+ libbalsa_server_set_password(server, gtk_entry_get_text(GTK_ENTRY(priv->password)), FALSE);
server->remember_passwd = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->remember_pass));
/* client certificate */
server->client_cert = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->require_cert));
g_free(server->cert_file);
server->cert_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->cert_file));
- g_free(server->cert_passphrase);
- server->cert_passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(priv->cert_pass)));
+ libbalsa_server_set_password(server, gtk_entry_get_text(GTK_ENTRY(priv->cert_pass)), TRUE);
server->remember_cert_passphrase =
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->remember_cert_pass));
}
diff --git a/libbalsa/server.c b/libbalsa/server.c
index bb50934d1..46be161b6 100644
--- a/libbalsa/server.c
+++ b/libbalsa/server.c
@@ -69,8 +69,8 @@ static void libbalsa_server_real_set_username(LibBalsaServer * server,
static void libbalsa_server_real_set_host(LibBalsaServer *server,
const gchar *host,
NetClientCryptMode
security);
-static gchar *libbalsa_server_get_password(LibBalsaServer *server,
- LibBalsaMailbox *mbox);
+static gchar *libbalsa_server_get_password(LibBalsaServer *server,
+ gchar
*cert_subject);
static gchar *libbalsa_free_password(gchar *password);
enum {
@@ -126,8 +126,7 @@ libbalsa_server_class_init(LibBalsaServerClass * klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(LibBalsaServerClass,
set_username),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
+ NULL, NULL, NULL,
G_TYPE_NONE, 1,
G_TYPE_STRING);
libbalsa_server_signals[SET_HOST] =
@@ -136,8 +135,7 @@ libbalsa_server_class_init(LibBalsaServerClass * klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(LibBalsaServerClass,
set_host),
- NULL, NULL,
- libbalsa_VOID__POINTER_INT,
+ NULL, NULL, NULL,
G_TYPE_NONE, 2,
G_TYPE_POINTER, G_TYPE_INT
);
@@ -147,25 +145,20 @@ libbalsa_server_class_init(LibBalsaServerClass * klass)
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET(LibBalsaServerClass,
config_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
+ NULL, NULL, NULL,
G_TYPE_NONE, 0);
-
libbalsa_server_signals[GET_PASSWORD] =
g_signal_new("get-password",
G_TYPE_FROM_CLASS(object_class),
G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET(LibBalsaServerClass,
- get_password),
- NULL, NULL,
- libbalsa_POINTER__OBJECT,
- G_TYPE_POINTER, 1,
- LIBBALSA_TYPE_MAILBOX);
+ 0U,
+ NULL, NULL, NULL,
+ G_TYPE_STRING, 1,
+ G_TYPE_BYTE_ARRAY);
klass->set_username = libbalsa_server_real_set_username;
klass->set_host = libbalsa_server_real_set_host;
- klass->get_password = NULL; /* libbalsa_server_real_get_password; */
}
static void
@@ -222,14 +215,22 @@ libbalsa_server_set_username(LibBalsaServer * server,
}
void
-libbalsa_server_set_password(LibBalsaServer * server,
- const gchar * passwd)
+libbalsa_server_set_password(LibBalsaServer *server,
+ const gchar *passwd,
+ gboolean for_cert)
{
+ gchar **target;
g_return_if_fail(LIBBALSA_IS_SERVER(server));
- server->passwd = libbalsa_free_password(server->passwd);
+ if (for_cert) {
+ target = &server->cert_passphrase;
+ } else {
+ target = &server->passwd;
+ }
+
+ *target = libbalsa_free_password(*target);
if ((passwd != NULL) && (passwd[0] != '\0')) {
- server->passwd = g_strdup(passwd);
+ *target = g_strdup(passwd);
}
}
@@ -256,16 +257,15 @@ libbalsa_server_config_changed(LibBalsaServer * server)
}
static gchar *
-libbalsa_server_get_password(LibBalsaServer *server,
- LibBalsaMailbox *mbox)
+libbalsa_server_get_password(LibBalsaServer *server,
+ gchar *cert_subject)
{
gchar *retval = NULL;
g_return_val_if_fail(server != NULL, NULL);
g_return_val_if_fail(LIBBALSA_IS_SERVER(server), NULL);
- g_signal_emit(G_OBJECT(server), libbalsa_server_signals[GET_PASSWORD],
- 0, mbox, &retval);
+ g_signal_emit(G_OBJECT(server), libbalsa_server_signals[GET_PASSWORD], 0, cert_subject, &retval);
return retval;
}
@@ -290,17 +290,6 @@ libbalsa_server_real_set_host(LibBalsaServer * server, const gchar * host,
server->security = security;
}
-
-#if 0
-static gchar *
-libbalsa_server_real_get_password(LibBalsaServer * server)
-{
- g_return_val_if_fail(LIBBALSA_IS_SERVER(server), NULL);
-
- return g_strdup(server->passwd);
-}
-#endif
-
void
libbalsa_server_load_security_config(LibBalsaServer *server)
{
@@ -602,9 +591,9 @@ libbalsa_server_check_cert(NetClient *client,
gchar *
-libbalsa_server_get_cert_pass(NetClient *client,
- const GByteArray *cert_der,
- gpointer user_data)
+libbalsa_server_get_cert_pass(NetClient *client,
+ gchar *cert_subject,
+ gpointer user_data)
{
LibBalsaServer *server = LIBBALSA_SERVER(user_data);
gchar *result;
@@ -612,7 +601,7 @@ libbalsa_server_get_cert_pass(NetClient *client,
if ((server->cert_passphrase != NULL) && (server->cert_passphrase[0] != '\0')) {
result = g_strdup(server->cert_passphrase);
} else {
- result = NULL; // FIXME - dialogue to read passphrase
+ result = libbalsa_server_get_password(server, cert_subject);
}
return result;
}
diff --git a/libbalsa/server.h b/libbalsa/server.h
index 1378b91f2..7610e6341 100644
--- a/libbalsa/server.h
+++ b/libbalsa/server.h
@@ -69,15 +69,15 @@ struct _LibBalsaServerClass {
void (*set_host) (LibBalsaServer * server,
const gchar * host, NetClientCryptMode security);
void (*config_changed) (LibBalsaServer * server);
- gchar *(*get_password) (LibBalsaServer * server);
};
LibBalsaServer *libbalsa_server_new(void);
void libbalsa_server_set_username(LibBalsaServer * server,
const gchar * username);
-void libbalsa_server_set_password(LibBalsaServer * server,
- const gchar * passwd);
+void libbalsa_server_set_password(LibBalsaServer *server,
+ const gchar *passwd,
+ gboolean for_cert);
void libbalsa_server_set_host(LibBalsaServer *server,
const gchar *host,
NetClientCryptMode security);
@@ -96,9 +96,9 @@ gboolean libbalsa_server_check_cert(NetClient *client,
GTlsCertificate *peer_cert,
GTlsCertificateFlags errors,
gpointer user_data);
-gchar *libbalsa_server_get_cert_pass(NetClient *client,
- const GByteArray *cert_der,
- gpointer user_data);
+gchar *libbalsa_server_get_cert_pass(NetClient *client,
+ gchar *cert_subject,
+ gpointer user_data);
void libbalsa_server_connect_signals(LibBalsaServer * server, GCallback cb,
gpointer cb_data);
diff --git a/libinit_balsa/assistant_page_user.c b/libinit_balsa/assistant_page_user.c
index de6b7ed0a..741f76de0 100644
--- a/libinit_balsa/assistant_page_user.c
+++ b/libinit_balsa/assistant_page_user.c
@@ -202,7 +202,7 @@ create_pop3_mbx(const gchar *name, const gchar* host, gint security,
LibBalsaServer *server = LIBBALSA_MAILBOX_REMOTE_SERVER(pop);
libbalsa_server_set_username(server, login);
- libbalsa_server_set_password(server, passwd);
+ libbalsa_server_set_password(server, passwd, FALSE);
libbalsa_server_set_host(server, host, security);
server->security = security;
server->remember_passwd = remember;
@@ -225,7 +225,7 @@ create_imap_mbx(const gchar *name, const gchar* host, NetClientCryptMode securit
LibBalsaServer *server =
LIBBALSA_SERVER(libbalsa_imap_server_new(login, host));
libbalsa_server_set_username(server, login);
- libbalsa_server_set_password(server, passwd);
+ libbalsa_server_set_password(server, passwd, FALSE);
libbalsa_server_set_host(server, host, security);
server->remember_passwd = remember;
mbnode = balsa_mailbox_node_new_imap_folder(server, NULL);
diff --git a/libnetclient/net-client.c b/libnetclient/net-client.c
index 7b4c376da..39b4d17f6 100644
--- a/libnetclient/net-client.c
+++ b/libnetclient/net-client.c
@@ -395,28 +395,33 @@ net_client_set_cert_from_pem(NetClient *client, const gchar *pem_data, GError **
} else {
res = gnutls_x509_privkey_import2(key, &data, GNUTLS_X509_FMT_PEM, NULL, 0);
if (res == GNUTLS_E_DECRYPTION_FAILED) {
- size_t der_size;
- guint8 *der_data;
+ size_t dn_size;
+ gchar *dn_str;
- /* determine cert buffer size requirements */
- der_size = 0U;
- (void) gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, NULL,
&der_size);
- der_data = g_malloc(der_size); /*lint !e9079 (MISRA C:2012
Rule 11.5) */
+ /* determine dn string buffer size requirements */
+ dn_size = 0U;
+ (void) gnutls_x509_crt_get_dn(cert, NULL, &dn_size);
+ dn_str = g_malloc0(dn_size + 1U); /*lint !e9079 (MISRA
C:2012 Rule 11.5) */
- res = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_DER, der_data,
&der_size);
+ res = gnutls_x509_crt_get_dn(cert, dn_str, &dn_size);
if (res == GNUTLS_E_SUCCESS) {
- GByteArray *cert_der;
gchar *key_pass = NULL;
- cert_der = g_byte_array_new_take(der_data, der_size);
+ if (!g_utf8_validate(dn_str, -1, NULL)) {
+ gchar *buf;
+
+ buf = g_locale_to_utf8(dn_str, -1, NULL, NULL, NULL);
+ g_free(dn_str);
+ dn_str = buf;
+ }
g_debug("emit 'cert-pass' signal for client %p", client);
- g_signal_emit(client, signals[2], 0, cert_der, &key_pass);
- g_byte_array_unref(cert_der);
+ g_signal_emit(client, signals[2], 0, dn_str, &key_pass);
if (key_pass != NULL) {
res = gnutls_x509_privkey_import2(key, &data,
GNUTLS_X509_FMT_PEM, key_pass, 0);
net_client_free_authstr(key_pass);
}
}
+ g_free(dn_str);
}
/* on success, set the certificate using the unencrypted key */
@@ -594,7 +599,7 @@ net_client_class_init(NetClientClass *klass)
G_TYPE_TLS_CERTIFICATE, G_TYPE_TLS_CERTIFICATE_FLAGS);
signals[1] = g_signal_new("auth", NET_CLIENT_TYPE, G_SIGNAL_RUN_LAST, 0U, NULL, NULL, NULL,
G_TYPE_STRV, 1U, G_TYPE_BOOLEAN);
signals[2] = g_signal_new("cert-pass", NET_CLIENT_TYPE, G_SIGNAL_RUN_LAST, 0U, NULL, NULL, NULL,
G_TYPE_STRING, 1U,
- G_TYPE_BYTE_ARRAY);
+ G_TYPE_STRING);
}
diff --git a/libnetclient/net-client.h b/libnetclient/net-client.h
index cd57be4e0..d0a394e23 100644
--- a/libnetclient/net-client.h
+++ b/libnetclient/net-client.h
@@ -339,8 +339,8 @@ gboolean net_client_can_read(NetClient *client);
* The following signals are implemented:
*
* - @anchor cert-pass cert-pass
- * @code gchar *cert_pass(NetClient *client, GByteArray *peer_cert_der, gpointer user_data) @endcode The
client certificate used
- * for the connection has a password-protected key. The certificate in DER format is passed to the signal
handler, and shall
+ * @code gchar *cert_pass(NetClient *client, char *cert_subject, gpointer user_data) @endcode The client
certificate used
+ * for the connection has a password-protected key. The certificate subject is passed to the signal
handler, which shall
* return a newly allocated string containing the password. The string is wiped and freed when it is not
needed any more.
* - @anchor cert-check cert-check
* @code gboolean check_cert(NetClient *client, GTlsCertificate *peer_cert, GTlsCertificateFlags errors,
gpointer user_data)
diff --git a/src/balsa-app.c b/src/balsa-app.c
index 3d51715d4..39e23a2a9 100644
--- a/src/balsa-app.c
+++ b/src/balsa-app.c
@@ -26,11 +26,6 @@
#include <string.h>
#include <stdlib.h>
-/* for creat(2) */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
#include "filter-funcs.h"
#include "libbalsa-conf.h"
#include "misc.h"
@@ -43,22 +38,93 @@
# include "macosx-helpers.h"
#endif
+#if HAVE_GCR
+#define GCR_API_SUBJECT_TO_CHANGE
+#include <gcr/gcr.h>
+#else
+#include <gnutls/x509.h>
+#endif
+
#include <glib/gi18n.h> /* Must come after balsa-app.h. */
/* Global application structure */
struct BalsaApplication balsa_app;
+#if HAVE_GCR
+
+static gchar *
+ask_password_real(LibBalsaServer *server, const gchar *cert_subject)
+{
+#if defined(HAVE_LIBSECRET)
+ static const gchar *remember_password_message =
+ N_("_Remember password in Secret Service");
+#else
+ static const gchar *remember_password_message =
+ N_("_Remember password");
+#endif /* defined(HAVE_LIBSECRET) */
+ GcrPromptDialog *dialog;
+ gchar *prompt;
+ gboolean *remember;
+ gchar *passwd;
+
+ g_return_val_if_fail(server != NULL, NULL);
+
+ if (cert_subject != NULL) {
+ prompt = g_strdup_printf(_("Password to unlock the user certificate\n%s\nfor %s@%s (%s)"),
+ cert_subject, server->user, server->host, server->protocol);
+ remember = &server->remember_cert_passphrase;
+ } else {
+ prompt = g_strdup_printf(_("Password for %s@%s (%s)"), server->user, server->host, server->protocol);
+ remember = &server->remember_passwd;
+ }
+ dialog = g_object_new(GCR_TYPE_PROMPT_DIALOG,
+ "use-header-bar", libbalsa_use_headerbar(),
+ "title", _("Password needed"),
+ "description", prompt,
+ "message", _("Password needed"),
+ "choice-label", remember_password_message,
+ "cancel-label", _("_Cancel"),
+ "continue-label", _("_OK"),
+ "choice-chosen", *remember,
+ "destroy-with-parent", TRUE,
+ "transient-for", GTK_WINDOW(balsa_app.main_window),
+ "modal", TRUE,
+ NULL);
+ g_free(prompt);
+ passwd = g_strdup(gcr_prompt_password_run(GCR_PROMPT(dialog), NULL, NULL));
+ if (passwd != NULL) {
+ gboolean old_remember;
+
+ old_remember = *remember;
+ *remember = gcr_prompt_get_choice_chosen(GCR_PROMPT(dialog));
+ libbalsa_server_set_password(server, passwd, cert_subject != NULL);
+ if (*remember || old_remember) {
+ libbalsa_server_config_changed(server);
+ }
+ }
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+ return passwd;
+}
+
+#else
+
#define HIG_PADDING 12
/* ask_password:
asks the user for the password to the mailbox on given remote server.
*/
static gchar *
-ask_password_real(LibBalsaServer * server, LibBalsaMailbox * mbox)
+ask_password_real(LibBalsaServer * server, const gchar *cert_subject)
{
- GtkWidget *dialog, *entry, *rememb;
- GtkWidget *content_area;
- gchar *prompt, *passwd = NULL;
+ GtkWidget *dialog;
+ GtkWidget *content;
+ GtkWidget *grid;
+ GtkWidget *label;
+ GtkWidget *entry;
+ GtkWidget *rememb_check;
+ gchar *prompt;
+ gchar *passwd;
+ gboolean *remember;
#if defined(HAVE_LIBSECRET)
static const gchar *remember_password_message =
N_("_Remember password in Secret Service");
@@ -68,15 +134,14 @@ ask_password_real(LibBalsaServer * server, LibBalsaMailbox * mbox)
#endif /* defined(HAVE_LIBSECRET) */
g_return_val_if_fail(server != NULL, NULL);
- if (mbox)
- prompt =
- g_strdup_printf(_("Opening remote mailbox %s.\n"
- "The _password for %s@%s:"),
- mbox->name, server->user, server->host);
- else
- prompt =
- g_strdup_printf(_("_Password for %s@%s (%s):"), server->user,
- server->host, server->protocol);
+ if (cert_subject != NULL) {
+ prompt = g_strdup_printf(_("Password to unlock the user certificate\n%s\nfor %s@%s (%s)"),
+ cert_subject, server->user, server->host, server->protocol);
+ remember = &server->remember_cert_passphrase;
+ } else {
+ prompt = g_strdup_printf(_("Password for %s@%s (%s)"), server->user, server->host, server->protocol);
+ remember = &server->remember_passwd;
+ }
dialog = gtk_dialog_new_with_buttons(_("Password needed"),
GTK_WINDOW(balsa_app.main_window),
@@ -88,43 +153,51 @@ ask_password_real(LibBalsaServer * server, LibBalsaMailbox * mbox)
#if HAVE_MACOSX_DESKTOP
libbalsa_macosx_menu_for_parent(dialog, GTK_WINDOW(balsa_app.main_window));
#endif
- content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
- gtk_box_set_spacing(GTK_BOX(content_area), HIG_PADDING);
- gtk_container_add(GTK_CONTAINER(content_area),
- gtk_label_new_with_mnemonic(prompt));
+
+ content = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ gtk_container_set_border_width(GTK_CONTAINER(content), HIG_PADDING);
+
+ grid = libbalsa_create_grid();
+ gtk_container_add(GTK_CONTAINER(content), grid);
+
+ gtk_grid_attach(GTK_GRID(grid), gtk_label_new(prompt), 0, 0, 2, 1);
g_free(prompt);
- gtk_container_add(GTK_CONTAINER(content_area),
- entry = gtk_entry_new());
- gtk_entry_set_width_chars(GTK_ENTRY(entry), 20);
+
+ label = libbalsa_create_grid_label(_("Password:"), grid, 1);
+ entry = libbalsa_create_grid_entry(grid, NULL, NULL, 1, NULL, label);
+ g_object_set(G_OBJECT(entry), "input-purpose", GTK_INPUT_PURPOSE_PASSWORD, NULL);
gtk_entry_set_visibility(GTK_ENTRY(entry), FALSE);
+ gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+ gtk_widget_grab_focus(entry);
- rememb = gtk_check_button_new_with_mnemonic(_(remember_password_message));
- gtk_container_add(GTK_CONTAINER(content_area), rememb);
- if(server->remember_passwd)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rememb), TRUE);
+ rememb_check = libbalsa_create_grid_check(remember_password_message, grid, 2, *remember);
- gtk_widget_show_all(content_area);
- gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+ gtk_widget_show_all(grid);
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
- gtk_widget_grab_focus (entry);
-
- if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
- unsigned old_rem = server->remember_passwd;
- passwd = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
- server->remember_passwd =
- !!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rememb));
- libbalsa_server_set_password(server, passwd);
- if( server->remember_passwd || old_rem )
- libbalsa_server_config_changed(server);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
+ gboolean old_remember;
+
+ old_remember = *remember;
+ passwd = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
+ *remember = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rememb_check));
+ libbalsa_server_set_password(server, passwd, cert_subject != NULL);
+ if (*remember || old_remember) {
+ libbalsa_server_config_changed(server);
+ }
+ } else {
+ passwd = NULL;
}
gtk_widget_destroy(dialog);
return passwd;
}
+#endif
+
typedef struct {
GCond cond;
LibBalsaServer* server;
- LibBalsaMailbox* mbox;
+ const gchar *cert_subject;
gchar* res;
gboolean done;
} AskPasswdData;
@@ -136,7 +209,7 @@ static gboolean
ask_passwd_idle(gpointer data)
{
AskPasswdData* apd = (AskPasswdData*)data;
- apd->res = ask_password_real(apd->server, apd->mbox);
+ apd->res = ask_password_real(apd->server, apd->cert_subject);
apd->done = TRUE;
g_cond_signal(&apd->cond);
return FALSE;
@@ -146,7 +219,7 @@ ask_passwd_idle(gpointer data)
GDK lock must not be held.
*/
static gchar *
-ask_password_mt(LibBalsaServer * server, LibBalsaMailbox * mbox)
+ask_password_mt(LibBalsaServer * server, const gchar *cert_subject)
{
static GMutex ask_passwd_lock;
AskPasswdData apd;
@@ -154,7 +227,7 @@ ask_password_mt(LibBalsaServer * server, LibBalsaMailbox * mbox)
g_mutex_lock(&ask_passwd_lock);
g_cond_init(&apd.cond);
apd.server = server;
- apd.mbox = mbox;
+ apd.cert_subject = cert_subject;
apd.done = FALSE;
g_idle_add(ask_passwd_idle, &apd);
while (!apd.done) {
@@ -166,84 +239,27 @@ ask_password_mt(LibBalsaServer * server, LibBalsaMailbox * mbox)
return apd.res;
}
-static gboolean
-set_passwd_from_matching_server(GtkTreeModel *model,
- GtkTreePath *path,
- GtkTreeIter *iter,
- gpointer data)
-{
- LibBalsaServer *server;
- LibBalsaServer *master;
- LibBalsaMailbox *mbox;
- BalsaMailboxNode *node;
-
- gtk_tree_model_get(model, iter, 0, &node, -1);
- g_return_val_if_fail(node != NULL, FALSE);
- if(node->server) {
- server = node->server;
- g_object_unref(node);
- } else {
- mbox = node->mailbox;
- g_object_unref(node);
- if(!mbox) /* eg. a collection of mboxes */
- return FALSE;
- g_return_val_if_fail(LIBBALSA_IS_MAILBOX(mbox), FALSE);
-
- if (!LIBBALSA_IS_MAILBOX_REMOTE(mbox)) return FALSE;
- server = LIBBALSA_MAILBOX_REMOTE_SERVER(mbox);
- g_return_val_if_fail(server != NULL, FALSE);
- }
- g_return_val_if_fail(server->host != NULL, FALSE);
- g_return_val_if_fail(server->user != NULL, FALSE);
- if (server->passwd == NULL) return FALSE;
-
- master = (LibBalsaServer *)data;
- g_return_val_if_fail(LIBBALSA_IS_SERVER(master), FALSE);
- if (master == server) return FALSE;
- g_return_val_if_fail(server->host != NULL, FALSE);
- g_return_val_if_fail(server->user != NULL, FALSE);
-
- if ((strcmp(server->host, master->host) == 0) &&
- (strcmp(server->user, master->user) == 0)) {
- g_free(master->passwd);
- master->passwd = g_strdup(server->passwd);
- return TRUE;
- };
-
- return FALSE;
-}
/* ask_password:
when called from thread, gdk lock must not be held.
+ @param cert_data
*/
gchar *
-ask_password(LibBalsaServer *server, LibBalsaMailbox *mbox)
+ask_password(LibBalsaServer *server, const gchar *cert_subject, gpointer user_data)
{
+ G_LOCK_DEFINE_STATIC(ask_password);
gchar *password;
g_return_val_if_fail(server != NULL, NULL);
-
- password = NULL;
- if (mbox) {
- gtk_tree_model_foreach(GTK_TREE_MODEL(balsa_app.mblist_tree_store),
- (GtkTreeModelForeachFunc)
- set_passwd_from_matching_server, server);
-
- if (server->passwd != NULL) {
- password = server->passwd;
- server->passwd = NULL;
- }
- }
-
- if (!password) {
- G_LOCK_DEFINE_STATIC(ask_password);
- G_LOCK(ask_password);
- password = !libbalsa_am_i_subthread() ?
- ask_password_real(server, mbox) : ask_password_mt(server, mbox);
- G_UNLOCK(ask_password);
- return password;
+ G_LOCK(ask_password);
+ if (libbalsa_am_i_subthread()) {
+ password = ask_password_mt(server, cert_subject);
+ } else {
+ password = ask_password_real(server, cert_subject);
}
+ G_UNLOCK(ask_password);
+
return password;
}
diff --git a/src/balsa-app.h b/src/balsa-app.h
index 27a401dea..79ca4be1a 100644
--- a/src/balsa-app.h
+++ b/src/balsa-app.h
@@ -390,7 +390,9 @@ void balsa_app_init(void);
void balsa_app_destroy(void);
void update_timer(gboolean update, guint minutes);
-gchar *ask_password(LibBalsaServer * server, LibBalsaMailbox * mbox);
+gchar *ask_password(LibBalsaServer *server,
+ const gchar *cert_subject,
+ gpointer user_data);
void balsa_open_mailbox_list(gchar ** urls);
/* Search functions */
diff --git a/src/save-restore.c b/src/save-restore.c
index 97cc21e37..09193cf84 100644
--- a/src/save-restore.c
+++ b/src/save-restore.c
@@ -37,6 +37,7 @@
#include "filter-funcs.h"
#include "mailbox-filter.h"
#include "libbalsa-conf.h"
+#include "net-client-utils.h"
#include "smtp-server.h"
#include "send.h"
@@ -420,7 +421,7 @@ config_mailbox_init(const gchar * prefix)
if (LIBBALSA_IS_MAILBOX_REMOTE(mailbox)) {
LibBalsaServer *server = LIBBALSA_MAILBOX_REMOTE_SERVER(mailbox);
libbalsa_server_connect_signals(server,
- G_CALLBACK(ask_password), mailbox);
+ G_CALLBACK(ask_password), NULL);
g_signal_connect_swapped(server, "config-changed",
G_CALLBACK(config_mailbox_update),
mailbox);
@@ -963,15 +964,15 @@ config_global_load(void)
passphrase = libbalsa_conf_private_get_string("ESMTPPassphrase", TRUE);
if (passphrase) {
- libbalsa_server_set_password(server, passphrase);
- g_free(passphrase);
+ libbalsa_server_set_password(server, passphrase, FALSE);
+ net_client_free_authstr(passphrase);
}
passphrase =
libbalsa_conf_private_get_string("ESMTPCertificatePassphrase", TRUE);
if (passphrase) {
- g_free(server->cert_passphrase);
- server->cert_passphrase = passphrase;
+ libbalsa_server_set_password(server, passphrase, TRUE);
+ net_client_free_authstr(passphrase);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]