2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 1999-2012 Colin Leroy <colin@colino.net>
4 * and the Claws Mail team
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "claws-features.h"
28 #include <glib/gi18n.h>
29 #include <gdk/gdkkeysyms.h>
30 #include <sys/types.h>
33 #include "ssl_manager.h"
34 #include "ssl_certificate.h"
35 #include "manage_window.h"
37 #include "mainwindow.h"
38 #include "alertpanel.h"
39 #include "sslcertwindow.h"
40 #include "prefs_common.h"
50 static struct SSLManager
57 GtkWidget
*delete_btn
;
61 static void ssl_manager_view_cb (GtkWidget
*widget
, gpointer data
);
62 static void ssl_manager_delete_cb (GtkWidget
*widget
, gpointer data
);
63 static void ssl_manager_close_cb (GtkWidget
*widget
, gpointer data
);
64 static gboolean
key_pressed (GtkWidget
*widget
, GdkEventKey
*event
,
66 static void ssl_manager_load_certs (void);
67 static void ssl_manager_double_clicked(GtkTreeView
*list_view
,
69 GtkTreeViewColumn
*column
,
72 void ssl_manager_open(MainWindow
*mainwin
)
77 manage_window_set_transient(GTK_WINDOW(manager
.window
));
78 gtk_widget_grab_focus(manager
.close_btn
);
80 ssl_manager_load_certs();
82 gtk_widget_show(manager
.window
);
86 static GtkListStore
* ssl_manager_create_data_store(void)
88 return gtk_list_store_new(N_SSL_MANAGER_COLUMNS
,
95 static void ssl_manager_create_list_view_columns(GtkWidget
*list_view
)
97 GtkTreeViewColumn
*column
;
98 GtkCellRenderer
*renderer
;
100 renderer
= gtk_cell_renderer_text_new();
101 column
= gtk_tree_view_column_new_with_attributes
104 "text", SSL_MANAGER_HOST
,
106 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
108 renderer
= gtk_cell_renderer_text_new();
109 column
= gtk_tree_view_column_new_with_attributes
112 "text", SSL_MANAGER_PORT
,
114 gtk_tree_view_append_column(GTK_TREE_VIEW(list_view
), column
);
117 static GtkWidget
*ssl_manager_list_view_create (void)
119 GtkTreeView
*list_view
;
120 GtkTreeSelection
*selector
;
123 model
= GTK_TREE_MODEL(ssl_manager_create_data_store());
124 list_view
= GTK_TREE_VIEW(gtk_tree_view_new_with_model(model
));
125 g_object_unref(model
);
127 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model
),
128 0, GTK_SORT_ASCENDING
);
129 gtk_tree_view_set_rules_hint(list_view
, prefs_common
.use_stripes_everywhere
);
131 selector
= gtk_tree_view_get_selection(list_view
);
132 gtk_tree_selection_set_mode(selector
, GTK_SELECTION_BROWSE
);
134 g_signal_connect(G_OBJECT(list_view
), "row_activated",
135 G_CALLBACK(ssl_manager_double_clicked
),
138 /* create the columns */
139 ssl_manager_create_list_view_columns(GTK_WIDGET(list_view
));
141 return GTK_WIDGET(list_view
);
145 void ssl_manager_create(void)
152 GtkWidget
*delete_btn
;
153 GtkWidget
*close_btn
;
155 window
= gtkut_window_new(GTK_WINDOW_TOPLEVEL
, "ssl_manager");
156 gtk_window_set_title (GTK_WINDOW(window
),
157 _("Saved SSL certificates"));
159 gtk_container_set_border_width (GTK_CONTAINER (window
), 8);
160 gtk_window_set_position (GTK_WINDOW (window
), GTK_WIN_POS_CENTER
);
161 gtk_window_set_resizable(GTK_WINDOW (window
), TRUE
);
162 g_signal_connect(G_OBJECT(window
), "delete_event",
163 G_CALLBACK(ssl_manager_close_cb
), NULL
);
164 g_signal_connect(G_OBJECT(window
), "key_press_event",
165 G_CALLBACK(key_pressed
), NULL
);
166 MANAGE_WINDOW_SIGNALS_CONNECT (window
);
168 hbox1
= gtk_hbox_new(FALSE
, 6);
169 vbox1
= gtk_vbox_new(FALSE
, 0);
170 delete_btn
= gtk_button_new_from_stock(GTK_STOCK_DELETE
);
172 g_signal_connect(G_OBJECT(delete_btn
), "clicked",
173 G_CALLBACK(ssl_manager_delete_cb
), NULL
);
175 view_btn
= gtk_button_new_from_stock(GTK_STOCK_PROPERTIES
);
176 g_signal_connect(G_OBJECT(view_btn
), "clicked",
177 G_CALLBACK(ssl_manager_view_cb
), NULL
);
179 close_btn
= gtk_button_new_from_stock(GTK_STOCK_CLOSE
);
180 g_signal_connect(G_OBJECT(close_btn
), "clicked",
181 G_CALLBACK(ssl_manager_close_cb
), NULL
);
183 certlist
= ssl_manager_list_view_create();
185 gtk_box_pack_start(GTK_BOX(hbox1
), certlist
, TRUE
, TRUE
, 0);
186 gtk_box_pack_start(GTK_BOX(hbox1
), vbox1
, FALSE
, FALSE
, 0);
187 gtk_box_pack_start(GTK_BOX(vbox1
), view_btn
, FALSE
, FALSE
, 4);
188 gtk_box_pack_start(GTK_BOX(vbox1
), delete_btn
, FALSE
, FALSE
, 4);
189 gtk_box_pack_end(GTK_BOX(vbox1
), close_btn
, FALSE
, FALSE
, 4);
191 gtk_widget_show(certlist
);
192 gtk_widget_show(hbox1
);
193 gtk_widget_show(vbox1
);
194 gtk_widget_show(close_btn
);
195 gtk_widget_show(delete_btn
);
196 gtk_widget_show(view_btn
);
197 gtk_container_add(GTK_CONTAINER (window
), hbox1
);
199 manager
.window
= window
;
200 manager
.hbox1
= hbox1
;
201 manager
.vbox1
= vbox1
;
202 manager
.certlist
= certlist
;
203 manager
.view_btn
= view_btn
;
204 manager
.delete_btn
= delete_btn
;
205 manager
.close_btn
= close_btn
;
207 gtk_widget_show(window
);
211 static char *get_server(char *str
)
213 char *ret
= NULL
, *tmp
= g_strdup(str
);
214 char *first_pos
= NULL
, *last_pos
= NULL
;
215 char *previous_pos
= NULL
, *pre_previous_pos
= NULL
;
216 int previous_dot_pos
;
218 if (!strchr(tmp
, ':')) {
220 if (strstr(tmp
, ".cert"))
221 *(strstr(tmp
, ".cert")+1) = '.';
225 while (tmp
&& (tmp
= strstr(tmp
,".")) != NULL
) {
227 pre_previous_pos
= previous_pos
;
228 previous_pos
= last_pos
;
231 previous_dot_pos
= (pre_previous_pos
- first_pos
);
232 if (previous_dot_pos
- 1 > 0)
233 ret
= g_strndup(first_pos
, previous_dot_pos
- 1);
235 ret
= g_strdup(first_pos
);
240 static char *get_port(char *str
)
242 char *ret
= NULL
, *tmp
= g_strdup(str
);
243 char *last_pos
= NULL
;
244 char *previous_pos
= NULL
, *pre_previous_pos
= NULL
;
246 if (!strchr(tmp
, ':')) {
248 if (strstr(tmp
, ".cert"))
249 *(strstr(tmp
, ".cert")+1) = '.';
252 while (tmp
&& (tmp
= strstr(tmp
,".")) != NULL
) {
254 pre_previous_pos
= previous_pos
;
255 previous_pos
= last_pos
;
258 if (previous_pos
&& pre_previous_pos
&& (int)(previous_pos
- pre_previous_pos
- 1) > 0)
259 ret
= g_strndup(pre_previous_pos
, (int)(previous_pos
- pre_previous_pos
- 1));
267 static char *get_fingerprint(char *str
)
269 char *ret
= NULL
, *tmp
= g_strdup(str
);
270 char *previous_pos
= NULL
, *last_pos
= NULL
;
272 if (!strchr(tmp
, ':')) {
274 if (strstr(tmp
, ".cert"))
275 *(strstr(tmp
, ".cert")+1) = '.';
278 while (tmp
&& (tmp
= strstr(tmp
,".")) != NULL
) {
280 previous_pos
= last_pos
;
283 if (last_pos
&& previous_pos
&& (int)(last_pos
- previous_pos
- 1) > 0)
284 ret
= g_strndup(previous_pos
, (int)(last_pos
- previous_pos
- 1));
292 static void ssl_manager_list_view_insert_cert(GtkWidget
*list_view
,
293 GtkTreeIter
*row_iter
,
296 SSLCertificate
*cert
)
299 GtkListStore
*list_store
= GTK_LIST_STORE(gtk_tree_view_get_model
300 (GTK_TREE_VIEW(list_view
)));
302 if (row_iter
== NULL
) {
304 gtk_list_store_append(list_store
, &iter
);
305 gtk_list_store_set(list_store
, &iter
,
306 SSL_MANAGER_HOST
, host
,
307 SSL_MANAGER_PORT
, port
,
308 SSL_MANAGER_CERT
, cert
,
311 gtk_list_store_set(list_store
, row_iter
,
312 SSL_MANAGER_HOST
, host
,
313 SSL_MANAGER_PORT
, port
,
314 SSL_MANAGER_CERT
, cert
,
319 static void ssl_manager_load_certs (void)
327 store
= GTK_LIST_STORE(gtk_tree_view_get_model
328 (GTK_TREE_VIEW(manager
.certlist
)));
330 gtk_list_store_clear(store
);
332 path
= g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S
,
333 "certs", G_DIR_SEPARATOR_S
, NULL
);
335 if((dir
= opendir(path
)) == NULL
) {
340 while ((d
= readdir(dir
)) != NULL
) {
341 gchar
*server
, *port
, *fp
;
342 SSLCertificate
*cert
;
344 if(strstr(d
->d_name
, ".cert") != d
->d_name
+ (strlen(d
->d_name
) - strlen(".cert")))
347 server
= get_server(d
->d_name
);
348 port
= get_port(d
->d_name
);
349 fp
= get_fingerprint(d
->d_name
);
351 cert
= ssl_certificate_find(server
, atoi(port
), fp
);
353 ssl_manager_list_view_insert_cert(manager
.certlist
, NULL
,
365 static void ssl_manager_close(void)
367 gtk_widget_hide(manager
.window
);
370 static void ssl_manager_close_cb(GtkWidget
*widget
,
376 static gboolean
key_pressed(GtkWidget
*widget
, GdkEventKey
*event
, gpointer data
)
378 if (event
&& event
->keyval
== GDK_KEY_Escape
)
383 static void ssl_manager_double_clicked(GtkTreeView
*list_view
,
385 GtkTreeViewColumn
*column
,
388 SSLCertificate
*cert
;
390 GtkTreeModel
*model
= gtk_tree_view_get_model(list_view
);
392 if (!gtk_tree_model_get_iter(model
, &iter
, path
))
395 gtk_tree_model_get(model
, &iter
,
396 SSL_MANAGER_CERT
, &cert
,
402 sslcertwindow_show_cert(cert
);
409 static void ssl_manager_delete_cb(GtkWidget
*widget
,
412 SSLCertificate
*cert
;
417 if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
418 (GTK_TREE_VIEW(manager
.certlist
)),
422 gtk_tree_model_get(model
, &sel
,
423 SSL_MANAGER_CERT
, &cert
,
428 val
= alertpanel_full(_("Delete certificate"),
429 _("Do you really want to delete this certificate?"),
430 GTK_STOCK_CANCEL
, GTK_STOCK_DELETE
, NULL
, FALSE
,
431 NULL
, ALERT_WARNING
, G_ALERTDEFAULT
);
434 if (val
!= G_ALERTALTERNATE
)
437 ssl_certificate_delete_from_disk(cert
);
438 ssl_certificate_destroy(cert
);
439 gtk_list_store_remove(GTK_LIST_STORE(model
), &sel
);
442 static void ssl_manager_view_cb(GtkWidget
*widget
,
445 SSLCertificate
*cert
;
449 if (!gtk_tree_selection_get_selected(gtk_tree_view_get_selection
450 (GTK_TREE_VIEW(manager
.certlist
)),
454 gtk_tree_model_get(model
, &sel
,
455 SSL_MANAGER_CERT
, &cert
,
460 sslcertwindow_show_cert(cert
);