From 6102b7fda33850dc675eb711aca7dc935453dcc9 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 3 Feb 2002 17:21:13 +0000 Subject: [PATCH] updartes. --- CHANGES | 37 ++++++++++++ Makefile.am.pre | 9 +++ TODO | 23 ++++---- .../irssi/src/fe-common/silc/module-formats.c | 12 ++-- apps/irssi/src/fe-text/screen.h | 2 +- apps/irssi/src/silc/core/client_ops.c | 1 + apps/irssi/src/silc/core/silc-channels.c | 10 ++-- apps/irssi/src/silc/core/silc-servers.c | 39 ++++++++----- apps/silcd/protocol.c | 12 ++-- includes/Makefile.am | 3 +- lib/Makefile.am.pre | 7 +++ lib/silcclient/client_channel.c | 9 ++- lib/silcclient/client_ftp.c | 58 ++++++++++++------- lib/silcclient/silcapi.h | 47 ++++++++------- lib/silccore/silcchannel.c | 51 ++++++++++------ lib/silccore/silcchannel.h | 16 ++--- lib/silcutil/silclog.c | 22 ++++--- 17 files changed, 239 insertions(+), 119 deletions(-) diff --git a/CHANGES b/CHANGES index 4fdc84b0..9326b222 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,40 @@ +Sun Feb 3 17:20:52 EET 2002 Pekka Riikonen + + * Fixed the file transfer's key agreement payload to include + zero port also if the hostname is NULL because it could not + be bound. + + Call file transfer monitor callback now also if error occurs + during key agreement protocol. + + Changed the silc_client_file_send interface to return the + SilcClientFileError instead of session id. The session ID + is returned into pointer provided as argument. + + Check that the file exists locally before sending the + file transfer request at all. + + Affected file lib/silcclient/client_ftp.c, silcapi.h. + + * Added SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED file transfer + error than can occur while key agreement protocol. Affected + file lib/silcclient/silcapi.h. + + * Fixed the event_mode CMODE handler to not crash when mode + is changed and +k mode is set in the channel. Affected file + irssi/src/silc/core/silc-channels.c. + + * Fixed SILC_LOG_ERROR to give out Error and not Warning, and + SILC_LOG_WARNING to give out Warning and not Error. Affected + file lib/silcutil/silclog.c. + + * Fixed the channel message payload decryption in the function + silc_channel_message_payload_decrypt to not modify the original + buffer before it is verified that the message decrypted + correctly. Otherwise, next time it is called with correct + channel key it won't encrypt since the payload is corrupted. + Affected file lib/silccore/silcchannel.c. + Sun Feb 3 11:46:12 EET 2002 Pekka Riikonen * Do not constantly resize the window. A fix patch by cras. diff --git a/Makefile.am.pre b/Makefile.am.pre index 575fea64..dad21445 100644 --- a/Makefile.am.pre +++ b/Makefile.am.pre @@ -69,6 +69,11 @@ doc-install: $(INSTALL_DATA) $(srcdir)/INSTALL $(docdir)/ $(INSTALL_DATA) $(srcdir)/TODO $(docdir)/ +toolkit-install: + -mkdir -p $(docdir)/toolkit/ + -$(INSTALL_DATA) $(srcdir)/doc/toolkit/silc* $(docdir)/toolkit + -$(INSTALL_DATA) $(srcdir)/doc/toolkit/index* $(docdir)/toolkit + examples-install: -mkdir -p $(docdir)/examples/ $(INSTALL_DATA) $(srcdir)/doc/examples/README $(docdir)/examples/ @@ -89,5 +94,9 @@ etc-install: if SILC_DIST_CLIENT install-data-hook: install-dirs sim-install doc-install etc-install else +if SILC_DIST_TOOLKIT +install-data-hook: install-dirs generate-server-key sim-install doc-install toolkit-install examples-install etc-install +else install-data-hook: install-dirs generate-server-key sim-install doc-install examples-install etc-install endif +endif diff --git a/TODO b/TODO index a7f03538..7ff7d52a 100644 --- a/TODO +++ b/TODO @@ -30,9 +30,6 @@ TODO/bugs in Irssi SILC client TODO/bugs In SILC Client Library ================================ - o Rewrite the channel's user list thingy and cross list it to the - Client entry. - o The PRIVATE_MESSAGE_KEY packet is not handled (it is implemented though). This should be added and perhaps new client operation should be added to notify application that it was received and @@ -51,6 +48,10 @@ TODO/bugs In SILC Client Library TODO/bugs In SILC Server ======================== + o Assure that server is allowed to connect only once to router. Meaning + if server connection is established already, same connection cannot be + established again. + o If server send CUMODE_CHANGE notify (like setting founder) to router and router does not have founder on channel (founder is left or there's no founder on channel at all), the router will accept the server's @@ -58,17 +59,12 @@ TODO/bugs In SILC Server o Make the normal server save user counts with LIST command reply. + o Add hashed passwords to silcd.conf file. + o The router should check for validity of received notify packets from servers (after all buggy servers may send notify that is actually something that should have not been sent). - o Add hashed passwords to silcd.conf file. - - o Backup router related issues - - o Channel user mode changes are notified unnecessarely when - switching to backup router on router crash. - o Add a timeout to handling incoming JOIN commands. It should be enforced that JOIN command is executed only once in a second or two seconds. Now it is possible to accept n incoming JOIN commands @@ -76,6 +72,11 @@ TODO/bugs In SILC Server each JOIN command will create and distribute the new channel key to everybody on the channel. + o Backup router related issues + + o Channel user mode changes are notified unnecessarely when + switching to backup router on router crash. + o New configuration file format must be added. The following tasks relates closely to this as well and must be done at the same time when adding the new config file format: @@ -318,6 +319,8 @@ least could be done. o Add SilcAsyncOperation to utility library. Any function that takes callback as an argument must return SilcAsyncOperation. + o Add DSS support. + o Cipher optimizations (asm, that this) at least for i386 would be nice. o Add builtin SOCKS and HTTP Proxy support, well the SOCKS at least. diff --git a/apps/irssi/src/fe-common/silc/module-formats.c b/apps/irssi/src/fe-common/silc/module-formats.c index 4a8ec128..3a259fd0 100644 --- a/apps/irssi/src/fe-common/silc/module-formats.c +++ b/apps/irssi/src/fe-common/silc/module-formats.c @@ -106,12 +106,12 @@ FORMAT_REC fecommon_silc_formats[] = { { "bad_nick", "Bad nickname {hilight $0}", 1, { 0 } }, { "unknown_notify", "Unknown notify type {hilight $0}", 1, { 0 } }, { "ke_bad_version", "You are running an incompatible client version (it may be too old or too new) ", 0 }, - { "ke_unsupported_public_key", "Server does not support your public key type", 0 }, - { "ke_unknown_group", "Server does not support one of your proposed KE group", 0 }, - { "ke_unknown_cipher", "Server does not support one of your proposed cipher", 0 }, - { "ke_unknown_pkcs", "Server does not support one of your proposed PKCS", 0 }, - { "ke_unknown_hash_function", "Server does not support one of your proposed hash function", 0 }, - { "ke_unknown_hmac", "Server does not support one of your proposed HMAC", 0 }, + { "ke_unsupported_public_key", "Remote does not trust/support your public key", 0 }, + { "ke_unknown_group", "Remote does not support one of your proposed KE group", 0 }, + { "ke_unknown_cipher", "Remote does not support one of your proposed cipher", 0 }, + { "ke_unknown_pkcs", "Remote does not support one of your proposed PKCS", 0 }, + { "ke_unknown_hash_function", "Remote does not support one of your proposed hash function", 0 }, + { "ke_unknown_hmac", "Remote does not support one of your proposed HMAC", 0 }, { "ke_incorrect_signature", "Incorrect signature", 0 }, { "ke_invalid_cookie", "Invalid cookie", 0 }, { "auth_failed", "Authentication failed", 0 }, diff --git a/apps/irssi/src/fe-text/screen.h b/apps/irssi/src/fe-text/screen.h index 700aba5c..9e6143fb 100644 --- a/apps/irssi/src/fe-text/screen.h +++ b/apps/irssi/src/fe-text/screen.h @@ -29,7 +29,7 @@ #define is_big5_lox(lo) (((char)0x80<=lo)&&(lo<=(char)0xFE)) /* extended */ #define is_big5_hi(hi) (((char)0x81<=hi)&&(hi<=(char)0xFE)) #define is_big5(hi,lo) is_big5_hi(hi) && (is_big5_los(lo) || is_big5_lox(lo)) -#endif WANT_BIG5 +#endif void screen_check_resizes(void); diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 5ece9892..64cdf7e8 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -656,6 +656,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, silc_client_get_clients_by_list(client, conn, list_count, client_id_list, silc_client_join_get_users, channel_entry); + break; } diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index fa50947d..054e5d4d 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -245,7 +245,7 @@ static void event_topic(SILC_SERVER_REC *server, va_list va) char userhost[256]; SilcIdType idtype; - idtype = va_arg(va, int); + idtype = va_arg(va, SilcIdType); entry = va_arg(va, void *); topic = va_arg(va, char *); channel = va_arg(va, SilcChannelEntry); @@ -344,9 +344,11 @@ static void event_cmode(SILC_SERVER_REC *server, va_list va) channel = va_arg(va, SilcChannelEntry); mode = silc_client_chmode(modei, - channel->channel_key->cipher->name, - silc_hmac_get_name(channel->hmac)); - + channel->channel_key ? + channel->channel_key->cipher->name : "", + channel->hmac ? + silc_hmac_get_name(channel->hmac) : ""); + chanrec = silc_channel_find_entry(server, channel); if (chanrec != NULL) { g_free_not_null(chanrec->mode); diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index ef0170b7..cb41470e 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -583,6 +583,7 @@ static void command_file(const char *data, SILC_SERVER_REC *server, FtpSession ftp; char *local_ip = NULL; uint32 local_port = 0; + uint32 session_id; if (!server || !IS_SILC_SERVER(server) || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); @@ -642,22 +643,34 @@ static void command_file(const char *data, SILC_SERVER_REC *server, if (argc >= 6) local_port = atoi(argv[5]); - ftp = silc_calloc(1, sizeof(*ftp)); - ftp->session_id = + ret = silc_client_file_send(silc_client, conn, silc_client_file_monitor, server, local_ip, local_port, - client_entry, argv[2]); + client_entry, argv[2], &session_id); + if (ret == SILC_CLIENT_FILE_OK) { + ftp = silc_calloc(1, sizeof(*ftp)); + ftp->session_id = session_id; - printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, - SILCTXT_FILE_SEND, client_entry->nickname, - argv[2]); - - ftp->client_entry = client_entry; - ftp->filepath = strdup(argv[2]); - ftp->conn = conn; - ftp->send = TRUE; - silc_dlist_add(server->ftp_sessions, ftp); - server->current_session = ftp; + printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, + SILCTXT_FILE_SEND, client_entry->nickname, + argv[2]); + + ftp->client_entry = client_entry; + ftp->filepath = strdup(argv[2]); + ftp->conn = conn; + ftp->send = TRUE; + silc_dlist_add(server->ftp_sessions, ftp); + server->current_session = ftp; + } else { + if (ret == SILC_CLIENT_FILE_ALREADY_STARTED) + printformat_module("fe-common/silc", server, NULL, + MSGLEVEL_CRAP, SILCTXT_FILE_ALREADY_STARTED, + client_entry->nickname); + if (ret == SILC_CLIENT_FILE_NO_SUCH_FILE) + printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP, + SILCTXT_FILE_ERROR_NO_SUCH_FILE, + client_entry->nickname, argv[2]); + } break; diff --git a/apps/silcd/protocol.c b/apps/silcd/protocol.c index cede19b5..d5a287d5 100644 --- a/apps/silcd/protocol.c +++ b/apps/silcd/protocol.c @@ -955,8 +955,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) return; } } else { - SILC_LOG_DEBUG(("No configuration for remote connection")); - SILC_LOG_ERROR(("Remote connection not configured")); + SILC_LOG_DEBUG(("No configuration for remote client connection")); + SILC_LOG_ERROR(("Remote client connection not configured")); SILC_LOG_ERROR(("Authentication failed")); silc_free(auth_data); protocol->state = SILC_PROTOCOL_STATE_ERROR; @@ -1017,8 +1017,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) return; } } else { - SILC_LOG_DEBUG(("No configuration for remote connection")); - SILC_LOG_ERROR(("Remote connection not configured")); + SILC_LOG_DEBUG(("No configuration for remote server connection")); + SILC_LOG_ERROR(("Remote server connection not configured")); SILC_LOG_ERROR(("Authentication failed")); protocol->state = SILC_PROTOCOL_STATE_ERROR; silc_protocol_execute(protocol, server->schedule, @@ -1079,8 +1079,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth) return; } } else { - SILC_LOG_DEBUG(("No configuration for remote connection")); - SILC_LOG_ERROR(("Remote connection not configured")); + SILC_LOG_DEBUG(("No configuration for remote router connection")); + SILC_LOG_ERROR(("Remote router connection not configured")); SILC_LOG_ERROR(("Authentication failed")); silc_free(auth_data); protocol->state = SILC_PROTOCOL_STATE_ERROR; diff --git a/includes/Makefile.am b/includes/Makefile.am index 256dc3b8..71f796e5 100644 --- a/includes/Makefile.am +++ b/includes/Makefile.am @@ -28,7 +28,8 @@ include_HEADERS = \ silcincludes.h \ silcwin32.h \ version.h \ - version_internal.h + version_internal.h \ + silcdefs.h endif EXTRA_DIST = \ diff --git a/lib/Makefile.am.pre b/lib/Makefile.am.pre index 6a256dbc..62b665df 100644 --- a/lib/Makefile.am.pre +++ b/lib/Makefile.am.pre @@ -69,6 +69,13 @@ remove: -rm -rf libsilc.a -rm -rf libsilcclient.a +if SILC_DIST_TOOLKIT +install-exec-hook: + -mkdir -p $(libdir) + -$(INSTALL) libsilc.a $(libdir)/ + -$(INSTALL) libsilcclient.a $(libdir)/ +endif + if SILC_DIST_WIN32DLL # WIN32 DLL generation silc.dll: libsilc.a diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 814dea43..8d3431ca 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -241,14 +241,19 @@ void silc_client_channel_message(SilcClient client, we will use the old key in decryption. If that fails too then we cannot do more and will drop the packet. */ if (!payload) { - if (!channel->old_channel_key) + SILC_LOG_ERROR(("decr failed")); + if (!channel->old_channel_key) { + SILC_LOG_ERROR(("no old key")); goto out; + } payload = silc_channel_message_payload_parse(buffer->data, buffer->len, channel->old_channel_key, channel->old_hmac); - if (!payload) + if (!payload) { + SILC_LOG_ERROR(("old decr failed")); goto out; + } } } else if (channel->private_keys) { SilcChannelPrivateKey entry; diff --git a/lib/silcclient/client_ftp.c b/lib/silcclient/client_ftp.c index f86ccbd5..90642aa2 100644 --- a/lib/silcclient/client_ftp.c +++ b/lib/silcclient/client_ftp.c @@ -464,6 +464,14 @@ SILC_TASK_CALLBACK(silc_client_ftp_key_agreement_final) if (protocol->state == SILC_PROTOCOL_STATE_ERROR || protocol->state == SILC_PROTOCOL_STATE_FAILURE) { + /* Call monitor callback */ + if (session->monitor) + (*session->monitor)(session->client, session->conn, + SILC_CLIENT_FILE_MONITOR_ERROR, + SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED, 0, 0, + session->client_entry, session->session_id, + session->filepath, session->monitor_context); + /* Error occured during protocol */ silc_ske_free_key_material(ctx->keymat); goto out; @@ -763,38 +771,40 @@ void silc_client_ftp_session_free(SilcClientFtpSession session) indicated by the `client_entry'. This will negotiate a secret key with the remote client before actually starting the transmission of the file. The `monitor' callback will be called to monitor the - transmission of the file. - - This returns a file session ID for the file transmission. It can - be used to close the session (and abort the file transmission) by - calling the silc_client_file_close function. The session ID is - also returned in the `monitor' callback. This returns 0 if the - file indicated by the `filepath' is being transmitted to the remote - client indicated by the `client_entry', already. */ - -uint32 silc_client_file_send(SilcClient client, - SilcClientConnection conn, - SilcClientFileMonitor monitor, - void *monitor_context, - const char *local_ip, - uint32 local_port, - SilcClientEntry client_entry, - const char *filepath) + transmission of the file. */ + +SilcClientFileError +silc_client_file_send(SilcClient client, + SilcClientConnection conn, + SilcClientFileMonitor monitor, + void *monitor_context, + const char *local_ip, + uint32 local_port, + SilcClientEntry client_entry, + const char *filepath, + uint32 *session_id) { SilcClientFtpSession session; SilcBuffer keyagr, ftp; char *filename, *path; + int fd; SILC_LOG_DEBUG(("Start")); /* Check for existing session for `filepath'. */ silc_dlist_start(conn->ftp_sessions); while ((session = silc_dlist_get(conn->ftp_sessions)) != SILC_LIST_END) { - if (!strcmp(session->filepath, filepath) && + if (session->filepath && !strcmp(session->filepath, filepath) && session->client_entry == client_entry) - return 0; + return SILC_CLIENT_FILE_ALREADY_STARTED; } + /* See whether the file exists, and can be opened in generally speaking */ + fd = silc_file_open(filepath, O_RDONLY); + if (fd < 0) + return SILC_CLIENT_FILE_NO_SUCH_FILE; + silc_file_close(fd); + /* Add new session */ session = silc_calloc(1, sizeof(*session)); session->session_id = ++conn->next_session_id; @@ -836,6 +846,7 @@ uint32 silc_client_file_send(SilcClient client, SILC_LOG_DEBUG(("Could not create listener")); silc_free(session->hostname); session->hostname = NULL; + session->port = 0; } else { /* Listener ready */ session->port = silc_net_get_local_port(session->listener); @@ -861,7 +872,10 @@ uint32 silc_client_file_send(SilcClient client, silc_buffer_free(ftp); silc_free(path); - return session->session_id; + if (session_id) + *session_id = session->session_id; + + return SILC_CLIENT_FILE_OK; } /* Receives a file from a client indicated by the `client_entry'. The @@ -1021,6 +1035,10 @@ static void silc_client_ftp_resolve_cb(SilcClient client, hostname = silc_key_agreement_get_hostname(payload); port = silc_key_agreement_get_port(payload); + if (!hostname) + port = 0; + if (!port) + hostname = NULL; if (session == SILC_LIST_END || (!hostname && !port)) { /* No session found, create one and let the application know about diff --git a/lib/silcclient/silcapi.h b/lib/silcclient/silcapi.h index 7bb91784..1cb8801c 100644 --- a/lib/silcclient/silcapi.h +++ b/lib/silcclient/silcapi.h @@ -1862,6 +1862,7 @@ typedef enum { SILC_CLIENT_FILE_ALREADY_STARTED, SILC_CLIENT_FILE_NO_SUCH_FILE, SILC_CLIENT_FILE_PERMISSION_DENIED, + SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED, } SilcClientFileError; /***/ @@ -1907,14 +1908,16 @@ typedef void (*SilcClientFileMonitor)(SilcClient client, * * SYNOPSIS * - * uint32 silc_client_file_send(SilcClient client, - * SilcClientConnection conn, - * SilcClientFileMonitor monitor, - * void *monitor_context, - * const char *local_ip, - * uint32 local_port, - * SilcClientEntry client_entry, - * const char *filepath); + * SilcClientFileError + * silc_client_file_send(SilcClient client, + * SilcClientConnection conn, + * SilcClientFileMonitor monitor, + * void *monitor_context, + * const char *local_ip, + * uint32 local_port, + * SilcClientEntry client_entry, + * const char *filepath); + * uint32 *session_id); * * DESCRIPTION * @@ -1924,12 +1927,10 @@ typedef void (*SilcClientFileMonitor)(SilcClient client, * the file. The `monitor' callback will be called to monitor the * transmission of the file. * - * This returns a file session ID for the file transmission. It can - * be used to close the session (and abort the file transmission) by - * calling the silc_client_file_close function. The session ID is - * also returned in the `monitor' callback. This returns 0 if the - * file indicated by the `filepath' is being transmitted to the remote - * client indicated by the `client_entry', already. + * This returns a file session ID for the file transmission to the + * `session_id' pointer.. It can be used to close the session (and + * abort the file transmission) by calling the silc_client_file_close + * function. The session ID is also returned in the `monitor' callback. * * If the `local_ip' is provided then this will try to bind the * listener for key exchange protocol to that IP. If `local_port' is @@ -1945,14 +1946,16 @@ typedef void (*SilcClientFileMonitor)(SilcClient client, * session. * ***/ -uint32 silc_client_file_send(SilcClient client, - SilcClientConnection conn, - SilcClientFileMonitor monitor, - void *monitor_context, - const char *local_ip, - uint32 local_port, - SilcClientEntry client_entry, - const char *filepath); +SilcClientFileError +silc_client_file_send(SilcClient client, + SilcClientConnection conn, + SilcClientFileMonitor monitor, + void *monitor_context, + const char *local_ip, + uint32 local_port, + SilcClientEntry client_entry, + const char *filepath, + uint32 *session_id); /****f* silcclient/SilcClientAPI/silc_client_file_receive * diff --git a/lib/silccore/silcchannel.c b/lib/silccore/silcchannel.c index 79419968..6bab3c22 100644 --- a/lib/silccore/silcchannel.c +++ b/lib/silccore/silcchannel.c @@ -236,42 +236,59 @@ struct SilcChannelMessagePayloadStruct { unsigned char *iv; }; -/* Decrypts the channel message payload. */ - -int silc_channel_message_payload_decrypt(unsigned char *data, - size_t data_len, - SilcCipher cipher, - SilcHmac hmac) +/* Decrypts the channel message payload. First push the IV out of the + packet. The IV is used in the decryption process. Then decrypt the + message. After decyprtion, take the MAC from the decrypted packet, + compute MAC and compare the MACs. If they match, the decryption was + successful and we have the channel message ready to be displayed. */ + +bool silc_channel_message_payload_decrypt(unsigned char *data, + size_t data_len, + SilcCipher cipher, + SilcHmac hmac) { uint32 iv_len, mac_len; unsigned char *end, *mac, mac2[32]; + unsigned char *dst, iv[SILC_CIPHER_MAX_IV_SIZE]; - /* Decrypt the channel message. First push the IV out of the packet. - The IV is used in the decryption process. Then decrypt the message. - After decyprtion, take the MAC from the decrypted packet, compute MAC - and compare the MACs. If they match, the decryption was successfull - and we have the channel message ready to be displayed. */ + /* Push the IV out of the packet, and copy the IV since we do not want + to modify the original data buffer. */ end = data + data_len; - - /* Push the IV out of the packet */ iv_len = silc_cipher_get_block_len(cipher); + memcpy(iv, end - iv_len, iv_len); + + /* Allocate destination decryption buffer since we do not want to modify + the original data buffer, since we might want to call this function + many times for same payload. */ + if (hmac) + dst = silc_calloc(data_len - iv_len, sizeof(*dst)); + else + dst = data; /* Decrypt the channel message */ - silc_cipher_decrypt(cipher, data, data, data_len - iv_len, (end - iv_len)); + silc_cipher_decrypt(cipher, data, dst, data_len - iv_len, iv); - /* Take the MAC */ if (hmac) { + /* Take the MAC */ + end = dst + (data_len - iv_len); mac_len = silc_hmac_len(hmac); - mac = (end - iv_len - mac_len); + mac = (end - mac_len); /* Check the MAC of the message */ SILC_LOG_DEBUG(("Checking channel message MACs")); - silc_hmac_make(hmac, data, (data_len - iv_len - mac_len), mac2, &mac_len); + silc_hmac_make(hmac, dst, (data_len - iv_len - mac_len), mac2, &mac_len); if (memcmp(mac, mac2, mac_len)) { SILC_LOG_DEBUG(("Channel message MACs does not match")); + silc_free(dst); return FALSE; } SILC_LOG_DEBUG(("MAC is Ok")); + + /* Now copy the decrypted data into the buffer since it is verified + it decrypted correctly. */ + memcpy(data, dst, data_len - iv_len); + memset(dst, 0, data_len - iv_len); + silc_free(dst); } return TRUE; diff --git a/lib/silccore/silcchannel.h b/lib/silccore/silcchannel.h index 5ad1f929..1db0c7b0 100644 --- a/lib/silccore/silcchannel.h +++ b/lib/silccore/silcchannel.h @@ -263,10 +263,10 @@ uint32 silc_channel_get_mode(SilcChannelPayload payload); * * SYNOPSIS * - * int silc_channel_message_payload_decrypt(unsigned char *data, - * size_t data_len, - * SilcCipher cipher, - * SilcHmac hmac); + * bool silc_channel_message_payload_decrypt(unsigned char *data, + * size_t data_len, + * SilcCipher cipher, + * SilcHmac hmac); * * DESCRIPTION * @@ -285,10 +285,10 @@ uint32 silc_channel_get_mode(SilcChannelPayload payload); * not verified. * ***/ -int silc_channel_message_payload_decrypt(unsigned char *data, - size_t data_len, - SilcCipher cipher, - SilcHmac hmac); +bool silc_channel_message_payload_decrypt(unsigned char *data, + size_t data_len, + SilcCipher cipher, + SilcHmac hmac); /****f* silccore/SilcChannelAPI/silc_channel_message_payload_parse * diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index 8a358309..6095910a 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -43,8 +43,8 @@ typedef struct SilcLogStruct *SilcLog; /* These are the known logging channels */ static struct SilcLogStruct silclogs[SILC_LOG_MAX] = { {NULL, NULL, 0, "Info", SILC_LOG_INFO, NULL, NULL}, - {NULL, NULL, 0, "Error", SILC_LOG_ERROR, NULL, NULL}, {NULL, NULL, 0, "Warning", SILC_LOG_WARNING, NULL, NULL}, + {NULL, NULL, 0, "Error", SILC_LOG_ERROR, NULL, NULL}, {NULL, NULL, 0, "Fatal", SILC_LOG_FATAL, NULL, NULL}, }; @@ -344,18 +344,22 @@ void silc_log_output_debug(char *file, char *function, { if (!silc_debug) goto end; + if (silc_log_debug_string && - !silc_string_regex_match(silc_log_debug_string, file) && - !silc_string_regex_match(silc_log_debug_string, function)) + !silc_string_regex_match(silc_log_debug_string, file) && + !silc_string_regex_match(silc_log_debug_string, function)) goto end; + if (silc_log_debug_cb) { if ((*silc_log_debug_cb)(file, function, line, string, silc_log_debug_context)) goto end; } + fprintf(stderr, "%s:%d: %s\n", function, line, string); fflush(stderr); -end: + + end: silc_free(string); } @@ -371,10 +375,12 @@ void silc_log_output_hexdump(char *file, char *function, if (!silc_debug_hexdump) goto end; + if (silc_log_debug_string && - !silc_string_regex_match(silc_log_debug_string, file) && - !silc_string_regex_match(silc_log_debug_string, function)) + !silc_string_regex_match(silc_log_debug_string, file) && + !silc_string_regex_match(silc_log_debug_string, function)) goto end; + if (silc_log_hexdump_cb) { if ((*silc_log_hexdump_cb)(file, function, line, data_in, len, string, silc_log_hexdump_context)) @@ -382,7 +388,6 @@ void silc_log_output_hexdump(char *file, char *function, } fprintf(stderr, "%s:%d: %s\n", function, line, string); - silc_free(string); k = 0; pos = 0; @@ -438,9 +443,8 @@ void silc_log_output_hexdump(char *file, char *function, if (count < 16) break; } - return; -end: + end: silc_free(string); } -- 2.24.0