talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 123cf6fbfe84f47d6bf277efc835a1b353ed0c94
parent dc6d8a1a1947544caa7b309d99b2614d61c6ec03
Author: Colin Leroy <colin@colino.net>
Date:   Tue, 29 Apr 2014 10:33:38 +0200

Implement SSL certificate verification option (default, and per-feed).
Fixes bug #3106, "Rssyl plugin does not verify SSL peer at all"

Diffstat:
Msrc/plugins/rssyl/feed.c | 17+++++++++++------
Msrc/plugins/rssyl/feed.h | 2+-
Msrc/plugins/rssyl/feedprops.c | 14++++++++++++++
Msrc/plugins/rssyl/feedprops.h | 1+
Msrc/plugins/rssyl/rssyl.c | 1+
Msrc/plugins/rssyl/rssyl.h | 1+
Msrc/plugins/rssyl/rssyl_gtk.c | 23++++++++++++++++++++++-
Msrc/plugins/rssyl/rssyl_gtk.h | 1+
Msrc/plugins/rssyl/rssyl_prefs.c | 17+++++++++++++++--
Msrc/plugins/rssyl/rssyl_prefs.h | 2++
10 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/src/plugins/rssyl/feed.c b/src/plugins/rssyl/feed.c @@ -84,6 +84,7 @@ struct _RSSylThreadCtx { gboolean defer_modified_check; gboolean ready; gchar *error; + gboolean ssl_verify_peer; }; typedef struct _RSSylThreadCtx RSSylThreadCtx; @@ -157,8 +158,10 @@ static void *rssyl_fetch_feed_threaded(void *arg) curl_easy_setopt(eh, CURLOPT_NOSIGNAL, 1); curl_easy_setopt(eh, CURLOPT_ENCODING, ""); #if LIBCURL_VERSION_NUM >= 0x070a00 - curl_easy_setopt(eh, CURLOPT_SSL_VERIFYPEER, 0); - curl_easy_setopt(eh, CURLOPT_SSL_VERIFYHOST, 0); + if(ctx->ssl_verify_peer == FALSE) { + curl_easy_setopt(eh, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(eh, CURLOPT_SSL_VERIFYHOST, 0); + } #endif curl_easy_setopt(eh, CURLOPT_USERAGENT, "Claws Mail RSSyl plugin "VERSION @@ -287,7 +290,7 @@ gchar *rssyl_feed_title_to_dir(const gchar *title) * it for title, create a directory based on the title. It returns a xmlDocPtr * for libxml2 to parse further. */ -xmlDocPtr rssyl_fetch_feed(const gchar *url, time_t last_update, gchar **title, gchar **error) { +xmlDocPtr rssyl_fetch_feed(const gchar *url, time_t last_update, gboolean ssl_verify_peer, gchar **title, gchar **error) { gchar *xpath, *rootnode, *dir; xmlDocPtr doc; xmlNodePtr node, n, rnode; @@ -314,6 +317,7 @@ xmlDocPtr rssyl_fetch_feed(const gchar *url, time_t last_update, gchar **title, ctx->last_update = last_update; ctx->not_modified = FALSE; ctx->defer_modified_check = FALSE; + ctx->ssl_verify_peer = ssl_verify_peer; *title = NULL; @@ -1504,7 +1508,8 @@ void rssyl_update_comments(RSSylFolderItem *ritem) (ritem->fetch_comments_for == -1 || time(NULL) - fitem->date <= ritem->fetch_comments_for*86400)) { debug_print("RSSyl: fetching comments '%s'\n", fitem->comments_link); - doc = rssyl_fetch_feed(fitem->comments_link, ritem->item.mtime, &title, NULL); + doc = rssyl_fetch_feed(fitem->comments_link, ritem->item.mtime, + ritem->ssl_verify_peer, &title, NULL); rssyl_parse_feed(doc, ritem, fitem->id); xmlFreeDoc(doc); g_free(title); @@ -1532,7 +1537,7 @@ void rssyl_update_feed(RSSylFolderItem *ritem) log_print(LOG_PROTOCOL, RSSYL_LOG_UPDATING, ritem->url); - doc = rssyl_fetch_feed(ritem->url, ritem->item.mtime, &title, &error); + doc = rssyl_fetch_feed(ritem->url, ritem->item.mtime, ritem->ssl_verify_peer, &title, &error); if (claws_is_exiting()) { debug_print("RSSyl: Claws-Mail is exiting, aborting feed parsing\n"); @@ -1725,7 +1730,7 @@ FolderItem *rssyl_subscribe_new_feed(FolderItem *parent, const gchar *url, } main_window_cursor_wait(mainwindow_get_mainwindow()); - doc = rssyl_fetch_feed(myurl, -1, &title, &error); + doc = rssyl_fetch_feed(myurl, -1, rssyl_prefs_get()->ssl_verify_peer, &title, &error); main_window_cursor_normal(mainwindow_get_mainwindow()); if( !doc || !title ) { if (verbose) { diff --git a/src/plugins/rssyl/feed.h b/src/plugins/rssyl/feed.h @@ -71,7 +71,7 @@ struct _RSSylParseCtx { typedef struct _RSSylParseCtx RSSylParseCtx; -xmlDocPtr rssyl_fetch_feed(const gchar *url, time_t last_update, gchar **title, gchar **error); +xmlDocPtr rssyl_fetch_feed(const gchar *url, time_t last_update, gboolean ssl_verify_peer, gchar **title, gchar **error); void rssyl_parse_feed(xmlDocPtr doc, RSSylFolderItem *ritem, gchar *parent); gboolean rssyl_add_feed_item(RSSylFolderItem *ritem, RSSylFeedItem *fitem); MsgInfo *rssyl_parse_feed_item_to_msginfo(gchar *file, MsgFlags flags, diff --git a/src/plugins/rssyl/feedprops.c b/src/plugins/rssyl/feedprops.c @@ -125,6 +125,10 @@ void rssyl_store_feed_props(RSSylFolderItem *ritem) xmlSetProp(node, RSSYL_PROP_SILENT_UPDATE, t_prop); g_free(t_prop); + t_prop = g_strdup_printf("%d", ritem->ssl_verify_peer); + xmlSetProp(node, RSSYL_PROP_SSL_VERIFY_PEER, t_prop); + g_free(t_prop); + found = TRUE; } xmlFree(tmp); @@ -278,6 +282,16 @@ void rssyl_get_feed_props(RSSylFolderItem *ritem) xmlFree(tmp); tmp = NULL; + /* ssl_verify_peer */ + tmp = xmlGetProp(node, RSSYL_PROP_SSL_VERIFY_PEER); + tmpi = 0; + if( tmp ) { + tmpi = atoi(tmp); + ritem->ssl_verify_peer = tmpi; + } + xmlFree(tmp); + tmp = NULL; + tmp = xmlGetProp(node, RSSYL_PROP_EXPIRED); if( ritem->default_expired_num ) diff --git a/src/plugins/rssyl/feedprops.h b/src/plugins/rssyl/feedprops.h @@ -16,6 +16,7 @@ #define RSSYL_PROP_FETCH_COMMENTS "fetch_comments" #define RSSYL_PROP_FETCH_COMMENTS_FOR "fetch_comments_for" #define RSSYL_PROP_SILENT_UPDATE "silent_update" +#define RSSYL_PROP_SSL_VERIFY_PEER "ssl_verify_peer" void rssyl_store_feed_props(RSSylFolderItem *ritem); void rssyl_get_feed_props(RSSylFolderItem *ritem); diff --git a/src/plugins/rssyl/rssyl.c b/src/plugins/rssyl/rssyl.c @@ -296,6 +296,7 @@ static FolderItem *rssyl_item_new(Folder *folder) ritem->refresh_id = 0; ritem->expired_num = rssyl_prefs_get()->expired; ritem->last_count = 0; + ritem->ssl_verify_peer = rssyl_prefs_get()->ssl_verify_peer; ritem->contents = NULL; ritem->feedprop = NULL; diff --git a/src/plugins/rssyl/rssyl.h b/src/plugins/rssyl/rssyl.h @@ -34,6 +34,7 @@ struct _RSSylFolderItem { gboolean fetch_comments; gint fetch_comments_for; gint silent_update; + gboolean ssl_verify_peer; struct _RSSylFeedProp *feedprop; }; diff --git a/src/plugins/rssyl/rssyl_gtk.c b/src/plugins/rssyl/rssyl_gtk.c @@ -234,7 +234,7 @@ static RSSylFeedProp *rssyl_gtk_prop_real(RSSylFolderItem *ritem) *expired_label, *hsep, *sep, *bbox, *cancel_button, *cancel_align, *cancel_hbox, *cancel_image, *cancel_label, *ok_button, *ok_align, *ok_hbox, *ok_image, *ok_label, *silent_update_label; - GtkWidget *ssl_verify_peer_checkbtn; + GtkObject *refresh_adj, *expired_adj, *fetch_comments_for_adj; gint refresh, expired; gint row = 0; @@ -452,6 +452,24 @@ static RSSylFeedProp *rssyl_gtk_prop_real(RSSylFolderItem *ritem) gtk_combo_box_set_active(GTK_COMBO_BOX(feedprop->silent_update), ritem->silent_update); + row++; + hsep = gtk_hseparator_new(); + gtk_widget_set_size_request(hsep, -1, 10); + gtk_table_attach(GTK_TABLE(table), hsep, 0, 2, row, row+1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 10, 5); + + row++; + feedprop->ssl_verify_peer_checkbtn = gtk_check_button_new_with_label( + _("Verify SSL certificate validity")); + gtk_widget_show(feedprop->ssl_verify_peer_checkbtn); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(feedprop->ssl_verify_peer_checkbtn), + ritem->ssl_verify_peer); + gtk_table_attach(GTK_TABLE(table), feedprop->ssl_verify_peer_checkbtn, 0, 1, row, row+1, + (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), + (GtkAttachOptions) (0), 10, 5); + + /* Separator above the button box */ sep = gtk_hseparator_new(); gtk_widget_set_size_request(sep, -1, 10); @@ -610,6 +628,9 @@ void rssyl_gtk_prop_store(RSSylFolderItem *ritem) if( ritem->silent_update < 0 ) ritem->silent_update = 0; + ritem->ssl_verify_peer = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON + (ritem->feedprop->ssl_verify_peer_checkbtn));; + rssyl_store_feed_props(ritem); debug_print("last_count %d, x %d, old_ex %d\n", ritem->last_count, x, old_ex); diff --git a/src/plugins/rssyl/rssyl_gtk.h b/src/plugins/rssyl/rssyl_gtk.h @@ -17,6 +17,7 @@ struct _RSSylFeedProp { GtkWidget *fetch_comments; GtkWidget *fetch_comments_for; GtkWidget *silent_update; + GtkWidget *ssl_verify_peer_checkbtn; }; typedef struct _RSSylFeedProp RSSylFeedProp; diff --git a/src/plugins/rssyl/rssyl_prefs.c b/src/plugins/rssyl/rssyl_prefs.c @@ -48,10 +48,12 @@ static PrefParam param[] = { NULL, NULL, NULL }, { "expired_keep", RSSYL_PREF_DEFAULT_EXPIRED, &rssyl_prefs.expired, P_INT, NULL, NULL, NULL }, - { "refresh_on_startup", FALSE, &rssyl_prefs.refresh_on_startup, P_BOOL, + { "refresh_on_startup", "FALSE", &rssyl_prefs.refresh_on_startup, P_BOOL, NULL, NULL, NULL }, { "cookies_path", "", &rssyl_prefs.cookies_path, P_STRING, NULL, NULL, NULL }, + { "ssl_verify_peer", "TRUE", &rssyl_prefs.ssl_verify_peer, P_BOOL, + NULL, NULL, NULL }, { 0, 0, 0, 0, 0, 0, 0 } }; @@ -92,11 +94,12 @@ static void create_rssyl_prefs_page(PrefsPage *page, GtkWidget *expired; GtkWidget *refresh_on_startup; GtkWidget *cookies_path; + GtkWidget *ssl_verify_peer_checkbtn; GtkWidget *label; GtkObject *refresh_adj, *expired_adj; table = gtk_table_new(RSSYL_NUM_PREFS, 2, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); + gtk_container_set_border_width(GTK_CONTAINER(table), 6); gtk_table_set_row_spacings(GTK_TABLE(table), VSPACING_NARROW); gtk_table_set_col_spacings(GTK_TABLE(table), 8); @@ -145,6 +148,13 @@ static void create_rssyl_prefs_page(PrefsPage *page, CLAWS_SET_TIP(cookies_path, _("Path to Netscape-style cookies.txt file containing your cookies")); + ssl_verify_peer_checkbtn = gtk_check_button_new_with_label( + _("Verify SSL certificates validity for new feeds")); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ssl_verify_peer_checkbtn), + rssyl_prefs.ssl_verify_peer); + gtk_table_attach(GTK_TABLE(table), ssl_verify_peer_checkbtn, 0, 2, 5, 6, + GTK_FILL | GTK_EXPAND, 0, 0, 0); + gtk_widget_show_all(table); prefs_page->page.widget = table; @@ -152,6 +162,7 @@ static void create_rssyl_prefs_page(PrefsPage *page, prefs_page->expired = expired; prefs_page->refresh_on_startup = refresh_on_startup; prefs_page->cookies_path = cookies_path; + prefs_page->ssl_verify_peer_checkbtn = ssl_verify_peer_checkbtn; } static void destroy_rssyl_prefs_page(PrefsPage *page) @@ -175,6 +186,8 @@ static void save_rssyl_prefs(PrefsPage *page) g_free(rssyl_prefs.cookies_path); rssyl_prefs.cookies_path = g_strdup(gtk_entry_get_text( GTK_ENTRY(prefs_page->cookies_path))); + rssyl_prefs.ssl_verify_peer = gtk_toggle_button_get_active( + GTK_TOGGLE_BUTTON(prefs_page->ssl_verify_peer_checkbtn)); pref_file = prefs_write_open(rc_file_path); g_free(rc_file_path); diff --git a/src/plugins/rssyl/rssyl_prefs.h b/src/plugins/rssyl/rssyl_prefs.h @@ -15,6 +15,7 @@ struct _RSSylPrefs { gint expired; gboolean refresh_on_startup; gchar *cookies_path; + gboolean ssl_verify_peer; }; typedef struct _RSSylPrefsPage RSSylPrefsPage; @@ -25,6 +26,7 @@ struct _RSSylPrefsPage { GtkWidget *expired; GtkWidget *refresh_on_startup; GtkWidget *cookies_path; + GtkWidget *ssl_verify_peer_checkbtn; }; void rssyl_prefs_init(void);