5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 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[1], "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[1], "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[1], "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[1], "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[1], "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[1], "preferred_langauge")) {
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[1], "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[1], "timezone")) {
189 } else if (!strcasecmp(argv[1], "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[1], "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[1], "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_langauge")) {
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;
250 SilcAttributeObjMime mime;
251 SilcAttributeObjGeo geo;
252 SilcAttributeObjDevice dev;
253 SilcAttributeObjPk pk;
254 SilcVCardStruct vcard;
257 memset(&service, 0, sizeof(service));
258 memset(&mime, 0, sizeof(mime));
259 memset(&geo, 0, sizeof(geo));
260 memset(&dev, 0, sizeof(dev));
261 memset(&pk, 0, sizeof(pk));
262 memset(&vcard, 0, sizeof(vcard));
264 sv = settings_get_str("attr_vcard");
267 silc_client_attribute_del(silc_client, conn,
268 SILC_ATTRIBUTE_USER_INFO, NULL);
269 tmp = silc_file_readfile(sv, &tmp_len);
270 if (tmp && silc_vcard_decode(tmp, tmp_len, &vcard))
271 silc_client_attribute_add(silc_client, conn,
272 SILC_ATTRIBUTE_USER_INFO, (void *)&vcard,
274 silc_vcard_free(&vcard);
278 sv = settings_get_str("attr_services");
281 silc_client_attribute_del(silc_client, conn,
282 SILC_ATTRIBUTE_SERVICE, NULL);
283 list = g_strsplit(sv, " ", -1);
284 for (entry = list; *entry != NULL; entry++) {
285 if (!strchr(*entry, ':'))
287 tmp = strchr(*entry, ':') + 1;
290 service.port = atoi(tmp);
291 *strchr(*entry, ':') = '\0';
292 silc_strncat(service.address, sizeof(service.address), *entry,
294 service.status = TRUE;
295 silc_client_attribute_add(silc_client, conn,
296 SILC_ATTRIBUTE_SERVICE, &service,
302 sv = settings_get_str("attr_status_mood");
304 /* Put STATUS_MOOD */
305 silc_client_attribute_del(silc_client, conn,
306 SILC_ATTRIBUTE_STATUS_MOOD, NULL);
308 list = g_strsplit(sv, " ", -1);
309 for (entry = list; *entry != NULL; entry++) {
310 if (!strcasecmp(*entry, "NORMAL"))
311 mask |= SILC_ATTRIBUTE_MOOD_NORMAL;
312 if (!strcasecmp(*entry, "HAPPY"))
313 mask |= SILC_ATTRIBUTE_MOOD_HAPPY;
314 if (!strcasecmp(*entry, "SAD"))
315 mask |= SILC_ATTRIBUTE_MOOD_SAD;
316 if (!strcasecmp(*entry, "ANGRY"))
317 mask |= SILC_ATTRIBUTE_MOOD_ANGRY;
318 if (!strcasecmp(*entry, "JEALOUS"))
319 mask |= SILC_ATTRIBUTE_MOOD_JEALOUS;
320 if (!strcasecmp(*entry, "ASHAMED"))
321 mask |= SILC_ATTRIBUTE_MOOD_ASHAMED;
322 if (!strcasecmp(*entry, "INVINCIBLE"))
323 mask |= SILC_ATTRIBUTE_MOOD_INVINCIBLE;
324 if (!strcasecmp(*entry, "INLOVE"))
325 mask |= SILC_ATTRIBUTE_MOOD_INLOVE;
326 if (!strcasecmp(*entry, "SLEEPY"))
327 mask |= SILC_ATTRIBUTE_MOOD_SLEEPY;
328 if (!strcasecmp(*entry, "BORED"))
329 mask |= SILC_ATTRIBUTE_MOOD_BORED;
330 if (!strcasecmp(*entry, "EXCITED"))
331 mask |= SILC_ATTRIBUTE_MOOD_EXCITED;
332 if (!strcasecmp(*entry, "ANXIOUS"))
333 mask |= SILC_ATTRIBUTE_MOOD_ANXIOUS;
334 silc_client_attribute_add(silc_client, conn,
335 SILC_ATTRIBUTE_STATUS_MOOD, (void *)mask,
341 sv = settings_get_str("attr_status_text");
343 /* Put STATUS_TEXT */
344 silc_client_attribute_del(silc_client, conn,
345 SILC_ATTRIBUTE_STATUS_FREETEXT, NULL);
346 silc_client_attribute_add(silc_client, conn,
347 SILC_ATTRIBUTE_STATUS_FREETEXT, (void *)sv,
351 sv = settings_get_str("attr_status_message");
353 /* Put STATUS_MESSAGE */
354 silc_client_attribute_del(silc_client, conn,
355 SILC_ATTRIBUTE_STATUS_MESSAGE, NULL);
356 tmp = silc_file_readfile(sv, &tmp_len);
358 mime.mime = (const unsigned char *)tmp;
359 mime.mime_len = tmp_len;
360 silc_client_attribute_add(silc_client, conn,
361 SILC_ATTRIBUTE_STATUS_MESSAGE, &mime,
367 sv = settings_get_str("attr_preferred_language");
369 /* Put PREFERRED_LANGUAGE */
370 silc_client_attribute_del(silc_client, conn,
371 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, NULL);
372 list = g_strsplit(sv, " ", -1);
373 for (entry = list; *entry != NULL; entry++) {
374 silc_client_attribute_add(silc_client, conn,
375 SILC_ATTRIBUTE_PREFERRED_LANGUAGE, *entry,
381 sv = settings_get_str("attr_preferred_contact");
383 /* Put PREFERRED_CONTACT */
384 silc_client_attribute_del(silc_client, conn,
385 SILC_ATTRIBUTE_PREFERRED_CONTACT, NULL);
387 list = g_strsplit(sv, " ", -1);
388 for (entry = list; *entry != NULL; entry++) {
389 if (!strcasecmp(*entry, "NONE"))
391 if (!strcasecmp(*entry, "EMAIL"))
392 mask |= SILC_ATTRIBUTE_CONTACT_EMAIL;
393 if (!strcasecmp(*entry, "CALL"))
394 mask |= SILC_ATTRIBUTE_CONTACT_CALL;
395 if (!strcasecmp(*entry, "PAGE"))
396 mask |= SILC_ATTRIBUTE_CONTACT_PAGE;
397 if (!strcasecmp(*entry, "SMS"))
398 mask |= SILC_ATTRIBUTE_CONTACT_SMS;
399 if (!strcasecmp(*entry, "MMS"))
400 mask |= SILC_ATTRIBUTE_CONTACT_MMS;
401 if (!strcasecmp(*entry, "CHAT"))
402 mask |= SILC_ATTRIBUTE_CONTACT_CHAT;
403 silc_client_attribute_add(silc_client, conn,
404 SILC_ATTRIBUTE_PREFERRED_CONTACT, (void *)mask,
411 allowed = settings_get_bool("attr_timezone");
412 silc_client_attribute_del(silc_client, conn,
413 SILC_ATTRIBUTE_TIMEZONE, NULL);
415 silc_client_attribute_add(silc_client, conn,
416 SILC_ATTRIBUTE_TIMEZONE, "foo", 3);
418 sv = settings_get_str("attr_geolocation");
420 /* Put GEOLOCATION */
421 silc_client_attribute_del(silc_client, conn,
422 SILC_ATTRIBUTE_GEOLOCATION, NULL);
423 list = g_strsplit(sv, ":", -1);
424 for (entry = list; *entry != NULL; entry++) {
425 if (!geo.longitude) {
426 geo.longitude = *entry;
430 geo.latitude = *entry;
434 geo.altitude = *entry;
438 geo.accuracy = *entry;
442 silc_client_attribute_add(silc_client, conn,
443 SILC_ATTRIBUTE_GEOLOCATION, &geo,
448 sv = settings_get_str("attr_device_info");
450 /* Put DEVICE_INFO */
451 silc_client_attribute_del(silc_client, conn,
452 SILC_ATTRIBUTE_DEVICE_INFO, NULL);
454 list = g_strsplit(sv, ":", -1);
455 for (entry = list; *entry != NULL; entry++) {
458 if (!strcasecmp(*entry, "COMPUTER"))
459 dev.type = SILC_ATTRIBUTE_DEVICE_COMPUTER;
460 if (!strcasecmp(*entry, "MOBILE_PHONE"))
461 dev.type = SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE;
462 if (!strcasecmp(sv, "PDA"))
463 dev.type = SILC_ATTRIBUTE_DEVICE_PDA;
464 if (!strcasecmp(sv, "TERMINAL"))
465 dev.type = SILC_ATTRIBUTE_DEVICE_TERMINAL;
468 if (!dev.manufacturer) {
469 dev.manufacturer = *entry;
473 dev.version = *entry;
481 dev.language = *entry;
485 silc_client_attribute_add(silc_client, conn,
486 SILC_ATTRIBUTE_DEVICE_INFO, &dev,
491 sv = settings_get_str("attr_public_keys");
493 /* Put USER_PUBLIC_KEY */
494 silc_client_attribute_del(silc_client, conn,
495 SILC_ATTRIBUTE_USER_PUBLIC_KEY, NULL);
496 list = g_strsplit(sv, " ", -1);
497 for (entry = list; *entry != NULL; entry++) {
498 if (!strncasecmp(*entry, "silc-rsa:", 8)) {
499 tmp = silc_file_readfile((*entry) + 8, &tmp_len);
501 pk.type = "silc-rsa";
503 pk.data_len = tmp_len;
504 silc_client_attribute_add(silc_client, conn,
505 SILC_ATTRIBUTE_USER_PUBLIC_KEY, &pk,
510 silc_say_error("Unsupported public key type '%s'", *entry);
519 SILC_SERVER_REC *server;
521 SilcAttributeObjPk userpk;
522 SilcVCardStruct vcard;
523 SilcAttributeObjMime message;
524 SilcAttributeObjMime extension;
527 void silc_query_attributes_print(SILC_SERVER_REC *server,
529 SilcClientConnection conn,
531 SilcClientEntry client_entry)
533 SilcAttributePayload attr;
534 SilcAttribute attribute;
536 SilcAttributeObjPk serverpk, usersign, serversign;
539 printformat_module("fe-common/silc", server, NULL,
540 MSGLEVEL_CRAP, SILCTXT_ATTR_HEADER);
542 memset(&serverpk, 0, sizeof(serverpk));
543 memset(&usersign, 0, sizeof(usersign));
544 memset(&serversign, 0, sizeof(serversign));
546 verify = silc_calloc(1, sizeof(*verify));
549 verify->client = client;
550 verify->server = server;
551 verify->name = strdup(client_entry->nickname);
553 silc_dlist_start(attrs);
554 while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
555 attribute = silc_attribute_get_attribute(attr);
556 memset(tmp, 0, sizeof(tmp));
560 case SILC_ATTRIBUTE_USER_INFO:
562 if (!silc_attribute_get_object(attr, (void *)&verify->vcard,
563 sizeof(verify->vcard)))
565 printformat_module("fe-common/silc", server, NULL,
566 MSGLEVEL_CRAP, SILCTXT_ATTR_VCARD_FILE,
571 case SILC_ATTRIBUTE_SERVICE:
573 SilcAttributeObjService service;
574 if (!silc_attribute_get_object(attr, (void *)&service,
577 snprintf(tmp, sizeof(tmp) - 1, "%s:%d (logged %s)",
578 service.address, (unsigned int)service.port,
579 service.status ? "in" : "out");
580 printformat_module("fe-common/silc", server, NULL,
581 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVICES, tmp);
585 case SILC_ATTRIBUTE_STATUS_MOOD:
588 if (!silc_attribute_get_object(attr, (void *)&mask, sizeof(mask)))
591 silc_strncat(tmp, sizeof(tmp), "NORMAL ", strlen(" NORMAL"));
592 if (mask & SILC_ATTRIBUTE_MOOD_HAPPY)
593 silc_strncat(tmp, sizeof(tmp), "HAPPY ", strlen(" HAPPY"));
594 if (mask & SILC_ATTRIBUTE_MOOD_SAD)
595 silc_strncat(tmp, sizeof(tmp), "SAD ", strlen(" SAD"));
596 if (mask & SILC_ATTRIBUTE_MOOD_ANGRY)
597 silc_strncat(tmp, sizeof(tmp), "ANGRY ", strlen(" ANGRY"));
598 if (mask & SILC_ATTRIBUTE_MOOD_JEALOUS)
599 silc_strncat(tmp, sizeof(tmp), "JEALOUS ", strlen(" JEALOUS"));
600 if (mask & SILC_ATTRIBUTE_MOOD_ASHAMED)
601 silc_strncat(tmp, sizeof(tmp), "ASHAMED ", strlen(" ASHAMED"));
602 if (mask & SILC_ATTRIBUTE_MOOD_INVINCIBLE)
603 silc_strncat(tmp, sizeof(tmp), "INVINCIBLE ", strlen(" INVINCIBLE"));
604 if (mask & SILC_ATTRIBUTE_MOOD_INLOVE)
605 silc_strncat(tmp, sizeof(tmp), "INLOVE ", strlen(" INLOVE"));
606 if (mask & SILC_ATTRIBUTE_MOOD_SLEEPY)
607 silc_strncat(tmp, sizeof(tmp), "SLEEPY ", strlen(" SLEEPY"));
608 if (mask & SILC_ATTRIBUTE_MOOD_BORED)
609 silc_strncat(tmp, sizeof(tmp), "BORED ", strlen(" BORED"));
610 if (mask & SILC_ATTRIBUTE_MOOD_EXCITED)
611 silc_strncat(tmp, sizeof(tmp), "EXCITED ", strlen(" EXCITED"));
612 if (mask & SILC_ATTRIBUTE_MOOD_ANXIOUS)
613 silc_strncat(tmp, sizeof(tmp), "ANXIOUS ", strlen(" ANXIOUS"));
614 printformat_module("fe-common/silc", server, NULL,
615 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MOOD, tmp);
619 case SILC_ATTRIBUTE_STATUS_FREETEXT:
621 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
623 printformat_module("fe-common/silc", server, NULL,
624 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_TEXT, tmp);
628 case SILC_ATTRIBUTE_STATUS_MESSAGE:
630 if (!silc_attribute_get_object(attr, (void *)&verify->message,
631 sizeof(verify->message)))
633 printformat_module("fe-common/silc", server, NULL,
634 MSGLEVEL_CRAP, SILCTXT_ATTR_STATUS_MESSAGE,
639 case SILC_ATTRIBUTE_PREFERRED_LANGUAGE:
641 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
643 printformat_module("fe-common/silc", server, NULL,
644 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_LANGUAGE,
649 case SILC_ATTRIBUTE_PREFERRED_CONTACT:
652 if (!silc_attribute_get_object(attr, (void *)&mask, sizeof(mask)))
655 silc_strncat(tmp, sizeof(tmp), "NONE ", strlen(" NONE"));
656 if (mask & SILC_ATTRIBUTE_CONTACT_CHAT)
657 silc_strncat(tmp, sizeof(tmp), "CHAT ", strlen(" CHAT"));
658 if (mask & SILC_ATTRIBUTE_CONTACT_EMAIL)
659 silc_strncat(tmp, sizeof(tmp), "EMAIL ", strlen(" EMAIL"));
660 if (mask & SILC_ATTRIBUTE_CONTACT_CALL)
661 silc_strncat(tmp, sizeof(tmp), "CALL ", strlen(" CALL"));
662 if (mask & SILC_ATTRIBUTE_CONTACT_PAGE)
663 silc_strncat(tmp, sizeof(tmp), "PAGE ", strlen(" PAGE"));
664 if (mask & SILC_ATTRIBUTE_CONTACT_SMS)
665 silc_strncat(tmp, sizeof(tmp), "SMS ", strlen(" SMS"));
666 if (mask & SILC_ATTRIBUTE_CONTACT_MMS)
667 silc_strncat(tmp, sizeof(tmp), "MMS ", strlen(" MMS"));
668 printformat_module("fe-common/silc", server, NULL,
669 MSGLEVEL_CRAP, SILCTXT_ATTR_PREFERRED_CONTACT, tmp);
673 case SILC_ATTRIBUTE_TIMEZONE:
675 if (!silc_attribute_get_object(attr, (void *)&tmp, sizeof(tmp) - 1))
677 printformat_module("fe-common/silc", server, NULL,
678 MSGLEVEL_CRAP, SILCTXT_ATTR_TIMEZONE, tmp);
682 case SILC_ATTRIBUTE_EXTENSION:
684 if (!silc_attribute_get_object(attr, (void *)&verify->extension,
685 sizeof(verify->extension)))
687 printformat_module("fe-common/silc", server, NULL,
688 MSGLEVEL_CRAP, SILCTXT_ATTR_EXTENSION,
693 case SILC_ATTRIBUTE_GEOLOCATION:
695 SilcAttributeObjGeo geo;
696 memset(&geo, 0, sizeof(geo));
697 if (!silc_attribute_get_object(attr, (void *)&geo, sizeof(geo)))
699 snprintf(tmp, sizeof(tmp) - 1, "%s:%s:%s:%s",
700 geo.longitude ? geo.longitude : "",
701 geo.latitude ? geo.latitude : "",
702 geo.altitude ? geo.altitude : "",
703 geo.accuracy ? geo.accuracy : "");
704 printformat_module("fe-common/silc", server, NULL,
705 MSGLEVEL_CRAP, SILCTXT_ATTR_GEOLOCATION, tmp);
709 case SILC_ATTRIBUTE_DEVICE_INFO:
711 SilcAttributeObjDevice dev;
712 memset(&dev, 0, sizeof(dev));
713 if (!silc_attribute_get_object(attr, (void *)&dev, sizeof(dev)))
715 snprintf(tmp, sizeof(tmp) - 1, "%s:%s:%s:%s:%s",
716 (dev.type == SILC_ATTRIBUTE_DEVICE_COMPUTER ? "COMPUTER" :
717 dev.type == SILC_ATTRIBUTE_DEVICE_PDA ? "PDA" :
718 dev.type == SILC_ATTRIBUTE_DEVICE_MOBILE_PHONE ?
720 dev.type == SILC_ATTRIBUTE_DEVICE_TERMINAL ? "TERMINAL" :
722 dev.manufacturer ? dev.manufacturer : "",
723 dev.version ? dev.version : "",
724 dev.model ? dev.model: "",
725 dev.language ? dev.language : "");
726 printformat_module("fe-common/silc", server, NULL,
727 MSGLEVEL_CRAP, SILCTXT_ATTR_DEVICE_INFO, tmp);
731 case SILC_ATTRIBUTE_USER_PUBLIC_KEY:
733 if (verify->userpk.type)
735 if (!silc_attribute_get_object(attr, (void *)&verify->userpk,
736 sizeof(verify->userpk)))
741 case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY:
745 if (!silc_attribute_get_object(attr, (void *)&serverpk,
751 case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE:
755 if (!silc_attribute_get_object(attr, (void *)&usersign,
761 case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE:
765 if (!silc_attribute_get_object(attr, (void *)&serversign,
776 /* Handle the signature verifications and public key verifying here */
778 if (usersign.data && !strcmp(verify->userpk.type, "silc-rsa")) {
779 /* Verify the signature now */
780 SilcPublicKey public_key;
782 unsigned char *verifyd;
783 SilcUInt32 verify_len;
785 if (silc_pkcs_public_key_decode(verify->userpk.data,
786 verify->userpk.data_len,
788 silc_pkcs_alloc("rsa", &pkcs);
789 verifyd = silc_attribute_get_verify_data(attrs, FALSE, &verify_len);
790 if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)){
791 if (silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
794 verifyd, verify_len)) {
795 printformat_module("fe-common/silc", server, NULL,
796 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_VERIFIED);
798 printformat_module("fe-common/silc", server, NULL,
799 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_FAILED);
803 silc_pkcs_public_key_free(public_key);
807 printformat_module("fe-common/silc", server, NULL,
808 MSGLEVEL_CRAP, SILCTXT_ATTR_USER_SIGN_NOT_PRESENT);
811 if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) {
812 /* Verify the signature now */
813 SilcPublicKey public_key;
815 unsigned char *verifyd;
816 SilcUInt32 verify_len;
818 if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len,
820 silc_pkcs_alloc("rsa", &pkcs);
821 verifyd = silc_attribute_get_verify_data(attrs, TRUE, &verify_len);
822 if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) {
823 if (silc_pkcs_verify_with_hash(pkcs, client->sha1hash,
826 verifyd, verify_len)) {
827 printformat_module("fe-common/silc", server, NULL,
828 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_VERIFIED);
830 printformat_module("fe-common/silc", server, NULL,
831 MSGLEVEL_CRAP, SILCTXT_ATTR_SERVER_SIGN_FAILED);
835 silc_pkcs_public_key_free(public_key);
840 if (!verify->userpk.type || !usersign.data)
841 printformat_module("fe-common/silc", server, NULL,
842 MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
844 silc_verify_public_key(client, conn, SILC_SOCKET_TYPE_CLIENT,
845 verify->userpk.data, verify->userpk.data_len,
846 SILC_SKE_PK_TYPE_SILC,
847 silc_query_attributes_print_final, verify);
850 static void silc_query_attributes_print_final(bool success, void *context)
852 AttrVerify verify = context;
853 SilcClient client = verify->client;
854 SILC_SERVER_REC *server = verify->server;
856 unsigned char filename[256], *fingerprint = NULL, *tmp;
861 printformat_module("fe-common/silc", NULL, NULL,
862 MSGLEVEL_CRAP, SILCTXT_PUBKEY_VERIFIED, "user",
865 printformat_module("fe-common/silc", NULL, NULL,
866 MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOTVERIFIED, "user",
870 printformat_module("fe-common/silc", server, NULL,
871 MSGLEVEL_CRAP, SILCTXT_ATTR_FOOTER);
873 /* Replace all whitespaces with `_'. */
874 fingerprint = silc_hash_fingerprint(client->sha1hash,
876 verify->userpk.data_len);
877 for (i = 0; i < strlen(fingerprint); i++)
878 if (fingerprint[i] == ' ')
879 fingerprint[i] = '_';
881 /* Filename for dir */
882 tmp = fingerprint + strlen(fingerprint) - 9;
883 snprintf(filename, sizeof(filename) - 1, "%s/friends/%s",
884 get_irssi_dir(), tmp);
885 silc_free(fingerprint);
887 if ((stat(filename, &st)) == -1) {
888 /* Ask to accept save requested attributes */
889 format = format_get_text("fe-common/silc", NULL, NULL, NULL,
891 keyboard_entry_redirect((SIGNAL_FUNC)silc_query_attributes_accept,
894 /* Save new data to existing directory */
895 silc_query_attributes_accept("Y", verify);
901 static void silc_query_attributes_accept(const char *line, void *context)
903 AttrVerify verify = context;
904 SilcClient client = verify->client;
905 SILC_SERVER_REC *server = verify->server;
908 unsigned char filename[256], filename2[256], *fingerprint = NULL, *tmp;
912 if (line[0] == 'Y' || line[0] == 'y') {
913 /* Save the attributes */
914 memset(filename, 0, sizeof(filename));
915 memset(filename2, 0, sizeof(filename2));
917 pw = getpwuid(getuid());
921 /* Replace all whitespaces with `_'. */
922 fingerprint = silc_hash_fingerprint(client->sha1hash,
924 verify->userpk.data_len);
925 for (i = 0; i < strlen(fingerprint); i++)
926 if (fingerprint[i] == ' ')
927 fingerprint[i] = '_';
929 /* Filename for dir */
930 tmp = fingerprint + strlen(fingerprint) - 9;
931 snprintf(filename, sizeof(filename) - 1, "%s/friends/%s",
932 get_irssi_dir(), tmp);
934 /* Create dir if it doesn't exist */
935 if ((stat(filename, &st)) == -1) {
936 /* If dir doesn't exist */
937 if (errno == ENOENT) {
938 if (pw->pw_uid == geteuid()) {
939 if ((mkdir(filename, 0755)) == -1) {
940 silc_say_error("Couldn't create `%s' directory",
945 silc_say_error("Couldn't create `%s' directory due to a "
946 "wrong uid!", filename);
950 silc_say_error("%s", strerror(errno));
955 /* Save the stuff to the directory */
958 snprintf(filename2, sizeof(filename2) - 1, "%s/vcard", filename);
959 if (verify->vcard.full_name) {
960 tmp = silc_vcard_encode(&verify->vcard, &len);
961 silc_file_writefile(filename2, tmp, len);
965 /* Save public key */
966 memset(filename2, 0, sizeof(filename2));
967 snprintf(filename2, sizeof(filename2) - 1, "%s/clientkey_%s.pub",
968 filename, fingerprint);
969 silc_pkcs_save_public_key_data(filename2, verify->userpk.data,
970 verify->userpk.data_len,
973 /* Save extension data */
974 if (verify->extension.mime) {
975 memset(filename2, 0, sizeof(filename2));
976 snprintf(filename2, sizeof(filename2) - 1, "%s/extension.mime",
978 silc_file_writefile(filename2, verify->extension.mime,
979 verify->extension.mime_len);
982 /* Save MIME message data */
983 if (verify->extension.mime) {
984 memset(filename2, 0, sizeof(filename2));
985 snprintf(filename2, sizeof(filename2) - 1, "%s/status_message.mime",
987 silc_file_writefile(filename2, verify->message.mime,
988 verify->message.mime_len);
991 printformat_module("fe-common/silc", server, NULL,
992 MSGLEVEL_CRAP, SILCTXT_ATTR_SAVED, filename);
996 silc_free(fingerprint);
997 silc_free(verify->name);
998 silc_vcard_free(&verify->vcard);