If channel user list could not be resolved or was not even
[crypto.git] / lib / silcclient / command_reply.c
index 61e4d73a082dea7df0a86f0d6791a9576612b313..ee71a4264b0c6fa3d7f107fd98fc2a72661bfa02 100644 (file)
@@ -822,7 +822,7 @@ SILC_FSM_STATE(silc_client_command_reply_topic)
   SilcClient client = conn->client;
   SilcCommandPayload payload = state_context;
   SilcArgumentPayload args = silc_command_get_args(payload);
-  SilcChannelEntry channel;
+  SilcChannelEntry channel = NULL;
   char *topic;
   SilcUInt32 len;
   SilcID id;
@@ -859,6 +859,7 @@ SILC_FSM_STATE(silc_client_command_reply_topic)
   silc_client_command_callback(cmd, channel, channel->topic);
 
  out:
+  silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_command_reply_processed);
   return SILC_FSM_CONTINUE;
 }
@@ -874,7 +875,7 @@ SILC_FSM_STATE(silc_client_command_reply_invite)
   SilcClient client = conn->client;
   SilcCommandPayload payload = state_context;
   SilcArgumentPayload args = silc_command_get_args(payload);
-  SilcChannelEntry channel;
+  SilcChannelEntry channel = NULL;
   unsigned char *tmp;
   SilcUInt32 len;
   SilcArgumentPayload invite_args = NULL;
@@ -909,6 +910,7 @@ SILC_FSM_STATE(silc_client_command_reply_invite)
     silc_argument_payload_free(invite_args);
 
  out:
+  silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_command_reply_processed);
   return SILC_FSM_CONTINUE;
 }
@@ -1109,6 +1111,29 @@ silc_client_command_reply_join_resolved(SilcClient client,
 {
   SilcClientCommandContext cmd = context;
   SilcChannelEntry channel = cmd->context;
+  SilcCommandPayload payload = silc_fsm_get_state_context(&cmd->thread);
+  SilcArgumentPayload args = silc_command_get_args(payload);
+  SilcUInt32 list_count;
+  unsigned char *tmp;
+  char msg[512];
+
+  if (!clients) {
+    silc_snprintf(msg, sizeof(msg), "Error resolving channel %s user list",
+                 channel->channel_name);
+    SAY(client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR, msg);
+  } else {
+    tmp = silc_argument_get_arg_type(args, 12, NULL);
+    if (tmp) {
+      SILC_GET32_MSB(list_count, tmp);
+      if (list_count - silc_dlist_count(clients) > 5) {
+       silc_snprintf(msg, sizeof(msg),
+                     "Channel %s user list was not fully resolved. "
+                     "The channel may not be fully synced.",
+                     channel->channel_name);
+       SAY(client, conn, SILC_CLIENT_MESSAGE_WARNING, msg);
+      }
+    }
+  }
 
   channel->internal.resolve_cmd_ident = 0;
   silc_client_unref_channel(client, conn, channel);
@@ -1170,7 +1195,7 @@ SILC_FSM_STATE(silc_client_command_reply_join)
 
   /* Get the list count */
   tmp = silc_argument_get_arg_type(args, 12, &len);
-  if (!tmp) {
+  if (!tmp || len != 4) {
     ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
     goto out;
   }
@@ -1208,7 +1233,6 @@ SILC_FSM_STATE(silc_client_command_reply_join)
   /* Add clients we received in the reply to the channel */
   for (i = 0; i < list_count; i++) {
     SilcUInt16 idp_len;
-    SilcUInt32 mode;
     SilcID id;
     SilcClientEntry client_entry;
 
@@ -1420,7 +1444,7 @@ SILC_FSM_STATE(silc_client_command_reply_cmode)
   SilcArgumentPayload args = silc_command_get_args(payload);
   unsigned char *tmp;
   SilcUInt32 mode;
-  SilcChannelEntry channel;
+  SilcChannelEntry channel = NULL;
   SilcUInt32 len;
   SilcPublicKey public_key = NULL;
   SilcID id;
@@ -1480,7 +1504,22 @@ SILC_FSM_STATE(silc_client_command_reply_cmode)
   silc_client_command_callback(cmd, channel, mode, public_key,
                               channel->channel_pubkeys, channel->user_limit);
 
+  silc_rwlock_wrlock(channel->internal.lock);
+
+  /* If founder key changed, update it */
+  if (public_key &&
+      (!channel->founder_key ||
+       !silc_pkcs_public_key_compare(public_key, channel->founder_key))) {
+    if (channel->founder_key)
+      silc_pkcs_public_key_free(channel->founder_key);
+    channel->founder_key = public_key;
+    public_key = NULL;
+  }
+
+  silc_rwlock_unlock(channel->internal.lock);
+
  out:
+  silc_client_unref_channel(client, conn, channel);
   if (public_key)
     silc_pkcs_public_key_free(public_key);
   silc_fsm_next(fsm, silc_client_command_reply_processed);
@@ -1499,7 +1538,7 @@ SILC_FSM_STATE(silc_client_command_reply_cumode)
   SilcCommandPayload payload = state_context;
   SilcArgumentPayload args = silc_command_get_args(payload);
   SilcClientEntry client_entry;
-  SilcChannelEntry channel;
+  SilcChannelEntry channel = NULL;
   SilcChannelUser chu;
   unsigned char *modev;
   SilcUInt32 len, mode;
@@ -1556,6 +1595,7 @@ SILC_FSM_STATE(silc_client_command_reply_cumode)
   silc_client_unref_client(client, conn, client_entry);
 
  out:
+  silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_command_reply_processed);
   return SILC_FSM_CONTINUE;
 }
@@ -1570,7 +1610,7 @@ SILC_FSM_STATE(silc_client_command_reply_kick)
   SilcCommandPayload payload = state_context;
   SilcArgumentPayload args = silc_command_get_args(payload);
   SilcClientEntry client_entry;
-  SilcChannelEntry channel;
+  SilcChannelEntry channel = NULL;
   SilcID id;
 
   /* Sanity checks */
@@ -1609,6 +1649,7 @@ SILC_FSM_STATE(silc_client_command_reply_kick)
   silc_client_unref_client(client, conn, client_entry);
 
  out:
+  silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_command_reply_processed);
   return SILC_FSM_CONTINUE;
 }
@@ -1716,7 +1757,7 @@ SILC_FSM_STATE(silc_client_command_reply_ban)
   SilcClient client = conn->client;
   SilcCommandPayload payload = state_context;
   SilcArgumentPayload args = silc_command_get_args(payload);
-  SilcChannelEntry channel;
+  SilcChannelEntry channel = NULL;
   unsigned char *tmp;
   SilcUInt32 len;
   SilcArgumentPayload invite_args = NULL;
@@ -1751,6 +1792,7 @@ SILC_FSM_STATE(silc_client_command_reply_ban)
     silc_argument_payload_free(invite_args);
 
  out:
+  silc_client_unref_channel(client, conn, channel);
   silc_fsm_next(fsm, silc_client_command_reply_processed);
   return SILC_FSM_CONTINUE;
 }
@@ -1851,8 +1893,8 @@ SILC_FSM_STATE(silc_client_command_reply_users)
   SilcCommandPayload payload = state_context;
   SilcArgumentPayload args = silc_command_get_args(payload);
   unsigned char *tmp;
-  SilcUInt32 tmp_len, list_count;
-  SilcUInt16 idp_len, mode;
+  SilcUInt32 tmp_len, list_count, mode;
+  SilcUInt16 idp_len;
   SilcHashTableList htl;
   SilcBufferStruct client_id_list, client_mode_list;
   SilcChannelEntry channel = NULL;
@@ -1997,6 +2039,8 @@ SILC_FSM_STATE(silc_client_command_reply_getkey)
     goto out;
   }
   if (!silc_public_key_payload_decode(tmp, len, &public_key)) {
+    SAY(client, conn, SILC_CLIENT_MESSAGE_COMMAND_ERROR,
+        "Cannot decode public key: malformed/unsupported public key");
     ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
     goto out;
   }