From 1e3f9fcb3a19ffd75561b4448cc1db7f75e21f41 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 18 Nov 2002 17:37:42 +0000 Subject: [PATCH] Added support for setting specific founder public key in CMODE command. --- apps/irssi/src/silc/core/client_ops.c | 8 ++- apps/irssi/src/silc/core/silc-channels.c | 7 ++ apps/irssi/src/silc/core/silc-core.c | 4 ++ apps/silcd/command.c | 86 ++++++++++++++---------- apps/silcd/packet_receive.c | 2 + lib/silcclient/client.c | 10 +++ lib/silcclient/command.c | 5 +- lib/silcclient/command_reply.c | 2 +- 8 files changed, 84 insertions(+), 40 deletions(-) diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index db9718e8..9a397ddd 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -1991,8 +1991,7 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn, verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ? (name ? strdup(name) : strdup(conn->sock->hostname)) : NULL); - verify->pk = silc_calloc(pk_len, sizeof(*verify->pk)); - memcpy(verify->pk, pk, pk_len); + verify->pk = silc_memdup(pk, pk_len); verify->pk_len = pk_len; verify->pk_type = pk_type; verify->completion = completion; @@ -2100,6 +2099,11 @@ silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn, if (completion) completion(TRUE, context); silc_free(fingerprint); + silc_free(verify->filename); + silc_free(verify->entity); + silc_free(verify->entity_name); + silc_free(verify->pk); + silc_free(verify); } } diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index cc32f507..e28768bd 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -109,6 +109,11 @@ static void sig_server_quit(SILC_SERVER_REC *server, const char *msg) silc_command_exec(server, "QUIT", msg); } +static void sig_gui_quit(SILC_SERVER_REC *server, const char *msg) +{ + silc_client_stop(silc_client); +} + /* Find Irssi channel entry by SILC channel entry */ SILC_CHANNEL_REC *silc_channel_find_entry(SILC_SERVER_REC *server, @@ -1001,6 +1006,7 @@ void silc_channels_init(void) signal_add("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); signal_add("server connected", (SIGNAL_FUNC) sig_connected); signal_add("server quit", (SIGNAL_FUNC) sig_server_quit); + signal_add("gui exit", (SIGNAL_FUNC) sig_gui_quit); command_bind_silc("part", MODULE_NAME, (SIGNAL_FUNC) command_part); command_bind_silc("me", MODULE_NAME, (SIGNAL_FUNC) command_me); @@ -1018,6 +1024,7 @@ void silc_channels_deinit(void) signal_remove("channel destroyed", (SIGNAL_FUNC) sig_channel_destroyed); signal_remove("server connected", (SIGNAL_FUNC) sig_connected); signal_remove("server quit", (SIGNAL_FUNC) sig_server_quit); + signal_remove("gui exit", (SIGNAL_FUNC) sig_gui_quit); command_unbind("part", (SIGNAL_FUNC) command_part); command_unbind("me", (SIGNAL_FUNC) command_me); diff --git a/apps/irssi/src/silc/core/silc-core.c b/apps/irssi/src/silc/core/silc-core.c index d00b483b..caf8b508 100644 --- a/apps/irssi/src/silc/core/silc-core.c +++ b/apps/irssi/src/silc/core/silc-core.c @@ -503,5 +503,9 @@ void silc_core_deinit(void) g_free(silc_client->username); g_free(silc_client->realname); + silc_free(silc_client->hostname); + silc_pkcs_free(silc_client->pkcs); + silc_pkcs_private_key_free(silc_client->private_key); + silc_pkcs_public_key_free(silc_client->public_key); silc_client_free(silc_client); } diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 42ce48a2..1a144382 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -2570,7 +2570,7 @@ SILC_SERVER_CMD_FUNC(cmode) return; } - SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 7); + SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CMODE, cmd, 1, 8); /* Get Channel ID */ tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2); @@ -2859,45 +2859,59 @@ SILC_SERVER_CMD_FUNC(cmode) if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) { if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) { - if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) { - /* Set the founder authentication */ - tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len); - if (!tmp) { - silc_server_command_send_status_reply( - cmd, SILC_COMMAND_CMODE, - SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0); - goto out; - } - - /* Verify the payload before setting the mode */ - if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY, - idata->public_key, 0, server->sha1hash, - client->id, SILC_ID_CLIENT)) { + /* Check if the founder public key was received */ + founder_key = idata->public_key; + tmp = silc_argument_get_arg_type(cmd->args, 8, &tmp_len); + if (tmp) { + if (!silc_pkcs_public_key_payload_decode(tmp, tmp_len, &founder_key)) { silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, SILC_STATUS_ERR_AUTH_FAILED, 0); goto out; } + } - /* Save the public key */ - channel->founder_key = silc_pkcs_public_key_copy(idata->public_key); - if (!channel->founder_key) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, - SILC_STATUS_ERR_AUTH_FAILED, - 0); - goto out; - } + /* Set the founder authentication */ + tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len); + if (!tmp) { + silc_server_command_send_status_reply( + cmd, SILC_COMMAND_CMODE, + SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, 0); + goto out; + } - founder_key = channel->founder_key; - fkey = silc_pkcs_public_key_payload_encode(founder_key); - if (!fkey) { - silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, - SILC_STATUS_ERR_AUTH_FAILED, - 0); - silc_pkcs_public_key_free(channel->founder_key); - channel->founder_key = NULL; - goto out; - } + /* Verify the payload before setting the mode */ + if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY, + founder_key, 0, server->sha1hash, + client->id, SILC_ID_CLIENT)) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, + SILC_STATUS_ERR_AUTH_FAILED, + 0); + goto out; + } + + /* Save the public key */ + if (channel->founder_key) + silc_pkcs_public_key_free(channel->founder_key); + if (silc_argument_get_arg_type(cmd->args, 8, NULL)) + channel->founder_key = founder_key; + else + channel->founder_key = silc_pkcs_public_key_copy(founder_key); + if (!channel->founder_key) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, + SILC_STATUS_ERR_AUTH_FAILED, + 0); + goto out; + } + + fkey = silc_pkcs_public_key_payload_encode(channel->founder_key); + if (!fkey) { + silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, + SILC_STATUS_ERR_AUTH_FAILED, + 0); + silc_pkcs_public_key_free(channel->founder_key); + channel->founder_key = NULL; + goto out; } } } else { @@ -2934,9 +2948,11 @@ SILC_SERVER_CMD_FUNC(cmode) /* Send command reply to sender */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE, - SILC_STATUS_OK, 0, ident, 2, + SILC_STATUS_OK, 0, ident, 3, 2, tmp_id, tmp_len2, - 3, tmp_mask, 4); + 3, tmp_mask, 4, + 4, fkey ? fkey->data : NULL, + fkey ? fkey->len : 0); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index b715828d..c65a6e5b 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -949,6 +949,7 @@ void silc_server_notify(SilcServer server, /* Now match the public key we have cached and public key sent. They must match. */ +#if 0 /* The key may be other than the client's in 1.2 */ if (client && client->data.public_key && !silc_pkcs_public_key_compare(channel->founder_key, client->data.public_key)) { @@ -957,6 +958,7 @@ void silc_server_notify(SilcServer server, notify_sent = TRUE; break; } +#endif if (!silc_pkcs_public_key_compare(channel->founder_key, founder_key)) { chl->mode = mode &= ~SILC_CHANNEL_UMODE_CHANFO; diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 631862a8..ec313c1a 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -88,6 +88,16 @@ void silc_client_free(SilcClient client) if (client->rng) silc_rng_free(client->rng); + silc_cipher_unregister_all(); + silc_pkcs_unregister_all(); + silc_hash_unregister_all(); + silc_hmac_unregister_all(); + + silc_hash_free(client->md5hash); + silc_hash_free(client->sha1hash); + silc_hmac_free(client->internal->md5hmac); + silc_hmac_free(client->internal->sha1hmac); + silc_cipher_free(client->internal->none_cipher); silc_free(client->internal->params); silc_free(client->internal->silc_client_version); silc_free(client->internal); diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index e36da519..ed6a49e2 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -258,6 +258,7 @@ void silc_client_command_free(SilcClientCommandContext ctx) for (i = 0; i < ctx->argc; i++) silc_free(ctx->argv[i]); + silc_free(ctx->argv); silc_free(ctx->argv_lens); silc_free(ctx->argv_types); silc_free(ctx); @@ -1544,13 +1545,13 @@ SILC_CLIENT_CMD_FUNC(cmode) that requires an argument. */ if (type && arg) { buffer = - silc_command_payload_encode_va(SILC_COMMAND_CMODE, 0, 3, + silc_command_payload_encode_va(SILC_COMMAND_CMODE, 0, 3, 1, chidp->data, chidp->len, 2, modebuf, sizeof(modebuf), type, arg, arg_len); } else { buffer = - silc_command_payload_encode_va(SILC_COMMAND_CMODE, 0, 2, + silc_command_payload_encode_va(SILC_COMMAND_CMODE, 0, 2, 1, chidp->data, chidp->len, 2, modebuf, sizeof(modebuf)); } diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 67d8f666..7d703787 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -1237,7 +1237,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(cmode) COMMAND_REPLY_ERROR; goto out; } - + /* Get channel mode */ tmp = silc_argument_get_arg_type(cmd->args, 3, NULL); if (!tmp) { -- 2.24.0