5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 - 2008 Pekka Riikonen
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.
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.
23 #include "silc-queries.h"
30 #include "fe-common/core/printtext.h"
31 #include "fe-common/core/fe-channels.h"
32 #include "fe-common/core/keyboard.h"
33 #include "fe-common/silc/module-formats.h"
35 static void silc_query_attributes_print_final(bool success, void *context);
36 static void silc_query_attributes_accept(const char *line, void *context);
38 QUERY_REC *silc_query_create(const char *server_tag,
39 const char *nick, int automatic)
43 g_return_val_if_fail(nick != NULL, NULL);
45 rec = g_new0(QUERY_REC, 1);
46 rec->chat_type = SILC_PROTOCOL;
47 rec->name = g_strdup(nick);
48 rec->server_tag = g_strdup(server_tag);
49 query_init(rec, automatic);
53 void silc_queries_init(void)
57 void silc_queries_deinit(void)
63 void command_attr(const char *data, SILC_SERVER_REC *server,
69 SilcUInt32 *argv_lens, *argv_types;
73 /* Now parse all arguments */
74 tmp = g_strconcat("ATTR", " ", data, NULL);
75 silc_parse_command_line(tmp, &argv, &argv_lens, &argv_types, &argc, 3);
79 /* Show all attributes */
80 printformat_module("fe-common/silc", server, NULL,
81 MSGLEVEL_CRAP, SILCTXT_ATTR_HEADER);
83 allowed = settings_get_bool("attr_allow");
84 printformat_module("fe-common/silc", server, NULL,
85 MSGLEVEL_CRAP, SILCTXT_ATTR_ALLOW,
86 allowed ? "Yes" : "No");
88 sv = settings_get_str("attr_vcard");
90 printformat_module("fe-common/silc", server, NULL,
91 MSGLEVEL_CRAP, SILCTXT_ATTR_VCARD_FILE, sv);
93 sv = settings_get_str("attr_services");
95 printformat_module("fe-common/silc", server, NULL,
96 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVICES, sv);
98 sv = settings_get_str("attr_status_mood");
100 printformat_module("fe-common/silc", server, NULL,
101 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MOOD, sv);
103 sv = settings_get_str("attr_status_text");
105 printformat_module("fe-common/silc", server, NULL,
106 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_TEXT, sv);
108 sv = settings_get_str("attr_status_message");
110 printformat_module("fe-common/silc", server, NULL,
111 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MESSAGE_FILE,
114 sv = settings_get_str("attr_preferred_language");
116 printformat_module("fe-common/silc", server, NULL,
117 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_LANGUAGE,
120 sv = settings_get_str("attr_preferred_contact");
122 printformat_module("fe-common/silc", server, NULL,
123 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_CONTACT,
126 sv = settings_get_str("attr_geolocation");
128 printformat_module("fe-common/silc", server, NULL,
129 MSGLEVEL_CRAP, SILCTXT_ATTR_GEOLOCATION,
132 sv = settings_get_str("attr_device_info");
134 printformat_module("fe-common/silc", server, NULL,
135 MSGLEVEL_CRAP, SILCTXT_ATTR_DEVICE_INFO,
138 sv = settings_get_str("attr_public_keys");
140 printformat_module("fe-common/silc", server, NULL,
141 MSGLEVEL_CRAP, SILCTXT_ATTR_PUBLIC_KEYS,
144 allowed = settings_get_bool("attr_timezone");
145 printformat_module("fe-common/silc", server, NULL,
146 MSGLEVEL_CRAP, SILCTXT_ATTR_TIMEZONE_ALLOW,
147 allowed ? "Yes" : "No");
149 printformat_module("fe-common/silc", server, NULL,
150 MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
155 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
157 if (!strcasecmp(argv[1], "-del")) {
158 /* Delete attribute */
159 if (!strcasecmp(argv[2], "vcard")) {
160 silc_client_attribute_del(silc_client, server->conn,
161 SILC_ATTRIBUTE_USER_INFO, NULL);
162 settings_set_str("attr_vcard", "");
163 } else if (!strcasecmp(argv[2], "services")) {
164 silc_client_attribute_del(silc_client, server->conn,
165 SILC_ATTRIBUTE_SERVICE, NULL);
166 settings_set_str("attr_services", argv[2]);
167 } else if (!strcasecmp(argv[2], "status_mood")) {
168 silc_client_attribute_del(silc_client, server->conn,
169 SILC_ATTRIBUTE_STATUS_MOOD, NULL);
170 settings_set_str("attr_status_mood", "");
171 } else if (!strcasecmp(argv[2], "status_text")) {
172 silc_client_attribute_del(silc_client, server->conn,
173 SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
174 settings_set_str("attr_status_text", "");
175 } else if (!strcasecmp(argv[2], "status_message")) {
176 silc_client_attribute_del(silc_client, server->conn,
177 SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
178 settings_set_str("attr_status_message", "");
179 } else if (!strcasecmp(argv[2], "preferred_language")) {
180 silc_client_attribute_del(silc_client, server->conn,
181 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
182 settings_set_str("attr_preferred_language", "");
183 } else if (!strcasecmp(argv[2], "preferred_contact")) {
184 silc_client_attribute_del(silc_client, server->conn,
185 SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
186 settings_set_str("attr_preferred_contact", "");
187 } else if (!strcasecmp(argv[2], "timezone")) {
189 } else if (!strcasecmp(argv[2], "geolocation")) {
190 silc_client_attribute_del(silc_client, server->conn,
191 SILC_ATTRIBUTE_GEOLOCATION, NULL);
192 settings_set_str("attr_geolocation", "");
193 } else if (!strcasecmp(argv[2], "device_info")) {
194 silc_client_attribute_del(silc_client, server->conn,
195 SILC_ATTRIBUTE_DEVICE_INFO, NULL);
196 settings_set_str("attr_device_info", "");
197 } else if (!strcasecmp(argv[2], "public_keys")) {
198 silc_client_attribute_del(silc_client, server->conn,
199 SILC_ATTRIBUTE_USER_PUBLIC_KEY, NULL);
200 settings_set_str("attr_public_keys", "");
202 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
207 /* Add new attribute */
208 if (!strcasecmp(argv[1], "allow")) {
209 allowed = !strcasecmp(argv[2], "ON") || !strcasecmp(argv[2], "YES");
210 settings_set_bool("attr_allow", allowed);
211 } else if (!strcasecmp(argv[1], "vcard")) {
212 settings_set_str("attr_vcard", argv[2]);
213 } else if (!strcasecmp(argv[1], "services")) {
214 settings_set_str("attr_services", argv[2]);
215 } else if (!strcasecmp(argv[1], "status_mood")) {
216 settings_set_str("attr_status_mood", argv[2]);
217 } else if (!strcasecmp(argv[1], "status_text")) {
218 settings_set_str("attr_status_text", argv[2]);
219 } else if (!strcasecmp(argv[1], "status_message")) {
220 settings_set_str("attr_status_message", argv[2]);
221 } else if (!strcasecmp(argv[1], "preferred_language")) {
222 settings_set_str("attr_preferred_language", argv[2]);
223 } else if (!strcasecmp(argv[1], "preferred_contact")) {
224 settings_set_str("attr_preferred_contact", argv[2]);
225 } else if (!strcasecmp(argv[1], "timezone")) {
226 allowed = !strcasecmp(argv[2], "ON") || !strcasecmp(argv[2], "YES");
227 settings_set_bool("attr_timezone", allowed);
228 } else if (!strcasecmp(argv[1], "geolocation")) {
229 settings_set_str("attr_geolocation", argv[2]);
230 } else if (!strcasecmp(argv[1], "device_info")) {
231 settings_set_str("attr_device_info", argv[2]);
232 } else if (!strcasecmp(argv[1], "public_keys")) {
233 settings_set_str("attr_public_keys", argv[2]);
235 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
238 silc_query_attributes_default(silc_client, server->conn);
241 /* Put default attributes to client library */
243 void silc_query_attributes_default(SilcClient client,
244 SilcClientConnection conn)
246 char *tmp, **list, **entry;
248 SilcUInt32 tmp_len, mask;
249 SilcAttributeObjService service;
251 SilcAttributeObjGeo geo;
252 SilcAttributeObjDevice dev;
253 SilcAttributeObjPk pk;
254 SilcVCardStruct vcard;
257 memset(&service, 0, sizeof(service));
258 memset(&geo, 0, sizeof(geo));
259 memset(&dev, 0, sizeof(dev));
260 memset(&pk, 0, sizeof(pk));
261 memset(&vcard, 0, sizeof(vcard));
263 allowed = settings_get_bool("attr_allow");
265 silc_client_attribute_del(silc_client, conn,
266 SILC_ATTRIBUTE_USER_INFO, NULL);
267 silc_client_attribute_del(silc_client, conn,
268 SILC_ATTRIBUTE_SERVICE, NULL);
269 silc_client_attribute_del(silc_client, conn,
270 SILC_ATTRIBUTE_STATUS_MOOD, NULL);
271 silc_client_attribute_del(silc_client, conn,
272 SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
273 silc_client_attribute_del(silc_client, conn,
274 SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
275 silc_client_attribute_del(silc_client, conn,
276 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
277 silc_client_attribute_del(silc_client, conn,
278 SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
279 silc_client_attribute_del(silc_client, conn,
280 SILC_ATTRIBUTE_TIMEZONE, NULL);
281 silc_client_attribute_del(silc_client, conn,
282 SILC_ATTRIBUTE_GEOLOCATION, NULL);
283 silc_client_attribute_del(silc_client, conn,
284 SILC_ATTRIBUTE_DEVICE_INFO, NULL);
285 silc_client_attribute_del(silc_client, conn,
286 SILC_ATTRIBUTE_USER_PUBLIC_KEY, NULL);
290 sv = settings_get_str("attr_vcard");
293 silc_client_attribute_del(silc_client, conn,
294 SILC_ATTRIBUTE_USER_INFO, NULL);
295 tmp = silc_file_readfile(sv, &tmp_len, NULL);
298 if (silc_vcard_decode(tmp, tmp_len, &vcard))
299 silc_client_attribute_add(silc_client, conn,
300 SILC_ATTRIBUTE_USER_INFO, (void *)&vcard,
303 silc_vcard_free(&vcard);
307 sv = settings_get_str("attr_services");
310 silc_client_attribute_del(silc_client, conn,
311 SILC_ATTRIBUTE_SERVICE, NULL);
312 list = g_strsplit(sv, " ", -1);
313 for (entry = list; *entry != NULL; entry++) {
314 if (!strchr(*entry, ':'))
316 tmp = strchr(*entry, ':') + 1;
319 memset(&service, 0, sizeof(service));
320 service.port = atoi(tmp);
321 *strchr(*entry, ':') = '\0';
322 silc_strncat(service.address, sizeof(service.address), *entry,
324 service.status = TRUE;
326 silc_client_attribute_add(silc_client, conn,
327 SILC_ATTRIBUTE_SERVICE, &service,
333 sv = settings_get_str("attr_status_mood");
335 /* Put STATUS_MOOD */
336 silc_client_attribute_del(silc_client, conn,
337 SILC_ATTRIBUTE_STATUS_MOOD, NULL);
339 list = g_strsplit(sv, " ", -1);
340 for (entry = list; *entry != NULL; entry++) {
341 if (!strcasecmp(*entry, "NORMAL"))
342 mask |= SILC_ATTRIBUTE_MOOD_NORMAL;
343 if (!strcasecmp(*entry, "HAPPY"))
344 mask |= SILC_ATTRIBUTE_MOOD_HAPPY;
345 if (!strcasecmp(*entry, "SAD"))
346 mask |= SILC_ATTRIBUTE_MOOD_SAD;
347 if (!strcasecmp(*entry, "ANGRY"))
348 mask |= SILC_ATTRIBUTE_MOOD_ANGRY;
349 if (!strcasecmp(*entry, "JEALOUS"))
350 mask |= SILC_ATTRIBUTE_MOOD_JEALOUS;
351 if (!strcasecmp(*entry, "ASHAMED"))
352 mask |= SILC_ATTRIBUTE_MOOD_ASHAMED;
353 if (!strcasecmp(*entry, "INVINCIBLE"))
354 mask |= SILC_ATTRIBUTE_MOOD_INVINCIBLE;
355 if (!strcasecmp(*entry, "INLOVE"))
356 mask |= SILC_ATTRIBUTE_MOOD_INLOVE;
357 if (!strcasecmp(*entry, "SLEEPY"))
358 mask |= SILC_ATTRIBUTE_MOOD_SLEEPY;
359 if (!strcasecmp(*entry, "BORED"))
360 mask |= SILC_ATTRIBUTE_MOOD_BORED;
361 if (!strcasecmp(*entry, "EXCITED"))
362 mask |= SILC_ATTRIBUTE_MOOD_EXCITED;
363 if (!strcasecmp(*entry, "ANXIOUS"))
364 mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS;
366 silc_client_attribute_add(silc_client, conn,
367 SILC_ATTRIBUTE_STATUS_MOOD,
368 SILC_32_TO_PTR(mask),
373 sv = settings_get_str("attr_status_text");
375 /* Put STATUS_TEXT */
376 silc_client_attribute_del(silc_client, conn,
377 SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
378 silc_client_attribute_add(silc_client, conn,
379 SILC_ATTRIBUTE_STATUS_FREETEXT, (void *)sv,
383 sv = settings_get_str("attr_status_message");
385 /* Put STATUS_MESSAGE */
386 silc_client_attribute_del(silc_client, conn,
387 SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
388 tmp = silc_file_readfile(sv, &tmp_len, NULL);
390 mime = silc_mime_decode(NULL, tmp, tmp_len);
392 silc_client_attribute_add(silc_client, conn,
393 SILC_ATTRIBUTE_STATUS_MESSAGE, mime,
399 sv = settings_get_str("attr_preferred_language");
401 /* Put PREFERRED_LANGUAGE */
402 silc_client_attribute_del(silc_client, conn,
403 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
404 list = g_strsplit(sv, " ", -1);
405 for (entry = list; *entry != NULL; entry++) {
406 silc_client_attribute_add(silc_client, conn,
407 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, *entry,
413 sv = settings_get_str("attr_preferred_contact");
415 /* Put PREFERRED_CONTACT */
416 silc_client_attribute_del(silc_client, conn,
417 SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
419 list = g_strsplit(sv, " ", -1);
420 for (entry = list; *entry != NULL; entry++) {
421 if (!strcasecmp(*entry, "NONE"))
423 if (!strcasecmp(*entry, "EMAIL"))
424 mask |= SILC_ATTRIBUTE_CONTACT_EMAIL;
425 if (!strcasecmp(*entry, "CALL"))
426 mask |= SILC_ATTRIBUTE_CONTACT_CALL;
427 if (!strcasecmp(*entry, "PAGE"))
428 mask |= SILC_ATTRIBUTE_CONTACT_PAGE;
429 if (!strcasecmp(*entry, "SMS"))
430 mask |= SILC_ATTRIBUTE_CONTACT_SMS;
431 if (!strcasecmp(*entry, "MMS"))
432 mask |= SILC_ATTRIBUTE_CONTACT_MMS;
433 if (!strcasecmp(*entry, "CHAT"))
434 mask |= SILC_ATTRIBUTE_CONTACT_CHAT;
435 if (!strcasecmp(*entry, "VIDEO"))
436 mask |= SILC_ATTRIBUTE_CONTACT_VIDEO;
438 silc_client_attribute_add(silc_client, conn,
439 SILC_ATTRIBUTE_PREFERRED_CONTACT,
440 SILC_32_TO_PTR(mask),
446 allowed = settings_get_bool("attr_timezone");
447 silc_client_attribute_del(silc_client, conn,
448 SILC_ATTRIBUTE_TIMEZONE, NULL);
450 silc_client_attribute_add(silc_client, conn,
451 SILC_ATTRIBUTE_TIMEZONE, "foo", 3);
453 sv = settings_get_str("attr_geolocation");
455 /* Put GEOLOCATION */
456 silc_client_attribute_del(silc_client, conn,
457 SILC_ATTRIBUTE_GEOLOCATION, NULL);
458 list = g_strsplit(sv, ":", -1);
459 for (entry = list; *entry != NULL; entry++) {
460 if (!geo.longitude) {
461 geo.longitude = *entry;
465 geo.latitude = *entry;
469 geo.altitude = *entry;
473 geo.accuracy = *entry;
477 silc_client_attribute_add(silc_client, conn,
478 SILC_ATTRIBUTE_GEOLOCATION, &geo,
483 sv = settings_get_str("attr_device_info");
485 /* Put DEVICE_INFO */
486 silc_client_attribute_del(silc_client, conn,
487 SILC_ATTRIBUTE_DEVICE_INFO, NULL);
489 list = g_strsplit(sv, ":", -1);
490 for (entry = list; *entry != NULL; entry++) {
493 if (!strcasecmp(*entry, "COMPUTER"))
494 dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER;
495 if (!strcasecmp(*entry, "MOBILE_PHONE"))
496 dev.type = SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE;
497 if (!strcasecmp(sv, "PDA"))
498 dev.type = SILC_ATTRIBUTE_DEVICE_PDA;
499 if (!strcasecmp(sv, "TERMINAL"))
500 dev.type = SILC_ATTRIBUTE_DEVICE_TERMINAL;
503 if (!dev.manufacturer) {
504 dev.manufacturer = *entry;
508 dev.version = *entry;
516 dev.language = *entry;
520 silc_client_attribute_add(silc_client, conn,
521 SILC_ATTRIBUTE_DEVICE_INFO, &dev,
526 sv = settings_get_str("attr_public_keys");
528 /* Put USER_PUBLIC_KEY */
529 silc_client_attribute_del(silc_client, conn,
530 SILC_ATTRIBUTE_USER_PUBLIC_KEY, NULL);
531 list = g_strsplit(sv, " ", -1);
532 for (entry = list; *entry != NULL; entry++) {
533 if (!strncasecmp(*entry, "silc-rsa:", 8)) {
534 tmp = silc_file_readfile((*entry) + 8, &tmp_len, NULL);
537 pk.type = "silc-rsa";
539 pk.data_len = tmp_len;
540 silc_client_attribute_add(silc_client, conn,
541 SILC_ATTRIBUTE_USER_PUBLIC_KEY, &pk,
546 silc_say_error("Unsupported public key type '%s'", *entry);
555 SILC_SERVER_REC *server;
557 SilcAttributeObjPk userpk;
558 SilcPublicKey public_key;
559 SilcVCardStruct vcard;
565 static void silc_query_attributes_verify(SilcBool success, void *context)
567 *(SilcBool *)context = success;
570 void silc_query_attributes_print(SILC_SERVER_REC *server,
572 SilcClientConnection conn,
574 SilcClientEntry client_entry)
576 SilcAttributePayload attr;
577 SilcAttribute attribute;
579 SilcAttributeObjPk serverpk, usersign, serversign;
582 printformat_module("fe-common/silc", server, NULL,
583 MSGLEVEL_CRAP, SILCTXT_ATTR_HEADER);
585 memset(&serverpk, 0, sizeof(serverpk));
586 memset(&usersign, 0, sizeof(usersign));
587 memset(&serversign, 0, sizeof(serversign));
589 verify = silc_calloc(1, sizeof(*verify));
592 verify->client = client;
593 verify->server = server;
594 verify->name = strdup(client_entry->nickname);
596 silc_dlist_start(attrs);
597 while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
598 attribute = silc_attribute_get_attribute(attr);
599 memset(tmp, 0, sizeof(tmp));
603 case SILC_ATTRIBUTE_USER_INFO:
605 if (!silc_attribute_get_object(attr, (void *)&verify->vcard,
606 sizeof(verify->vcard)))
608 printformat_module("fe-common/silc", server, NULL,
609 MSGLEVEL_CRAP, SILCTXT_ATTR_VCARD_FILE,
614 case SILC_ATTRIBUTE_SERVICE:
616 SilcAttributeObjService service;
617 memset(&service, 0, sizeof(service));
618 if (!silc_attribute_get_object(attr, (void *)&service,
621 snprintf(tmp, sizeof(tmp) - 1, "%s:%d (logged %s) idle %d seconds",
622 service.address, (unsigned int)service.port,
623 service.status ? "in" : "out",
624 (unsigned int)service.idle);
625 printformat_module("fe-common/silc", server, NULL,
626 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVICES, tmp);
630 case SILC_ATTRIBUTE_STATUS_MOOD:
633 if (!silc_attribute_get_object(attr, (void *)&mask, sizeof(mask)))
636 silc_strncat(tmp, sizeof(tmp), "NORMAL ", strlen(" NORMAL"));
637 if (mask & SILC_ATTRIBUTE_MOOD_HAPPY)
638 silc_strncat(tmp, sizeof(tmp), "HAPPY ", strlen(" HAPPY"));
639 if (mask & SILC_ATTRIBUTE_MOOD_SAD)
640 silc_strncat(tmp, sizeof(tmp), "SAD ", strlen(" SAD"));
641 if (mask & SILC_ATTRIBUTE_MOOD_ANGRY)
642 silc_strncat(tmp, sizeof(tmp), "ANGRY ", strlen(" ANGRY"));
643 if (mask & SILC_ATTRIBUTE_MOOD_JEALOUS)
644 silc_strncat(tmp, sizeof(tmp), "JEALOUS ", strlen(" JEALOUS"));
645 if (mask & SILC_ATTRIBUTE_MOOD_ASHAMED)
646 silc_strncat(tmp, sizeof(tmp), "ASHAMED ", strlen(" ASHAMED"));
647 if (mask & SILC_ATTRIBUTE_MOOD_INVINCIBLE)
648 silc_strncat(tmp, sizeof(tmp), "INVINCIBLE ", strlen(" INVINCIBLE"));
649 if (mask & SILC_ATTRIBUTE_MOOD_INLOVE)
650 silc_strncat(tmp, sizeof(tmp), "INLOVE ", strlen(" INLOVE"));
651 if (mask & SILC_ATTRIBUTE_MOOD_SLEEPY)
652 silc_strncat(tmp, sizeof(tmp), "SLEEPY ", strlen(" SLEEPY"));
653 if (mask & SILC_ATTRIBUTE_MOOD_BORED)
654 silc_strncat(tmp, sizeof(tmp), "BORED ", strlen(" BORED"));
655 if (mask & SILC_ATTRIBUTE_MOOD_EXCITED)
656 silc_strncat(tmp, sizeof(tmp), "EXCITED ", strlen(" EXCITED"));
657 if (mask & SILC_ATTRIBUTE_MOOD_ANXIOUS)
658 silc_strncat(tmp, sizeof(tmp), "ANXIOUS ", strlen(" ANXIOUS"));
659 printformat_module("fe-common/silc", server, NULL,
660 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MOOD, tmp);
664 case SILC_ATTRIBUTE_STATUS_FREETEXT:
666 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
668 printformat_module("fe-common/silc", server, NULL,
669 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_TEXT, tmp);
673 case SILC_ATTRIBUTE_STATUS_MESSAGE:
675 verify->message = silc_mime_alloc();
676 if (!verify->message)
678 if (!silc_attribute_get_object(attr, (void *)verify->message,
679 sizeof(*verify->message)))
681 printformat_module("fe-common/silc", server, NULL,
682 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MESSAGE,
687 case SILC_ATTRIBUTE_PREFERRED_LANGUAGE:
689 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
691 printformat_module("fe-common/silc", server, NULL,
692 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_LANGUAGE,
697 case SILC_ATTRIBUTE_PREFERRED_CONTACT:
700 if (!silc_attribute_get_object(attr, (void *)&mask, sizeof(mask)))
703 silc_strncat(tmp, sizeof(tmp), "NONE ", strlen(" NONE"));
704 if (mask & SILC_ATTRIBUTE_CONTACT_CHAT)
705 silc_strncat(tmp, sizeof(tmp), "CHAT ", strlen(" CHAT"));
706 if (mask & SILC_ATTRIBUTE_CONTACT_EMAIL)
707 silc_strncat(tmp, sizeof(tmp), "EMAIL ", strlen(" EMAIL"));
708 if (mask & SILC_ATTRIBUTE_CONTACT_CALL)
709 silc_strncat(tmp, sizeof(tmp), "CALL ", strlen(" CALL"));
710 if (mask & SILC_ATTRIBUTE_CONTACT_PAGE)
711 silc_strncat(tmp, sizeof(tmp), "PAGE ", strlen(" PAGE"));
712 if (mask & SILC_ATTRIBUTE_CONTACT_SMS)
713 silc_strncat(tmp, sizeof(tmp), "SMS ", strlen(" SMS"));
714 if (mask & SILC_ATTRIBUTE_CONTACT_MMS)
715 silc_strncat(tmp, sizeof(tmp), "MMS ", strlen(" MMS"));
716 if (mask & SILC_ATTRIBUTE_CONTACT_VIDEO)
717 silc_strncat(tmp, sizeof(tmp), "VIDEO ", strlen(" VIDEO"));
718 printformat_module("fe-common/silc", server, NULL,
719 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_CONTACT, tmp);
723 case SILC_ATTRIBUTE_TIMEZONE:
725 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
727 printformat_module("fe-common/silc", server, NULL,
728 MSGLEVEL_CRAP, SILCTXT_ATTR_TIMEZONE, tmp);
732 case SILC_ATTRIBUTE_EXTENSION:
734 verify->extension = silc_mime_alloc();
735 if (!verify->extension)
737 if (!silc_attribute_get_object(attr, (void *)verify->extension,
738 sizeof(*verify->extension)))
740 printformat_module("fe-common/silc", server, NULL,
741 MSGLEVEL_CRAP, SILCTXT_ATTR_EXTENSION,
746 case SILC_ATTRIBUTE_GEOLOCATION:
748 SilcAttributeObjGeo geo;
749 memset(&geo, 0, sizeof(geo));
750 if (!silc_attribute_get_object(attr, (void *)&geo, sizeof(geo)))
752 snprintf(tmp, sizeof(tmp) - 1, "%s:%s:%s:%s",
753 geo.longitude ? geo.longitude : "",
754 geo.latitude ? geo.latitude : "",
755 geo.altitude ? geo.altitude : "",
756 geo.accuracy ? geo.accuracy : "");
757 printformat_module("fe-common/silc", server, NULL,
758 MSGLEVEL_CRAP, SILCTXT_ATTR_GEOLOCATION, tmp);
762 case SILC_ATTRIBUTE_DEVICE_INFO:
764 SilcAttributeObjDevice dev;
765 memset(&dev, 0, sizeof(dev));
766 if (!silc_attribute_get_object(attr, (void *)&dev, sizeof(dev)))
768 snprintf(tmp, sizeof(tmp) - 1, "%s:%s:%s:%s:%s",
769 (dev.type == SILC_ATTRIBUTE_DEVICE_COMPUTER ? "COMPUTER" :
770 dev.type == SILC_ATTRIBUTE_DEVICE_PDA ? "PDA" :
771 dev.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE ?
773 dev.type == SILC_ATTRIBUTE_DEVICE_TERMINAL ? "TERMINAL" :
775 dev.manufacturer ? dev.manufacturer : "",
776 dev.version ? dev.version : "",
777 dev.model ? dev.model: "",
778 dev.language ? dev.language : "");
779 printformat_module("fe-common/silc", server, NULL,
780 MSGLEVEL_CRAP, SILCTXT_ATTR_DEVICE_INFO, tmp);
784 case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
786 if (verify->userpk.type)
788 if (!silc_attribute_get_object(attr, (void *)&verify->userpk,
789 sizeof(verify->userpk)))
794 case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
798 if (!silc_attribute_get_object(attr, (void *)&serverpk,
804 case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
808 if (!silc_attribute_get_object(attr, (void *)&usersign,
814 case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
818 if (!silc_attribute_get_object(attr, (void *)&serversign,
829 /* Handle the signature verifications and public key verifying here */
831 if (verify->userpk.data) {
832 SilcPKCSType type = 0;
834 if (!strcmp(verify->userpk.type, "silc-rsa"))
835 type = SILC_PKCS_SILC;
836 else if (!strcmp(verify->userpk.type, "ssh-rsa"))
837 type = SILC_PKCS_SSH2;
838 else if (!strcmp(verify->userpk.type, "x509v3-sign-rsa"))
839 type = SILC_PKCS_X509V3;
840 else if (!strcmp(verify->userpk.type, "pgp-sign-rsa"))
841 type = SILC_PKCS_OPENPGP;
843 silc_pkcs_public_key_alloc(type, verify->userpk.data,
844 verify->userpk.data_len,
845 &verify->public_key);
849 /* Verify the signature now */
850 unsigned char *verifyd;
851 SilcUInt32 verify_len;
852 SilcBool verified = FALSE;
854 if (verify->public_key) {
855 verifyd = silc_attribute_get_verify_data(attrs, FALSE, &verify_len);
857 silc_pkcs_verify_async(verify->public_key, usersign.data,
858 usersign.data_len, verifyd, verify_len,
860 silc_query_attributes_verify, &verified);
863 printformat_module("fe-common/silc", server, NULL,
864 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_VERIFIED);
866 printformat_module("fe-common/silc", server, NULL,
867 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
872 printformat_module("fe-common/silc", server, NULL,
873 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
876 printformat_module("fe-common/silc", server, NULL,
877 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_NOT_PRESENT);
880 if (serversign.data) {
881 /* Verify the signature now */
882 SilcPublicKey public_key;
883 SilcPKCSType type = 0;
884 unsigned char *verifyd;
885 SilcUInt32 verify_len;
886 SilcBool verified = FALSE;
888 if (!strcmp(serverpk.type, "silc-rsa"))
889 type = SILC_PKCS_SILC;
890 else if (!strcmp(serverpk.type, "ssh-rsa"))
891 type = SILC_PKCS_SSH2;
892 else if (!strcmp(serverpk.type, "x509v3-sign-rsa"))
893 type = SILC_PKCS_X509V3;
894 else if (!strcmp(serverpk.type, "pgp-sign-rsa"))
895 type = SILC_PKCS_OPENPGP;
897 if (silc_pkcs_public_key_alloc(type, serverpk.data,
900 verifyd = silc_attribute_get_verify_data(attrs, TRUE, &verify_len);
902 silc_pkcs_verify_async(public_key, serversign.data,
903 serversign.data_len, verifyd,
904 verify_len, TRUE, sha1hash,
905 silc_query_attributes_verify, &verified);
907 printformat_module("fe-common/silc", server, NULL,
908 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_VERIFIED);
910 printformat_module("fe-common/silc", server, NULL,
911 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
914 silc_pkcs_public_key_free(public_key);
917 printformat_module("fe-common/silc", server, NULL,
918 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
922 if (verify->public_key) {
923 silc_verify_public_key(client, conn, SILC_CONN_CLIENT,
925 silc_query_attributes_print_final, verify);
928 silc_query_attributes_print_final(FALSE, verify);
932 static void silc_query_attributes_print_final(bool success, void *context)
934 AttrVerify verify = context;
935 SILC_SERVER_REC *server = verify->server;
937 unsigned char filename[256], *fingerprint = NULL, *tmp;
943 printformat_module("fe-common/silc", NULL, NULL,
944 MSGLEVEL_CRAP, SILCTXT_PUBKEY_VERIFIED, "user",
947 printformat_module("fe-common/silc", NULL, NULL,
948 MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOTVERIFIED, "user",
953 printformat_module("fe-common/silc", server, NULL,
954 MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
956 /* Replace all whitespaces with `_'. */
957 fingerprint = silc_hash_fingerprint(sha1hash,
959 verify->userpk.data_len);
960 for (i = 0; i < strlen(fingerprint); i++)
961 if (fingerprint[i] == ' ')
962 fingerprint[i] = '_';
964 /* Filename for dir */
965 tmp = fingerprint + strlen(fingerprint) - 9;
966 snprintf(filename, sizeof(filename) - 1, "%s/friends/%s",
967 get_irssi_dir(), tmp);
968 silc_free(fingerprint);
970 if ((stat(filename, &st)) == -1) {
971 /* Ask to accept save requested attributes */
972 format = format_get_text("fe-common/silc", NULL, NULL, NULL,
974 keyboard_entry_redirect((SIGNAL_FUNC)silc_query_attributes_accept,
977 /* Save new data to existing directory */
978 silc_query_attributes_accept("Y", verify);
984 static void silc_query_attributes_accept(const char *line, void *context)
986 AttrVerify verify = context;
987 SILC_SERVER_REC *server = verify->server;
990 unsigned char filename[256], filename2[256], *fingerprint = NULL, *tmp;
994 if (line[0] == 'Y' || line[0] == 'y') {
995 /* Save the attributes */
996 memset(filename, 0, sizeof(filename));
997 memset(filename2, 0, sizeof(filename2));
999 pw = getpwuid(getuid());
1003 /* Replace all whitespaces with `_'. */
1004 fingerprint = silc_hash_fingerprint(sha1hash,
1005 verify->userpk.data,
1006 verify->userpk.data_len);
1007 for (i = 0; i < strlen(fingerprint); i++)
1008 if (fingerprint[i] == ' ')
1009 fingerprint[i] = '_';
1011 /* Filename for dir */
1012 tmp = fingerprint + strlen(fingerprint) - 9;
1013 snprintf(filename, sizeof(filename) - 1, "%s/friends/%s",
1014 get_irssi_dir(), tmp);
1016 /* Create dir if it doesn't exist */
1017 if ((stat(filename, &st)) == -1) {
1018 /* If dir doesn't exist */
1019 if (errno == ENOENT) {
1020 if (pw->pw_uid == geteuid()) {
1021 if ((mkdir(filename, 0755)) == -1) {
1022 silc_say_error("Couldn't create `%s' directory",
1027 silc_say_error("Couldn't create `%s' directory due to a "
1028 "wrong uid!", filename);
1032 silc_say_error("%s", strerror(errno));
1037 /* Save the stuff to the directory */
1040 snprintf(filename2, sizeof(filename2) - 1, "%s/vcard", filename);
1041 if (verify->vcard.full_name) {
1042 tmp = silc_vcard_encode(&verify->vcard, &len);
1043 silc_file_writefile(filename2, tmp, len);
1047 /* Save public key */
1048 if (verify->public_key) {
1049 memset(filename2, 0, sizeof(filename2));
1050 snprintf(filename2, sizeof(filename2) - 1, "%s/clientkey_%s.pub",
1051 filename, fingerprint);
1052 silc_pkcs_save_public_key(filename2, verify->public_key,
1053 SILC_PKCS_FILE_BASE64);
1056 /* Save extension data */
1057 if (verify->extension) {
1058 memset(filename2, 0, sizeof(filename2));
1059 snprintf(filename2, sizeof(filename2) - 1, "%s/extension.mime",
1061 tmp = silc_mime_encode(verify->extension, &len);
1063 silc_file_writefile(filename2, tmp, len);
1066 /* Save MIME message data */
1067 if (verify->message) {
1068 memset(filename2, 0, sizeof(filename2));
1069 snprintf(filename2, sizeof(filename2) - 1, "%s/status_message.mime",
1071 tmp = silc_mime_encode(verify->message, &len);
1073 silc_file_writefile(filename2, tmp, len);
1076 printformat_module("fe-common/silc", server, NULL,
1077 MSGLEVEL_CRAP, SILCTXT_ATTR_SAVED, filename);
1081 silc_free(fingerprint);
1082 silc_free(verify->name);
1083 silc_vcard_free(&verify->vcard);