updates.
authorPekka Riikonen <priikone@silcnet.org>
Thu, 21 Jun 2001 18:19:02 +0000 (18:19 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Thu, 21 Jun 2001 18:19:02 +0000 (18:19 +0000)
14 files changed:
CHANGES
TODO
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/silc-channels.c
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/server.c
lib/silcclient/client.c
lib/silcclient/command.c
lib/silcclient/protocol.c
lib/silccore/silcpacket.h
lib/silcske/silcske.c
lib/silcske/silcske.h
lib/silcske/silcske_status.h

diff --git a/CHANGES b/CHANGES
index 2a159c486aac0ceb36e11616649fbde2f535d75f..022a733cb9d862df923593036671c23672a13175 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,31 @@ Thu Jun 21 17:10:08 CEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
          from the start and end of the arguments.  Affected file is
          lib/silcutil/silcutil.c.
 
          from the start and end of the arguments.  Affected file is
          lib/silcutil/silcutil.c.
 
+       * Cancel and free any active protocol in the function
+         silc_server_close_connection.  Affected file silcd/server.c.
+
+       * Cancel and free any active protocol in the function
+         silc_client_close_connction.  Affected file is
+         lib/silcclient/client.c.
+
+       * Do not execute the KILL command for clients that are in
+         history (ie. they are not in the network).  Affected file is
+         silcd/command.c.
+
+       * Fixed KILL notify handling, client does not crash anymore.
+         Affected file irssi/src/silc/core/silc-channels.c.
+
+       * Reduced the default packet buffer size from 2048 to 1024 in   
+         lib/silccore/silcpacket.c.
+
+       * Added SILC_SKE_STATUS_FREED SKE status type and a reference
+         counter to the SKE context that is incresed when the SKE library
+         performs async operation outside the library.  If the outside
+         process frees the SKE context and FREED status will be set 
+         and the library will detect after the sync operation that the
+         libary is freed.  The affected files are
+         lib/silcske/silcske[_status].[ch].
+
 Tue Jun 19 22:10:36 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Fixed a possible crash in silc_packet_send_prepare.  It now
 Tue Jun 19 22:10:36 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Fixed a possible crash in silc_packet_send_prepare.  It now
diff --git a/TODO b/TODO
index ad15d63429dcca71c1c09ca97793ac49063354f4..47181d968fc5dd52a898ae68db82b9109b33df3a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -5,11 +5,6 @@ TODO/bugs in Irssi SILC client
 
  o /KICK does not remove the client from Irssi's NAMES list.
 
 
  o /KICK does not remove the client from Irssi's NAMES list.
 
- o Giving KILL command crashes the client.
-
- o Waiting the answer for accepting new key after the protocol has
-   timeout and then ansering Y will crash the client.
-
  o Add PERL scripting support from Irssi CVS.
 
  o Add local commands to list the current server and client public keys
  o Add PERL scripting support from Irssi CVS.
 
  o Add local commands to list the current server and client public keys
@@ -43,6 +38,9 @@ TODO/bugs In SILC Client Library
    then it should attempt to resolve it at least once and no return
    NULL entry to the application.
 
    then it should attempt to resolve it at least once and no return
    NULL entry to the application.
 
+ o Add some silc_client_del_client and other deletion funtions for
+   application to delete client entrys from the cache.
+
  o All protocol execution timeouts are hard coded. They should be 
    configurable and the Irssi SILC client should be able to set them
    with for example /set key_exchange_timeout etc.  The silc_client_alloc
  o All protocol execution timeouts are hard coded. They should be 
    configurable and the Irssi SILC client should be able to set them
    with for example /set key_exchange_timeout etc.  The silc_client_alloc
index f80deb805012c02bc71eb421056a174bcf7bb14a..bb95f116a7b3e7fb8860c5ac0b04865e71d31208 100644 (file)
@@ -184,7 +184,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
    or connecting failed.  This is also the first time application receives
    the SilcClientConnection objecet which it should save somewhere. */
 
    or connecting failed.  This is also the first time application receives
    the SilcClientConnection objecet which it should save somewhere. */
 
-void  silc_connect(SilcClient client, SilcClientConnection conn, int success)
+void silc_connect(SilcClient client, SilcClientConnection conn, int success)
 {
   SILC_SERVER_REC *server = conn->context;
 
 {
   SILC_SERVER_REC *server = conn->context;
 
index 04d56233eba1917fe5c841b747ff08de26ba2552..71e597e2c1fc9fd049ef9884cd32e9a9685e89db 100644 (file)
@@ -426,11 +426,11 @@ static void event_kick(SILC_SERVER_REC *server, va_list va)
   
   if (client_entry == conn->local_entry) {
     printformat_module("fe-common/silc", server, channel_entry->channel_name,
   
   if (client_entry == conn->local_entry) {
     printformat_module("fe-common/silc", server, channel_entry->channel_name,
-                      MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_KICKED_YOU, 
+                      MSGLEVEL_CRAP, SILCTXT_CHANNEL_KICKED_YOU, 
                       channel_entry->channel_name, tmp ? tmp : "");
   } else {
     printformat_module("fe-common/silc", server, channel_entry->channel_name,
                       channel_entry->channel_name, tmp ? tmp : "");
   } else {
     printformat_module("fe-common/silc", server, channel_entry->channel_name,
-                      MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_KICKED, 
+                      MSGLEVEL_CRAP, SILCTXT_CHANNEL_KICKED, 
                       client_entry->nickname,
                       channel_entry->channel_name, tmp ? tmp : "");
   }
                       client_entry->nickname,
                       channel_entry->channel_name, tmp ? tmp : "");
   }
@@ -444,22 +444,20 @@ static void event_kill(SILC_SERVER_REC *server, va_list va)
 {
   SilcClientConnection conn = server->conn;
   SilcClientEntry client_entry;
 {
   SilcClientConnection conn = server->conn;
   SilcClientEntry client_entry;
-  SilcChannelEntry channel_entry;
   char *tmp;
 
   client_entry = va_arg(va, SilcClientEntry);
   tmp = va_arg(va, char *);
   char *tmp;
 
   client_entry = va_arg(va, SilcClientEntry);
   tmp = va_arg(va, char *);
-  channel_entry = va_arg(va, SilcChannelEntry);
   
   if (client_entry == conn->local_entry) {
   
   if (client_entry == conn->local_entry) {
-    printformat_module("fe-common/silc", server, channel_entry->channel_name,
-                      MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_KILLED_YOU, 
-                      channel_entry->channel_name, tmp ? tmp : "");
+    printformat_module("fe-common/silc", server, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED_YOU, 
+                      tmp ? tmp : "");
   } else {
   } else {
-    printformat_module("fe-common/silc", server, channel_entry->channel_name,
-                      MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_KILLED, 
+    printformat_module("fe-common/silc", server, NULL,
+                      MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED, 
                       client_entry->nickname,
                       client_entry->nickname,
-                      channel_entry->channel_name, tmp ? tmp : "");
+                      tmp ? tmp : "");
   }
 }
 
   }
 }
 
index 2d0f493e7b928c462e1ffdcc69fd5ba3eccca9ea..48033266a4e0eb5f7ced7b97007340b52f18e0f3 100644 (file)
@@ -2458,6 +2458,12 @@ SILC_SERVER_CMD_FUNC(kill)
     }
   }
 
     }
   }
 
+  if (remote_client->data.registered == FALSE) {
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_KILL,
+                                         SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+    goto out;
+  }
+
   /* Get comment */
   comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
   if (tmp_len2 > 128)
   /* Get comment */
   comment = silc_argument_get_arg_type(cmd->args, 2, &tmp_len2);
   if (tmp_len2 > 128)
index d4899345a514001b22b1d0e8a0d2ef5e5d741692..0c010bdfe97d377dd98ecf46207aaf7ac4143bfa 100644 (file)
@@ -316,7 +316,7 @@ void silc_server_notify(SilcServer server,
 
     if (channel->topic)
       silc_free(channel->topic);
 
     if (channel->topic)
       silc_free(channel->topic);
-    channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
+    channel->topic = silc_calloc(tmp_len + 1, sizeof(*channel->topic));
     memcpy(channel->topic, tmp, tmp_len);
 
     /* Send the same notify to the channel */
     memcpy(channel->topic, tmp, tmp_len);
 
     /* Send the same notify to the channel */
index d20df0767481e7418b6f2ce4355f7e40f9451d74..cda5026b58dde21d9d39c46486fe3e32ec5e4223 100644 (file)
@@ -2080,6 +2080,14 @@ void silc_server_close_connection(SilcServer server,
                  sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
                  "Router"), sock->sock));
 
                  sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" :
                  "Router"), sock->sock));
 
+  /* If any protocol is active cancel its execution */
+  if (sock->protocol) {
+    silc_protocol_cancel(sock->protocol, server->timeout_queue);
+    sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
+    silc_protocol_execute_final(sock->protocol, server->timeout_queue);
+    sock->protocol = NULL;
+  }
+
   /* We won't listen for this connection anymore */
   silc_schedule_unset_listen_fd(sock->sock);
 
   /* We won't listen for this connection anymore */
   silc_schedule_unset_listen_fd(sock->sock);
 
index 0fbc909d2c6ee78558c89245e2beba485463f7cc..36c4c93d50613744a23bb06b9dcaa3b658ba2bf4 100644 (file)
@@ -1156,16 +1156,34 @@ void silc_client_close_connection(SilcClient client,
   /* Close the actual connection */
   silc_net_close_connection(sock->sock);
 
   /* Close the actual connection */
   silc_net_close_connection(sock->sock);
 
+  /* Cancel any active protocol */
+  if (sock->protocol) {
+    if (sock->protocol->protocol->type == 
+       SILC_PROTOCOL_CLIENT_KEY_EXCHANGE ||
+       sock->protocol->protocol->type == 
+       SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
+      sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
+      silc_protocol_execute_final(sock->protocol, client->timeout_queue);
+      sock->protocol = NULL;
+      /* The application will recall this function with these protocols
+        (the ops->connect client operation). */
+      return;
+    } else {
+      sock->protocol->state = SILC_PROTOCOL_STATE_ERROR;
+      silc_protocol_execute_final(sock->protocol, client->timeout_queue);
+      sock->protocol = NULL;
+    }
+  }
+
   /* Free everything */
   if (del && sock->user_data) {
     /* XXX Free all client entries and channel entries. */
 
   /* Free everything */
   if (del && sock->user_data) {
     /* XXX Free all client entries and channel entries. */
 
-    client->ops->say(client, sock->user_data,
-                    "Closed connection to host %s", sock->hostname);
-
     /* Clear ID caches */
     /* Clear ID caches */
-    silc_idcache_del_all(conn->client_cache);
-    silc_idcache_del_all(conn->channel_cache);
+    if (conn->client_cache)
+      silc_idcache_del_all(conn->client_cache);
+    if (conn->channel_cache)
+      silc_idcache_del_all(conn->channel_cache);
 
     /* Free data */
     if (conn->remote_host)
 
     /* Free data */
     if (conn->remote_host)
@@ -1185,27 +1203,10 @@ void silc_client_close_connection(SilcClient client,
     if (conn->rekey)
       silc_free(conn->rekey);
 
     if (conn->rekey)
       silc_free(conn->rekey);
 
-    conn->sock = NULL;
-    conn->remote_port = 0;
-    conn->remote_type = 0;
-    conn->send_key = NULL;
-    conn->receive_key = NULL;
-    conn->hmac_send = NULL;
-    conn->hmac_receive = NULL;
-    conn->local_id = NULL;
-    conn->local_id_data = NULL;
-    conn->remote_host = NULL;
-    conn->current_channel = NULL;
-    conn->pending_commands = NULL;
-    conn->rekey = NULL;
-
+    memset(conn, 0, sizeof(*conn));
     silc_client_del_connection(client, conn);
   }
 
     silc_client_del_connection(client, conn);
   }
 
-  if (sock->protocol) {
-    silc_protocol_free(sock->protocol);
-    sock->protocol = NULL;
-  }
   silc_socket_free(sock);
 }
 
   silc_socket_free(sock);
 }
 
index 6b90b3698c136d85fedc86de62a9e46cb767e921..ee12b1ea27fe48ede6136042b0603ae49cf9006e 100644 (file)
@@ -793,6 +793,20 @@ SILC_CLIENT_CMD_FUNC(kill)
   silc_buffer_free(buffer);
   silc_buffer_free(idp);
 
   silc_buffer_free(buffer);
   silc_buffer_free(idp);
 
+  /* Remove the client entry from the local cache. */
+  silc_idcache_del_by_context(conn->client_cache, target);
+  if (target->nickname)
+    silc_free(target->nickname);
+  if (target->server)
+    silc_free(target->server);
+  if (target->id)
+    silc_free(target->id);
+  if (target->send_key)
+    silc_cipher_free(target->send_key);
+  if (target->receive_key)
+    silc_cipher_free(target->receive_key);
+  silc_free(target);
+
   /* Notify application */
   COMMAND;
 
   /* Notify application */
   COMMAND;
 
index 9231f8cf5ac7e3f5f0e7b8f06d6d69f8ce15cdfa..bb9c651313c53e0b96d3983b30431bb6fba06b53 100644 (file)
@@ -74,7 +74,7 @@ static void silc_client_verify_key_cb(bool success, void *context)
   silc_free(verify);
 }
 
   silc_free(verify);
 }
 
-/* Callback that is called when we have received KE2 payload from
+/* Callback that is called when we have received KE payload from
    responder. We try to verify the public key now. */
 
 void silc_client_protocol_ke_verify_key(SilcSKE ske,
    responder. We try to verify the public key now. */
 
 void silc_client_protocol_ke_verify_key(SilcSKE ske,
index 029c455debfcaee7e462fdc11c5a65c3e911bb71..2174b0fbdb8ed22c8e20fea16dadce8e65e54d38 100644 (file)
@@ -35,9 +35,8 @@
 /* Amount of bytes to be read from the socket connection at once. */
 #define SILC_PACKET_READ_SIZE 16384
 
 /* Amount of bytes to be read from the socket connection at once. */
 #define SILC_PACKET_READ_SIZE 16384
 
-/* Default byte size of the packet. This can be set larger if this
-   is not enough, we shall see. */
-#define SILC_PACKET_DEFAULT_SIZE 2048
+/* Default byte size of the packet. */
+#define SILC_PACKET_DEFAULT_SIZE 1024
 
 /* Header length without source and destination ID's. */
 #define SILC_PACKET_HEADER_LEN 8 + 2
 
 /* Header length without source and destination ID's. */
 #define SILC_PACKET_HEADER_LEN 8 + 2
index 7d34d61aa2c426e706921c6064fdb51b3bb88bdf..6399b0f162158176bd2838b5032f90c1bf5265e5 100644 (file)
@@ -33,6 +33,7 @@ SilcSKE silc_ske_alloc()
 
   ske = silc_calloc(1, sizeof(*ske));
   ske->status = SILC_SKE_STATUS_OK;
 
   ske = silc_calloc(1, sizeof(*ske));
   ske->status = SILC_SKE_STATUS_OK;
+  ske->users = 1;
 
   return ske;
 }
 
   return ske;
 }
@@ -41,6 +42,13 @@ SilcSKE silc_ske_alloc()
 
 void silc_ske_free(SilcSKE ske)
 {
 
 void silc_ske_free(SilcSKE ske)
 {
+  ske->users--;
+  if (ske->users > 0) {
+    SILC_LOG_DEBUG(("Key Exchange set to FREED status"));
+    ske->status = SILC_SKE_STATUS_FREED;
+    return;
+  }
+
   SILC_LOG_DEBUG(("Freeing Key Exchange object"));
 
   if (ske) {
   SILC_LOG_DEBUG(("Freeing Key Exchange object"));
 
   if (ske) {
@@ -336,11 +344,22 @@ static void silc_ske_initiator_finish_final(SilcSKE ske,
                                            void *context)
 {
   SKEInitiatorFinish finish = (SKEInitiatorFinish)context;
                                            void *context)
 {
   SKEInitiatorFinish finish = (SKEInitiatorFinish)context;
-  SilcSKEKEPayload *payload = ske->ke2_payload;
+  SilcSKEKEPayload *payload;
   unsigned char hash[32];
   uint32 hash_len;
   SilcPublicKey public_key = NULL;
 
   unsigned char hash[32];
   uint32 hash_len;
   SilcPublicKey public_key = NULL;
 
+  /* If the SKE was freed during the async call then free it really now,
+     otherwise just decrement the reference counter. */
+  if (ske->status == SILC_SKE_STATUS_FREED) {
+    silc_ske_free(ske);
+    return;
+  } else {
+    ske->users--;
+  }
+
+  payload = ske->ke2_payload;
+
   /* If the caller returns PENDING status SKE library will assume that
      the caller will re-call this callback when it is not anymore in
      PENDING status. */
   /* If the caller returns PENDING status SKE library will assume that
      the caller will re-call this callback when it is not anymore in
      PENDING status. */
@@ -382,8 +401,7 @@ static void silc_ske_initiator_finish_final(SilcSKE ske,
     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
 
     /* Verify signature */
     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
 
     /* Verify signature */
-    silc_pkcs_public_key_data_set(ske->prop->pkcs, public_key->pk, 
-                                 public_key->pk_len);
+    silc_pkcs_public_key_set(ske->prop->pkcs, public_key);
     if (silc_pkcs_verify(ske->prop->pkcs, payload->sign_data, 
                         payload->sign_len, hash, hash_len) == FALSE) {
       
     if (silc_pkcs_verify(ske->prop->pkcs, payload->sign_data, 
                         payload->sign_len, hash, hash_len) == FALSE) {
       
@@ -500,6 +518,7 @@ SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske,
   if (payload->pk_data && verify_key) {
     SILC_LOG_DEBUG(("Verifying public key"));
     
   if (payload->pk_data && verify_key) {
     SILC_LOG_DEBUG(("Verifying public key"));
     
+    ske->users++;
     (*verify_key)(ske, payload->pk_data, payload->pk_len,
                  payload->pk_type, verify_context,
                  silc_ske_initiator_finish_final, finish);
     (*verify_key)(ske, payload->pk_data, payload->pk_len,
                  payload->pk_type, verify_context,
                  silc_ske_initiator_finish_final, finish);
@@ -696,6 +715,15 @@ static void silc_ske_responder_phase2_final(SilcSKE ske,
   SilcSKEKEPayload *recv_payload, *send_payload;
   SilcMPInt *x, f;
 
   SilcSKEKEPayload *recv_payload, *send_payload;
   SilcMPInt *x, f;
 
+  /* If the SKE was freed during the async call then free it really now,
+     otherwise just decrement the reference counter. */
+  if (ske->status == SILC_SKE_STATUS_FREED) {
+    silc_ske_free(ske);
+    return;
+  } else {
+    ske->users--;
+  }
+
   recv_payload = ske->ke1_payload;
 
   /* If the caller returns PENDING status SKE library will assume that
   recv_payload = ske->ke1_payload;
 
   /* If the caller returns PENDING status SKE library will assume that
@@ -748,8 +776,7 @@ static void silc_ske_responder_phase2_final(SilcSKE ske,
     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
     
     /* Verify signature */
     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
     
     /* Verify signature */
-    silc_pkcs_public_key_data_set(ske->prop->pkcs, public_key->pk, 
-                                 public_key->pk_len);
+    silc_pkcs_public_key_set(ske->prop->pkcs, public_key);
     if (silc_pkcs_verify(ske->prop->pkcs, recv_payload->sign_data, 
                         recv_payload->sign_len, hash, hash_len) == FALSE) {
       
     if (silc_pkcs_verify(ske->prop->pkcs, recv_payload->sign_data, 
                         recv_payload->sign_len, hash, hash_len) == FALSE) {
       
@@ -867,6 +894,7 @@ SilcSKEStatus silc_ske_responder_phase_2(SilcSKE ske,
     if (recv_payload->pk_data && verify_key) {
       SILC_LOG_DEBUG(("Verifying public key"));
 
     if (recv_payload->pk_data && verify_key) {
       SILC_LOG_DEBUG(("Verifying public key"));
 
+      ske->users++;
       (*verify_key)(ske, recv_payload->pk_data, recv_payload->pk_len,
                    recv_payload->pk_type, verify_context,
                    silc_ske_responder_phase2_final, finish);
       (*verify_key)(ske, recv_payload->pk_data, recv_payload->pk_len,
                    recv_payload->pk_type, verify_context,
                    silc_ske_responder_phase2_final, finish);
index 14620c71a0635ddd4b9b8e5b6c60ef592b680405..63388dc2a1bd5c8da979cfedc458bb3c275222f9 100644 (file)
@@ -160,6 +160,10 @@ struct SilcSKEStruct {
 
   /* Current status of SKE */
   SilcSKEStatus status;
 
   /* Current status of SKE */
   SilcSKEStatus status;
+
+  /* Reference counter. This is used when SKE library is performing async
+     operations, like public key verification. */
+  int users;
 };
 
 /* Prototypes */
 };
 
 /* Prototypes */
index c2f85c9c5b56b3f77f6a9bde73148589ce080f1d..7e03cecb6fb7fca9157e1f670526f512745bf5b7 100644 (file)
@@ -43,6 +43,7 @@ typedef enum {
   SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH,
   SILC_SKE_STATUS_INCORRECT_HASH,
   SILC_SKE_STATUS_INCORRECT_PUBLIC_KEY,
   SILC_SKE_STATUS_BAD_PAYLOAD_LENGTH,
   SILC_SKE_STATUS_INCORRECT_HASH,
   SILC_SKE_STATUS_INCORRECT_PUBLIC_KEY,
+  SILC_SKE_STATUS_FREED,
 } SilcSKEStatus;
 
 #endif
 } SilcSKEStatus;
 
 #endif