Fixed /LISTKEYS
authorPekka Riikonen <priikone@silcnet.org>
Sun, 14 Jan 2007 15:32:26 +0000 (15:32 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 14 Jan 2007 15:32:26 +0000 (15:32 +0000)
Fixed connection authentication request handling.

apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/client_ops.h
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-core.c
apps/irssi/src/silc/core/silc-servers.c

index 67cc80b9d5bf97b67b5c7ed7077571ada94adb0b..1dd0598c6bbff6b9c1a811d9599bd29ac6d53290 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2006 Pekka Riikonen
+  Copyright (C) 2001 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -1276,7 +1276,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
    after application has called the command. Just to tell application
    that the command really was processed. */
 
-static bool cmode_list_chpks = FALSE;
+static SilcBool cmode_list_chpks = FALSE;
 
 void silc_command(SilcClient client, SilcClientConnection conn,
                  SilcBool success, SilcCommand command, SilcStatus status,
@@ -2220,6 +2220,28 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
       silc_free(file);
     }
     break;
+
+  case SILC_COMMAND_KILL:
+    {
+      SilcClientEntry client_entry;
+
+      if (SILC_STATUS_IS_ERROR(status)) {
+       silc_say_error("KILL: %s", silc_get_status_message(status));
+       return;
+      }
+
+      client_entry = va_arg(vp, SilcClientEntry);
+      if (!client_entry || !client_entry->nickname[0])
+       break;
+
+      /* Print this only if the killed client isn't joined on channels.
+        If it is, we receive KILLED notify and we'll print this there. */
+      if (!silc_hash_table_count(client_entry->channels))
+       printformat_module("fe-common/silc", server, NULL,
+                          MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED,
+                          client_entry->nickname,
+                          conn->local_entry->nickname, "");
+    }
   }
 }
 
@@ -2525,82 +2547,60 @@ void silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
 typedef struct {
   SilcGetAuthMeth completion;
   void *context;
-} *InternalGetAuthMethod;
+} *GetAuthMethod;
 
-/* Callback called when we've received the authentication method information
-   from the server after we've requested it. This will get the authentication
-   data from the user if needed. */
-
-static void silc_get_auth_method_callback(SilcClient client,
-                                         SilcClientConnection conn,
-                                         SilcAuthMethod auth_meth,
-                                         void *context)
+static void silc_get_auth_ask_passphrase(unsigned char *passphrase,
+                                        SilcUInt32 passphrase_len,
+                                        void *context)
 {
-  InternalGetAuthMethod internal = (InternalGetAuthMethod)context;
-
-  SILC_LOG_DEBUG(("Start"));
-
-  switch (auth_meth) {
-  case SILC_AUTH_NONE:
-    /* No authentication required. */
-    (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-    break;
-  case SILC_AUTH_PASSWORD:
-    {
-      /* Check whether we find the password for this server in our
-        configuration.  If not, then don't provide so library will ask
-        it from the user. */
-      SERVER_SETUP_REC *setup = server_setup_find_port(conn->remote_host,
-                                                      conn->remote_port);
-      if (!setup || !setup->password) {
-       (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-       break;
-      }
-
-      (*internal->completion)(TRUE, auth_meth, setup->password,
-                             strlen(setup->password), internal->context);
-    }
-    break;
-  case SILC_AUTH_PUBLIC_KEY:
-    /* Do not get the authentication data now, the library will generate
-       it using our default key, if we do not provide it here. */
-    /* XXX In the future when we support multiple local keys and multiple
-       local certificates we will need to ask from user which one to use. */
-    (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
-    break;
-  }
-
-  silc_free(internal);
+  GetAuthMethod a = context;
+  a->completion(passphrase ? SILC_AUTH_PASSWORD : SILC_AUTH_NONE,
+               passphrase, passphrase_len, a->context);
+  silc_free(a);
 }
 
-/* Find authentication method and authentication data by hostname and
-   port. The hostname may be IP address as well. The found authentication
-   method and authentication data is returned to `auth_meth', `auth_data'
-   and `auth_data_len'. The function returns TRUE if authentication method
-   is found and FALSE if not. `conn' may be NULL. */
+/* Find authentication data by hostname and port. The hostname may be IP
+   address as well.*/
 
 void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
                          char *hostname, SilcUInt16 port,
+                         SilcAuthMethod auth_meth,
                          SilcGetAuthMeth completion, void *context)
 {
-  InternalGetAuthMethod internal;
+  SERVER_SETUP_REC *setup;
 
   SILC_LOG_DEBUG(("Start"));
 
-  /* If we do not have this connection configured by the user in a
-     configuration file then resolve the authentication method from the
-     server for this session. */
-  internal = silc_calloc(1, sizeof(*internal));
-  internal->completion = completion;
-  internal->context = context;
+  if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
+    /* Returning NULL will cause library to use our private key configured
+       for this connection */
+    completion(SILC_AUTH_PUBLIC_KEY, NULL, 0, context);
+    return;
+  }
+
+  /* Check whether we find the password for this server in our
+     configuration.  If it's set, always send it server. */
+  setup = server_setup_find_port(hostname, port);
+  if (setup && setup->password) {
+    completion(SILC_AUTH_PASSWORD, setup->password, strlen(setup->password),
+              context);
+    return;
+  }
 
-#if 0
-  silc_client_request_authentication_method(client, conn,
-                                           silc_get_auth_method_callback,
-                                           internal);
-#else
-  completion(TRUE, SILC_AUTH_NONE, NULL, 0, context);
-#endif
+  /* Didn't find password.  If server wants it, ask it from user. */
+  if (auth_meth == SILC_AUTH_PASSWORD) {
+    GetAuthMethod a;
+    a = silc_calloc(1, sizeof(*a));
+    if (a) {
+      a->completion = completion;
+      a->context = context;
+      silc_ask_passphrase(client, conn, silc_get_auth_ask_passphrase, a);
+      return;
+    }
+  }
+
+  /* No authentication */
+  completion(SILC_AUTH_NONE, NULL, 0, context);
 }
 
 /* Asks whether the user would like to perform the key agreement protocol.
index 87c81bb3bce378ae24a2375fb417dba8fe3d4db5..0d20e52bcb097e336ad1a86be81fddddf9e1f9a5 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001, 2006 Pekka Riikonen
+  Copyright (C) 2001 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -56,6 +56,7 @@ void silc_verify_public_key(SilcClient client, SilcClientConnection conn,
                            SilcVerifyPublicKey completion, void *context);
 void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
                          char *hostname, SilcUInt16 port,
+                         SilcAuthMethod auth_meth,
                          SilcGetAuthMeth completion, void *context);
 void silc_key_agreement(SilcClient client, SilcClientConnection conn,
                        SilcClientEntry client_entry, const char *hostname,
index 85ebe48d9f6fceaa3175364ea33a71b2769c6e25..7a8797460528ff2b00e4b3dbe48d886e85773d64 100644 (file)
@@ -1,7 +1,7 @@
 /*
   silc-channels.c : irssi
 
-  Copyright (C) 2000 - 2001, 2004, 2006 Timo Sirainen
+  Copyright (C) 2000 - 2001, 2004, 2006, 2007 Timo Sirainen
                 Pekka Riikonen <priikone@silcnet.org>
 
   This program is free software; you can redistribute it and/or modify
@@ -582,7 +582,7 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
   unsigned char **argv;
   SilcUInt32 *argv_lens, *argv_types;
   char *bindhost = NULL;
-  SilcChannelEntry ch = NULL;
+  SilcChannelPrivateKey ch = NULL;
   SilcDList ckeys;
   SilcBool udp = FALSE;
   int i;
@@ -751,7 +751,6 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
     }
   }
 
-#if 0
   /* List command */
   if (!strcasecmp(argv[3], "list")) {
     command = 3;
@@ -844,20 +843,20 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
       if (!ckeys)
        goto out;
 
-      for (k = 0; k < keys_count; k++) {
+      while ((ch = silc_dlist_get(ckeys))) {
        memset(buf, 0, sizeof(buf));
        strncat(buf, "  ", 2);
 
-       len = strlen(silc_cipher_get_name(keys[k]->cipher));
-       strncat(buf, silc_cipher_get_name(keys[k]->cipher),
+       len = strlen(silc_cipher_get_name(ch->cipher));
+       strncat(buf, silc_cipher_get_name(ch->cipher),
                len > 16 ? 16 : len);
        if (len < 16)
          for (i = 0; i < 16 - len; i++)
            strcat(buf, " ");
        strcat(buf, " ");
 
-       len = strlen(silc_hmac_get_name(keys[k]->hmac));
-       strncat(buf, silc_hmac_get_name(keys[k]->hmac), len > 16 ? 16 : len);
+       len = strlen(silc_hmac_get_name(ch->hmac));
+       strncat(buf, silc_hmac_get_name(ch->hmac), len > 16 ? 16 : len);
        if (len < 16)
          for (i = 0; i < 16 - len; i++)
            strcat(buf, " ");
@@ -868,12 +867,11 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
        silc_say(silc_client, conn, SILC_CLIENT_MESSAGE_INFO, "%s", buf);
       }
 
-      silc_client_free_channel_private_keys(keys, keys_count);
+      silc_dlist_uninit(ckeys);
     }
 
     goto out;
   }
-#endif /* 0 */
 
   /* Send command is used to send key agreement */
   if (!strcasecmp(argv[3], "agreement")) {
@@ -1046,38 +1044,39 @@ static void command_key(const char *data, SILC_SERVER_REC *server,
   return;
 }
 
-#if 0
 void silc_list_key(const char *pub_filename, int verbose)
 {
   SilcPublicKey public_key;
   SilcPublicKeyIdentifier ident;
+  SilcSILCPublicKey silc_pubkey;
   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;
-    }
+  if (!silc_pkcs_load_public_key((char *)pub_filename, &public_key)) {
+    printformat_module("fe-common/silc", NULL, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_LISTKEY_LOADPUB,
+                      pub_filename);
+    return;
+  }
 
-  ident = silc_pkcs_decode_identifier(public_key->identifier);
+  /* Print only SILC public keys */
+  if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) {
+    printformat_module("fe-common/silc", NULL, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_LISTKEY_LOADPUB,
+                      pub_filename);
+    return;
+  }
+
+  silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
+  ident = &silc_pubkey->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);
-  }
+  key_len = silc_pkcs_public_key_get_len(public_key);
 
   printformat_module("fe-common/silc", NULL, NULL,
                      MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_FILE,
@@ -1086,7 +1085,7 @@ void silc_list_key(const char *pub_filename, int verbose)
   if (verbose)
     printformat_module("fe-common/silc", NULL, NULL,
                        MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_ALG,
-                       public_key->name);
+                      silc_pkcs_get_name(public_key));
   if (key_len && verbose)
     printformat_module("fe-common/silc", NULL, NULL,
                         MSGLEVEL_CRAP, SILCTXT_LISTKEY_PUB_BITS,
@@ -1129,8 +1128,6 @@ void silc_list_key(const char *pub_filename, int verbose)
   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)
@@ -1141,7 +1138,7 @@ void silc_list_keys_in_dir(const char *dirname, const char *where)
   dir = opendir(dirname);
 
   if (dir == NULL)
-         cmd_return_error(CMDERR_ERRNO);
+    cmd_return_error(CMDERR_ERRNO);
 
   printformat_module("fe-common/silc", NULL, NULL,
                      MSGLEVEL_CRAP, SILCTXT_LISTKEY_LIST,
@@ -1191,9 +1188,7 @@ void silc_list_file(const char *filename)
 list_key:
 
   silc_list_key(path, TRUE);
-
 }
-#endif /* 0 */
 
 /* Lists locally saved client and server public keys. */
 static void command_listkeys(const char *data, SILC_SERVER_REC *server,
@@ -1248,9 +1243,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("listkeys", MODULE_NAME, (SIGNAL_FUNC) command_listkeys);
+  command_bind("listkeys", MODULE_NAME, (SIGNAL_FUNC) command_listkeys);
 
-  //command_set_options("listkeys", "clients servers");
+  command_set_options("listkeys", "clients servers");
   command_set_options("action", "sign channel");
   command_set_options("notice", "sign channel");
 
@@ -1270,7 +1265,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 5566ace2212d936df6f1872e65dfcb651a2ad31a..8c38c5c7130c294b96197e8aee2671649ac52bd4 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 - 2006 Pekka Riikonen
+  Copyright (C) 2001 - 2007 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -473,7 +473,6 @@ void silc_core_init(void)
   settings_add_int("server", "key_exchange_timeout_secs", 120);
   settings_add_int("server", "key_exchange_rekey_secs", 3600);
   settings_add_bool("server", "key_exchange_rekey_pfs", FALSE);
-  settings_add_int("server", "connauth_request_secs", 2);
   settings_add_int("server", "heartbeat", 300);
   settings_add_bool("server", "ignore_message_signatures", FALSE);
   settings_add_str("server", "session_filename", "session.$chatnet");
@@ -513,7 +512,6 @@ void silc_core_init(void)
   /* Initialize client parameters */
   memset(&params, 0, sizeof(params));
   strcat(params.nickname_format, "%n@%h%a");
-  params.connauth_request_secs = settings_get_int("connauth_request_secs");
 
   /* Allocate SILC client */
   silc_client = silc_client_alloc(&ops, &params, NULL, silc_version_string);
index e283abee9a383d44d9613cd3420c565515d9a572..6f58b5a0ceed6c07bba09278e4f1d47e6daa4459 100644 (file)
@@ -383,6 +383,8 @@ static void silc_connect_cb(SilcClient client,
   }
 }
 
+/* Called after TCP stream has been created */
+
 static void sig_connected_stream_created(SilcSocketStreamStatus status,
                                         SilcStream stream, void *context)
 {
@@ -466,6 +468,7 @@ static void sig_disconnected(SILC_SERVER_REC *server)
     net_sendbuffer_destroy(server->handle, FALSE);
     server->handle = NULL;
   } else if (server->op) {
+    /* Abort on going connecting (key exchange) */
     silc_async_abort(server->op, NULL, NULL);
     server->op = NULL;
   }