5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 - 2007 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"
29 #include "clientutil.h"
31 #include "fe-common/core/printtext.h"
32 #include "fe-common/core/fe-channels.h"
33 #include "fe-common/core/keyboard.h"
34 #include "fe-common/silc/module-formats.h"
36 static void silc_query_attributes_print_final(bool success, void *context);
37 static void silc_query_attributes_accept(const char *line, void *context,
38 SilcKeyboardPromptStatus reason);
40 QUERY_REC *silc_query_create(const char *server_tag,
41 const char *nick, int automatic)
45 g_return_val_if_fail(nick != NULL, NULL);
47 rec = g_new0(QUERY_REC, 1);
48 rec->chat_type = SILC_PROTOCOL;
49 rec->name = g_strdup(nick);
50 rec->server_tag = g_strdup(server_tag);
51 query_init(rec, automatic);
55 void silc_queries_init(void)
59 void silc_queries_deinit(void)
65 void command_attr(const char *data, SILC_SERVER_REC *server,
71 SilcUInt32 *argv_lens, *argv_types;
75 /* Now parse all arguments */
76 tmp = g_strconcat("ATTR", " ", data, NULL);
77 silc_parse_command_line(tmp, &argv, &argv_lens, &argv_types, &argc, 3);
81 /* Show all attributes */
82 printformat_module("fe-common/silc", server, NULL,
83 MSGLEVEL_CRAP, SILCTXT_ATTR_HEADER);
85 allowed = settings_get_bool("attr_allow");
86 printformat_module("fe-common/silc", server, NULL,
87 MSGLEVEL_CRAP, SILCTXT_ATTR_ALLOW,
88 allowed ? "Yes" : "No");
90 sv = settings_get_str("attr_vcard");
92 printformat_module("fe-common/silc", server, NULL,
93 MSGLEVEL_CRAP, SILCTXT_ATTR_VCARD_FILE, sv);
95 sv = settings_get_str("attr_services");
97 printformat_module("fe-common/silc", server, NULL,
98 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVICES, sv);
100 sv = settings_get_str("attr_status_mood");
102 printformat_module("fe-common/silc", server, NULL,
103 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MOOD, sv);
105 sv = settings_get_str("attr_status_text");
107 printformat_module("fe-common/silc", server, NULL,
108 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_TEXT, sv);
110 sv = settings_get_str("attr_status_message");
112 printformat_module("fe-common/silc", server, NULL,
113 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MESSAGE_FILE,
116 sv = settings_get_str("attr_preferred_language");
118 printformat_module("fe-common/silc", server, NULL,
119 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_LANGUAGE,
122 sv = settings_get_str("attr_preferred_contact");
124 printformat_module("fe-common/silc", server, NULL,
125 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_CONTACT,
128 sv = settings_get_str("attr_geolocation");
130 printformat_module("fe-common/silc", server, NULL,
131 MSGLEVEL_CRAP, SILCTXT_ATTR_GEOLOCATION,
134 sv = settings_get_str("attr_device_info");
136 printformat_module("fe-common/silc", server, NULL,
137 MSGLEVEL_CRAP, SILCTXT_ATTR_DEVICE_INFO,
140 sv = settings_get_str("attr_public_keys");
142 printformat_module("fe-common/silc", server, NULL,
143 MSGLEVEL_CRAP, SILCTXT_ATTR_PUBLIC_KEYS,
146 allowed = settings_get_bool("attr_timezone");
147 printformat_module("fe-common/silc", server, NULL,
148 MSGLEVEL_CRAP, SILCTXT_ATTR_TIMEZONE_ALLOW,
149 allowed ? "Yes" : "No");
151 printformat_module("fe-common/silc", server, NULL,
152 MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
157 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
159 if (!strcasecmp(argv[1], "-del")) {
160 /* Delete attribute */
161 if (!strcasecmp(argv[2], "vcard")) {
162 silc_client_attribute_del(silc_client, server->conn,
163 SILC_ATTRIBUTE_USER_INFO, NULL);
164 settings_set_str("attr_vcard", "");
165 } else if (!strcasecmp(argv[2], "services")) {
166 silc_client_attribute_del(silc_client, server->conn,
167 SILC_ATTRIBUTE_SERVICE, NULL);
168 settings_set_str("attr_services", argv[2]);
169 } else if (!strcasecmp(argv[2], "status_mood")) {
170 silc_client_attribute_del(silc_client, server->conn,
171 SILC_ATTRIBUTE_STATUS_MOOD, NULL);
172 settings_set_str("attr_status_mood", "");
173 } else if (!strcasecmp(argv[2], "status_text")) {
174 silc_client_attribute_del(silc_client, server->conn,
175 SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
176 settings_set_str("attr_status_text", "");
177 } else if (!strcasecmp(argv[2], "status_message")) {
178 silc_client_attribute_del(silc_client, server->conn,
179 SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
180 settings_set_str("attr_status_message", "");
181 } else if (!strcasecmp(argv[2], "preferred_language")) {
182 silc_client_attribute_del(silc_client, server->conn,
183 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
184 settings_set_str("attr_preferred_language", "");
185 } else if (!strcasecmp(argv[2], "preferred_contact")) {
186 silc_client_attribute_del(silc_client, server->conn,
187 SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
188 settings_set_str("attr_preferred_contact", "");
189 } else if (!strcasecmp(argv[2], "timezone")) {
191 } else if (!strcasecmp(argv[2], "geolocation")) {
192 silc_client_attribute_del(silc_client, server->conn,
193 SILC_ATTRIBUTE_GEOLOCATION, NULL);
194 settings_set_str("attr_geolocation", "");
195 } else if (!strcasecmp(argv[2], "device_info")) {
196 silc_client_attribute_del(silc_client, server->conn,
197 SILC_ATTRIBUTE_DEVICE_INFO, NULL);
198 settings_set_str("attr_device_info", "");
199 } else if (!strcasecmp(argv[2], "public_keys")) {
200 silc_client_attribute_del(silc_client, server->conn,
201 SILC_ATTRIBUTE_USER_PUBLIC_KEY, NULL);
202 settings_set_str("attr_public_keys", "");
204 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
209 /* Add new attribute */
210 if (!strcasecmp(argv[1], "allow")) {
211 allowed = !strcasecmp(argv[2], "ON") || !strcasecmp(argv[2], "YES");
212 settings_set_bool("attr_allow", allowed);
213 } else if (!strcasecmp(argv[1], "vcard")) {
214 settings_set_str("attr_vcard", argv[2]);
215 } else if (!strcasecmp(argv[1], "services")) {
216 settings_set_str("attr_services", argv[2]);
217 } else if (!strcasecmp(argv[1], "status_mood")) {
218 settings_set_str("attr_status_mood", argv[2]);
219 } else if (!strcasecmp(argv[1], "status_text")) {
220 settings_set_str("attr_status_text", argv[2]);
221 } else if (!strcasecmp(argv[1], "status_message")) {
222 settings_set_str("attr_status_message", argv[2]);
223 } else if (!strcasecmp(argv[1], "preferred_language")) {
224 settings_set_str("attr_preferred_language", argv[2]);
225 } else if (!strcasecmp(argv[1], "preferred_contact")) {
226 settings_set_str("attr_preferred_contact", argv[2]);
227 } else if (!strcasecmp(argv[1], "timezone")) {
228 allowed = !strcasecmp(argv[2], "ON") || !strcasecmp(argv[2], "YES");
229 settings_set_bool("attr_timezone", allowed);
230 } else if (!strcasecmp(argv[1], "geolocation")) {
231 settings_set_str("attr_geolocation", argv[2]);
232 } else if (!strcasecmp(argv[1], "device_info")) {
233 settings_set_str("attr_device_info", argv[2]);
234 } else if (!strcasecmp(argv[1], "public_keys")) {
235 settings_set_str("attr_public_keys", argv[2]);
237 cmd_return_error(CMDERR_NOT_ENOUGH_PARAMS);
240 silc_query_attributes_default(silc_client, server->conn);
243 /* Put default attributes to client library */
245 void silc_query_attributes_default(SilcClient client,
246 SilcClientConnection conn)
248 char *tmp, **list, **entry;
250 SilcUInt32 tmp_len, mask;
251 SilcAttributeObjService service;
253 SilcAttributeObjGeo geo;
254 SilcAttributeObjDevice dev;
255 SilcAttributeObjPk pk;
256 SilcVCardStruct vcard;
259 memset(&service, 0, sizeof(service));
260 memset(&geo, 0, sizeof(geo));
261 memset(&dev, 0, sizeof(dev));
262 memset(&pk, 0, sizeof(pk));
263 memset(&vcard, 0, sizeof(vcard));
265 allowed = settings_get_bool("attr_allow");
267 silc_client_attribute_del(silc_client, conn,
268 SILC_ATTRIBUTE_USER_INFO, NULL);
269 silc_client_attribute_del(silc_client, conn,
270 SILC_ATTRIBUTE_SERVICE, NULL);
271 silc_client_attribute_del(silc_client, conn,
272 SILC_ATTRIBUTE_STATUS_MOOD, NULL);
273 silc_client_attribute_del(silc_client, conn,
274 SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
275 silc_client_attribute_del(silc_client, conn,
276 SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
277 silc_client_attribute_del(silc_client, conn,
278 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
279 silc_client_attribute_del(silc_client, conn,
280 SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
281 silc_client_attribute_del(silc_client, conn,
282 SILC_ATTRIBUTE_TIMEZONE, NULL);
283 silc_client_attribute_del(silc_client, conn,
284 SILC_ATTRIBUTE_GEOLOCATION, NULL);
285 silc_client_attribute_del(silc_client, conn,
286 SILC_ATTRIBUTE_DEVICE_INFO, NULL);
287 silc_client_attribute_del(silc_client, conn,
288 SILC_ATTRIBUTE_USER_PUBLIC_KEY, NULL);
292 sv = settings_get_str("attr_vcard");
295 silc_client_attribute_del(silc_client, conn,
296 SILC_ATTRIBUTE_USER_INFO, NULL);
297 tmp = silc_file_readfile(sv, &tmp_len);
300 if (silc_vcard_decode(tmp, tmp_len, &vcard))
301 silc_client_attribute_add(silc_client, conn,
302 SILC_ATTRIBUTE_USER_INFO, (void *)&vcard,
305 silc_vcard_free(&vcard);
309 sv = settings_get_str("attr_services");
312 silc_client_attribute_del(silc_client, conn,
313 SILC_ATTRIBUTE_SERVICE, NULL);
314 list = g_strsplit(sv, " ", -1);
315 for (entry = list; *entry != NULL; entry++) {
316 if (!strchr(*entry, ':'))
318 tmp = strchr(*entry, ':') + 1;
321 memset(&service, 0, sizeof(service));
322 service.port = atoi(tmp);
323 *strchr(*entry, ':') = '\0';
324 silc_strncat(service.address, sizeof(service.address), *entry,
326 service.status = TRUE;
328 silc_client_attribute_add(silc_client, conn,
329 SILC_ATTRIBUTE_SERVICE, &service,
335 sv = settings_get_str("attr_status_mood");
337 /* Put STATUS_MOOD */
338 silc_client_attribute_del(silc_client, conn,
339 SILC_ATTRIBUTE_STATUS_MOOD, NULL);
341 list = g_strsplit(sv, " ", -1);
342 for (entry = list; *entry != NULL; entry++) {
343 if (!strcasecmp(*entry, "NORMAL"))
344 mask |= SILC_ATTRIBUTE_MOOD_NORMAL;
345 if (!strcasecmp(*entry, "HAPPY"))
346 mask |= SILC_ATTRIBUTE_MOOD_HAPPY;
347 if (!strcasecmp(*entry, "SAD"))
348 mask |= SILC_ATTRIBUTE_MOOD_SAD;
349 if (!strcasecmp(*entry, "ANGRY"))
350 mask |= SILC_ATTRIBUTE_MOOD_ANGRY;
351 if (!strcasecmp(*entry, "JEALOUS"))
352 mask |= SILC_ATTRIBUTE_MOOD_JEALOUS;
353 if (!strcasecmp(*entry, "ASHAMED"))
354 mask |= SILC_ATTRIBUTE_MOOD_ASHAMED;
355 if (!strcasecmp(*entry, "INVINCIBLE"))
356 mask |= SILC_ATTRIBUTE_MOOD_INVINCIBLE;
357 if (!strcasecmp(*entry, "INLOVE"))
358 mask |= SILC_ATTRIBUTE_MOOD_INLOVE;
359 if (!strcasecmp(*entry, "SLEEPY"))
360 mask |= SILC_ATTRIBUTE_MOOD_SLEEPY;
361 if (!strcasecmp(*entry, "BORED"))
362 mask |= SILC_ATTRIBUTE_MOOD_BORED;
363 if (!strcasecmp(*entry, "EXCITED"))
364 mask |= SILC_ATTRIBUTE_MOOD_EXCITED;
365 if (!strcasecmp(*entry, "ANXIOUS"))
366 mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS;
368 silc_client_attribute_add(silc_client, conn,
369 SILC_ATTRIBUTE_STATUS_MOOD, (void *)mask,
374 sv = settings_get_str("attr_status_text");
376 /* Put STATUS_TEXT */
377 silc_client_attribute_del(silc_client, conn,
378 SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
379 silc_client_attribute_add(silc_client, conn,
380 SILC_ATTRIBUTE_STATUS_FREETEXT, (void *)sv,
384 sv = settings_get_str("attr_status_message");
386 /* Put STATUS_MESSAGE */
387 silc_client_attribute_del(silc_client, conn,
388 SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
389 tmp = silc_file_readfile(sv, &tmp_len);
391 mime = silc_mime_decode(NULL, tmp, tmp_len);
393 silc_client_attribute_add(silc_client, conn,
394 SILC_ATTRIBUTE_STATUS_MESSAGE, mime,
400 sv = settings_get_str("attr_preferred_language");
402 /* Put PREFERRED_LANGUAGE */
403 silc_client_attribute_del(silc_client, conn,
404 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
405 list = g_strsplit(sv, " ", -1);
406 for (entry = list; *entry != NULL; entry++) {
407 silc_client_attribute_add(silc_client, conn,
408 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, *entry,
414 sv = settings_get_str("attr_preferred_contact");
416 /* Put PREFERRED_CONTACT */
417 silc_client_attribute_del(silc_client, conn,
418 SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
420 list = g_strsplit(sv, " ", -1);
421 for (entry = list; *entry != NULL; entry++) {
422 if (!strcasecmp(*entry, "NONE"))
424 if (!strcasecmp(*entry, "EMAIL"))
425 mask |= SILC_ATTRIBUTE_CONTACT_EMAIL;
426 if (!strcasecmp(*entry, "CALL"))
427 mask |= SILC_ATTRIBUTE_CONTACT_CALL;
428 if (!strcasecmp(*entry, "PAGE"))
429 mask |= SILC_ATTRIBUTE_CONTACT_PAGE;
430 if (!strcasecmp(*entry, "SMS"))
431 mask |= SILC_ATTRIBUTE_CONTACT_SMS;
432 if (!strcasecmp(*entry, "MMS"))
433 mask |= SILC_ATTRIBUTE_CONTACT_MMS;
434 if (!strcasecmp(*entry, "CHAT"))
435 mask |= SILC_ATTRIBUTE_CONTACT_CHAT;
436 if (!strcasecmp(*entry, "VIDEO"))
437 mask |= SILC_ATTRIBUTE_CONTACT_VIDEO;
439 silc_client_attribute_add(silc_client, conn,
440 SILC_ATTRIBUTE_PREFERRED_CONTACT, (void *)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);
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;
566 void silc_query_attributes_print(SILC_SERVER_REC *server,
568 SilcClientConnection conn,
570 SilcClientEntry client_entry)
572 SilcAttributePayload attr;
573 SilcAttribute attribute;
575 SilcAttributeObjPk serverpk, usersign, serversign;
578 printformat_module("fe-common/silc", server, NULL,
579 MSGLEVEL_CRAP, SILCTXT_ATTR_HEADER);
581 memset(&serverpk, 0, sizeof(serverpk));
582 memset(&usersign, 0, sizeof(usersign));
583 memset(&serversign, 0, sizeof(serversign));
585 verify = silc_calloc(1, sizeof(*verify));
588 verify->client = client;
589 verify->server = server;
590 verify->name = strdup(client_entry->nickname);
592 silc_dlist_start(attrs);
593 while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
594 attribute = silc_attribute_get_attribute(attr);
595 memset(tmp, 0, sizeof(tmp));
599 case SILC_ATTRIBUTE_USER_INFO:
601 if (!silc_attribute_get_object(attr, (void *)&verify->vcard,
602 sizeof(verify->vcard)))
604 printformat_module("fe-common/silc", server, NULL,
605 MSGLEVEL_CRAP, SILCTXT_ATTR_VCARD_FILE,
610 case SILC_ATTRIBUTE_SERVICE:
612 SilcAttributeObjService service;
613 memset(&service, 0, sizeof(service));
614 if (!silc_attribute_get_object(attr, (void *)&service,
617 snprintf(tmp, sizeof(tmp) - 1, "%s:%d (logged %s) idle %d seconds",
618 service.address, (unsigned int)service.port,
619 service.status ? "in" : "out",
620 (unsigned int)service.idle);
621 printformat_module("fe-common/silc", server, NULL,
622 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVICES, tmp);
626 case SILC_ATTRIBUTE_STATUS_MOOD:
629 if (!silc_attribute_get_object(attr, (void *)&mask, sizeof(mask)))
632 silc_strncat(tmp, sizeof(tmp), "NORMAL ", strlen(" NORMAL"));
633 if (mask & SILC_ATTRIBUTE_MOOD_HAPPY)
634 silc_strncat(tmp, sizeof(tmp), "HAPPY ", strlen(" HAPPY"));
635 if (mask & SILC_ATTRIBUTE_MOOD_SAD)
636 silc_strncat(tmp, sizeof(tmp), "SAD ", strlen(" SAD"));
637 if (mask & SILC_ATTRIBUTE_MOOD_ANGRY)
638 silc_strncat(tmp, sizeof(tmp), "ANGRY ", strlen(" ANGRY"));
639 if (mask & SILC_ATTRIBUTE_MOOD_JEALOUS)
640 silc_strncat(tmp, sizeof(tmp), "JEALOUS ", strlen(" JEALOUS"));
641 if (mask & SILC_ATTRIBUTE_MOOD_ASHAMED)
642 silc_strncat(tmp, sizeof(tmp), "ASHAMED ", strlen(" ASHAMED"));
643 if (mask & SILC_ATTRIBUTE_MOOD_INVINCIBLE)
644 silc_strncat(tmp, sizeof(tmp), "INVINCIBLE ", strlen(" INVINCIBLE"));
645 if (mask & SILC_ATTRIBUTE_MOOD_INLOVE)
646 silc_strncat(tmp, sizeof(tmp), "INLOVE ", strlen(" INLOVE"));
647 if (mask & SILC_ATTRIBUTE_MOOD_SLEEPY)
648 silc_strncat(tmp, sizeof(tmp), "SLEEPY ", strlen(" SLEEPY"));
649 if (mask & SILC_ATTRIBUTE_MOOD_BORED)
650 silc_strncat(tmp, sizeof(tmp), "BORED ", strlen(" BORED"));
651 if (mask & SILC_ATTRIBUTE_MOOD_EXCITED)
652 silc_strncat(tmp, sizeof(tmp), "EXCITED ", strlen(" EXCITED"));
653 if (mask & SILC_ATTRIBUTE_MOOD_ANXIOUS)
654 silc_strncat(tmp, sizeof(tmp), "ANXIOUS ", strlen(" ANXIOUS"));
655 printformat_module("fe-common/silc", server, NULL,
656 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MOOD, tmp);
660 case SILC_ATTRIBUTE_STATUS_FREETEXT:
662 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
664 printformat_module("fe-common/silc", server, NULL,
665 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_TEXT, tmp);
669 case SILC_ATTRIBUTE_STATUS_MESSAGE:
671 verify->message = silc_mime_alloc();
672 if (!verify->message)
674 if (!silc_attribute_get_object(attr, (void *)verify->message,
675 sizeof(*verify->message)))
677 printformat_module("fe-common/silc", server, NULL,
678 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MESSAGE,
683 case SILC_ATTRIBUTE_PREFERRED_LANGUAGE:
685 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
687 printformat_module("fe-common/silc", server, NULL,
688 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_LANGUAGE,
693 case SILC_ATTRIBUTE_PREFERRED_CONTACT:
696 if (!silc_attribute_get_object(attr, (void *)&mask, sizeof(mask)))
699 silc_strncat(tmp, sizeof(tmp), "NONE ", strlen(" NONE"));
700 if (mask & SILC_ATTRIBUTE_CONTACT_CHAT)
701 silc_strncat(tmp, sizeof(tmp), "CHAT ", strlen(" CHAT"));
702 if (mask & SILC_ATTRIBUTE_CONTACT_EMAIL)
703 silc_strncat(tmp, sizeof(tmp), "EMAIL ", strlen(" EMAIL"));
704 if (mask & SILC_ATTRIBUTE_CONTACT_CALL)
705 silc_strncat(tmp, sizeof(tmp), "CALL ", strlen(" CALL"));
706 if (mask & SILC_ATTRIBUTE_CONTACT_PAGE)
707 silc_strncat(tmp, sizeof(tmp), "PAGE ", strlen(" PAGE"));
708 if (mask & SILC_ATTRIBUTE_CONTACT_SMS)
709 silc_strncat(tmp, sizeof(tmp), "SMS ", strlen(" SMS"));
710 if (mask & SILC_ATTRIBUTE_CONTACT_MMS)
711 silc_strncat(tmp, sizeof(tmp), "MMS ", strlen(" MMS"));
712 if (mask & SILC_ATTRIBUTE_CONTACT_VIDEO)
713 silc_strncat(tmp, sizeof(tmp), "VIDEO ", strlen(" VIDEO"));
714 printformat_module("fe-common/silc", server, NULL,
715 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_CONTACT, tmp);
719 case SILC_ATTRIBUTE_TIMEZONE:
721 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
723 printformat_module("fe-common/silc", server, NULL,
724 MSGLEVEL_CRAP, SILCTXT_ATTR_TIMEZONE, tmp);
728 case SILC_ATTRIBUTE_EXTENSION:
730 verify->extension = silc_mime_alloc();
731 if (!verify->extension)
733 if (!silc_attribute_get_object(attr, (void *)verify->extension,
734 sizeof(*verify->extension)))
736 printformat_module("fe-common/silc", server, NULL,
737 MSGLEVEL_CRAP, SILCTXT_ATTR_EXTENSION,
742 case SILC_ATTRIBUTE_GEOLOCATION:
744 SilcAttributeObjGeo geo;
745 memset(&geo, 0, sizeof(geo));
746 if (!silc_attribute_get_object(attr, (void *)&geo, sizeof(geo)))
748 snprintf(tmp, sizeof(tmp) - 1, "%s:%s:%s:%s",
749 geo.longitude ? geo.longitude : "",
750 geo.latitude ? geo.latitude : "",
751 geo.altitude ? geo.altitude : "",
752 geo.accuracy ? geo.accuracy : "");
753 printformat_module("fe-common/silc", server, NULL,
754 MSGLEVEL_CRAP, SILCTXT_ATTR_GEOLOCATION, tmp);
758 case SILC_ATTRIBUTE_DEVICE_INFO:
760 SilcAttributeObjDevice dev;
761 memset(&dev, 0, sizeof(dev));
762 if (!silc_attribute_get_object(attr, (void *)&dev, sizeof(dev)))
764 snprintf(tmp, sizeof(tmp) - 1, "%s:%s:%s:%s:%s",
765 (dev.type == SILC_ATTRIBUTE_DEVICE_COMPUTER ? "COMPUTER" :
766 dev.type == SILC_ATTRIBUTE_DEVICE_PDA ? "PDA" :
767 dev.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE ?
769 dev.type == SILC_ATTRIBUTE_DEVICE_TERMINAL ? "TERMINAL" :
771 dev.manufacturer ? dev.manufacturer : "",
772 dev.version ? dev.version : "",
773 dev.model ? dev.model: "",
774 dev.language ? dev.language : "");
775 printformat_module("fe-common/silc", server, NULL,
776 MSGLEVEL_CRAP, SILCTXT_ATTR_DEVICE_INFO, tmp);
780 case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
782 if (verify->userpk.type)
784 if (!silc_attribute_get_object(attr, (void *)&verify->userpk,
785 sizeof(verify->userpk)))
790 case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
794 if (!silc_attribute_get_object(attr, (void *)&serverpk,
800 case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
804 if (!silc_attribute_get_object(attr, (void *)&usersign,
810 case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
814 if (!silc_attribute_get_object(attr, (void *)&serversign,
825 /* Handle the signature verifications and public key verifying here */
827 if (verify->userpk.data) {
828 SilcPKCSType type = 0;
830 if (!strcmp(verify->userpk.type, "silc-rsa"))
831 type = SILC_PKCS_SILC;
832 else if (!strcmp(verify->userpk.type, "ssh-rsa"))
833 type = SILC_PKCS_SSH2;
834 else if (!strcmp(verify->userpk.type, "x509v3-sign-rsa"))
835 type = SILC_PKCS_X509V3;
836 else if (!strcmp(verify->userpk.type, "pgp-sign-rsa"))
837 type = SILC_PKCS_OPENPGP;
839 silc_pkcs_public_key_alloc(type, verify->userpk.data,
840 verify->userpk.data_len,
841 &verify->public_key);
845 /* Verify the signature now */
846 unsigned char *verifyd;
847 SilcUInt32 verify_len;
849 if (verify->public_key) {
850 verifyd = silc_attribute_get_verify_data(attrs, FALSE, &verify_len);
851 if (verifyd && silc_pkcs_verify(verify->public_key,
856 printformat_module("fe-common/silc", server, NULL,
857 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_VERIFIED);
859 printformat_module("fe-common/silc", server, NULL,
860 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
865 printformat_module("fe-common/silc", server, NULL,
866 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
869 printformat_module("fe-common/silc", server, NULL,
870 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_NOT_PRESENT);
873 if (serversign.data) {
874 /* Verify the signature now */
875 SilcPublicKey public_key;
876 SilcPKCSType type = 0;
877 unsigned char *verifyd;
878 SilcUInt32 verify_len;
880 if (!strcmp(serverpk.type, "silc-rsa"))
881 type = SILC_PKCS_SILC;
882 else if (!strcmp(serverpk.type, "ssh-rsa"))
883 type = SILC_PKCS_SSH2;
884 else if (!strcmp(serverpk.type, "x509v3-sign-rsa"))
885 type = SILC_PKCS_X509V3;
886 else if (!strcmp(serverpk.type, "pgp-sign-rsa"))
887 type = SILC_PKCS_OPENPGP;
889 if (silc_pkcs_public_key_alloc(type, serverpk.data,
892 verifyd = silc_attribute_get_verify_data(attrs, TRUE, &verify_len);
893 if (verifyd && silc_pkcs_verify(public_key,
898 printformat_module("fe-common/silc", server, NULL,
899 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_VERIFIED);
901 printformat_module("fe-common/silc", server, NULL,
902 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
905 silc_pkcs_public_key_free(public_key);
908 printformat_module("fe-common/silc", server, NULL,
909 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
913 if (verify->public_key) {
914 silc_verify_public_key(client, conn, SILC_CONN_CLIENT,
916 silc_query_attributes_print_final, verify);
919 silc_query_attributes_print_final(FALSE, verify);
923 static void silc_query_attributes_print_final(bool success, void *context)
925 AttrVerify verify = context;
926 SILC_SERVER_REC *server = verify->server;
928 unsigned char filename[256], *fingerprint = NULL, *tmp;
935 printformat_module("fe-common/silc", NULL, NULL,
936 MSGLEVEL_CRAP, SILCTXT_PUBKEY_VERIFIED, "user",
939 printformat_module("fe-common/silc", NULL, NULL,
940 MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOTVERIFIED, "user",
945 printformat_module("fe-common/silc", server, NULL,
946 MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
948 /* Replace all whitespaces with `_'. */
949 fingerprint = silc_hash_fingerprint(sha1hash,
951 verify->userpk.data_len);
953 len = strlen(fingerprint);
955 for (i = 0; i < len; i++)
956 if (fingerprint[i] == ' ')
957 fingerprint[i] = '_';
959 /* Filename for dir */
960 tmp = fingerprint + strlen(fingerprint) - 9;
961 snprintf(filename, sizeof(filename) - 1, "%s/friends/%s",
962 get_irssi_dir(), tmp);
963 silc_free(fingerprint);
965 if ((stat(filename, &st)) == -1) {
966 /* Ask to accept save requested attributes */
967 format = format_get_text("fe-common/silc", NULL, NULL, NULL,
969 silc_keyboard_entry_redirect(silc_query_attributes_accept,
970 format, 0, verify, &server->prompt_op);
972 /* Save new data to existing directory */
973 verify->autoaccept = TRUE; /* Ensure we don't twiddle the async context */
974 silc_query_attributes_accept("Y", verify, KeyboardCompletionSuccess);
980 static void silc_query_attributes_accept(const char *line, void *context,
981 SilcKeyboardPromptStatus reason)
983 AttrVerify verify = context;
984 SILC_SERVER_REC *server = verify->server;
987 unsigned char filename[256], filename2[256], *fingerprint = NULL, *tmp;
990 bool success = (reason == KeyboardCompletionSuccess);
992 if (success && (line[0] == 'Y' || line[0] == 'y')) {
993 /* Save the attributes */
994 memset(filename, 0, sizeof(filename));
995 memset(filename2, 0, sizeof(filename2));
997 pw = getpwuid(getuid());
1001 /* Replace all whitespaces with `_'. */
1002 fingerprint = silc_hash_fingerprint(sha1hash,
1003 verify->userpk.data,
1004 verify->userpk.data_len);
1005 for (i = 0; i < strlen(fingerprint); i++)
1006 if (fingerprint[i] == ' ')
1007 fingerprint[i] = '_';
1009 /* Filename for dir */
1010 tmp = fingerprint + strlen(fingerprint) - 9;
1011 snprintf(filename, sizeof(filename) - 1, "%s/friends/%s",
1012 get_irssi_dir(), tmp);
1014 /* Create dir if it doesn't exist */
1015 if ((stat(filename, &st)) == -1) {
1016 /* If dir doesn't exist */
1017 if (errno == ENOENT) {
1018 if (pw->pw_uid == geteuid()) {
1019 if ((mkdir(filename, 0755)) == -1) {
1020 silc_say_error("Couldn't create `%s' directory",
1025 silc_say_error("Couldn't create `%s' directory due to a "
1026 "wrong uid!", filename);
1030 silc_say_error("%s", strerror(errno));
1035 /* Save the stuff to the directory */
1038 snprintf(filename2, sizeof(filename2) - 1, "%s/vcard", filename);
1039 if (verify->vcard.full_name) {
1040 tmp = silc_vcard_encode(&verify->vcard, &len);
1041 silc_file_writefile(filename2, tmp, len);
1045 /* Save public key */
1046 if (verify->public_key) {
1047 memset(filename2, 0, sizeof(filename2));
1048 snprintf(filename2, sizeof(filename2) - 1, "%s/clientkey_%s.pub",
1049 filename, fingerprint);
1050 silc_pkcs_save_public_key(filename2, verify->public_key,
1051 SILC_PKCS_FILE_BASE64);
1054 /* Save extension data */
1055 if (verify->extension) {
1056 memset(filename2, 0, sizeof(filename2));
1057 snprintf(filename2, sizeof(filename2) - 1, "%s/extension.mime",
1059 tmp = silc_mime_encode(verify->extension, &len);
1061 silc_file_writefile(filename2, tmp, len);
1064 /* Save MIME message data */
1065 if (verify->message) {
1066 memset(filename2, 0, sizeof(filename2));
1067 snprintf(filename2, sizeof(filename2) - 1, "%s/status_message.mime",
1069 tmp = silc_mime_encode(verify->message, &len);
1071 silc_file_writefile(filename2, tmp, len);
1074 printformat_module("fe-common/silc", server, NULL,
1075 MSGLEVEL_CRAP, SILCTXT_ATTR_SAVED, filename);
1079 if((!verify->autoaccept) && (reason != KeyboardCompletionFailed))
1080 verify->server->prompt_op = NULL;
1081 silc_free(fingerprint);
1082 silc_free(verify->name);
1083 silc_vcard_free(&verify->vcard);