Hi all, attached is a patch with a few SMTP-related extensions: 1. implement TLS client certificate support 2. rework the smtp config dialogue.
Re. #1: some ISP's use client certificates to authenticate MUA's against their mail servers, either as a machine authentication (which would still need the usual RFC 5321 authentication), or as a user authentication from the certificate's CN which is then anonymous from the SMTP pov. Client certificates are used rarely, though, and I wonder if it ever worked with the old implementation where it was possible to set the certificate passphrase, but not the certificate itself. I did not implement a dialogue for the certificate passphrase, i.e. it must be given in the config. Re. #2: I rearranged the config items for SMTP on two notebook tabs, shifting the somewhat exotic options (client cert, message splitting) to the second page. I also added more items and more controls for widget sensitivity as to distinguish between anonymous access and authentication etc. more clearly. Note that it may be necessary to check the configuration settings after applying the patch. Opinions? Cheers, Albrecht. --- Patch details: * libbalsa/smtp-server.[hc]: rework config dialogue, implement client cert related methods * libbalsa/send.c: use anonymous and client cert options * README: remove reference to libesmtp, update SMTP config options description
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);
pgpof8mFkjrUr.pgp
Description: PGP signature
_______________________________________________ balsa-list mailing list [email protected] https://mail.gnome.org/mailman/listinfo/balsa-list
