comparison src/protocols/silc/util.c @ 8849:50d0f76639e7

[gaim-migrate @ 9616] Let there be SILC. committer: Tailor Script <tailor@pidgin.im>
author Ethan Blanton <elb@pidgin.im>
date Sat, 01 May 2004 19:34:44 +0000
parents
children 26c9b8761707
comparison
equal deleted inserted replaced
8848:56e6b9bdcdbc 8849:50d0f76639e7
1 /*
2
3 silcgaim_util.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 /**************************** Utility Routines *******************************/
25
26 static char str[256], str2[256];
27
28 const char *silcgaim_silcdir(void)
29 {
30 const char *hd = gaim_home_dir();
31 memset(str, 0, sizeof(str));
32 g_snprintf(str, sizeof(str) - 1, "%s" G_DIR_SEPARATOR_S ".silc", hd ? hd : "/tmp");
33 return (const char *)str;
34 }
35
36 const char *silcgaim_session_file(const char *account)
37 {
38 memset(str2, 0, sizeof(str2));
39 g_snprintf(str2, sizeof(str2) - 1, "%s" G_DIR_SEPARATOR_S "%s_session",
40 silcgaim_silcdir(), account);
41 return (const char *)str2;
42 }
43
44 gboolean silcgaim_ip_is_private(const char *ip)
45 {
46 if (silc_net_is_ip4(ip)) {
47 if (!strncmp(ip, "10.", 3)) {
48 return TRUE;
49 } else if (!strncmp(ip, "172.", 4) && strlen(ip) > 6) {
50 char tmp[3];
51 memset(tmp, 0, sizeof(tmp));
52 strncpy(tmp, ip + 4, 2);
53 int s = atoi(tmp);
54 if (s >= 16 && s <= 31)
55 return TRUE;
56 } else if (!strncmp(ip, "192.168.", 8)) {
57 return TRUE;
58 }
59 }
60
61 return FALSE;
62 }
63
64 /* This checks stats for various SILC files and directories. First it
65 checks if ~/.silc directory exist and is owned by the correct user. If
66 it doesn't exist, it will create the directory. After that it checks if
67 user's Public and Private key files exists and creates them if needed. */
68
69 gboolean silcgaim_check_silc_dir(GaimConnection *gc)
70 {
71 char filename[256], file_public_key[256], file_private_key[256];
72 char servfilename[256], clientfilename[256], friendsfilename[256];
73 struct stat st;
74 struct passwd *pw;
75
76 pw = getpwuid(getuid());
77 if (!pw) {
78 fprintf(stderr, "silc: %s\n", strerror(errno));
79 return FALSE;
80 }
81
82 g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S, silcgaim_silcdir());
83 g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys",
84 silcgaim_silcdir());
85 g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys",
86 silcgaim_silcdir());
87 g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends",
88 silcgaim_silcdir());
89
90 /*
91 * Check ~/.silc directory
92 */
93 if ((stat(filename, &st)) == -1) {
94 /* If dir doesn't exist */
95 if (errno == ENOENT) {
96 if (pw->pw_uid == geteuid()) {
97 if ((mkdir(filename, 0755)) == -1) {
98 fprintf(stderr, "Couldn't create `%s' directory\n", filename);
99 return FALSE;
100 }
101 } else {
102 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
103 filename);
104 return FALSE;
105 }
106 } else {
107 fprintf(stderr, "%s\n", strerror(errno));
108 return FALSE;
109 }
110 } else {
111 /* Check the owner of the dir */
112 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
113 fprintf(stderr, "You don't seem to own `%s' directory\n",
114 filename);
115 return FALSE;
116 }
117 }
118
119 /*
120 * Check ~./silc/serverkeys directory
121 */
122 if ((stat(servfilename, &st)) == -1) {
123 /* If dir doesn't exist */
124 if (errno == ENOENT) {
125 if (pw->pw_uid == geteuid()) {
126 if ((mkdir(servfilename, 0755)) == -1) {
127 fprintf(stderr, "Couldn't create `%s' directory\n", servfilename);
128 return FALSE;
129 }
130 } else {
131 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
132 servfilename);
133 return FALSE;
134 }
135 } else {
136 fprintf(stderr, "%s\n", strerror(errno));
137 return FALSE;
138 }
139 }
140
141 /*
142 * Check ~./silc/clientkeys directory
143 */
144 if ((stat(clientfilename, &st)) == -1) {
145 /* If dir doesn't exist */
146 if (errno == ENOENT) {
147 if (pw->pw_uid == geteuid()) {
148 if ((mkdir(clientfilename, 0755)) == -1) {
149 fprintf(stderr, "Couldn't create `%s' directory\n", clientfilename);
150 return FALSE;
151 }
152 } else {
153 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
154 clientfilename);
155 return FALSE;
156 }
157 } else {
158 fprintf(stderr, "%s\n", strerror(errno));
159 return FALSE;
160 }
161 }
162
163 /*
164 * Check ~./silc/friends directory
165 */
166 if ((stat(friendsfilename, &st)) == -1) {
167 /* If dir doesn't exist */
168 if (errno == ENOENT) {
169 if (pw->pw_uid == geteuid()) {
170 if ((mkdir(friendsfilename, 0755)) == -1) {
171 fprintf(stderr, "Couldn't create `%s' directory\n", friendsfilename);
172 return FALSE;
173 }
174 } else {
175 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
176 friendsfilename);
177 return FALSE;
178 }
179 } else {
180 fprintf(stderr, "%s\n", strerror(errno));
181 return FALSE;
182 }
183 }
184
185 /*
186 * Check Public and Private keys
187 */
188 g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s",
189 gaim_prefs_get_string("/plugins/prpl/silc/pubkey"));
190 g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s",
191 gaim_prefs_get_string("/plugins/prpl/silc/privkey"));
192
193 if ((stat(file_public_key, &st)) == -1) {
194 /* If file doesn't exist */
195 if (errno == ENOENT) {
196 gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
197 silc_create_key_pair(SILCGAIM_DEF_PKCS,
198 SILCGAIM_DEF_PKCS_LEN,
199 file_public_key, file_private_key, NULL,
200 "", NULL, NULL, NULL, FALSE);
201 } else {
202 fprintf(stderr, "%s\n", strerror(errno));
203 return FALSE;
204 }
205 }
206
207 /* Check the owner of the public key */
208 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
209 fprintf(stderr, "You don't seem to own your public key!?\n");
210 return FALSE;
211 }
212
213 if ((stat(file_private_key, &st)) == -1) {
214 /* If file doesn't exist */
215 if (errno == ENOENT) {
216 gaim_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
217 silc_create_key_pair(SILCGAIM_DEF_PKCS,
218 SILCGAIM_DEF_PKCS_LEN,
219 file_public_key, file_private_key, NULL,
220 "", NULL, NULL, NULL, FALSE);
221 } else {
222 fprintf(stderr, "%s\n", strerror(errno));
223 return FALSE;
224 }
225 }
226
227 /* Check the owner of the private key */
228 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
229 fprintf(stderr, "You don't seem to own your private key!?\n");
230 return FALSE;
231 }
232
233 /* Check the permissions for the private key */
234 if ((st.st_mode & 0777) != 0600) {
235 fprintf(stderr, "Wrong permissions in your private key file `%s'!\n"
236 "Trying to change them ... ", file_private_key);
237 if ((chmod(file_private_key, 0600)) == -1) {
238 fprintf(stderr,
239 "Failed to change permissions for private key file!\n"
240 "Permissions for your private key file must be 0600.\n");
241 return FALSE;
242 }
243 fprintf(stderr, "Done.\n\n");
244 }
245
246 return TRUE;
247 }
248
249 void silcgaim_show_public_key(SilcGaim sg,
250 const char *name, SilcPublicKey public_key,
251 GCallback callback, void *context)
252 {
253 SilcPublicKeyIdentifier ident;
254 SilcPKCS pkcs;
255 char *fingerprint, *babbleprint;
256 unsigned char *pk;
257 SilcUInt32 pk_len, key_len = 0;
258 GString *s;
259 char *buf;
260
261 ident = silc_pkcs_decode_identifier(public_key->identifier);
262 if (!ident)
263 return;
264
265 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
266 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
267 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
268
269 if (silc_pkcs_alloc(public_key->name, &pkcs)) {
270 key_len = silc_pkcs_public_key_set(pkcs, public_key);
271 silc_pkcs_free(pkcs);
272 }
273
274 s = g_string_new("");
275 if (ident->realname)
276 g_string_append_printf(s, "Real Name: \t%s\n", ident->realname);
277 if (ident->username)
278 g_string_append_printf(s, "User Name: \t%s\n", ident->username);
279 if (ident->email)
280 g_string_append_printf(s, "EMail: \t\t%s\n", ident->email);
281 if (ident->host)
282 g_string_append_printf(s, "Host Name: \t%s\n", ident->host);
283 if (ident->org)
284 g_string_append_printf(s, "Organization: \t%s\n", ident->org);
285 if (ident->country)
286 g_string_append_printf(s, "Country: \t%s\n", ident->country);
287 g_string_append_printf(s, "Algorithm: \t\t%s\n", public_key->name);
288 g_string_append_printf(s, "Key Length: \t%d bits\n", (int)key_len);
289 g_string_append_printf(s, "\n");
290 g_string_append_printf(s, "Public Key Fingerprint:\n%s\n\n", fingerprint);
291 g_string_append_printf(s, "Public Key Babbleprint:\n%s", babbleprint);
292
293 buf = g_string_free(s, FALSE);
294
295 gaim_request_action(NULL, _("Public Key Information"),
296 _("Public Key Information"),
297 buf, 0, context, 1,
298 _("Close"), callback);
299
300 g_free(buf);
301 silc_free(fingerprint);
302 silc_free(babbleprint);
303 silc_free(pk);
304 silc_pkcs_free_identifier(ident);
305 }
306
307 SilcAttributePayload
308 silcgaim_get_attr(SilcDList attrs, SilcAttribute attribute)
309 {
310 SilcAttributePayload attr = NULL;
311
312 if (!attrs)
313 return NULL;
314
315 silc_dlist_start(attrs);
316 while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END)
317 if (attribute == silc_attribute_get_attribute(attr))
318 break;
319
320 return attr;
321 }
322
323 void silcgaim_get_umode_string(SilcUInt32 mode, char *buf,
324 SilcUInt32 buf_size)
325 {
326 memset(buf, 0, buf_size);
327 if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
328 (mode & SILC_UMODE_ROUTER_OPERATOR)) {
329 strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ?
330 "[server operator] " :
331 (mode & SILC_UMODE_ROUTER_OPERATOR) ?
332 "[SILC operator] " : "[unknown mode] ");
333 }
334 if (mode & SILC_UMODE_GONE)
335 strcat(buf, "[away] ");
336 if (mode & SILC_UMODE_INDISPOSED)
337 strcat(buf, "[indisposed] ");
338 if (mode & SILC_UMODE_BUSY)
339 strcat(buf, "[busy] ");
340 if (mode & SILC_UMODE_PAGE)
341 strcat(buf, "[wake me up] ");
342 if (mode & SILC_UMODE_HYPER)
343 strcat(buf, "[hyperactive] ");
344 if (mode & SILC_UMODE_ROBOT)
345 strcat(buf, "[robot] ");
346 if (mode & SILC_UMODE_ANONYMOUS)
347 strcat(buf, "[anonymous] ");
348 if (mode & SILC_UMODE_BLOCK_PRIVMSG)
349 strcat(buf, "[blocks private messages] ");
350 if (mode & SILC_UMODE_DETACHED)
351 strcat(buf, "[detached] ");
352 if (mode & SILC_UMODE_REJECT_WATCHING)
353 strcat(buf, "[rejects watching] ");
354 if (mode & SILC_UMODE_BLOCK_INVITE)
355 strcat(buf, "[blocks invites] ");
356 }
357
358 void silcgaim_get_chmode_string(SilcUInt32 mode, char *buf,
359 SilcUInt32 buf_size)
360 {
361 memset(buf, 0, buf_size);
362 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
363 strcat(buf, "[permanent] ");
364 if (mode & SILC_CHANNEL_MODE_PRIVATE)
365 strcat(buf, "[private] ");
366 if (mode & SILC_CHANNEL_MODE_SECRET)
367 strcat(buf, "[secret] ");
368 if (mode & SILC_CHANNEL_MODE_SECRET)
369 strcat(buf, "[secret] ");
370 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
371 strcat(buf, "[private key] ");
372 if (mode & SILC_CHANNEL_MODE_INVITE)
373 strcat(buf, "[invite only] ");
374 if (mode & SILC_CHANNEL_MODE_TOPIC)
375 strcat(buf, "[topic restricted] ");
376 if (mode & SILC_CHANNEL_MODE_ULIMIT)
377 strcat(buf, "[user count limit] ");
378 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
379 strcat(buf, "[passphrase auth] ");
380 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
381 strcat(buf, "[public key auth] ");
382 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
383 strcat(buf, "[users silenced] ");
384 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
385 strcat(buf, "[operators silenced] ");
386 }
387
388 void silcgaim_get_chumode_string(SilcUInt32 mode, char *buf,
389 SilcUInt32 buf_size)
390 {
391 memset(buf, 0, buf_size);
392 if (mode & SILC_CHANNEL_UMODE_CHANFO)
393 strcat(buf, "[founder] ");
394 if (mode & SILC_CHANNEL_UMODE_CHANOP)
395 strcat(buf, "[operator] ");
396 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
397 strcat(buf, "[blocks messages] ");
398 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
399 strcat(buf, "[blocks user messages] ");
400 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
401 strcat(buf, "[blocks robot messages] ");
402 if (mode & SILC_CHANNEL_UMODE_QUIET)
403 strcat(buf, "[quieted] ");
404 }