Mercurial > pidgin
annotate src/protocols/silc/pk.c @ 11807:1f70f265cf27
[gaim-migrate @ 14098]
These files don't seem to be using these includes. What's the
deal with the leaked bonobo objects when using the evolution plugin?
I've also had some crashes caused by the evo plugin that I think
are slightly related.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Tue, 25 Oct 2005 04:24:26 +0000 |
parents | 07dc8c6a359f |
children | e4e47871c373 |
rev | line source |
---|---|
8849 | 1 /* |
2 | |
3 silcgaim_pk.c | |
4 | |
5 Author: Pekka Riikonen <priikone@silcnet.org> | |
6 | |
7 Copyright (C) 2004 Pekka Riikonen | |
8 | |
9 This program is free software; you can redistribute it and/or modify | |
10 it under the terms of the GNU General Public License as published by | |
11 the Free Software Foundation; version 2 of the License. | |
12 | |
13 This program is distributed in the hope that it will be useful, | |
14 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 GNU General Public License for more details. | |
17 | |
18 */ | |
19 | |
20 #include "silcincludes.h" | |
21 #include "silcclient.h" | |
22 #include "silcgaim.h" | |
23 | |
24 /************************* Public Key Verification ***************************/ | |
25 | |
26 typedef struct { | |
27 SilcClient client; | |
28 SilcClientConnection conn; | |
29 char *filename; | |
30 char *entity; | |
31 char *entity_name; | |
32 char *fingerprint; | |
33 char *babbleprint; | |
34 unsigned char *pk; | |
35 SilcUInt32 pk_len; | |
36 SilcSKEPKType pk_type; | |
37 SilcVerifyPublicKey completion; | |
38 void *context; | |
39 gboolean changed; | |
40 } *PublicKeyVerify; | |
41 | |
42 static void silcgaim_verify_ask(const char *entity, | |
43 const char *fingerprint, | |
44 const char *babbleprint, | |
45 PublicKeyVerify verify); | |
46 | |
47 static void silcgaim_verify_cb(PublicKeyVerify verify, gint id) | |
48 { | |
49 if (id != 2) { | |
50 if (verify->completion) | |
51 verify->completion(FALSE, verify->context); | |
52 } else { | |
53 if (verify->completion) | |
54 verify->completion(TRUE, verify->context); | |
55 | |
56 /* Save the key for future checking */ | |
57 silc_pkcs_save_public_key_data(verify->filename, verify->pk, | |
58 verify->pk_len, SILC_PKCS_FILE_PEM); | |
59 } | |
60 | |
61 silc_free(verify->filename); | |
62 silc_free(verify->entity); | |
63 silc_free(verify->entity_name); | |
64 silc_free(verify->fingerprint); | |
65 silc_free(verify->babbleprint); | |
66 silc_free(verify->pk); | |
67 silc_free(verify); | |
68 } | |
69 | |
70 static void silcgaim_verify_details_cb(PublicKeyVerify verify) | |
71 { | |
72 /* What a hack. We have to display the accept dialog _again_ | |
73 because Gaim closes the dialog after you press the button. Gaim | |
74 should have option for the dialogs whether the buttons close them | |
75 or not. */ | |
76 silcgaim_verify_ask(verify->entity, verify->fingerprint, | |
77 verify->babbleprint, verify); | |
78 } | |
79 | |
80 static void silcgaim_verify_details(PublicKeyVerify verify, gint id) | |
81 { | |
82 SilcPublicKey public_key; | |
83 GaimConnection *gc = verify->client->application; | |
84 SilcGaim sg = gc->proto_data; | |
85 | |
86 silc_pkcs_public_key_decode(verify->pk, verify->pk_len, | |
87 &public_key); | |
88 silcgaim_show_public_key(sg, verify->entity_name, public_key, | |
89 G_CALLBACK(silcgaim_verify_details_cb), | |
90 verify); | |
91 silc_pkcs_public_key_free(public_key); | |
92 } | |
93 | |
94 static void silcgaim_verify_ask(const char *entity, | |
95 const char *fingerprint, | |
96 const char *babbleprint, | |
97 PublicKeyVerify verify) | |
98 { | |
99 char tmp[256], tmp2[256]; | |
100 | |
101 if (verify->changed) { | |
102 g_snprintf(tmp, sizeof(tmp), | |
103 _("Received %s's public key. Your local copy does not match this " | |
104 "key. Would you still like to accept this public key?"), | |
105 entity); | |
106 } else { | |
107 g_snprintf(tmp, sizeof(tmp), | |
108 _("Received %s's public key. Would you like to accept this " | |
109 "public key?"), entity); | |
110 } | |
111 g_snprintf(tmp2, sizeof(tmp2), | |
112 _("Fingerprint and babbleprint for the %s key are:\n\n" | |
113 "%s\n%s\n"), entity, fingerprint, babbleprint); | |
114 | |
11201 | 115 gaim_request_action(verify->client->application, _("Verify Public Key"), tmp, tmp2, |
10116 | 116 GAIM_DEFAULT_ACTION_NONE, verify, 3, |
8849 | 117 _("Yes"), G_CALLBACK(silcgaim_verify_cb), |
118 _("No"), G_CALLBACK(silcgaim_verify_cb), | |
119 _("View..."), G_CALLBACK(silcgaim_verify_details)); | |
120 } | |
121 | |
122 void silcgaim_verify_public_key(SilcClient client, SilcClientConnection conn, | |
123 const char *name, SilcSocketType conn_type, | |
124 unsigned char *pk, SilcUInt32 pk_len, | |
125 SilcSKEPKType pk_type, | |
126 SilcVerifyPublicKey completion, void *context) | |
127 { | |
128 GaimConnection *gc = client->application; | |
129 int i; | |
130 char file[256], filename[256], filename2[256], *ipf, *hostf = NULL; | |
131 char *fingerprint, *babbleprint; | |
132 struct passwd *pw; | |
133 struct stat st; | |
134 char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER || | |
135 conn_type == SILC_SOCKET_TYPE_ROUTER) ? | |
136 "server" : "client"); | |
137 PublicKeyVerify verify; | |
138 | |
139 if (pk_type != SILC_SKE_PK_TYPE_SILC) { | |
140 gaim_notify_error(gc, _("Verify Public Key"), | |
141 _("Unsupported public key type"), NULL); | |
142 if (completion) | |
143 completion(FALSE, context); | |
144 return; | |
145 } | |
146 | |
147 pw = getpwuid(getuid()); | |
148 if (!pw) { | |
149 if (completion) | |
150 completion(FALSE, context); | |
151 return; | |
152 } | |
153 | |
154 memset(filename, 0, sizeof(filename)); | |
155 memset(filename2, 0, sizeof(filename2)); | |
156 memset(file, 0, sizeof(file)); | |
157 | |
158 if (conn_type == SILC_SOCKET_TYPE_SERVER || | |
159 conn_type == SILC_SOCKET_TYPE_ROUTER) { | |
160 if (!name) { | |
161 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, | |
162 conn->sock->ip, conn->sock->port); | |
163 g_snprintf(filename, sizeof(filename) - 1, | |
164 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", | |
165 silcgaim_silcdir(), entity, file); | |
166 | |
167 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, | |
168 conn->sock->hostname, conn->sock->port); | |
169 g_snprintf(filename2, sizeof(filename2) - 1, | |
170 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", | |
171 silcgaim_silcdir(), entity, file); | |
172 | |
173 ipf = filename; | |
174 hostf = filename2; | |
175 } else { | |
176 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, | |
177 name, conn->sock->port); | |
178 g_snprintf(filename, sizeof(filename) - 1, | |
179 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", | |
180 silcgaim_silcdir(), entity, file); | |
181 | |
182 ipf = filename; | |
183 } | |
184 } else { | |
185 /* Replace all whitespaces with `_'. */ | |
186 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | |
187 for (i = 0; i < strlen(fingerprint); i++) | |
188 if (fingerprint[i] == ' ') | |
189 fingerprint[i] = '_'; | |
190 | |
191 g_snprintf(file, sizeof(file) - 1, "%skey_%s.pub", entity, fingerprint); | |
192 g_snprintf(filename, sizeof(filename) - 1, | |
193 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", | |
194 silcgaim_silcdir(), entity, file); | |
195 silc_free(fingerprint); | |
196 | |
197 ipf = filename; | |
198 } | |
199 | |
200 verify = silc_calloc(1, sizeof(*verify)); | |
201 if (!verify) | |
202 return; | |
203 verify->client = client; | |
204 verify->conn = conn; | |
205 verify->filename = strdup(ipf); | |
206 verify->entity = strdup(entity); | |
207 verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ? | |
208 (name ? strdup(name) : strdup(conn->sock->hostname)) | |
209 : NULL); | |
210 verify->pk = silc_memdup(pk, pk_len); | |
211 verify->pk_len = pk_len; | |
212 verify->pk_type = pk_type; | |
213 verify->completion = completion; | |
214 verify->context = context; | |
215 fingerprint = verify->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | |
216 babbleprint = verify->babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); | |
217 | |
218 /* Check whether this key already exists */ | |
10589
0f7452b1f777
[gaim-migrate @ 11994]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
10116
diff
changeset
|
219 if (g_stat(ipf, &st) < 0 && (!hostf || g_stat(hostf, &st) < 0)) { |
8849 | 220 /* Key does not exist, ask user to verify the key and save it */ |
221 silcgaim_verify_ask(name ? name : entity, | |
222 fingerprint, babbleprint, verify); | |
223 return; | |
224 } else { | |
225 /* The key already exists, verify it. */ | |
226 SilcPublicKey public_key; | |
227 unsigned char *encpk; | |
228 SilcUInt32 encpk_len; | |
229 | |
230 /* Load the key file, try for both IP filename and hostname filename */ | |
231 if (!silc_pkcs_load_public_key(ipf, &public_key, | |
232 SILC_PKCS_FILE_PEM) && | |
233 !silc_pkcs_load_public_key(ipf, &public_key, | |
234 SILC_PKCS_FILE_BIN) && | |
235 (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key, | |
236 SILC_PKCS_FILE_PEM) && | |
237 !silc_pkcs_load_public_key(hostf, &public_key, | |
238 SILC_PKCS_FILE_BIN)))) { | |
239 silcgaim_verify_ask(name ? name : entity, | |
240 fingerprint, babbleprint, verify); | |
241 return; | |
242 } | |
243 | |
244 /* Encode the key data */ | |
245 encpk = silc_pkcs_public_key_encode(public_key, &encpk_len); | |
246 if (!encpk) { | |
247 silcgaim_verify_ask(name ? name : entity, | |
248 fingerprint, babbleprint, verify); | |
249 return; | |
250 } | |
251 | |
252 /* Compare the keys */ | |
253 if (memcmp(encpk, pk, encpk_len)) { | |
254 /* Ask user to verify the key and save it */ | |
255 verify->changed = TRUE; | |
256 silcgaim_verify_ask(name ? name : entity, | |
257 fingerprint, babbleprint, verify); | |
258 return; | |
259 } | |
260 | |
261 /* Local copy matched */ | |
262 if (completion) | |
263 completion(TRUE, context); | |
264 silc_free(verify->filename); | |
265 silc_free(verify->entity); | |
266 silc_free(verify->entity_name); | |
267 silc_free(verify->pk); | |
268 silc_free(verify->fingerprint); | |
269 silc_free(verify->babbleprint); | |
270 silc_free(verify); | |
271 } | |
272 } |