1 /*  Key acceptance UI bits                                                */
2 /*             Copyright (C) 2001-2003 William Tompkins                   */
3 
4 /* This plugin is free software, distributed under the GNU General Public */
5 /* License.                                                               */
6 /* Please see the file "COPYING" distributed with this source code        */
7 /* for more details                                                       */
8 /*                                                                        */
9 /*                                                                        */
10 /*    This software 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 GNU    */
13 /*   General Public License for more details.                             */
14 
15 /*   To compile and use:                                                  */
16 /*     See INSTALL file.                                                  */
17 
18 #include "internal.h"
19 
20 #include <gdk/gdk.h>
21 #include <gtk/gtk.h>
22 #include <gtk/gtkplug.h>
23 
24 #include <debug.h>
25 #include <prefs.h>
26 #include <gtkdialogs.h>
27 #include <sound.h>
28 
29 #include "encrypt.h"
30 #include "keys.h"
31 #include "prefs.h"
32 #include "keys_ui.h"
33 #include "nls.h"
34 
35 #ifdef _WIN32
36 #include "win32dep.h"
37 #endif
38 
39 typedef struct accept_key_ui {
40    GtkWidget *window;
41    key_ring_data *ring_data;
42    gchar* resend_msg_id;
43 } accept_key_ui;
44 
45 
destroy_callback(GtkWidget * widget,gpointer ginstance)46 static void destroy_callback(GtkWidget* widget, gpointer ginstance) {
47    accept_key_ui *instance = (accept_key_ui*)ginstance;
48 
49    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "enter destroy_callback\n");
50 
51    g_free(instance->resend_msg_id);
52    gtk_widget_destroy(instance->window);
53    g_free(instance);
54    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "leaving destroy_callback\n");
55 }
56 
reject_key_callback(GtkWidget * widget,gpointer ginstance)57 static void reject_key_callback(GtkWidget* widget, gpointer ginstance) {
58    accept_key_ui *instance = (accept_key_ui*)ginstance;
59 
60    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "enter reject_callback\n");
61    gtk_widget_destroy(instance->window);
62    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "leaving reject_callback\n");
63 }
64 
accept_key_callback(GtkWidget * widget,gpointer ginstance)65 static void accept_key_callback(GtkWidget* widget, gpointer ginstance) {
66    accept_key_ui *instance = (accept_key_ui*)ginstance;
67 
68    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "enter accept_callback\n");
69    PE_buddy_ring = PE_add_key_to_ring(PE_buddy_ring, instance->ring_data);
70 
71    PE_send_stored_msgs(instance->ring_data->account, instance->ring_data->name);
72    PE_show_stored_msgs(instance->ring_data->account, instance->ring_data->name);
73    if (instance->resend_msg_id) {
74       PE_resend_msg(instance->ring_data->account, instance->ring_data->name, instance->resend_msg_id);
75    }
76    instance->ring_data = 0;
77 
78    gtk_widget_destroy(instance->window);
79    /* reject_key_callback will now be called since we called destroy on the window */
80 
81    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "exit accept_callback\n");
82 }
83 
save_key_callback(GtkWidget * widget,gpointer ginstance)84 static void save_key_callback(GtkWidget* widget, gpointer ginstance) {
85    accept_key_ui *instance = (accept_key_ui*)ginstance;
86 
87    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "enter save_callback\n");
88    PE_add_key_to_file(Buddy_key_file, instance->ring_data);
89    accept_key_callback(widget, ginstance);
90    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "exit save_callback\n");
91 }
92 
93 
PE_choose_accept_unknown_key(key_ring_data * newkey,gchar * resend_msg_id,PurpleConversation * conv)94 void PE_choose_accept_unknown_key(key_ring_data* newkey, gchar* resend_msg_id, PurpleConversation *conv) {
95    GtkWidget *win;
96    GtkWidget *vbox, *hbox;
97    GtkWidget *button;
98    GtkWidget *label;
99    char strbuf[4096];
100    accept_key_ui *this_instance;
101 
102    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "enter choose_accept_unknown\n");
103    /* First look at the prefs...  */
104    if (purple_prefs_get_bool("/plugins/gtk/encrypt/accept_unknown_key")) {
105       PE_add_key_to_file(Buddy_key_file, newkey);
106       PE_buddy_ring = PE_add_key_to_ring(PE_buddy_ring, newkey);
107       PE_send_stored_msgs(newkey->account, newkey->name);
108       PE_show_stored_msgs(newkey->account, newkey->name);
109       if (resend_msg_id) {
110          PE_resend_msg(newkey->account, newkey->name, resend_msg_id);
111       }
112       return;
113    }
114 
115    /* Need to ask the user... */
116 
117    if (conv) {
118       purple_sound_play_event(PURPLE_SOUND_RECEIVE, purple_conversation_get_account(conv));
119    }
120 
121    this_instance = g_malloc(sizeof(accept_key_ui));
122    PIDGIN_DIALOG(win);
123    this_instance->window = win;
124    this_instance->ring_data = newkey;
125    this_instance->resend_msg_id = g_strdup(resend_msg_id);
126 
127    gtk_window_set_title(GTK_WINDOW(win), _("Pidgin-Encryption Key Received"));
128    g_signal_connect(GTK_OBJECT(win), "destroy",
129                     GTK_SIGNAL_FUNC(destroy_callback),
130                     (gpointer)this_instance);
131 
132    vbox = gtk_vbox_new(0, 2);
133    gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
134    gtk_container_add(GTK_CONTAINER(win), vbox);
135    gtk_widget_show (vbox);
136 
137    g_snprintf(strbuf, sizeof(strbuf), _("%s key received for '%s'"),
138               newkey->key->proto->name, newkey->name);
139    label = gtk_label_new(strbuf);
140    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
141    gtk_widget_set_size_request(label, -1, 30);
142    gtk_widget_show(label);
143 
144    g_snprintf(strbuf, sizeof(strbuf), _("Key Fingerprint:%*s"),
145               KEY_FINGERPRINT_LENGTH, newkey->key->fingerprint);
146    label = gtk_label_new(strbuf);
147    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
148    gtk_widget_set_size_request(label, -1, 30);
149    gtk_widget_show(label);
150 
151    g_snprintf(strbuf, sizeof(strbuf), _("Do you want to accept this key?"));
152    label = gtk_label_new(strbuf);
153    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
154    gtk_widget_set_size_request(label, -1, 30);
155    gtk_widget_show(label);
156 
157    hbox = gtk_hbox_new(FALSE, 2);
158    gtk_box_pack_end(GTK_BOX(vbox), hbox, 0, 0, 0);
159    gtk_widget_show(hbox);
160 
161    button = gtk_button_new_with_label(_("No"));
162    g_signal_connect(GTK_OBJECT(button), "clicked",
163                     GTK_SIGNAL_FUNC(reject_key_callback),
164                     (gpointer)this_instance);
165    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
166    gtk_widget_set_size_request(button, 100, -1);
167    gtk_widget_show(button);
168 
169    button = gtk_button_new_with_label(_("Accept and Save"));
170    g_signal_connect(GTK_OBJECT(button), "clicked",
171                     GTK_SIGNAL_FUNC(save_key_callback),
172                     (gpointer)this_instance);
173    gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
174    gtk_widget_set_size_request(button, 120, -1);
175    gtk_widget_show(button);
176 
177    button = gtk_button_new_with_label(_("This session only"));
178    g_signal_connect(GTK_OBJECT(button), "clicked",
179                     GTK_SIGNAL_FUNC(accept_key_callback),
180                     (gpointer)this_instance);
181    gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
182    gtk_widget_set_size_request(button, 130, -1);
183    gtk_widget_show(button);
184 
185    gtk_widget_show(win);
186 
187    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "exit choose_accept_unknown\n");
188 }
189 
190 
PE_choose_accept_conflict_key(key_ring_data * newkey,gchar * resend_msg_id,PurpleConversation * conv)191 void PE_choose_accept_conflict_key(key_ring_data* newkey, gchar* resend_msg_id, PurpleConversation *conv) {
192    GtkWidget *win;
193    GtkWidget *vbox, *hbox;
194    GtkWidget *button;
195    GtkWidget *label;
196    char strbuf[4096];
197    accept_key_ui *this_instance;
198 
199    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "enter choose_accept_conflict\n");
200    /* First look at the prefs...  */
201    if (purple_prefs_get_bool("/plugins/gtk/encrypt/accept_conflicting_key")) {
202       PE_add_key_to_file(Buddy_key_file, newkey);
203       PE_buddy_ring = PE_add_key_to_ring(PE_buddy_ring, newkey);
204       PE_send_stored_msgs(newkey->account, newkey->name);
205       PE_show_stored_msgs(newkey->account, newkey->name);
206       if (resend_msg_id) {
207          PE_resend_msg(newkey->account, newkey->name, resend_msg_id);
208       }
209       return;
210    }
211 
212    /* Need to ask the user... */
213 
214    if (conv) {
215       purple_sound_play_event(PURPLE_SOUND_RECEIVE, purple_conversation_get_account(conv));
216    }
217 
218    this_instance = g_malloc(sizeof(accept_key_ui));
219    PIDGIN_DIALOG(win);
220    this_instance->window = win;
221    this_instance->ring_data = newkey;
222    this_instance->resend_msg_id = g_strdup(resend_msg_id);
223 
224    gtk_window_set_title(GTK_WINDOW(win), _("CONFLICTING Pidgin-Encryption Key Received"));
225    g_signal_connect(GTK_OBJECT(win), "destroy",
226                     GTK_SIGNAL_FUNC(destroy_callback),
227                     (gpointer)this_instance);
228 
229    vbox = gtk_vbox_new(0, 2);
230    gtk_container_set_border_width(GTK_CONTAINER(vbox), 4);
231    gtk_container_add(GTK_CONTAINER(win), vbox);
232    gtk_widget_show (vbox);
233 
234    label = gtk_label_new(_(" ******* WARNING ******* "));
235    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
236    gtk_widget_set_size_request(label, -1, 30);
237    gtk_widget_show(label);
238 
239    g_snprintf(strbuf, sizeof(strbuf), _("CONFLICTING %s key received for '%s'!"),
240               newkey->key->proto->name, newkey->name);
241    label = gtk_label_new(strbuf);
242    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
243    gtk_widget_set_size_request(label, -1, 30);
244    gtk_widget_show(label);
245 
246    g_snprintf(strbuf, sizeof(strbuf), _("Key Fingerprint:%*s"),
247               KEY_FINGERPRINT_LENGTH, newkey->key->fingerprint);
248    label = gtk_label_new(strbuf);
249    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
250    gtk_widget_set_size_request(label, -1, 30);
251    gtk_widget_show(label);
252 
253    label = gtk_label_new(_(" ******* WARNING ******* "));
254    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
255    gtk_widget_set_size_request(label, -1, 30);
256    gtk_widget_show(label);
257 
258    label = gtk_label_new(_("This could be a man-in-the-middle attack, or\n"
259                            "could be someone impersonating your buddy.\n"
260                            "You should check with your buddy to see if they have\n"
261                            "generated this new key before trusting it."));
262    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
263    //   gtk_widget_set_size_request(label, -1, 30);
264    gtk_widget_show(label);
265 
266    g_snprintf(strbuf, sizeof(strbuf), _("Do you want to accept this key?"));
267    label = gtk_label_new(strbuf);
268    gtk_box_pack_start(GTK_BOX(vbox), label, 0, 0, 0);
269    gtk_widget_set_size_request(label, -1, 30);
270    gtk_widget_show(label);
271 
272    hbox = gtk_hbox_new(FALSE, 2);
273    gtk_box_pack_end(GTK_BOX(vbox), hbox, 0, 0, 0);
274    gtk_widget_show(hbox);
275 
276    button = gtk_button_new_with_label(_("No"));
277    g_signal_connect(GTK_OBJECT(button), "clicked",
278                       GTK_SIGNAL_FUNC(reject_key_callback),
279                       (gpointer)this_instance);
280    gtk_box_pack_start(GTK_BOX(hbox), button, 0, 0, 0);
281    gtk_widget_set_size_request(button, 100, -1);
282    gtk_widget_show(button);
283 
284    button = gtk_button_new_with_label(_("Accept and Save"));
285    g_signal_connect(GTK_OBJECT(button), "clicked",
286                       GTK_SIGNAL_FUNC(save_key_callback),
287                       (gpointer)this_instance);
288    gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
289    gtk_widget_set_size_request(button, 120, -1);
290    gtk_widget_show(button);
291 
292    button = gtk_button_new_with_label(_("This session only"));
293    g_signal_connect(GTK_OBJECT(button), "clicked",
294                     GTK_SIGNAL_FUNC(accept_key_callback),
295                     (gpointer)this_instance);
296    gtk_box_pack_end(GTK_BOX(hbox), button, 0, 0, 0);
297    gtk_widget_set_size_request(button, 130, -1);
298    gtk_widget_show(button);
299 
300    gtk_widget_show(win);
301 
302    purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "enter choose_accept_conflict\n");
303 }
304 
305 
306