From 0b5b6edac7f73475b1676570c7f70e4e44f3be08 Mon Sep 17 00:00:00 2001 From: Jochen Eisinger Date: Thu, 30 Oct 2003 20:26:55 +0000 Subject: [PATCH] Thu Oct 30 21:23:24 CET 2003 Jochen Eisinger * Add a /LISTKEYS command which lists the locally cached client and server keys. Affected files irssi/src/fe-common/module-formats.[ch], irssi/src/silc/core/silc-{channels,servers}.c irssi/docs/help/in/listkeys.in --- CHANGES | 8 + .../irssi/src/fe-common/silc/module-formats.c | 16 ++ .../irssi/src/fe-common/silc/module-formats.h | 16 ++ apps/irssi/src/silc/core/silc-channels.c | 188 +++++++++++++++++- apps/irssi/src/silc/core/silc-servers.c | 1 + 5 files changed, 226 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 2b91d32d..485885a3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +Thu Oct 30 21:23:24 CET 2003 Jochen Eisinger + + * Add a /LISTKEYS command which lists the locally cached + client and server keys. Affected files + irssi/src/fe-common/module-formats.[ch], + irssi/src/silc/core/silc-{channels,servers}.c + irssi/docs/help/in/listkeys.in + Thu Oct 30 20:23:40 EET 2003 Pekka Riikonen * Check that packet queue purging was successful. Affected diff --git a/apps/irssi/src/fe-common/silc/module-formats.c b/apps/irssi/src/fe-common/silc/module-formats.c index 36770228..ff2675bd 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.c +++ b/apps/irssi/src/fe-common/silc/module-formats.c @@ -213,6 +213,22 @@ FORMAT_REC fecommon_silc_formats[] = { { "attr_extension", " Extension : $0", 1, { 0 } }, { "attr_save", "Would you like to save the attributes (y/n)?", 0 }, { "attr_saved", "Requested Attributes located in {hilight $0}", 1, { 0 } }, + /* Public Key Information */ + { NULL, "Public Key Information", 0}, + + { "lstkey_file", "Public key file : $0", 1, { 0 } }, + { "lstkey_alg", "Algorithm : $0", 1, { 0 } }, + { "lstkey_bits", "Key length (bits) : $0", 1, { 1 } }, + { "lstkey_rn", "Real name : $0", 1, { 0 } }, + { "lstkey_un", "Username : $0", 1, { 0 } }, + { "lstkey_hn", "Hostname : $0", 1, { 0 } }, + { "lstkey_email", "Email : $0", 1, { 0 } }, + { "lstkey_org", "Organization : $0", 1, { 0 } }, + { "lstkey_c", "Country : $0", 1, { 0 } }, + { "lstkey_finger", "Fingerprint (SHA1) : $0", 1, { 0 } }, + { "lstkey_babl", "Babbelprint (SHA1) : $0", 1, { 0 } }, + { "lstkey_loadpub", "Could not load public key file `$0'", 1, { 0 } }, + { "lstkey_list", "Stored {hilight $0} public keys:", 1, { 0 } }, { NULL, NULL, 0 } }; diff --git a/apps/irssi/src/fe-common/silc/module-formats.h b/apps/irssi/src/fe-common/silc/module-formats.h index f46e6ea2..4e8e8849 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.h +++ b/apps/irssi/src/fe-common/silc/module-formats.h @@ -205,6 +205,22 @@ enum { SILCTXT_ATTR_EXTENSION, SILCTXT_ATTR_SAVE, SILCTXT_ATTR_SAVED, + + SILCTXT_FILL_7, + SILCTXT_LISTKEY_PUB_FILE, + SILCTXT_LISTKEY_PUB_ALG, + SILCTXT_LISTKEY_PUB_BITS, + SILCTXT_LISTKEY_PUB_RN, + SILCTXT_LISTKEY_PUB_UN, + SILCTXT_LISTKEY_PUB_HN, + SILCTXT_LISTKEY_PUB_EMAIL, + SILCTXT_LISTKEY_PUB_ORG, + SILCTXT_LISTKEY_PUB_C, + SILCTXT_LISTKEY_PUB_FINGER, + SILCTXT_LISTKEY_PUB_BABL, + SILCTXT_LISTKEY_LOADPUB, + SILCTXT_LISTKEY_LIST, + }; extern FORMAT_REC fecommon_silc_formats[]; diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index baff1b8c..9352f67e 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -1023,12 +1023,192 @@ static void command_key(const char *data, SILC_SERVER_REC *server, silc_free(nickname); } -/* Lists locally saved client and server public keys. */ +void silc_list_key(const char *pub_filename, int verbose) +{ + SilcPublicKey public_key; + SilcPublicKeyIdentifier ident; + char *fingerprint, *babbleprint; + unsigned char *pk; + SilcUInt32 pk_len; + SilcPKCS pkcs; + SilcUInt32 key_len = 0; + int is_server_key = (strstr(pub_filename, "serverkeys") != NULL); + + if (silc_pkcs_load_public_key((char *)pub_filename, &public_key, + SILC_PKCS_FILE_PEM) == FALSE) + if (silc_pkcs_load_public_key((char *)pub_filename, &public_key, + SILC_PKCS_FILE_BIN) == FALSE) { + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_LOADPUB, + pub_filename); + return; + } + + ident = silc_pkcs_decode_identifier(public_key->identifier); + + pk = silc_pkcs_public_key_encode(public_key, &pk_len); + fingerprint = silc_hash_fingerprint(NULL, pk, pk_len); + babbleprint = silc_hash_babbleprint(NULL, pk, pk_len); + + if (silc_pkcs_alloc(public_key->name, &pkcs)) { + key_len = silc_pkcs_public_key_set(pkcs, public_key); + silc_pkcs_free(pkcs); + } + + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_FILE, + pub_filename); + + if (verbose) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_ALG, + public_key->name); + if (key_len && verbose) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_BITS, + (unsigned int)key_len); + if (ident->realname && (!is_server_key || verbose)) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_RN, + ident->realname); + if (ident->username && verbose) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_UN, + ident->username); + if (ident->host && (is_server_key || verbose)) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_HN, + ident->host); + if (ident->email && verbose) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_EMAIL, + ident->email); + if (ident->org && verbose) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_ORG, + ident->org); + if (ident->country && verbose) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_C, + ident->country); + + if (verbose) { + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_FINGER, + fingerprint); + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_BABL, + babbleprint); + } + + silc_free(fingerprint); + silc_free(babbleprint); + silc_free(pk); + silc_pkcs_public_key_free(public_key); + silc_pkcs_free_identifier(ident); + +} + + +void silc_list_keys_in_dir(const char *dirname, const char *where) +{ + DIR *dir; + struct dirent *entry; + + dir = opendir(dirname); + + if (dir == NULL) + cmd_return_error(CMDERR_ERRNO); + + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_LISTKEY_LIST, + where); + + rewinddir(dir); + + while ((entry = readdir(dir)) != NULL) { + /* try to open everything that isn't a directory */ + struct stat buf; + char filename[256]; + + snprintf(filename, sizeof(filename) - 1, "%s/%s", dirname, entry->d_name); + if (!stat(filename, &buf) && S_ISREG(buf.st_mode)) + silc_list_key(filename, FALSE); + } + + closedir(dir); +} + +void silc_list_file(const char *filename) +{ + + char path[256]; + struct stat buf; + + snprintf(path, sizeof(path) - 1, "%s", filename); + if (!stat(path, &buf) && S_ISREG(buf.st_mode)) + goto list_key; + + snprintf(path, sizeof(path) - 1, "%s/%s", get_irssi_dir(), filename); + if (!stat(path, &buf) && S_ISREG(buf.st_mode)) + goto list_key; + + snprintf(path,sizeof(path) - 1, "%s/clientkeys/%s", get_irssi_dir(), + filename); + if (!stat(path, &buf) && S_ISREG(buf.st_mode)) + goto list_key; + + snprintf(path,sizeof(path) - 1, "%s/serverkeys/%s", get_irssi_dir(), + filename); + if (!stat(path, &buf) && S_ISREG(buf.st_mode)) + goto list_key; + return; + +list_key: + + silc_list_key(path, TRUE); + +} + +/* Lists locally saved client and server public keys. */ static void command_listkeys(const char *data, SILC_SERVER_REC *server, WI_ITEM_REC *item) { + GHashTable *optlist; + char *filename; + void *free_arg; + char dirname[256]; + + if (!cmd_get_params(data, &free_arg, 1 | PARAM_FLAG_OPTIONS | + PARAM_FLAG_GETREST, "listkeys", &optlist, + &filename)) + return; + + if (*filename != '\0') { + + silc_list_file(filename); + + } else { + int clients, servers; + + clients = (g_hash_table_lookup(optlist, "clients") != NULL); + servers = (g_hash_table_lookup(optlist, "servers") != NULL); + if (!(clients || servers)) + clients = servers = 1; + + if (servers) { + snprintf(dirname, sizeof(dirname) - 1, "%s/serverkeys", get_irssi_dir()); + silc_list_keys_in_dir(dirname, "server"); + } + + if (clients) { + snprintf(dirname, sizeof(dirname) - 1, "%s/clientkeys", get_irssi_dir()); + silc_list_keys_in_dir(dirname, "client"); + } + } + cmd_params_free(free_arg); } void silc_channels_init(void) @@ -1045,7 +1225,9 @@ void silc_channels_init(void) command_bind_silc("notice", MODULE_NAME, (SIGNAL_FUNC) command_notice); command_bind_silc("away", MODULE_NAME, (SIGNAL_FUNC) command_away); command_bind_silc("key", MODULE_NAME, (SIGNAL_FUNC) command_key); -/* command_bind_silc("listkeys", MODULE_NAME, (SIGNAL_FUNC) command_listkeys); */ + command_bind("listkeys", MODULE_NAME, (SIGNAL_FUNC) command_listkeys); + + command_set_options("listkeys", "clients servers"); silc_nicklist_init(); } @@ -1064,7 +1246,7 @@ void silc_channels_deinit(void) command_unbind("notice", (SIGNAL_FUNC) command_notice); command_unbind("away", (SIGNAL_FUNC) command_away); command_unbind("key", (SIGNAL_FUNC) command_key); -/* command_unbind("listkeys", (SIGNAL_FUNC) command_listkeys); */ + command_unbind("listkeys", (SIGNAL_FUNC) command_listkeys); silc_nicklist_deinit(); } diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 54803ba1..a49ff6c5 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -447,6 +447,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server) /* SYNTAX: STATS */ /* SYNTAX: ATTR [<-del>