From: Pekka Riikonen Date: Thu, 5 Dec 2002 21:37:28 +0000 (+0000) Subject: Fixed backup router resuming protocol bugs, especially packet X-Git-Tag: silc.client.0.9.10~1 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=dba41a02cdff7195e61b8ea22716ee8047d08f21;p=silc.git Fixed backup router resuming protocol bugs, especially packet decryption bugs which cause server crashes. --- diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index afee4c0f..cd1f4f13 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -741,6 +741,9 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server, unsigned char *data, unsigned int data_len) { + SilcUInt32 mac_len, iv_len; + unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; + /* If we are router and the packet came from router and private key has not been set for the channel then we must encrypt the packet as it was decrypted with the session key shared between us and the @@ -748,11 +751,17 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server, same channel key. */ if (server->server_type == SILC_ROUTER && sock->type == SILC_SOCKET_TYPE_ROUTER && - !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && - channel->channel_key) { - SilcUInt32 mac_len = silc_hmac_len(channel->hmac); - SilcUInt32 iv_len = silc_cipher_get_block_len(channel->channel_key); - unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; + !(channel->mode & SILC_CHANNEL_MODE_PRIVKEY) && channel->key) { + + /* 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) + return TRUE; + + mac_len = silc_hmac_len(channel->hmac); + iv_len = silc_cipher_get_block_len(channel->channel_key); if (data_len <= mac_len + iv_len) { SILC_LOG_WARNING(("Corrupted channel message, cannot relay it")); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 7c7c5294..1e4f94ad 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -2144,6 +2144,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process) SilcCipher cipher = NULL; SilcHmac hmac = NULL; SilcUInt32 sequence = 0; + bool local_is_router; int ret; if (!sock) { @@ -2265,10 +2266,20 @@ SILC_TASK_CALLBACK(silc_server_packet_process) sequence = idata->psn_receive; } - /* Process the packet. This will call the parser that will then + /* Then, process the packet. This will call the parser that will then decrypt and parse the packet. */ - ret = silc_packet_receive_process(sock, server->server_type == SILC_ROUTER ? - TRUE : FALSE, cipher, hmac, sequence, + + local_is_router = (server->server_type == SILC_ROUTER); + + /* If socket connection is our primary, we are backup and we are doing + backup resuming, we won't process the packet as being a router + (affects channel message decryption). */ + if (server->backup_router && SILC_SERVER_IS_BACKUP(sock) && + SILC_PRIMARY_ROUTE(server) == sock) + local_is_router = FALSE; + + ret = silc_packet_receive_process(sock, local_is_router, + cipher, hmac, sequence, silc_server_packet_parse, server); /* If processing failed the connection is closed. */ @@ -2406,14 +2417,14 @@ bool silc_server_packet_parse(SilcPacketParserContext *parser_context, and we want to call this processor with valid cipher. */ if (idata) ret = silc_packet_receive_process( - sock, server->server_type == SILC_ROUTER ? - TRUE : FALSE, idata->receive_key, + sock, server->server_type == SILC_ROUTER, + idata->receive_key, idata->hmac_receive, idata->psn_receive, silc_server_packet_parse, server); else ret = silc_packet_receive_process( - sock, server->server_type == SILC_ROUTER ? - TRUE : FALSE, NULL, NULL, 0, + sock, server->server_type == SILC_ROUTER, + NULL, NULL, 0, silc_server_packet_parse, server); if (!ret) { @@ -2919,7 +2930,7 @@ void silc_server_close_connection(SilcServer server, char tmp[128]; if (!server->sockets[sock->sock] && SILC_IS_DISCONNECTED(sock)) { - silc_schedule_task_add(server->schedule, 0, + silc_schedule_task_add(server->schedule, sock->sock, silc_server_close_connection_final, (void *)sock, 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); @@ -2961,7 +2972,7 @@ void silc_server_close_connection(SilcServer server, } } - silc_schedule_task_add(server->schedule, 0, + silc_schedule_task_add(server->schedule, sock->sock, silc_server_close_connection_final, (void *)sock, 0, 1, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index 88da61f8..a6cfffb6 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -1197,6 +1197,9 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) SILC_LOG_ERROR(("Error occurred during backup router resuming protcool")); } + if (server->server_shutdown) + return; + /* Remove this protocol from all server entries that has it */ if (silc_idcache_get_all(server->local_list->servers, &list)) { if (silc_idcache_list_first(list, &id_cache)) {