Mercurial > pidgin
comparison finch/gntcertmgr.c @ 19516:e1751162ab1f
Add certificate UI in finch.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Wed, 29 Aug 2007 05:18:39 +0000 |
parents | |
children | b7fa8fa4de5b |
comparison
equal
deleted
inserted
replaced
19515:b62683f4120d | 19516:e1751162ab1f |
---|---|
1 /** | |
2 * @file gntcertmgr.c GNT Certificate Manager API | |
3 * @ingroup finch | |
4 * | |
5 * finch | |
6 * | |
7 * Finch is the legal property of its developers, whose names are too numerous | |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
10 * | |
11 * This program is free software; you can redistribute it and/or modify | |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 * | |
25 */ | |
26 | |
27 #include "certificate.h" | |
28 #include "debug.h" | |
29 #include "notify.h" | |
30 #include "request.h" | |
31 | |
32 #include "finch.h" | |
33 #include "gntcertmgr.h" | |
34 | |
35 #include "gntbutton.h" | |
36 #include "gntlabel.h" | |
37 #include "gnttree.h" | |
38 #include "gntutils.h" | |
39 #include "gntwindow.h" | |
40 | |
41 struct { | |
42 GntWidget *window; | |
43 GntWidget *tree; | |
44 PurpleCertificatePool *pool; | |
45 } certmgr; | |
46 | |
47 /* Pretty much Xerox of gtkcertmgr */ | |
48 | |
49 /* Add certificate */ | |
50 static void | |
51 tls_peers_mgmt_import_ok2_cb(gpointer data, const char *result) | |
52 { | |
53 PurpleCertificate *crt = (PurpleCertificate *) data; | |
54 const char *id = result; | |
55 | |
56 /* TODO: Perhaps prompt if you're overwriting a cert? */ | |
57 | |
58 purple_certificate_pool_store(purple_certificate_find_pool("x509", "tls_peers"), id, crt); | |
59 purple_certificate_destroy(crt); | |
60 } | |
61 | |
62 static void | |
63 tls_peers_mgmt_import_cancel2_cb(gpointer data, const char *result) | |
64 { | |
65 PurpleCertificate *crt = (PurpleCertificate *) data; | |
66 purple_certificate_destroy(crt); | |
67 } | |
68 | |
69 static void | |
70 tls_peers_mgmt_import_ok_cb(gpointer data, const char *filename) | |
71 { | |
72 PurpleCertificateScheme *x509; | |
73 PurpleCertificate *crt; | |
74 | |
75 x509 = purple_certificate_pool_get_scheme(purple_certificate_find_pool("x509", "tls_peers")); | |
76 | |
77 crt = purple_certificate_import(x509, filename); | |
78 | |
79 if (crt != NULL) { | |
80 gchar *default_hostname; | |
81 default_hostname = purple_certificate_get_subject_name(crt); | |
82 purple_request_input(NULL, | |
83 _("Certificate Import"), | |
84 _("Specify a hostname"), | |
85 _("Type the host name this certificate is for."), | |
86 default_hostname, FALSE, FALSE, NULL, | |
87 _("OK"), G_CALLBACK(tls_peers_mgmt_import_ok2_cb), | |
88 _("Cancel"), G_CALLBACK(tls_peers_mgmt_import_cancel2_cb), | |
89 NULL, NULL, NULL, | |
90 crt); | |
91 g_free(default_hostname); | |
92 } else { | |
93 gchar * secondary; | |
94 secondary = g_strdup_printf(_("File %s could not be imported.\nMake sure that the file is readable and in PEM format.\n"), filename); | |
95 purple_notify_error(NULL, | |
96 _("Certificate Import Error"), | |
97 _("X.509 certificate import failed"), | |
98 secondary); | |
99 g_free(secondary); | |
100 } | |
101 } | |
102 | |
103 static void | |
104 add_cert_cb(GntWidget *button, gpointer null) | |
105 { | |
106 purple_request_file(NULL, | |
107 _("Select a PEM certificate"), | |
108 "certificate.pem", | |
109 FALSE, | |
110 G_CALLBACK(tls_peers_mgmt_import_ok_cb), | |
111 NULL, | |
112 NULL, NULL, NULL, NULL ); | |
113 } | |
114 | |
115 /* Save certs in some file */ | |
116 static void | |
117 tls_peers_mgmt_export_ok_cb(gpointer data, const char *filename) | |
118 { | |
119 PurpleCertificate *crt = (PurpleCertificate *) data; | |
120 | |
121 if (!purple_certificate_export(filename, crt)) { | |
122 gchar * secondary; | |
123 | |
124 secondary = g_strdup_printf(_("Export to file %s failed.\nCheck that you have write permission to the target path\n"), filename); | |
125 purple_notify_error(NULL, | |
126 _("Certificate Export Error"), | |
127 _("X.509 certificate export failed"), | |
128 secondary); | |
129 g_free(secondary); | |
130 } | |
131 | |
132 purple_certificate_destroy(crt); | |
133 } | |
134 | |
135 static void | |
136 save_cert_cb(GntWidget *button, gpointer null) | |
137 { | |
138 PurpleCertificate *crt; | |
139 const char *key; | |
140 | |
141 if (!certmgr.window) | |
142 return; | |
143 | |
144 key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree)); | |
145 if (!key) | |
146 return; | |
147 | |
148 crt = purple_certificate_pool_retrieve(certmgr.pool, key); | |
149 if (!crt) { | |
150 purple_debug_error("gntcertmgr/tls_peers_mgmt", | |
151 "Id %s was not in the peers cache?!\n", key); | |
152 return; | |
153 } | |
154 | |
155 purple_request_file((void*)key, | |
156 _("PEM X.509 Certificate Export"), | |
157 "certificate.pem", TRUE, | |
158 G_CALLBACK(tls_peers_mgmt_export_ok_cb), | |
159 G_CALLBACK(purple_certificate_destroy), | |
160 NULL, NULL, NULL, | |
161 crt); | |
162 } | |
163 | |
164 /* Show information about a cert */ | |
165 static void | |
166 info_cert_cb(GntWidget *button, gpointer null) | |
167 { | |
168 const char *key; | |
169 PurpleCertificate *crt; | |
170 gchar *subject; | |
171 GByteArray *fpr_sha1; | |
172 gchar *fpr_sha1_asc; | |
173 gchar *primary, *secondary; | |
174 | |
175 if (!certmgr.window) | |
176 return; | |
177 | |
178 key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree)); | |
179 if (!key) | |
180 return; | |
181 | |
182 crt = purple_certificate_pool_retrieve(certmgr.pool, key); | |
183 g_return_if_fail(crt); | |
184 | |
185 primary = g_strdup_printf(_("Certificate for %s"), key); | |
186 | |
187 fpr_sha1 = purple_certificate_get_fingerprint_sha1(crt); | |
188 fpr_sha1_asc = purple_base16_encode_chunked(fpr_sha1->data, | |
189 fpr_sha1->len); | |
190 subject = purple_certificate_get_subject_name(crt); | |
191 | |
192 secondary = g_strdup_printf(_("Common name: %s\n\nSHA1 fingerprint:\n%s"), subject, fpr_sha1_asc); | |
193 | |
194 purple_notify_info(NULL, | |
195 _("SSL Host Certificate"), primary, secondary); | |
196 | |
197 g_free(primary); | |
198 g_free(secondary); | |
199 g_byte_array_free(fpr_sha1, TRUE); | |
200 g_free(fpr_sha1_asc); | |
201 g_free(subject); | |
202 purple_certificate_destroy(crt); | |
203 } | |
204 | |
205 /* Delete a cert */ | |
206 static void | |
207 tls_peers_mgmt_delete_confirm_cb(gchar *id, gint dontcare) | |
208 { | |
209 if (!purple_certificate_pool_delete(certmgr.pool, id)) { | |
210 purple_debug_warning("gntcertmgr/tls_peers_mgmt", | |
211 "Deletion failed on id %s\n", id); | |
212 }; | |
213 | |
214 g_free(id); | |
215 } | |
216 | |
217 static void | |
218 delete_cert_cb(GntWidget *button, gpointer null) | |
219 { | |
220 gchar *primary; | |
221 const char *key; | |
222 | |
223 if (!certmgr.window) | |
224 return; | |
225 | |
226 key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree)); | |
227 if (!key) | |
228 return; | |
229 | |
230 primary = g_strdup_printf(_("Really delete certificate for %s?"), key); | |
231 | |
232 purple_request_close_with_handle((void *)key); | |
233 purple_request_yes_no((void *)key, _("Confirm certificate delete"), | |
234 primary, NULL, | |
235 2, | |
236 NULL, NULL, NULL, | |
237 g_strdup(key), | |
238 tls_peers_mgmt_delete_confirm_cb, | |
239 g_free); | |
240 | |
241 g_free(primary); | |
242 } | |
243 | |
244 /* populate the list */ | |
245 static void | |
246 populate_cert_list() | |
247 { | |
248 GList *idlist, *l; | |
249 | |
250 if (!certmgr.window) | |
251 return; | |
252 | |
253 gnt_tree_remove_all(GNT_TREE(certmgr.tree)); | |
254 | |
255 idlist = purple_certificate_pool_get_idlist(purple_certificate_find_pool("x509", "tls_peers")); | |
256 for (l = idlist; l; l = l->next) { | |
257 gnt_tree_add_row_last(GNT_TREE(certmgr.tree), g_strdup(l->data), | |
258 gnt_tree_create_row(GNT_TREE(certmgr.tree), l->data), NULL); | |
259 } | |
260 purple_certificate_pool_destroy_idlist(idlist); | |
261 } | |
262 | |
263 static void | |
264 cert_list_added(PurpleCertificatePool *pool, const char *id, gpointer null) | |
265 { | |
266 g_return_if_fail(certmgr.window); | |
267 gnt_tree_add_row_last(GNT_TREE(certmgr.tree), g_strdup(id), | |
268 gnt_tree_create_row(GNT_TREE(certmgr.tree), id), NULL); | |
269 } | |
270 | |
271 static void | |
272 cert_list_removed(PurpleCertificatePool *pool, const char *id, gpointer null) | |
273 { | |
274 g_return_if_fail(certmgr.window); | |
275 purple_request_close_with_handle((void*)id); | |
276 gnt_tree_remove(GNT_TREE(certmgr.tree), (void*)id); | |
277 } | |
278 | |
279 void finch_certmgr_show(void) | |
280 { | |
281 GntWidget *win, *tree, *box, *button; | |
282 PurpleCertificatePool *pool; | |
283 | |
284 if (certmgr.window) { | |
285 gnt_window_present(certmgr.window); | |
286 return; | |
287 } | |
288 | |
289 certmgr.window = win = gnt_vwindow_new(FALSE); | |
290 gnt_box_set_title(GNT_BOX(win), _("Certificate Manager")); | |
291 gnt_box_set_pad(GNT_BOX(win), 0); | |
292 | |
293 certmgr.tree = tree = gnt_tree_new(); | |
294 gnt_tree_set_hash_fns(GNT_TREE(tree), g_str_hash, g_str_equal, g_free); | |
295 gnt_tree_set_column_title(GNT_TREE(tree), 0, _("Hostname")); | |
296 gnt_tree_set_show_title(GNT_TREE(tree), TRUE); | |
297 | |
298 gnt_box_add_widget(GNT_BOX(win), tree); | |
299 | |
300 box = gnt_hbox_new(FALSE); | |
301 gnt_box_add_widget(GNT_BOX(win), box); | |
302 | |
303 button = gnt_button_new(_("Add")); | |
304 gnt_box_add_widget(GNT_BOX(box), button); | |
305 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_cert_cb), NULL); | |
306 gnt_util_set_trigger_widget(GNT_WIDGET(tree), GNT_KEY_INS, button); | |
307 | |
308 button = gnt_button_new(_("Save")); | |
309 gnt_box_add_widget(GNT_BOX(box), button); | |
310 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(save_cert_cb), NULL); | |
311 | |
312 button = gnt_button_new(_("Info")); | |
313 gnt_box_add_widget(GNT_BOX(box), button); | |
314 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(info_cert_cb), NULL); | |
315 | |
316 button = gnt_button_new(_("Delete")); | |
317 gnt_box_add_widget(GNT_BOX(box), button); | |
318 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(delete_cert_cb), NULL); | |
319 gnt_util_set_trigger_widget(GNT_WIDGET(tree), GNT_KEY_DEL, button); | |
320 | |
321 button = gnt_button_new(_("Close")); | |
322 gnt_box_add_widget(GNT_BOX(box), button); | |
323 g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), win); | |
324 | |
325 g_signal_connect_swapped(G_OBJECT(win), "destroy", G_CALLBACK(g_nullify_pointer), &certmgr.window); | |
326 | |
327 populate_cert_list(); | |
328 | |
329 pool = certmgr.pool = purple_certificate_find_pool("x509", "tls_peers"); | |
330 purple_signal_connect(pool, "certificate-stored", | |
331 win, PURPLE_CALLBACK(cert_list_added), NULL); | |
332 purple_signal_connect(pool, "certificate-deleted", | |
333 win, PURPLE_CALLBACK(cert_list_removed), NULL); | |
334 g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(purple_signals_disconnect_by_handle), NULL); | |
335 | |
336 gnt_widget_show(certmgr.window); | |
337 } | |
338 |