Thu Oct 30 21:23:24 CET 2003 Jochen Eisinger <jochen@penguin-breeder.org>
authorJochen Eisinger <coffee@silcnet.org>
Thu, 30 Oct 2003 20:26:55 +0000 (20:26 +0000)
committerJochen Eisinger <coffee@silcnet.org>
Thu, 30 Oct 2003 20:26:55 +0000 (20:26 +0000)
* 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
apps/irssi/src/fe-common/silc/module-formats.c
apps/irssi/src/fe-common/silc/module-formats.h
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-servers.c

diff --git a/CHANGES b/CHANGES
index 2b91d32d9173a3b92dfcc34515cd3b081db05b6f..485885a3ab25f5fb47c88e7c72f7eed2f816998d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,11 @@
+Thu Oct 30 21:23:24 CET 2003 Jochen Eisinger <jochen@penguin-breeder.org>
+
+       * 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 <priikone@silcnet.org>
 
        * Check that packet queue purging was successful.  Affected
index 367702286edf0a26d78673a2eb526c0402b0c40a..ff2675bdccf151fe6f37b41bb7d7c7b1800af404 100644 (file)
@@ -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 }
 };
index f46e6ea2862d7b8e4edbdfc35be8b452de825b22..4e8e8849afde67a23501b6decbae7c0cdcd63808 100644 (file)
@@ -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[];
index baff1b8c9ba8d3110e70a00be0d8431ee3795942..9352f67ee93a023bcc51b4ece510c19fbd601555 100644 (file)
@@ -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();
 }
index 54803ba1c14025cdc42cab6bddfd56a35a9f8fc3..a49ff6c53c3fd66b28e6034abb7d191845630740 100644 (file)
@@ -447,6 +447,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server)
 /* SYNTAX: STATS */
 /* SYNTAX: ATTR [<-del> <option> [{ <value>}]] */
 /* SYNTAX: SMSG [<-channel>] <target> <message> */
+/* SYNTAX: LISTKEYS [-servers] [-clients] [<public key file>] */
 
 void silc_command_exec(SILC_SERVER_REC *server,
                       const char *command, const char *args)