Change Finch to use Pidgin's clientkey/devid when connecting to ICQ.
[pidgin-git.git] / finch / gntcertmgr.c
blob7d97b92f299aea4b0eb4d58226f32548a7074554
1 /**
2 * @file gntcertmgr.c GNT Certificate Manager API
3 * @ingroup finch
4 */
6 /* finch
8 * Finch is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
28 #include <internal.h>
29 #include "finch.h"
31 #include "certificate.h"
32 #include "debug.h"
33 #include "notify.h"
34 #include "request.h"
36 #include "gntcertmgr.h"
38 #include "gntbutton.h"
39 #include "gntlabel.h"
40 #include "gnttree.h"
41 #include "gntutils.h"
42 #include "gntwindow.h"
44 struct {
45 GntWidget *window;
46 GntWidget *tree;
47 PurpleCertificatePool *pool;
48 } certmgr;
50 /* Pretty much Xerox of gtkcertmgr */
52 /* Add certificate */
53 static void
54 tls_peers_mgmt_import_ok2_cb(gpointer data, const char *result)
56 PurpleCertificate *crt = (PurpleCertificate *) data;
57 const char *id = result;
59 /* TODO: Perhaps prompt if you're overwriting a cert? */
61 purple_certificate_pool_store(purple_certificate_find_pool("x509", "tls_peers"), id, crt);
62 purple_certificate_destroy(crt);
65 static void
66 tls_peers_mgmt_import_cancel2_cb(gpointer data, const char *result)
68 PurpleCertificate *crt = (PurpleCertificate *) data;
69 purple_certificate_destroy(crt);
72 static void
73 tls_peers_mgmt_import_ok_cb(gpointer data, const char *filename)
75 PurpleCertificateScheme *x509;
76 PurpleCertificate *crt;
78 x509 = purple_certificate_pool_get_scheme(purple_certificate_find_pool("x509", "tls_peers"));
80 crt = purple_certificate_import(x509, filename);
82 if (crt != NULL) {
83 gchar *default_hostname;
84 default_hostname = purple_certificate_get_subject_name(crt);
85 purple_request_input(NULL,
86 _("Certificate Import"),
87 _("Specify a hostname"),
88 _("Type the host name this certificate is for."),
89 default_hostname, FALSE, FALSE, NULL,
90 _("OK"), G_CALLBACK(tls_peers_mgmt_import_ok2_cb),
91 _("Cancel"), G_CALLBACK(tls_peers_mgmt_import_cancel2_cb),
92 NULL, NULL, NULL,
93 crt);
94 g_free(default_hostname);
95 } else {
96 gchar * secondary;
97 secondary = g_strdup_printf(_("File %s could not be imported.\nMake sure that the file is readable and in PEM format.\n"), filename);
98 purple_notify_error(NULL,
99 _("Certificate Import Error"),
100 _("X.509 certificate import failed"),
101 secondary);
102 g_free(secondary);
106 static void
107 add_cert_cb(GntWidget *button, gpointer null)
109 purple_request_file(NULL,
110 _("Select a PEM certificate"),
111 "certificate.pem",
112 FALSE,
113 G_CALLBACK(tls_peers_mgmt_import_ok_cb),
114 NULL,
115 NULL, NULL, NULL, NULL );
118 /* Save certs in some file */
119 static void
120 tls_peers_mgmt_export_ok_cb(gpointer data, const char *filename)
122 PurpleCertificate *crt = (PurpleCertificate *) data;
124 if (!purple_certificate_export(filename, crt)) {
125 gchar * secondary;
127 secondary = g_strdup_printf(_("Export to file %s failed.\nCheck that you have write permission to the target path\n"), filename);
128 purple_notify_error(NULL,
129 _("Certificate Export Error"),
130 _("X.509 certificate export failed"),
131 secondary);
132 g_free(secondary);
135 purple_certificate_destroy(crt);
138 static void
139 save_cert_cb(GntWidget *button, gpointer null)
141 PurpleCertificate *crt;
142 const char *key;
144 if (!certmgr.window)
145 return;
147 key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree));
148 if (!key)
149 return;
151 crt = purple_certificate_pool_retrieve(certmgr.pool, key);
152 if (!crt) {
153 purple_debug_error("gntcertmgr/tls_peers_mgmt",
154 "Id %s was not in the peers cache?!\n", key);
155 return;
158 purple_request_file((void*)key,
159 _("PEM X.509 Certificate Export"),
160 "certificate.pem", TRUE,
161 G_CALLBACK(tls_peers_mgmt_export_ok_cb),
162 G_CALLBACK(purple_certificate_destroy),
163 NULL, NULL, NULL,
164 crt);
167 /* Show information about a cert */
168 static void
169 info_cert_cb(GntWidget *button, gpointer null)
171 const char *key;
172 PurpleCertificate *crt;
173 gchar *subject;
174 GByteArray *fpr_sha1;
175 gchar *fpr_sha1_asc;
176 gchar *primary, *secondary;
178 if (!certmgr.window)
179 return;
181 key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree));
182 if (!key)
183 return;
185 crt = purple_certificate_pool_retrieve(certmgr.pool, key);
186 g_return_if_fail(crt);
188 primary = g_strdup_printf(_("Certificate for %s"), key);
190 fpr_sha1 = purple_certificate_get_fingerprint_sha1(crt);
191 fpr_sha1_asc = purple_base16_encode_chunked(fpr_sha1->data,
192 fpr_sha1->len);
193 subject = purple_certificate_get_subject_name(crt);
195 secondary = g_strdup_printf(_("Common name: %s\n\nSHA1 fingerprint:\n%s"), subject, fpr_sha1_asc);
197 purple_notify_info(NULL,
198 _("SSL Host Certificate"), primary, secondary);
200 g_free(primary);
201 g_free(secondary);
202 g_byte_array_free(fpr_sha1, TRUE);
203 g_free(fpr_sha1_asc);
204 g_free(subject);
205 purple_certificate_destroy(crt);
208 /* Delete a cert */
209 static void
210 tls_peers_mgmt_delete_confirm_cb(gchar *id, gint dontcare)
212 if (!purple_certificate_pool_delete(certmgr.pool, id)) {
213 purple_debug_warning("gntcertmgr/tls_peers_mgmt",
214 "Deletion failed on id %s\n", id);
217 g_free(id);
220 static void
221 delete_cert_cb(GntWidget *button, gpointer null)
223 gchar *primary;
224 const char *key;
226 if (!certmgr.window)
227 return;
229 key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree));
230 if (!key)
231 return;
233 primary = g_strdup_printf(_("Really delete certificate for %s?"), key);
235 purple_request_close_with_handle((void *)key);
236 purple_request_yes_no((void *)key, _("Confirm certificate delete"),
237 primary, NULL,
239 NULL, NULL, NULL,
240 g_strdup(key),
241 tls_peers_mgmt_delete_confirm_cb,
242 g_free);
244 g_free(primary);
247 /* populate the list */
248 static void
249 populate_cert_list(void)
251 GList *idlist, *l;
253 if (!certmgr.window)
254 return;
256 gnt_tree_remove_all(GNT_TREE(certmgr.tree));
258 idlist = purple_certificate_pool_get_idlist(purple_certificate_find_pool("x509", "tls_peers"));
259 for (l = idlist; l; l = l->next) {
260 gnt_tree_add_row_last(GNT_TREE(certmgr.tree), g_strdup(l->data),
261 gnt_tree_create_row(GNT_TREE(certmgr.tree), l->data), NULL);
263 purple_certificate_pool_destroy_idlist(idlist);
266 static void
267 cert_list_added(PurpleCertificatePool *pool, const char *id, gpointer null)
269 g_return_if_fail(certmgr.window);
270 gnt_tree_add_row_last(GNT_TREE(certmgr.tree), g_strdup(id),
271 gnt_tree_create_row(GNT_TREE(certmgr.tree), id), NULL);
274 static void
275 cert_list_removed(PurpleCertificatePool *pool, const char *id, gpointer null)
277 g_return_if_fail(certmgr.window);
278 purple_request_close_with_handle((void*)id);
279 gnt_tree_remove(GNT_TREE(certmgr.tree), (void*)id);
282 void finch_certmgr_show(void)
284 GntWidget *win, *tree, *box, *button;
285 PurpleCertificatePool *pool;
287 if (certmgr.window) {
288 gnt_window_present(certmgr.window);
289 return;
292 certmgr.window = win = gnt_vwindow_new(FALSE);
293 gnt_box_set_title(GNT_BOX(win), _("Certificate Manager"));
294 gnt_box_set_pad(GNT_BOX(win), 0);
296 certmgr.tree = tree = gnt_tree_new();
297 gnt_tree_set_hash_fns(GNT_TREE(tree), g_str_hash, g_str_equal, g_free);
298 gnt_tree_set_column_title(GNT_TREE(tree), 0, _("Hostname"));
299 gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
301 gnt_box_add_widget(GNT_BOX(win), tree);
303 box = gnt_hbox_new(FALSE);
304 gnt_box_add_widget(GNT_BOX(win), box);
306 button = gnt_button_new(_("Add"));
307 gnt_box_add_widget(GNT_BOX(box), button);
308 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_cert_cb), NULL);
309 gnt_util_set_trigger_widget(GNT_WIDGET(tree), GNT_KEY_INS, button);
311 button = gnt_button_new(_("Save"));
312 gnt_box_add_widget(GNT_BOX(box), button);
313 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(save_cert_cb), NULL);
315 button = gnt_button_new(_("Info"));
316 gnt_box_add_widget(GNT_BOX(box), button);
317 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(info_cert_cb), NULL);
319 button = gnt_button_new(_("Delete"));
320 gnt_box_add_widget(GNT_BOX(box), button);
321 g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(delete_cert_cb), NULL);
322 gnt_util_set_trigger_widget(GNT_WIDGET(tree), GNT_KEY_DEL, button);
324 button = gnt_button_new(_("Close"));
325 gnt_box_add_widget(GNT_BOX(box), button);
326 g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), win);
328 g_signal_connect_swapped(G_OBJECT(win), "destroy", G_CALLBACK(g_nullify_pointer), &certmgr.window);
330 populate_cert_list();
332 pool = certmgr.pool = purple_certificate_find_pool("x509", "tls_peers");
333 purple_signal_connect(pool, "certificate-stored",
334 win, PURPLE_CALLBACK(cert_list_added), NULL);
335 purple_signal_connect(pool, "certificate-deleted",
336 win, PURPLE_CALLBACK(cert_list_removed), NULL);
337 g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(purple_signals_disconnect_by_handle), NULL);
339 gnt_widget_show(certmgr.window);