From: Pekka Riikonen Date: Sat, 22 Jun 2002 15:00:52 +0000 (+0000) Subject: Fixed TOPIC_SET, CMODE_CHANGE notifys and New Channel packet X-Git-Tag: silc.client.0.9.3~7 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=6598e3df6635ec0e44caec364bc4f3bd58d2728f Fixed TOPIC_SET, CMODE_CHANGE notifys and New Channel packet handling. Fixed CMODE rights checking. --- diff --git a/CHANGES b/CHANGES index 8bc79681..46f6f97c 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,17 @@ +Sat Jun 22 17:06:58 EEST 2002 Pekka Riikonen + + * Don't send or handle TOPIC_SET if topic is already set and + is same as being set. Affected files silcd/command.c and + silcd/packet_receive.c. + + * Fixed CMODE change rights checking to work correctly when + removing modes by operator. Affected file is + silcd/server_util.c. + + * Fixed some handling with New Channel packet in router and + fixed some CMODE_CHANGE notify handling in server and router. + Affected file is silcd/packet_receive.c. + Sat Jun 22 12:49:21 EEST 2002 Pekka Riikonen * All CMODE_CHANGE and CUMODE_CHANGE notifys are now sent back diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 992402a8..f0889aef 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -2440,24 +2440,26 @@ SILC_SERVER_CMD_FUNC(topic) goto out; } - /* Set the topic for channel */ - silc_free(channel->topic); - channel->topic = strdup(tmp); - - /* Send TOPIC_SET notify type to the network */ - silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server), - SILC_BROADCAST(server), channel, - client->id, SILC_ID_CLIENT, - channel->topic); - - idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); - - /* Send notify about topic change to all clients on the channel */ - silc_server_send_notify_to_channel(server, NULL, channel, FALSE, - SILC_NOTIFY_TYPE_TOPIC_SET, 2, - idp->data, idp->len, - channel->topic, strlen(channel->topic)); - silc_buffer_free(idp); + if (!channel->topic || strcmp(channel->topic, tmp)) { + /* Set the topic for channel */ + silc_free(channel->topic); + channel->topic = strdup(tmp); + + /* Send TOPIC_SET notify type to the network */ + silc_server_send_notify_topic_set(server, SILC_PRIMARY_ROUTE(server), + SILC_BROADCAST(server), channel, + client->id, SILC_ID_CLIENT, + channel->topic); + + /* Send notify about topic change to all clients on the channel */ + idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); + silc_server_send_notify_to_channel(server, NULL, channel, FALSE, + SILC_NOTIFY_TYPE_TOPIC_SET, 2, + idp->data, idp->len, + channel->topic, + strlen(channel->topic)); + silc_buffer_free(idp); + } } /* Send the topic to client as reply packet */ @@ -4010,6 +4012,7 @@ SILC_SERVER_CMD_FUNC(cmode) /* Check that client has rights to change any requested channel modes */ if (set_mask && !silc_server_check_cmode_rights(server, channel, chl, mode_mask)) { + SILC_LOG_DEBUG(("Client does not have rights to change mode")); silc_server_command_send_status_reply( cmd, SILC_COMMAND_CMODE, (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP) ? diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index f5b28e61..2ca1e630 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -94,13 +94,12 @@ void silc_server_notify(SilcServer server, if (!channel_id) goto out; - if (!server->standalone) - silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server), - packet->type, packet->flags | - SILC_PACKET_FLAG_BROADCAST, - channel_id, SILC_ID_CHANNEL, - packet->buffer->data, - packet->buffer->len, FALSE); + silc_server_packet_send_dest(server, SILC_PRIMARY_ROUTE(server), + packet->type, packet->flags | + SILC_PACKET_FLAG_BROADCAST, + channel_id, SILC_ID_CHANNEL, + packet->buffer->data, + packet->buffer->len, FALSE); silc_server_backup_send_dest(server, (SilcServerEntry)sock->user_data, packet->type, packet->flags, channel_id, SILC_ID_CHANNEL, @@ -108,12 +107,11 @@ void silc_server_notify(SilcServer server, FALSE, TRUE); } else { /* Packet is destined to client or server */ - if (!server->standalone) - silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), - packet->type, - packet->flags | SILC_PACKET_FLAG_BROADCAST, - packet->buffer->data, packet->buffer->len, - FALSE); + silc_server_packet_send(server, SILC_PRIMARY_ROUTE(server), + packet->type, + packet->flags | SILC_PACKET_FLAG_BROADCAST, + packet->buffer->data, packet->buffer->len, + FALSE); silc_server_backup_send(server, (SilcServerEntry)sock->user_data, packet->type, packet->flags, packet->buffer->data, packet->buffer->len, @@ -148,6 +146,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -259,6 +258,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -409,13 +409,16 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } } - if (channel->topic && !strcmp(channel->topic, tmp)) + if (channel->topic && !strcmp(channel->topic, tmp)) { + SILC_LOG_DEBUG(("Topic is already set and same")); goto out; + } if (client) { /* Get user's channel entry and check that topic set is allowed. */ @@ -504,9 +507,9 @@ void silc_server_notify(SilcServer server, /* * Distribute the notify to local clients on the channel */ - + SILC_LOG_DEBUG(("CMODE CHANGE notify")); - + /* Get client ID */ tmp = silc_argument_get_arg_type(args, 1, &tmp_len); if (!tmp) @@ -544,6 +547,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -568,22 +572,51 @@ void silc_server_notify(SilcServer server, goto out; if (!silc_server_check_cmode_rights(server, channel, chl, mode)) { SILC_LOG_DEBUG(("CMODE change is not allowed")); + silc_server_send_notify_cmode(server, sock, FALSE, channel, + channel->mode, server->id, + SILC_ID_SERVER, channel->cipher, + channel->hmac_name, + channel->passphrase, + channel->founder_key); goto out; } } else { + /* Assure that server is not removing founder mode from us */ if (server->server_type == SILC_ROUTER && + sock != SILC_PRIMARY_ROUTE(server) && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH && !(mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) { SILC_LOG_DEBUG(("Enforcing sender to change channel mode")); silc_server_send_notify_cmode(server, sock, FALSE, channel, channel->mode, server->id, - SILC_ID_SERVER, - channel->cipher, + SILC_ID_SERVER, channel->cipher, channel->hmac_name, channel->passphrase, channel->founder_key); goto out; } + + /* If server is adding founder mode, check whether there is founder + on channel already and is not from this server */ + if (server->server_type == SILC_ROUTER && + sock != SILC_PRIMARY_ROUTE(server) && + mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) { + silc_hash_table_list(channel->user_list, &htl); + while (silc_hash_table_get(&htl, NULL, (void *)&chl)) + if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && + chl->client->router != sock->user_data) { + SILC_LOG_DEBUG(("Enforcing sender to change channel mode")); + silc_server_send_notify_cmode(server, sock, FALSE, channel, + channel->mode, server->id, + SILC_ID_SERVER, channel->cipher, + channel->hmac_name, + channel->passphrase, + channel->founder_key); + silc_hash_table_list_reset(&htl); + goto out; + } + silc_hash_table_list_reset(&htl); + } } /* If the channel had private keys set and the mode was removed then @@ -694,9 +727,9 @@ void silc_server_notify(SilcServer server, */ SilcChannelClientEntry chl2 = NULL; bool notify_sent = FALSE; - + SILC_LOG_DEBUG(("CUMODE CHANGE notify")); - + /* Get client ID */ tmp = silc_argument_get_arg_type(args, 1, &tmp_len); if (!tmp) @@ -734,6 +767,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -797,10 +831,15 @@ void silc_server_notify(SilcServer server, if (!silc_server_client_on_channel(client2, channel, &chl)) goto out; + if (server->server_type == SILC_SERVER && chl->mode == mode) { + SILC_LOG_DEBUG(("Mode is changed already")); + break; + } + if (mode & SILC_CHANNEL_UMODE_CHANFO && !(chl->mode & SILC_CHANNEL_UMODE_CHANFO) && server->server_type == SILC_ROUTER && - sock->user_data != server->router) { + sock != SILC_PRIMARY_ROUTE(server)) { SilcPublicKey founder_key = NULL; /* If channel doesn't have founder auth mode then it's impossible @@ -890,7 +929,7 @@ void silc_server_notify(SilcServer server, silc_pkcs_public_key_free(founder_key); } - if (chl->mode == mode) { + if (server->server_type != SILC_SERVER && chl->mode == mode) { SILC_LOG_DEBUG(("Mode is changed already")); break; } @@ -933,6 +972,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -1040,6 +1080,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->global_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -1247,6 +1288,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -1507,6 +1549,7 @@ void silc_server_notify(SilcServer server, channel = silc_idlist_find_channel_by_id(server->local_list, channel_id, NULL); if (!channel) { + SILC_LOG_DEBUG(("Notify for unknown channel")); silc_free(channel_id); goto out; } @@ -2693,8 +2736,6 @@ void silc_server_new_channel(SilcServer server, SilcServerEntry server_entry; SilcChannelEntry channel; - SILC_LOG_DEBUG(("Processing New Channel")); - if (sock->type == SILC_SOCKET_TYPE_CLIENT || packet->src_id_type != SILC_ID_SERVER || server->server_type == SILC_SERVER) @@ -2766,6 +2807,8 @@ void silc_server_new_channel(SilcServer server, /* If the channel does not exist, then create it. This creates a new key to the channel as well that we will send to the server. */ if (!channel) { + SILC_LOG_DEBUG(("Channel is new to us")); + /* The protocol says that the Channel ID's IP address must be based on the router's IP address. Check whether the ID is based in our IP and if it is not then create a new ID and enforce the server @@ -2793,6 +2836,7 @@ void silc_server_new_channel(SilcServer server, return; } channel->disabled = TRUE; + channel->mode = silc_channel_get_mode(payload); /* Send the new channel key to the server */ id = silc_id_id2str(channel->id, SILC_ID_CHANNEL); @@ -2812,6 +2856,8 @@ void silc_server_new_channel(SilcServer server, We also create a new key for the channel. */ SilcBuffer modes = NULL, users = NULL, users_modes = NULL; + SILC_LOG_DEBUG(("Channel already exists")); + if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) { /* They don't match, send CHANNEL_CHANGE notify to the server to force the ID change. */ @@ -2823,8 +2869,8 @@ void silc_server_new_channel(SilcServer server, return; } -#if 0 /* Lets expect that server send CMODE_CHANGE notify anyway to - (attempt) force mode change, and may very well get it. */ +#if 0 /* We will announce our CMODE anyway for this channel, so no need + to check it (implicit enforce). */ /* If the mode is different from what we have then enforce the mode change. */ diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index ed048624..18c4011d 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -745,11 +745,11 @@ void silc_server_packet_relay_to_channel(SilcServer server, bool gone = FALSE; int k; - SILC_LOG_DEBUG(("Relaying packet to channel")); - if (!silc_server_client_on_channel(sender_entry, channel, &chl_sender)) return; + SILC_LOG_DEBUG(("Relaying packet to channel %s", channel->channel_name)); + /* This encrypts the packet, if needed. It will be encrypted if it came from the router thus it needs to be encrypted with the channel key. If the channel key does not exist, then we know we @@ -950,7 +950,8 @@ void silc_server_packet_send_local_channel(SilcServer server, SilcHashTableList htl; SilcSocketConnection sock = NULL; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Send packet to local clients on channel %s", + channel->channel_name)); /* Send the message to clients on the channel's client list. */ silc_hash_table_list(channel->user_list, &htl); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 6ac9508c..ee5765ee 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -726,6 +726,9 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_retry) return; } + SILC_LOG_DEBUG(("Retrying connecting to a router in %d seconds", + sconn->retry_timeout)); + /* We will lookup a fresh pointer later */ silc_server_config_unref(&sconn->conn); @@ -3390,7 +3393,7 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, SilcUInt32 tmp_len; char *cipher; - SILC_LOG_DEBUG(("Start")); + SILC_LOG_DEBUG(("Saving new channel key")); /* Decode channel key payload */ payload = silc_channel_key_payload_parse(key_payload->data, diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 54ed8e13..713b8528 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -1068,8 +1068,10 @@ bool silc_server_check_cmode_rights(SilcServer server, } if (mode & SILC_CHANNEL_MODE_PASSPHRASE) { - if (is_op && !is_fo) - return FALSE; + if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE)) { + if (is_op && !is_fo) + return FALSE; + } } else { if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) { if (is_op && !is_fo) @@ -1078,8 +1080,10 @@ bool silc_server_check_cmode_rights(SilcServer server, } if (mode & SILC_CHANNEL_MODE_CIPHER) { - if (is_op && !is_fo) - return FALSE; + if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER)) { + if (is_op && !is_fo) + return FALSE; + } } else { if (channel->mode & SILC_CHANNEL_MODE_CIPHER) { if (is_op && !is_fo) @@ -1088,8 +1092,10 @@ bool silc_server_check_cmode_rights(SilcServer server, } if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) { - if (is_op && !is_fo) - return FALSE; + if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) { + if (is_op && !is_fo) + return FALSE; + } } else { if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) { if (is_op && !is_fo) @@ -1098,8 +1104,10 @@ bool silc_server_check_cmode_rights(SilcServer server, } if (mode & SILC_CHANNEL_MODE_SILENCE_USERS) { - if (is_op && !is_fo) - return FALSE; + if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS)) { + if (is_op && !is_fo) + return FALSE; + } } else { if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS) { if (is_op && !is_fo) @@ -1108,8 +1116,10 @@ bool silc_server_check_cmode_rights(SilcServer server, } if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS) { - if (is_op && !is_fo) - return FALSE; + if (!(channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS)) { + if (is_op && !is_fo) + return FALSE; + } } else { if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS) { if (is_op && !is_fo)