Simplified the invite and ban string handling.
authorPekka Riikonen <priikone@silcnet.org>
Mon, 4 Apr 2005 12:47:24 +0000 (12:47 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Mon, 4 Apr 2005 12:47:24 +0000 (12:47 +0000)
CHANGES
TODO
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/server_util.c
apps/silcd/server_util.h

diff --git a/CHANGES b/CHANGES
index d9dfd5ba82a53103d2461ec5d9e7e4c0c79b4fdf..864cbe68e4690635adb9f174d18f1b167a5c69a7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+Mon Apr  4 15:15:46 EEST 2005  Pekka Riikonen <priikone@silcnet.org>
+
+       * Simplified the invite and ban string handling in the
+         server.  Check for valid invite and ban arguments also.
+         Affected file silcd/server_util.c.
+
 Sun Apr  3 14:58:53 EEST 2005  Pekka Riikonen <priikone@silcnet.org>
 
        * Added WATCH list announcing in backup router protocol.
diff --git a/TODO b/TODO
index 0f5cfaae51bb18e20cd4313db5559fc2a8f5f6de..e1c30b328f58a8ef9a9a301eb2113f60a1b252a8 100644 (file)
--- a/TODO
+++ b/TODO
@@ -18,11 +18,12 @@ TODO for SILC Server 1.0
  o BUG: silc_idlist_del_client had been called but sock->user_data remained
    and pointed to invalid pointer.  Where it was called is not known.
 
- o Check for valid ban strings.  Check ban string notifying.
-
  o Basic UTF-8 stringprep profile that makes sure UTF-8 strings are
    as defined in spec-08 section 3.13.
 
+ o Server sometimes connects more than once to router and keeps
+   connecting even though connection exists.
+
  o Testing
 
 
index 1b848205d639619f74219e28687386202e813291..c50ccba7915ca1189d6b48fd58c0bf02118355e1 100644 (file)
@@ -1265,8 +1265,14 @@ SILC_SERVER_CMD_FUNC(invite)
       }
 
       /* Now add or delete the information. */
-      silc_server_inviteban_process(server, channel->invite_list,
-                                   (SilcUInt8)atype[0], args);
+      if (!silc_server_inviteban_process(server, channel->invite_list,
+                                        (SilcUInt8)atype[0], args)) {
+       silc_server_command_send_status_reply(
+                                   cmd, SILC_COMMAND_INVITE,
+                                   SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+                                   0);
+       goto out;
+      }
     }
     silc_argument_payload_free(args);
   }
@@ -3839,6 +3845,7 @@ SILC_SERVER_CMD_FUNC(kick)
       silc_argument_payload_encode_one(NULL, target_idp, target_idp_len, 3);
     SilcArgumentPayload args =
       silc_argument_payload_parse(ab->data, ab->len, 1);
+
     silc_server_inviteban_process(server, channel->invite_list, 1, args);
     silc_buffer_free(ab);
     silc_argument_payload_free(args);
@@ -4611,8 +4618,14 @@ SILC_SERVER_CMD_FUNC(ban)
       }
 
       /* Now add or delete the information. */
-      silc_server_inviteban_process(server, channel->ban_list,
-                                   (SilcUInt8)atype[0], args);
+      if (!silc_server_inviteban_process(server, channel->ban_list,
+                                        (SilcUInt8)atype[0], args)) {
+       silc_server_command_send_status_reply(
+                                     cmd, SILC_COMMAND_BAN,
+                                     SILC_STATUS_ERR_NOT_ENOUGH_PARAMS,
+                                     0);
+       goto out;
+      }
     }
     silc_argument_payload_free(args);
   }
index 35d9ccbb22784fbecdb07969bc86e675193e81ae..9c2378bf9ba3201bd19d12f67e79cc375d51264a 100644 (file)
@@ -1168,15 +1168,16 @@ void silc_server_notify(SilcServer server,
       if (!iargs)
        goto out;
 
-      if (action != 0x01 && !channel->invite_list)
+      if (!channel->invite_list)
        channel->invite_list =
          silc_hash_table_alloc(0, silc_hash_ptr,
                                NULL, NULL, NULL,
                                silc_server_inviteban_destruct, channel, TRUE);
 
       /* Proces the invite action */
-      silc_server_inviteban_process(server, channel->invite_list, action,
-                                   iargs);
+      if (!silc_server_inviteban_process(server, channel->invite_list, action,
+                                        iargs))
+       goto out;
       silc_argument_payload_free(iargs);
 
       /* If we are router we must send this notify to our local servers on
@@ -1787,15 +1788,16 @@ void silc_server_notify(SilcServer server,
       if (!iargs)
        goto out;
 
-      if (action != 0x01 && !channel->ban_list)
+      if (!channel->ban_list)
        channel->ban_list =
          silc_hash_table_alloc(0, silc_hash_ptr,
                                NULL, NULL, NULL,
                                silc_server_inviteban_destruct, channel, TRUE);
 
       /* Proces the ban action */
-      silc_server_inviteban_process(server, channel->ban_list, action,
-                                   iargs);
+      if (!silc_server_inviteban_process(server, channel->ban_list, action,
+                                        iargs))
+       goto out;
       silc_argument_payload_free(iargs);
 
       /* If we are router we must send this notify to our local servers on
index 8b2c6233dd84531e9c2fad6ee428721613286fe5..54a95feb5ad86538488fd003e1dbded40835d0ad 100644 (file)
@@ -1879,6 +1879,8 @@ bool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
   SilcBuffer entry, idp = NULL, pkp = NULL;
   bool ret = FALSE;
 
+  SILC_LOG_DEBUG(("Matching invite/ban"));
+
   if (type < 1 || type > 3 || !check)
     return FALSE;
 
@@ -1928,7 +1930,7 @@ bool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
 
 /* Process invite or ban information */
 
-void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
+bool silc_server_inviteban_process(SilcServer server, SilcHashTable list,
                                   SilcUInt8 action, SilcArgumentPayload args)
 {
   unsigned char *tmp;
@@ -1946,68 +1948,42 @@ void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
     tmp = silc_argument_get_first_arg(args, &type, &len);
     while (tmp) {
       if (type == 1) {
-       /* Invite string.  Get the old invite string from hash table
-          and append this at the end of the existing one. */
-       if (!silc_hash_table_find(list, (void *)1, NULL, (void *)&tmp2)) {
-         tmp2 = silc_calloc(1, sizeof(*tmp2));
-         silc_hash_table_add(list, (void *)1, tmp2);
+       /* Check validity of the string */
+       if (!silc_utf8_valid(tmp, len) || !len) {
+         tmp = silc_argument_get_next_arg(args, &type, &len);
+         continue;
        }
 
-       /* Check that the string is not part of invite string already */
-       if (action == 0x00) {
-         if (silc_string_match(tmp2->data, tmp))
+       /* Check if the string is added already */
+       silc_hash_table_list(list, &htl);
+       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
+         if (type == 1 && silc_string_match(tmp2->data, tmp)) {
+           tmp = NULL;
            break;
-
-         if (len) {
-           if (tmp[len - 1] == ',')
-             tmp[len - 1] = '\0';
-           silc_buffer_strformat(tmp2, tmp, SILC_STRFMT_END);
-           silc_buffer_strformat(tmp2, ",", SILC_STRFMT_END);
-         }
-       } else {
-         /* Announced list.  Check each entry in the list */
-         unsigned char e[256];
-         char *start, *end, *n, *rtmp;
-         int i, k;
-
-         rtmp = silc_memdup(tmp, len);
-         for (i = 0, k = 0; i < len; i++) {
-           if (tmp[i] != ',')
-             continue;
-
-           memset(e, 0, sizeof(e));
-           silc_strncat(e, sizeof(e), tmp + k, i - k);
-           if (!silc_string_match(tmp2->data, e)) {
-             k = i + 1;
-             continue;
-           }
-
-           /* Matches.  Delete it since we have it already */
-           start = strstr(rtmp, e);
-           if (start && strlen(start) >= (i - k)) {
-             end = start + (i - k);
-             n = silc_calloc(strlen(rtmp) - (i - k), sizeof(*n));
-             strncat(n, rtmp, start - rtmp);
-             if (strlen(end) > 1)
-               strncat(n, end + 1, ((rtmp + strlen(rtmp)) - end) - 1);
-             silc_free(rtmp);
-             rtmp = n;
-           }
-
-           k = i + 1;
          }
+       }
+       silc_hash_table_list_reset(&htl);
 
-         /* Save the part that we didn't already have. */
-         if (strlen(rtmp) > 1) {
-           silc_buffer_strformat(tmp2, rtmp, SILC_STRFMT_END);
-           silc_buffer_strformat(tmp2, ",", SILC_STRFMT_END);
-         }
-         silc_free(rtmp);
+       if (tmp) {
+         /* Add the string to hash table */
+         tmp2 = silc_buffer_alloc_size(len + 1);
+         if (tmp[len - 1] == ',')
+           tmp[len - 1] = '\0';
+         silc_buffer_put(tmp2, tmp, len);
+         silc_hash_table_add(list, (void *)1, tmp2);
        }
 
       } else if (type == 2) {
        /* Public key.  Check first if the public key is already on the
           list and ignore it if it is, otherwise, add it to hash table. */
+       SilcPublicKey pk;
+
+       /* Verify validity of the public key */
+       if (!silc_pkcs_public_key_payload_decode(tmp, len, &pk)) {
+         tmp = silc_argument_get_next_arg(args, &type, &len);
+         continue;
+       }
+       silc_pkcs_public_key_free(pk);
 
        /* Check if the public key is in the list already */
        silc_hash_table_list(list, &htl);
@@ -2057,32 +2033,32 @@ void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
     tmp = silc_argument_get_first_arg(args, &type, &len);
     while (tmp) {
       if (type == 1) {
-       /* Invite string.  Get the old string from hash table and delete
-          the requested string. */
-       char *string = NULL, *start, *end, *n;
-
-       if (silc_hash_table_find(list, (void *)1, NULL, (void *)&tmp2)) {
-         string = tmp2->head;
-         if (tmp2->truelen && !strncmp(string, tmp, tmp2->truelen - 1)) {
-           /* Delete entire string */
-           silc_hash_table_del(list, (void *)1);
-         } else if (tmp2->truelen) {
-           /* Delete part of the string */
-           start = strstr(string, tmp);
-           if (start && strlen(start) >= len) {
-             end = start + len;
-             n = silc_calloc(strlen(string) - len, sizeof(*n));
-             strncat(n, string, start - string);
-             if (strlen(end) > 1)
-               strncat(n, end + 1, ((string + strlen(string)) - end) - 1);
-             silc_free(tmp2->head);
-             silc_buffer_set(tmp2, n, strlen(n));
-           }
+       /* Check validity of the string */
+       if (!silc_utf8_valid(tmp, len)) {
+         tmp = silc_argument_get_next_arg(args, &type, &len);
+         continue;
+       }
+
+       /* Delete from the list */
+       silc_hash_table_list(list, &htl);
+       while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) {
+         if (type == 1 && silc_string_match(tmp2->data, tmp)) {
+           silc_hash_table_del_by_context(list, (void *)1, tmp2);
+           break;
          }
        }
+       silc_hash_table_list_reset(&htl);
 
       } else if (type == 2) {
        /* Public key. */
+       SilcPublicKey pk;
+
+       /* Verify validity of the public key */
+       if (!silc_pkcs_public_key_payload_decode(tmp, len, &pk)) {
+         tmp = silc_argument_get_next_arg(args, &type, &len);
+         continue;
+       }
+       silc_pkcs_public_key_free(pk);
 
        /* Delete from the invite list */
        silc_hash_table_list(list, &htl);
@@ -2111,6 +2087,8 @@ void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
       tmp = silc_argument_get_next_arg(args, &type, &len);
     }
   }
+
+  return TRUE;
 }
 
 /* Destructor for invite and ban list entrys */
index 413bdeb97284c108dec09cb9f6a5b5052b5cd88c..62b3d60fef2527d0c76e14f23fa2d783345e83e9 100644 (file)
@@ -4,7 +4,7 @@
 
   Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 1997 - 2003 Pekka Riikonen
+  Copyright (C) 1997 - 2005 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -202,7 +202,7 @@ bool silc_server_inviteban_match(SilcServer server, SilcHashTable list,
                                 SilcUInt8 type, void *check);
 
 /* Process invite or ban information */
-void silc_server_inviteban_process(SilcServer server, SilcHashTable list,
+bool silc_server_inviteban_process(SilcServer server, SilcHashTable list,
                                   SilcUInt8 action, SilcArgumentPayload args);
 
 /* Destructor for invite or ban list entrys */