From: Pekka Riikonen Date: Fri, 17 May 2002 09:08:07 +0000 (+0000) Subject: updates. X-Git-Tag: silc.client.0.9.1~7 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=f5ff7cf783e9df23f91fe5fcf3da13a1b8373311 updates. --- diff --git a/CHANGES b/CHANGES index 6e12aef3..133015d2 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,16 @@ Fri May 17 08:33:41 CEST 2002 Pekka Riikonen * Fixed watcher list checking during server signoff. It crashed the server. Affected file silcd/server_util.c. + * The JOIN command reply returns now the founder's public + key. Affected file is silcd/command.c. + + * Announce the channel mode, and the mode properties with + CMODE_CHANGE notify. Affected file silcd/server.c. + + * Mark new channels by default disabled, untill at least + one user joins the channel. Affected file is + silcd/packet_receive.c. + Thu May 16 13:05:13 CEST 2002 Pekka Riikonen * The nickname argument to watch notify can be optional. diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 28c46634..4c8b900b 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -3174,6 +3174,8 @@ static void silc_server_command_join_channel(SilcServer server, char check[512], check2[512]; bool founder = FALSE; bool resolve; + unsigned char *fkey = NULL; + SilcUInt32 fkey_len = 0; SILC_LOG_DEBUG(("Start")); @@ -3370,9 +3372,12 @@ static void silc_server_command_join_channel(SilcServer server, silc_free(tmp); } + if (channel->founder_key) + fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len); + reply = silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN, - SILC_STATUS_OK, 0, ident, 13, + SILC_STATUS_OK, 0, ident, 14, 2, channel->channel_name, strlen(channel->channel_name), 3, chidp->data, chidp->len, @@ -3396,7 +3401,8 @@ static void silc_server_command_join_channel(SilcServer server, 12, tmp3, 4, 13, user_list->data, user_list->len, 14, mode_list->data, - mode_list->len); + mode_list->len, + 15, fkey, fkey_len); /* Send command reply */ silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, @@ -3429,13 +3435,11 @@ static void silc_server_command_join_channel(SilcServer server, notify the mode change to the channel. */ if (founder) { SILC_PUT32_MSB(chl->mode, mode); - tmp = silc_pkcs_public_key_encode(channel->founder_key, &tmp_len); silc_server_send_notify_to_channel(server, NULL, channel, FALSE, SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4, clidp->data, clidp->len, mode, 4, clidp->data, clidp->len, - tmp, tmp_len); - silc_free(tmp); + fkey, fkey_len); /* Set CUMODE notify type to network */ if (!server->standalone) @@ -3453,6 +3457,7 @@ static void silc_server_command_join_channel(SilcServer server, silc_buffer_free(keyp); silc_buffer_free(user_list); silc_buffer_free(mode_list); + silc_free(fkey); out: silc_free(passphrase); @@ -3647,7 +3652,7 @@ SILC_SERVER_CMD_FUNC(join) } if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS && - !silc_hash_table_count(channel->user_list)) + !channel->disabled && !silc_hash_table_count(channel->user_list)) created = TRUE; } diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 3696ec3a..22fe1f1c 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -781,6 +781,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) char *channel_name, *tmp; SilcUInt32 mode, created; SilcBuffer keyp = NULL, client_id_list = NULL, client_mode_list = NULL; + SilcPublicKey founder_key = NULL; COMMAND_CHECK_STATUS; @@ -860,6 +861,11 @@ SILC_SERVER_CMD_REPLY_FUNC(join) silc_buffer_pull_tail(client_mode_list, len); silc_buffer_put(client_mode_list, tmp, len); + /* Get founder key */ + tmp = silc_argument_get_arg_type(cmd->args, 15, &len); + if (tmp) + silc_pkcs_public_key_decode(tmp, len, &founder_key); + /* See whether we already have the channel. */ entry = silc_idlist_find_channel_by_name(server->local_list, channel_name, &cache); @@ -903,6 +909,13 @@ SILC_SERVER_CMD_REPLY_FUNC(join) } } + if (founder_key) { + if (entry->founder_key) + silc_pkcs_public_key_free(entry->founder_key); + entry->founder_key = founder_key; + founder_key = NULL; + } + if (entry->hmac_name && hmac) { silc_free(entry->hmac_name); entry->hmac_name = strdup(silc_hmac_get_name(hmac)); @@ -962,6 +975,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) silc_free(client_id); silc_server_command_reply_free(cmd); + silc_pkcs_public_key_free(founder_key); if (client_id_list) silc_buffer_free(client_id_list); if (client_mode_list) diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 91d08cd3..310a14da 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -229,6 +229,7 @@ void silc_server_notify(SilcServer server, silc_hash_table_add(client->channels, channel, chl); silc_free(client_id); channel->user_count++; + channel->disabled = FALSE; break; @@ -628,7 +629,7 @@ void silc_server_notify(SilcServer server, if (channel->founder_key) silc_pkcs_public_key_free(channel->founder_key); channel->founder_key = NULL; - } else if (!client->data.public_key) { + } else if (client && !client->data.public_key) { client->data.public_key = silc_pkcs_public_key_copy(channel->founder_key); } @@ -768,7 +769,7 @@ void silc_server_notify(SilcServer server, server->server_type == SILC_ROUTER) { /* Check whether this client is allowed to be channel founder on this channel. */ - SilcPublicKey founder_key; + SilcPublicKey founder_key = NULL; /* If channel doesn't have founder auth mode then it's impossible that someone would be getting founder rights with CUMODE command. @@ -810,15 +811,26 @@ void silc_server_notify(SilcServer server, break; } - /* Now match the public key we have cached and publick key sent. + /* Now match the public key we have cached and public key sent. They must match. */ - if (!silc_pkcs_public_key_compare(channel->founder_key, + if (client->data.public_key && + !silc_pkcs_public_key_compare(channel->founder_key, client->data.public_key)) { mode &= ~SILC_CHANNEL_UMODE_CHANFO; silc_server_force_cumode_change(server, sock, channel, chl, mode); notify_sent = TRUE; break; } + if (!silc_pkcs_public_key_compare(channel->founder_key, + founder_key)) { + mode &= ~SILC_CHANNEL_UMODE_CHANFO; + silc_server_force_cumode_change(server, sock, channel, chl, mode); + notify_sent = TRUE; + break; + } + + if (founder_key) + silc_pkcs_public_key_free(founder_key); } SILC_LOG_DEBUG(("Changing the channel user mode")); @@ -999,7 +1011,7 @@ void silc_server_notify(SilcServer server, } if (channel_id2) { - SilcBuffer users = NULL, users_modes = NULL; + SilcBuffer modes = NULL, users = NULL, users_modes = NULL; /* Re-announce this channel which ID was changed. */ silc_server_send_new_channel(server, sock, FALSE, channel->channel_name, @@ -1009,8 +1021,16 @@ void silc_server_notify(SilcServer server, channel->mode); /* Re-announce our clients on the channel as the ID has changed now */ - silc_server_announce_get_channel_users(server, channel, &users, + silc_server_announce_get_channel_users(server, channel, &modes, &users, &users_modes); + if (modes) { + silc_buffer_push(modes, modes->data - modes->head); + silc_server_packet_send_dest(server, sock, + SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, + channel->id, SILC_ID_CHANNEL, + modes->data, modes->len, FALSE); + silc_buffer_free(modes); + } if (users) { silc_buffer_push(users, users->data - users->head); silc_server_packet_send(server, sock, @@ -2621,6 +2641,7 @@ void silc_server_new_channel(SilcServer server, 0, channel_id, sock->user_data, NULL, NULL, 0); if (!channel) return; + channel->disabled = TRUE; server->stat.channels++; if (server->server_type == SILC_ROUTER) @@ -2671,9 +2692,13 @@ void silc_server_new_channel(SilcServer server, silc_free(channel_id); return; } + channel->disabled = TRUE; +#if 0 + /* CMODE change notify is expected */ /* Get the mode and set it to the channel */ channel->mode = silc_channel_get_mode(payload); +#endif /* Send the new channel key to the server */ id = silc_id_id2str(channel->id, SILC_ID_CHANNEL); @@ -2692,7 +2717,7 @@ void silc_server_new_channel(SilcServer server, /* The channel exist by that name, check whether the ID's match. If they don't then we'll force the server to use the ID we have. We also create a new key for the channel. */ - SilcBuffer users = NULL, users_modes = NULL; + SilcBuffer modes = NULL, users = NULL, users_modes = NULL; if (!SILC_ID_CHANNEL_COMPARE(channel_id, channel->id)) { /* They don't match, send CHANNEL_CHANGE notify to the server to @@ -2745,8 +2770,16 @@ void silc_server_new_channel(SilcServer server, /* Since the channel is coming from server and we also know about it then send the JOIN notify to the server so that it see's our users on the channel "joining" the channel. */ - silc_server_announce_get_channel_users(server, channel, &users, + silc_server_announce_get_channel_users(server, channel, &modes, &users, &users_modes); + if (modes) { + silc_buffer_push(modes, modes->data - modes->head); + silc_server_packet_send_dest(server, sock, + SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, + channel->id, SILC_ID_CHANNEL, + modes->data, modes->len, FALSE); + silc_buffer_free(modes); + } if (users) { silc_buffer_push(users, users->data - users->head); silc_server_packet_send(server, sock, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 9243ad01..e8874aec 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -3541,6 +3541,7 @@ void silc_server_announce_get_channel_topic(SilcServer server, void silc_server_announce_get_channel_users(SilcServer server, SilcChannelEntry channel, + SilcBuffer *channel_modes, SilcBuffer *channel_users, SilcBuffer *channel_users_modes) { @@ -3551,11 +3552,43 @@ void silc_server_announce_get_channel_users(SilcServer server, int len; unsigned char mode[4], *fkey = NULL; SilcUInt32 fkey_len = 0; + char *hmac; SILC_LOG_DEBUG(("Start")); - /* Now find all users on the channel */ chidp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL); + + /* CMODE notify */ + clidp = silc_id_payload_encode(server->id, SILC_ID_SERVER); + SILC_PUT32_MSB(channel->mode, mode); + hmac = channel->hmac ? (char *)silc_hmac_get_name(channel->hmac) : NULL; + if (channel->founder_key) + fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len); + tmp = + silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CMODE_CHANGE, + 6, clidp->data, clidp->len, + mode, sizeof(mode), + NULL, 0, + hmac, hmac ? strlen(hmac) : 0, + channel->passphrase, + channel->passphrase ? + strlen(channel->passphrase) : 0, + fkey, fkey_len); + len = tmp->len; + *channel_modes = + silc_buffer_realloc(*channel_modes, + (*channel_modes ? + (*channel_modes)->truelen + len : len)); + silc_buffer_pull_tail(*channel_modes, + ((*channel_modes)->end - + (*channel_modes)->data)); + silc_buffer_put(*channel_modes, tmp->data, tmp->len); + silc_buffer_pull(*channel_modes, len); + silc_buffer_free(tmp); + silc_buffer_free(clidp); + silc_free(fkey); + + /* Now find all users on the channel */ silc_hash_table_list(channel->user_list, &htl); while (silc_hash_table_get(&htl, NULL, (void *)&chl)) { clidp = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT); @@ -3612,6 +3645,7 @@ void silc_server_announce_get_channel_users(SilcServer server, void silc_server_announce_get_channels(SilcServer server, SilcIDList id_list, SilcBuffer *channels, + SilcBuffer **channel_modes, SilcBuffer *channel_users, SilcBuffer **channel_users_modes, SilcUInt32 *channel_users_modes_c, @@ -3670,10 +3704,14 @@ void silc_server_announce_get_channels(SilcServer server, sizeof(**channel_users_modes) * (i + 1)); (*channel_users_modes)[i] = NULL; + *channel_modes = silc_realloc(*channel_modes, + sizeof(**channel_modes) * (i + 1)); + (*channel_modes)[i] = NULL; *channel_ids = silc_realloc(*channel_ids, sizeof(**channel_ids) * (i + 1)); (*channel_ids)[i] = NULL; silc_server_announce_get_channel_users(server, channel, + &(*channel_modes)[i], channel_users, &(*channel_users_modes)[i]); (*channel_ids)[i] = channel->id; @@ -3708,7 +3746,7 @@ void silc_server_announce_channels(SilcServer server, unsigned long creation_time, SilcSocketConnection remote) { - SilcBuffer channels = NULL, channel_users = NULL; + SilcBuffer channels = NULL, *channel_modes = NULL, channel_users = NULL; SilcBuffer *channel_users_modes = NULL; SilcBuffer *channel_topics = NULL; SilcUInt32 channel_users_modes_c = 0; @@ -3718,7 +3756,8 @@ void silc_server_announce_channels(SilcServer server, /* Get channels and channel users in local list */ silc_server_announce_get_channels(server, server->local_list, - &channels, &channel_users, + &channels, &channel_modes, + &channel_users, &channel_users_modes, &channel_users_modes_c, &channel_topics, @@ -3727,7 +3766,8 @@ void silc_server_announce_channels(SilcServer server, /* Get channels and channel users in global list */ if (server->server_type != SILC_SERVER) silc_server_announce_get_channels(server, server->global_list, - &channels, &channel_users, + &channels, &channel_modes, + &channel_users, &channel_users_modes, &channel_users_modes_c, &channel_topics, @@ -3746,6 +3786,28 @@ void silc_server_announce_channels(SilcServer server, silc_buffer_free(channels); } + if (channel_modes) { + int i; + + for (i = 0; i < channel_users_modes_c; i++) { + if (!channel_modes[i]) + continue; + silc_buffer_push(channel_modes[i], + channel_modes[i]->data - + channel_modes[i]->head); + SILC_LOG_HEXDUMP(("channel modes"), channel_modes[i]->data, + channel_modes[i]->len); + silc_server_packet_send_dest(server, remote, + SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST, + channel_ids[i], SILC_ID_CHANNEL, + channel_modes[i]->data, + channel_modes[i]->len, + FALSE); + silc_buffer_free(channel_modes[i]); + } + silc_free(channel_modes); + } + if (channel_users) { silc_buffer_push(channel_users, channel_users->data - channel_users->head); SILC_LOG_HEXDUMP(("channel users"), channel_users->data, diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 404696ce..d4341f4d 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -176,11 +176,13 @@ void silc_server_announce_get_channel_topic(SilcServer server, SilcBuffer *topic); void silc_server_announce_get_channel_users(SilcServer server, SilcChannelEntry channel, + SilcBuffer *channel_modes, SilcBuffer *channel_users, SilcBuffer *channel_users_modes); void silc_server_announce_get_channels(SilcServer server, SilcIDList id_list, SilcBuffer *channels, + SilcBuffer **channel_modes, SilcBuffer *channel_users, SilcBuffer **channel_users_modes, SilcUInt32 *channel_users_modes_c, diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index d9d2319c..ea539913 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -1018,6 +1018,10 @@ bool silc_server_check_cmode_rights(SilcServer server, if (is_op && is_fo) return TRUE; + /* Founder emplies operator */ + if (is_fo) + is_op = TRUE; + /* We know that client is channel operator, check that they are not changing anything that requires channel founder rights. Rest of the modes are available automatically for channel operator. */ diff --git a/doc/draft-riikonen-silc-commands-04.nroff b/doc/draft-riikonen-silc-commands-04.nroff index 6f776301..9f3656e6 100644 --- a/doc/draft-riikonen-silc-commands-04.nroff +++ b/doc/draft-riikonen-silc-commands-04.nroff @@ -8,7 +8,7 @@ .ds RF FORMFEED[Page %] .ds CF .ds LH Internet Draft -.ds RH 15 May 2002 +.ds RH XXX .ds CH .na .hy 0 @@ -16,14 +16,14 @@ .nf Network Working Group P. Riikonen Internet-Draft -draft-riikonen-silc-commands-03.txt 15 May 2002 -Expires: 15 November 2002 +draft-riikonen-silc-commands-04.txt XXX +Expires: XXX .in 3 .ce 2 SILC Commands - + .ti 0 Status of this Memo @@ -919,7 +919,7 @@ List of all defined commands in SILC follows. Reply messages to the command: - Max Arguments: 14 + Max Arguments: 15 Arguments: (1) (2) (3) (4) (5) (6) @@ -927,6 +927,7 @@ List of all defined commands in SILC follows. (9) [] (10) [] (11) [] (12) (13) (14) + (15) [] This command replies with the channel name requested by the client, channel ID of the channel and topic of the channel @@ -940,7 +941,8 @@ List of all defined commands in SILC follows. the clients currently on the channel and their modes on the channel. The is formed by adding the ID Payloads one after the other. The is formed by adding - 32 bit MSB first order values one after the other. + 32 bit MSB first order values one after the other. The is the public key of the channel founder. Client receives the channel key in the reply message as well inside . @@ -2385,7 +2387,7 @@ Finland EMail: priikone@iki.fi -This Internet-Draft expires 15 November 2002 +This Internet-Draft expires XXX .ti 0 diff --git a/doc/draft-riikonen-silc-spec-06.nroff b/doc/draft-riikonen-silc-spec-06.nroff index e14cd826..45cd9476 100644 --- a/doc/draft-riikonen-silc-spec-06.nroff +++ b/doc/draft-riikonen-silc-spec-06.nroff @@ -8,7 +8,7 @@ .ds RF FORMFEED[Page %] .ds CF .ds LH Internet Draft -.ds RH 15 May 2002 +.ds RH XXX .ds CH .na .hy 0 @@ -16,15 +16,15 @@ .nf Network Working Group P. Riikonen Internet-Draft -draft-riikonen-silc-spec-05.txt 15 May 2002 -Expires: 15 November 2002 +draft-riikonen-silc-spec-06.txt XXX +Expires: XXX .in 3 .ce 3 Secure Internet Live Conferencing (SILC), Protocol Specification - + .ti 0 Status of this Memo @@ -1837,8 +1837,10 @@ MUST be announced. All clients are announced by compiling a list of ID Payloads into the SILC_PACKET_NEW_ID packet. All channels are announced by compiling a -list of Channel Payloads into the SILC_PACKET_NEW_CHANNEL packet. Also, -the channel users on the channels must be announced by compiling a +list of Channel Payloads into the SILC_PACKET_NEW_CHANNEL packet. +Channels' mode and founder public key and other channel mode specific +data is announced by sending SILC_NOTIFY_TYPE_CMODE_CHANGE notify list. +Also, the channel users on the channels must be announced by compiling a list of Notify Payloads with the SILC_NOTIFY_TYPE_JOIN notify type into the SILC_PACKET_NOTIFY packet. The users' modes on the channel must also be announced by compiling list of Notify Payloads with the @@ -2375,4 +2377,4 @@ Finland EMail: priikone@iki.fi -This Internet-Draft expires 15 November 2002 +This Internet-Draft expires XXX diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index ac40809f..10ca6f96 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -905,7 +905,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) } argc = silc_argument_get_arg_num(cmd->args); - if (argc < 7 || argc > 14) { + if (argc < 7 || argc > 15) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot join channel: Bad reply packet"); COMMAND_REPLY_ERROR;