updates.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 12 Mar 2001 17:22:22 +0000 (17:22 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 12 Mar 2001 17:22:22 +0000 (17:22 +0000)
CHANGES
apps/silc/client_ops.c
apps/silcd/command.c
apps/silcd/packet_receive.c
lib/silcclient/client_channel.c
lib/silcclient/command_reply.c

diff --git a/CHANGES b/CHANGES
index 5e0f9021baf01d9546736c09eaec49002f2196ac..7be82e78b99b88d774d09398276c569d5cceed57 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,24 @@
+Mon Mar 12 18:43:38 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Server now enforces the maximum length for the nickname and
+         the channel as protocol specification dictates.  128 bytes for
+         nickname and 256 bytes for channel name.
+
+       * Moved the WHOIS printing to the application.  The client libary
+         does not print out the WHOIS information anymore, the application
+         must do it.  Renamed silc_client_command_reply_whois_print to
+         the silc_client_command_reply_whois_save.
+
+         The client's idle time is also sent to the application now, and
+         the idle is shown on screen.
+
+       * Added silc_client_command_reply_identify_save to save the
+         received IDENTIFY entries.
+
+       * Do not check for channel private keys in message sending and
+         reception if the channel does not have the PRIVKEY mode set.
+         Affected file lib/silclient/client_channel.c.
+
 Sun Mar 11 20:25:06 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Fixed a minor bug if WHOIS and IDENTIFY command parsing that
index c9a5743feb4af904c5bea1652819cf02ab8714a1..8d9566fe14a84ecf91d455799e7b26e2bb42ab47 100644 (file)
@@ -277,6 +277,7 @@ void silc_command(SilcClient client, SilcClientConnection conn,
 
   switch(command)
     {
+       
     case SILC_COMMAND_QUIT:
       app->screen->bottom_line->channel = NULL;
       silc_screen_print_bottom_line(app->screen, 0);
@@ -314,6 +315,9 @@ void silc_client_show_users(SilcClient client,
   silc_list_start(channel->clients);
   while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
     char *m, *n = chu->client->nickname;
+    if (!n)
+      continue;
+
     len2 = strlen(n);
     len1 += len2;
     
@@ -372,6 +376,45 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
 
   switch(command)
     {
+    case SILC_COMMAND_WHOIS:
+      {
+       char buf[1024], *nickname, *username, *realname;
+       int len;
+       unsigned int idle;
+
+       (void)va_arg(vp, SilcClientEntry);
+       nickname = va_arg(vp, char *);
+       username = va_arg(vp, char *);
+       realname = va_arg(vp, char *);
+       (void)va_arg(vp, void *);
+       idle = va_arg(vp, unsigned int);
+
+       memset(buf, 0, sizeof(buf));
+
+       if (nickname) {
+         len = strlen(nickname);
+         strncat(buf, nickname, len);
+         strncat(buf, " is ", 4);
+       }
+       
+       if (username) {
+         strncat(buf, username, strlen(nickname));
+       }
+       
+       if (realname) {
+         strncat(buf, " (", 2);
+         strncat(buf, realname, strlen(realname));
+         strncat(buf, ")", 1);
+       }
+
+       client->ops->say(client, conn, "%s", buf);
+       if (idle && nickname)
+         client->ops->say(client, conn, "%s has been idle %d %s",
+                          nickname,
+                          idle > 60 ? (idle / 60) : idle,
+                          idle > 60 ? "minutes" : "seconds");
+      }
+      break;
 
     case SILC_COMMAND_JOIN:
       {
index 0b06c10b87f5a0a6d95ebd234b58f84a3ce26172..a10f877b10bd850447b718e7a08f3139c5da2bca 100644 (file)
@@ -1281,6 +1281,9 @@ SILC_SERVER_CMD_FUNC(nick)
     goto out;
   }
 
+  if (strlen(nick) > 128)
+    nick[127] = '\0';
+
   /* Create new Client ID */
   silc_id_create_client_id(cmd->server->id, cmd->server->rng, 
                           cmd->server->md5hash, nick,
@@ -1976,6 +1979,9 @@ SILC_SERVER_CMD_FUNC(join)
   }
   channel_name = tmp;
 
+  if (strlen(channel_name) > 256)
+    channel_name[255] = '\0';
+
   if (silc_server_command_bad_chars(channel_name) == TRUE) {
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
                                          SILC_STATUS_ERR_BAD_CHANNEL);
index 7c8df0e88cc85a411d31c0110e1aa932b0757dea..55ed8819d9508b6487dc988198f3d7abb6e111f3 100644 (file)
@@ -1047,6 +1047,9 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   silc_id_create_client_id(server->id, server->rng, server->md5hash,
                           username, &client_id);
 
+  if (strlen(username) > 128)
+    username[127] = '\0';
+
   /* Update client entry */
   idata->registered = TRUE;
   client->nickname = strdup(username);
index 81c9ca9a5b2f33030fb97f2dcba444f1eafb4291..46190226fecaf19b85cfc65f843ff38211afe9dd 100644 (file)
@@ -59,24 +59,30 @@ void silc_client_send_channel_message(SilcClient client,
   }
 
   /* Take the key to be used */
-  if (key) {
-    /* Use key application specified */
-    cipher = key->cipher;
-    hmac = key->hmac;
-  } else if (channel->curr_key) {
-    /* Use current private key */
-    cipher = channel->curr_key->cipher;
-    hmac = channel->curr_key->hmac;
-  } else if (!channel->curr_key && channel->private_keys) {
-    /* Use just some private key since we don't know what to use 
-       and private keys are set. */
-    silc_dlist_start(channel->private_keys);
-    key = silc_dlist_get(channel->private_keys);
-    cipher = key->cipher;
-    hmac = key->hmac;
-
-    /* Use this key as current private key */
-    channel->curr_key = key;
+  if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
+    if (key) {
+      /* Use key application specified */
+      cipher = key->cipher;
+      hmac = key->hmac;
+    } else if (channel->curr_key) {
+      /* Use current private key */
+      cipher = channel->curr_key->cipher;
+      hmac = channel->curr_key->hmac;
+    } else if (!channel->curr_key && channel->private_keys) {
+      /* Use just some private key since we don't know what to use 
+        and private keys are set. */
+      silc_dlist_start(channel->private_keys);
+      key = silc_dlist_get(channel->private_keys);
+      cipher = key->cipher;
+      hmac = key->hmac;
+      
+      /* Use this key as current private key */
+      channel->curr_key = key;
+    } else {
+      /* Use normal channel key generated by the server */
+      cipher = channel->channel_key;
+      hmac = channel->hmac;
+    }
   } else {
     /* Use normal channel key generated by the server */
     cipher = channel->channel_key;
@@ -192,13 +198,13 @@ void silc_client_channel_message(SilcClient client,
   /* If there is no channel private key then just decrypt the message 
      with the channel key. If private keys are set then just go through
      all private keys and check what decrypts correctly. */
-  if (!channel->private_keys) {
+  if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
     /* Parse the channel message payload. This also decrypts the payload */
     payload = silc_channel_payload_parse(buffer, channel->channel_key,
                                         channel->hmac);
     if (!payload)
       goto out;
-  } else {
+  } else if (channel->private_keys) {
     SilcChannelPrivateKey entry;
 
     silc_dlist_start(channel->private_keys);
@@ -211,6 +217,8 @@ void silc_client_channel_message(SilcClient client,
     }
     if (entry == SILC_LIST_END)
       goto out;
+  } else {
+    goto out;
   }
 
   message = silc_channel_get_data(payload, NULL);
index b58d690be8d5b662ae808cf830cf23dc0b7036ff..014ba8ce39a141ef9391cfd99f911ec368d056bd 100644 (file)
@@ -207,20 +207,18 @@ void silc_client_command_reply_free(SilcClientCommandReplyContext cmd)
 }
 
 static void 
-silc_client_command_reply_whois_print(SilcClientCommandReplyContext cmd,
-                                     SilcCommandStatus status)
+silc_client_command_reply_whois_save(SilcClientCommandReplyContext cmd,
+                                    SilcCommandStatus status)
 {
-  char buf[256];
-  int argc, len;
-  unsigned char *id_data;
-  char *nickname = NULL, *username = NULL;
-  char *realname = NULL;
+  SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
   SilcClientID *client_id;
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry client_entry = NULL;
-  SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
-  
-  memset(buf, 0, sizeof(buf));
+  int argc, len;
+  unsigned char *id_data, *tmp;
+  char *nickname = NULL, *username = NULL;
+  char *realname = NULL;
+  unsigned int idle = 0;
   
   argc = silc_argument_get_arg_num(cmd->args);
 
@@ -237,26 +235,22 @@ silc_client_command_reply_whois_print(SilcClientCommandReplyContext cmd,
   }
   
   nickname = silc_argument_get_arg_type(cmd->args, 3, &len);
-  if (nickname) {
-    strncat(buf, nickname, len);
-    strncat(buf, " is ", 4);
-  }
-  
   username = silc_argument_get_arg_type(cmd->args, 4, &len);
-  if (username) {
-    strncat(buf, username, len);
-  }
-  
   realname = silc_argument_get_arg_type(cmd->args, 5, &len);
-  if (realname) {
-    strncat(buf, " (", 2);
-    strncat(buf, realname, len);
-    strncat(buf, ")", 1);
+  if (!nickname || !username || !realname) {
+    COMMAND_REPLY_ERROR;
+    return;
   }
-  
+
+  tmp = silc_argument_get_arg_type(cmd->args, 7, &len);
+  if (tmp)
+    SILC_GET32_MSB(idle, tmp);
+
   /* Check if we have this client cached already. */
   if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
                                   SILC_ID_CLIENT, &id_cache)) {
+    SILC_LOG_DEBUG(("Adding new client entry"));
+
     client_entry = silc_calloc(1, sizeof(*client_entry));
     client_entry->id = client_id;
     silc_parse_nickname(nickname, &client_entry->nickname, 
@@ -279,6 +273,8 @@ silc_client_command_reply_whois_print(SilcClientCommandReplyContext cmd,
     if (client_entry->realname)
       silc_free(client_entry->realname);
 
+    SILC_LOG_DEBUG(("Updating client entry"));
+
     silc_parse_nickname(nickname, &client_entry->nickname, 
                        &client_entry->server, &client_entry->num);
     client_entry->username = strdup(username);
@@ -291,12 +287,10 @@ silc_client_command_reply_whois_print(SilcClientCommandReplyContext cmd,
     silc_free(client_id);
   }
 
-  if (!cmd->callback)
-    cmd->client->ops->say(cmd->client, conn, "%s", buf);
-
   /* Notify application */
-  COMMAND_REPLY((ARGS, client_entry, nickname, username, realname, 
-                NULL, NULL));
+  if (!cmd->callback)
+    COMMAND_REPLY((ARGS, client_entry, nickname, username, realname, 
+                  NULL, idle));
 }
 
 /* Received reply for WHOIS command. This maybe called several times
@@ -337,21 +331,20 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois)
   }
 
   /* Display one whois reply */
-  if (status == SILC_STATUS_OK) {
-    silc_client_command_reply_whois_print(cmd, status);
-  }
+  if (status == SILC_STATUS_OK)
+    silc_client_command_reply_whois_save(cmd, status);
 
-  /* XXX list should not be displayed untill all items has been received. */
-  if (status == SILC_STATUS_LIST_START) {
-    silc_client_command_reply_whois_print(cmd, status);
-  }
-
-  if (status == SILC_STATUS_LIST_ITEM) {
-    silc_client_command_reply_whois_print(cmd, status);
-  }
+  /* List */
+  if (status == SILC_STATUS_LIST_START ||
+      status == SILC_STATUS_LIST_ITEM ||
+      status == SILC_STATUS_LIST_END)
+    silc_client_command_reply_whois_save(cmd, status);
 
-  if (status == SILC_STATUS_LIST_END) {
-    silc_client_command_reply_whois_print(cmd, status);
+  /* Pending callbacks are not executed if this was an list entry */
+  if (status != SILC_STATUS_OK &&
+      status != SILC_STATUS_LIST_END) {
+    silc_client_command_reply_free(cmd);
+    return;
   }
 
   /* Execute any pending command callbacks */
@@ -369,6 +362,77 @@ SILC_CLIENT_CMD_REPLY_FUNC(whowas)
 
 }
 
+static void 
+silc_client_command_reply_identify_save(SilcClientCommandReplyContext cmd,
+                                       SilcCommandStatus status)
+{
+  SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
+  SilcClientID *client_id;
+  SilcIDCacheEntry id_cache = NULL;
+  SilcClientEntry client_entry = NULL;
+  int argc, len;
+  unsigned char *id_data;
+  char *nickname = NULL, *username = NULL;
+  
+  argc = silc_argument_get_arg_num(cmd->args);
+
+  id_data = silc_argument_get_arg_type(cmd->args, 2, &len);
+  if (!id_data) {
+    COMMAND_REPLY_ERROR;
+    return;
+  }
+  
+  client_id = silc_id_payload_parse_id(id_data, len);
+  if (!client_id) {
+    COMMAND_REPLY_ERROR;
+    return;
+  }
+  
+  nickname = silc_argument_get_arg_type(cmd->args, 3, &len);
+  username = silc_argument_get_arg_type(cmd->args, 4, &len);
+
+  /* Check if we have this client cached already. */
+  if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
+                                  SILC_ID_CLIENT, &id_cache)) {
+    SILC_LOG_DEBUG(("Adding new client entry"));
+
+    client_entry = silc_calloc(1, sizeof(*client_entry));
+    client_entry->id = client_id;
+    silc_parse_nickname(nickname, &client_entry->nickname, 
+                       &client_entry->server, &client_entry->num);
+    if (username)
+      client_entry->username = strdup(username);
+    
+    /* Add client to cache */
+    silc_idcache_add(conn->client_cache, client_entry->nickname,
+                    SILC_ID_CLIENT, client_id, (void *)client_entry, TRUE);
+  } else {
+    client_entry = (SilcClientEntry)id_cache->context;
+    if (client_entry->nickname)
+      silc_free(client_entry->nickname);
+    if (client_entry->server)
+      silc_free(client_entry->server);
+    if (username && client_entry->username)
+      silc_free(client_entry->username);
+    
+    SILC_LOG_DEBUG(("Updating client entry"));
+
+    silc_parse_nickname(nickname, &client_entry->nickname, 
+                       &client_entry->server, &client_entry->num);
+    
+    if (username)
+      client_entry->username = strdup(username);
+    
+    id_cache->data = client_entry->nickname;
+    silc_idcache_sort_by_data(conn->client_cache);
+    
+    silc_free(client_id);
+  }
+
+  /* Notify application */
+  COMMAND_REPLY((ARGS, client_entry, nickname, username));
+}
+
 /* Received reply for IDENTIFY command. This maybe called several times
    for one IDENTIFY command as server may reply with list of results. 
    This is totally silent and does not print anything on screen. */
@@ -377,8 +441,6 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify)
 {
   SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context;
   SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data;
-  SilcClientEntry client_entry;
-  SilcIDCacheEntry id_cache = NULL;
   SilcCommandStatus status;
   unsigned char *tmp;
 
@@ -409,61 +471,17 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify)
     }
   }
 
-  /* Display one whois reply */
-  if (status == SILC_STATUS_OK ||
-      status == SILC_STATUS_LIST_START ||
-      status == SILC_STATUS_LIST_ITEM ||
-      status == SILC_STATUS_LIST_END) {
-    unsigned int len;
-    unsigned char *id_data;
-    char *nickname;
-    char *username;
-    SilcClientID *client_id;
-
-    id_data = silc_argument_get_arg_type(cmd->args, 2, &len);
-    if (!id_data)
-      goto out;
-    client_id = silc_id_payload_parse_id(id_data, len);
-    if (!client_id)
-      goto out;
-
-    nickname = silc_argument_get_arg_type(cmd->args, 3, NULL);
-    username = silc_argument_get_arg_type(cmd->args, 4, NULL);
+  /* Save one IDENTIFY entry */
+  if (status == SILC_STATUS_OK)
+    silc_client_command_reply_identify_save(cmd, status);
 
-    if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
-                                    SILC_ID_CLIENT, &id_cache)) {
-      client_entry = silc_calloc(1, sizeof(*client_entry));
-      client_entry->id = client_id;
-      silc_parse_nickname(nickname, &client_entry->nickname, 
-                         &client_entry->server, &client_entry->num);
-      if (username)
-       client_entry->username = strdup(username);
-    
-      /* Add client to cache */
-      silc_idcache_add(conn->client_cache, client_entry->nickname,
-                      SILC_ID_CLIENT, client_id, (void *)client_entry, TRUE);
-    } else {
-      client_entry = (SilcClientEntry)id_cache->context;
-      if (client_entry->nickname)
-       silc_free(client_entry->nickname);
-      if (client_entry->server)
-       silc_free(client_entry->server);
-      if (username && client_entry->username)
-       silc_free(client_entry->username);
-
-      silc_parse_nickname(nickname, &client_entry->nickname, 
-                         &client_entry->server, &client_entry->num);
-
-      if (username)
-       client_entry->username = strdup(username);
-
-      id_cache->data = client_entry->nickname;
-      silc_idcache_sort_by_data(conn->client_cache);
-    
-      silc_free(client_id);
-    }
-  }
+  /* List */
+  if (status == SILC_STATUS_LIST_START ||
+      status == SILC_STATUS_LIST_ITEM ||
+      status == SILC_STATUS_LIST_END)
+    silc_client_command_reply_identify_save(cmd, status);
 
+  /* Pending callbacks are not executed if this was an list entry */
   if (status != SILC_STATUS_OK &&
       status != SILC_STATUS_LIST_END) {
     silc_client_command_reply_free(cmd);