From: Pekka Riikonen Date: Mon, 4 Apr 2005 12:47:24 +0000 (+0000) Subject: Simplified the invite and ban string handling. X-Git-Tag: silc.server.0.9.19~8 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=1d49861e0bb7d186cbd2a142a7b4902259aafc19 Simplified the invite and ban string handling. --- diff --git a/CHANGES b/CHANGES index d9dfd5ba..864cbe68 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +Mon Apr 4 15:15:46 EEST 2005 Pekka Riikonen + + * 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 * Added WATCH list announcing in backup router protocol. diff --git a/TODO b/TODO index 0f5cfaae..e1c30b32 100644 --- 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 diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 1b848205..c50ccba7 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -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); } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 35d9ccbb..9c2378bf 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -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 diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 8b2c6233..54a95feb 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -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 */ diff --git a/apps/silcd/server_util.h b/apps/silcd/server_util.h index 413bdeb9..62b3d60f 100644 --- a/apps/silcd/server_util.h +++ b/apps/silcd/server_util.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - 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 */