updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 2 Apr 2001 10:24:13 +0000 (10:24 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 2 Apr 2001 10:24:13 +0000 (10:24 +0000)
CHANGES
TODO
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/idlist.c
apps/silcd/idlist.h
apps/silcd/server.c
lib/silcutil/silctask.c
lib/silcutil/silctask.h

diff --git a/CHANGES b/CHANGES
index 0755122a3ea61d0b1fa0eb539bb5dcfae1282349..8fb8dedef55806d9c36f370d435edbf597fa4621 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,4 @@
-Mon Apr  2 15:13:23 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+Mon Apr  2 13:13:23 EEST 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Updated TODO.
 
diff --git a/TODO b/TODO
index 2798813789e52b4a7e69ef6cc1f30722ab5af4a1..13beb86d0e651192bba149c56478a3f111cbe28b 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,17 +1,3 @@
-TODO
-====
-
-This is more or less complete list of tasks that has to be done before
-SILC 1.0 could ever be released.  It is clear that the list does not
-include all the bugs that exists.  At the end of list are tasks that 
-needs to be done but are probably post 1.0.
-
-Feel free to contribute if you have the ability and free time - all the
-help is really appreciated - and needed.
-
-                                                       - Pekka
-
-
 TODO General
 ============
 
@@ -32,20 +18,9 @@ TODO In SILC Client Library
    the SilcSocketConnection reference counter at all.  This must be
    fixed.
 
- o Logic for handling multiple same nicknames for example in private
-   message sending.  I guess the logic is done in server side but is
-   missing from client.
-
  o I guess, public key authentication (when connecting to a server)
    is not working currently.  It is just matter of loading the keys
-   from file and using them (see corresponding code in server, it should
-   support public key authentication already).
-
- o Non-blocking connection on the background must be stopped if some
-   other connection on same window has established.  Now it is possible
-   that some non-blocking connection timeouts on the background when
-   we already have a working connection to some other place; things
-   goes bad.
+   from file and using them (see corresponding code in server).
 
  o Add client library parameters or options that handle what kind of
    messages the library should print out (using `say' client operation,
@@ -75,20 +50,20 @@ TODO In SILC Server
 
        o SERVER_SIGNOFF notify type is not implemented
 
- o Packet processing can be made faster. All packet function in the
-   packet_receive.c has same prototypes.  Instead of calling those from
-   huge switch() make a table of callback functions that can be called
-   directly by the packet type.
+ o Acceptance of incoming connections (client and server connections)
+   should be checked before key exchange protocol.  Currently it is
+   checked at the authentication phase after KE, that is ok, but it should
+   be checked before starting KE, as well.
 
  o DNS/IP lookup blocks the server.  This must be fixed.  Check the
    resolver stuff (resolver(3), resolver(5)).  Either we have to do the
    own resolver stuff (through scheduler, if possible without writing
    too much own stuff) or use threads.
 
- o Acceptance of incoming connections (client and server connections)
-   should be checked before key exchange protocol.  Currently it is
-   checked at the authentication phase after KE, that is ok, but it should
-   be checked before starting KE, as well.
+ o Packet processing can be made faster. All packet function in the
+   packet_receive.c has same prototypes.  Instead of calling those from
+   huge switch() make a table of callback functions that can be called
+   directly by the packet type.
 
  o Server says that it is able to listen on multiple ports but currently
    that is bogus.  It can, but internals are for single server.
@@ -105,10 +80,6 @@ TODO In SILC Server
 TODO In SILC Libraries
 ======================
 
- o The SKE Start Payload parsing routines are an overkill.  Use the
-   SILC_STR_UI16_NSTRING_ALLOC in the parsing and not parsing them
-   one by one like done now.
-
  o Implement PFS (Perfect Forward Secrecy) flag in SKE (and in client and
    server, actually).  If PFS is set, re-key must cause new key exchange.
    This is required by the SILC protocol.
@@ -151,13 +122,6 @@ TODO in the protocol before SILC 0.x
          public keys blindly without third party verification; that's
          why SENDKEY is not for servers).
 
- o New features in the KE/auth protocol
-   (draft-riikonen-silc-ke-auth-xx.txt):
-
-       o Define group exchange support for the SKE so that the SKE
-         could be performed among more than two entities.  This is not
-         a showstopper and may be defined later.
-
 
 TODO After 1.0
 ==============
index c317a5462a2d40c22556cde3dccfad2bcffc3970..75afbfd92f472408088af380bf379badd5d83149 100644 (file)
@@ -3919,7 +3919,7 @@ SILC_SERVER_CMD_FUNC(cumode)
       goto out;
     }
 
-    chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
+    sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
     notify = TRUE;
   } else {
     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
index 79eb2bbeabebbc518b25719608d2e336f2e17d5f..588c1a0ca30b3187beb600033a4f0558d9f5d9d2 100644 (file)
@@ -722,8 +722,8 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
     }
   } else {
     /* The entry exists. */
-    if (entry->id)
-      silc_free(entry->id);
+    if (cache->id)
+      silc_free(cache->id);
     entry->id = id;
     cache->id = entry->id;
 
@@ -784,9 +784,8 @@ SILC_SERVER_CMD_REPLY_FUNC(join)
   entry->mode = mode;
 
   /* Save channel key */
-  if (!(entry->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
+  if (!(entry->mode & SILC_CHANNEL_MODE_PRIVKEY))
     silc_server_save_channel_key(server, keyp, entry);
-  }
   if (keyp)
     silc_buffer_free(keyp);
 
index 99b375e762eab456bd8569cae99a46e7af18e477..02f9f41e5890d0ce2ef879f54ceae46c9aa4cf47 100644 (file)
@@ -630,6 +630,8 @@ int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry)
       silc_free(entry->cipher);
     if (entry->hmac_name)
       silc_free(entry->hmac_name);
+    if (entry->rekey)
+      silc_free(entry->rekey);
 
     /* Free all data, free also any reference from the client's channel
        list since they share the same memory. */
index 57eb1d065931097edb11aa24c067e18aed12423a..f36a6a633dd34369d08f31f4bbff5788b6c8837c 100644 (file)
@@ -33,6 +33,13 @@ typedef struct {
   void *timeout_queue;
 } *SilcIDListPurge;
 
+/* Channel key re-key context. */
+typedef struct {
+  void *context;
+  SilcChannelEntry channel;
+  unsigned int key_len;
+} *SilcServerChannelRekey;
+
 /*
    Generic ID list data structure.
 
@@ -394,6 +401,10 @@ struct SilcClientEntryStruct {
 
        HMAC of the channel.
 
+   SilcServerChannelRekey rekey
+
+       Channel key re-key context.
+
 */
 struct SilcChannelEntryStruct {
   char *channel_name;
@@ -426,6 +437,8 @@ struct SilcChannelEntryStruct {
   unsigned int key_len;
   unsigned char iv[SILC_CIPHER_MAX_IV_SIZE];
   SilcHmac hmac;
+
+  SilcServerChannelRekey rekey;
 };
 
 /* 
index 64e70fd16d7597710460572b33e2a9f8f6a445fb..b96d50435e2a85900674efa5afa5634ed2b47071 100644 (file)
@@ -2266,11 +2266,13 @@ void silc_server_remove_from_channels(SilcServer server,
        silc_list_count(channel->user_list) < 2) {
       server->stat.my_channels--;
 
+      if (channel->rekey)
+       silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
+
       if (channel->founder_key) {
        /* The founder auth data exists, do not remove the channel entry */
        SilcChannelClientEntry chl2;
 
-       silc_free(channel->id);
        channel->id = NULL;
 
        silc_list_start(channel->user_list);
@@ -2313,11 +2315,13 @@ void silc_server_remove_from_channels(SilcServer server,
 
       server->stat.my_channels--;
 
+      if (channel->rekey)
+       silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
+
       if (channel->founder_key) {
        /* The founder auth data exists, do not remove the channel entry */
        SilcChannelClientEntry chl2;
 
-       silc_free(channel->id);
        channel->id = NULL;
 
        silc_list_start(channel->user_list);
@@ -2394,6 +2398,8 @@ int silc_server_remove_from_one_channel(SilcServer server,
     /* Remove channel if there is no users anymore */
     if (server->server_type == SILC_ROUTER &&
        silc_list_count(channel->user_list) < 2) {
+      if (channel->rekey)
+       silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
       if (!silc_idlist_del_channel(server->local_list, channel))
        silc_idlist_del_channel(server->global_list, channel);
       silc_buffer_free(clidp);
@@ -2425,11 +2431,13 @@ int silc_server_remove_from_one_channel(SilcServer server,
       server->stat.my_channels--;
       silc_buffer_free(clidp);
 
+      if (channel->rekey)
+       silc_task_unregister_by_context(server->timeout_queue, channel->rekey);
+
       if (channel->founder_key) {
        /* The founder auth data exists, do not remove the channel entry */
        SilcChannelClientEntry chl2;
 
-       silc_free(channel->id);
        channel->id = NULL;
 
        silc_list_start(channel->user_list);
@@ -2622,6 +2630,23 @@ silc_server_create_new_channel_with_id(SilcServer server,
   return entry;
 }
 
+/* Channel's key re-key timeout callback. */
+
+SILC_TASK_CALLBACK(silc_server_channel_key_rekey)
+{
+  SilcServerChannelRekey rekey = (SilcServerChannelRekey)context;
+  SilcServer server = (SilcServer)rekey->context;
+
+  silc_server_create_channel_key(server, rekey->channel, rekey->key_len);
+  silc_server_send_channel_key(server, NULL, rekey->channel, FALSE);
+
+  silc_task_register(server->timeout_queue, 0, 
+                    silc_server_channel_key_rekey,
+                    (void *)rekey, 3600, 0,
+                    SILC_TASK_TIMEOUT,
+                    SILC_TASK_PRI_NORMAL);
+}
+
 /* Generates new channel key. This is used to create the initial channel key
    but also to re-generate new key for channel. If `key_len' is provided
    it is the bytes of the key length. */
@@ -2676,6 +2701,22 @@ void silc_server_create_channel_key(SilcServer server,
   silc_hash_make(channel->hmac->hash, channel->key, len, hash);
   silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash));
   memset(hash, 0, sizeof(hash));
+
+  if (server->server_type == SILC_ROUTER) {
+    if (!channel->rekey)
+      channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
+    channel->rekey->context = (void *)server;
+    channel->rekey->channel = channel;
+    channel->rekey->key_len = key_len;
+
+    silc_task_unregister_by_callback(server->timeout_queue,
+                                    silc_server_channel_key_rekey);
+    silc_task_register(server->timeout_queue, 0, 
+                      silc_server_channel_key_rekey,
+                      (void *)channel->rekey, 3600, 0,
+                      SILC_TASK_TIMEOUT,
+                      SILC_TASK_PRI_NORMAL);
+  }
 }
 
 /* Saves the channel key found in the encoded `key_payload' buffer. This 
@@ -2767,6 +2808,21 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server,
   memset(hash, 0, sizeof(hash));
   memset(tmp, 0, tmp_len);
 
+  if (server->server_type == SILC_ROUTER) {
+    if (!channel->rekey)
+      channel->rekey = silc_calloc(1, sizeof(*channel->rekey));
+    channel->rekey->context = (void *)server;
+    channel->rekey->channel = channel;
+
+    silc_task_unregister_by_callback(server->timeout_queue,
+                                    silc_server_channel_key_rekey);
+    silc_task_register(server->timeout_queue, 0, 
+                      silc_server_channel_key_rekey,
+                      (void *)channel->rekey, 3600, 0,
+                      SILC_TASK_TIMEOUT,
+                      SILC_TASK_PRI_NORMAL);
+  }
+
  out:
   if (id)
     silc_free(id);
index 19c17f37dbddadfe0e1af00240e407debec1d885..688594c92cb092ec0bda0c79d57e27aff928cd40 100644 (file)
@@ -594,6 +594,28 @@ void silc_task_unregister_by_callback(SilcTaskQueue queue,
   }
 }
 
+/* Unregister a task by context. This invalidates the task. */
+
+void silc_task_unregister_by_context(SilcTaskQueue queue, void *context)
+{
+  SilcTask next;
+
+  SILC_LOG_DEBUG(("Unregister task by context"));
+
+  if (queue->task == NULL)
+    return;
+
+  next = queue->task;
+
+  while(1) {
+    if (next->context == context)
+      next->valid = FALSE;
+    if (queue->task == next->next)
+      break;
+    next = next->next;
+  }
+}
+
 /* Sets the I/O mask for the task. Only one I/O type can be set at a
    time. */
 
index 13a3ec90b3669d1abf7aa62e39bdab6eec495206..6fff792ed983573fb562577f7e42fbd5bc981b77 100644 (file)
@@ -351,6 +351,7 @@ void silc_task_unregister(SilcTaskQueue queue, SilcTask task);
 void silc_task_unregister_by_fd(SilcTaskQueue queue, int fd);
 void silc_task_unregister_by_callback(SilcTaskQueue queue, 
                                      SilcTaskCallback callback);
+void silc_task_unregister_by_context(SilcTaskQueue queue, void *context);
 void silc_task_set_iotype(SilcTask task, int type);
 void silc_task_reset_iotype(SilcTask task, int type);
 int silc_task_timeout_compare(struct timeval *smaller,