Fix bug 3793: segfault when autocompletion asks for master passphrase
authorAndrej Kacian <ticho@claws-mail.org>
Sun, 10 Dec 2017 09:49:01 +0000 (10:49 +0100)
committerRicardo Mones <ricardo@mones.org>
Sun, 10 Dec 2017 17:13:28 +0000 (18:13 +0100)
This is done by checking early if any ldap server is password-protected,
and asking for master passphrase when compose window appears.  If user
cancels the dialog (does not enter the passphrase), we temporarily
disable the password-protected LDAP servers, just for that particular
compose window. We reenable them in compose_destroy().

src/addrindex.c
src/addrindex.h
src/compose.c
src/compose.h

index d11e210..282281f 100644 (file)
@@ -3200,6 +3200,52 @@ gchar *addrindex_get_picture_file(const gchar *emailaddr)
        return filename;
 }
 
+#ifdef USE_LDAP
+GSList *addrindex_get_password_protected_ldap_servers()
+{
+       AddressInterface *iface;
+       AddressDataSource *ds;
+       GList *nodeIf;
+       GList *nodeDS;
+       GSList *list = NULL;
+       LdapServer *server;
+       LdapControl *ctl;
+
+       nodeIf = _addressIndex_->searchOrder;
+       while (nodeIf) {
+               iface = nodeIf->data;
+               nodeIf = g_list_next(nodeIf);
+
+               if (!iface->useInterface)
+                       continue;
+               if (!iface->externalQuery)
+                       continue;
+               if (iface->type != ADDR_IF_LDAP)
+                       continue;
+
+               nodeDS = iface->listSource;
+               while (nodeDS) {
+                       ds = nodeDS->data;
+                       nodeDS = g_list_next(nodeDS);
+                       server = ds->rawDataSource;
+                       if (!server->searchFlag)
+                               continue;
+
+                       ctl = server->control;
+
+                       if (!ctl)
+                               continue;
+
+                       if (ctl->bindDN != NULL && strlen(ctl->bindDN)) {
+                               list = g_slist_append(list, server);
+                       }
+               }
+       }
+
+       return list;
+}
+#endif /* USE_LDAP */
+
 /*
  * End of Source.
  */
index b5b9e9a..2db902a 100644 (file)
@@ -180,6 +180,11 @@ gboolean addrindex_load_person_attribute( const gchar *attr,
 gboolean addrindex_load_person_ds( gint (*callBackFunc)
                        ( ItemPerson *, AddressDataSource * ) );
 gchar *addrindex_get_picture_file(const gchar *emailaddr);             
+
+#ifdef USE_LDAP
+GSList *addrindex_get_password_protected_ldap_servers();
+#endif
+
 #endif /* __ADDRINDEX_H__ */
 
 /*
index e60d178..e52f467 100644 (file)
 #include "autofaces.h"
 #include "spell_entry.h"
 #include "headers.h"
+#ifdef USE_LDAP
+#include "password.h"
+#include "ldapserver.h"
+#endif
 
 enum
 {
@@ -7091,6 +7095,15 @@ extra_headers_done:
        g_slist_foreach(extra_headers, (GFunc)compose_add_extra_header, (gpointer)model);
 }
 
+static void _ldap_srv_func(gpointer data, gpointer user_data)
+{
+       LdapServer *server = (LdapServer *)data;
+       gboolean *enable = (gboolean *)user_data;
+
+       debug_print("%s server '%s'\n", (*enable == TRUE ? "enabling" : "disabling"), server->control->hostName);
+       server->searchFlag = *enable;
+}
+
 static void compose_create_header_entry(Compose *compose) 
 {
        gchar *headers[] = {"To:", "Cc:", "Bcc:", "Newsgroups:", "Reply-To:", "Followup-To:", NULL};
@@ -7229,7 +7242,22 @@ static void compose_create_header_entry(Compose *compose)
        g_signal_connect(G_OBJECT(entry), "populate-popup",
                         G_CALLBACK(compose_entry_popup_extend),
                         NULL);
-       
+
+#ifdef USE_LDAP
+       GSList *pwd_servers = addrindex_get_password_protected_ldap_servers();
+       if (pwd_servers != NULL && master_passphrase() == NULL) {
+               gboolean enable = FALSE;
+               debug_print("Master passphrase not available, disabling password-protected LDAP servers for this compose window.\n");
+               /* Temporarily disable password-protected LDAP servers,
+                * because user did not provide a master passphrase.
+                * We can safely enable searchFlag on all servers in this list
+                * later, since addrindex_get_password_protected_ldap_servers()
+                * includes servers which have it enabled initially. */
+               g_slist_foreach(pwd_servers, _ldap_srv_func, &enable);
+               compose->passworded_ldap_servers = pwd_servers;
+       }
+#endif
+
        address_completion_register_entry(GTK_ENTRY(entry), TRUE);
 
         headerentry->compose = compose;
@@ -9070,6 +9098,11 @@ static void compose_destroy(Compose *compose)
 
        compose_list = g_list_remove(compose_list, compose);
 
+       gboolean enable = TRUE;
+       g_slist_foreach(compose->passworded_ldap_servers,
+                       _ldap_srv_func, &enable);
+       g_slist_free(compose->passworded_ldap_servers);
+
        if (compose->updating) {
                debug_print("danger, not destroying anything now\n");
                compose->deferred_destroy = TRUE;
index 5fe65a3..fee1956 100644 (file)
@@ -252,6 +252,12 @@ struct _Compose
         GtkAspell *gtkaspell;
        GtkWidget *aspell_options_menu;
 #endif
+
+#ifdef USE_LDAP
+       /* List of addressbook ifaces which we disabled, and will
+        * enable in compose_destroy. */
+       GSList *passworded_ldap_servers;
+#endif
 };
 
 struct _AttachInfo