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"
48 static struct SSLManager
55 GtkWidget
*delete_btn
;
59 static void ssl_manager_view_cb (GtkWidget
*widget
, gpointer data
);
60 static void ssl_manager_delete_cb (GtkWidget
*widget
, gpointer data
);
61 static void ssl_manager_close_cb (GtkWidget
*widget
, gpointer data
);
62 static gboolean
key_pressed (GtkWidget
*widget
, GdkEventKey
*event
,
64 static void ssl_manager_load_certs (void);
65 static void ssl_manager_double_clicked(GtkTreeView
*list_view
,
67 GtkTreeViewColumn
*column
,
70 void ssl_manager_open(MainWindow
*mainwin
)
75 manage_window_set_transient(GTK_WINDOW(manager
.window
));
76 gtk_widget_grab_focus(manager
.close_btn
);
78 ssl_manager_load_certs();
80 gtk_widget_show(manager
.window
);
84 static GtkListStore
* ssl_manager_create_data_store(void)
86 return gtk_list_store_new(N_SSL_MANAGER_COLUMNS
,
93 static void ssl_manager_create_list_view_columns(GtkWidget
*list_view
)
95 GtkTreeViewColumn
*column
;
96 GtkCellRenderer
*renderer
;
98 renderer
= gtk_cell_renderer_text_new();
99 column
= gtk_tree_view_column_new_with_attributes
102 "text", SSL_MANAGER_HOST
,
104 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
106 renderer
= gtk_cell_renderer_text_new();
107 column
= gtk_tree_view_column_new_with_attributes
110 "text", SSL_MANAGER_PORT
,
112 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
115 static GtkWidget
*ssl_manager_list_view_create (void)
117 GtkTreeView
*list_view
;
118 GtkTreeSelection
*selector
;
121 model
= GTK_TREE_MODEL(ssl_manager_create_data_store());
122 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(model
));
123 g_object_unref(model
);
125 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model
),
126 0, GTK_SORT_ASCENDING
);
127 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
129 selector
= gtk_tree_view_get_selection(list_view
);
130 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
132 g_signal_connect(G_OBJECT(list_view
), "row_activated",
133 G_CALLBACK(ssl_manager_double_clicked
),
136 /* create the columns */
137 ssl_manager_create_list_view_columns(GTK_WIDGET(list_view
));
139 return GTK_WIDGET(list_view
);
143 void ssl_manager_create(void)
151 GtkWidget
*delete_btn
;
152 GtkWidget
*close_btn
;
154 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "ssl_manager");
155 gtk_window_set_title (GTK_WINDOW(window
),
156 _("Saved SSL/TLS certificates"));
158 gtk_container_set_border_width (GTK_CONTAINER (window
), 8);
159 gtk_window_set_position (GTK_WINDOW (window
), GTK_WIN_POS_CENTER
);
160 gtk_window_set_resizable(GTK_WINDOW (window
), TRUE
);
161 g_signal_connect(G_OBJECT(window
), "delete_event",
162 G_CALLBACK(ssl_manager_close_cb
), NULL
);
163 g_signal_connect(G_OBJECT(window
), "key_press_event",
164 G_CALLBACK(key_pressed
), NULL
);
165 MANAGE_WINDOW_SIGNALS_CONNECT (window
);
167 hbox1
= gtk_hbox_new(FALSE
, 6);
168 vbox1
= gtk_vbox_new(FALSE
, 0);
169 delete_btn
= gtk_button_new_from_stock(GTK_STOCK_DELETE
);
171 g_signal_connect(G_OBJECT(delete_btn
), "clicked",
172 G_CALLBACK(ssl_manager_delete_cb
), NULL
);
174 view_btn
= gtk_button_new_from_stock(GTK_STOCK_PROPERTIES
);
175 g_signal_connect(G_OBJECT(view_btn
), "clicked",
176 G_CALLBACK(ssl_manager_view_cb
), NULL
);
178 close_btn
= gtk_button_new_from_stock(GTK_STOCK_CLOSE
);
179 g_signal_connect(G_OBJECT(close_btn
), "clicked",
180 G_CALLBACK(ssl_manager_close_cb
), NULL
);
182 certlist
= ssl_manager_list_view_create();
184 scroll
= gtk_scrolled_window_new (NULL
, NULL
);
185 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll
),
187 GTK_POLICY_AUTOMATIC
);
188 gtk_container_add(GTK_CONTAINER (scroll
), certlist
);
190 gtk_box_pack_start(GTK_BOX(hbox1
), scroll
, TRUE
, TRUE
, 0);
191 gtk_box_pack_start(GTK_BOX(hbox1
), vbox1
, FALSE
, FALSE
, 0);
192 gtk_box_pack_start(GTK_BOX(vbox1
), view_btn
, FALSE
, FALSE
, 4);
193 gtk_box_pack_start(GTK_BOX(vbox1
), delete_btn
, FALSE
, FALSE
, 4);
194 gtk_box_pack_end(GTK_BOX(vbox1
), close_btn
, FALSE
, FALSE
, 4);
196 gtk_widget_show(certlist
);
197 gtk_widget_show(scroll
);
198 gtk_widget_show(hbox1
);
199 gtk_widget_show(vbox1
);
200 gtk_widget_show(close_btn
);
201 gtk_widget_show(delete_btn
);
202 gtk_widget_show(view_btn
);
203 gtk_container_add(GTK_CONTAINER (window
), hbox1
);
205 manager
.window
= window
;
206 manager
.hbox1
= hbox1
;
207 manager
.vbox1
= vbox1
;
208 manager
.certlist
= certlist
;
209 manager
.view_btn
= view_btn
;
210 manager
.delete_btn
= delete_btn
;
211 manager
.close_btn
= close_btn
;
213 gtk_widget_show(window
);
216 static char *get_server(const char *str
)
218 char *ret
= NULL
, *tmp
= g_strdup(str
);
219 char *first_pos
= NULL
, *last_pos
= NULL
;
220 char *previous_pos
= NULL
, *pre_previous_pos
= NULL
;
221 int previous_dot_pos
;
223 if (!strchr(tmp
, ':')) {
225 if (strstr(tmp
, ".cert"))
226 *(strstr(tmp
, ".cert")+1) = '.';
230 while (tmp
&& (tmp
= strstr(tmp
,".")) != NULL
) {
232 pre_previous_pos
= previous_pos
;
233 previous_pos
= last_pos
;
236 previous_dot_pos
= (pre_previous_pos
- first_pos
);
237 if (previous_dot_pos
- 1 > 0)
238 ret
= g_strndup(first_pos
, previous_dot_pos
- 1);
240 ret
= g_strdup(first_pos
);
245 static char *get_port(const char *str
)
247 char *ret
= NULL
, *tmp
= g_strdup(str
);
248 char *last_pos
= NULL
;
249 char *previous_pos
= NULL
, *pre_previous_pos
= NULL
;
251 if (!strchr(tmp
, ':')) {
253 if (strstr(tmp
, ".cert"))
254 *(strstr(tmp
, ".cert")+1) = '.';
257 while (tmp
&& (tmp
= strstr(tmp
,".")) != NULL
) {
259 pre_previous_pos
= previous_pos
;
260 previous_pos
= last_pos
;
263 if (previous_pos
&& pre_previous_pos
&& (int)(previous_pos
- pre_previous_pos
- 1) > 0)
264 ret
= g_strndup(pre_previous_pos
, (int)(previous_pos
- pre_previous_pos
- 1));
272 static char *get_fingerprint(const char *str
)
274 char *ret
= NULL
, *tmp
= g_strdup(str
);
275 char *previous_pos
= NULL
, *last_pos
= NULL
;
277 if (!strchr(tmp
, ':')) {
279 if (strstr(tmp
, ".cert"))
280 *(strstr(tmp
, ".cert")+1) = '.';
283 while (tmp
&& (tmp
= strstr(tmp
,".")) != NULL
) {
285 previous_pos
= last_pos
;
288 if (last_pos
&& previous_pos
&& (int)(last_pos
- previous_pos
- 1) > 0)
289 ret
= g_strndup(previous_pos
, (int)(last_pos
- previous_pos
- 1));
297 static void ssl_manager_list_view_insert_cert(GtkWidget
*list_view
,
298 GtkTreeIter
*row_iter
,
301 SSLCertificate
*cert
)
304 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model
305 (GTK_TREE_VIEW(list_view
)));
307 if (row_iter
== NULL
) {
309 gtk_list_store_append(list_store
, &iter
);
310 gtk_list_store_set(list_store
, &iter
,
311 SSL_MANAGER_HOST
, host
,
312 SSL_MANAGER_PORT
, port
,
313 SSL_MANAGER_CERT
, cert
,
316 gtk_list_store_set(list_store
, row_iter
,
317 SSL_MANAGER_HOST
, host
,
318 SSL_MANAGER_PORT
, port
,
319 SSL_MANAGER_CERT
, cert
,
324 static void ssl_manager_load_certs (void)
328 GError
*error
= NULL
;
333 store
= GTK_LIST_STORE(gtk_tree_view_get_model
334 (GTK_TREE_VIEW(manager
.certlist
)));
336 gtk_list_store_clear(store
);
338 path
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
339 "certs", G_DIR_SEPARATOR_S
, NULL
);
341 if((dir
= g_dir_open(path
, 0, &error
)) == NULL
) {
342 debug_print("couldn't open dir '%s': %s (%d)\n", path
,
343 error
->message
, error
->code
);
348 while ((d
= g_dir_read_name(dir
)) != NULL
) {
349 gchar
*server
, *port
, *fp
;
350 SSLCertificate
*cert
;
352 if(strstr(d
, ".cert") != d
+ (strlen(d
) - strlen(".cert")))
355 server
= get_server(d
);
357 fp
= get_fingerprint(d
);
359 cert
= ssl_certificate_find(server
, atoi(port
), fp
);
361 ssl_manager_list_view_insert_cert(manager
.certlist
, NULL
,
373 static void ssl_manager_close(void)
375 gtk_widget_hide(manager
.window
);
378 static void ssl_manager_close_cb(GtkWidget
*widget
,
384 static gboolean
key_pressed(GtkWidget
*widget
, GdkEventKey
*event
, gpointer data
)
386 if (event
&& event
->keyval
== GDK_KEY_Escape
)
391 static void ssl_manager_double_clicked(GtkTreeView
*list_view
,
393 GtkTreeViewColumn
*column
,
396 SSLCertificate
*cert
;
398 GtkTreeModel
*model
= gtk_tree_view_get_model(list_view
);
400 if (!gtk_tree_model_get_iter(model
, &iter
, path
))
403 gtk_tree_model_get(model
, &iter
,
404 SSL_MANAGER_CERT
, &cert
,
410 sslcertwindow_show_cert(cert
);
417 static void ssl_manager_delete_cb(GtkWidget
*widget
,
420 SSLCertificate
*cert
;
425 if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
426 (GTK_TREE_VIEW(manager
.certlist
)),
430 gtk_tree_model_get(model
, &sel
,
431 SSL_MANAGER_CERT
, &cert
,
436 val
= alertpanel_full(_("Delete certificate"),
437 _("Do you really want to delete this certificate?"),
438 GTK_STOCK_CANCEL
, GTK_STOCK_DELETE
, NULL
, FALSE
,
439 NULL
, ALERT_WARNING
, G_ALERTDEFAULT
);
442 if (val
!= G_ALERTALTERNATE
)
445 ssl_certificate_delete_from_disk(cert
);
446 ssl_certificate_destroy(cert
);
447 gtk_list_store_remove(GTK_LIST_STORE(model
), &sel
);
450 static void ssl_manager_view_cb(GtkWidget
*widget
,
453 SSLCertificate
*cert
;
457 if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
458 (GTK_TREE_VIEW(manager
.certlist
)),
462 gtk_tree_model_get(model
, &sel
,
463 SSL_MANAGER_CERT
, &cert
,
468 sslcertwindow_show_cert(cert
);