From 8efe5c6b18756ea335788ebf0afdf294764f4c26 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 7 May 2002 09:22:03 +0000 Subject: [PATCH] updates. --- CHANGES | 7 +++ apps/irssi/src/silc/core/silc-servers.c | 2 +- apps/silcd/command.c | 56 +++++++++++++---------- apps/silcd/packet_receive.c | 31 ++++++++++--- apps/silcd/packet_send.c | 16 +++++-- apps/silcd/packet_send.h | 3 +- apps/silcd/server.c | 13 ++++-- apps/silcd/server_util.c | 9 +++- doc/draft-riikonen-silc-commands-03.nroff | 6 ++- doc/draft-riikonen-silc-pp-05.nroff | 11 +++-- doc/draft-riikonen-silc-spec-05.nroff | 3 +- lib/silcclient/command.c | 43 +++++++---------- 12 files changed, 124 insertions(+), 76 deletions(-) diff --git a/CHANGES b/CHANGES index 688fb222..11aede39 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,10 @@ +Tue May 7 11:07:16 EEST 2002 Pekka Riikonen + + * Added the founder's public key delivery to the + CUMODE_CHANGE notify type as well. Updated the protocol + specs and the code. Affected files are silcd/packet_send.[ch], + silcd/packet_receive.c and silcd/command.c. + Mon May 6 19:46:12 EEST 2002 Pekka Riikonen * Added silc_pkcs_public_key_copy function into the diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index ba829c82..c0897f29 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -347,7 +347,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server) /* SYNTAX: FILE RECEIVE [] */ /* SYNTAX: FILE CLOSE [] */ /* SYNTAX: FILE */ -/* SYNTAX: JOIN [] [-cipher ] [-hmac ] [-founder <-pubkey|passwd>] */ +/* SYNTAX: JOIN [] [-cipher ] [-hmac ] [-founder] */ /* SYNTAX: DETACH */ /* SYNTAX: WATCH [<-add | -del> ] */ diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 653996dc..be654fdb 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -3223,8 +3223,8 @@ static void silc_server_command_join_channel(SilcServer server, idata->public_key)) { /* Check whether the client is to become founder */ if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY, - channel->founder_key, 0, - idata->hash, client->id, SILC_ID_CLIENT)) { + channel->founder_key, 0, server->sha1hash, + client->id, SILC_ID_CLIENT)) { umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO); founder = TRUE; } @@ -3424,24 +3424,27 @@ static void silc_server_command_join_channel(SilcServer server, /* Distribute the channel key to all backup routers. */ silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0, keyp->data, keyp->len, FALSE, TRUE); - } - /* If client became founder by providing correct founder auth data - notify the mode change to the channel. */ - if (founder) { - SILC_PUT32_MSB(chl->mode, mode); - silc_server_send_notify_to_channel(server, NULL, channel, FALSE, - SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3, - clidp->data, clidp->len, - mode, 4, clidp->data, clidp->len); + /* If client became founder by providing correct founder auth data + 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); - /* Set CUMODE notify type to network */ - if (!server->standalone) - silc_server_send_notify_cumode(server, server->router->connection, - server->server_type == SILC_ROUTER ? - TRUE : FALSE, channel, - chl->mode, client->id, SILC_ID_CLIENT, - client->id); + /* Set CUMODE notify type to network */ + if (!server->standalone) + silc_server_send_notify_cumode(server, server->router->connection, + server->server_type == SILC_ROUTER ? + TRUE : FALSE, channel, + chl->mode, client->id, SILC_ID_CLIENT, + client->id, channel->founder_key); + } } silc_buffer_free(reply); @@ -4193,7 +4196,7 @@ SILC_SERVER_CMD_FUNC(cmode) /* Verify the payload before setting the mode */ if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY, - idata->public_key, 0, idata->hash, + idata->public_key, 0, server->sha1hash, client->id, SILC_ID_CLIENT)) { silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, SILC_STATUS_ERR_AUTH_FAILED, @@ -4275,6 +4278,9 @@ SILC_SERVER_CMD_FUNC(cumode) SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len; int notify = FALSE; SilcUInt16 ident = silc_command_get_ident(cmd->payload); + SilcPublicKey founder_key = NULL; + unsigned char *fkey = NULL; + SilcUInt32 fkey_len = 0; SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4); @@ -4406,7 +4412,7 @@ SILC_SERVER_CMD_FUNC(cumode) /* Verify the authentication payload */ if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY, - channel->founder_key, 0, idata->hash, + channel->founder_key, 0, server->sha1hash, client->id, SILC_ID_CLIENT)) { silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE, SILC_STATUS_ERR_AUTH_FAILED, 0); @@ -4415,6 +4421,8 @@ SILC_SERVER_CMD_FUNC(cumode) sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO; notify = TRUE; + founder_key = channel->founder_key; + fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len); } } else { if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) { @@ -4538,10 +4546,11 @@ SILC_SERVER_CMD_FUNC(cumode) /* Send notify to channel, notify only if mode was actually changed. */ if (notify) { silc_server_send_notify_to_channel(server, NULL, channel, FALSE, - SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3, + SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4, idp->data, idp->len, tmp_mask, 4, - tmp_id, tmp_len); + tmp_id, tmp_len, + fkey, fkey_len); /* Set CUMODE notify type to network */ if (!server->standalone) @@ -4550,7 +4559,7 @@ SILC_SERVER_CMD_FUNC(cumode) TRUE : FALSE, channel, target_mask, client->id, SILC_ID_CLIENT, - target_client->id); + target_client->id, founder_key); } /* Send command reply to sender */ @@ -4568,6 +4577,7 @@ SILC_SERVER_CMD_FUNC(cumode) silc_buffer_free(idp); out: + silc_free(fkey); silc_server_command_free(cmd); } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 03fcde91..ff021166 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -757,6 +757,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; /* If channel doesn't have founder auth mode then it's impossible that someone would be getting founder rights with CUMODE command. @@ -784,14 +785,29 @@ void silc_server_notify(SilcServer server, if (!(mode & SILC_CHANNEL_UMODE_CHANFO)) break; - /* XXX Founder not found of the channel. Since the founder auth mode + /* Founder not found of the channel. Since the founder auth mode is set on the channel now check whether this is the client that - originally set the mode. If we don't have the public key it - is resolved first. + originally set the mode. */ + + /* Get public key that must be present in notify */ + tmp = silc_argument_get_arg_type(args, 4, &tmp_len); + if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len, + &founder_key)) { + mode &= ~SILC_CHANNEL_UMODE_CHANFO; + silc_server_force_cumode_change(server, sock, channel, chl, mode); + notify_sent = TRUE; + break; + } + + /* Now match the public key we have cached and publick key sent. + They must match. */ if (!silc_pkcs_public_key_compare(channel->founder_key, - client->data.public_key)) - */ - + client->data.public_key)) { + mode &= ~SILC_CHANNEL_UMODE_CHANFO; + silc_server_force_cumode_change(server, sock, channel, chl, mode); + notify_sent = TRUE; + break; + } } SILC_LOG_DEBUG(("Changing the channel user mode")); @@ -3169,7 +3185,8 @@ void silc_server_resume_client(SilcServer server, /* Verify the authentication payload. This has to be successful in order to allow the resuming */ - if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY, + if (!idata->hash || + !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY, detached_client->data.public_key, 0, idata->hash, detached_client->id, SILC_ID_CLIENT)) { diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 3836144f..14e46bd5 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -1190,7 +1190,7 @@ void silc_server_send_notify_cmode(SilcServer server, silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE, - 5, idp->data, idp->len, + 6, idp->data, idp->len, mode, 4, cipher, cipher ? strlen(cipher) : 0, hmac, hmac ? strlen(hmac) : 0, @@ -1211,21 +1211,27 @@ void silc_server_send_notify_cumode(SilcServer server, SilcChannelEntry channel, SilcUInt32 mode_mask, void *id, SilcIdType id_type, - SilcClientID *target) + SilcClientID *target, + SilcPublicKey founder_key) { SilcBuffer idp1, idp2; - unsigned char mode[4]; + unsigned char mode[4], *key = NULL; + SilcUInt32 key_len = 0; idp1 = silc_id_payload_encode((void *)id, id_type); idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT); SILC_PUT32_MSB(mode_mask, mode); + if (founder_key) + key = silc_pkcs_public_key_encode(founder_key, &key_len); silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, SILC_ID_CHANNEL, - SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3, + SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4, idp1->data, idp1->len, mode, 4, - idp2->data, idp2->len); + idp2->data, idp2->len, + key, key_len); + silc_free(key); silc_buffer_free(idp1); silc_buffer_free(idp2); } diff --git a/apps/silcd/packet_send.h b/apps/silcd/packet_send.h index 491fc5db..8e8ca9c9 100644 --- a/apps/silcd/packet_send.h +++ b/apps/silcd/packet_send.h @@ -150,7 +150,8 @@ void silc_server_send_notify_cumode(SilcServer server, SilcChannelEntry channel, SilcUInt32 mode_mask, void *id, SilcIdType id_type, - SilcClientID *target); + SilcClientID *target, + SilcPublicKey founder_key); void silc_server_send_notify_signoff(SilcServer server, SilcSocketConnection sock, bool broadcast, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index beecd96a..c1d097e8 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -2790,7 +2790,6 @@ void silc_server_remove_from_channels(SilcServer server, silc_schedule_task_del_by_context(server->schedule, channel->rekey); silc_server_channel_delete(server, channel); - silc_buffer_free(clidp); continue; } @@ -3551,7 +3550,8 @@ void silc_server_announce_get_channel_users(SilcServer server, SilcBuffer chidp, clidp; SilcBuffer tmp; int len; - unsigned char mode[4]; + unsigned char mode[4], *fkey = NULL; + SilcUInt32 fkey_len = 0; SILC_LOG_DEBUG(("Start")); @@ -3580,10 +3580,13 @@ void silc_server_announce_get_channel_users(SilcServer server, /* CUMODE notify for mode change on the channel */ SILC_PUT32_MSB(chl->mode, mode); + if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key) + fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len); tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE, - 3, clidp->data, clidp->len, + 4, clidp->data, clidp->len, mode, 4, - clidp->data, clidp->len); + clidp->data, clidp->len, + fkey, fkey_len); len = tmp->len; *channel_users_modes = silc_buffer_realloc(*channel_users_modes, @@ -3596,7 +3599,7 @@ void silc_server_announce_get_channel_users(SilcServer server, silc_buffer_put(*channel_users_modes, tmp->data, tmp->len); silc_buffer_pull(*channel_users_modes, len); silc_buffer_free(tmp); - + silc_free(fkey); silc_buffer_free(clidp); } silc_hash_table_list_reset(&htl); diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 2a7cb7a7..4cb11f4b 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -1208,6 +1208,9 @@ void silc_server_kill_client(SilcServer server, { SilcBuffer killed, killer; + SILC_LOG_DEBUG(("Killing client %s", + silc_id_render(remote_client->id, SILC_ID_CLIENT))); + /* Send the KILL notify packets. First send it to the channel, then to our primary router and then directly to the client who is being killed right now. */ @@ -1390,9 +1393,11 @@ bool silc_server_force_cumode_change(SilcServer server, SilcBuffer idp1, idp2; unsigned char cumode[4]; + SILC_LOG_DEBUG(("Start")); + silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode, server->id, SILC_ID_SERVER, - chl->client->id); + chl->client->id, NULL); idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER); idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT); @@ -1404,4 +1409,6 @@ bool silc_server_force_cumode_change(SilcServer server, idp2->data, idp2->len); silc_buffer_free(idp1); silc_buffer_free(idp2); + + return TRUE; } diff --git a/doc/draft-riikonen-silc-commands-03.nroff b/doc/draft-riikonen-silc-commands-03.nroff index d4979d53..1db9bc3d 100644 --- a/doc/draft-riikonen-silc-commands-03.nroff +++ b/doc/draft-riikonen-silc-commands-03.nroff @@ -893,7 +893,8 @@ List of all defined commands in SILC follows. privileges the same way as the client had given the SILC_COMMAND_CUMODE command to gain founder privileges. The client is still able to join the channel even if the founder - privileges could not be gained. + privileges could not be gained. The hash function used with + the MUST be sha1. The server MUST check whether the user is allowed to join to the requested channel. Various modes set to the channel affect @@ -1338,7 +1339,8 @@ List of all defined commands in SILC follows. used to verify the payload is the public key of the client sending this command. The mode may be set only if the was verified successfully. The - server also MUST save the founder's public key. + server also MUST save the founder's public key. The + hash function used with the MUST be sha1. The public key of the founder is sent in the SILC_NOTIFY_TYPE_CMODE_CHANGE notify type so that other diff --git a/doc/draft-riikonen-silc-pp-05.nroff b/doc/draft-riikonen-silc-pp-05.nroff index db9cbb00..597b9586 100644 --- a/doc/draft-riikonen-silc-pp-05.nroff +++ b/doc/draft-riikonen-silc-pp-05.nroff @@ -1375,15 +1375,18 @@ UTF-8 [RFC2279] encoded. sent only to the clients which is joined on the channel where the target client is on. - Max Arguments: 3 - Arguments: (1) (2) - (3) + Max Arguments: 4 + Arguments: (1) (2) + (3) (3) [] The is the ID (usually Client ID but it can be Server ID as well when the router is enforcing user's mode change) of the entity which changed the mode. The is the new mode mask of the channel. The - is the client which mode was changed. + is the client which mode was changed. The + is the public key of the channel founder and is sent only + when first setting the channel founder mode using the + SILC_COMMAND_CUMODE command, and when sending this notify. 9 SILC_NOTIFY_TYPE_MOTD diff --git a/doc/draft-riikonen-silc-spec-05.nroff b/doc/draft-riikonen-silc-spec-05.nroff index 9bcdb4a4..0e8a5ee5 100644 --- a/doc/draft-riikonen-silc-spec-05.nroff +++ b/doc/draft-riikonen-silc-spec-05.nroff @@ -1157,7 +1157,8 @@ the Authentication Data is computed as follows: Authentication Data = sign(HASH); The hash() and the sign() are the hash function and the public key -cryptography function selected in the SKE protocol. The public key +cryptography function selected in the SKE protocol, unless otherwise +stated in the context where this payload is used. The public key is SILC style public key unless certificates are used. The ID is the entity's ID (Client or Server ID) which is authenticating itself. The ID encoding is described in [SILC2]. The random bytes are non-zero diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index b62a72fe..88f5ac40 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -991,18 +991,14 @@ SILC_CLIENT_CMD_FUNC(join) } else if (!strcasecmp(cmd->argv[i], "-hmac") && cmd->argc > i + 1) { hmac = cmd->argv[i + 1]; i++; - } else if (!strcasecmp(cmd->argv[i], "-founder") && cmd->argc > i + 1) { - if (!strcasecmp(cmd->argv[i + 1], "-pubkey")) { - auth = silc_auth_public_key_auth_generate(cmd->client->public_key, - cmd->client->private_key, - cmd->client->rng, conn->hash, - conn->local_id, - SILC_ID_CLIENT); - } else { - auth = silc_auth_payload_encode(SILC_AUTH_PASSWORD, NULL, 0, - cmd->argv[i + 1], - cmd->argv_lens[i + 1]); - } + } else if (!strcasecmp(cmd->argv[i], "-founder")) { + auth = silc_auth_public_key_auth_generate(cmd->client->public_key, + cmd->client->private_key, + cmd->client->rng, + cmd->client->internal-> + sha1hash, + conn->local_id, + SILC_ID_CLIENT); i++; } else { /* Passphrases must be UTF-8 encoded, so encode if it is not */ @@ -1416,7 +1412,8 @@ SILC_CLIENT_CMD_FUNC(cmode) auth = silc_auth_public_key_auth_generate(cmd->client->public_key, cmd->client->private_key, cmd->client->rng, - conn->hash, + cmd->client->internal-> + sha1hash, conn->local_id, SILC_ID_CLIENT); arg = auth->data; @@ -1568,19 +1565,13 @@ SILC_CLIENT_CMD_FUNC(cumode) break; case 'f': if (add) { - if (cmd->argc == 5) { - if (!strcasecmp(cmd->argv[4], "-pubkey")) { - auth = silc_auth_public_key_auth_generate(cmd->client->public_key, - cmd->client->private_key, - cmd->client->rng, - conn->hash, - conn->local_id, - SILC_ID_CLIENT); - } else { - auth = silc_auth_payload_encode(SILC_AUTH_PASSWORD, NULL, 0, - cmd->argv[4], cmd->argv_lens[4]); - } - } + auth = silc_auth_public_key_auth_generate(cmd->client->public_key, + cmd->client->private_key, + cmd->client->rng, + cmd->client->internal-> + sha1hash, + conn->local_id, + SILC_ID_CLIENT); mode |= SILC_CHANNEL_UMODE_CHANFO; } else { mode &= ~SILC_CHANNEL_UMODE_CHANFO; -- 2.24.0