Fixed CMODE sending and receiving when it comes to channel
authorPekka Riikonen <priikone@silcnet.org>
Mon, 7 May 2007 18:34:43 +0000 (18:34 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 7 May 2007 18:34:43 +0000 (18:34 +0000)
public keys.

CHANGES
TODO
lib/silcclient/client_channel.c
lib/silcclient/client_channel.h
lib/silcclient/client_entry.c
lib/silcclient/client_notify.c
lib/silcclient/client_prvmsg.c
lib/silcclient/command.c
lib/silcclient/command_reply.c
lib/silcclient/silcclient.h

diff --git a/CHANGES b/CHANGES
index 5b0ef69ccb9abd15c74361955f6702df1fef341b..25e2a1cd18accaa6b939775e5917dc47edebf085 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+Mon May  7 18:18:48 EEST 2007  Pekka Riikonen <priikone@silcnet.org>
+
+       * Fixed CMODE channel auth public key retrieval.  Affected
+         file is lib/silcclient/command.c.
+
+       * Fixed CMODE command reply to return channel public keys
+         correctly.  Affected files are lib/silcclient/command_reply.c
+         and client_channel.c.
+
 Sun May  6 12:43:19 EEST 2007  Pekka Riikonen <priikone@silcnet.org>
 
        * Added current channel key cipher name and HMAC name to
diff --git a/TODO b/TODO
index f7a6ee6a4471d8809edb91f1ecdc55a0e9bc07dd..b091bdb41cfbcb98322e5bc1a4f509a973afe85c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -38,7 +38,7 @@ apps/silcd, The SILC Server   ****PARTLY DONE****
 SILC Client    ****PARTLY DONE****
 ===========
 
- o Porting to new Toolkit API and new Client Library API (***TESTING NEEDED)
+ o Porting to new Toolkit API and new Client Library API (***DONE)
 
  o Improve help files, especially /cmode, /cumode and /key.
 
index 077399b213db7784ee66ef31876df75426d00f93..1d78d221b6f6c438ddb6980ef335ae5cf59b17b7 100644 (file)
@@ -887,12 +887,29 @@ void silc_client_empty_channel(SilcClient client,
 
 SilcBool silc_client_channel_save_public_keys(SilcChannelEntry channel,
                                              unsigned char *chpk_list,
-                                             SilcUInt32 chpk_list_len)
+                                             SilcUInt32 chpk_list_len,
+                                             SilcBool remove_all)
 {
   SilcArgumentDecodedList a, b;
   SilcDList chpks;
   SilcBool found;
 
+  if (remove_all) {
+    /* Remove all channel public keys */
+    if (!channel->channel_pubkeys)
+      return FALSE;
+
+    silc_dlist_start(channel->channel_pubkeys);
+    while ((b = silc_dlist_get(channel->channel_pubkeys)))
+      silc_dlist_del(channel->channel_pubkeys, b);
+
+    silc_dlist_uninit(channel->channel_pubkeys);
+    channel->channel_pubkeys = NULL;
+
+    return TRUE;
+  }
+
+  /* Parse channel public key list and add or remove public keys */
   chpks = silc_argument_list_parse_decoded(chpk_list, chpk_list_len,
                                           SILC_ARGUMENT_PUBLIC_KEY);
   if (!chpks)
index 6ec49c6c2356f53c34cf1bfa7bd3c1baa6333d17..0854aa5fac5f9e453b25d01f4cf287c62f4a82fc 100644 (file)
@@ -47,6 +47,7 @@ void silc_client_empty_channel(SilcClient client,
                               SilcChannelEntry channel);
 SilcBool silc_client_channel_save_public_keys(SilcChannelEntry channel,
                                              unsigned char *chpk_list,
-                                             SilcUInt32 chpk_list_len);
+                                             SilcUInt32 chpk_list_len,
+                                             SilcBool remove_all);
 
 #endif /* CLIENT_CHANNEL_H */
index f4354a8aba9371d0b17d93aab74bc27a20e0a874..fb6479a7c6b5eb525d39ff009de79ee4cdc444c9 100644 (file)
@@ -257,8 +257,11 @@ silc_client_get_client_by_id_resolve(SilcClient client,
   SilcBuffer idp;
   SilcUInt16 cmd_ident;
 
-  if (!client || !conn | !client_id)
+  if (!client || !conn | !client_id) {
+    SILC_LOG_ERROR(("Missing arguments to "
+                   "silc_client_get_clients_by_id_resolve call"));
     return 0;
+  }
 
   SILC_LOG_DEBUG(("Resolve client by ID (%s)",
                  silc_id_render(client_id, SILC_ID_CLIENT)));
@@ -326,10 +329,14 @@ static SilcUInt16 silc_client_get_clients_i(SilcClient client,
   SILC_LOG_DEBUG(("Resolve client by %s command",
                  silc_get_command_name(command)));
 
-  if (!client || !conn)
+  if (!client || !conn) {
+    SILC_LOG_ERROR(("Missing arguments to silc_client_get_clients call"));
     return 0;
-  if (!nickname && !attributes)
+  }
+  if (!nickname && !attributes) {
+    SILC_LOG_ERROR(("Missing arguments to silc_client_get_clients call"));
     return 0;
+  }
 
   /* Parse server name from the nickname if set */
   if (silc_parse_userfqdn(nickname, nick, sizeof(nick),
index 12d22a8be7f0e88d3502d4afade8373898c2789f..10c36a324f8fa5bae0fd151cbc1dc5789f061133 100644 (file)
@@ -928,13 +928,15 @@ SILC_FSM_STATE(silc_client_notify_cmode_change)
   if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT))
     channel->user_limit = 0;
 
-  /* Save the new mode */
-  channel->mode = mode;
-
   /* Get the channel public key that was added or removed */
   tmp = silc_argument_get_arg_type(args, 7, &tmp_len);
   if (tmp)
-    silc_client_channel_save_public_keys(channel, tmp, tmp_len);
+    silc_client_channel_save_public_keys(channel, tmp, tmp_len, FALSE);
+  else if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
+    silc_client_channel_save_public_keys(channel, NULL, 0, TRUE);
+
+  /* Save the new mode */
+  channel->mode = mode;
 
   silc_rwlock_unlock(channel->internal.lock);
 
index 9b6002e5dac80f52a182e78c427ca85e5253df6a..c988494299b3baad131affa8e5ca676e9a5be215 100644 (file)
@@ -624,6 +624,16 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
   silc_free(keys);
 }
 
+/* Return private message key from the client entry. */
+
+SilcBool
+silc_client_private_message_key_is_set(SilcClient client,
+                                      SilcClientConnection conn,
+                                      SilcClientEntry client_entry)
+{
+  return client_entry->internal.send_key != NULL;
+}
+
 /* Sets away `message'.  The away message may be set when the client's
    mode is changed to SILC_UMODE_GONE and the client whishes to reply
    to anyone who sends private message.  The `message' will be sent
index 86ce6acbbe490a4c734f5bf1c26cb30f9cdca4e1..f7fd114af9e53d24f93099f03c5629d368df605d 100644 (file)
@@ -1836,10 +1836,14 @@ SILC_FSM_STATE(silc_client_command_cmode)
                                      NULL, NULL, 1,
                                      1, silc_buffer_datalen(chidp));
          silc_buffer_free(chidp);
+         silc_client_unref_channel(client, conn, channel);
 
          /* Notify application */
          COMMAND(SILC_STATUS_OK);
-         goto out;
+
+         /** Wait for command reply */
+         silc_fsm_next(fsm, silc_client_command_reply_wait);
+         return SILC_FSM_CONTINUE;
        }
 
        if (cmd->argc >= 4) {
index dd68d9ced409c98d23b3a67a913ea0b13d559237..9dda29d38e2c4839010a932b86c66e74c48566ee 100644 (file)
@@ -1290,7 +1290,7 @@ SILC_FSM_STATE(silc_client_command_reply_join)
   /* Get channel public key list */
   tmp = silc_argument_get_arg_type(args, 16, &len);
   if (tmp)
-    silc_client_channel_save_public_keys(channel, tmp, len);
+    silc_client_channel_save_public_keys(channel, tmp, len, FALSE);
 
   /* Set current channel */
   conn->current_channel = channel;
@@ -1420,7 +1420,6 @@ SILC_FSM_STATE(silc_client_command_reply_cmode)
   SilcChannelEntry channel;
   SilcUInt32 len;
   SilcPublicKey public_key = NULL;
-  SilcDList channel_pubkeys = NULL;
   SilcID id;
 
   /* Sanity checks */
@@ -1451,13 +1450,10 @@ SILC_FSM_STATE(silc_client_command_reply_cmode)
     ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
     goto out;
   }
+  SILC_GET32_MSB(mode, tmp);
 
   silc_rwlock_wrlock(channel->internal.lock);
 
-  /* Save the mode */
-  SILC_GET32_MSB(mode, tmp);
-  channel->mode = mode;
-
   /* Get user limit */
   tmp = silc_argument_get_arg_type(args, 6, &len);
   if (tmp && len == 4)
@@ -1468,15 +1464,18 @@ SILC_FSM_STATE(silc_client_command_reply_cmode)
   /* Get channel public key(s) */
   tmp = silc_argument_get_arg_type(args, 5, &len);
   if (tmp)
-    silc_client_channel_save_public_keys(channel, tmp, len);
+    silc_client_channel_save_public_keys(channel, tmp, len, FALSE);
+  else if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
+    silc_client_channel_save_public_keys(channel, NULL, 0, TRUE);
+
+  /* Save the mode */
+  channel->mode = mode;
 
   silc_rwlock_unlock(channel->internal.lock);
 
   /* Notify application */
   silc_client_command_callback(cmd, channel, mode, public_key,
-                              channel_pubkeys, channel->user_limit);
-
-  silc_argument_list_free(channel_pubkeys, SILC_ARGUMENT_PUBLIC_KEY);
+                              channel->channel_pubkeys, channel->user_limit);
 
  out:
   if (public_key)
index 622670b32d16943a94da56c27556cde989896e2a..f491e37e75bc5d0a8712f902d1a48546a404221f 100644 (file)
@@ -1611,6 +1611,26 @@ silc_client_list_private_message_keys(SilcClient client,
 void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
                                           SilcUInt32 key_count);
 
+/****f* silcclient/SilcClientAPI/silc_client_private_message_key_is_set
+ *
+ * SYNOPSIS
+ *
+ *    SilcBool
+ *    silc_client_private_message_key_is_set(SilcClient client,
+ *                                           SilcClientConnection conn,
+ *                                           SilcClientEntry client_entry);
+ *
+ * DESCRIPTION
+ *
+ *    Returns TRUE if the private message key has been set for the client
+ *    entry indicated by `client_entry'.
+ *
+ ***/
+SilcBool
+silc_client_private_message_key_is_set(SilcClient client,
+                                      SilcClientConnection conn,
+                                      SilcClientEntry client_entry);
+
 
 /* Channel private key management */