Mercurial > pidgin
comparison libpurple/protocols/silc/pk.c @ 17568:980a104267da
Patch from Pekka Riikonen to update the SILC protocol plugin to work with
SILC Toolkit 1.1
I added the fallback to SILC Toolkit 1.0 support (silc10 protocol
directory) and configure.ac adjustments, any problems with this are 100%
my fault.
author | Stu Tomlinson <stu@nosnilmot.com> |
---|---|
date | Sat, 09 Jun 2007 17:31:28 +0000 |
parents | a5176db228b7 |
children | 285bb637a2b7 6b02dba5bf41 |
comparison
equal
deleted
inserted
replaced
17567:ba1b50f114f6 | 17568:980a104267da |
---|---|
2 | 2 |
3 silcpurple_pk.c | 3 silcpurple_pk.c |
4 | 4 |
5 Author: Pekka Riikonen <priikone@silcnet.org> | 5 Author: Pekka Riikonen <priikone@silcnet.org> |
6 | 6 |
7 Copyright (C) 2004 Pekka Riikonen | 7 Copyright (C) 2004 - 2007 Pekka Riikonen |
8 | 8 |
9 This program is free software; you can redistribute it and/or modify | 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 | 10 it under the terms of the GNU General Public License as published by |
11 the Free Software Foundation; version 2 of the License. | 11 the Free Software Foundation; version 2 of the License. |
12 | 12 |
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 GNU General Public License for more details. | 16 GNU General Public License for more details. |
17 | 17 |
18 */ | 18 */ |
19 | 19 |
20 #include "silcincludes.h" | 20 #include "silc.h" |
21 #include "silcclient.h" | 21 #include "silcclient.h" |
22 #include "silcpurple.h" | 22 #include "silcpurple.h" |
23 | 23 |
24 /************************* Public Key Verification ***************************/ | 24 /************************* Public Key Verification ***************************/ |
25 | 25 |
29 char *filename; | 29 char *filename; |
30 char *entity; | 30 char *entity; |
31 char *entity_name; | 31 char *entity_name; |
32 char *fingerprint; | 32 char *fingerprint; |
33 char *babbleprint; | 33 char *babbleprint; |
34 unsigned char *pk; | 34 SilcPublicKey public_key; |
35 SilcUInt32 pk_len; | |
36 SilcSKEPKType pk_type; | |
37 SilcVerifyPublicKey completion; | 35 SilcVerifyPublicKey completion; |
38 void *context; | 36 void *context; |
39 gboolean changed; | 37 gboolean changed; |
40 } *PublicKeyVerify; | 38 } *PublicKeyVerify; |
41 | 39 |
42 static void silcpurple_verify_ask(const char *entity, | 40 static void silcpurple_verify_ask(const char *entity, |
43 const char *fingerprint, | 41 const char *fingerprint, |
44 const char *babbleprint, | 42 const char *babbleprint, |
45 PublicKeyVerify verify); | 43 PublicKeyVerify verify); |
46 | 44 |
47 static void silcpurple_verify_cb(PublicKeyVerify verify, gint id) | 45 static void silcpurple_verify_cb(PublicKeyVerify verify, gint id) |
48 { | 46 { |
49 if (id != 2) { | 47 if (id != 2) { |
50 if (verify->completion) | 48 if (verify->completion) |
52 } else { | 50 } else { |
53 if (verify->completion) | 51 if (verify->completion) |
54 verify->completion(TRUE, verify->context); | 52 verify->completion(TRUE, verify->context); |
55 | 53 |
56 /* Save the key for future checking */ | 54 /* Save the key for future checking */ |
57 silc_pkcs_save_public_key_data(verify->filename, verify->pk, | 55 silc_pkcs_save_public_key(verify->filename, verify->public_key, |
58 verify->pk_len, SILC_PKCS_FILE_PEM); | 56 SILC_PKCS_FILE_BASE64); |
59 } | 57 } |
60 | 58 |
61 silc_free(verify->filename); | 59 silc_free(verify->filename); |
62 silc_free(verify->entity); | 60 silc_free(verify->entity); |
63 silc_free(verify->entity_name); | 61 silc_free(verify->entity_name); |
64 silc_free(verify->fingerprint); | 62 silc_free(verify->fingerprint); |
65 silc_free(verify->babbleprint); | 63 silc_free(verify->babbleprint); |
66 silc_free(verify->pk); | 64 silc_pkcs_public_key_free(verify->public_key); |
67 silc_free(verify); | 65 silc_free(verify); |
68 } | 66 } |
69 | 67 |
70 static void silcpurple_verify_details_cb(PublicKeyVerify verify) | 68 static void silcpurple_verify_details_cb(PublicKeyVerify verify) |
71 { | 69 { |
72 /* What a hack. We have to display the accept dialog _again_ | 70 /* What a hack. We have to display the accept dialog _again_ |
73 because Purple closes the dialog after you press the button. Purple | 71 because Purple closes the dialog after you press the button. Purple |
74 should have option for the dialogs whether the buttons close them | 72 should have option for the dialogs whether the buttons close them |
75 or not. */ | 73 or not. */ |
76 silcpurple_verify_ask(verify->entity, verify->fingerprint, | 74 silcpurple_verify_ask(verify->entity, verify->fingerprint, |
77 verify->babbleprint, verify); | 75 verify->babbleprint, verify); |
78 } | 76 } |
79 | 77 |
80 static void silcpurple_verify_details(PublicKeyVerify verify, gint id) | 78 static void silcpurple_verify_details(PublicKeyVerify verify, gint id) |
81 { | 79 { |
82 SilcPublicKey public_key; | |
83 PurpleConnection *gc = verify->client->application; | 80 PurpleConnection *gc = verify->client->application; |
84 SilcPurple sg = gc->proto_data; | 81 SilcPurple sg = gc->proto_data; |
85 | 82 |
86 silc_pkcs_public_key_decode(verify->pk, verify->pk_len, | 83 silcpurple_show_public_key(sg, verify->entity_name, verify->public_key, |
87 &public_key); | 84 G_CALLBACK(silcpurple_verify_details_cb), |
88 silcpurple_show_public_key(sg, verify->entity_name, public_key, | 85 verify); |
89 G_CALLBACK(silcpurple_verify_details_cb), | |
90 verify); | |
91 silc_pkcs_public_key_free(public_key); | |
92 } | 86 } |
93 | 87 |
94 static void silcpurple_verify_ask(const char *entity, | 88 static void silcpurple_verify_ask(const char *entity, |
95 const char *fingerprint, | 89 const char *fingerprint, |
96 const char *babbleprint, | 90 const char *babbleprint, |
97 PublicKeyVerify verify) | 91 PublicKeyVerify verify) |
98 { | 92 { |
99 PurpleConnection *gc = verify->client->application; | 93 PurpleConnection *gc = verify->client->application; |
100 char tmp[256], tmp2[256]; | 94 char tmp[256], tmp2[256]; |
101 | 95 |
102 if (verify->changed) { | 96 if (verify->changed) { |
112 g_snprintf(tmp2, sizeof(tmp2), | 106 g_snprintf(tmp2, sizeof(tmp2), |
113 _("Fingerprint and babbleprint for the %s key are:\n\n" | 107 _("Fingerprint and babbleprint for the %s key are:\n\n" |
114 "%s\n%s\n"), entity, fingerprint, babbleprint); | 108 "%s\n%s\n"), entity, fingerprint, babbleprint); |
115 | 109 |
116 purple_request_action(gc, _("Verify Public Key"), tmp, tmp2, | 110 purple_request_action(gc, _("Verify Public Key"), tmp, tmp2, |
117 PURPLE_DEFAULT_ACTION_NONE, | 111 PURPLE_DEFAULT_ACTION_NONE, |
118 purple_connection_get_account(gc), entity, NULL, verify, 3, | 112 purple_connection_get_account(gc), entity, NULL, verify, 3, |
119 _("Yes"), G_CALLBACK(silcpurple_verify_cb), | 113 _("Yes"), G_CALLBACK(silcpurple_verify_cb), |
120 _("No"), G_CALLBACK(silcpurple_verify_cb), | 114 _("No"), G_CALLBACK(silcpurple_verify_cb), |
121 _("_View..."), G_CALLBACK(silcpurple_verify_details)); | 115 _("_View..."), G_CALLBACK(silcpurple_verify_details)); |
122 } | 116 } |
123 | 117 |
124 void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn, | 118 void silcpurple_verify_public_key(SilcClient client, SilcClientConnection conn, |
125 const char *name, SilcSocketType conn_type, | 119 const char *name, SilcConnectionType conn_type, |
126 unsigned char *pk, SilcUInt32 pk_len, | 120 SilcPublicKey public_key, |
127 SilcSKEPKType pk_type, | 121 SilcVerifyPublicKey completion, void *context) |
128 SilcVerifyPublicKey completion, void *context) | |
129 { | 122 { |
130 PurpleConnection *gc = client->application; | 123 PurpleConnection *gc = client->application; |
131 int i; | 124 int i; |
132 char file[256], filename[256], filename2[256], *ipf, *hostf = NULL; | 125 char file[256], filename[256], filename2[256], *ipf, *hostf = NULL; |
133 char *fingerprint, *babbleprint; | 126 char *fingerprint, *babbleprint; |
134 struct passwd *pw; | 127 struct passwd *pw; |
135 struct stat st; | 128 struct stat st; |
136 char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER || | 129 char *entity = ((conn_type == SILC_CONN_SERVER || |
137 conn_type == SILC_SOCKET_TYPE_ROUTER) ? | 130 conn_type == SILC_CONN_ROUTER) ? |
138 "server" : "client"); | 131 "server" : "client"); |
139 PublicKeyVerify verify; | 132 PublicKeyVerify verify; |
140 | 133 const char *ip, *hostname; |
141 if (pk_type != SILC_SKE_PK_TYPE_SILC) { | 134 SilcUInt16 port; |
135 unsigned char *pk; | |
136 SilcUInt32 pk_len; | |
137 | |
138 if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) { | |
142 purple_notify_error(gc, _("Verify Public Key"), | 139 purple_notify_error(gc, _("Verify Public Key"), |
143 _("Unsupported public key type"), NULL); | 140 _("Unsupported public key type"), NULL); |
144 if (completion) | 141 if (completion) |
145 completion(FALSE, context); | 142 completion(FALSE, context); |
146 return; | 143 return; |
147 } | 144 } |
148 | 145 |
155 | 152 |
156 memset(filename, 0, sizeof(filename)); | 153 memset(filename, 0, sizeof(filename)); |
157 memset(filename2, 0, sizeof(filename2)); | 154 memset(filename2, 0, sizeof(filename2)); |
158 memset(file, 0, sizeof(file)); | 155 memset(file, 0, sizeof(file)); |
159 | 156 |
160 if (conn_type == SILC_SOCKET_TYPE_SERVER || | 157 silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->stream), |
161 conn_type == SILC_SOCKET_TYPE_ROUTER) { | 158 NULL, &hostname, &ip, &port); |
159 | |
160 pk = silc_pkcs_public_key_encode(public_key, &pk_len); | |
161 | |
162 if (conn_type == SILC_CONN_SERVER || | |
163 conn_type == SILC_CONN_ROUTER) { | |
162 if (!name) { | 164 if (!name) { |
163 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, | 165 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, |
164 conn->sock->ip, conn->sock->port); | 166 ip, port); |
165 g_snprintf(filename, sizeof(filename) - 1, | 167 g_snprintf(filename, sizeof(filename) - 1, |
166 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", | 168 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", |
167 silcpurple_silcdir(), entity, file); | 169 silcpurple_silcdir(), entity, file); |
168 | 170 |
169 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, | 171 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, |
170 conn->sock->hostname, conn->sock->port); | 172 hostname, port); |
171 g_snprintf(filename2, sizeof(filename2) - 1, | 173 g_snprintf(filename2, sizeof(filename2) - 1, |
172 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", | 174 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", |
173 silcpurple_silcdir(), entity, file); | 175 silcpurple_silcdir(), entity, file); |
174 | 176 |
175 ipf = filename; | 177 ipf = filename; |
176 hostf = filename2; | 178 hostf = filename2; |
177 } else { | 179 } else { |
178 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, | 180 g_snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, |
179 name, conn->sock->port); | 181 name, port); |
180 g_snprintf(filename, sizeof(filename) - 1, | 182 g_snprintf(filename, sizeof(filename) - 1, |
181 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", | 183 "%s" G_DIR_SEPARATOR_S "%skeys" G_DIR_SEPARATOR_S "%s", |
182 silcpurple_silcdir(), entity, file); | 184 silcpurple_silcdir(), entity, file); |
183 | 185 |
184 ipf = filename; | 186 ipf = filename; |
204 return; | 206 return; |
205 verify->client = client; | 207 verify->client = client; |
206 verify->conn = conn; | 208 verify->conn = conn; |
207 verify->filename = strdup(ipf); | 209 verify->filename = strdup(ipf); |
208 verify->entity = strdup(entity); | 210 verify->entity = strdup(entity); |
209 verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ? | 211 verify->entity_name = (conn_type != SILC_CONN_CLIENT ? |
210 (name ? strdup(name) : strdup(conn->sock->hostname)) | 212 (name ? strdup(name) : strdup(hostname)) |
211 : NULL); | 213 : NULL); |
212 verify->pk = silc_memdup(pk, pk_len); | 214 verify->public_key = silc_pkcs_public_key_copy(public_key); |
213 verify->pk_len = pk_len; | |
214 verify->pk_type = pk_type; | |
215 verify->completion = completion; | 215 verify->completion = completion; |
216 verify->context = context; | 216 verify->context = context; |
217 fingerprint = verify->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); | 217 fingerprint = verify->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); |
218 babbleprint = verify->babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); | 218 babbleprint = verify->babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); |
219 | 219 |
220 /* Check whether this key already exists */ | 220 /* Check whether this key already exists */ |
221 if (g_stat(ipf, &st) < 0 && (!hostf || g_stat(hostf, &st) < 0)) { | 221 if (g_stat(ipf, &st) < 0 && (!hostf || g_stat(hostf, &st) < 0)) { |
222 /* Key does not exist, ask user to verify the key and save it */ | 222 /* Key does not exist, ask user to verify the key and save it */ |
223 silcpurple_verify_ask(name ? name : entity, | 223 silcpurple_verify_ask(name ? name : entity, |
224 fingerprint, babbleprint, verify); | 224 fingerprint, babbleprint, verify); |
225 return; | 225 return; |
226 } else { | 226 } else { |
227 /* The key already exists, verify it. */ | 227 /* The key already exists, verify it. */ |
228 SilcPublicKey public_key; | 228 SilcPublicKey public_key; |
229 unsigned char *encpk; | 229 unsigned char *encpk; |
230 SilcUInt32 encpk_len; | 230 SilcUInt32 encpk_len; |
231 | 231 |
232 /* Load the key file, try for both IP filename and hostname filename */ | 232 /* Load the key file, try for both IP filename and hostname filename */ |
233 if (!silc_pkcs_load_public_key(ipf, &public_key, | 233 if (!silc_pkcs_load_public_key(ipf, &public_key) && |
234 SILC_PKCS_FILE_PEM) && | 234 (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key)))) { |
235 !silc_pkcs_load_public_key(ipf, &public_key, | |
236 SILC_PKCS_FILE_BIN) && | |
237 (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key, | |
238 SILC_PKCS_FILE_PEM) && | |
239 !silc_pkcs_load_public_key(hostf, &public_key, | |
240 SILC_PKCS_FILE_BIN)))) { | |
241 silcpurple_verify_ask(name ? name : entity, | 235 silcpurple_verify_ask(name ? name : entity, |
242 fingerprint, babbleprint, verify); | 236 fingerprint, babbleprint, verify); |
243 return; | 237 return; |
244 } | 238 } |
245 | 239 |
264 if (completion) | 258 if (completion) |
265 completion(TRUE, context); | 259 completion(TRUE, context); |
266 silc_free(verify->filename); | 260 silc_free(verify->filename); |
267 silc_free(verify->entity); | 261 silc_free(verify->entity); |
268 silc_free(verify->entity_name); | 262 silc_free(verify->entity_name); |
269 silc_free(verify->pk); | |
270 silc_free(verify->fingerprint); | 263 silc_free(verify->fingerprint); |
271 silc_free(verify->babbleprint); | 264 silc_free(verify->babbleprint); |
265 silc_pkcs_public_key_free(verify->public_key); | |
272 silc_free(verify); | 266 silc_free(verify); |
273 } | 267 } |
274 } | 268 } |