[balsa] SMTP extensions: TLS client cert; rework dialog
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa] SMTP extensions: TLS client cert; rework dialog
- Date: Mon, 20 Feb 2017 00:01:17 +0000 (UTC)
commit ef318bebdbf14c677574032279c542ce9593ae94
Author: Albrecht Dreß <albrecht dress arcor de>
Date: Sun Feb 19 18:59:47 2017 -0500
SMTP extensions: TLS client cert; rework dialog
* README: make it not quite so out of date.
* libbalsa/send.c (get_auth), (get_cert_pass),
(lbs_process_queue): use client cert if required.
* libbalsa/smtp-server.c (libbalsa_smtp_server_finalize),
(libbalsa_smtp_server_new_from_config),
(libbalsa_smtp_server_save_config),
(libbalsa_smtp_server_require_client_cert),
(libbalsa_smtp_server_get_cert_file), (smtp_server_response),
(smtp_server_changed), (libbalsa_smtp_server_dialog): add
cert-related entries to LibBalsaSmtpServer, and set and use
them.
* libbalsa/smtp-server.h: add cert-related API.
Signed-off-by: Peter Bloomfield <PeterBloomfield bellsouth net>
ChangeLog | 17 +++
README | 54 ++++------
libbalsa/send.c | 34 ++++++-
libbalsa/smtp-server.c | 269 ++++++++++++++++++++++++++++++++----------------
libbalsa/smtp-server.h | 2 +
5 files changed, 249 insertions(+), 127 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 7445ae3..d700acc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2017-02-19 Peter Bloomfield <pbloomfield bellsouth net>
+
+ SMTP extensions: TLS client cert; rework config dialog
+
+ * README: make it not quite so out of date.
+ * libbalsa/send.c (get_auth), (get_cert_pass),
+ (lbs_process_queue): use client cert if required.
+ * libbalsa/smtp-server.c (libbalsa_smtp_server_finalize),
+ (libbalsa_smtp_server_new_from_config),
+ (libbalsa_smtp_server_save_config),
+ (libbalsa_smtp_server_require_client_cert),
+ (libbalsa_smtp_server_get_cert_file), (smtp_server_response),
+ (smtp_server_changed), (libbalsa_smtp_server_dialog): add
+ cert-related entries to LibBalsaSmtpServer, and set and use
+ them.
+ * libbalsa/smtp-server.h: add cert-related API.
+
2017-02-19 Albrecht Dreß
Make "Select Filters..." dialogue respect the headerbars config
diff --git a/README b/README
index ec9630f..55ac09b 100644
--- a/README
+++ b/README
@@ -116,10 +116,7 @@ messages, and for syntax highlighting in attachments.
Libraries:
---------
- Balsa uses libESMTP library available at
-http://www.stafford.uklinux.net/libesmtp/
-
-Balsa also needs the aspell spell checking libraries.
+Balsa needs the aspell spell checking libraries.
Make sure you have libtool installed (if you get some error
messages during compilation or when running precompiled binaries saying that
@@ -145,17 +142,22 @@ https://wiki.gnome.org/Git/Developers
Specifying the SMTP Server:
---------------------------
- when compiled to use libESMTP, the remote SMTP server details
-are configured on the Mail Servers tab of the Preferences dialogue box
-as follows:-
-
Remote SMTP Server:
Specify the domain name and optionally the port for of the SMTP
server you use for submitting mail. Please note that the
- default port number is 587. The syntax is hostname[:port].
- Port can be a decimal number or the name of the service as
- specified in /etc/services. Typically you can just set this to
- localhost:25.
+ default port number is 587 or 465 for SMTPS (see below). The
+ syntax is hostname[:port]. Port can be a decimal number or the
+ name of the service as specified in /etc/services. Typically
+ you can just set this to localhost:25.
+
+Security:
+ Specify the security level. For an ISP, this is typically "SMTP
+ over SSL (SMTPS)" (default port 465) or "TLS required" (default
+ 587, but many ISP's listen on port 25). If your ISP does not
+ support either, choose a different ISP. For a local connection
+ (i.e. to localhost), an unencrypted connection is fine.
+ Note that Balsa will not use the PLAIN or LOGIN authentication
+ mechanisms if the connection is not encrypted.
User:
If the remote SMTP server requires authentication, enter your
@@ -169,28 +171,14 @@ Pass Phrase:
password. Limitations on the length of the pass phrase depend
on the SMTP server.
+Client Certificate and Pass Phrase:
+ Few ISP's hand over a client certificate Balsa must present when
+ connecting. Choose the PEM-encoded certificate file and -if it
+ has an encrypted private key- set the key's pass phrase.
-TLS extension in SMTP mail submission:
---------------------------------------
-
- If you have libESMTP 0.8.5{preX} there will be a box for entry of
- the client certificate's password. The client certificate should
- be stored in PEM format in the file
-
- $HOME/.authenticate/$HOSTNAME/private/smtp-starttls.pem
-
- Both the certificate and the private key are stored in the same
- file. The permissions on the certificate file *must* be 0600 or 0400
- otherwise libESMTP will ignore it.
-
- libESMTP 0.8.4 will establish an encrypted connection with servers
- supporting STARTTLS but there is no certificate support. If the
- remote SMTP server requires a certificate, you will have to set
- "Use TLS" to "Never".
-
- Note that libESMTP 0.8.5 will only negotiate a TLS connection. It
- will not use SSLv2 or SSLv3 which are subject to downgrade
- attacks.
+Split large messages:
+ Some ISP's impose a message size limit. In this case, enter the
+ appropriate value here.
Gtk+-3 Dialog Header Bars:
diff --git a/libbalsa/send.c b/libbalsa/send.c
index d579c70..9055e73 100644
--- a/libbalsa/send.c
+++ b/libbalsa/send.c
@@ -654,8 +654,7 @@ get_auth(NetClient *client,
g_debug("%s: %p %p: encrypted = %d", __func__, client, user_data,
net_client_is_encrypted(client));
- /* Note: if the usr name is empty, we assume anonymous access */
- if ((server->try_anonymous == 0U) && (server->user != NULL) && (server->user[0] != '\0')) {
+ if (server->try_anonymous == 0U) {
result = g_new0(gchar *, 3U);
result[0] = g_strdup(server->user);
if ((server->passwd != NULL) && (server->passwd[0] != '\0')) {
@@ -668,6 +667,16 @@ get_auth(NetClient *client,
}
+static gchar *
+get_cert_pass(NetClient *client,
+ const GByteArray *cert_der,
+ gpointer user_data)
+{
+ /* FIXME - we just return the passphrase from the config, but we may also want to show a dialogue
here... */
+ return g_strdup(libbalsa_smtp_server_get_cert_passphrase(LIBBALSA_SMTP_SERVER(user_data)));
+}
+
+
/* libbalsa_process_queue:
treats given mailbox as a set of messages to send. Loads them up and
launches sending thread/routine.
@@ -700,8 +709,25 @@ lbs_process_queue(LibBalsaMailbox *outbox,
// FIXME - submission (587) is the standard, but most isp's use 25...
session = net_client_smtp_new(server->host, 587U, server->security);
}
- // FIXME - set user cert and connect cert-pass signal if we have a user cert
- g_signal_connect(G_OBJECT(session), "cert-check", G_CALLBACK(check_cert), session); // FIXME!!
+
+ /* load client certificate if configured */
+ if (libbalsa_smtp_server_require_client_cert(smtp_server)) {
+ const gchar *client_cert = libbalsa_smtp_server_get_cert_file(smtp_server);
+ GError *error = NULL;
+
+ g_signal_connect(G_OBJECT(session), "cert-pass", G_CALLBACK(get_cert_pass), smtp_server);
+ if (!net_client_set_cert_from_file(NET_CLIENT(session), client_cert, &error)) {
+ libbalsa_information(LIBBALSA_INFORMATION_ERROR,
+ _("Cannot load certificate file %s: %s"),
+ client_cert, error->message);
+ g_error_free(error);
+ g_mutex_unlock(&send_messages_lock);
+ return FALSE;
+ }
+ }
+
+ /* connect signals */
+ g_signal_connect(G_OBJECT(session), "cert-check", G_CALLBACK(check_cert), session);
g_signal_connect(G_OBJECT(session), "auth", G_CALLBACK(get_auth), smtp_server);
send_message_info =
diff --git a/libbalsa/smtp-server.c b/libbalsa/smtp-server.c
index c91e81a..d1296bd 100644
--- a/libbalsa/smtp-server.c
+++ b/libbalsa/smtp-server.c
@@ -45,8 +45,10 @@ struct _LibBalsaSmtpServer {
LibBalsaServer server;
gchar *name;
- gchar *cert_passphrase;
- guint big_message; /* size of partial messages; in kB */
+ gboolean client_cert; // FIXME - maybe move to the server base class?
+ gchar *cert_file; // FIXME - maybe move to the server base class?
+ gchar *cert_passphrase; // FIXME - maybe move to the server base class?
+ guint big_message; /* size of partial messages; in kB; 0 disables splitting */
};
typedef struct _LibBalsaSmtpServerClass {
@@ -67,6 +69,7 @@ libbalsa_smtp_server_finalize(GObject * object)
smtp_server = LIBBALSA_SMTP_SERVER(object);
g_free(smtp_server->name);
+ g_free(smtp_server->cert_file);
g_free(smtp_server->cert_passphrase);
G_OBJECT_CLASS(parent_class)->finalize(object);
@@ -152,8 +155,9 @@ libbalsa_smtp_server_new_from_config(const gchar * name)
libbalsa_server_load_config(LIBBALSA_SERVER(smtp_server));
- smtp_server->cert_passphrase =
- libbalsa_conf_private_get_string("CertificatePassphrase");
+ smtp_server->client_cert = libbalsa_conf_get_bool("NeedClientCert=false");
+ smtp_server->cert_file = libbalsa_conf_get_string("UserCertificateFile");
+ smtp_server->cert_passphrase = libbalsa_conf_private_get_string("CertificatePassphrase");
if (smtp_server->cert_passphrase) {
gchar *tmp = libbalsa_rot(smtp_server->cert_passphrase);
g_free(smtp_server->cert_passphrase);
@@ -170,6 +174,10 @@ libbalsa_smtp_server_save_config(LibBalsaSmtpServer * smtp_server)
{
libbalsa_server_save_config(LIBBALSA_SERVER(smtp_server));
+ libbalsa_conf_set_bool("NeedClientCert", smtp_server->client_cert);
+ if (smtp_server->cert_file != NULL) {
+ libbalsa_conf_set_string("UserCertificateFile", smtp_server->cert_file);
+ }
if (smtp_server->cert_passphrase) {
gchar *tmp = libbalsa_rot(smtp_server->cert_passphrase);
libbalsa_conf_private_set_string("CertificatePassphrase", tmp);
@@ -192,6 +200,18 @@ libbalsa_smtp_server_get_name(LibBalsaSmtpServer * smtp_server)
return smtp_server ? smtp_server->name : _("Default");
}
+gboolean
+libbalsa_smtp_server_require_client_cert(LibBalsaSmtpServer *smtp_server)
+{
+ return smtp_server->client_cert;
+}
+
+const gchar *
+libbalsa_smtp_server_get_cert_file(LibBalsaSmtpServer *smtp_server)
+{
+ return smtp_server->cert_file;
+}
+
void
libbalsa_smtp_server_set_cert_passphrase(LibBalsaSmtpServer * smtp_server,
const gchar * passphrase)
@@ -255,7 +275,10 @@ struct smtp_server_dialog_info {
GtkWidget *user;
GtkWidget *pass;
GtkWidget *tlsm;
- GtkWidget *cert;
+ GtkWidget *auth_button;
+ GtkWidget *cert_button;
+ GtkWidget *cert_file;
+ GtkWidget *cert_pass;
GtkWidget *split_button;
GtkWidget *big_message;
};
@@ -333,6 +356,7 @@ smtp_server_response(GtkDialog * dialog, gint response,
libbalsa_server_set_host(server,
gtk_entry_get_text(GTK_ENTRY(sdi->host)),
FALSE);
+ server->try_anonymous = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->auth_button)) ? 0U : 1U;
libbalsa_server_set_username(server,
gtk_entry_get_text(GTK_ENTRY
(sdi->user)));
@@ -340,17 +364,19 @@ smtp_server_response(GtkDialog * dialog, gint response,
gtk_entry_get_text(GTK_ENTRY
(sdi->pass)));
server->security = (NetClientCryptMode) (gtk_combo_box_get_active(GTK_COMBO_BOX(sdi->tlsm)) + 1);
+ sdi->smtp_server->client_cert = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->cert_button));
+ g_free(sdi->smtp_server->cert_file);
+ sdi->smtp_server->cert_file =
g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(sdi->cert_file)));
libbalsa_smtp_server_set_cert_passphrase(sdi->smtp_server,
gtk_entry_get_text
- (GTK_ENTRY(sdi->cert)));
- if (gtk_toggle_button_get_active
- (GTK_TOGGLE_BUTTON(sdi->split_button)))
+ (GTK_ENTRY(sdi->cert_pass)));
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->split_button))) {
/* big_message is stored in kB, but the widget is in MB. */
- LIBBALSA_SMTP_SERVER(server)->big_message =
- gtk_spin_button_get_value(GTK_SPIN_BUTTON
- (sdi->big_message)) * 1024;
- else
- LIBBALSA_SMTP_SERVER(server)->big_message = 0;
+ sdi->smtp_server->big_message =
+ gtk_spin_button_get_value(GTK_SPIN_BUTTON(sdi->big_message)) * 1024.0;
+ } else {
+ sdi->smtp_server->big_message = 0U;
+ }
break;
default:
break;
@@ -367,30 +393,61 @@ smtp_server_response(GtkDialog * dialog, gint response,
}
static void
-smtp_server_changed(GtkWidget * widget,
+smtp_server_changed(GtkWidget G_GNUC_UNUSED *widget,
struct smtp_server_dialog_info *sdi)
{
- gboolean ok;
+ gboolean sensitive;
+ gboolean enable_ok = FALSE;
- /* Minimal sanity check: Name and Host fields both non-blank. */
- ok = *gtk_entry_get_text(GTK_ENTRY(sdi->name))
- && *gtk_entry_get_text(GTK_ENTRY(sdi->host));
+ /* enable ok button only if a name and a host have been given */
+ if ((sdi->name != NULL) && (sdi->host != NULL)) {
+ enable_ok = (*gtk_entry_get_text(GTK_ENTRY(sdi->name)) != '\0')
+ && (*gtk_entry_get_text(GTK_ENTRY(sdi->host)) != '\0');
+ }
- gtk_dialog_set_response_sensitive(GTK_DIALOG(sdi->dialog),
- GTK_RESPONSE_OK, ok);
+ /* user name/password only if authentication is required */
+ if ((sdi->auth_button != NULL) && (sdi->user != NULL) && (sdi->pass != NULL)) {
+ sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->auth_button));
+ gtk_widget_set_sensitive(sdi->user, sensitive);
+ gtk_widget_set_sensitive(sdi->pass, sensitive);
+
+ /* disable ok if authentication is required, but no user name given */
+ if (sensitive && (*gtk_entry_get_text(GTK_ENTRY(sdi->user)) == '\0')) {
+ enable_ok = FALSE;
+ }
+ }
+
+ /* client certificate and passphrase stuff only if TLS/SSL is enabled */
+ if ((sdi->tlsm != NULL) && (sdi->cert_button != NULL) && (sdi->cert_file != NULL) && (sdi->cert_pass
!= NULL)) {
+ sensitive = (NetClientCryptMode) (gtk_combo_box_get_active(GTK_COMBO_BOX(sdi->tlsm)) + 1) !=
NET_CLIENT_CRYPT_NONE;
+ gtk_widget_set_sensitive(sdi->cert_button, sensitive);
+ if (sensitive) {
+ sensitive = sensitive &&
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->cert_button));
+ }
+
+ gtk_widget_set_sensitive(sdi->cert_file, sensitive);
+ gtk_widget_set_sensitive(sdi->cert_pass, sensitive);
+
+ /* disable ok if a certificate is required, but no file name given */
+ if (sensitive) {
+ gchar *cert_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(sdi->cert_file));
+
+ if ((cert_file == NULL) || (cert_file[0] == '\0')) {
+ enable_ok = FALSE;
+ }
+ g_free(cert_file);
+ }
+ }
+
+ /* split big messages */
+ if ((sdi->big_message != NULL) && (sdi->split_button != NULL)) {
+ sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->split_button));
+ gtk_widget_set_sensitive(sdi->big_message, sensitive);
+ }
+
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(sdi->dialog), GTK_RESPONSE_OK, enable_ok);
gtk_dialog_set_default_response(GTK_DIALOG(sdi->dialog),
- ok ? GTK_RESPONSE_OK :
- GTK_RESPONSE_CANCEL);
-}
-
-static void
-smtp_server_split_button_changed(GtkWidget * button,
- struct smtp_server_dialog_info *sdi)
-{
- gtk_widget_set_sensitive(sdi->big_message,
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
- (button)));
- smtp_server_changed(button, sdi);
+ enable_ok ? GTK_RESPONSE_OK : GTK_RESPONSE_CANCEL);
}
void
@@ -401,6 +458,7 @@ libbalsa_smtp_server_dialog(LibBalsaSmtpServer * smtp_server,
LibBalsaServer *server = LIBBALSA_SERVER(smtp_server);
struct smtp_server_dialog_info *sdi;
GtkWidget *dialog;
+ GtkWidget *notebook;
GtkWidget *grid;
gint row;
GtkWidget *label, *hbox;
@@ -408,12 +466,12 @@ libbalsa_smtp_server_dialog(LibBalsaSmtpServer * smtp_server,
/* Show only one dialog at a time. */
sdi = g_object_get_data(G_OBJECT(smtp_server),
LIBBALSA_SMTP_SERVER_DIALOG_KEY);
- if (sdi) {
+ if (sdi != NULL) {
gtk_window_present(GTK_WINDOW(sdi->dialog));
return;
}
- sdi = g_new(struct smtp_server_dialog_info, 1);
+ sdi = g_new0(struct smtp_server_dialog_info, 1U);
g_object_set_data_full(G_OBJECT(smtp_server),
LIBBALSA_SMTP_SERVER_DIALOG_KEY, sdi,
(GDestroyNotify) smtp_server_destroy_notify);
@@ -442,84 +500,115 @@ libbalsa_smtp_server_dialog(LibBalsaSmtpServer * smtp_server,
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK,
FALSE);
+ notebook = gtk_notebook_new();
+ gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook);
+
#define HIG_PADDING 12
- grid = libbalsa_create_grid();
- gtk_container_set_border_width(GTK_CONTAINER(grid), HIG_PADDING);
- gtk_container_add(GTK_CONTAINER
- (gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
- grid);
+ /* notebook page with basic options */
+ grid = libbalsa_create_grid();
row = 0;
- smtp_server_add_widget(grid, row, _("_Descriptive Name:"),
- sdi->name = gtk_entry_new());
- if (smtp_server->name)
+ gtk_container_set_border_width(GTK_CONTAINER(grid), HIG_PADDING);
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), grid,
+ gtk_label_new_with_mnemonic(_("_Basic")));
+
+ /* server descriptive name */
+ sdi->name = gtk_entry_new();
+ gtk_widget_set_hexpand(sdi->name, TRUE);
+ smtp_server_add_widget(grid, row, _("_Descriptive Name:"), sdi->name);
+ if (smtp_server->name != NULL) {
gtk_entry_set_text(GTK_ENTRY(sdi->name), smtp_server->name);
- g_signal_connect(sdi->name, "changed", G_CALLBACK(smtp_server_changed),
- sdi);
+ }
+ g_signal_connect(sdi->name, "changed", G_CALLBACK(smtp_server_changed), sdi);
- smtp_server_add_widget(grid, ++row, _("_Server:"),
- sdi->host = gtk_entry_new());
- if (server->host)
+ /* host and port */
+ sdi->host = gtk_entry_new();
+ smtp_server_add_widget(grid, ++row, _("_Server:"), sdi->host);
+ if (server->host != NULL) {
gtk_entry_set_text(GTK_ENTRY(sdi->host), server->host);
- g_signal_connect(sdi->host, "changed", G_CALLBACK(smtp_server_changed),
- sdi);
-
- smtp_server_add_widget(grid, ++row, _("_User Name:"),
- sdi->user = gtk_entry_new());
- if (server->user)
+ }
+ g_signal_connect(sdi->host, "changed", G_CALLBACK(smtp_server_changed), sdi);
+
+ /* security settings */
+ sdi->tlsm = smtp_server_tls_widget(smtp_server);
+ smtp_server_add_widget(grid, ++row, _("Se_curity:"), sdi->tlsm);
+ g_signal_connect(sdi->tlsm, "changed", G_CALLBACK(smtp_server_changed), sdi);
+
+ /* authentication or anonymous access */
+ sdi->auth_button = gtk_check_button_new_with_mnemonic(_("Server requires authentication"));
+ smtp_server_add_widget(grid, ++row, _("_Authentication:"), sdi->auth_button);
+ g_signal_connect(sdi->auth_button, "toggled", G_CALLBACK(smtp_server_changed), sdi);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sdi->auth_button), server->try_anonymous == 0U);
+
+ /* user name and password */
+ sdi->user = gtk_entry_new();
+ smtp_server_add_widget(grid, ++row, _("_User Name:"), sdi->user);
+ if (server->user != NULL) {
gtk_entry_set_text(GTK_ENTRY(sdi->user), server->user);
- g_signal_connect(sdi->user, "changed", G_CALLBACK(smtp_server_changed),
- sdi);
+ }
+ g_signal_connect(sdi->user, "changed", G_CALLBACK(smtp_server_changed), sdi);
- smtp_server_add_widget(grid, ++row, _("_Pass Phrase:"),
- sdi->pass = gtk_entry_new());
+ sdi->pass = gtk_entry_new();
+ smtp_server_add_widget(grid, ++row, _("_Pass Phrase:"), sdi->pass);
+ g_object_set(G_OBJECT(sdi->pass), "input-purpose", GTK_INPUT_PURPOSE_PASSWORD, NULL);
gtk_entry_set_visibility(GTK_ENTRY(sdi->pass), FALSE);
- if (server->passwd)
+ if (server->passwd != NULL) {
gtk_entry_set_text(GTK_ENTRY(sdi->pass), server->passwd);
- g_signal_connect(sdi->pass, "changed", G_CALLBACK(smtp_server_changed),
- sdi);
-
- smtp_server_add_widget(grid, ++row, _("Se_curity:"), sdi->tlsm =
- smtp_server_tls_widget(smtp_server));
- g_signal_connect(sdi->tlsm, "changed", G_CALLBACK(smtp_server_changed),
- sdi);
-
- smtp_server_add_widget(grid, ++row, _("C_ertificate Pass Phrase:"),
- sdi->cert = gtk_entry_new());
- gtk_entry_set_visibility(GTK_ENTRY(sdi->cert), FALSE);
- if (smtp_server->cert_passphrase)
- gtk_entry_set_text(GTK_ENTRY(sdi->cert),
- smtp_server->cert_passphrase);
- g_signal_connect(sdi->cert, "changed", G_CALLBACK(smtp_server_changed),
- sdi);
-
- ++row;
- sdi->split_button =
- gtk_check_button_new_with_mnemonic(_("Sp_lit message larger than"));
- gtk_grid_attach(GTK_GRID(grid), sdi->split_button, 0, row, 1, 1);
+ }
+ g_signal_connect(sdi->pass, "changed", G_CALLBACK(smtp_server_changed), sdi);
+
+ /* notebook page with advanced options */
+ grid = libbalsa_create_grid();
+ row = 0;
+ gtk_container_set_border_width(GTK_CONTAINER(grid), HIG_PADDING);
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), grid,
+ gtk_label_new_with_mnemonic(_("_Advanced")));
+
+ /* client certificate and passphrase */
+ sdi->cert_button = gtk_check_button_new_with_mnemonic(_("Server requires client certificate"));
+ smtp_server_add_widget(grid, row, _("_Client Certificate:"), sdi->cert_button);
+ g_signal_connect(sdi->cert_button, "toggled", G_CALLBACK(smtp_server_changed), sdi);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sdi->cert_button), smtp_server->client_cert);
+
+ sdi->cert_file = gtk_file_chooser_button_new(_("Choose Client Certificate"),
GTK_FILE_CHOOSER_ACTION_OPEN);
+ gtk_widget_set_hexpand(sdi->cert_file, TRUE);
+ smtp_server_add_widget(grid, ++row, _("Certificate _File:"), sdi->cert_file);
+ if (smtp_server->cert_file != NULL) {
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(sdi->cert_file), smtp_server->cert_file);
+ }
+ g_signal_connect(sdi->cert_file, "file-set", G_CALLBACK(smtp_server_changed), sdi);
+
+ sdi->cert_pass = gtk_entry_new();
+ smtp_server_add_widget(grid, ++row, _("Certificate _Pass Phrase:"), sdi->cert_pass);
+ g_object_set(G_OBJECT(sdi->cert_pass), "input-purpose", GTK_INPUT_PURPOSE_PASSWORD, NULL);
+ gtk_entry_set_visibility(GTK_ENTRY(sdi->cert_pass), FALSE);
+ if (smtp_server->cert_passphrase != NULL) {
+ gtk_entry_set_text(GTK_ENTRY(sdi->cert_pass), smtp_server->cert_passphrase);
+ }
+ g_signal_connect(sdi->cert_pass, "changed", G_CALLBACK(smtp_server_changed), sdi);
+
+ /* split large messages */
+ sdi->split_button = gtk_check_button_new_with_mnemonic(_("Sp_lit message larger than"));
+ gtk_grid_attach(GTK_GRID(grid), sdi->split_button, 0, ++row, 1, 1);
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
sdi->big_message = gtk_spin_button_new_with_range(0.1, 100, 0.1);
gtk_box_pack_start(GTK_BOX(hbox), sdi->big_message, TRUE, TRUE, 0);
label = gtk_label_new(_("MB"));
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
if (smtp_server->big_message > 0) {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sdi->split_button),
- TRUE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sdi->split_button), TRUE);
/* The widget is in MB, but big_message is stored in kB. */
gtk_spin_button_set_value(GTK_SPIN_BUTTON(sdi->big_message),
- ((float) smtp_server->big_message) /
- 1024);
+ ((gdouble) smtp_server->big_message) / 1024.0);
} else {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sdi->split_button),
- FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sdi->split_button), FALSE);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(sdi->big_message), 1);
- gtk_widget_set_sensitive(sdi->big_message, FALSE);
}
- g_signal_connect(sdi->split_button, "toggled",
- G_CALLBACK(smtp_server_split_button_changed), sdi);
- g_signal_connect(sdi->big_message, "changed",
- G_CALLBACK(smtp_server_changed), sdi);
+ g_signal_connect(sdi->split_button, "toggled", G_CALLBACK(smtp_server_changed), sdi);
+ g_signal_connect(sdi->big_message, "changed", G_CALLBACK(smtp_server_changed), sdi);
gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
+ smtp_server_changed(NULL, sdi);
+
gtk_widget_show_all(dialog);
}
diff --git a/libbalsa/smtp-server.h b/libbalsa/smtp-server.h
index 3f757f3..0915060 100644
--- a/libbalsa/smtp-server.h
+++ b/libbalsa/smtp-server.h
@@ -46,6 +46,8 @@ void libbalsa_smtp_server_set_name(LibBalsaSmtpServer * smtp_server,
const gchar * name);
const gchar *libbalsa_smtp_server_get_name(LibBalsaSmtpServer *
smtp_server);
+gboolean libbalsa_smtp_server_require_client_cert(LibBalsaSmtpServer *smtp_server);
+const gchar *libbalsa_smtp_server_get_cert_file(LibBalsaSmtpServer *smtp_server);
void libbalsa_smtp_server_set_cert_passphrase(LibBalsaSmtpServer *
smtp_server,
const gchar * passphrase);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]