[balsa] Unified server configuration GUI



commit 87a3d3e987fc0600f1fb0045ffa2498b17d4ff4e
Author: Albrecht Dreß <albrecht dress arcor de>
Date:   Sun Nov 4 18:03:58 2018 -0500

    Unified server configuration GUI
    
    - libbalsa/Makefile.am, libbalsa/meson.build: add new server-config module
    - libbalsa/imap-server.c: use common config class; ensure server hash
    key required by changed folder conf approach
    - libbalsa/libbalsa-conf.[ch]: add option for obfustaced private string,
    so libbalsa_rot() is used only locally
    - libbalsa/address-book-ldap.c: use changed libbalsa-conf api
    - libbalsa/libbalsa.[ch]: libbalsa_rot() moved to libbalsa/libbalsa-conf.c
    - libbalsa/mailbox_pop3.c: properly initialise procmail command
    - libbalsa/send.c: fix broken signal connections if a user certificate
    is used
    - libbalsa/server-config.[ch]: implement new server config gui class
    - libbalsa/server.[ch]: use new config gui; refactor libsecret stuff;
    store user cert passphrase using libsecret if requested; clean up
    exported types
    - libbalsa/smtp-server.c: use new config gui
    - src/folder-conf.c: use new config gui; Note: slightly changed approach
    for adding an IMAP folder
    - src/mailbox-conf.[ch]: use new config gui, removes loads of obsolete
    exported code
    - src/mailbox-node.c: use g_debug() for debug messages
    - src/save-restore.c: use changed libbalsa-conf api
    
    Signed-off-by: Peter Bloomfield <PeterBloomfield bellsouth net>

 ChangeLog                    |  29 ++
 libbalsa/Makefile.am         |   2 +
 libbalsa/address-book-ldap.c |   8 +-
 libbalsa/imap-server.c       | 164 ++++-----
 libbalsa/imap/auth-gssapi.c  |  11 +-
 libbalsa/libbalsa-conf.c     |  61 ++++
 libbalsa/libbalsa-conf.h     |  10 +-
 libbalsa/libbalsa.c          |  26 --
 libbalsa/libbalsa.h          |   2 -
 libbalsa/mailbox_pop3.c      |   2 +-
 libbalsa/meson.build         |   2 +
 libbalsa/send.c              |   8 +-
 libbalsa/server-config.c     | 430 ++++++++++++++++++++++++
 libbalsa/server-config.h     | 142 ++++++++
 libbalsa/server.c            | 294 +++++++++++------
 libbalsa/server.h            |  27 +-
 libbalsa/smtp-server.c       | 193 +----------
 src/folder-conf.c            | 307 ++++-------------
 src/mailbox-conf.c           | 770 +++++++++----------------------------------
 src/mailbox-conf.h           |  24 --
 src/mailbox-node.c           |  45 ++-
 src/save-restore.c           |  14 +-
 22 files changed, 1207 insertions(+), 1364 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 48db7ea4d..4c6be8749 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,32 @@
+2018-11-04  Albrecht Dreß  <albrecht dress arcor de>
+
+       Unified server configuration GUI
+
+       * libbalsa/Makefile.am, libbalsa/meson.build: add new
+       server-config module
+       * libbalsa/imap-server.c: use common config class; ensure server
+       hash key required by changed folder conf approach
+       * libbalsa/libbalsa-conf.[ch]: add option for obfuscated private
+       string, so libbalsa_rot() is used only locally
+       * libbalsa/address-book-ldap.c: use changed libbalsa-conf api
+       * libbalsa/libbalsa.[ch]: libbalsa_rot() moved to
+       libbalsa/libbalsa-conf.c
+       * libbalsa/mailbox_pop3.c: properly initialise procmail command
+       * libbalsa/send.c: fix broken signal connections if a user
+       certificate is used
+       * libbalsa/server-config.[ch]: implement new server config
+       gui class
+       * libbalsa/server.[ch]: use new config gui; refactor libsecret
+       stuff; store user cert passphrase using libsecret if requested;
+       clean up exported types
+       * libbalsa/smtp-server.c: use new config gui
+       * src/folder-conf.c: use new config gui; Note: slightly changed
+       approach for adding an IMAP folder
+       * src/mailbox-conf.[ch]: use new config gui, removes loads of
+       obsolete exported code
+       * src/mailbox-node.c: use g_debug() for debug messages
+       * src/save-restore.c: use changed libbalsa-conf api
+
 2018-10-17  Peter Bloomfield  <pbloomfield bellsouth net>
 
        * src/main-window.c (bw_create_index_widget):
diff --git a/libbalsa/Makefile.am b/libbalsa/Makefile.am
index d6e01786d..e737e4011 100644
--- a/libbalsa/Makefile.am
+++ b/libbalsa/Makefile.am
@@ -150,6 +150,8 @@ libbalsa_a_SOURCES =                \
        send.h                  \
        server.c                \
        server.h                \
+       server-config.c         \
+       server-config.h         \
        smtp-server.c           \
        smtp-server.h           \
        source-viewer.c         \
diff --git a/libbalsa/address-book-ldap.c b/libbalsa/address-book-ldap.c
index a3d87484e..67c404530 100644
--- a/libbalsa/address-book-ldap.c
+++ b/libbalsa/address-book-ldap.c
@@ -835,8 +835,8 @@ libbalsa_address_book_ldap_save_config(LibBalsaAddressBook * ab,
 
     libbalsa_conf_set_string("Host", ldap->host);
     if(ldap->base_dn) libbalsa_conf_set_string("BaseDN", ldap->base_dn);
-    if(ldap->bind_dn) libbalsa_conf_private_set_string("BindDN", ldap->bind_dn);
-    if(ldap->passwd)  libbalsa_conf_private_set_string("Passwd", ldap->passwd);
+    if(ldap->bind_dn) libbalsa_conf_private_set_string("BindDN", ldap->bind_dn, FALSE);
+    if(ldap->passwd)  libbalsa_conf_private_set_string("Passwd", ldap->passwd, FALSE);
     if(ldap->priv_book_dn)
         libbalsa_conf_set_string("BookDN", ldap->priv_book_dn);
     libbalsa_conf_set_bool("EnableTLS", ldap->enable_tls);
@@ -860,11 +860,11 @@ libbalsa_address_book_ldap_load_config(LibBalsaAddressBook * ab,
        g_free(ldap->base_dn); ldap->base_dn = NULL; 
     }
 
-    ldap->bind_dn = libbalsa_conf_private_get_string("BindDN");
+    ldap->bind_dn = libbalsa_conf_private_get_string("BindDN", FALSE);
     if(ldap->bind_dn && *ldap->bind_dn == 0) { 
        g_free(ldap->bind_dn); ldap->bind_dn = NULL; 
     }
-    ldap->passwd = libbalsa_conf_private_get_string("Passwd");
+    ldap->passwd = libbalsa_conf_private_get_string("Passwd", FALSE);
     if(ldap->passwd && *ldap->passwd == 0) { 
        g_free(ldap->passwd); ldap->passwd = NULL; 
     }
diff --git a/libbalsa/imap-server.c b/libbalsa/imap-server.c
index 7bea82422..61067c553 100644
--- a/libbalsa/imap-server.c
+++ b/libbalsa/imap-server.c
@@ -30,10 +30,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-#if defined(HAVE_LIBSECRET)
-#include <libsecret/secret.h>
-#endif                          /* defined(HAVE_LIBSECRET) */
-
 #include "libbalsa.h"
 #include "libbalsa-conf.h"
 #include "server.h"
@@ -59,13 +55,13 @@ struct LibBalsaImapServer_ {
     guint used_connections;
     GList *used_handles;
     GList *free_handles;
-    unsigned persistent_cache:1; /* if TRUE, messages will be cached in
+    gboolean persistent_cache; /* if TRUE, messages will be cached in
                                     $HOME and preserved between
                                     sessions. If FALSE, messages will be
                                     kept in /tmp and cleaned on exit. */
-    unsigned has_fetch_bug:1;
-    unsigned use_status:1; /**< server has fast STATUS command */
-    unsigned use_idle:1;  /**< IDLE will work: no dummy firewall on the way */
+    gboolean has_fetch_bug;
+    gboolean use_status; /**< server has fast STATUS command */
+    gboolean use_idle;  /**< IDLE will work: no dummy firewall on the way */
 };
 
 typedef struct LibBalsaImapServerClass_ {
@@ -138,6 +134,9 @@ static void libbalsa_imap_server_set_username(LibBalsaServer * server,
     if(server->host && name) { /* we have been initialized... */
         LibBalsaImapServer *imap_server = LIBBALSA_IMAP_SERVER(server);
         
+        if (imap_server->key == NULL) {
+               imap_server->key = g_strdup_printf("%s@%s", name, server->host);
+        }
         g_mutex_lock(&imap_servers_lock);
         g_hash_table_steal(imap_servers, imap_server->key);
         g_free(imap_server->key);
@@ -147,6 +146,7 @@ static void libbalsa_imap_server_set_username(LibBalsaServer * server,
     }
     (parent_class)->set_username(server, name);
 }
+
 static void
 libbalsa_imap_server_set_host(LibBalsaServer     *server,
                               const gchar        *host,
@@ -154,6 +154,10 @@ libbalsa_imap_server_set_host(LibBalsaServer     *server,
 {
     if(server->user && host) { /* we have been initialized... */
         LibBalsaImapServer *imap_server = LIBBALSA_IMAP_SERVER(server);
+
+        if (imap_server->key == NULL) {
+               imap_server->key = g_strdup_printf("%s@%s", server->user, host);
+        }
         g_mutex_lock(&imap_servers_lock);
         g_hash_table_steal(imap_servers, imap_server->key);
         g_free(imap_server->key);
@@ -163,6 +167,7 @@ libbalsa_imap_server_set_host(LibBalsaServer     *server,
     }
     (parent_class)->set_host(server, host, security);
 }
+
 static void
 libbalsa_imap_server_class_init(LibBalsaImapServerClass * klass)
 {
@@ -405,108 +410,64 @@ LibBalsaImapServer* libbalsa_imap_server_new(const gchar *username,
     return get_or_create(username, host);
 }
 
+static inline void
+set_bool_if_defined(const gchar *path, gboolean *dest)
+{
+       gboolean dflt;
+       gboolean val;
+
+    val = libbalsa_conf_get_bool_with_default(path, &dflt);
+    if (!dflt) {
+       *dest = val;
+    }
+}
+
 LibBalsaImapServer*
 libbalsa_imap_server_new_from_config(void)
 {
-    LibBalsaServer tmp_server;
+       gchar *host;
+       gchar *user;
     LibBalsaImapServer *imap_server;
     LibBalsaServer *server;
-    gboolean d, d1;
-    gint conn_limit;
+    gboolean d;
 
-    tmp_server.host = libbalsa_conf_get_string("Server");
-    if(strrchr(tmp_server.host, ':') == NULL) {
+    host = libbalsa_conf_get_string("Server");
+    if (strrchr(host, ':') == NULL) {
         gint port;
+
         port = libbalsa_conf_get_int_with_default("Port", &d);
         if (!d) {
-            gchar *newhost = g_strdup_printf("%s:%d", tmp_server.host, port);
-            g_free(tmp_server.host);
-            tmp_server.host = newhost;
+            gchar *newhost = g_strdup_printf("%s:%d", host, port);
+            g_free(host);
+            host = newhost;
         }
     }       
-    tmp_server.user = libbalsa_conf_private_get_string("Username");
-    if (!tmp_server.user)
-        tmp_server.user = g_strdup(getenv("USER"));
+    user = libbalsa_conf_private_get_string("Username", FALSE);
+    if (user == NULL) {
+        user = g_strdup(g_get_user_name());
+    }
 
-    imap_server = get_or_create(tmp_server.user, tmp_server.host);
+    imap_server = get_or_create(user, host);
+    g_free(user);
+    g_free(host);
     server = LIBBALSA_SERVER(imap_server);
-    if (server->user) {
-        g_free(tmp_server.user);
-        g_free(tmp_server.host);
-    } else {
-        server->user = tmp_server.user;
-        server->host = tmp_server.host;
-    }
-    d1 = libbalsa_conf_get_bool_with_default("Anonymous", &d);
-    if(!d) server->try_anonymous = !!d1;
-    libbalsa_server_load_security_config(server);
-    conn_limit = libbalsa_conf_get_int_with_default("ConnectionLimit", &d);
-    if(!d) imap_server->max_connections = conn_limit;
-    d1 = libbalsa_conf_get_bool_with_default("PersistentCache", &d);
-    if(!d) imap_server->persistent_cache = !!d1;
-    d1 = libbalsa_conf_get_bool_with_default("HasFetchBug", &d);
-    if(!d) imap_server->has_fetch_bug = !!d1;
-    d1 = libbalsa_conf_get_bool_with_default("UseStatus", &d);
-    if(!d) imap_server->use_status = !!d1;
-    d1 = libbalsa_conf_get_bool_with_default("UseIdle", &d);
-    if(!d) imap_server->use_idle = !!d1;
-    if (!server->passwd) {
-        server->remember_passwd = libbalsa_conf_get_bool("RememberPasswd=false");
-        if(server->remember_passwd) {
-#if defined(HAVE_LIBSECRET)
-            GError *err = NULL;
-
-            server->passwd =
-                secret_password_lookup_sync(LIBBALSA_SERVER_SECRET_SCHEMA,
-                                            NULL, &err,
-                                            "protocol", server->protocol,
-                                            "server",   server->host,
-                                            "user",     server->user,
-                                            NULL);
-            if (err) {
-                libbalsa_free_password(server->passwd);
-                server->passwd = NULL;
-                printf(_("Error looking up password for %s@%s: %s\n"),
-                       server->user, server->host, err->message);
-                printf(_("Falling back\n"));
-                g_clear_error(&err);
-                server->passwd =
-                    libbalsa_conf_private_get_string("Password");
-                if (server->passwd != NULL) {
-                    gchar *buff = libbalsa_rot(server->passwd);
-                    libbalsa_free_password(server->passwd);
-                    server->passwd = buff;
-                    secret_password_store_sync
-                        (LIBBALSA_SERVER_SECRET_SCHEMA, NULL,
-                         _("Balsa passwords"), server->passwd, NULL, &err,
-                         "protocol", server->protocol,
-                         "server",   server->host,
-                         "user",     server->user,
-                         NULL);
-                    /* We could in principle clear the password in the
-                     * config file here but we do not for the backward
-                     * compatibility. */
-                    if (err) {
-                        printf(_("Error storing password for %s@%s: %s\n"),
-                               server->user, server->host, err->message);
-                        g_error_free(err);
-                    }
-                }
-            }
-#else
-            server->passwd = libbalsa_conf_private_get_string("Password");
-           if (server->passwd != NULL) {
-               gchar *buff = libbalsa_rot(server->passwd);
-               libbalsa_free_password(server->passwd);
-               server->passwd = buff;
-           }
-#endif                          /* defined(HAVE_LIBSECRET) */
-       }
-        if(server->passwd && server->passwd[0] == '\0') {
-            libbalsa_free_password(server->passwd);
-            server->passwd = NULL;
+    if (server->host == NULL) {
+        gint conn_limit;
+
+        /* common server configs */
+       libbalsa_server_load_config(server);
+
+       /* imap specials */
+        conn_limit = libbalsa_conf_get_int_with_default("ConnectionLimit", &d);
+        if (!d) {
+               imap_server->max_connections = conn_limit;
         }
+        set_bool_if_defined("PersistentCache", &imap_server->persistent_cache);
+        set_bool_if_defined("HasFetchBug", &imap_server->has_fetch_bug);
+        set_bool_if_defined("UseStatus", &imap_server->use_status);
+        set_bool_if_defined("UseIdle", &imap_server->use_idle);
     }
+
     return imap_server;
 }
 
@@ -766,7 +727,7 @@ libbalsa_imap_server_set_max_connections(LibBalsaImapServer *server,
                                          int max)
 {
     server->max_connections = max;
-    printf("set_max_connections: set to %d\n", max);
+    g_debug("set_max_connections: set to %d", max);
 }
 
 int
@@ -779,7 +740,7 @@ void
 libbalsa_imap_server_enable_persistent_cache(LibBalsaImapServer *server,
                                              gboolean enable)
 {
-    server->persistent_cache = !!enable;
+    server->persistent_cache = enable;
 }
 gboolean
 libbalsa_imap_server_has_persistent_cache(LibBalsaImapServer *srv)
@@ -884,7 +845,7 @@ void
 libbalsa_imap_server_set_bug(LibBalsaImapServer *server,
                              LibBalsaImapServerBug bug, gboolean hasp)
 {
-    server->has_fetch_bug = !! hasp;
+    server->has_fetch_bug = hasp;
 }
 
 gboolean
@@ -898,7 +859,7 @@ void
 libbalsa_imap_server_set_use_status(LibBalsaImapServer *server, 
                                     gboolean use_status)
 {
-    server->use_status = !!use_status;
+    server->use_status = use_status;
 }
 gboolean
 libbalsa_imap_server_get_use_status(LibBalsaImapServer *server)
@@ -912,9 +873,8 @@ libbalsa_imap_server_set_use_idle(LibBalsaImapServer *server,
 {
     GList *list;
 
-    server->use_idle = !!use_idle;
-    printf("Server will%s use IDLE\n",
-           server->use_idle ? "" : " NOT");
+    server->use_idle = use_idle;
+    g_debug("Server will%s use IDLE", server->use_idle ? "" : " NOT");
     for (list = server->used_handles; list; list = list->next) {
         struct handle_info *info = list->data;
         imap_handle_set_option(info->handle, IMAP_OPT_IDLE,
diff --git a/libbalsa/imap/auth-gssapi.c b/libbalsa/imap/auth-gssapi.c
index 1c382d502..14a2de569 100644
--- a/libbalsa/imap/auth-gssapi.c
+++ b/libbalsa/imap/auth-gssapi.c
@@ -115,6 +115,7 @@ imap_gss_auth_loop(ImapMboxHandle* handle, NetClientGssCtx *gss_ctx, unsigned cm
 ImapResult
 imap_auth_gssapi(ImapMboxHandle* handle)
 {
+       gchar **auth_data;
     NetClientGssCtx *gss_ctx;
     GError *error = NULL;
     ImapResult retval;
@@ -123,8 +124,15 @@ imap_auth_gssapi(ImapMboxHandle* handle)
         return IMAP_AUTH_UNAVAIL;
     }
 
+    g_signal_emit_by_name(handle->sio, "auth", FALSE, &auth_data);
+    if((auth_data == NULL) || (auth_data[0] == NULL)) {
+       imap_mbox_handle_set_msg(handle, "User name required, authentication cancelled");
+       g_strfreev(auth_data);
+       return IMAP_AUTH_CANCELLED;
+    }
+
     /* try to create the context */
-    gss_ctx = net_client_gss_ctx_new("imap", handle->host, "test", &error);
+    gss_ctx = net_client_gss_ctx_new("imap", handle->host, auth_data[0], &error);
     if (gss_ctx == NULL) {
        retval = IMAP_AUTH_UNAVAIL;
     } else {
@@ -145,6 +153,7 @@ imap_auth_gssapi(ImapMboxHandle* handle)
                net_client_gss_ctx_free(gss_ctx);
                retval = (result && (rc == IMR_OK)) ? IMAP_SUCCESS : IMAP_AUTH_UNAVAIL;
     }
+       g_strfreev(auth_data);
 
     if (error != NULL) {
         gchar *err_msg;
diff --git a/libbalsa/libbalsa-conf.c b/libbalsa/libbalsa-conf.c
index c376b0391..7a7083a10 100644
--- a/libbalsa/libbalsa-conf.c
+++ b/libbalsa/libbalsa-conf.c
@@ -48,6 +48,9 @@ static LibBalsaConf lbc_conf;
 static LibBalsaConf lbc_conf_priv;
 static GSList *lbc_groups;
 
+static gchar * libbalsa_rot(const gchar * pass)
+       G_GNUC_WARN_UNUSED_RESULT;
+
 #define BALSA_KEY_FILE "config"
 #define DEBUG FALSE
 #define LBC_KEY_FILE(priv) \
@@ -411,6 +414,21 @@ libbalsa_conf_set_string_(const char *path, const char *value,
     LBC_CHANGED(priv);
 }
 
+void
+libbalsa_conf_private_set_string(const gchar *path, const gchar *value, gboolean obfuscated)
+{
+       if (obfuscated && (value != NULL)) {
+               gchar *obf;
+
+               obf = libbalsa_rot(value);
+               libbalsa_conf_set_string_(path, obf, TRUE);
+               memset(obf, 0, strlen(obf));
+               g_free(obf);
+       } else {
+               libbalsa_conf_set_string_(path, value, TRUE);
+       }
+}
+
 gchar *
 libbalsa_conf_get_string_with_default_(const char *path, gboolean * def,
                                        gboolean priv)
@@ -436,6 +454,23 @@ libbalsa_conf_get_string_with_default_(const char *path, gboolean * def,
     return retval;
 }
 
+gchar *
+libbalsa_conf_private_get_string(const gchar *path, gboolean obfuscated)
+{
+       gchar *result;
+
+       result = libbalsa_conf_get_string_with_default_(path, NULL, TRUE);
+       if (obfuscated && (result != NULL)) {
+               gchar *deob;
+
+               deob = libbalsa_rot(result);
+               memset(result, 0, strlen(result));
+               g_free(result);
+               result = deob;
+       }
+       return result;
+}
+
 void
 libbalsa_conf_set_vector(const char *path, int argc,
                          const char *const argv[])
@@ -568,3 +603,29 @@ libbalsa_conf_queue_sync(void)
 #endif                          /* DEBUG */
     G_UNLOCK(lbc_sync_idle_id);
 }
+
+
+/* libbalsa_rot:
+   return rot13'ed string.
+*/
+static gchar *
+libbalsa_rot(const gchar * pass)
+{
+    gchar *buff;
+    gint len = 0, i = 0;
+
+    /*PKGW: let's do the assert() BEFORE we coredump... */
+
+    len = strlen(pass);
+    buff = g_strdup(pass);
+
+    for (i = 0; i < len; i++) {
+       if ((buff[i] <= 'M' && buff[i] >= 'A')
+           || (buff[i] <= 'm' && buff[i] >= 'a'))
+           buff[i] += 13;
+       else if ((buff[i] <= 'Z' && buff[i] >= 'N')
+                || (buff[i] <= 'z' && buff[i] >= 'n'))
+           buff[i] -= 13;
+    }
+    return buff;
+}
diff --git a/libbalsa/libbalsa-conf.h b/libbalsa/libbalsa-conf.h
index e566ca274..a5b6e40f3 100644
--- a/libbalsa/libbalsa-conf.h
+++ b/libbalsa/libbalsa-conf.h
@@ -95,8 +95,9 @@ void libbalsa_conf_set_string_               (const char *path,
                                               gboolean priv);
 #define libbalsa_conf_set_string(path,new_value) \
         (libbalsa_conf_set_string_((path),(new_value),FALSE))
-#define libbalsa_conf_private_set_string(path,new_value) \
-        (libbalsa_conf_set_string_((path),(new_value),TRUE))
+void libbalsa_conf_private_set_string(const gchar *path,
+                                                                 const gchar *value,
+                                                                         gboolean     obfuscated);
 
 char *libbalsa_conf_get_string_with_default_ (const char *path,
                                               gboolean * def,
@@ -105,8 +106,9 @@ char *libbalsa_conf_get_string_with_default_ (const char *path,
         (libbalsa_conf_get_string_with_default_((path),NULL, FALSE))
 #define libbalsa_conf_get_string_with_default(path, def) \
         (libbalsa_conf_get_string_with_default_((path),(def), FALSE))
-#define libbalsa_conf_private_get_string(path) \
-        (libbalsa_conf_get_string_with_default_((path),NULL, TRUE))
+gchar *libbalsa_conf_private_get_string(const gchar *path,
+                                                                               gboolean         obfuscated)
+       G_GNUC_WARN_UNUSED_RESULT;
 
 void libbalsa_conf_set_vector                (const char *path,
                                              int argc,
diff --git a/libbalsa/libbalsa.c b/libbalsa/libbalsa.c
index ad43ea921..fabdcaa6e 100644
--- a/libbalsa/libbalsa.c
+++ b/libbalsa/libbalsa.c
@@ -114,32 +114,6 @@ libbalsa_init(void)
 }
 
 
-/* libbalsa_rot:
-   return rot13'ed string.
-*/
-gchar *
-libbalsa_rot(const gchar * pass)
-{
-    gchar *buff;
-    gint len = 0, i = 0;
-
-    /*PKGW: let's do the assert() BEFORE we coredump... */
-
-    len = strlen(pass);
-    buff = g_strdup(pass);
-
-    for (i = 0; i < len; i++) {
-       if ((buff[i] <= 'M' && buff[i] >= 'A')
-           || (buff[i] <= 'm' && buff[i] >= 'a'))
-           buff[i] += 13;
-       else if ((buff[i] <= 'Z' && buff[i] >= 'N')
-                || (buff[i] <= 'z' && buff[i] >= 'n'))
-           buff[i] -= 13;
-    }
-    return buff;
-}
-
-
 /* libbalsa_guess_email_address:
    Email address can be determined in four ways:
    1. Using the environment variable 'EMAIL'
diff --git a/libbalsa/libbalsa.h b/libbalsa/libbalsa.h
index df5865bc0..2ce1e62be 100644
--- a/libbalsa/libbalsa.h
+++ b/libbalsa/libbalsa.h
@@ -119,7 +119,6 @@ void libbalsa_show_message_source(GtkApplication * application,
                                   const gchar * font,
                                   gboolean *escape_specials,
                                   gint * width, gint * height);
-gchar *libbalsa_rot(const gchar * pass);
 
 gchar *libbalsa_guess_email_address(void);
 gchar *libbalsa_guess_mail_spool(void);
@@ -143,7 +142,6 @@ GThread *libbalsa_get_main_thread(void);
 gboolean libbalsa_am_i_subthread(void);
 void libbalsa_message(const char *fmt, ...)
        G_GNUC_PRINTF(1, 2);
-gchar * libbalsa_rot(const gchar * pass);
 
 typedef enum {
     LIBBALSA_PROGRESS_NO = 0,
diff --git a/libbalsa/mailbox_pop3.c b/libbalsa/mailbox_pop3.c
index 7ac1a6520..f72016574 100644
--- a/libbalsa/mailbox_pop3.c
+++ b/libbalsa/mailbox_pop3.c
@@ -126,7 +126,7 @@ libbalsa_mailbox_pop3_init(LibBalsaMailboxPop3 * mailbox)
     mailbox->msg_size_limit = -1;
 
     mailbox->filter = FALSE;
-    mailbox->filter_cmd = NULL;
+    mailbox->filter_cmd = g_strdup("procmail -f -");
     remote = LIBBALSA_MAILBOX_REMOTE(mailbox);
     remote->server = libbalsa_server_new();
 }
diff --git a/libbalsa/meson.build b/libbalsa/meson.build
index a1ff7adf7..70fbe73cc 100644
--- a/libbalsa/meson.build
+++ b/libbalsa/meson.build
@@ -127,6 +127,8 @@ libbalsa_a_sources = [
   'send.h',
   'server.c',
   'server.h',
+  'server-config.c',
+  'server-config.h',
   'smtp-server.c',
   'smtp-server.h',
   'source-viewer.c',
diff --git a/libbalsa/send.c b/libbalsa/send.c
index ae1708904..ff80d5d52 100644
--- a/libbalsa/send.c
+++ b/libbalsa/send.c
@@ -784,6 +784,10 @@ lbs_process_queue_init_session(LibBalsaServer* server)
                session = net_client_smtp_new(server->host, 587U, server->security);
        }
 
+       /* connect signals */
+       g_signal_connect(G_OBJECT(session), "cert-check", G_CALLBACK(libbalsa_server_check_cert), session);
+       g_signal_connect(G_OBJECT(session), "auth", G_CALLBACK(libbalsa_server_get_auth), server);
+
        /* load client certificate if configured */
        if (server->client_cert) {
                GError* error = NULL;
@@ -796,10 +800,6 @@ lbs_process_queue_init_session(LibBalsaServer* server)
                        g_object_unref(session);
                        session = NULL;
                }
-       } else {
-               /* connect signals */
-               g_signal_connect(G_OBJECT(session), "cert-check", G_CALLBACK(libbalsa_server_check_cert), 
session);
-               g_signal_connect(G_OBJECT(session), "auth", G_CALLBACK(libbalsa_server_get_auth), server);
        }
 
        return session;
diff --git a/libbalsa/server-config.c b/libbalsa/server-config.c
new file mode 100644
index 000000000..3c23110c7
--- /dev/null
+++ b/libbalsa/server-config.c
@@ -0,0 +1,430 @@
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/* Balsa E-Mail Client
+ *
+ * Copyright (C) 1997-2018 Stuart Parmenter and others,
+ *                         See the file AUTHORS for a list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if defined(HAVE_CONFIG_H) && HAVE_CONFIG_H
+# include "config.h"
+#endif                          /* HAVE_CONFIG_H */
+
+#include <glib/gi18n.h>
+#include "misc.h"
+#include "server-config.h"
+
+
+struct _LibBalsaServerCfgPrivate {
+       /* "Basic" notebook page */
+       GtkWidget *basic_grid;                  /* grid */
+       guint basic_rows;                               /* count of rows */
+       GtkWidget *name;                                /* descriptive name */
+       GtkWidget *host_port;                   /* host and optionally port */
+       GtkWidget *security;                    /* security (SSL/TLS/...) */
+       GtkWidget *require_auth;                /* require authentication */
+       GtkWidget *username;                    /* user name for authentication */
+       GtkWidget *password;                    /* password for authentication */
+       GtkWidget *remember_pass;               /* remember password */
+
+       /* "Advanced" notebook page */
+       GtkWidget *advanced_grid;               /* grid */
+       guint advanced_rows;                    /* count of rows */
+       GtkWidget *require_cert;                /* require a client certificate */
+       GtkWidget *cert_file;                   /* client certificate file name */
+       GtkWidget *cert_pass;                   /* client certificate pass phrase */
+       GtkWidget *remember_cert_pass;  /* remember certificate pass phrase */
+
+       gboolean cfg_valid;                             /* whether the config options are valid (parent may 
enable OK) */
+};
+
+
+G_DEFINE_TYPE_WITH_PRIVATE(LibBalsaServerCfg, libbalsa_server_cfg, GTK_TYPE_NOTEBOOK)
+
+
+static void libbalsa_server_cfg_class_init(LibBalsaServerCfgClass *klass);
+static void libbalsa_server_cfg_init(LibBalsaServerCfg *self);
+static GtkWidget *server_cfg_add_entry(GtkWidget *grid, guint row, const gchar *label, const gchar *value, 
GCallback callback,
+                                                               gpointer cb_data)
+       G_GNUC_WARN_UNUSED_RESULT;
+static GtkWidget *server_cfg_add_check(GtkWidget *grid, guint row, const gchar *label, gboolean value, 
GCallback callback,
+                                                                          gpointer cb_data)
+       G_GNUC_WARN_UNUSED_RESULT;
+static void server_cfg_add_widget(GtkWidget *grid, guint row, const gchar *text, GtkWidget *widget);
+static GtkWidget *server_cfg_security_widget(LibBalsaServer *server);
+static void on_server_cfg_changed(GtkWidget *widget, LibBalsaServerCfg *server_cfg);
+
+
+static guint changed_sig;
+
+
+#if defined(HAVE_LIBSECRET)
+static const gchar *remember_password_message[2] = {
+       N_("_Remember user password in Secret Service"),
+       N_("_Remember certificate pass phrase in Secret Service")
+};
+#else
+static const gchar *remember_password_message[2] = {
+       N_("_Remember user password"),
+       N_("_Remember certificate pass phrase")
+};
+#endif                          /* defined(HAVE_LIBSECRET) */
+
+
+LibBalsaServerCfg *
+libbalsa_server_cfg_new(LibBalsaServer *server, const gchar *name)
+{
+       LibBalsaServerCfg *server_cfg;
+       LibBalsaServerCfgPrivate *priv;
+
+       g_return_val_if_fail(LIBBALSA_IS_SERVER(server), NULL);
+
+    server_cfg = LIBBALSA_SERVER_CFG(g_object_new(libbalsa_server_cfg_get_type(), NULL));
+    priv = server_cfg->priv;
+
+    /* notebook page with basic options */
+#define HIG_PADDING 12
+    priv->basic_grid = libbalsa_create_grid();
+    priv->basic_rows = 0U;
+
+    gtk_container_set_border_width(GTK_CONTAINER(priv->basic_grid), HIG_PADDING);
+    gtk_notebook_append_page(GTK_NOTEBOOK(server_cfg), priv->basic_grid, 
gtk_label_new_with_mnemonic(_("_Basic")));
+
+    /* server descriptive name */
+    priv->name = server_cfg_add_entry(priv->basic_grid, priv->basic_rows++, _("_Descriptive Name:"), name,
+       G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+    /* host and port */
+    priv->host_port = server_cfg_add_entry(priv->basic_grid, priv->basic_rows++, _("_Server:"), server->host,
+       G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+    /* security settings */
+    priv->security = server_cfg_security_widget(server);
+    server_cfg_add_widget(priv->basic_grid, priv->basic_rows++, _("Se_curity:"), priv->security);
+    g_signal_connect(priv->security, "changed", G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+    /* check box for authentication or anonymous access - smtp and imap only */
+    if ((strcmp(server->protocol, "smtp") == 0) || (strcmp(server->protocol, "imap") == 0)) {
+       priv->require_auth = server_cfg_add_check(priv->basic_grid, priv->basic_rows++, _("Server requires 
_authentication"),
+               !server->try_anonymous, G_CALLBACK(on_server_cfg_changed), server_cfg);
+    }
+
+    /* user name and password */
+    priv->username = server_cfg_add_entry(priv->basic_grid, priv->basic_rows++, _("_User Name:"), 
server->user,
+       G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+    priv->password = server_cfg_add_entry(priv->basic_grid, priv->basic_rows++, _("_Pass Phrase:"), 
server->passwd,
+       G_CALLBACK(on_server_cfg_changed), server_cfg);
+    g_object_set(G_OBJECT(priv->password), "input-purpose", GTK_INPUT_PURPOSE_PASSWORD, NULL);
+    gtk_entry_set_visibility(GTK_ENTRY(priv->password), FALSE);
+
+    priv->remember_pass = server_cfg_add_check(priv->basic_grid, priv->basic_rows++, 
remember_password_message[0],
+       server->remember_passwd, G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+    /* notebook page with advanced options */
+    priv->advanced_grid = libbalsa_create_grid();
+    priv->advanced_rows = 0U;
+    gtk_container_set_border_width(GTK_CONTAINER(priv->advanced_grid), HIG_PADDING);
+    gtk_notebook_append_page(GTK_NOTEBOOK(server_cfg), priv->advanced_grid, 
gtk_label_new_with_mnemonic(_("_Advanced")));
+
+    /* client certificate and passphrase */
+    priv->require_cert = server_cfg_add_check(priv->advanced_grid, priv->advanced_rows++, _("Server 
_requires client certificate"),
+       server->client_cert, G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+    priv->cert_file = gtk_file_chooser_button_new(_("Choose Client Certificate"), 
GTK_FILE_CHOOSER_ACTION_OPEN);
+    server_cfg_add_widget(priv->advanced_grid, priv->advanced_rows++, _("Certificate _File:"), 
priv->cert_file);
+    if (server->cert_file != NULL) {
+       gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(priv->cert_file), server->cert_file);
+    }
+    g_signal_connect(priv->cert_file, "file-set", G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+       priv->cert_pass = server_cfg_add_entry(priv->advanced_grid, priv->advanced_rows++, _("Certificate 
_Pass Phrase:"),
+               server->cert_passphrase, G_CALLBACK(on_server_cfg_changed), server_cfg);
+    g_object_set(G_OBJECT(priv->cert_pass), "input-purpose", GTK_INPUT_PURPOSE_PASSWORD, NULL);
+    gtk_entry_set_visibility(GTK_ENTRY(priv->cert_pass), FALSE);
+
+    priv->remember_cert_pass = server_cfg_add_check(priv->advanced_grid, priv->advanced_rows++, 
remember_password_message[1],
+       server->remember_cert_passphrase, G_CALLBACK(on_server_cfg_changed), server_cfg);
+
+    /* initially run the validity check */
+    on_server_cfg_changed(NULL, server_cfg);
+
+    return server_cfg;
+}
+
+
+gboolean
+libbalsa_server_cfg_valid(LibBalsaServerCfg *server_cfg)
+{
+       g_return_val_if_fail(LIBBALSA_IS_SERVER_CFG(server_cfg), FALSE);
+       return server_cfg->priv->cfg_valid;
+}
+
+
+GtkWidget *
+libbalsa_server_cfg_add_check(LibBalsaServerCfg *server_cfg, gboolean basic, const gchar *label, gboolean 
initval,
+       GCallback callback, gpointer cb_data)
+{
+       GtkWidget *new_check;
+       LibBalsaServerCfgPrivate *priv;
+
+       g_return_val_if_fail(LIBBALSA_IS_SERVER_CFG(server_cfg) && (label != NULL), NULL);
+
+       priv = server_cfg->priv;
+       if (basic) {
+               new_check = server_cfg_add_check(priv->basic_grid, priv->basic_rows++, label, initval, 
callback, cb_data);
+       } else {
+               new_check = server_cfg_add_check(priv->advanced_grid, priv->advanced_rows++, label, initval, 
callback, cb_data);
+       }
+       return new_check;
+}
+
+
+GtkWidget *
+libbalsa_server_cfg_add_entry(LibBalsaServerCfg *server_cfg, gboolean basic, const gchar *label, const gchar 
*initval,
+       GCallback callback, gpointer cb_data)
+{
+       GtkWidget *new_entry;
+       LibBalsaServerCfgPrivate *priv;
+
+       g_return_val_if_fail(LIBBALSA_IS_SERVER_CFG(server_cfg) && (label != NULL), NULL);
+
+       priv = server_cfg->priv;
+       if (basic) {
+               new_entry = server_cfg_add_entry(priv->basic_grid, priv->basic_rows++, label, initval, 
callback, cb_data);
+       } else {
+               new_entry = server_cfg_add_entry(priv->advanced_grid, priv->advanced_rows++, label, initval, 
callback, cb_data);
+       }
+       return new_entry;
+}
+
+
+void
+libbalsa_server_cfg_add_item(LibBalsaServerCfg *server_cfg, gboolean basic, const gchar *label, GtkWidget 
*widget)
+{
+       LibBalsaServerCfgPrivate *priv;
+
+       g_return_if_fail(LIBBALSA_IS_SERVER_CFG(server_cfg) && (label != NULL) && (widget != NULL));
+
+       priv = server_cfg->priv;
+       if (basic) {
+               server_cfg_add_widget(priv->basic_grid, priv->basic_rows++, label, widget);
+       } else {
+               server_cfg_add_widget(priv->advanced_grid, priv->advanced_rows++, label, widget);
+       }
+}
+
+
+void
+libbalsa_server_cfg_add_row(LibBalsaServerCfg *server_cfg, gboolean basic, GtkWidget *left, GtkWidget *right)
+{
+       LibBalsaServerCfgPrivate *priv;
+       GtkGrid *dest;
+       guint *dest_row;
+
+       g_return_if_fail(LIBBALSA_IS_SERVER_CFG(server_cfg) && (left != NULL));
+
+       priv = server_cfg->priv;
+       if (basic) {
+               dest = GTK_GRID(priv->basic_grid);
+               dest_row = &priv->basic_rows;
+       } else {
+               dest = GTK_GRID(priv->advanced_grid);
+               dest_row = &priv->advanced_rows;
+       }
+
+       if (right != NULL) {
+               gtk_grid_attach(GTK_GRID(dest), left, 0, *dest_row, 1, 1);
+               gtk_grid_attach(GTK_GRID(dest), right, 1, *dest_row, 2, 1);
+       } else {
+               gtk_grid_attach(GTK_GRID(dest), left, 0, *dest_row, 2, 1);
+       }
+       *dest_row += 1;
+}
+
+
+const gchar *
+libbalsa_server_cfg_get_name(LibBalsaServerCfg *server_cfg)
+{
+       g_return_val_if_fail(LIBBALSA_IS_SERVER_CFG(server_cfg), FALSE);
+       return gtk_entry_get_text(GTK_ENTRY(server_cfg->priv->name));
+}
+
+
+/* note: name is special, see libbalsa_server_cfg_get_name() */
+void
+libbalsa_server_cfg_assign_server(LibBalsaServerCfg *server_cfg, LibBalsaServer *server)
+{
+       LibBalsaServerCfgPrivate *priv;
+
+       g_return_if_fail(LIBBALSA_IS_SERVER_CFG(server_cfg) && LIBBALSA_IS_SERVER(server));
+
+       priv = server_cfg->priv;
+
+       /* host, post and security */
+    server->security = (NetClientCryptMode) (gtk_combo_box_get_active(GTK_COMBO_BOX(priv->security)) + 1);
+    libbalsa_server_set_host(server, gtk_entry_get_text(GTK_ENTRY(priv->host_port)), server->security);
+
+    /* authentication stuff */
+    if (priv->require_auth != NULL) {
+       server->try_anonymous = !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->require_auth));
+    } else {
+       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)));
+    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)));
+    server->remember_cert_passphrase = 
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->remember_cert_pass));
+}
+
+
+/* -- local stuff 
---------------------------------------------------------------------------------------------------------------
 */
+static void
+libbalsa_server_cfg_class_init(LibBalsaServerCfgClass *klass)
+{
+       changed_sig = g_signal_new("changed", LIBBALSA_TYPE_SERVER_CFG, G_SIGNAL_RUN_LAST, 0U, NULL, NULL, 
NULL, G_TYPE_NONE, 0U);
+}
+
+
+static void
+libbalsa_server_cfg_init(LibBalsaServerCfg *self)
+{
+       self->priv = libbalsa_server_cfg_get_instance_private(self);
+}
+
+
+static GtkWidget *
+server_cfg_add_entry(GtkWidget *grid, guint row, const gchar *label, const gchar *value, GCallback callback, 
gpointer cb_data)
+{
+       GtkWidget *new_entry;
+
+       new_entry = gtk_entry_new();
+    server_cfg_add_widget(grid, row, label, new_entry);
+    if (value != NULL) {
+        gtk_entry_set_text(GTK_ENTRY(new_entry), value);
+    }
+    if (callback != NULL) {
+       g_signal_connect(new_entry, "changed", callback, cb_data);
+    }
+    return new_entry;
+}
+
+
+static GtkWidget *
+server_cfg_add_check(GtkWidget *grid, guint row, const gchar *label, gboolean value, GCallback callback, 
gpointer cb_data)
+{
+       GtkWidget *new_check;
+
+       new_check = libbalsa_create_grid_check(label, grid, row, value);
+    if (callback != NULL) {
+       g_signal_connect(new_check, "toggled", callback, cb_data);
+    }
+    return new_check;
+}
+
+
+static void
+server_cfg_add_widget(GtkWidget *grid, guint row, const gchar *text, GtkWidget *widget)
+{
+    GtkWidget *label;
+
+    label = libbalsa_create_grid_label(text, grid, row);
+    gtk_widget_set_hexpand(widget, TRUE);
+    gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
+    gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget);
+}
+
+
+/**
+ * \note Make sure that the order of entries in the combo matches the order of enum _NetClientCryptMode 
items.  If calling
+ *       gtk_combo_box_get_active() on the returned widget, remember it starts with 0, so compensate for the 
offset of
+ *       NET_CLIENT_CRYPT_ENCRYPTED.
+ */
+static GtkWidget *
+server_cfg_security_widget(LibBalsaServer *server)
+{
+    GtkWidget *combo_box = gtk_combo_box_text_new();
+    gchar *proto_upper;
+    gchar *ssl_label;
+
+    proto_upper = g_ascii_strup(server->protocol, -1);
+    ssl_label = g_strdup_printf(_("%s over SSL (%sS)"), proto_upper, proto_upper);
+    g_free(proto_upper);
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), ssl_label);
+    g_free(ssl_label);
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), _("TLS required"));
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), _("TLS if possible (not recommended)"));
+    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), _("None (not recommended)"));
+    gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), (gint) server->security - 1);
+
+    return combo_box;
+}
+
+
+static void
+on_server_cfg_changed(GtkWidget *widget, LibBalsaServerCfg *server_cfg)
+{
+       LibBalsaServerCfgPrivate *priv = server_cfg->priv;
+       gboolean sensitive;
+
+       /* valid configuration only if a name and a host have been given */
+       priv->cfg_valid = (*gtk_entry_get_text(GTK_ENTRY(priv->name)) != '\0') &&
+               (*gtk_entry_get_text(GTK_ENTRY(priv->host_port)) != '\0');
+
+       /* user name/password only if authentication is required */
+       if (priv->require_auth != NULL) {
+               sensitive = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->require_auth));
+       } else {
+               sensitive = TRUE;
+       }
+       gtk_widget_set_sensitive(priv->username, sensitive);
+       gtk_widget_set_sensitive(priv->password, sensitive);
+       gtk_widget_set_sensitive(priv->remember_pass, sensitive);
+
+       /* invalid configuration if authentication is required, but no user name given */
+       if (sensitive && (*gtk_entry_get_text(GTK_ENTRY(priv->username)) == '\0')) {
+               priv->cfg_valid = FALSE;
+       }
+
+       /* client certificate and passphrase stuff only if TLS/SSL is enabled */
+       sensitive = (NetClientCryptMode) (gtk_combo_box_get_active(GTK_COMBO_BOX(priv->security)) + 1) != 
NET_CLIENT_CRYPT_NONE;
+       gtk_widget_set_sensitive(priv->require_cert, sensitive);
+       if (sensitive) {
+               sensitive = sensitive && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->require_cert));
+       }
+
+       gtk_widget_set_sensitive(priv->cert_file, sensitive);
+       gtk_widget_set_sensitive(priv->cert_pass, sensitive);
+       gtk_widget_set_sensitive(priv->remember_cert_pass, sensitive);
+
+       /* invalid configuration if a certificate is required, but no file name given */
+       if (sensitive) {
+               gchar *cert_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->cert_file));
+
+               if ((cert_file == NULL) || (cert_file[0] == '\0')) {
+                       priv->cfg_valid = FALSE;
+               }
+               g_free(cert_file);
+       }
+
+       g_signal_emit(server_cfg, changed_sig, 0);
+}
diff --git a/libbalsa/server-config.h b/libbalsa/server-config.h
new file mode 100644
index 000000000..35e5f6038
--- /dev/null
+++ b/libbalsa/server-config.h
@@ -0,0 +1,142 @@
+/* -*-mode:c; c-style:k&r; c-basic-offset:4; -*- */
+/* Balsa E-Mail Client
+ *
+ * Copyright (C) 1997-2018 Stuart Parmenter and others,
+ *                         See the file AUTHORS for a list.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBBALSA_SERVER_CONFIG_H_
+#define LIBBALSA_SERVER_CONFIG_H_
+
+
+#include <gtk/gtk.h>
+#include "server.h"
+
+
+#ifndef BALSA_VERSION
+# error "Include config.h before this file."
+#endif
+
+
+#define LIBBALSA_TYPE_SERVER_CFG                               (libbalsa_server_cfg_get_type())
+#define LIBBALSA_SERVER_CFG(obj)                               (G_TYPE_CHECK_INSTANCE_CAST(obj, 
LIBBALSA_TYPE_SERVER_CFG, LibBalsaServerCfg))
+#define LIBBALSA_SERVER_CFG_CLASS(klass)               (G_TYPE_CHECK_CLASS_CAST(klass, 
LIBBALSA_TYPE_SERVER_CFG, LibBalsaServerCfgClass))
+#define LIBBALSA_IS_SERVER_CFG(obj)                    (G_TYPE_CHECK_INSTANCE_TYPE(obj, 
LIBBALSA_TYPE_SERVER_CFG))
+#define LIBBALSA_IS_SERVER_CFG_CLASS(klass)            (G_TYPE_CHECK_CLASS_TYPE(klass, 
LIBBALSA_TYPE_SERVER_CFG))
+
+
+typedef struct _LibBalsaServerCfgClass LibBalsaServerCfgClass;
+typedef struct _LibBalsaServerCfg LibBalsaServerCfg;
+typedef struct _LibBalsaServerCfgPrivate LibBalsaServerCfgPrivate;
+
+struct _LibBalsaServerCfg {
+    GtkNotebook parent;
+    LibBalsaServerCfgPrivate *priv;
+};
+
+struct _LibBalsaServerCfgClass {
+    GtkNotebookClass parent;
+};
+
+
+GType libbalsa_server_cfg_get_type(void);
+
+/** @brief Create a new server configuration widget
+ * @param server server data, must not be NULL
+ * @param name name, may be NULL
+ * @return a newly allocated and populated server configuration notebook widget
+ */
+LibBalsaServerCfg *libbalsa_server_cfg_new(LibBalsaServer *server,
+                                                                                  const gchar    *name)
+       G_GNUC_WARN_UNUSED_RESULT;
+
+/** @brief Check if the server configuration is valid
+ * @param server_cfg server configuration widget
+ * @return TRUE if the configuration is valid, i.e. all mandatory fields are filled in
+ */
+gboolean libbalsa_server_cfg_valid(LibBalsaServerCfg *server_cfg);
+
+/** @brief Add a custom widget to the server configuration
+ * @param server_cfg server configuration widget
+ * @param basic TRUE to append the widget to the @em Basic or FALSE to the @em Advanced page
+ * @param label widget label, must not be NULL
+ * @param widget widget to append, must not be NULL
+ */
+void libbalsa_server_cfg_add_item(LibBalsaServerCfg *server_cfg,
+                                                                 gboolean           basic,
+                                                                 const gchar       *label,
+                                                                 GtkWidget         *widget);
+
+/** @brief Add custom widgets to the server configuration
+ * @param server_cfg server configuration widget
+ * @param basic TRUE to append the widget to the @em Basic or FALSE to the @em Advanced page
+ * @param left widget in the left grid column, must not be NULL
+ * @param right widget in the right grid column, may be NULL if the left widget shall span over both grid 
columns
+ */
+void libbalsa_server_cfg_add_row(LibBalsaServerCfg *server_cfg,
+                                                                gboolean           basic,
+                                                                GtkWidget         *left,
+                                                                GtkWidget         *right);
+
+/** @brief Add a custom check box to the server configuration
+ * @param server_cfg server configuration widget
+ * @param basic TRUE to append the widget to the @em Basic or FALSE to the @em Advanced page
+ * @param label widget label, must not be NULL
+ * @param initval initial check box value
+ * @param callback callback function for the @em toggled signal, may be NULL
+ * @param cb_data data to pass to the callback
+ * @return a new GtkCheckButton
+ */
+GtkWidget *libbalsa_server_cfg_add_check(LibBalsaServerCfg *server_cfg,
+                                                                    gboolean           basic,
+                                                                                const gchar       *label,
+                                                                                gboolean                     
  initval,
+                                                                                GCallback                    
  callback,
+                                                                                gpointer                     
  cb_data)
+       G_GNUC_WARN_UNUSED_RESULT;
+
+/** @brief Add a custom entry to the server configuration
+ * @param server_cfg server configuration widget
+ * @param basic TRUE to append the widget to the @em Basic or FALSE to the @em Advanced page
+ * @param label widget label, must not be NULL
+ * @param initval initial entry value, may be NULL
+ * @param callback callback function for the @em changed signal, may be NULL
+ * @param cb_data data to pass to the callback
+ * @return a new GtkEntry
+ */
+GtkWidget *libbalsa_server_cfg_add_entry(LibBalsaServerCfg *server_cfg,
+                                                                    gboolean           basic,
+                                                                                const gchar       *label,
+                                                                                const gchar       *initval,
+                                                                                GCallback                    
  callback,
+                                                                                gpointer                     
  cb_data)
+       G_GNUC_WARN_UNUSED_RESULT;
+
+/** @brief Get the name of the server configuration
+ * @param server_cfg server configuration widget
+ * @return the name entered in the <em>Descriptive Name</em> GtkEntry
+ */
+const gchar *libbalsa_server_cfg_get_name(LibBalsaServerCfg *server_cfg);
+
+/** @brief Get the server configuration
+ * @param server_cfg server configuration widget
+ * @param server server data, must not be NULL
+ */
+void libbalsa_server_cfg_assign_server(LibBalsaServerCfg *server_cfg,
+                                                                          LibBalsaServer    *server);
+
+
+#endif /* LIBBALSA_SERVER_CONFIG_H_ */
diff --git a/libbalsa/server.c b/libbalsa/server.c
index 5f7af731a..bb50934d1 100644
--- a/libbalsa/server.c
+++ b/libbalsa/server.c
@@ -47,7 +47,16 @@ static const SecretSchema server_schema = {
        { NULL, 0 }
     }
 };
-const SecretSchema *LIBBALSA_SERVER_SECRET_SCHEMA = &server_schema;
+
+static const SecretSchema cert_pass_schema = {
+    "org.gnome.Balsa.CertificatePassword", SECRET_SCHEMA_NONE,
+    {
+       { "protocol", SECRET_SCHEMA_ATTRIBUTE_STRING },
+       { "server",   SECRET_SCHEMA_ATTRIBUTE_STRING },
+       { "user",     SECRET_SCHEMA_ATTRIBUTE_STRING },
+       { NULL, 0 }
+    }
+};
 #endif                          /* defined(HAVE_LIBSECRET) */
 
 static GObjectClass *parent_class = NULL;
@@ -60,7 +69,9 @@ 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_real_get_password(LibBalsaServer *server); */
+static gchar *libbalsa_server_get_password(LibBalsaServer  *server,
+                                                                          LibBalsaMailbox *mbox);
+static gchar *libbalsa_free_password(gchar *password);
 
 enum {
     SET_USERNAME,
@@ -180,15 +191,11 @@ libbalsa_server_finalize(GObject * object)
 
     g_free(server->host);   server->host = NULL;
     g_free(server->user);   server->user = NULL;
-    if (server->passwd != NULL) {
-       memset(server->passwd, 0, strlen(server->passwd));
-    }
-    libbalsa_free_password(server->passwd); server->passwd = NULL;
+    server->passwd = libbalsa_free_password(server->passwd);
 
     g_free(server->cert_file);
     server->cert_file = NULL;
-    net_client_free_authstr(server->cert_passphrase);
-    server->cert_passphrase = NULL;
+    server->cert_passphrase = libbalsa_free_password(server->cert_passphrase);
 
     G_OBJECT_CLASS(parent_class)->finalize(object);
 }
@@ -220,10 +227,10 @@ libbalsa_server_set_password(LibBalsaServer * server,
 {
     g_return_if_fail(LIBBALSA_IS_SERVER(server));
 
-    libbalsa_free_password(server->passwd);
-    if(passwd && passwd[0])
-       server->passwd = g_strdup(passwd);
-    else server->passwd = NULL;
+    server->passwd = libbalsa_free_password(server->passwd);
+    if ((passwd != NULL) && (passwd[0] != '\0')) {
+       server->passwd = g_strdup(passwd);
+    }
 }
 
 void
@@ -248,9 +255,9 @@ libbalsa_server_config_changed(LibBalsaServer * server)
                   0);
 }
 
-gchar *
-libbalsa_server_get_password(LibBalsaServer * server,
-                            LibBalsaMailbox * mbox)
+static gchar *
+libbalsa_server_get_password(LibBalsaServer  *server,
+                                                LibBalsaMailbox *mbox)
 {
     gchar *retval = NULL;
 
@@ -332,6 +339,106 @@ libbalsa_server_load_security_config(LibBalsaServer *server)
 
 }
 
+
+#if defined(HAVE_LIBSECRET)
+
+static gchar *
+libbalsa_free_password(gchar *password)
+{
+       secret_password_free(password);
+       return NULL;
+}
+
+static void
+store_password_libsecret(const LibBalsaServer *server,
+                                        const gchar          *password,
+                                                const SecretSchema   *schema)
+{
+    GError *err = NULL;
+
+    secret_password_store_sync(schema, NULL, _("Balsa passwords"), password, NULL, &err,
+       "protocol", server->protocol,
+               "server",   server->host,
+               "user",     server->user,
+               NULL);
+    if (err != NULL) {
+       g_info(_("Error storing password for %s@%s:%s: %s"), server->user, server->protocol, server->host, 
err->message);
+        g_error_free(err);
+    } else {
+       g_debug("stored password for %s@%s:%s in secret service", server->user, server->protocol, 
server->host);
+    }
+}
+
+static gchar *
+load_password_libsecret(const LibBalsaServer *server,
+                                           const gchar          *cfg_path,
+                                               const SecretSchema   *schema)
+{
+    GError *err = NULL;
+    gchar *password;
+
+    password = secret_password_lookup_sync(schema, NULL, &err,
+       "protocol", server->protocol,
+               "server",   server->host,
+               "user",     server->user,
+               NULL);
+    if (err != NULL) {
+        g_info(_("Error looking up password for %s@%s:%s: %s"), server->user, server->protocol, 
server->host, err->message);
+        g_error_free(err);
+
+        /* fall back to the private config file */
+        password = libbalsa_conf_private_get_string(cfg_path, TRUE);
+        if ((password != NULL) && (password[0] != '\0')) {
+               g_info(_("loaded fallback password from private config file"));
+               /* store a fallback password in the key ring */
+               store_password_libsecret(server, password, schema);
+            /* We could in principle clear the password in the config file here but we do not for the 
backward compatibility.
+             * FIXME - Is this really the proper approach, as we leave the obfuscated password in the config 
file, and the user
+             * relies on the message that the password is stored in the Secret Service only.  OTOH, there 
are better methods for
+             * protecting the user's secrets, like full disk encryption. */
+        }
+    } else {
+       g_debug("loaded password for %s@%s:%s from secret service", server->user, server->protocol, 
server->host);
+    }
+
+    return password;
+}
+
+static void
+erase_password_libsecret(const LibBalsaServer *server,
+                                                const SecretSchema   *schema)
+{
+    GError *err = NULL;
+    gboolean removed;
+
+    removed = secret_password_clear_sync(schema, NULL, &err,
+       "protocol", server->protocol,
+               "server",   server->host,
+               "user",     server->user,
+               NULL);
+    if (err != NULL) {
+       g_info("error erasing password for %s@%s:%s from secret service: %s", server->user, server->protocol, 
server->host,
+               err->message);
+       g_error_free(err);
+    } else if (removed) {
+       g_debug("erased password for %s@%s:%s from secret service", server->user, server->protocol, 
server->host);
+    } else {
+       g_debug("no password erased for %s@%s:%s from secret service", server->user, server->protocol, 
server->host);
+    }
+}
+
+#else
+
+static gchar *
+libbalsa_free_password(gchar *password)
+{
+       net_client_free_authstr(password);
+       return NULL;
+}
+
+#endif
+
+
 /* libbalsa_server_load_config:
    load the server configuration using gnome-config.
    Try to use sensible defaults.
@@ -341,90 +448,55 @@ libbalsa_server_load_security_config(LibBalsaServer *server)
 void
 libbalsa_server_load_config(LibBalsaServer * server)
 {
-    gboolean d;
     server->host = libbalsa_conf_get_string("Server");
-    if(server->host && strrchr(server->host, ':') == NULL) {
+    if ((server->host != NULL) && (strrchr(server->host, ':') == NULL)) {
         gint port;
+        gboolean d;
+
         port = libbalsa_conf_get_int_with_default("Port", &d);
         if (!d) {
             gchar *newhost = g_strdup_printf("%s:%d", server->host, port);
+
             g_free(server->host);
             server->host = newhost;
         }
     }
     libbalsa_server_load_security_config(server);
-    server->user = libbalsa_conf_private_get_string("Username");
-    if (!server->user)
-       server->user = g_strdup(getenv("USER"));
+    server->user = libbalsa_conf_private_get_string("Username", FALSE);
+    if (server->user == NULL) {
+       server->user = g_strdup(g_get_user_name());
+    }
 
     server->try_anonymous = libbalsa_conf_get_bool("Anonymous=false");
     server->remember_passwd = libbalsa_conf_get_bool("RememberPasswd=false");
 
-    if(server->remember_passwd) {
+    server->passwd = libbalsa_free_password(server->passwd);
+    if (server->remember_passwd) {
 #if defined(HAVE_LIBSECRET)
-        GError *err = NULL;
-
-        server->passwd =
-            secret_password_lookup_sync(LIBBALSA_SERVER_SECRET_SCHEMA,
-                                        NULL, &err,
-                                        "protocol", server->protocol,
-                                        "server",   server->host,
-                                        "user",     server->user,
-                                        NULL);
-        if (err) {
-            libbalsa_free_password(server->passwd);
-            server->passwd = NULL;
-            printf(_("Error looking up password for %s@%s: %s\n"),
-                   server->user, server->host, err->message);
-            printf(_("Falling back\n"));
-            g_clear_error(&err);
-            server->passwd = libbalsa_conf_private_get_string("Password");
-            if (server->passwd != NULL) {
-                gchar *buff = libbalsa_rot(server->passwd);
-                libbalsa_free_password(server->passwd);
-                server->passwd = buff;
-                secret_password_store_sync
-                    (LIBBALSA_SERVER_SECRET_SCHEMA, NULL,
-                     _("Balsa passwords"), server->passwd, NULL, &err,
-                     "protocol", server->protocol,
-                     "server",   server->host,
-                     "user",     server->user,
-                     NULL);
-                /* We could in principle clear the password in the
-                 * config file here but we do not for the backward
-                 * compatibility. */
-                if (err) {
-                    printf(_("Error storing password for %s@%s: %s\n"),
-                           server->user, server->host, err->message);
-                    g_error_free(err);
-                }
-            }
-        }
+       server->passwd = load_password_libsecret(server, "Password", &server_schema);
 #else
-       server->passwd = libbalsa_conf_private_get_string("Password");
-       if (server->passwd != NULL) {
-           gchar *buff = libbalsa_rot(server->passwd);
-           libbalsa_free_password(server->passwd);
-           server->passwd = buff;
-       }
-#endif
-    }
-    if(server->passwd && server->passwd[0] == '\0') {
-       libbalsa_free_password(server->passwd);
-       server->passwd = NULL;
+       server->passwd = libbalsa_conf_private_get_string("Password", TRUE);
+#endif         /* HAVE_LIBSECRET */
+       if ((server->passwd != NULL) && (server->passwd[0] == '\0')) {
+               server->passwd = libbalsa_free_password(server->passwd);
+       }
     }
 
+    /* client certificate stuff */
     server->client_cert = libbalsa_conf_get_bool("NeedClientCert=false");
     server->cert_file = libbalsa_conf_get_string("UserCertificateFile");
-    server->cert_passphrase = libbalsa_conf_private_get_string("CertificatePassphrase");
-    if ((server->cert_passphrase != NULL) && (server->cert_passphrase[0] != '\0')) {
-        gchar *tmp = libbalsa_rot(server->cert_passphrase);
+    server->remember_cert_passphrase = libbalsa_conf_get_bool("RememberCertPasswd=false");
 
-        g_free(server->cert_passphrase);
-        server->cert_passphrase = tmp;
-    } else {
-       g_free(server->cert_passphrase);
-       server->cert_passphrase = NULL;
+    server->cert_passphrase = libbalsa_free_password(server->cert_passphrase);
+    if (server->client_cert && server->remember_cert_passphrase) {
+#if defined(HAVE_LIBSECRET)
+       server->cert_passphrase = load_password_libsecret(server, "CertificatePassphrase", &cert_pass_schema);
+#else
+       server->cert_passphrase = libbalsa_conf_private_get_string("CertificatePassphrase", TRUE);
+#endif         /* HAVE_LIBSECRET */
+       if ((server->cert_passphrase != NULL) && (server->cert_passphrase[0] == '\0')) {
+               server->cert_passphrase = libbalsa_free_password(server->cert_passphrase);
+       }
     }
 }
 
@@ -438,43 +510,42 @@ void
 libbalsa_server_save_config(LibBalsaServer * server)
 {
     libbalsa_conf_set_string("Server", server->host);
-    libbalsa_conf_private_set_string("Username", server->user);
+    libbalsa_conf_private_set_string("Username", server->user, FALSE);
     libbalsa_conf_set_bool("Anonymous",          server->try_anonymous);
-    libbalsa_conf_set_bool("RememberPasswd", 
-                          server->remember_passwd && server->passwd != NULL);
 
-    if (server->remember_passwd && server->passwd != NULL) {
+    if (server->remember_passwd && (server->passwd != NULL)) {
+       libbalsa_conf_set_bool("RememberPasswd", TRUE);
 #if defined(HAVE_LIBSECRET)
-        GError *err = NULL;
-
-        secret_password_store_sync(LIBBALSA_SERVER_SECRET_SCHEMA, NULL,
-                                   _("Balsa passwords"), server->passwd,
-                                   NULL, &err,
-                                   "protocol", server->protocol,
-                                   "server",   server->host,
-                                   "user",     server->user,
-                                   NULL);
-        if (err) {
-            printf(_("Error storing password for %s@%s: %s\n"),
-                   server->user, server->host, err->message);
-            g_error_free(err);
-        }
+       store_password_libsecret(server, server->passwd, &server_schema);
 #else
-       gchar *buff = libbalsa_rot(server->passwd);
-       libbalsa_conf_private_set_string("Password", buff);
-       g_free(buff);
-#endif                          /* defined(HAVE_LIBSECRET) */
+       libbalsa_conf_private_set_string("Password", server->passwd, TRUE);
+#endif
+    } else {
+       libbalsa_conf_set_bool("RememberPasswd", FALSE);
+#if defined(HAVE_LIBSECRET)
+       erase_password_libsecret(server, &server_schema);
+#endif         /* HAVE_LIBSECRET */
+       libbalsa_conf_private_set_string("Password", NULL, TRUE);
     }
 
     libbalsa_conf_set_bool("NeedClientCert", server->client_cert);
     if (server->cert_file != NULL) {
        libbalsa_conf_set_string("UserCertificateFile", server->cert_file);
-    }
-    if (server->cert_passphrase != NULL) {
-        gchar *tmp = libbalsa_rot(server->cert_passphrase);
+       if (server->remember_cert_passphrase && (server->cert_passphrase != NULL)) {
+               libbalsa_conf_set_bool("RememberCertPasswd", TRUE);
+#if defined(HAVE_LIBSECRET)
+               store_password_libsecret(server, server->cert_passphrase, &cert_pass_schema);
+#else
+               libbalsa_conf_private_set_string("CertificatePassphrase", server->cert_passphrase, TRUE);
+#endif
 
-        libbalsa_conf_private_set_string("CertificatePassphrase", tmp);
-        g_free(tmp);
+       } else {
+               libbalsa_conf_set_bool("RememberCertPasswd", FALSE);
+#if defined(HAVE_LIBSECRET)
+               erase_password_libsecret(server, &cert_pass_schema);
+#endif         /* HAVE_LIBSECRET */
+               libbalsa_conf_private_set_string("CertificatePassphrase", NULL, TRUE);
+       }
     }
 
     libbalsa_conf_set_int("Security", server->security);
@@ -505,7 +576,7 @@ libbalsa_server_get_auth(NetClient *client,
 
     g_debug("%s: %p %p: encrypted = %d", __func__, client, user_data,
             net_client_is_encrypted(client));
-    if ((server->try_anonymous == 0U) || (strcmp(server->protocol, "imap") == 0)) {
+    if (!server->try_anonymous || (strcmp(server->protocol, "imap") == 0)) {
         result = g_new0(gchar *, 3U);
         result[0] = g_strdup(server->user);
         if (need_passwd) {
@@ -535,8 +606,15 @@ libbalsa_server_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_SERVER(user_data)->cert_passphrase);
+    LibBalsaServer *server = LIBBALSA_SERVER(user_data);
+    gchar *result;
+
+    if ((server->cert_passphrase != NULL) && (server->cert_passphrase[0] != '\0')) {
+       result = g_strdup(server->cert_passphrase);
+    } else {
+       result = NULL;  // FIXME - dialogue to read passphrase
+    }
+       return result;
 }
 
 /* Test whether a server is reachable */
diff --git a/libbalsa/server.h b/libbalsa/server.h
index 4082a4ed3..1378b91f2 100644
--- a/libbalsa/server.h
+++ b/libbalsa/server.h
@@ -29,14 +29,6 @@
 #include "libbalsa.h"
 #include "net-client.h"
 
-#if defined(HAVE_LIBSECRET)
-#include <libsecret/secret.h>
-extern const SecretSchema *LIBBALSA_SERVER_SECRET_SCHEMA;
-#define libbalsa_free_password secret_password_free
-#else
-#define libbalsa_free_password g_free
-#endif                          /* defined(HAVE_LIBSECRET) */
-
 #define LIBBALSA_TYPE_SERVER \
     (libbalsa_server_get_type())
 #define LIBBALSA_SERVER(obj) \
@@ -53,13 +45,6 @@ GType libbalsa_server_get_type(void);
 
 typedef struct _LibBalsaServerClass LibBalsaServerClass;
 
-#if 0
-typedef enum {
-    LIBBALSA_TLS_DISABLED,
-    LIBBALSA_TLS_ENABLED,
-    LIBBALSA_TLS_REQUIRED
-} LibBalsaTlsMode;
-#endif
 
 struct _LibBalsaServer {
     GObject object;
@@ -72,13 +57,9 @@ struct _LibBalsaServer {
     gboolean client_cert;
     gchar *cert_file;
     gchar *cert_passphrase;
-    /* We include SSL support in UI unconditionally to preserve config
-     * between SSL and non-SSL builds. We just fail if SSL is requested
-     * in non-SSL build. */
-    //LibBalsaTlsMode tls_mode;
-    //unsigned use_ssl:1;
-    unsigned remember_passwd:1;
-    unsigned try_anonymous:1; /* user wants anonymous access */
+    gboolean remember_passwd;
+    gboolean remember_cert_passphrase;
+    gboolean try_anonymous; /* user wants anonymous access */
 };
 
 struct _LibBalsaServerClass {
@@ -100,8 +81,6 @@ void libbalsa_server_set_password(LibBalsaServer * server,
 void libbalsa_server_set_host(LibBalsaServer     *server,
                                                          const gchar        *host,
                                                          NetClientCryptMode  security);
-gchar *libbalsa_server_get_password(LibBalsaServer * server,
-                                   LibBalsaMailbox * mbox);
 
 void libbalsa_server_config_changed(LibBalsaServer * server);
 void libbalsa_server_load_config(LibBalsaServer * server);
diff --git a/libbalsa/smtp-server.c b/libbalsa/smtp-server.c
index 67ffec440..1ecccc0de 100644
--- a/libbalsa/smtp-server.c
+++ b/libbalsa/smtp-server.c
@@ -34,6 +34,7 @@
 #include "misc.h"
 #include <glib/gi18n.h>
 #include "net-client.h"
+#include "server-config.h"
 
 #if HAVE_MACOSX_DESKTOP
 #  include "macosx-helpers.h"
@@ -243,15 +244,7 @@ struct smtp_server_dialog_info {
     gchar *old_name;
     LibBalsaSmtpServerUpdate update;
     GtkWidget *dialog;
-    GtkWidget *name;
-    GtkWidget *host;
-    GtkWidget *user;
-    GtkWidget *pass;
-    GtkWidget *tlsm;
-    GtkWidget *auth_button;
-    GtkWidget *cert_button;
-    GtkWidget *cert_file;
-    GtkWidget *cert_pass;
+    LibBalsaServerCfg *notebook;
     GtkWidget *split_button;
     GtkWidget *big_message;
 };
@@ -275,32 +268,6 @@ smtp_server_weak_notify(struct smtp_server_dialog_info *sdi, GObject *dialog)
                       LIBBALSA_SMTP_SERVER_DIALOG_KEY, NULL);
 }
 
-static void
-smtp_server_add_widget(GtkWidget * grid, gint row, const gchar * text,
-                       GtkWidget * widget)
-{
-    GtkWidget *label = libbalsa_create_grid_label(text, grid, row);
-    gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), widget);
-}
-
-static
-GtkWidget *
-smtp_server_tls_widget(LibBalsaSmtpServer * smtp_server)
-{
-    LibBalsaServer *server = LIBBALSA_SERVER(smtp_server);
-    GtkWidget *combo_box = gtk_combo_box_text_new();
-
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), _("SMTP over SSL (SMTPS)"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), _("TLS required"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), _("TLS if possible (not recommended)"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo_box), _("None (not recommended)"));
-
-    gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), (gint) server->security - 1);
-
-    return combo_box;
-}
-
 static void
 smtp_server_response(GtkDialog * dialog, gint response,
                      struct smtp_server_dialog_info *sdi)
@@ -331,25 +298,8 @@ smtp_server_response(GtkDialog * dialog, gint response,
         }
         return;
     case GTK_RESPONSE_OK:
-        libbalsa_smtp_server_set_name(sdi->smtp_server,
-                                      gtk_entry_get_text(GTK_ENTRY
-                                                         (sdi->name)));
-        server->security = (NetClientCryptMode) (gtk_combo_box_get_active(GTK_COMBO_BOX(sdi->tlsm)) + 1);
-        libbalsa_server_set_host(server,
-                                 gtk_entry_get_text(GTK_ENTRY(sdi->host)),
-                                                                server->security);
-        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)));
-        libbalsa_server_set_password(server,
-                                     gtk_entry_get_text(GTK_ENTRY
-                                                        (sdi->pass)));
-        server->client_cert = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->cert_button));
-        g_free(server->cert_file);
-        server->cert_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(sdi->cert_file));
-        g_free(server->cert_passphrase);
-        server->cert_passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(sdi->cert_pass)));
+        libbalsa_smtp_server_set_name(sdi->smtp_server, libbalsa_server_cfg_get_name(sdi->notebook));
+        libbalsa_server_cfg_assign_server(sdi->notebook, server);
         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sdi->split_button))) {
             /* big_message is stored in kB, but the widget is in MB. */
                sdi->smtp_server->big_message =
@@ -377,47 +327,7 @@ smtp_server_changed(GtkWidget G_GNUC_UNUSED *widget,
                     struct smtp_server_dialog_info *sdi)
 {
        gboolean sensitive;
-       gboolean enable_ok = FALSE;
-
-       /* 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');
-    }
-
-       /* 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);
-               }
-       }
+       gboolean enable_ok = libbalsa_server_cfg_valid(sdi->notebook);
 
        /* split big messages */
        if ((sdi->big_message != NULL) && (sdi->split_button != NULL)) {
@@ -438,9 +348,6 @@ 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;
 
     /* Show only one dialog at a time. */
@@ -480,96 +387,13 @@ 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);
+    sdi->notebook = libbalsa_server_cfg_new(server, smtp_server->name);
+    gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 
GTK_WIDGET(sdi->notebook));
 
 #define HIG_PADDING 12
 
-    /* notebook page with basic 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(_("_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);
-
-    /* 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);
-
-    /* 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);
-
-    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 != NULL) {
-        gtk_entry_set_text(GTK_ENTRY(sdi->pass), server->passwd);
-    }
-    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), 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 (server->cert_file != NULL) {
-       gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(sdi->cert_file), 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 (server->cert_passphrase != NULL) {
-        gtk_entry_set_text(GTK_ENTRY(sdi->cert_pass), 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);
@@ -584,9 +408,10 @@ libbalsa_smtp_server_dialog(LibBalsaSmtpServer * smtp_server,
         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sdi->split_button), FALSE);
         gtk_spin_button_set_value(GTK_SPIN_BUTTON(sdi->big_message), 1);
     }
+    libbalsa_server_cfg_add_row(sdi->notebook, FALSE, sdi->split_button, hbox);
+    g_signal_connect(sdi->notebook, "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);
 
diff --git a/src/folder-conf.c b/src/folder-conf.c
index d39b8f40d..77341d5e8 100644
--- a/src/folder-conf.c
+++ b/src/folder-conf.c
@@ -30,6 +30,7 @@
 #include "save-restore.h"
 #include "pref-manager.h"
 #include "imap-server.h"
+#include "server-config.h"
 #include <glib/gi18n.h>
 
 #if HAVE_MACOSX_DESKTOP
@@ -55,9 +56,9 @@ struct _CommonDialogData {
 
 struct _FolderDialogData {
     FOLDER_CONF_COMMON;
-    BalsaServerConf bsc;
-    GtkWidget *folder_name, *port, *username, *anonymous, *remember,
-        *password, *subscribed, *list_inbox, *prefix;
+    LibBalsaServerCfg *server_cfg;
+    LibBalsaServer *server;
+    GtkWidget *subscribed, *list_inbox, *prefix;
     GtkWidget *connection_limit, *enable_persistent,
         *use_idle, *has_bugs, *use_status;
 };
@@ -150,141 +151,64 @@ folder_conf_response(GtkDialog * dialog, int response,
    Creates the node when mn == NULL.
 */
 static void 
-validate_folder(GtkWidget *w, FolderDialogData * fcw)
+validate_folder(GtkWidget G_GNUC_UNUSED *w, FolderDialogData *fcw)
 {
-    gboolean sensitive = TRUE;
-
-    if (!*gtk_entry_get_text(GTK_ENTRY(fcw->folder_name))) {
-       sensitive = FALSE;
-    } else if (!*gtk_entry_get_text(GTK_ENTRY(fcw->bsc.server))) {
-       sensitive = FALSE;
-    }
-
-    /* encryption w/ client cert requires cert file */
-    if (sensitive &&
-       ((gtk_combo_box_get_active(GTK_COMBO_BOX(fcw->bsc.security)) + 1) != NET_CLIENT_CRYPT_NONE) &&
-               gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->bsc.need_client_cert))) {
-       gchar *cert_file;
-
-       cert_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fcw->bsc.client_cert_file));
-       if ((cert_file == NULL) || (cert_file[0] == '\0')) {
-               sensitive = FALSE;
-       }
-       g_free(cert_file);
-    }
-
-    gtk_dialog_set_response_sensitive(fcw->dialog, GTK_RESPONSE_OK, sensitive);
-}
-
-static void
-anonymous_cb(GtkToggleButton * button, FolderDialogData * fcw)
-{
-    gtk_widget_set_sensitive(fcw->anonymous,
-                             gtk_toggle_button_get_active(button));
-}
-
-static void
-remember_cb(GtkToggleButton * button, FolderDialogData * fcw)
-{
-    gtk_widget_set_sensitive(fcw->password,
-                             gtk_toggle_button_get_active(button));
-}
-
-static void
-security_cb(GtkComboBox *combo, FolderDialogData *fcw)
-{
-       gboolean sensitive;
-
-       sensitive = (gtk_combo_box_get_active(combo) + 1) != NET_CLIENT_CRYPT_NONE;
-       gtk_widget_set_sensitive(fcw->bsc.need_client_cert, sensitive);
-       sensitive = sensitive & gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->bsc.need_client_cert));
-       gtk_widget_set_sensitive(fcw->bsc.client_cert_file, sensitive);
-       gtk_widget_set_sensitive(fcw->bsc.client_cert_passwd, sensitive);
-       validate_folder(GTK_WIDGET(combo), fcw);
+    gtk_dialog_set_response_sensitive(fcw->dialog, GTK_RESPONSE_OK, 
libbalsa_server_cfg_valid(fcw->server_cfg));
 }
 
 static gboolean
 folder_conf_clicked_ok(FolderDialogData * fcw)
 {
     gboolean insert;
-    LibBalsaServer *s;
-    const gchar *username;
-    const gchar *host;
-
-    host = gtk_entry_get_text(GTK_ENTRY(fcw->bsc.server));
-    username = gtk_entry_get_text(GTK_ENTRY(fcw->username));
+    LibBalsaImapServer *imap;
 
     if (fcw->mbnode) {
         insert = FALSE;
-        s = fcw->mbnode->server;
     } else {
         insert = TRUE;
-       s = LIBBALSA_SERVER(libbalsa_imap_server_new(username, host));
-        g_signal_connect(G_OBJECT(s), "get-password",
+        g_signal_connect(G_OBJECT(fcw->server), "get-password",
                          G_CALLBACK(ask_password), NULL);
     }
 
-    s->security = balsa_server_conf_get_security(&fcw->bsc);
-    libbalsa_imap_server_set_max_connections
-        (LIBBALSA_IMAP_SERVER(s),
-         gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
-                                          (fcw->connection_limit)));
-    libbalsa_imap_server_enable_persistent_cache
-        (LIBBALSA_IMAP_SERVER(s),
-         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->enable_persistent)));
-    libbalsa_imap_server_set_use_idle
-        (LIBBALSA_IMAP_SERVER(s), 
-         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->use_idle)));
-    libbalsa_imap_server_set_bug
-        (LIBBALSA_IMAP_SERVER(s), ISBUG_FETCH,
-         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->has_bugs)));
-    libbalsa_imap_server_set_use_status
-        (LIBBALSA_IMAP_SERVER(s),
-         gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->use_status)));
-    libbalsa_server_set_username(s, username);
-    s->try_anonymous =
-        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->anonymous));
-    s->remember_passwd =
-        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->remember));
-    libbalsa_server_set_password(s,
-                                 gtk_entry_get_text(GTK_ENTRY
-                                                    (fcw->password)));
-    if (!fcw->mbnode) {
-        fcw->mbnode = balsa_mailbox_node_new_imap_folder(s, NULL);
-       /* mbnode will be unrefed in folder_conf_response. */
-       g_object_ref(fcw->mbnode);
-        /* The mailbox node takes over ownership of the
-         * FolderDialogData. */
-        g_object_set_data_full(G_OBJECT(fcw->mbnode),
-                               BALSA_FOLDER_CONF_IMAP_KEY, fcw,
-                               (GDestroyNotify) folder_conf_destroy_cdd);
+    libbalsa_server_cfg_assign_server(fcw->server_cfg, fcw->server);
+
+    imap = LIBBALSA_IMAP_SERVER(fcw->server);
+    libbalsa_imap_server_set_max_connections(imap, 
gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(fcw->connection_limit)));
+    libbalsa_imap_server_enable_persistent_cache(imap, 
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->enable_persistent)));
+    libbalsa_imap_server_set_use_idle(imap, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->use_idle)));
+    libbalsa_imap_server_set_bug(imap, ISBUG_FETCH, 
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->has_bugs)));
+    libbalsa_imap_server_set_use_status(imap, 
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->use_status)));
+
+    if (insert) {
+       fcw->mbnode = balsa_mailbox_node_new_imap_folder(fcw->server, NULL);
+       g_object_ref(fcw->mbnode);
+       /* The mailbox node takes over ownership of the
+        * FolderDialogData. */
+       g_object_set_data_full(G_OBJECT(fcw->mbnode),
+               BALSA_FOLDER_CONF_IMAP_KEY, fcw,
+                       (GDestroyNotify) folder_conf_destroy_cdd);
     }
 
+    g_free(fcw->mbnode->name);
+    fcw->mbnode->name = g_strdup(libbalsa_server_cfg_get_name(fcw->server_cfg));
+    fcw->mbnode->subscribed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->subscribed));
+    fcw->mbnode->list_inbox = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->list_inbox));
     g_free(fcw->mbnode->dir);
     fcw->mbnode->dir = g_strdup(gtk_entry_get_text(GTK_ENTRY(fcw->prefix)));
-    g_free(fcw->mbnode->name);
-    fcw->mbnode->name =
-        g_strdup(gtk_entry_get_text(GTK_ENTRY(fcw->folder_name)));
-    fcw->mbnode->subscribed =
-        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->subscribed));
-    fcw->mbnode->list_inbox =
-        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fcw->list_inbox));
 
-    libbalsa_server_set_host(s, host, s->security);
-    libbalsa_server_config_changed(s); /* trigger config save */
+    libbalsa_server_config_changed(fcw->server); /* trigger config save */
 
     if (insert) {
-       balsa_mblist_mailbox_node_append(NULL, fcw->mbnode);
-        balsa_mailbox_node_append_subtree(fcw->mbnode);
-        config_folder_add(fcw->mbnode, NULL);
-       g_signal_connect_swapped(s, "config-changed",
-                                G_CALLBACK(config_folder_update),
-                                fcw->mbnode);
-        update_mail_servers();
+       balsa_mblist_mailbox_node_append(NULL, fcw->mbnode);
+       balsa_mailbox_node_append_subtree(fcw->mbnode);
+       config_folder_add(fcw->mbnode, NULL);
+       g_signal_connect_swapped(fcw->server, "config-changed", G_CALLBACK(config_folder_update), 
fcw->mbnode);
+       update_mail_servers();
     } else {
-        balsa_mailbox_node_rescan(fcw->mbnode);
-       balsa_mblist_mailbox_node_redraw(fcw->mbnode);
+       balsa_mailbox_node_rescan(fcw->mbnode);
+       balsa_mblist_mailbox_node_redraw(fcw->mbnode);
     }
+
     return TRUE;
 }
 
@@ -295,20 +219,8 @@ folder_conf_clicked_ok(FolderDialogData * fcw)
 void
 folder_conf_imap_node(BalsaMailboxNode *mn)
 {
-    GtkWidget *notebook, *grid, *label, *advanced;
     FolderDialogData *fcw;
     static FolderDialogData *fcw_new;
-    LibBalsaServer *s;
-    gchar *default_server;
-    int r = 0;
-
-#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) */
 
     /* Allow only one dialog per mailbox node, and one with mn == NULL
      * for creating a new folder. */
@@ -319,9 +231,13 @@ folder_conf_imap_node(BalsaMailboxNode *mn)
         return;
     }
 
-    s = mn ? mn->server : NULL;
-
     fcw = g_new(FolderDialogData, 1);
+    if (mn != NULL) {
+       fcw->server = mn->server;
+    } else {
+       fcw->server = g_object_new(LIBBALSA_TYPE_IMAP_SERVER, NULL);
+    }
+
     fcw->ok = (CommonDialogFunc) folder_conf_clicked_ok;
     fcw->mbnode = mn;
     fcw->dialog =
@@ -350,127 +266,42 @@ folder_conf_imap_node(BalsaMailboxNode *mn)
                                   (gpointer) &fcw_new);
     }
 
-    notebook = gtk_notebook_new();
-    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(fcw->dialog)),
-                       notebook, TRUE, TRUE, 0);
-    grid = libbalsa_create_grid();
-    gtk_container_set_border_width(GTK_CONTAINER(grid), 12);
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), grid,
-                             gtk_label_new_with_mnemonic(_("_Basic")));
-    advanced = balsa_server_conf_get_advanced_widget(&fcw->bsc);
-    /* Limit number of connections */
-    fcw->connection_limit = 
-        balsa_server_conf_add_spinner
-        (&fcw->bsc, _("_Max number of connections:"), 1, 40, 1,
-         s 
-         ? libbalsa_imap_server_get_max_connections(LIBBALSA_IMAP_SERVER(s))
-         : 20);
-    fcw->enable_persistent = 
-        balsa_server_conf_add_checkbox(&fcw->bsc,
-                                       _("Enable _persistent cache"));
-    if(!s || 
-       libbalsa_imap_server_has_persistent_cache(LIBBALSA_IMAP_SERVER(s)))
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcw->enable_persistent),
-                                     TRUE);
-    fcw->use_idle = 
-        balsa_server_conf_add_checkbox(&fcw->bsc,
-                                       _("Use IDLE command"));
-    if(s &&
-       libbalsa_imap_server_get_use_idle(LIBBALSA_IMAP_SERVER(s)))
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcw->use_idle),
-                                     TRUE);
-    fcw->has_bugs = 
-        balsa_server_conf_add_checkbox(&fcw->bsc,
-                                       _("Enable _bug workarounds"));
-    if(s &&
-       libbalsa_imap_server_has_bug(LIBBALSA_IMAP_SERVER(s), ISBUG_FETCH))
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcw->has_bugs),
-                                     TRUE);
-    fcw->use_status = 
-        balsa_server_conf_add_checkbox(&fcw->bsc,
-                                       _("Use STATUS for mailbox checking"));
-    if(s &&
-       libbalsa_imap_server_get_use_status(LIBBALSA_IMAP_SERVER(s)))
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcw->use_status),
-                                     TRUE);
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advanced,
-                             gtk_label_new_with_mnemonic(_("_Advanced")));
-
-    /* INPUT FIELD CREATION */
-    label = libbalsa_create_grid_label(_("Descriptive _name:"), grid, 0);
-    fcw->folder_name =
-        libbalsa_create_grid_entry(grid, G_CALLBACK(validate_folder),
-                                   fcw, r++, mn ? mn->name : NULL,
-                                  label);
-
-    default_server = libbalsa_guess_imap_server();
-    label = libbalsa_create_grid_label(_("_Server:"), grid, 1);
-    fcw->bsc.server =
-        libbalsa_create_grid_entry(grid, G_CALLBACK(validate_folder),
-                                   fcw, r++, s ? s->host : default_server,
-                                   label);
-    g_free(default_server);
-
-    label = libbalsa_create_grid_label(_("Se_curity:"), grid, r);
-    fcw->bsc.security = gtk_combo_box_text_new();
-    gtk_widget_set_hexpand(fcw->bsc.security, TRUE);
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fcw->bsc.security), _("IMAP over SSL (IMAPS)"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fcw->bsc.security), _("TLS required"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fcw->bsc.security), _("TLS if possible (not 
recommended)"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(fcw->bsc.security), _("None (not recommended)"));
-    gtk_grid_attach(GTK_GRID(grid), fcw->bsc.security, 1, r++, 1, 1);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(fcw->bsc.security), s ? s->security - 1 : 
NET_CLIENT_CRYPT_STARTTLS - 1);
-    g_signal_connect(fcw->bsc.security, "changed", G_CALLBACK(security_cb), fcw);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), fcw->bsc.security);
-
-    label= libbalsa_create_grid_label(_("Use_r name:"), grid, r);
-    fcw->username =
-        libbalsa_create_grid_entry(grid, G_CALLBACK(validate_folder),
-                                   fcw, r++, s ? s->user : g_get_user_name(),
-                                   label);
-
-    label = libbalsa_create_grid_label(_("_Password:"), grid, r);
-    fcw->password =
-        libbalsa_create_grid_entry(grid, NULL, NULL, r++,
-                                   s ? s->passwd : NULL, label);
-    gtk_entry_set_visibility(GTK_ENTRY(fcw->password), FALSE);
-
-    fcw->anonymous =
-        libbalsa_create_grid_check(_("_Anonymous access"), grid, r++,
-                                   s ? s->try_anonymous : FALSE);
-    g_signal_connect(G_OBJECT(fcw->anonymous), "toggled",
-                     G_CALLBACK(anonymous_cb), fcw);
-    fcw->remember =
-        libbalsa_create_grid_check(_(remember_password_message), grid, r++,
-                                   s ? s->remember_passwd : TRUE);
-    g_signal_connect(G_OBJECT(fcw->remember), "toggled",
-                     G_CALLBACK(remember_cb), fcw);
-
-    fcw->subscribed =
-        libbalsa_create_grid_check(_("Subscribed _folders only"), grid, r++,
-                                   mn ? mn->subscribed : FALSE);
-    fcw->list_inbox =
-        libbalsa_create_grid_check(_("Always show _Inbox"), grid, r++,
-                                   mn ? mn->list_inbox : TRUE);
-
-    label = libbalsa_create_grid_label(_("Pr_efix:"), grid, r);
-    fcw->prefix =
-        libbalsa_create_grid_entry(grid, NULL, NULL, r++,
-                                   mn ? mn->dir : NULL, label);
+    fcw->server_cfg = libbalsa_server_cfg_new(fcw->server, (mn != NULL) ? mn->name : NULL);
+    gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(fcw->dialog))), 
GTK_WIDGET(fcw->server_cfg));
+    g_signal_connect(fcw->server_cfg, "changed", G_CALLBACK(validate_folder), fcw);
+
+    /* additional basic settings */
+    fcw->subscribed = libbalsa_server_cfg_add_check(fcw->server_cfg, TRUE, _("Subscribed _folders only"),
+       (mn != NULL) ? mn->subscribed : FALSE, NULL, NULL);
+    fcw->list_inbox = libbalsa_server_cfg_add_check(fcw->server_cfg, TRUE, _("Always show _Inbox"),
+       (mn != NULL) ? mn->list_inbox : TRUE, NULL, NULL);
+    fcw->prefix = libbalsa_server_cfg_add_entry(fcw->server_cfg, TRUE, _("Pr_efix:"),
+       (mn != NULL) ? mn->dir : NULL, NULL, NULL);
+
+    /* additional advanced settings */
+    fcw->connection_limit = gtk_spin_button_new_with_range(1.0, 40.0, 1.0);
+    gtk_spin_button_set_value(GTK_SPIN_BUTTON(fcw->connection_limit),
+       (gdouble) libbalsa_imap_server_get_max_connections(LIBBALSA_IMAP_SERVER(fcw->server)));
+    libbalsa_server_cfg_add_item(fcw->server_cfg, FALSE, _("_Max number of connections:"), 
fcw->connection_limit);
+    fcw->enable_persistent = libbalsa_server_cfg_add_check(fcw->server_cfg, FALSE, _("Enable _persistent 
cache"),
+       libbalsa_imap_server_has_persistent_cache(LIBBALSA_IMAP_SERVER(fcw->server)), NULL, NULL);
+    fcw->use_idle = libbalsa_server_cfg_add_check(fcw->server_cfg, FALSE, _("Use IDLE command"),
+       libbalsa_imap_server_get_use_idle(LIBBALSA_IMAP_SERVER(fcw->server)), NULL, NULL);
+    fcw->has_bugs = libbalsa_server_cfg_add_check(fcw->server_cfg, FALSE, _("Enable _bug workarounds"),
+       libbalsa_imap_server_has_bug(LIBBALSA_IMAP_SERVER(fcw->server), ISBUG_FETCH), NULL, NULL);
+    fcw->use_status = libbalsa_server_cfg_add_check(fcw->server_cfg, FALSE, _("Use STATUS for mailbox 
checking"),
+       libbalsa_imap_server_get_use_status(LIBBALSA_IMAP_SERVER(fcw->server)), NULL, NULL);
 
     gtk_widget_show_all(GTK_WIDGET(fcw->dialog));
 
     validate_folder(NULL, fcw);
-    gtk_widget_grab_focus(fcw->folder_name);
 
     gtk_dialog_set_default_response(fcw->dialog, 
                                     mn ? GTK_RESPONSE_OK 
                                     : GTK_RESPONSE_CANCEL);
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
 
     g_signal_connect(G_OBJECT(fcw->dialog), "response",
                      G_CALLBACK(folder_conf_response), fcw);
-    gtk_widget_show_all(GTK_WIDGET(fcw->dialog));
 }
 
 /* folder_conf_imap_sub_node:
diff --git a/src/mailbox-conf.c b/src/mailbox-conf.c
index 4f4d00aab..fe9f90077 100644
--- a/src/mailbox-conf.c
+++ b/src/mailbox-conf.c
@@ -50,6 +50,7 @@
 #include "mailbox-node.h"
 #include "pref-manager.h"
 #include "save-restore.h"
+#include "server-config.h"
 
 #include "libbalsa.h"
 #include "imap-server.h"
@@ -62,7 +63,6 @@
 #endif
 
 struct _BalsaMailboxConfView {
-    GtkWindow *window;
     GtkWidget *identity_combo_box;
     GtkWidget *show_to;
     GtkWidget *subscribe;
@@ -73,7 +73,9 @@ struct _BalsaMailboxConfView {
     GtkWidget *subject_gather;
     LibBalsaMailbox *mailbox;
 };
+
 typedef struct _MailboxConfWindow MailboxConfWindow;
+
 struct _MailboxConfWindow {
     LibBalsaMailbox *mailbox;
 
@@ -81,33 +83,22 @@ struct _MailboxConfWindow {
 
     void (*ok_handler)(MailboxConfWindow*);
     const gchar *ok_button_name;
-    GtkWidget *mailbox_name;
     GType mailbox_type;
     BalsaMailboxConfView *view_info;
-    gboolean ok_sensitive;
 
     union {
-       /* for imap mailboxes & directories */
+       /* for local mailboxes */
        struct {
-           GtkWidget *port;
-           GtkWidget *username;
-            GtkWidget *anonymous;
-            GtkWidget *remember;
-           GtkWidget *password;
-           GtkWidget *folderpath;
-            GtkWidget *enable_persistent, *has_bugs;
-            BalsaServerConf bsc;
-       } imap;
+           GtkWidget *mailbox_name;
+       } local;
 
        /* for pop3 mailboxes */
        struct {
-           GtkWidget *username;
-           GtkWidget *password;
+               LibBalsaServerCfg *server_cfg;
            GtkWidget *check;
            GtkWidget *delete_from_server;
-            BalsaServerConf bsc;
-            GtkWidget *disable_apop;
-            GtkWidget *enable_pipe;
+           GtkWidget *disable_apop;
+           GtkWidget *enable_pipe;
            GtkWidget *filter;
            GtkWidget *filter_cmd;
        } pop3;
@@ -120,10 +111,6 @@ static void mailbox_conf_add(MailboxConfWindow *conf_window);
 /* misc functions */
 static void mailbox_conf_set_values(MailboxConfWindow *mcw);
 
-static void fill_in_imap_data(MailboxConfWindow *mcw, gchar ** name, 
-                              gchar ** path);
-static void update_imap_mailbox(MailboxConfWindow *mcw);
-
 static void update_pop_mailbox(MailboxConfWindow *mcw);
 static BalsaMailboxConfView *
     mailbox_conf_view_new_full(LibBalsaMailbox * mailbox,
@@ -140,158 +127,6 @@ static GtkWidget *create_pop_mailbox_dialog(MailboxConfWindow *mcw);
 
 static void check_for_blank_fields(GtkWidget *widget, MailboxConfWindow *mcw);
 
-/* ========================================================= */
-/* BEGIN BalsaServerConf =================================== */
-#ifdef HAVE_GPGME
-struct menu_data {
-    const char *label;
-    int tag;
-};
-struct mailbox_conf_combo_box_info {
-    GSList *tags;
-};
-#define BALSA_MC_COMBO_BOX_INFO "balsa-mailbox-conf-combo-box-info"
-
-static void
-mailbox_conf_combo_box_info_free(struct mailbox_conf_combo_box_info *info)
-{
-    g_slist_free(info->tags);
-    g_free(info);
-}
-
-static void
-mailbox_conf_combo_box_make(GtkComboBoxText * combo_box, unsigned cnt,
-                            const struct menu_data *data)
-{
-    struct mailbox_conf_combo_box_info *info =
-        g_new(struct mailbox_conf_combo_box_info, 1);
-    gint i;
-
-    info->tags = NULL;
-    for (i = cnt; --i >= 0;) {
-        gtk_combo_box_text_prepend_text(combo_box, _(data[i].label));
-        info->tags =
-            g_slist_prepend(info->tags, GINT_TO_POINTER(data[i].tag));
-    }
-    g_object_set_data_full(G_OBJECT(combo_box), BALSA_MC_COMBO_BOX_INFO,
-                           info,
-                           (GDestroyNotify)
-                           mailbox_conf_combo_box_info_free);
-}
-#endif /* HAVE_GPGME */
-
-
-GtkWidget*
-balsa_server_conf_get_advanced_widget(BalsaServerConf *bsc)
-{
-    GtkWidget *box;
-    GtkWidget *label;
-
-    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
-
-    bsc->grid = GTK_GRID(libbalsa_create_grid());
-    gtk_container_set_border_width(GTK_CONTAINER(bsc->grid), 12);
-    gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(bsc->grid), FALSE, FALSE, 0);
-
-    bsc->used_rows = 0U;
-
-    /* client certificate configuration */
-    bsc->need_client_cert = balsa_server_conf_add_checkbox(bsc, _("Server requires client certificate"));
-
-    label = libbalsa_create_grid_label(_("Certificate _File:"), GTK_WIDGET(bsc->grid), bsc->used_rows);
-    bsc->client_cert_file = gtk_file_chooser_button_new(_("Choose Client Certificate"), 
GTK_FILE_CHOOSER_ACTION_OPEN);
-    gtk_widget_set_hexpand(bsc->client_cert_file, TRUE);
-    gtk_grid_attach(bsc->grid, bsc->client_cert_file, 1, bsc->used_rows++, 1, 1);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), bsc->client_cert_file);
-
-    label = libbalsa_create_grid_label(_("Certificate _Pass Phrase:"), GTK_WIDGET(bsc->grid), 
bsc->used_rows);
-    bsc->client_cert_passwd = libbalsa_create_grid_entry(GTK_WIDGET(bsc->grid), NULL, NULL, 
bsc->used_rows++, NULL, label);
-    g_object_set(G_OBJECT(bsc->client_cert_passwd), "input-purpose", GTK_INPUT_PURPOSE_PASSWORD, NULL);
-    gtk_entry_set_visibility(GTK_ENTRY(bsc->client_cert_passwd), FALSE);
-
-    return box;
-}
-
-GtkWidget*
-balsa_server_conf_add_checkbox(BalsaServerConf *bsc,
-                               const char *label)
-{
-    return libbalsa_create_grid_check(label, GTK_WIDGET(bsc->grid),
-                                      bsc->used_rows++, FALSE);
-}
-
-GtkWidget*
-balsa_server_conf_add_spinner(BalsaServerConf *bsc,
-                              const char *label, gint lo, gint hi, gint step,
-                              gint initial_value)
-{
-    GtkWidget *spin_button;
-    GtkWidget *lbl = libbalsa_create_grid_label(label, GTK_WIDGET(bsc->grid),
-                                                bsc->used_rows);
-    spin_button = gtk_spin_button_new_with_range(lo, hi, step);
-    gtk_widget_set_hexpand(spin_button, TRUE);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_button),
-                             (float) initial_value);
-
-    gtk_grid_attach(bsc->grid, spin_button, 1, bsc->used_rows, 1, 1);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(lbl), spin_button);
-    bsc->used_rows++;
-    return spin_button;
-}
-
-NetClientCryptMode
-balsa_server_conf_get_security(BalsaServerConf *bsc)
-{
-       return gtk_combo_box_get_active(GTK_COMBO_BOX(bsc->security)) + 1;
-}
-
-/* END BalsaServerConf ===================================== */
-/* ========================================================= */
-
-static void
-pop3_enable_filter_cb(GtkWidget * w, MailboxConfWindow * mcw)
-{
-    GtkToggleButton *button = GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.filter);
-    gtk_widget_set_sensitive(mcw->mb_data.pop3.filter_cmd,
-                             gtk_toggle_button_get_active(button));
-    check_for_blank_fields(NULL, mcw);
-}
-
-static void
-client_cert_changed(GtkToggleButton *button, MailboxConfWindow *mcw)
-{
-       gboolean sensitive;
-       BalsaServerConf *bsc;
-
-       if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3)) {
-               bsc = &mcw->mb_data.pop3.bsc;
-       } else {
-               bsc = &mcw->mb_data.imap.bsc;
-       }
-       sensitive = gtk_toggle_button_get_active(button);
-       gtk_widget_set_sensitive(bsc->client_cert_file, sensitive);
-       gtk_widget_set_sensitive(bsc->client_cert_passwd, sensitive);
-    check_for_blank_fields(NULL, mcw);
-}
-
-static void
-security_changed(GtkComboBox *combo, MailboxConfWindow *mcw)
-{
-       gboolean sensitive;
-       BalsaServerConf *bsc;
-
-       if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3)) {
-               bsc = &mcw->mb_data.pop3.bsc;
-       } else {
-               bsc = &mcw->mb_data.imap.bsc;
-       }
-       sensitive = (gtk_combo_box_get_active(combo) + 1) != NET_CLIENT_CRYPT_NONE;
-       gtk_widget_set_sensitive(bsc->need_client_cert, sensitive);
-       sensitive = sensitive & gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bsc->need_client_cert));
-       gtk_widget_set_sensitive(bsc->client_cert_file, sensitive);
-       gtk_widget_set_sensitive(bsc->client_cert_passwd, sensitive);
-    check_for_blank_fields(NULL, mcw);
-}
 
 /* BEGIN OF COMMONLY USED CALLBACKS SECTION ---------------------- */
 
@@ -495,17 +330,23 @@ static void
 conf_response_cb(GtkDialog* dialog, gint response, MailboxConfWindow * mcw)
 {
     switch(response) {
-    case MCW_RESPONSE: mcw->ok_handler(mcw); 
-        /* fall through */
+    case MCW_RESPONSE:
+       /* add or update */
+       mcw->ok_handler(mcw);
+        g_object_set_data(G_OBJECT(mcw->mailbox), BALSA_MAILBOX_CONF_DIALOG, NULL);
+        break;
     default:
-        if (mcw->mailbox)
-            g_object_set_data(G_OBJECT(mcw->mailbox),
-                              BALSA_MAILBOX_CONF_DIALOG, NULL);
-        gtk_widget_destroy(GTK_WIDGET(dialog));
-        /* fall through */
-    case 0:
+       /* everything else */
+       if (mcw->ok_handler == mailbox_conf_add) {
+               /* add: destroy intermediate mailbox */
+               g_object_unref(mcw->mailbox);
+               mcw->mailbox = NULL;
+       } else {
+            g_object_set_data(G_OBJECT(mcw->mailbox), BALSA_MAILBOX_CONF_DIALOG, NULL);
+       }
         break;
     }
+    gtk_widget_destroy(GTK_WIDGET(dialog));
 }
 
 static GtkWidget *
@@ -526,20 +367,23 @@ run_mailbox_conf(BalsaMailboxNode* mbnode, GType mailbox_type,
     } else {
         mcw->ok_handler = mailbox_conf_add;
         mcw->ok_button_name = _("_Add");
+        mcw->mailbox = g_object_new(mailbox_type, NULL);
     }
     mcw->mailbox_type = mailbox_type;
 
     mcw->window = GTK_DIALOG(create_dialog(mcw));
     g_object_weak_ref(G_OBJECT(mcw->window), (GWeakNotify) g_free, mcw);
     
-    gtk_dialog_set_response_sensitive(mcw->window, MCW_RESPONSE, FALSE);
-    mcw->ok_sensitive = FALSE;
+    if (!g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3)) {
+       gtk_dialog_set_response_sensitive(mcw->window, MCW_RESPONSE, FALSE);
+    }
     gtk_dialog_set_default_response(mcw->window,
                                     update ? GTK_RESPONSE_CANCEL :
                                     MCW_RESPONSE);
 
-    if(mbnode)
+    if ((mbnode != NULL) && (mbnode == NULL) && (!g_type_is_a(mcw->mailbox_type, 
LIBBALSA_TYPE_MAILBOX_POP3))) {
         mailbox_conf_set_values(mcw);
+    }
 
     g_signal_connect(G_OBJECT(mcw->window), "response", 
                      G_CALLBACK(conf_response_cb), mcw);
@@ -589,61 +433,10 @@ mailbox_conf_edit(BalsaMailboxNode * mbnode)
                       dialog);
 }
 
-static void
-mailbox_conf_set_values_pop3(LibBalsaMailbox   *mailbox,
-                                                        MailboxConfWindow *mcw)
-{
-       LibBalsaMailboxPop3 *pop3;
-       LibBalsaServer *server;
-       gboolean sensitive;
-
-       pop3 = LIBBALSA_MAILBOX_POP3(mailbox);
-       server = LIBBALSA_MAILBOX_REMOTE_SERVER(mailbox);
-
-       /* basic settings */
-       if (server->host != NULL) {
-               gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.pop3.bsc.server), server->host);
-       }
-       gtk_combo_box_set_active(GTK_COMBO_BOX(mcw->mb_data.pop3.bsc.security), server->security - 1);
-
-       if (server->user != NULL) {
-               gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.pop3.username), server->user);
-       }
-
-       if (server->passwd != NULL) {
-               gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.pop3.password), server->passwd);
-       }
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.delete_from_server), 
pop3->delete_from_server);
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.check), pop3->check);
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.filter), pop3->filter);
-       if (pop3->filter_cmd != NULL) {
-               gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.pop3.filter_cmd), pop3->filter_cmd);
-       }
-       gtk_widget_set_sensitive(mcw->mb_data.pop3.filter_cmd, pop3->filter);
-
-       /* advanced settings */
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.bsc.need_client_cert), 
server->client_cert);
-       sensitive = (server->security != NET_CLIENT_CRYPT_NONE);
-       gtk_widget_set_sensitive(mcw->mb_data.pop3.bsc.need_client_cert, sensitive);
-       sensitive = sensitive & server->client_cert;
-
-    if (server->cert_file != NULL) {
-       gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(mcw->mb_data.pop3.bsc.client_cert_file), 
server->cert_file);
-    }
-    gtk_widget_set_sensitive(mcw->mb_data.pop3.bsc.client_cert_file, sensitive);
-
-       if (server->cert_passphrase != NULL) {
-               gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.pop3.bsc.client_cert_passwd), 
server->cert_passphrase);
-       }
-       gtk_widget_set_sensitive(mcw->mb_data.pop3.bsc.client_cert_passwd, sensitive);
-
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.disable_apop), pop3->disable_apop);
-       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.enable_pipe), pop3->enable_pipe);
-}
-
-
 /*
  * Initialise the dialogs fields from mcw->mailbox
+ *
+ * Note: used for local mailboxes only
  */
 static void
 mailbox_conf_set_values(MailboxConfWindow *mcw)
@@ -652,65 +445,19 @@ mailbox_conf_set_values(MailboxConfWindow *mcw)
 
        mailbox = mcw->mailbox;
 
-       g_return_if_fail(LIBBALSA_IS_MAILBOX(mailbox));
-
-       if (mcw->mailbox_name && mailbox->name)
-               gtk_entry_set_text(GTK_ENTRY(mcw->mailbox_name), mailbox->name);
-
-       if (LIBBALSA_IS_MAILBOX_LOCAL(mailbox)) {
-               if (mailbox->url) {
-                       GtkFileChooser *chooser = GTK_FILE_CHOOSER(mcw->window);
-                       LibBalsaMailboxLocal *local = LIBBALSA_MAILBOX_LOCAL(mailbox);
-                       const gchar *path = libbalsa_mailbox_local_get_path(local);
-                       gchar *basename = g_path_get_basename(path);
-                       gtk_file_chooser_set_filename(chooser, path);
-                       gtk_file_chooser_set_current_name(chooser, basename);
-                       g_free(basename);
-               }
-       } else if (LIBBALSA_IS_MAILBOX_POP3(mailbox)) {
-               mailbox_conf_set_values_pop3(mailbox, mcw);
-       } else if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
-               LibBalsaMailboxImap *imap;
-               LibBalsaServer *server;
-               const gchar *path;
-               imap = LIBBALSA_MAILBOX_IMAP(mailbox);
-               server = LIBBALSA_MAILBOX_REMOTE_SERVER(mailbox);
-
-               if (server->host)
-                       gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.imap.bsc.server),
-                               server->host);
-               if (server->user)
-                       gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.imap.username),
-                               server->user);
-               gtk_toggle_button_set_active
-               (GTK_TOGGLE_BUTTON(mcw->mb_data.imap.anonymous),
-                       server->try_anonymous);
-               gtk_toggle_button_set_active
-               (GTK_TOGGLE_BUTTON(mcw->mb_data.imap.remember),
-                       server->remember_passwd);
-               if (server->passwd)
-                       gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.imap.password),
-                               server->passwd);
-               path = libbalsa_mailbox_imap_get_path(imap);
-               if (path)
-                       gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.imap.folderpath),
-                               path);
-               if(libbalsa_imap_server_has_persistent_cache
-                       (LIBBALSA_IMAP_SERVER(server)))
-                       gtk_toggle_button_set_active
-                       (GTK_TOGGLE_BUTTON(mcw->mb_data.imap.enable_persistent),
-                               TRUE);
-               if(libbalsa_imap_server_has_bug(LIBBALSA_IMAP_SERVER(server),
-                       ISBUG_FETCH))
-                       gtk_toggle_button_set_active
-                       (GTK_TOGGLE_BUTTON(mcw->mb_data.imap.has_bugs),
-                               TRUE);
-               if(!server->try_anonymous)
-                       gtk_widget_set_sensitive(GTK_WIDGET(mcw->mb_data.imap.anonymous),
-                               FALSE);
-               if(!server->remember_passwd)
-                       gtk_widget_set_sensitive(GTK_WIDGET(mcw->mb_data.imap.password),
-                               FALSE);
+       g_return_if_fail(LIBBALSA_IS_MAILBOX_LOCAL(mailbox));
+
+       if (mcw->mb_data.local.mailbox_name && mailbox->name)
+               gtk_entry_set_text(GTK_ENTRY(mcw->mb_data.local.mailbox_name), mailbox->name);
+
+       if (mailbox->url) {
+               GtkFileChooser *chooser = GTK_FILE_CHOOSER(mcw->window);
+               LibBalsaMailboxLocal *local = LIBBALSA_MAILBOX_LOCAL(mailbox);
+               const gchar *path = libbalsa_mailbox_local_get_path(local);
+               gchar *basename = g_path_get_basename(path);
+               gtk_file_chooser_set_filename(chooser, path);
+               gtk_file_chooser_set_current_name(chooser, basename);
+               g_free(basename);
        }
 }
 
@@ -722,85 +469,46 @@ mailbox_conf_set_values(MailboxConfWindow *mcw)
  * on any widget which can affect the validity of the input.
  */
 static void
-check_for_blank_fields(GtkWidget G_GNUC_UNUSED *widget, MailboxConfWindow *mcw)
+check_for_blank_fields(GtkWidget G_GNUC_UNUSED *widget,
+                                          MailboxConfWindow       *mcw)
 {
     gboolean sensitive;
-    BalsaServerConf *bsc = NULL;
 
-    if (mcw == NULL || mcw->window == NULL)
+    if ((mcw == NULL) || (mcw->window == NULL)) {
         return;
-
-    sensitive = TRUE;
-
-    if (mcw->mailbox_name &&!*gtk_entry_get_text(GTK_ENTRY(mcw->mailbox_name))) {
-       sensitive = FALSE;
-    } else if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_LOCAL) ) {
-       gchar *filename =
-               gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(mcw->window));
-       if (filename) {
-               g_free(filename);
-       } else {
-               sensitive = FALSE;
-       }
-    } else if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_IMAP ) ) {
-       bsc = &mcw->mb_data.imap.bsc;
-       if (!*gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.imap.folderpath))
-               || !*gtk_entry_get_text(GTK_ENTRY(bsc->server))
-                       || !*gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.imap.username))) {
-               sensitive = FALSE;
-       }
-    } else if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3) ) {
-       /* POP3: require user name and server */
-       bsc = &mcw->mb_data.pop3.bsc;
-       if ((gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.pop3.username))[0] == '\0') ||
-               (gtk_entry_get_text(GTK_ENTRY(bsc->server))[0] == '\0')) {
-               sensitive = FALSE;
-       }
-       /* procmail filtering requires command */
-       if (sensitive &&
-               gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.filter)) &&
-                       (gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.pop3.filter_cmd))[0] == '\0')) {
-               sensitive = FALSE;
-       }
     }
 
-    /* encryption w/ client cert requires cert file */
-    if (sensitive && (bsc != NULL) &&
-       ((gtk_combo_box_get_active(GTK_COMBO_BOX(bsc->security)) + 1) != NET_CLIENT_CRYPT_NONE) &&
-               gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bsc->need_client_cert))) {
-       gchar *cert_file;
+    if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3)) {
+       gboolean enable_filter;
+
+       sensitive = libbalsa_server_cfg_valid(mcw->mb_data.pop3.server_cfg);
 
-       cert_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(bsc->client_cert_file));
-       if ((cert_file == NULL) || (cert_file[0] == '\0')) {
-               sensitive = FALSE;
+       /* procmail filter */
+       enable_filter = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.filter));
+       gtk_widget_set_sensitive(mcw->mb_data.pop3.filter_cmd, enable_filter);
+       if (enable_filter) {
+               sensitive = sensitive && (*gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.pop3.filter_cmd)) != 
'\0');
        }
-       g_free(cert_file);
+    } else if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_LOCAL)) {
+       sensitive = TRUE;
+
+        if ((mcw->mb_data.local.mailbox_name != NULL) &&
+               (*gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.local.mailbox_name)) == '\0')) {
+               sensitive = FALSE;
+        } else if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_LOCAL)) {
+               gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(mcw->window));
+               if (filename != NULL) {
+                       g_free(filename);
+               } else {
+                       sensitive = FALSE;
+               }
+        }
+    } else {
+       g_assert_not_reached();
     }
 
     gtk_dialog_set_response_sensitive(mcw->window, MCW_RESPONSE, sensitive);
-    mcw->ok_sensitive = sensitive;
-}
-
-/*
- * Update an IMAP mailbox with details from the dialog
- */
-static void
-fill_in_imap_data(MailboxConfWindow *mcw, gchar ** name, gchar ** path)
-{
-    *path =
-       gtk_editable_get_chars(GTK_EDITABLE(mcw->mb_data.imap.folderpath),
-                               0, -1);
-
-    if (mcw->mailbox_name && (!(*name =
-         g_strdup(gtk_entry_get_text(GTK_ENTRY(mcw->mailbox_name))))
-       || *(g_strstrip(*name)) == '\0')) {
-       if (*name)
-           g_free(*name);
-
-       *name = g_strdup_printf(_("%s on %s"), *path,
-                               gtk_entry_get_text(GTK_ENTRY
-                                                  (mcw->mb_data.imap.bsc.server)));
-    }
+    gtk_dialog_set_default_response(mcw->window, sensitive ? MCW_RESPONSE : GTK_RESPONSE_CANCEL);
 }
 
 /*
@@ -811,21 +519,14 @@ update_pop_mailbox(MailboxConfWindow *mcw)
 {
        LibBalsaMailboxPop3 *mailbox;
        LibBalsaServer *server;
-       BalsaServerConf *bsc;
 
        mailbox = LIBBALSA_MAILBOX_POP3(mcw->mailbox);
        server = LIBBALSA_MAILBOX_REMOTE_SERVER(mailbox);
-       bsc = &mcw->mb_data.pop3.bsc;
 
        /* basic data */
        g_free(LIBBALSA_MAILBOX(mailbox)->name);
-       LIBBALSA_MAILBOX(mailbox)->name = g_strdup(gtk_entry_get_text(GTK_ENTRY(mcw->mailbox_name)));
-
-       server->security = balsa_server_conf_get_security(&mcw->mb_data.pop3.bsc);
-       libbalsa_server_set_host(server, gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.pop3.bsc.server)), 
server->security);
-
-       libbalsa_server_set_username(server, gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.pop3.username)));
-       libbalsa_server_set_password(server, gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.pop3.password)));
+       LIBBALSA_MAILBOX(mailbox)->name = 
g_strdup(libbalsa_server_cfg_get_name(mcw->mb_data.pop3.server_cfg));
+       libbalsa_server_cfg_assign_server(mcw->mb_data.pop3.server_cfg, server);
        libbalsa_server_config_changed(server);
 
        mailbox->check = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.check));
@@ -835,74 +536,10 @@ update_pop_mailbox(MailboxConfWindow *mcw)
        mailbox->filter_cmd = g_strdup(gtk_entry_get_text(GTK_ENTRY(mcw->mb_data.pop3.filter_cmd)));
 
        /* advanced settings */
-       server->client_cert = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bsc->need_client_cert));
-       g_free(server->cert_file);
-       server->cert_file = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(bsc->client_cert_file)));;
-       g_free(server->cert_passphrase);
-       server->cert_passphrase = g_strdup(gtk_entry_get_text(GTK_ENTRY(bsc->client_cert_passwd)));
        mailbox->disable_apop = 
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.disable_apop));
        mailbox->enable_pipe = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mcw->mb_data.pop3.enable_pipe));
 }
 
-/*
- * Update an imap mcw->mailbox with details from the dialog
- */
-static void
-update_imap_mailbox(MailboxConfWindow *mcw)
-{
-    gchar *path;
-    LibBalsaMailboxImap *mailbox;
-    LibBalsaServer* server;
-
-    mailbox = LIBBALSA_MAILBOX_IMAP(mcw->mailbox);
-    server  = LIBBALSA_MAILBOX_REMOTE_SERVER(mailbox);
-    if (!server) {
-       server = LIBBALSA_SERVER(libbalsa_imap_server_new("",""));
-       libbalsa_mailbox_remote_set_server(LIBBALSA_MAILBOX_REMOTE(mailbox),
-                                          server);
-       g_signal_connect_swapped(server, "config-changed",
-                                 G_CALLBACK(config_mailbox_update),
-                                mailbox);
-    }
-    g_free(LIBBALSA_MAILBOX(mailbox)->name);
-    fill_in_imap_data(mcw, &LIBBALSA_MAILBOX(mailbox)->name, &path);
-    libbalsa_server_set_username(server,
-                                gtk_entry_get_text(GTK_ENTRY
-                                                   (mcw->mb_data.imap.username)));
-    server->try_anonymous = 
-        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mcw->
-                                                       mb_data.imap.anonymous));
-    server->remember_passwd = 
-        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mcw->
-                                                       mb_data.imap.remember));
-       server->security = balsa_server_conf_get_security(&mcw->mb_data.imap.bsc);
-    libbalsa_server_set_password(server,
-                                gtk_entry_get_text(GTK_ENTRY
-                                                   (mcw->mb_data.imap.password)));
-    libbalsa_imap_server_enable_persistent_cache
-        (LIBBALSA_IMAP_SERVER(server),
-         gtk_toggle_button_get_active
-         GTK_TOGGLE_BUTTON(mcw->mb_data.imap.enable_persistent));
-    libbalsa_imap_server_set_bug
-        (LIBBALSA_IMAP_SERVER(server), ISBUG_FETCH,
-         gtk_toggle_button_get_active
-         GTK_TOGGLE_BUTTON(mcw->mb_data.imap.has_bugs));
-    /* Set host after all other server changes, as it triggers
-     * save-to-config for any folder or mailbox using this server. */
-    libbalsa_server_set_host(server,
-                            gtk_entry_get_text(GTK_ENTRY
-                                               (mcw->mb_data.imap.bsc.server)),
-                                               server->security);
-    libbalsa_server_config_changed(server);
-    g_signal_connect(G_OBJECT(server), "get-password",
-                     G_CALLBACK(ask_password), mailbox);
-
-    libbalsa_mailbox_imap_set_path(mailbox,
-                                  (path == NULL || path[0] == '\0') 
-                                  ? "INBOX" : path);
-    g_free(path);
-}
-
 /* conf_update_mailbox:
    if changing path of the local mailbox in the local mail directory, just 
    rename the file, don't insert it to the configuration.
@@ -959,8 +596,8 @@ mailbox_conf_update(MailboxConfWindow *mcw)
             g_free(path_dir);
        }
 
-        name = mcw->mailbox_name ?
-            gtk_editable_get_chars(GTK_EDITABLE(mcw->mailbox_name), 0, -1)
+        name = mcw->mb_data.local.mailbox_name ?
+            gtk_editable_get_chars(GTK_EDITABLE(mcw->mb_data.local.mailbox_name), 0, -1)
             : g_path_get_basename(filename);
        if (strcmp(name, mailbox->name)) {
            /* Change name. */
@@ -975,10 +612,8 @@ mailbox_conf_update(MailboxConfWindow *mcw)
        g_free(path);
     } else if (LIBBALSA_IS_MAILBOX_POP3(mailbox)) {
        update_pop_mailbox(mcw);
-    } else if (LIBBALSA_IS_MAILBOX_IMAP(mailbox)) {
-       update_imap_mailbox(mcw);
-        /* update_imap_mailbox saved the config so we do not need to here: */
-       return;
+    } else {
+       g_assert_not_reached();
     }
 
     if (mailbox->config_prefix)
@@ -998,7 +633,6 @@ mailbox_conf_add(MailboxConfWindow * mcw)
     BalsaMailboxNode *mbnode;
     gboolean save_to_config = TRUE;
 
-    mcw->mailbox = g_object_new(mcw->mailbox_type, NULL);
     mailbox_conf_view_check(mcw->view_info, mcw->mailbox);
 
     if ( LIBBALSA_IS_MAILBOX_LOCAL(mcw->mailbox) ) {
@@ -1018,7 +652,7 @@ mailbox_conf_add(MailboxConfWindow * mcw)
        save_to_config =
             !libbalsa_path_is_below_dir(path,
                                         balsa_app.local_mail_directory);
-        printf("Save to config: %d\n", save_to_config);
+        g_debug("Save to config: %d", save_to_config);
        mcw->mailbox->name = g_path_get_basename(path);
         g_free(path);
 
@@ -1031,9 +665,7 @@ mailbox_conf_add(MailboxConfWindow * mcw)
        balsa_app.inbox_input =
            g_list_append(balsa_app.inbox_input, mbnode);
     } else if ( LIBBALSA_IS_MAILBOX_IMAP(mcw->mailbox) ) {
-       update_imap_mailbox(mcw);
-       balsa_mblist_mailbox_node_append(NULL, mbnode);
-       update_mail_servers();
+       g_assert_not_reached();
     } else if ( !LIBBALSA_IS_MAILBOX_LOCAL(mcw->mailbox) ) {
        g_assert_not_reached();
     }
@@ -1050,15 +682,14 @@ mailbox_conf_add(MailboxConfWindow * mcw)
 static GtkWidget *
 create_dialog(MailboxConfWindow *mcw)
 {
-    if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_LOCAL) ) {
-       return create_local_mailbox_dialog(mcw);
-    } else if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3) ) {
-       return create_pop_mailbox_dialog(mcw);
-    } else {
-       g_warning("Unknown mailbox type: %s\n",
-                  g_type_name(mcw->mailbox_type));
-       return NULL;
-    }
+       if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_LOCAL)) {
+               return create_local_mailbox_dialog(mcw);
+       } else if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3)) {
+               return create_pop_mailbox_dialog(mcw);
+       } else {
+               g_warning("Unknown mailbox type: %s\n", g_type_name(mcw->mailbox_type));
+               return NULL;
+       }
 }
 
 static void
@@ -1081,22 +712,20 @@ balsa_get_entry(GtkWidget * widget, GtkWidget ** entry)
  * so we don't change button sensitivity.
  */
 static void
-local_mailbox_dialog_cb(GtkWidget * widget, MailboxConfWindow * mcw)
+local_mailbox_dialog_cb(GtkWidget         *widget,
+                                               MailboxConfWindow *mcw)
 {
-    gchar *filename =
-        gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(mcw->window));
+    gchar *filename = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER(mcw->window));
 
-    if (filename) {
+    if (filename != NULL) {
         gboolean changed = TRUE;
-        if (mcw->mailbox) {
-            LibBalsaMailboxLocal *local =
-                LIBBALSA_MAILBOX_LOCAL(mcw->mailbox);
-            const gchar *path = libbalsa_mailbox_local_get_path(local);
-            changed = strcmp(filename, path);
+        if (mcw->mailbox != NULL) {
+            changed = (g_strcmp0(filename, mcw->mailbox->url) != 0);
         }
         g_free(filename);
-        if (changed)
+        if (changed) {
             check_for_blank_fields(widget, mcw);
+        }
     }
 }
 
@@ -1105,7 +734,6 @@ create_local_mailbox_dialog(MailboxConfWindow *mcw)
 {
     GtkWidget *dialog;
     GtkWidget *grid;
-    GtkWidget *label = NULL;
     gint row = -1;
     GtkFileChooserAction action;
     GtkWidget *entry = NULL;
@@ -1115,15 +743,6 @@ create_local_mailbox_dialog(MailboxConfWindow *mcw)
 
     grid = libbalsa_create_grid();
 
-    /* mailbox name */
-    if(mcw->mailbox && mcw->mailbox->config_prefix) {
-        label = libbalsa_create_grid_label(_("_Mailbox Name:"), grid, ++row);
-        mcw->mailbox_name =
-            libbalsa_create_grid_entry(grid,
-                                       G_CALLBACK(check_for_blank_fields),
-                                       mcw, row, NULL, label);
-    } else mcw->mailbox_name = NULL;
-
     type = g_type_name(mcw->mailbox_type) + 15;
     title = g_strdup_printf(mcw->mailbox ?
                             _("Local %s Mailbox Properties") :
@@ -1131,7 +750,7 @@ create_local_mailbox_dialog(MailboxConfWindow *mcw)
 
     action = mcw->mailbox_type == LIBBALSA_TYPE_MAILBOX_MBOX ?
         GTK_FILE_CHOOSER_ACTION_SAVE :
-        GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
+               GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
     dialog =
         gtk_file_chooser_dialog_new(title,
                                     GTK_WINDOW(balsa_app.main_window),
@@ -1144,15 +763,37 @@ create_local_mailbox_dialog(MailboxConfWindow *mcw)
     libbalsa_macosx_menu_for_parent(dialog, GTK_WINDOW(balsa_app.main_window));
 #endif
 
-    size_group = libbalsa_create_size_group(dialog);
-    if (label)
-        gtk_size_group_add_widget(size_group, label);
-
     gtk_file_chooser_set_extra_widget(GTK_FILE_CHOOSER(dialog), grid);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog),
-                                       balsa_app.local_mail_directory);
+    if (mcw->mailbox->url != NULL) {
+               const gchar *path = libbalsa_mailbox_local_get_path(LIBBALSA_MAILBOX_LOCAL(mcw->mailbox));
+               gchar *basename = g_path_get_basename(path);
+
+               g_message("'%s' -> '%s' '%s'", mcw->mailbox->url, path, basename);
+               //gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), path);
+               //gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), basename);
+               gtk_file_chooser_set_uri(GTK_FILE_CHOOSER(dialog), mcw->mailbox->url);
+               g_free(basename);
+               // FIXME - not optimal
+    } else {
+        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), balsa_app.local_mail_directory);
+    }
     g_signal_connect(G_OBJECT(dialog), "selection-changed",
                      G_CALLBACK(local_mailbox_dialog_cb), mcw);
+
+    size_group = libbalsa_create_size_group(dialog);
+    if (mcw->mailbox->config_prefix) {
+        GtkWidget *label;
+
+        label = libbalsa_create_grid_label(_("_Mailbox Name:"), grid, ++row);
+        mcw->mb_data.local.mailbox_name =
+            libbalsa_create_grid_entry(grid,
+                                       G_CALLBACK(check_for_blank_fields),
+                                       mcw, row, mcw->mailbox->name, label);
+        gtk_size_group_add_widget(size_group, label);
+    } else {
+       mcw->mb_data.local.mailbox_name = NULL;
+    }
+
     balsa_get_entry(dialog, &entry);
     if (entry)
        g_signal_connect(G_OBJECT(entry), "changed",
@@ -1166,113 +807,51 @@ create_local_mailbox_dialog(MailboxConfWindow *mcw)
 }
 
 static GtkWidget *
-create_generic_dialog(MailboxConfWindow * mcw)
+create_pop_mailbox_dialog(MailboxConfWindow *mcw)
 {
-    GtkWidget *dialog =
-        gtk_dialog_new_with_buttons(_("Remote Mailbox Configurator"),
-                                    GTK_WINDOW(balsa_app.main_window),
-                                    GTK_DIALOG_DESTROY_WITH_PARENT |
-                                    libbalsa_dialog_flags(),
-                                    mcw->ok_button_name, MCW_RESPONSE,
-                                    _("_Cancel"), GTK_RESPONSE_CANCEL,
-                                    NULL);
+       LibBalsaMailbox *mailbox = mcw->mailbox;
+    LibBalsaMailboxPop3 *pop3 = LIBBALSA_MAILBOX_POP3(mailbox);
+
+       mcw->window = GTK_DIALOG(gtk_dialog_new_with_buttons(_("Remote Mailbox Configurator"),
+        GTK_WINDOW(balsa_app.main_window),
+               GTK_DIALOG_DESTROY_WITH_PARENT | libbalsa_dialog_flags(),
+        mcw->ok_button_name, MCW_RESPONSE,
+               _("_Cancel"), GTK_RESPONSE_CANCEL,
+        NULL));
 #if HAVE_MACOSX_DESKTOP
-    libbalsa_macosx_menu_for_parent(dialog, GTK_WINDOW(balsa_app.main_window));
+    libbalsa_macosx_menu_for_parent(mcw->window, GTK_WINDOW(balsa_app.main_window));
 #endif
-    return dialog;
-}
-
-static GtkWidget *
-create_security_entry(GtkWidget *grid, gint *row, MailboxConfWindow *mcw)
-{
-    GtkWidget *label;
-    GtkWidget *security;
 
-    label = libbalsa_create_grid_label(_("Se_curity:"), grid, *row);
-    security = gtk_combo_box_text_new();
-    gtk_widget_set_hexpand(security, TRUE);
-    if (g_type_is_a(mcw->mailbox_type, LIBBALSA_TYPE_MAILBOX_POP3)) {
-       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(security), _("POP3 over SSL (POP3S)"));
-    } else {
-       gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(security), _("IMAP over SSL (IMAPS)"));
-    }
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(security), _("TLS required"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(security), _("TLS if possible (not recommended)"));
-    gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(security), _("None (not recommended)"));
-    gtk_grid_attach(GTK_GRID(grid), security, 1, (*row)++, 1, 1);
-    g_signal_connect(security, "changed", G_CALLBACK(security_changed), mcw);
-    gtk_label_set_mnemonic_widget(GTK_LABEL(label), security);
-    return security;
-}
-
-static GtkWidget *
-create_pop_mailbox_dialog(MailboxConfWindow *mcw)
-{
-    GtkWidget *dialog;
-    GtkWidget *notebook, *grid, *label, *advanced;
-    gint row;
-
-    notebook = gtk_notebook_new();
-    grid = libbalsa_create_grid();
-    gtk_container_set_border_width(GTK_CONTAINER(grid), 12);
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), grid,
-                             gtk_label_new_with_mnemonic(_("_Basic")));
-    row = 0;
-
-    /* mailbox name */
-    label = libbalsa_create_grid_label(_("Mailbox _name:"), grid, row);
-    mcw->mailbox_name = libbalsa_create_grid_entry(grid, G_CALLBACK(check_for_blank_fields), mcw, row++, 
NULL, label);
-    /* pop server */
-    label = libbalsa_create_grid_label(_("_Server:"), grid, row);
-    mcw->mb_data.pop3.bsc.server =
-       libbalsa_create_grid_entry(grid, G_CALLBACK(check_for_blank_fields), mcw, row++, "localhost", label);
-
-    /* security */
-    mcw->mb_data.pop3.bsc.security = create_security_entry(grid, &row, mcw);
-
-    /* username  */
-    label= libbalsa_create_grid_label(_("Use_r name:"), grid, row);
-    mcw->mb_data.pop3.username =
-       libbalsa_create_grid_entry(grid, G_CALLBACK(check_for_blank_fields), mcw, row++, g_get_user_name(), 
label);
-
-    /* password field */
-    label = libbalsa_create_grid_label(_("Pass_word:"), grid, row);
-    mcw->mb_data.pop3.password = libbalsa_create_grid_entry(grid, NULL, NULL, row++, NULL, label);
-    gtk_entry_set_visibility(GTK_ENTRY(mcw->mb_data.pop3.password), FALSE);
+    mcw->mb_data.pop3.server_cfg = libbalsa_server_cfg_new(LIBBALSA_MAILBOX_REMOTE_SERVER(mailbox), 
mailbox->name);
+    gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(mcw->window))), 
GTK_WIDGET(mcw->mb_data.pop3.server_cfg));
+    g_signal_connect(mcw->mb_data.pop3.server_cfg, "changed", G_CALLBACK(check_for_blank_fields), mcw);
 
     /* toggle for deletion from server */
-    mcw->mb_data.pop3.delete_from_server =
-       libbalsa_create_grid_check(_("_Delete messages from server after download"), grid, row++, TRUE);
+    mcw->mb_data.pop3.delete_from_server = libbalsa_server_cfg_add_check(mcw->mb_data.pop3.server_cfg, TRUE,
+       _("_Delete messages from server after download"), pop3->delete_from_server, NULL, NULL);
 
     /* toggle for check */
-    mcw->mb_data.pop3.check =
-       libbalsa_create_grid_check(_("_Enable check for new mail"), grid, row++, TRUE);
+    mcw->mb_data.pop3.check = libbalsa_server_cfg_add_check(mcw->mb_data.pop3.server_cfg, TRUE, _("_Enable 
check for new mail"),
+       pop3->check, NULL, NULL);
 
     /* Procmail */
-    mcw->mb_data.pop3.filter =
-       libbalsa_create_grid_check(_("_Filter messages through procmail"), grid, row++, FALSE);
-    g_signal_connect(G_OBJECT(mcw->mb_data.pop3.filter), "toggled", G_CALLBACK(pop3_enable_filter_cb), mcw);
-    label = libbalsa_create_grid_label(_("Fi_lter Command:"), grid, row);
-    mcw->mb_data.pop3.filter_cmd =
-       libbalsa_create_grid_entry(grid, G_CALLBACK(check_for_blank_fields), mcw, row++, "procmail -f -", 
label);
-
-    advanced = balsa_server_conf_get_advanced_widget(&mcw->mb_data.pop3.bsc);
-    gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advanced, gtk_label_new_with_mnemonic(_("_Advanced")));
-       g_signal_connect(mcw->mb_data.pop3.bsc.need_client_cert, "toggled", G_CALLBACK(client_cert_changed), 
mcw);
-       g_signal_connect(mcw->mb_data.pop3.bsc.client_cert_file, "file-set", 
G_CALLBACK(check_for_blank_fields), mcw);
-
-    /* toggle for apop */
-    mcw->mb_data.pop3.disable_apop = balsa_server_conf_add_checkbox(&mcw->mb_data.pop3.bsc, _("Disable 
_APOP"));
+    mcw->mb_data.pop3.filter = libbalsa_server_cfg_add_check(mcw->mb_data.pop3.server_cfg, TRUE,
+       _("_Filter messages through procmail"), pop3->filter, G_CALLBACK(check_for_blank_fields), mcw);
+    mcw->mb_data.pop3.filter_cmd = libbalsa_server_cfg_add_entry(mcw->mb_data.pop3.server_cfg, TRUE, 
_("Fi_lter Command:"),
+       pop3->filter_cmd, G_CALLBACK(check_for_blank_fields), mcw);
+
+    /* advanced - toggle for apop */
+    mcw->mb_data.pop3.disable_apop = libbalsa_server_cfg_add_check(mcw->mb_data.pop3.server_cfg, FALSE, 
_("Disable _APOP"),
+       pop3->disable_apop, NULL, NULL);
+
     /* toggle for enabling pipeling */
-    mcw->mb_data.pop3.enable_pipe = balsa_server_conf_add_checkbox(&mcw->mb_data.pop3.bsc, _("Overlap 
commands"));
+    mcw->mb_data.pop3.enable_pipe = libbalsa_server_cfg_add_check(mcw->mb_data.pop3.server_cfg, FALSE, 
_("Overlap commands"),
+       pop3->enable_pipe, NULL, NULL);
 
-    gtk_widget_show_all(notebook);
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
-    gtk_widget_grab_focus(mcw->mailbox_name);
+    /* initially call the check */
+    check_for_blank_fields(NULL, mcw);
 
-    dialog = create_generic_dialog(mcw);
-    gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook);
-    return dialog;
+    return GTK_WIDGET(mcw->window);
 }
 
 /* Manage the widgets that control aspects of the view, not the config.
@@ -1326,7 +905,6 @@ mailbox_conf_view_new_full(LibBalsaMailbox * mailbox,
     view_info = g_new(BalsaMailboxConfView, 1);
     g_object_weak_ref(G_OBJECT(window), (GWeakNotify) g_free, view_info);
     view_info->mailbox = mailbox;
-    view_info->window = window;
 
     label = libbalsa_create_grid_label(_("_Identity:"), grid, row);
     if (size_group)
@@ -1348,12 +926,6 @@ mailbox_conf_view_new_full(LibBalsaMailbox * mailbox,
 #ifdef HAVE_GPGME
     {
        /* scope */
-       static const struct menu_data chk_crypt_menu[] = {
-           { N_("Never"),       LB_MAILBOX_CHK_CRYPT_NEVER  },
-           { N_("If Possible"), LB_MAILBOX_CHK_CRYPT_MAYBE  },
-           { N_("Always"),      LB_MAILBOX_CHK_CRYPT_ALWAYS }
-       };
-
         label =
             libbalsa_create_grid_label(_("_Decrypt and check\n"
                                          "signatures automatically:"),
@@ -1363,12 +935,11 @@ mailbox_conf_view_new_full(LibBalsaMailbox * mailbox,
 
         view_info->chk_crypt = gtk_combo_box_text_new();
         gtk_label_set_mnemonic_widget(GTK_LABEL(label), view_info->chk_crypt);
-        mailbox_conf_combo_box_make(GTK_COMBO_BOX_TEXT(view_info->chk_crypt),
-                                    ELEMENTS(chk_crypt_menu),
-                                    chk_crypt_menu);
+        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(view_info->chk_crypt), _("Never"));
+        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(view_info->chk_crypt), _("If Possible"));
+        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(view_info->chk_crypt), _("Always"));
         gtk_combo_box_set_active(GTK_COMBO_BOX(view_info->chk_crypt),
-                                 libbalsa_mailbox_get_crypto_mode
-                                 (mailbox));
+                                 libbalsa_mailbox_get_crypto_mode(mailbox));
         if (mcw)
             g_signal_connect(view_info->chk_crypt, "changed",
                              G_CALLBACK(check_for_blank_fields), mcw);
@@ -1452,21 +1023,6 @@ mailbox_conf_view_new(LibBalsaMailbox * mailbox,
                                       NULL, NULL, callback);
 }
 
-#ifdef HAVE_GPGME
-static LibBalsaChkCryptoMode
-balsa_mailbox_conf_get_crypto_mode(BalsaMailboxConfView *view_info)
-{
-    struct mailbox_conf_combo_box_info *info =
-        g_object_get_data(G_OBJECT(view_info->chk_crypt),
-                          BALSA_MC_COMBO_BOX_INFO);
-    gint active =
-        gtk_combo_box_get_active(GTK_COMBO_BOX(view_info->chk_crypt));
-
-    return (LibBalsaChkCryptoMode)
-        GPOINTER_TO_INT(g_slist_nth_data(info->tags, active));
-}
-#endif
-
 /* When closing the dialog, check whether any view items were changed,
  * and carry out the changes if necessary.
  *
@@ -1533,7 +1089,7 @@ mailbox_conf_view_check(BalsaMailboxConfView * view_info,
 
 #ifdef HAVE_GPGME
     if (libbalsa_mailbox_set_crypto_mode(mailbox,
-                                        balsa_mailbox_conf_get_crypto_mode(view_info)))
+                                        gtk_combo_box_get_active(GTK_COMBO_BOX(view_info->chk_crypt))))
        changed = TRUE;
 #endif
 
diff --git a/src/mailbox-conf.h b/src/mailbox-conf.h
index d10aab0d8..756fd043e 100644
--- a/src/mailbox-conf.h
+++ b/src/mailbox-conf.h
@@ -21,7 +21,6 @@
 #define __MAILBOX_CONF_H__
 
 #include "mailbox-node.h"
-
 #include "server.h"
 
 typedef struct _BalsaMailboxConfView BalsaMailboxConfView;
@@ -45,27 +44,4 @@ BalsaMailboxConfView *mailbox_conf_view_new(LibBalsaMailbox * mailbox,
 void mailbox_conf_view_check(BalsaMailboxConfView * mcc,
                              LibBalsaMailbox * mailbox);
 
-
-typedef struct {
-    GtkWidget *security;
-    GtkGrid   *grid;       /* internal */
-    GtkWidget *server;     /* internal */
-    GtkWidget *need_client_cert;
-    GtkWidget *client_cert_file;
-    GtkWidget *client_cert_passwd;
-    unsigned   used_rows;  /* internal */
-} BalsaServerConf;
-
-
-GtkWidget*      balsa_server_conf_get_advanced_widget(BalsaServerConf *bsc);
-GtkWidget*      balsa_server_conf_add_checkbox(BalsaServerConf *bsc,
-                                               const char *label);
-GtkWidget*      balsa_server_conf_add_spinner(BalsaServerConf *bsc,
-                                              const char *label,
-                                              gint lo, gint hi, gint step,
-                                              gint initial_value);
-void            balsa_server_conf_set_values(BalsaServerConf *bsc,
-                                             LibBalsaServer *server);
-NetClientCryptMode balsa_server_conf_get_security(BalsaServerConf *bsc);
-
 #endif                         /* __MAILBOX_CONF_H__ */
diff --git a/src/mailbox-node.c b/src/mailbox-node.c
index a57ce2d8e..8285a91e2 100644
--- a/src/mailbox-node.c
+++ b/src/mailbox-node.c
@@ -269,7 +269,7 @@ balsa_mailbox_node_real_save_config(BalsaMailboxNode* mn, const gchar * group)
     g_return_if_fail(!mn->parent);
 
     if(mn->name)
-       printf("Saving mailbox node %s with group %s\n", mn->name, group);
+       g_debug("Saving mailbox node %s with group %s", mn->name, group);
     libbalsa_imap_server_save_config(LIBBALSA_IMAP_SERVER(mn->server));
     libbalsa_conf_set_string("Name",      mn->name);
     libbalsa_conf_set_string("Directory", mn->dir);
@@ -282,7 +282,7 @@ balsa_mailbox_node_real_save_config(BalsaMailboxNode* mn, const gchar * group)
         children_names = g_ptr_array_new();
         balsa_mailboxes_append_children(model, &iter,
                                         children_names);
-        printf("Saving %d children\n", children_names->len);
+        g_debug("Saving %d children", children_names->len);
         libbalsa_conf_set_vector("Children", children_names->len,
                                  (const char*const*)(children_names->pdata));
         g_ptr_array_foreach(children_names, (GFunc)g_free, NULL);
@@ -366,9 +366,7 @@ check_local_path(const gchar * path, guint depth)
     libbalsa_conf_foreach_group(VIEW_BY_URL_SECTION_PREFIX,
                                 (LibBalsaConfForeachFunc) check_url_func,
                                 &cpi);
-    if(balsa_app.debug) 
-       printf("check_local_path: path “%s” must_scan %d.\n",
-               cpi.url, cpi.must_scan);
+    g_debug("check_local_path: path “%s” must_scan %d.", cpi.url, cpi.must_scan);
     g_free(cpi.url);
 
     return cpi.must_scan;
@@ -429,9 +427,7 @@ imap_scan_attach_mailbox(BalsaMailboxNode * mbnode, imap_scan_item * isi)
     libbalsa_mailbox_remote_set_server(LIBBALSA_MAILBOX_REMOTE(m),
                                       mbnode->server);
     libbalsa_mailbox_imap_set_path(m, isi->fn);
-    if(balsa_app.debug)
-        printf("imap_scan_attach_mailbox: add mbox of name %s "
-              "(full path %s)\n", isi->fn, mailbox->url);
+    g_debug("imap_scan_attach_mailbox: add mbox of name %s (full path %s)", isi->fn, mailbox->url);
     /* avoid allocating the name again: */
     mailbox->name = mbnode->name;
     mbnode->name = NULL;
@@ -541,10 +537,10 @@ imap_dir_cb(BalsaMailboxNode* mb)
     }
     imap_scan_destroy_tree(&imap_tree);
 
-    if(balsa_app.debug && mb->name)
-        printf("imap_dir_cb:  main mailbox node %s mailbox is %p\n", 
-               mb->name, mb->mailbox);
-    if(balsa_app.debug) printf("%d: Scanning done.\n", (int)time(NULL));
+    if (mb->name) {
+       g_debug("imap_dir_cb: main mailbox node %s mailbox is %p", mb->name, mb->mailbox);
+    }
+    g_debug("%d: Scanning done.", (int)time(NULL));
     gtk_statusbar_pop(statusbar, context_id);
 
     /* We can save the cache now... */
@@ -781,8 +777,9 @@ restore_children_from_cache(BalsaMailboxNode *mn)
     imap_scan_item isi;
 
     if(!children) {
-        if(mn->name)
-            printf("No cache for %s - quitting.\n", mn->name);
+        if (mn->name) {
+               g_debug("No cache for %s - quitting.", mn->name);
+        }
         return FALSE;
     }
 
@@ -1226,7 +1223,7 @@ add_local_mailbox(BalsaMailboxNode *root, const gchar * name,
            mailbox = NULL;
        }
        if(!mailbox) {/* local mailbox could not be created; privileges? */
-           printf("Not accessible mailbox %s\n", path);
+               g_warning("Not accessible mailbox %s", path);
            return NULL;
        }
        mailbox->name = g_strdup(name);
@@ -1395,10 +1392,8 @@ handle_imap_path(const char *fn, char delim, int noselect, int noscan,
            /* ignore mailboxes that begin with a dot */
            return;
     }
-    if (balsa_app.debug)
-       printf("handle_imap_path: Adding mailbox of path “%s” "
-              "delim `%c' noselect %d noscan %d\n",
-              fn, delim, noselect, noscan);
+    g_debug("handle_imap_path: Adding mailbox of path “%s” delim `%c' noselect %d noscan %d",
+       fn, delim, noselect, noscan);
     add_imap_entry(fn, delim, noscan, !noselect, marked, data);
 }
 
@@ -1425,9 +1420,7 @@ check_imap_path(const gchar *fn, LibBalsaServer * server, guint depth)
     libbalsa_conf_foreach_group(VIEW_BY_URL_SECTION_PREFIX,
                                 (LibBalsaConfForeachFunc) check_url_func,
                                 &cpi);
-    if(balsa_app.debug) 
-       printf("check_imap_path: path “%s” must_scan %d.\n",
-               cpi.url, cpi.must_scan);
+    g_debug("check_imap_path: path “%s” must_scan %d.", cpi.url, cpi.must_scan);
     g_free(cpi.url);
 
     return cpi.must_scan;
@@ -1443,8 +1436,7 @@ mark_imap_path(const gchar * fn, gpointer data)
     imap_scan_tree *tree = data;
     GSList *list;
 
-    if(balsa_app.debug) 
-       printf("mark_imap_path: find path “%s”.\n", fn);
+    g_debug("mark_imap_path: find path “%s”.", fn);
     for (list = tree->list; list; list = list->next) {
         imap_scan_item *item = list->data;
         if (!strcmp(item->fn, fn)) {
@@ -1452,6 +1444,7 @@ mark_imap_path(const gchar * fn, gpointer data)
             break;
         }
     }
-    if (!list && balsa_app.debug)
-       printf(" not found.\n");
+    if (!list) {
+       g_debug("… not found.");
+    }
 }
diff --git a/src/save-restore.c b/src/save-restore.c
index 2ced86d84..97cc21e37 100644
--- a/src/save-restore.c
+++ b/src/save-restore.c
@@ -961,21 +961,17 @@ config_global_load(void)
        libbalsa_server_set_username(server,
                libbalsa_conf_get_string("ESMTPUser"));
 
-        passphrase = libbalsa_conf_private_get_string("ESMTPPassphrase");
+        passphrase = libbalsa_conf_private_get_string("ESMTPPassphrase", TRUE);
        if (passphrase) {
-            gchar* passphrase_rot = libbalsa_rot(passphrase);
-            g_free(passphrase); 
-            libbalsa_server_set_password(server, passphrase_rot);
-           g_free(passphrase_rot);
+            libbalsa_server_set_password(server, passphrase);
+           g_free(passphrase);
         }
 
        passphrase =
-           libbalsa_conf_private_get_string("ESMTPCertificatePassphrase");
+           libbalsa_conf_private_get_string("ESMTPCertificatePassphrase", TRUE);
        if (passphrase) {
-            gchar* passphrase_rot = libbalsa_rot(passphrase);
-            g_free(passphrase);
            g_free(server->cert_passphrase);
-           server->cert_passphrase = passphrase_rot;
+           server->cert_passphrase = passphrase;
        }
     }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]