2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2016 Colin Leroy and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "claws-features.h"
26 #include <glib/gi18n.h>
27 #include <gdk/gdkkeysyms.h>
28 #include <sys/types.h>
31 #include "ssl_manager.h"
32 #include "ssl_certificate.h"
33 #include "manage_window.h"
35 #include "mainwindow.h"
36 #include "alertpanel.h"
37 #include "sslcertwindow.h"
38 #include "prefs_common.h"
46 SSL_MANAGER_FONT_WEIGHT
,
51 static struct SSLManager
58 GtkWidget
*delete_btn
;
62 static void ssl_manager_view_cb (GtkWidget
*widget
, gpointer data
);
63 static void ssl_manager_delete_cb (GtkWidget
*widget
, gpointer data
);
64 static void ssl_manager_close_cb (GtkWidget
*widget
, gpointer data
);
65 static gboolean
key_pressed (GtkWidget
*widget
, GdkEventKey
*event
,
67 static void ssl_manager_load_certs (void);
68 static void ssl_manager_double_clicked(GtkTreeView
*list_view
,
70 GtkTreeViewColumn
*column
,
73 void ssl_manager_open(MainWindow
*mainwin
)
78 manage_window_set_transient(GTK_WINDOW(manager
.window
));
79 gtk_widget_grab_focus(manager
.close_btn
);
81 ssl_manager_load_certs();
83 gtk_widget_show(manager
.window
);
87 static GtkListStore
* ssl_manager_create_data_store(void)
89 return gtk_list_store_new(N_SSL_MANAGER_COLUMNS
,
99 static void ssl_manager_create_list_view_columns(GtkWidget
*list_view
)
101 GtkTreeViewColumn
*column
;
102 GtkCellRenderer
*renderer
;
104 renderer
= gtk_cell_renderer_text_new();
105 g_object_set(renderer
, "weight", PANGO_WEIGHT_NORMAL
,
106 "weight-set", TRUE
, NULL
);
108 column
= gtk_tree_view_column_new_with_attributes
111 "text", SSL_MANAGER_HOST
,
112 "weight", SSL_MANAGER_FONT_WEIGHT
,
114 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
116 column
= gtk_tree_view_column_new_with_attributes
119 "text", SSL_MANAGER_PORT
,
121 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
123 column
= gtk_tree_view_column_new_with_attributes
126 "text", SSL_MANAGER_STATUS
,
128 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
130 column
= gtk_tree_view_column_new_with_attributes
133 "text", SSL_MANAGER_EXPIRY
,
135 gtk_tree_view_column_set_attributes
137 "text", SSL_MANAGER_EXPIRY
,
139 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
142 static GtkWidget
*ssl_manager_list_view_create (void)
144 GtkTreeView
*list_view
;
145 GtkTreeSelection
*selector
;
148 model
= GTK_TREE_MODEL(ssl_manager_create_data_store());
149 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(model
));
150 g_object_unref(model
);
152 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model
),
153 0, GTK_SORT_ASCENDING
);
154 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
156 selector
= gtk_tree_view_get_selection(list_view
);
157 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
159 g_signal_connect(G_OBJECT(list_view
), "row_activated",
160 G_CALLBACK(ssl_manager_double_clicked
),
163 /* create the columns */
164 ssl_manager_create_list_view_columns(GTK_WIDGET(list_view
));
166 return GTK_WIDGET(list_view
);
170 *\brief Save Gtk object size to prefs dataset
172 static void ssl_manager_size_allocate_cb(GtkWidget
*widget
,
173 GtkAllocation
*allocation
)
175 cm_return_if_fail(allocation
!= NULL
);
177 prefs_common
.sslmanwin_width
= allocation
->width
;
178 prefs_common
.sslmanwin_height
= allocation
->height
;
181 void ssl_manager_create(void)
189 GtkWidget
*delete_btn
;
190 GtkWidget
*close_btn
;
191 static GdkGeometry geometry
;
193 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "ssl_manager");
194 gtk_window_set_title (GTK_WINDOW(window
),
195 _("Saved SSL/TLS certificates"));
197 gtk_container_set_border_width (GTK_CONTAINER (window
), 8);
198 gtk_window_set_position (GTK_WINDOW (window
), GTK_WIN_POS_CENTER
);
199 gtk_window_set_resizable(GTK_WINDOW (window
), TRUE
);
200 gtk_window_set_type_hint(GTK_WINDOW(window
), GDK_WINDOW_TYPE_HINT_DIALOG
);
201 g_signal_connect(G_OBJECT(window
), "delete_event",
202 G_CALLBACK(ssl_manager_close_cb
), NULL
);
203 g_signal_connect(G_OBJECT(window
), "size_allocate",
204 G_CALLBACK(ssl_manager_size_allocate_cb
), NULL
);
205 g_signal_connect(G_OBJECT(window
), "key_press_event",
206 G_CALLBACK(key_pressed
), NULL
);
207 MANAGE_WINDOW_SIGNALS_CONNECT (window
);
209 hbox1
= gtk_hbox_new(FALSE
, 6);
210 vbox1
= gtk_vbox_new(FALSE
, 0);
211 delete_btn
= gtk_button_new_from_stock(GTK_STOCK_DELETE
);
213 g_signal_connect(G_OBJECT(delete_btn
), "clicked",
214 G_CALLBACK(ssl_manager_delete_cb
), NULL
);
216 view_btn
= gtk_button_new_from_stock(GTK_STOCK_PROPERTIES
);
217 g_signal_connect(G_OBJECT(view_btn
), "clicked",
218 G_CALLBACK(ssl_manager_view_cb
), NULL
);
220 close_btn
= gtk_button_new_from_stock(GTK_STOCK_CLOSE
);
221 g_signal_connect(G_OBJECT(close_btn
), "clicked",
222 G_CALLBACK(ssl_manager_close_cb
), NULL
);
224 certlist
= ssl_manager_list_view_create();
226 scroll
= gtk_scrolled_window_new (NULL
, NULL
);
227 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll
),
229 GTK_POLICY_AUTOMATIC
);
231 gtk_container_add(GTK_CONTAINER (scroll
), certlist
);
233 gtk_box_pack_start(GTK_BOX(hbox1
), scroll
, TRUE
, TRUE
, 0);
234 gtk_box_pack_start(GTK_BOX(hbox1
), vbox1
, FALSE
, FALSE
, 0);
235 gtk_box_pack_start(GTK_BOX(vbox1
), view_btn
, FALSE
, FALSE
, 4);
236 gtk_box_pack_start(GTK_BOX(vbox1
), delete_btn
, FALSE
, FALSE
, 4);
237 gtk_box_pack_end(GTK_BOX(vbox1
), close_btn
, FALSE
, FALSE
, 4);
239 if (!geometry
.min_height
) {
240 geometry
.min_width
= 700;
241 geometry
.min_height
= 250;
244 gtk_window_set_geometry_hints(GTK_WINDOW(window
), NULL
, &geometry
,
246 gtk_widget_set_size_request(window
, prefs_common
.sslmanwin_width
,
247 prefs_common
.sslmanwin_height
);
249 gtk_widget_show(certlist
);
250 gtk_widget_show(scroll
);
251 gtk_widget_show(hbox1
);
252 gtk_widget_show(vbox1
);
253 gtk_widget_show(close_btn
);
254 gtk_widget_show(delete_btn
);
255 gtk_widget_show(view_btn
);
256 gtk_container_add(GTK_CONTAINER (window
), hbox1
);
258 manager
.window
= window
;
259 manager
.hbox1
= hbox1
;
260 manager
.vbox1
= vbox1
;
261 manager
.certlist
= certlist
;
262 manager
.view_btn
= view_btn
;
263 manager
.delete_btn
= delete_btn
;
264 manager
.close_btn
= close_btn
;
266 gtk_widget_show(window
);
269 static void ssl_manager_list_view_insert_cert(GtkWidget
*list_view
,
270 GtkTreeIter
*row_iter
,
273 SSLCertificate
*cert
)
275 char *sig_status
, *exp_date
;
279 PangoWeight weight
= PANGO_WEIGHT_NORMAL
;
280 GtkTreeIter iter
, *iterptr
;
281 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model
282 (GTK_TREE_VIEW(list_view
)));
284 g_return_if_fail(cert
!= NULL
);
286 exp_time_t
= gnutls_x509_crt_get_expiration_time(cert
->x509_cert
);
288 memset(buf
, 0, sizeof(buf
));
289 if (exp_time_t
> 0) {
290 fast_strftime(buf
, sizeof(buf
)-1, prefs_common
.date_format
, localtime_r(&exp_time_t
, <
));
291 exp_date
= (*buf
) ? g_strdup(buf
):g_strdup("?");
293 exp_date
= g_strdup("");
295 if (exp_time_t
< time(NULL
))
296 weight
= PANGO_WEIGHT_BOLD
;
298 sig_status
= ssl_certificate_check_signer(cert
, cert
->status
);
300 if (sig_status
== NULL
)
301 sig_status
= g_strdup_printf(_("Correct%s"),exp_time_t
< time(NULL
)? _(" (expired)"): "");
303 weight
= PANGO_WEIGHT_BOLD
;
304 if (exp_time_t
< time(NULL
))
305 sig_status
= g_strconcat(sig_status
,_(" (expired)"),NULL
);
308 if (row_iter
== NULL
) {
310 gtk_list_store_append(list_store
, &iter
);
315 gtk_list_store_set(list_store
, iterptr
,
316 SSL_MANAGER_HOST
, host
,
317 SSL_MANAGER_PORT
, port
,
318 SSL_MANAGER_CERT
, cert
,
319 SSL_MANAGER_STATUS
, sig_status
,
320 SSL_MANAGER_EXPIRY
, exp_date
,
321 SSL_MANAGER_FONT_WEIGHT
, weight
,
328 static void ssl_manager_load_certs (void)
332 GError
*error
= NULL
;
337 store
= GTK_LIST_STORE(gtk_tree_view_get_model
338 (GTK_TREE_VIEW(manager
.certlist
)));
340 gtk_list_store_clear(store
);
342 path
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
343 "certs", G_DIR_SEPARATOR_S
, NULL
);
345 if((dir
= g_dir_open(path
, 0, &error
)) == NULL
) {
346 debug_print("couldn't open dir '%s': %s (%d)\n", path
,
347 error
->message
, error
->code
);
352 while ((d
= g_dir_read_name(dir
)) != NULL
) {
353 gchar
*server
= NULL
, *port
= NULL
, *fp
= NULL
;
354 SSLCertificate
*cert
;
356 if(strstr(d
, ".cert") != d
+ (strlen(d
) - strlen(".cert")))
359 if (get_serverportfp_from_filename(d
, &server
, &port
, &fp
)) {
361 if (server
!= NULL
&& port
!= NULL
) {
362 gint portnum
= atoi(port
);
363 if (portnum
> 0 && portnum
<= 65535) {
364 cert
= ssl_certificate_find(server
, portnum
, fp
);
365 ssl_manager_list_view_insert_cert(manager
.certlist
, NULL
,
380 static void ssl_manager_close(void)
382 gtk_widget_hide(manager
.window
);
385 static void ssl_manager_close_cb(GtkWidget
*widget
,
391 static gboolean
key_pressed(GtkWidget
*widget
, GdkEventKey
*event
, gpointer data
)
396 if (event
->keyval
== GDK_KEY_Escape
)
398 else if (event
->keyval
== GDK_KEY_Delete
)
399 ssl_manager_delete_cb(manager
.delete_btn
, NULL
);
404 static void ssl_manager_double_clicked(GtkTreeView
*list_view
,
406 GtkTreeViewColumn
*column
,
409 SSLCertificate
*cert
;
411 GtkTreeModel
*model
= gtk_tree_view_get_model(list_view
);
413 if (!gtk_tree_model_get_iter(model
, &iter
, path
))
416 gtk_tree_model_get(model
, &iter
,
417 SSL_MANAGER_CERT
, &cert
,
423 sslcertwindow_show_cert(cert
);
430 static void ssl_manager_delete_cb(GtkWidget
*widget
,
433 SSLCertificate
*cert
;
438 cert
= gtkut_tree_view_get_selected_pointer(
439 GTK_TREE_VIEW(manager
.certlist
), SSL_MANAGER_CERT
,
440 &model
, NULL
, &iter
);
445 val
= alertpanel_full(_("Delete certificate"),
446 _("Do you really want to delete this certificate?"),
447 GTK_STOCK_CANCEL
, GTK_STOCK_DELETE
, NULL
, ALERTFOCUS_FIRST
,
448 FALSE
, NULL
, ALERT_WARNING
);
451 if (val
!= G_ALERTALTERNATE
)
454 ssl_certificate_delete_from_disk(cert
);
455 ssl_certificate_destroy(cert
);
456 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
459 static void ssl_manager_view_cb(GtkWidget
*widget
,
462 SSLCertificate
*cert
;
464 cert
= gtkut_tree_view_get_selected_pointer(
465 GTK_TREE_VIEW(manager
.certlist
), SSL_MANAGER_CERT
,
471 sslcertwindow_show_cert(cert
);