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 static char *silc_create_pk_identifier(void)
25 char *username = NULL, *realname = NULL;
26 char *hostname, email[256];
30 realname = silc_get_real_name();
33 hostname = silc_net_localhost();
37 /* Get username (mandatory) */
38 username = silc_get_username();
42 /* Create default email address, whether it is right or not */
43 silc_snprintf(email, sizeof(email), "%s@%s", username, hostname);
45 ident = silc_pkcs_silc_encode_identifier(NULL, username, hostname, realname,
46 email, NULL, NULL, NULL);
55 /* Generate key pair */
57 SilcBool silc_create_key_pair(const char *pkcs_name,
58 SilcUInt32 key_len_bits,
59 const char *pub_filename,
60 const char *prv_filename,
61 const char *pub_identifier,
62 const char *passphrase,
63 SilcPublicKey *return_public_key,
64 SilcPrivateKey *return_private_key,
69 char *pkfile = pub_filename ? strdup(pub_filename) : NULL;
70 char *prvfile = prv_filename ? strdup(prv_filename) : NULL;
71 char *alg = pkcs_name ? strdup(pkcs_name) : NULL;
72 char *identifier = pub_identifier ? strdup(pub_identifier) : NULL;
73 char *pass = passphrase ? strdup(passphrase) : NULL;
74 SilcPublicKey public_key;
75 SilcPrivateKey private_key;
77 if (interactive && (!alg || !pub_filename || !prv_filename))
79 New pair of keys will be created. Please, answer to following questions.\n\
85 alg = silc_get_input("PKCS name (l to list names) [rsa]: ", FALSE);
89 if (*alg == 'l' || *alg == 'L') {
90 char *list = silc_pkcs_get_supported();
102 if (!silc_pkcs_find_algorithm(alg, NULL)) {
103 fprintf(stderr, "Unknown PKCS algorithm `%s' or crypto library"
104 "is not initialized", alg);
111 length = silc_get_input("Key length in key_len_bits [2048]: ", FALSE);
113 key_len_bits = atoi(length);
121 char *def = silc_create_pk_identifier();
124 memset(line, 0, sizeof(line));
126 silc_snprintf(line, sizeof(line), "Identifier [%s]: ", def);
128 silc_snprintf(line, sizeof(line),
129 "Identifier (eg. UN=jon, HN=jon.dummy.com, "
130 "RN=Jon Johnson, E=jon@dummy.com): ");
132 while (!identifier) {
133 identifier = silc_get_input(line, FALSE);
134 if (!identifier && def)
135 identifier = strdup(def);
139 fprintf(stderr, "Could not create public key identifier: %s\n",
143 identifier = strdup(def);
149 if (!strstr(identifier, "UN=") || !strstr(identifier, "HN=")) {
150 fprintf(stderr, "Invalid public key identifier. You must specify both "
155 rng = silc_rng_alloc();
157 silc_rng_global_init(rng);
161 memset(line, 0, sizeof(line));
162 silc_snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
163 pkfile = silc_get_input(line, FALSE);
166 pkfile = strdup("public_key.pub");
171 memset(line, 0, sizeof(line));
172 silc_snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
173 prvfile = silc_get_input(line, FALSE);
176 prvfile = strdup("private_key.prv");
182 pass = silc_get_input("Private key passphrase: ", TRUE);
189 pass2 = silc_get_input("Retype private key passphrase: ", TRUE);
192 match = !strcmp(pass, pass2);
196 fprintf(stderr, "\nPassphrases do not match\n\n");
202 printf("\nGenerating the key pair...\n");
205 if (!silc_pkcs_silc_generate_key(alg, key_len_bits,
206 identifier, rng, &public_key,
210 /* Save public key into file */
211 if (!silc_pkcs_save_public_key(pkfile, public_key, SILC_PKCS_FILE_BASE64))
214 /* Save private key into file */
215 if (!silc_pkcs_save_private_key(prvfile, private_key,
216 (const unsigned char *)pass, strlen(pass),
217 SILC_PKCS_FILE_BIN, rng))
220 if (return_public_key)
221 *return_public_key = public_key;
223 silc_pkcs_public_key_free(public_key);
225 if (return_private_key)
226 *return_private_key = private_key;
228 silc_pkcs_private_key_free(private_key);
230 printf("Public key has been saved into `%s'.\n", pkfile);
231 printf("Private key has been saved into `%s'.\n", prvfile);
233 printf("Press <Enter> to continue...\n");
241 silc_free(identifier);
242 memset(pass, 0, strlen(pass));
250 SilcBool silc_load_key_pair(const char *pub_filename,
251 const char *prv_filename,
252 const char *passphrase,
253 SilcPublicKey *return_public_key,
254 SilcPrivateKey *return_private_key)
256 char *pass = passphrase ? strdup(passphrase) : NULL;
258 SILC_LOG_DEBUG(("Loading public and private keys"));
260 if (!silc_pkcs_load_public_key(pub_filename,
261 SILC_PKCS_ANY, return_public_key)) {
263 memset(pass, 0, strlen(pass));
269 pass = silc_get_input("Private key passphrase: ", TRUE);
274 if (!silc_pkcs_load_private_key(prv_filename,
275 (const unsigned char *)pass, strlen(pass),
277 return_private_key)) {
278 silc_pkcs_public_key_free(*return_public_key);
279 *return_public_key = NULL;
280 memset(pass, 0, strlen(pass));
285 memset(pass, 0, strlen(pass));
290 /* Dump public key into stdout */
292 SilcBool silc_show_public_key(SilcPublicKey public_key)
294 SilcSILCPublicKey silc_pubkey;
295 SilcPublicKeyIdentifier ident;
296 char *fingerprint, *babbleprint;
299 SilcUInt32 key_len = 0;
301 silc_pubkey = silc_pkcs_public_key_get_pkcs(SILC_PKCS_SILC, public_key);
305 ident = &silc_pubkey->identifier;
306 key_len = silc_pkcs_public_key_get_len(public_key);
307 pk = silc_pkcs_public_key_encode(NULL, public_key, &pk_len);
310 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
311 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
313 printf("Algorithm : %s\n", silc_pkcs_get_name(public_key));
315 printf("Key length (bits) : %d\n", (unsigned int)key_len);
317 printf("Version : %s\n", ident->version);
319 printf("Real name : %s\n", ident->realname);
321 printf("Username : %s\n", ident->username);
323 printf("Hostname : %s\n", ident->host);
325 printf("Email : %s\n", ident->email);
327 printf("Organization : %s\n", ident->org);
329 printf("Country : %s\n", ident->country);
330 printf("Fingerprint (SHA1) : %s\n", fingerprint);
331 printf("Babbleprint (SHA1) : %s\n", babbleprint);
335 silc_free(fingerprint);
336 silc_free(babbleprint);
342 /* Dump public key into stdout */
344 SilcBool silc_show_public_key_file(const char *pub_filename)
346 SilcPublicKey public_key;
349 if (!silc_pkcs_load_public_key((char *)pub_filename,
350 SILC_PKCS_ANY, &public_key)) {
351 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
355 printf("Public key file : %s\n", pub_filename);
356 ret = silc_show_public_key(public_key);
357 silc_pkcs_public_key_free(public_key);
362 /* Change private key passphrase */
364 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
365 const char *old_passphrase,
366 const char *new_passphrase)
368 SilcPrivateKey private_key;
372 pass = old_passphrase ? strdup(old_passphrase) : NULL;
374 pass = silc_get_input("Old passphrase: ", TRUE);
379 if (!silc_pkcs_load_private_key(prv_filename,
380 (const unsigned char *)pass, strlen(pass),
383 memset(pass, 0, strlen(pass));
385 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
389 memset(pass, 0, strlen(pass));
392 pass = new_passphrase ? strdup(new_passphrase) : NULL;
395 fprintf(stdout, "\n");
396 pass = silc_get_input("New passphrase: ", TRUE);
402 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
405 if (!strcmp(pass, pass2))
407 fprintf(stderr, "\nPassphrases do not match");
413 rng = silc_rng_alloc();
416 silc_pkcs_save_private_key((char *)prv_filename, private_key,
417 (unsigned char *)pass, strlen(pass),
418 SILC_PKCS_FILE_BIN, rng);
420 fprintf(stdout, "\nPassphrase changed\n");
422 memset(pass, 0, strlen(pass));
425 silc_pkcs_private_key_free(private_key);
431 /* Checks that the 'identifier' string is valid identifier string
432 and does not contain any unassigned or prohibited character. This
433 function is used to check for valid nicknames, channel names,
434 server names, usernames, hostnames, service names, algorithm names,
435 other security property names, and SILC Public Key name. */
437 unsigned char *silc_identifier_check(const unsigned char *identifier,
438 SilcUInt32 identifier_len,
439 SilcStringEncoding identifier_encoding,
440 SilcUInt32 max_allowed_length,
443 unsigned char *utf8s;
444 SilcUInt32 utf8s_len;
445 SilcStringprepStatus status;
447 if (!identifier || !identifier_len)
450 if (max_allowed_length && identifier_len > max_allowed_length)
453 status = silc_stringprep(identifier, identifier_len,
454 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
455 &utf8s, &utf8s_len, SILC_STRING_UTF8);
456 if (status != SILC_STRINGPREP_OK) {
457 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
462 *out_len = utf8s_len;
467 /* Same as above but does not allocate memory, just checks the
468 validity of the string. */
470 SilcBool silc_identifier_verify(const unsigned char *identifier,
471 SilcUInt32 identifier_len,
472 SilcStringEncoding identifier_encoding,
473 SilcUInt32 max_allowed_length)
475 SilcStringprepStatus status;
477 if (!identifier || !identifier_len)
480 if (max_allowed_length && identifier_len > max_allowed_length)
483 status = silc_stringprep(identifier, identifier_len,
484 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
485 NULL, NULL, SILC_STRING_UTF8);
486 if (status != SILC_STRINGPREP_OK) {
487 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
494 unsigned char *silc_channel_name_check(const unsigned char *identifier,
495 SilcUInt32 identifier_len,
496 SilcStringEncoding identifier_encoding,
497 SilcUInt32 max_allowed_length,
500 unsigned char *utf8s;
501 SilcUInt32 utf8s_len;
502 SilcStringprepStatus status;
504 if (!identifier || !identifier_len)
507 if (max_allowed_length && identifier_len > max_allowed_length)
510 status = silc_stringprep(identifier, identifier_len,
511 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
512 &utf8s, &utf8s_len, SILC_STRING_UTF8);
513 if (status != SILC_STRINGPREP_OK) {
514 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
519 *out_len = utf8s_len;
524 /* Same as above but does not allocate memory, just checks the
525 validity of the string. */
527 SilcBool silc_channel_name_verify(const unsigned char *identifier,
528 SilcUInt32 identifier_len,
529 SilcStringEncoding identifier_encoding,
530 SilcUInt32 max_allowed_length)
532 SilcStringprepStatus status;
534 if (!identifier || !identifier_len)
537 if (max_allowed_length && identifier_len > max_allowed_length)
540 status = silc_stringprep(identifier, identifier_len,
541 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
542 NULL, NULL, SILC_STRING_UTF8);
543 if (status != SILC_STRINGPREP_OK) {
544 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
551 /* Return mode list */
553 SilcBool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
558 if (silc_buffer_len(mode_list) / 4 != mode_list_count)
561 *list = silc_calloc(mode_list_count, sizeof(**list));
563 for (i = 0; i < mode_list_count; i++) {
564 SILC_GET32_MSB((*list)[i], mode_list->data);
565 silc_buffer_pull(mode_list, 4);
568 silc_buffer_push(mode_list, mode_list->data - mode_list->head);
573 /* Status message structure. Messages are defined below. */
579 #define STAT(x) SILC_STATUS_ERR_##x
580 static const SilcStatusMessage silc_status_messages[] = {
582 { STAT(NO_SUCH_NICK), "There was no such nickname" },
583 { STAT(NO_SUCH_CHANNEL), "There was no such channel" },
584 { STAT(NO_SUCH_SERVER), "There was no such server" },
585 { STAT(INCOMPLETE_INFORMATION), "Incomplete registration information" },
586 { STAT(NO_RECIPIENT), "No recipient given" },
587 { STAT(UNKNOWN_COMMAND), "Unknown command" },
588 { STAT(WILDCARDS), "Wilcrads not allowed" },
589 { STAT(NO_CLIENT_ID), "No Client ID given" },
590 { STAT(NO_CHANNEL_ID), "No Channel ID given" },
591 { STAT(NO_SERVER_ID), "No Server ID given" },
592 { STAT(BAD_CLIENT_ID), "Bad Client ID" },
593 { STAT(BAD_CHANNEL_ID), "Bad Channel ID" },
594 { STAT(NO_SUCH_CLIENT_ID), "There is no such client" },
595 { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" },
596 { STAT(NICKNAME_IN_USE), "Nickname already exists" },
597 { STAT(NOT_ON_CHANNEL), "You are not on that channel" },
598 { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" },
599 { STAT(USER_ON_CHANNEL), "User already on the channel" },
600 { STAT(NOT_REGISTERED), "You have not registered" },
601 { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" },
602 { STAT(TOO_MANY_PARAMS), "Too many parameters" },
603 { STAT(PERM_DENIED), "Permission denied" },
604 { STAT(BANNED_FROM_SERVER),"You are not allowed to connect" },
605 { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" },
606 { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" },
607 { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" },
608 { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" },
609 { STAT(UNKNOWN_MODE), "Unknown mode" },
610 { STAT(NOT_YOU), "Cannot change mode for other users" },
611 { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" },
612 { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" },
613 { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" },
614 { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" },
615 { STAT(BAD_NICKNAME), "Bad nickname" },
616 { STAT(BAD_CHANNEL), "Bad channel name" },
617 { STAT(AUTH_FAILED), "Authentication failed" },
618 { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" },
619 { STAT(NO_SUCH_SERVER_ID), "No such Server ID" },
620 { STAT(RESOURCE_LIMIT), "No more free resources" },
621 { STAT(NO_SUCH_SERVICE), "Service doesn't exist" },
622 { STAT(NOT_AUTHENTICATED), "You have not been authenticated" },
623 { STAT(BAD_SERVER_ID), "Server ID is not valid" },
624 { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
625 { STAT(BAD_VERSION), "Bad version" },
626 { STAT(TIMEDOUT), "Service timed out" },
627 { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
628 { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
629 { STAT(BAD_SERVER), "Bad server name" },
630 { STAT(BAD_USERNAME), "Bad user name" },
631 { STAT(NO_SUCH_PUBLIC_KEY), "Unknown public key" },
636 /* Returns status message string */
638 const char *silc_get_status_message(unsigned char status)
642 for (i = 0; silc_status_messages[i].message; i++) {
643 if (silc_status_messages[i].status == status)
647 if (silc_status_messages[i].message == NULL)
650 return silc_status_messages[i].message;
653 static const char *packet_name[] = {
664 "PRIVATE MESSAGE KEY",
670 "CONNECTION AUTH REQUEST",
685 /* Returns packet type name */
687 const char *silc_get_packet_name(unsigned char type)
689 if (type >= SILC_PACKET_MAX)
691 if (type >= SILC_PACKET_PRIVATE)
692 return "PRIVATE RANGE";
693 if (type > (sizeof(packet_name) / sizeof(*packet_name)))
695 return packet_name[type];
698 static const char *command_name[] = {
729 /* Returns command name */
731 const char *silc_get_command_name(unsigned char command)
733 if (command >= SILC_COMMAND_RESERVED)
735 if (command >= SILC_COMMAND_PRIVATE)
736 return "PRIVATE RANGE";
737 if (command > (sizeof(command_name) / sizeof(*command_name)))
739 return command_name[command];
742 /* Parses SILC protocol style version string. */
744 SilcBool silc_parse_version_string(const char *version,
745 SilcUInt32 *protocol_version,
746 char **protocol_version_string,
747 SilcUInt32 *software_version,
748 char **software_version_string,
749 char **vendor_version)
752 int maj = 0, min = 0;
754 if (!strstr(version, "SILC-"))
757 cp = (char *)version + 5;
761 /* Take protocol version */
764 if (!strchr(cp, '.'))
766 cp = strchr(cp, '.') + 1;
771 memset(buf, 0, sizeof(buf));
772 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
773 if (protocol_version)
774 *protocol_version = atoi(buf);
775 memset(buf, 0, sizeof(buf));
776 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
777 if (protocol_version_string)
778 *protocol_version_string = strdup(buf);
780 /* Take software version */
784 if (!strchr(cp, '-'))
786 cp = strchr(cp, '-') + 1;
791 if (strchr(cp, '.')) {
792 cp = strchr(cp, '.') + 1;
797 memset(buf, 0, sizeof(buf));
798 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
799 if (software_version)
800 *software_version = atoi(buf);
801 memset(buf, 0, sizeof(buf));
802 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
803 if (software_version_string)
804 *software_version_string = strdup(buf);
806 /* Take vendor string */
808 if (strchr(cp, '.')) {
809 cp = strchr(cp, '.') + 1;
810 if (cp && *cp && vendor_version)
811 *vendor_version = strdup(cp);
812 } else if (strchr(cp, ' ')) {
813 cp = strchr(cp, ' ') + 1;
814 if (cp && *cp && vendor_version)
815 *vendor_version = strdup(cp);
821 /* Converts version string x.x into number representation. */
823 SilcUInt32 silc_version_to_num(const char *version)
825 int maj = 0, min = 0;
831 cp = (char *)version;
833 cp = strchr(cp, '.');
837 memset(buf, 0, sizeof(buf));
838 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
839 return (SilcUInt32)atoi(buf);
842 /* Parses mode mask and returns the mode as string. */
844 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
851 memset(string, 0, sizeof(string));
853 if (mode & SILC_CHANNEL_MODE_PRIVATE)
854 strncat(string, "p", 1);
856 if (mode & SILC_CHANNEL_MODE_SECRET)
857 strncat(string, "s", 1);
859 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
860 strncat(string, "k", 1);
862 if (mode & SILC_CHANNEL_MODE_INVITE)
863 strncat(string, "i", 1);
865 if (mode & SILC_CHANNEL_MODE_TOPIC)
866 strncat(string, "t", 1);
868 if (mode & SILC_CHANNEL_MODE_ULIMIT)
869 strncat(string, "l", 1);
871 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
872 strncat(string, "a", 1);
874 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
875 strncat(string, "f", 1);
877 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
878 strncat(string, "C", 1);
880 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
881 strncat(string, "m", 1);
883 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
884 strncat(string, "M", 1);
886 if (mode & SILC_CHANNEL_MODE_CIPHER)
887 strncat(string, "c", 1);
889 if (mode & SILC_CHANNEL_MODE_HMAC)
890 strncat(string, "h", 1);
892 if (mode & SILC_CHANNEL_MODE_CIPHER) {
893 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
894 strncat(string, " ", 1);
895 strncat(string, cipher, strlen(cipher));
899 if (mode & SILC_CHANNEL_MODE_HMAC) {
900 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
901 strncat(string, " ", 1);
902 strncat(string, hmac, strlen(hmac));
906 /* Rest of mode is ignored */
908 return strdup(string);
911 /* Parses channel user mode mask and returns te mode as string */
913 char *silc_client_chumode(SilcUInt32 mode)
920 memset(string, 0, sizeof(string));
922 if (mode & SILC_CHANNEL_UMODE_CHANFO)
923 strncat(string, "f", 1);
925 if (mode & SILC_CHANNEL_UMODE_CHANOP)
926 strncat(string, "o", 1);
928 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
929 strncat(string, "b", 1);
931 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
932 strncat(string, "u", 1);
934 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
935 strncat(string, "r", 1);
937 if (mode & SILC_CHANNEL_UMODE_QUIET)
938 strncat(string, "q", 1);
940 return strdup(string);
943 /* Parses channel user mode and returns it as special mode character. */
945 char *silc_client_chumode_char(SilcUInt32 mode)
952 memset(string, 0, sizeof(string));
954 if (mode & SILC_CHANNEL_UMODE_CHANFO)
955 strncat(string, "*", 1);
957 if (mode & SILC_CHANNEL_UMODE_CHANOP)
958 strncat(string, "@", 1);
960 if (mode & SILC_CHANNEL_UMODE_QUIET)
961 strncat(string, "&", 1);
963 return strdup(string);
966 /* Renders ID to suitable to print for example to log file. */
968 static char rid[256];
969 #define _PUT_STRING(__d__, __s__) \
971 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
972 if (__sp < strlen(__s__)) { \
974 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
976 strncat(__d__, __s__, strlen(__s__)); \
980 char *silc_id_render(void *id, SilcIdType id_type)
983 unsigned char tmps[2];
986 memset(rid, 0, sizeof(rid));
990 SilcServerID *server_id = (SilcServerID *)id;
991 if (server_id->ip.data_len > 4) {
993 struct sockaddr_in6 ipv6;
994 memset(&ipv6, 0, sizeof(ipv6));
995 ipv6.sin6_family = AF_INET6;
996 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
997 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
998 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
999 _PUT_STRING(rid, tmp);
1002 struct in_addr ipv4;
1003 memmove(&ipv4.s_addr, server_id->ip.data, 4);
1004 cp = inet_ntoa(ipv4);
1006 _PUT_STRING(rid, cp);
1009 memset(tmp, 0, sizeof(tmp));
1010 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
1011 _PUT_STRING(rid, tmp);
1012 SILC_PUT16_MSB(server_id->rnd, tmps);
1013 memset(tmp, 0, sizeof(tmp));
1014 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1015 _PUT_STRING(rid, tmp);
1018 case SILC_ID_CLIENT:
1020 SilcClientID *client_id = (SilcClientID *)id;
1021 if (client_id->ip.data_len > 4) {
1023 struct sockaddr_in6 ipv6;
1024 memset(&ipv6, 0, sizeof(ipv6));
1025 ipv6.sin6_family = AF_INET6;
1026 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
1027 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1028 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1029 _PUT_STRING(rid, tmp);
1032 struct in_addr ipv4;
1033 memmove(&ipv4.s_addr, client_id->ip.data, 4);
1034 cp = inet_ntoa(ipv4);
1036 _PUT_STRING(rid, cp);
1039 memset(tmp, 0, sizeof(tmp));
1040 silc_snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
1041 _PUT_STRING(rid, tmp);
1042 memset(tmp, 0, sizeof(tmp));
1043 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1044 client_id->hash[0], client_id->hash[1],
1045 client_id->hash[2], client_id->hash[3]);
1046 _PUT_STRING(rid, tmp);
1049 case SILC_ID_CHANNEL:
1051 SilcChannelID *channel_id = (SilcChannelID *)id;
1052 if (channel_id->ip.data_len > 4) {
1054 struct sockaddr_in6 ipv6;
1055 memset(&ipv6, 0, sizeof(ipv6));
1056 ipv6.sin6_family = AF_INET6;
1057 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1058 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1059 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1060 _PUT_STRING(rid, tmp);
1063 struct in_addr ipv4;
1064 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1065 cp = inet_ntoa(ipv4);
1067 _PUT_STRING(rid, cp);
1070 memset(tmp, 0, sizeof(tmp));
1071 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1072 _PUT_STRING(rid, tmp);
1073 SILC_PUT16_MSB(channel_id->rnd, tmps);
1074 memset(tmp, 0, sizeof(tmp));
1075 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1076 _PUT_STRING(rid, tmp);