From 9dc1fda2316904b96281b908c51aad2908fb4bae Mon Sep 17 00:00:00 2001 From: Colin Leroy Date: Fri, 28 Sep 2007 15:17:56 +0000 Subject: [PATCH] 2007-09-28 [colin] 3.0.1cvs39 * src/plugins/spamassassin/spamassassin.c * src/plugins/spamassassin/spamassassin.h * src/plugins/spamassassin/spamassassin_gtk.c Add addressbook-based whitelisting --- ChangeLog | 7 ++ PATCHSETS | 1 + configure.ac | 2 +- src/plugins/spamassassin/spamassassin.c | 56 +++++++++++++++ src/plugins/spamassassin/spamassassin.h | 2 + src/plugins/spamassassin/spamassassin_gtk.c | 77 ++++++++++++++++++++- 6 files changed, 143 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2f3453e8..6f74b4f12 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-09-28 [colin] 3.0.1cvs39 + + * src/plugins/spamassassin/spamassassin.c + * src/plugins/spamassassin/spamassassin.h + * src/plugins/spamassassin/spamassassin_gtk.c + Add addressbook-based whitelisting + 2007-09-28 [colin] 3.0.1cvs38 * src/folder.c diff --git a/PATCHSETS b/PATCHSETS index e0f3e6665..f0acd6813 100644 --- a/PATCHSETS +++ b/PATCHSETS @@ -2902,3 +2902,4 @@ ( cvs diff -u -r 1.1.2.11 -r 1.1.2.12 src/prefs_folder_column.c; cvs diff -u -r 1.10.2.20 -r 1.10.2.21 src/prefs_summary_column.c; ) > 3.0.1cvs36.patchset ( cvs diff -u -r 1.52.2.51 -r 1.52.2.52 src/prefs_folder_item.c; ) > 3.0.1cvs37.patchset ( cvs diff -u -r 1.213.2.163 -r 1.213.2.164 src/folder.c; ) > 3.0.1cvs38.patchset +( cvs diff -u -r 1.18.2.56 -r 1.18.2.57 src/plugins/spamassassin/spamassassin.c; cvs diff -u -r 1.4.2.17 -r 1.4.2.18 src/plugins/spamassassin/spamassassin.h; cvs diff -u -r 1.23.2.41 -r 1.23.2.42 src/plugins/spamassassin/spamassassin_gtk.c; ) > 3.0.1cvs39.patchset diff --git a/configure.ac b/configure.ac index 3e779c0ad..35e81152e 100644 --- a/configure.ac +++ b/configure.ac @@ -11,7 +11,7 @@ MINOR_VERSION=0 MICRO_VERSION=1 INTERFACE_AGE=0 BINARY_AGE=0 -EXTRA_VERSION=38 +EXTRA_VERSION=39 EXTRA_RELEASE= EXTRA_GTK2_VERSION= diff --git a/src/plugins/spamassassin/spamassassin.c b/src/plugins/spamassassin/spamassassin.c index 0bf39e13a..b59106144 100644 --- a/src/plugins/spamassassin/spamassassin.c +++ b/src/plugins/spamassassin/spamassassin.c @@ -49,6 +49,7 @@ #include "log.h" #include "prefs_common.h" #include "alertpanel.h" +#include "addr_compl.h" #ifdef HAVE_SYSEXITS_H #include @@ -110,6 +111,10 @@ static PrefParam param[] = { NULL, NULL, NULL}, {"mark_as_read", "TRUE", &config.mark_as_read, P_BOOL, NULL, NULL, NULL}, + {"whitelist_ab", "FALSE", &config.whitelist_ab, P_BOOL, + NULL, NULL, NULL}, + {"whitelist_ab_folder", N_("Any"), &config.whitelist_ab_folder, P_STRING, + NULL, NULL, NULL}, {NULL, NULL, NULL, P_OTHER, NULL, NULL, NULL} }; @@ -190,6 +195,33 @@ static MsgStatus msg_is_spam(FILE *fp) return is_spam ? MSG_IS_SPAM:MSG_IS_HAM; } +static gboolean sa_found_in_addressbook(const gchar *address) +{ + gchar *addr = NULL; + gboolean found = FALSE; + gint num_addr = 0; + + if (!address) + return FALSE; + + addr = g_strdup(address); + extract_address(addr); + num_addr = complete_address(addr); + if (num_addr > 1) { + /* skip first item (this is the search string itself) */ + int i = 1; + for (; i < num_addr && !found; i++) { + gchar *caddr = get_complete_address(i); + extract_address(caddr); + if (strcasecmp(caddr, addr) == 0) + found = TRUE; + g_free(caddr); + } + } + g_free(addr); + return found; +} + static gboolean mail_filtering_hook(gpointer source, gpointer data) { MailFilteringData *mail_filtering_data = (MailFilteringData *) source; @@ -214,6 +246,30 @@ static gboolean mail_filtering_hook(gpointer source, gpointer data) return FALSE; } + if (config.whitelist_ab) { + gchar *ab_folderpath; + gboolean whitelisted = FALSE; + + if (*config.whitelist_ab_folder == '\0' || + strcasecmp(config.whitelist_ab_folder, _("Any")) == 0) { + /* match the whole addressbook */ + ab_folderpath = NULL; + } else { + /* match the specific book/folder of the addressbook */ + ab_folderpath = config.whitelist_ab_folder; + } + + start_address_completion(ab_folderpath); + if (msginfo->from && + sa_found_in_addressbook(msginfo->from)) + whitelisted = TRUE; + end_address_completion(); + + if (whitelisted) { + debug_print("message is ham (whitelisted)\n"); + return FALSE; + } + } pid = fork(); if (pid == 0) { _exit(msg_is_spam(fp)); diff --git a/src/plugins/spamassassin/spamassassin.h b/src/plugins/spamassassin/spamassassin.h index 5a6e1f681..538e4e4a3 100644 --- a/src/plugins/spamassassin/spamassassin.h +++ b/src/plugins/spamassassin/spamassassin.h @@ -48,6 +48,8 @@ struct _SpamAssassinConfig guint timeout; gchar *username; gboolean mark_as_read; + gboolean whitelist_ab; + gchar *whitelist_ab_folder; }; SpamAssassinConfig *spamassassin_get_config (void); diff --git a/src/plugins/spamassassin/spamassassin_gtk.c b/src/plugins/spamassassin/spamassassin_gtk.c index 7eb671621..bf6abe2ff 100644 --- a/src/plugins/spamassassin/spamassassin_gtk.c +++ b/src/plugins/spamassassin/spamassassin_gtk.c @@ -39,6 +39,7 @@ #include "spamassassin.h" #include "statusbar.h" #include "menu.h" +#include "addressbook.h" struct SpamAssassinPage { @@ -59,10 +60,19 @@ struct SpamAssassinPage GtkWidget *max_size; GtkWidget *timeout; GtkWidget *mark_as_read; + GtkWidget *whitelist_ab; + GtkWidget *whitelist_ab_folder_combo; SpamAssassinTransport trans; }; +/*! + *\brief Preset addressbook book/folder items + */ +static const gchar *whitelist_ab_folder_text [] = { + N_("Any") +}; + struct Transport { gchar *name; @@ -88,6 +98,18 @@ struct Transport transports[] = { { N_("Unix Socket"), SPAMASSASSIN_TRANSPORT_UNIX, PAGE_UNIX, 0 }, }; +static void spamassassin_whitelist_ab_select_cb(GtkWidget *widget, gpointer data) +{ + struct SpamAssassinPage *page = (struct SpamAssassinPage *) data; + gchar *folderpath = NULL; + gboolean ret = FALSE; + + folderpath = (gchar *) gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(page->whitelist_ab_folder_combo)->entry)); + ret = addressbook_folder_selection(&folderpath); + if ( ret != FALSE && folderpath != NULL) + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(page->whitelist_ab_folder_combo)->entry), folderpath); +} + static void foldersel_cb(GtkWidget *widget, gpointer data) { struct SpamAssassinPage *page = (struct SpamAssassinPage *) data; @@ -188,7 +210,11 @@ static void spamassassin_create_widget_func(PrefsPage * _page, GtkWidget *frame_transport, *table_transport, *vbox_transport; GtkWidget *hbox_spamd, *hbox_max_size, *hbox_timeout; GtkWidget *hbox_process_emails, *hbox_save_spam; - GtkWidget *hbox_mark_as_read; + GtkWidget *hbox_mark_as_read, *hbox_whitelist; + GtkWidget *whitelist_ab_checkbtn; + GtkWidget *whitelist_ab_folder_combo; + GtkWidget *whitelist_ab_select_btn; + GList *combo_items; GtkWidget *enable_sa_checkbtn; @@ -400,6 +426,39 @@ static void spamassassin_create_widget_func(PrefsPage * _page, gtk_widget_show(mark_as_read_checkbtn); gtk_box_pack_start(GTK_BOX(hbox_mark_as_read), mark_as_read_checkbtn, TRUE, TRUE, 0); + hbox_whitelist = gtk_hbox_new(FALSE, 8); + gtk_widget_show(hbox_whitelist); + gtk_box_pack_start (GTK_BOX (vbox2), hbox_whitelist, TRUE, TRUE, 0); + + whitelist_ab_checkbtn = gtk_check_button_new_with_label(_("Whitelist senders found in address book/folder")); + gtk_widget_show(whitelist_ab_checkbtn); + gtk_box_pack_start(GTK_BOX(hbox_whitelist), whitelist_ab_checkbtn, FALSE, FALSE, 0); + gtk_tooltips_set_tip(tooltips, whitelist_ab_checkbtn, + _("Messages coming from your address book contacts will be received in the normal folder even if detected as spam"), NULL); + + whitelist_ab_folder_combo = gtk_combo_new(); + gtk_widget_show(whitelist_ab_folder_combo); + gtk_widget_set_size_request(whitelist_ab_folder_combo, 100, -1); + gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(whitelist_ab_folder_combo)->entry), + TRUE); + + combo_items = NULL; + for (i = 0; i < (gint) (sizeof(whitelist_ab_folder_text) / sizeof(gchar *)); i++) { + combo_items = g_list_append(combo_items, + (gpointer) _(whitelist_ab_folder_text[i])); + } + gtk_combo_set_popdown_strings(GTK_COMBO(whitelist_ab_folder_combo), combo_items); + g_list_free(combo_items); + + gtk_box_pack_start (GTK_BOX (hbox_whitelist), whitelist_ab_folder_combo, TRUE, TRUE, 0); + + whitelist_ab_select_btn = gtk_button_new_with_label(_("Select ...")); + gtk_widget_show (whitelist_ab_select_btn); + gtk_box_pack_start (GTK_BOX (hbox_whitelist), whitelist_ab_select_btn, FALSE, FALSE, 0); + gtk_tooltips_set_tip(tooltips, whitelist_ab_select_btn, + _("Click this button to select a book or folder in the address book"), + NULL); + SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, frame_transport); SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, hbox_max_size); SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, hbox_timeout); @@ -408,11 +467,15 @@ static void spamassassin_create_widget_func(PrefsPage * _page, SET_TOGGLE_SENSITIVITY(save_spam_checkbtn, save_spam_folder_select); SET_TOGGLE_SENSITIVITY(enable_sa_checkbtn, hbox_process_emails); SET_TOGGLE_SENSITIVITY(save_spam_checkbtn, mark_as_read_checkbtn); + SET_TOGGLE_SENSITIVITY(whitelist_ab_checkbtn, whitelist_ab_folder_combo); + SET_TOGGLE_SENSITIVITY(whitelist_ab_checkbtn, whitelist_ab_select_btn); config = spamassassin_get_config(); g_signal_connect(G_OBJECT(save_spam_folder_select), "clicked", G_CALLBACK(foldersel_cb), page); + g_signal_connect(G_OBJECT (whitelist_ab_select_btn), "clicked", + G_CALLBACK(spamassassin_whitelist_ab_select_cb), page); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enable_sa_checkbtn), config->enable); if (config->username != NULL) @@ -421,11 +484,15 @@ static void spamassassin_create_widget_func(PrefsPage * _page, gtk_entry_set_text(GTK_ENTRY(spamd_hostname_entry), config->hostname); if (config->socket != NULL) gtk_entry_set_text(GTK_ENTRY(spamd_socket_entry), config->socket); + if (config->whitelist_ab_folder != NULL) + gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(whitelist_ab_folder_combo)->entry), + config->whitelist_ab_folder); gtk_spin_button_set_value(GTK_SPIN_BUTTON(spamd_port_spinbtn), (float) config->port); gtk_spin_button_set_value(GTK_SPIN_BUTTON(max_size_spinbtn), (float) config->max_size); gtk_spin_button_set_value(GTK_SPIN_BUTTON(timeout_spinbtn), (float) config->timeout); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(process_emails_checkbtn), config->process_emails); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(save_spam_checkbtn), config->receive_spam); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(whitelist_ab_checkbtn), config->whitelist_ab); if (config->save_folder != NULL) gtk_entry_set_text(GTK_ENTRY(save_spam_folder_entry), config->save_folder); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mark_as_read_checkbtn), config->mark_as_read); @@ -445,6 +512,8 @@ static void spamassassin_create_widget_func(PrefsPage * _page, page->save_folder = save_spam_folder_entry; page->save_folder_select = save_spam_folder_select; page->mark_as_read = mark_as_read_checkbtn; + page->whitelist_ab = whitelist_ab_checkbtn; + page->whitelist_ab_folder_combo = whitelist_ab_folder_combo; active = 0; for (i = 0; i < (sizeof(transports) / sizeof(struct Transport)); i++) { @@ -530,6 +599,12 @@ static void spamassassin_save_func(PrefsPage *_page) /* mark_as_read */ config->mark_as_read = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->mark_as_read)); + /* whitelist_ab */ + config->whitelist_ab = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(page->whitelist_ab)); + g_free(config->whitelist_ab_folder); + config->whitelist_ab_folder = gtk_editable_get_chars( + GTK_EDITABLE(GTK_COMBO(page->whitelist_ab_folder_combo)->entry), 0, -1); + if (config->process_emails) { spamassassin_register_hook(); } else { -- 2.25.1