From c2b07fdc09d15d9eb661cbc8ae1bc4acd9cb4bcd Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Thu, 24 Oct 2002 10:29:25 +0000 Subject: [PATCH] Fixed memory leaks around the tree. Fixed channel key packet processing bug in backup router. Fixed channel message encryption bug in backup router during backup resuming protoocol. --- CHANGES | 13 +++++++++++++ apps/silcd/packet_receive.c | 24 +++++++++++++++++++----- apps/silcd/packet_send.c | 17 ++++++++++++++++- apps/silcd/server.c | 3 +++ apps/silcd/server.h | 5 +++++ lib/silccore/silcpacket.c | 5 ++++- 6 files changed, 60 insertions(+), 7 deletions(-) diff --git a/CHANGES b/CHANGES index 8c8a7425..c6aafe36 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,16 @@ +Thu Oct 24 12:22:35 EEST 2002 Pekka Riikonen + + * Fixed channel key packet processing bug on backup router + during backup resuming protocol. Affected file is + silcd/packet_receive.c. + + * Fixed memory leaks in server. Affected files are + silcd/server.c and silcd/packet_receive.c. + + * Fixed packet decryption problem when backup router encrypted + channel message with wrong key during backup resuming + protocol. Affected file silcd/packet_send.c. + Wed Oct 23 19:01:41 EEST 2002 Pekka Riikonen * Fixed unaligned access in lib/silccore/silcattrs.c. diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 22ebddbf..bb778149 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -131,6 +131,9 @@ void silc_server_notify(SilcServer server, */ SILC_LOG_DEBUG(("JOIN notify")); + if (channel_id) + silc_free(channel_id); + /* Get Channel ID */ tmp = silc_argument_get_arg_type(args, 2, &tmp_len); if (!tmp) @@ -303,6 +306,7 @@ void silc_server_notify(SilcServer server, } } silc_free(client_id); + silc_free(channel_id); /* Check if on channel */ if (!silc_server_client_on_channel(client, channel, NULL)) @@ -546,8 +550,8 @@ void silc_server_notify(SilcServer server, goto out; } } - silc_free(client_id); } + silc_free(client_id); if (!channel_id) { channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len, @@ -798,8 +802,8 @@ void silc_server_notify(SilcServer server, goto out; } } - silc_free(client_id); } + silc_free(client_id); if (!channel_id) { channel_id = silc_id_str2id(packet->dst_id, packet->dst_id_len, @@ -2089,7 +2093,7 @@ void silc_server_channel_key(SilcServer server, SilcChannelEntry channel; if (packet->src_id_type != SILC_ID_SERVER || - (server->server_type == SILC_ROUTER && + (server->server_type == SILC_ROUTER && !server->backup_router && sock->type == SILC_SOCKET_TYPE_ROUTER)) return; @@ -2904,8 +2908,11 @@ void silc_server_new_channel(SilcServer server, channel = silc_idlist_add_channel(server->global_list, strdup(channel_name), 0, channel_id, sock->user_data, NULL, NULL, 0); - if (!channel) + if (!channel) { + silc_channel_payload_free(payload); + silc_free(channel_id); return; + } channel->disabled = TRUE; /* Disabled until someone JOINs */ server->stat.channels++; @@ -2944,6 +2951,7 @@ void silc_server_new_channel(SilcServer server, if (silc_id_create_channel_id(server, server->id, server->rng, &tmp)) { silc_server_send_notify_channel_change(server, sock, FALSE, channel_id, tmp); + silc_channel_payload_free(payload); silc_free(channel_id); silc_free(tmp); } @@ -2984,6 +2992,7 @@ void silc_server_new_channel(SilcServer server, silc_server_packet_send(server, sock, SILC_PACKET_CHANNEL_KEY, 0, chk->data, chk->len, FALSE); silc_buffer_free(chk); + silc_free(id); } else { /* 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. @@ -2998,6 +3007,8 @@ void silc_server_new_channel(SilcServer server, SILC_LOG_DEBUG(("Forcing the server to change Channel ID")); silc_server_send_notify_channel_change(server, sock, FALSE, channel_id, channel->id); + silc_channel_payload_free(payload); + silc_free(channel_id); /* Wait that server re-announces this channel */ return; @@ -3025,8 +3036,11 @@ void silc_server_new_channel(SilcServer server, if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) { if (silc_hash_table_count(channel->user_list)) { - if (!silc_server_create_channel_key(server, channel, 0)) + if (!silc_server_create_channel_key(server, channel, 0)) { + silc_channel_payload_free(payload); + silc_free(channel_id); return; + } /* Send to the channel */ silc_server_send_channel_key(server, sock, channel, FALSE); diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index e51506ac..49d12c7b 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -168,7 +168,8 @@ void silc_server_packet_send_dest(SilcServer server, return; } - SILC_LOG_DEBUG(("Sending %s packet", silc_get_packet_name(type))); + SILC_LOG_DEBUG(("Sending %s packet (forced=%s)", + silc_get_packet_name(type), force_send ? "yes" : "no")); if (dst_id) { dst_id_data = silc_id_id2str(dst_id, dst_id_type); @@ -882,6 +883,20 @@ void silc_server_packet_relay_to_channel(SilcServer server, continue; gone = TRUE; + /* If we are backup router and remote is our primary router and + we are currently doing backup resuming protocol we must not + re-encrypt message with session key. */ + if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) && + SILC_PRIMARY_ROUTE(server) == sock) { + silc_server_packet_send_to_channel_real(server, sock, &packetdata, + idata->send_key, + idata->hmac_send, + idata->psn_send++, + data, data_len, TRUE, + force_send); + continue; + } + SILC_LOG_DEBUG(("Remote is router, encrypt with session key")); /* If private key mode is not set then decrypt the packet diff --git a/apps/silcd/server.c b/apps/silcd/server.c index c1987df3..b1d06032 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -4410,6 +4410,9 @@ void silc_server_announce_get_channels(SilcServer server, silc_server_announce_get_channel_topic(server, channel, &(*channel_topics)[i]); (*channel_users_modes_c)++; + + silc_free(cid); + i++; } diff --git a/apps/silcd/server.h b/apps/silcd/server.h index e01f27b7..f7520b79 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -115,6 +115,11 @@ do { \ (sock->protocol && sock->protocol->protocol && \ sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY) +/* Check whether backup resuming protocol is active */ +#define SILC_SERVER_IS_BACKUP(sock) \ + (sock->protocol && sock->protocol->protocol && \ + sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP) + /* Output an error message wether to stderr or LOG_ERROR if we are in the background. */ #define SILC_SERVER_LOG_ERROR(fmt) silc_server_stderr(silc_format fmt) diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index b2fad174..fa3b9cdb 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -389,12 +389,15 @@ bool silc_packet_receive_process(SilcSocketConnection sock, if (silc_packet_decrypt(cipher, hmac, parse_ctx->packet->sequence, parse_ctx->packet->buffer, parse_ctx->normal) == -1) { - SILC_LOG_WARNING(("Packet decryption failed %s:%d [%s]", + SILC_LOG_WARNING(("Packet decryption failed %s:%d [%s] [%s]", sock->hostname, sock->port, + silc_get_packet_name(parse_ctx->packet->type), (sock->type == SILC_SOCKET_TYPE_UNKNOWN ? "Unknown" : sock->type == SILC_SOCKET_TYPE_CLIENT ? "Client" : sock->type == SILC_SOCKET_TYPE_SERVER ? "Server" : "Router"))); + silc_packet_context_free(parse_ctx->packet); + silc_free(parse_ctx); return FALSE; } -- 2.24.0