updates.
[silc.git] / apps / silcd / packet_receive.c
index f09bccb6dc4d7910c847e52d2d79001dc20ec545..a4bedaef9f402599f9fbf6ffcc273c4ad851d012 100644 (file)
@@ -180,7 +180,7 @@ void silc_server_notify(SilcServer server,
        client = 
          silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
                                 silc_id_dup(client_id, SILC_ID_CLIENT), 
-                                sock->user_data, NULL);
+                                sock->user_data, NULL, 0);
        if (!client) {
          SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
          silc_free(client_id);
@@ -367,10 +367,8 @@ void silc_server_notify(SilcServer server,
       goto out;
     }
 
-    if (channel->topic)
-      silc_free(channel->topic);
-    channel->topic = silc_calloc(tmp_len + 1, sizeof(*channel->topic));
-    memcpy(channel->topic, tmp, tmp_len);
+    silc_free(channel->topic);
+    channel->topic = strdup(tmp);
 
     /* Send the same notify to the channel */
     silc_server_packet_send_to_channel(server, sock, channel, packet->type, 
@@ -520,6 +518,13 @@ void silc_server_notify(SilcServer server,
       memset(hash, 0, sizeof(hash));
     }
 
+    /* Get the passphrase */
+    tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
+    if (tmp) {
+      silc_free(channel->passphrase);
+      channel->passphrase = strdup(tmp);
+    }
+
     break;
 
   case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
@@ -800,6 +805,15 @@ void silc_server_notify(SilcServer server,
                                     users_modes->len, FALSE);
        silc_buffer_free(users_modes);
       }
+
+      /* Re-announce channel's topic */
+      if (channel->topic) {
+       silc_server_send_notify_topic_set(server, sock,
+                                         server->server_type == SILC_ROUTER ?
+                                         TRUE : FALSE, channel, 
+                                         channel->id, SILC_ID_CHANNEL,
+                                         channel->topic);
+      }
     }
 
     silc_free(channel_id);
@@ -1206,9 +1220,22 @@ void silc_server_private_message(SilcServer server,
     if (!idp)
       return;
 
-    silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY,
-                                  SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0, 1,
-                                  2, idp, idp->len);
+    if (packet->src_id_type == SILC_ID_CLIENT) {
+      SilcClientID *client_id = silc_id_str2id(packet->src_id,
+                                              packet->src_id_len,
+                                              packet->src_id_type);
+      silc_server_send_dest_command_reply(server, sock, 
+                                         client_id, SILC_ID_CLIENT,
+                                         SILC_COMMAND_IDENTIFY,
+                                         SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 
+                                         0, 1, 2, idp->data, idp->len);
+      silc_free(client_id);
+    } else {
+      silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY,
+                                    SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 
+                                    0, 1, 2, idp->data, idp->len);
+    }
+
     silc_buffer_free(idp);
     return;
   }
@@ -1290,7 +1317,7 @@ void silc_server_command_reply(SilcServer server,
 
   if (packet->dst_id_type == SILC_ID_SERVER) {
     /* For now this must be for us */
-    if (memcmp(packet->dst_id, server->id_string, packet->dst_id_len)) {
+    if (memcmp(packet->dst_id, server->id_string, server->id_string_len)) {
       SILC_LOG_ERROR(("Cannot process command reply to unknown server"));
       return;
     }
@@ -1444,8 +1471,8 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   SilcClientID *client_id;
   SilcBuffer reply;
   SilcIDListData idata;
-  SilcIDCacheEntry id_cache = NULL;
   char *username = NULL, *realname = NULL, *id_string;
+  uint16 username_len;
   uint32 id_len;
   int ret;
   char *hostname, *nickname;
@@ -1470,14 +1497,13 @@ SilcClientEntry silc_server_new_client(SilcServer server,
 
   /* Parse incoming packet */
   ret = silc_buffer_unformat(buffer,
-                            SILC_STR_UI16_STRING_ALLOC(&username),
+                            SILC_STR_UI16_NSTRING_ALLOC(&username, 
+                                                        &username_len),
                             SILC_STR_UI16_STRING_ALLOC(&realname),
                             SILC_STR_END);
   if (ret == -1) {
-    if (username)
-      silc_free(username);
-    if (realname)
-      silc_free(realname);
+    silc_free(username);
+    silc_free(realname);
     silc_server_disconnect_remote(server, sock, "Server closed connection: "
                                   "Incomplete client information");
     return NULL;
@@ -1485,17 +1511,22 @@ SilcClientEntry silc_server_new_client(SilcServer server,
 
   if (!username) {
     silc_free(username);
-    if (realname)
-      silc_free(realname);
+    silc_free(realname);
     silc_server_disconnect_remote(server, sock, "Server closed connection: "
                                   "Incomplete client information");
     return NULL;
   }
 
-  if (strlen(username) > 128)
-    username[127] = '\0';
+  if (username_len > 128)
+    username[128] = '\0';
 
-  nickname = strdup(username);
+  /* Check for bad characters for nickname, and modify the nickname if
+     it includes those. */
+  if (silc_server_name_bad_chars(username, username_len)) {
+    nickname = silc_server_name_modify_bad(username, username_len);
+  } else {
+    nickname = strdup(username);
+  }
 
   /* Make sanity checks for the hostname of the client. If the hostname
      is provided in the `username' check that it is the same than the
@@ -1514,8 +1545,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
        strcmp(sock->hostname, hostname)) {
       silc_free(username);
       silc_free(hostname);
-      if (realname)
-       silc_free(realname);
+      silc_free(realname);
       silc_server_disconnect_remote(server, sock, 
                                    "Server closed connection: "
                                    "Incomplete client information");
@@ -1532,18 +1562,15 @@ SilcClientEntry silc_server_new_client(SilcServer server,
        phostname && strcmp(phostname, hostname)) {
       silc_free(username);
       silc_free(hostname);
-      if (phostname)
-       silc_free(phostname);
-      if (realname)
-       silc_free(realname);
+      silc_free(phostname);
+      silc_free(realname);
       silc_server_disconnect_remote(server, sock, 
                                    "Server closed connection: "
                                    "Incomplete client information");
       return NULL;
     }
     
-    if (phostname)
-      silc_free(phostname);
+    silc_free(phostname);
   } else {
     /* The hostname is not present, add it. */
     char *newusername;
@@ -1598,7 +1625,7 @@ SilcClientEntry silc_server_new_client(SilcServer server,
 
   /* Add the client again to the ID cache */
   silc_idcache_add(server->local_list->clients, client->nickname,
-                  client_id, client, FALSE);
+                  client_id, client, 0, NULL);
 
   /* Notify our router about new client on the SILC network */
   if (!server->standalone)
@@ -1766,7 +1793,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   /* Add again the entry to the ID cache. */
   silc_idcache_add(local ? server->local_list->servers : 
                   server->global_list->servers, server_name, server_id, 
-                  new_server, FALSE);
+                  new_server, 0, NULL);
 
   /* Distribute the information about new server in the SILC network
      to our router. If we are normal server we won't send anything
@@ -1912,7 +1939,7 @@ static void silc_server_new_id_real(SilcServer server,
         global list. Cell wide information however is kept in the local
         list. */
       entry = silc_idlist_add_client(id_list, NULL, NULL, NULL, 
-                                    id, router, NULL);
+                                    id, router, NULL, 0);
       if (!entry) {
        SILC_LOG_ERROR(("Could not add new client to the ID Cache"));
 
@@ -2151,7 +2178,7 @@ void silc_server_new_channel(SilcServer server,
                      sock->hostname));
     
       silc_idlist_add_channel(server->global_list, strdup(channel_name), 
-                             0, channel_id, sock->user_data, NULL, NULL);
+                             0, channel_id, sock->user_data, NULL, NULL, 0);
       server->stat.channels++;
     }
   } else {
@@ -2204,6 +2231,8 @@ void silc_server_new_channel(SilcServer server,
       channel->mode = silc_channel_get_mode(payload);
 
       /* Send the new channel key to the server */
+      id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
+      id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
       chk = silc_channel_key_payload_encode(id_len, id,
                                            strlen(channel->channel_key->
                                                   cipher->name),
@@ -2236,7 +2265,8 @@ void silc_server_new_channel(SilcServer server,
        silc_server_send_notify_cmode(server, sock, FALSE, channel,
                                      channel->mode, server->id,
                                      SILC_ID_SERVER,
-                                     channel->cipher, channel->hmac_name);
+                                     channel->cipher, channel->hmac_name,
+                                     channel->passphrase);
       }
 
       /* Create new key for the channel and send it to the server and
@@ -2249,8 +2279,8 @@ void silc_server_new_channel(SilcServer server,
        /* Send to the channel */
        silc_server_send_channel_key(server, sock, channel, FALSE);
        id = silc_id_id2str(channel->id, SILC_ID_CHANNEL);
-       id_len = SILC_ID_CHANNEL_LEN;
-       
+       id_len = silc_id_get_len(channel->id, SILC_ID_CHANNEL);
+
        /* Send to the server */
        chk = silc_channel_key_payload_encode(id_len, id,
                                              strlen(channel->channel_key->