Integer type name change.
[silc.git] / apps / silcd / packet_receive.c
index 926163899005ea30c40485d2b411a3e4c16db780..07d1e1c86fad97b154863f60dee0baf6003a9169 100644 (file)
@@ -46,9 +46,10 @@ void silc_server_notify(SilcServer server,
   SilcChannelClientEntry chl;
   SilcIDCacheEntry cache;
   SilcHashTableList htl;
-  uint32 mode;
+  SilcUInt32 mode;
   unsigned char *tmp;
-  uint32 tmp_len;
+  SilcUInt32 tmp_len;
+  bool local;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -211,6 +212,8 @@ void silc_server_notify(SilcServer server,
       /* The channel is global now */
       channel->global_users = TRUE;
 
+    SILC_LOG_DEBUG(("Joining to channel %s", channel->channel_name));
+
     /* JOIN the global client to the channel (local clients (if router 
        created the channel) is joined in the pending JOIN command). */
     chl = silc_calloc(1, sizeof(*chl));
@@ -225,6 +228,7 @@ void silc_server_notify(SilcServer server,
     silc_hash_table_add(channel->user_list, client, chl);
     silc_hash_table_add(client->channels, channel, chl);
     silc_free(client_id);
+    channel->user_count++;
 
     break;
 
@@ -324,14 +328,18 @@ void silc_server_notify(SilcServer server,
     if (tmp_len > 128)
       tmp = NULL;
 
+    /* Update statistics */
+    server->stat.clients--;
+    if (server->server_type == SILC_ROUTER)
+      server->stat.cell_clients--;
+    SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
+    SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+
     /* Remove the client from all channels. */
     silc_server_remove_from_channels(server, NULL, client, TRUE, tmp, FALSE);
 
     client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
     cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
-    server->stat.clients--;
-    if (server->server_type == SILC_ROUTER)
-      server->stat.cell_clients--;
     break;
 
   case SILC_NOTIFY_TYPE_TOPIC_SET:
@@ -623,6 +631,7 @@ void silc_server_notify(SilcServer server,
          if (chl2) {
            chl2->mode = mode;
            silc_free(channel_id);
+           silc_hash_table_list_reset(&htl);
            goto out;
          }
        }
@@ -633,6 +642,8 @@ void silc_server_notify(SilcServer server,
            break;
          }
 
+         SILC_LOG_DEBUG(("Changing the channel user mode"));
+
          /* Change the mode */
          chl->mode = mode;
          if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
@@ -641,6 +652,7 @@ void silc_server_notify(SilcServer server,
          chl2 = chl;
        }
       }
+      silc_hash_table_list_reset(&htl);
       
       /* Send the same notify to the channel */
       if (!notify_sent)
@@ -745,10 +757,10 @@ void silc_server_notify(SilcServer server,
       goto out;
 
     /* Get the channel entry */
-    channel = silc_idlist_find_channel_by_id(server->global_list, 
+    channel = silc_idlist_find_channel_by_id(server->local_list, 
                                             channel_id, NULL);
     if (!channel) {
-      channel = silc_idlist_find_channel_by_id(server->local_list, 
+      channel = silc_idlist_find_channel_by_id(server->global_list, 
                                               channel_id, NULL);
       if (!channel) {
        silc_free(channel_id);
@@ -775,9 +787,9 @@ void silc_server_notify(SilcServer server,
                    silc_id_render(channel_id2, SILC_ID_CHANNEL)));
 
     /* Replace the Channel ID */
-    if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
+    if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
                                        channel_id2))
-      if (!silc_idlist_replace_channel_id(server->local_list, channel_id,
+      if (!silc_idlist_replace_channel_id(server->global_list, channel_id,
                                          channel_id2)) {
        silc_free(channel_id2);
        channel_id2 = NULL;
@@ -785,7 +797,14 @@ void silc_server_notify(SilcServer server,
 
     if (channel_id2) {
       SilcBuffer users = NULL, users_modes = NULL;
-      
+
+      /* Re-announce this channel which ID was changed. */
+      silc_server_send_new_channel(server, sock, FALSE, channel->channel_name,
+                                  channel->id, 
+                                  silc_id_get_len(channel->id, 
+                                                  SILC_ID_CHANNEL),
+                                  channel->mode);
+
       /* Re-announce our clients on the channel as the ID has changed now */
       silc_server_announce_get_channel_users(server, channel, &users,
                                             &users_modes);
@@ -838,9 +857,11 @@ void silc_server_notify(SilcServer server,
     /* Get server entry */
     server_entry = silc_idlist_find_server_by_id(server->global_list, 
                                                 server_id, TRUE, NULL);
+    local = TRUE;
     if (!server_entry) {
       server_entry = silc_idlist_find_server_by_id(server->local_list, 
                                                   server_id, TRUE, NULL);
+      local = TRUE;
       if (!server_entry) {
        /* If we are normal server then we might not have the server. Check
           whether router was kind enough to send the list of all clients
@@ -862,9 +883,11 @@ void silc_server_notify(SilcServer server,
            /* Get client entry */
            client = silc_idlist_find_client_by_id(server->global_list, 
                                                   client_id, TRUE, &cache);
+           local = TRUE;
            if (!client) {
              client = silc_idlist_find_client_by_id(server->local_list, 
                                                     client_id, TRUE, &cache);
+             local = FALSE;
              if (!client) {
                silc_free(client_id);
                continue;
@@ -872,15 +895,20 @@ void silc_server_notify(SilcServer server,
            }
            silc_free(client_id);
 
-           /* Remove the client from all channels. */
-           silc_server_remove_from_channels(server, NULL, client, 
-                                            TRUE, NULL, FALSE);
-           
-           client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
-           cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+           /* Update statistics */
            server->stat.clients--;
            if (server->server_type == SILC_ROUTER)
              server->stat.cell_clients--;
+           SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
+           SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+
+           /* Remove the client from all channels. */
+           silc_server_remove_from_channels(server, NULL, client, 
+                                            TRUE, NULL, FALSE);
+
+           /* Remove the client */
+           silc_idlist_del_client(local ? server->local_list :
+                                  server->global_list, client);
          }
        }
 
@@ -895,8 +923,8 @@ void silc_server_notify(SilcServer server,
     silc_server_remove_clients_by_server(server, server_entry, TRUE);
 
     /* Remove the server entry */
-    if (!silc_idlist_del_server(server->global_list, server_entry))
-      silc_idlist_del_server(server->local_list, server_entry);
+    silc_idlist_del_server(local ? server->local_list :
+                          server->global_list, server_entry);
 
     /* XXX update statistics */
 
@@ -965,7 +993,7 @@ void silc_server_notify(SilcServer server,
        * Distribute the notify to local clients on channels
        */
       unsigned char *id;
-      uint32 id_len;
+      SilcUInt32 id_len;
     
       SILC_LOG_DEBUG(("KILLED notify"));
       
@@ -1025,7 +1053,7 @@ void silc_server_notify(SilcServer server,
      */
 
     SILC_LOG_DEBUG(("UMODE_CHANGE notify"));
-      
+
     /* Get client ID */
     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
     if (!tmp)
@@ -1051,9 +1079,33 @@ void silc_server_notify(SilcServer server,
     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
     if (!tmp)
       goto out;
+    SILC_GET32_MSB(mode, tmp);
+
+#define SILC_UMODE_STATS_UPDATE(oper, mod)     \
+do {                                           \
+    if (client->mode & (mod)) {                        \
+      if (!(mode & (mod))) {                   \
+       if (client->connection)                 \
+         server->stat.my_ ## oper ## _ops--;   \
+        if (server->server_type == SILC_ROUTER)        \
+         server->stat. oper ## _ops--;         \
+      }                                                \
+    } else {                                   \
+      if (mode & (mod)) {                      \
+       if (client->connection)                 \
+         server->stat.my_ ## oper ## _ops++;   \
+        if (server->server_type == SILC_ROUTER)        \
+         server->stat. oper ## _ops++;         \
+      }                                                \
+    }                                          \
+} while(0)
+
+    /* Update statistics */
+    SILC_UMODE_STATS_UPDATE(server, SILC_UMODE_SERVER_OPERATOR);
+    SILC_UMODE_STATS_UPDATE(router, SILC_UMODE_ROUTER_OPERATOR);
 
     /* Save the mode */
-    SILC_GET32_MSB(client->mode, tmp);
+    client->mode = mode;
 
     break;
 
@@ -1105,7 +1157,7 @@ void silc_server_notify(SilcServer server,
     if (tmp && channel->ban_list) {
       char *start, *end, *n;
       
-      if (!strcmp(channel->ban_list, tmp)) {
+      if (!strncmp(channel->ban_list, tmp, strlen(channel->ban_list) - 1)) {
        silc_free(channel->ban_list);
        channel->ban_list = NULL;
       } else {
@@ -1121,7 +1173,6 @@ void silc_server_notify(SilcServer server,
        }
       }
     }
-
     break;
 
     /* Ignore rest of the notify types for now */
@@ -1142,7 +1193,7 @@ void silc_server_notify_list(SilcServer server,
 {
   SilcPacketContext *new;
   SilcBuffer buffer;
-  uint16 len;
+  SilcUInt16 len;
 
   SILC_LOG_DEBUG(("Processing Notify List"));
 
@@ -1317,7 +1368,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;
     }
@@ -1472,7 +1523,8 @@ SilcClientEntry silc_server_new_client(SilcServer server,
   SilcBuffer reply;
   SilcIDListData idata;
   char *username = NULL, *realname = NULL, *id_string;
-  uint32 id_len;
+  SilcUInt16 username_len;
+  SilcUInt32 id_len;
   int ret;
   char *hostname, *nickname;
   int nickfail = 0;
@@ -1496,14 +1548,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;
@@ -1511,17 +1562,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
@@ -1533,15 +1589,13 @@ SilcClientEntry silc_server_new_client(SilcServer server,
     int tlen = strcspn(username, "@");
     char *phostname = NULL;
 
-    hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
-    memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
+    hostname = silc_memdup(username + tlen + 1, strlen(username) - tlen - 1);
 
     if (strcmp(sock->hostname, sock->ip) && 
        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");
@@ -1558,18 +1612,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;
@@ -1672,10 +1723,14 @@ SilcClientEntry silc_server_new_client(SilcServer server,
                             server->stat.my_servers,
                             server->stat.my_routers));
     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
-                           ("%d server operators and %d router operators "
-                            "online",
-                            server->stat.my_server_ops,
-                            server->stat.my_router_ops));
+                           ("There are %d server operators and %d router "
+                            "operators online",
+                            server->stat.server_ops,
+                            server->stat.router_ops));
+    SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+                           ("I have %d operators online",
+                            server->stat.my_router_ops +
+                            server->stat.my_server_ops));
   } else {
     SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
                            ("I have %d clients and %d channels formed",
@@ -1717,7 +1772,7 @@ SilcServerEntry silc_server_new_server(SilcServer server,
   SilcServerID *server_id;
   SilcIDListData idata;
   unsigned char *server_name, *id_string;
-  uint16 id_len, name_len;
+  SilcUInt16 id_len, name_len;
   int ret;
   bool local = TRUE;
 
@@ -1905,12 +1960,13 @@ static void silc_server_new_id_real(SilcServer server,
       router = silc_idlist_find_server_by_id(server->local_list,
                                             sender_id, TRUE, NULL);
     silc_free(sender_id);
-    if (!router)
-      goto out;
     router_sock = sock;
     id_list = server->global_list;
   }
 
+  if (!router)
+    goto out;
+
   switch(id_type) {
   case SILC_ID_CLIENT:
     {
@@ -2054,7 +2110,7 @@ void silc_server_new_id_list(SilcServer server, SilcSocketConnection sock,
 {
   SilcPacketContext *new_id;
   SilcBuffer idp;
-  uint16 id_len;
+  SilcUInt16 id_len;
 
   SILC_LOG_DEBUG(("Processing New ID List"));
 
@@ -2126,10 +2182,10 @@ void silc_server_new_channel(SilcServer server,
   SilcChannelPayload payload;
   SilcChannelID *channel_id;
   char *channel_name;
-  uint32 name_len;
+  SilcUInt32 name_len;
   unsigned char *id;
-  uint32 id_len;
-  uint32 mode;
+  SilcUInt32 id_len;
+  SilcUInt32 mode;
   SilcServerEntry server_entry;
   SilcChannelEntry channel;
 
@@ -2230,6 +2286,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),
@@ -2276,8 +2334,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->
@@ -2330,7 +2388,7 @@ void silc_server_new_channel_list(SilcServer server,
 {
   SilcPacketContext *new;
   SilcBuffer buffer;
-  uint16 len1, len2;
+  SilcUInt16 len1, len2;
 
   SILC_LOG_DEBUG(("Processing New Channel List"));
 
@@ -2441,10 +2499,10 @@ void silc_server_connection_auth_request(SilcServer server,
                                         SilcSocketConnection sock,
                                         SilcPacketContext *packet)
 {
-  SilcServerConfigSectionClientConnection *client = NULL;
-  uint16 conn_type;
-  int ret, port;
-  SilcAuthMethod auth_meth;
+  SilcServerConfigClient *client = NULL;
+  SilcUInt16 conn_type;
+  int ret;
+  SilcAuthMethod auth_meth = SILC_AUTH_NONE;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -2464,21 +2522,21 @@ void silc_server_connection_auth_request(SilcServer server,
 
   /* Get the authentication method for the client */
   auth_meth = SILC_AUTH_NONE;
-  port = server->sockets[server->sock]->port; /* Listenning port */
-  client = silc_server_config_find_client_conn(server->config,
-                                              sock->ip,
-                                              port);
+  client = silc_server_config_find_client(server, sock->ip);
   if (!client)
-    client = silc_server_config_find_client_conn(server->config,
-                                                sock->hostname,
-                                                port);
-  if (client)
-    auth_meth = client->auth_meth;
-         
+    client = silc_server_config_find_client(server, sock->hostname);
+  if (client) {
+    if (client->passphrase) {
+      if (client->publickey && !server->config->prefer_passphrase_auth)
+       auth_meth = SILC_AUTH_PUBLIC_KEY;
+      else
+       auth_meth = SILC_AUTH_PASSWORD;
+    } else if (client->publickey)
+      auth_meth = SILC_AUTH_PUBLIC_KEY;
+  }
+
   /* Send it back to the client */
-  silc_server_send_connection_auth_request(server, sock,
-                                          conn_type,
-                                          auth_meth);
+  silc_server_send_connection_auth_request(server, sock, conn_type, auth_meth);
 }
 
 /* Received REKEY packet. The sender of the packet wants to regenerate