updartes.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 3 Feb 2002 17:21:13 +0000 (17:21 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 3 Feb 2002 17:21:13 +0000 (17:21 +0000)
17 files changed:
CHANGES
Makefile.am.pre
TODO
apps/irssi/src/fe-common/silc/module-formats.c
apps/irssi/src/fe-text/screen.h
apps/irssi/src/silc/core/client_ops.c
apps/irssi/src/silc/core/silc-channels.c
apps/irssi/src/silc/core/silc-servers.c
apps/silcd/protocol.c
includes/Makefile.am
lib/Makefile.am.pre
lib/silcclient/client_channel.c
lib/silcclient/client_ftp.c
lib/silcclient/silcapi.h
lib/silccore/silcchannel.c
lib/silccore/silcchannel.h
lib/silcutil/silclog.c

diff --git a/CHANGES b/CHANGES
index 4fdc84b06282084ac6a03cb73db92991f7c6058c..9326b222454188ceb3483ab7f2799e2ab4e217a2 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,40 @@
+Sun Feb  3 17:20:52 EET 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * 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 <priikone@silcnet.org>
 
        * Do not constantly resize the window.  A fix patch by cras.
index 575fea648be5a7c5fe28119527e5b79a349eb8d5..dad214450bcfa82ef841d36a3c6ae7306e07cd26 100644 (file)
@@ -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 a7f0353880d773f97e5d2eb23ea015b8e2c22ced..7ff7d52ac4baa8c1c491a2ffe7a66b369852f190 100644 (file)
--- 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.
index 4a8ec1288b9e82ef9eb2093ebabd5db8f1b48954..3a259fd0d6edcdee5fd98fbfd435ff10c8ad02aa 100644 (file)
@@ -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 },
index 700aba5c8d1643fc33ece2804da3cea9f43acfcb..9e6143fb1804102553c5214ccc7b9471249359d2 100644 (file)
@@ -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);
 
index 5ece98928c10e725fd1b5e8e801fdda75a62d75f..64cdf7e8be811707ca0c2c8c7cb6bd9f9c75233e 100644 (file)
@@ -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;
     }
 
index fa50947d524c06187b2fe04d821043e89d3f6ca5..054e5d4d276f070e29cd9587e2767d79f4d0ffcd 100644 (file)
@@ -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);
index ef0170b7f85992d7964d3e075df2ad99ba12c227..cb41470edfca631dffacfee201f73dd5c8f692f6 100644 (file)
@@ -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;
 
index cede19b5aa91d70b627cf6a3d19d2a8da8e57c0b..d5a287d53275d437c322328f1f6b95d31ea73fc5 100644 (file)
@@ -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;
index 256dc3b8dc495fb939f24bf4e053b1d0b2a25566..71f796e576d4e8ff25239166e34c6c07ee8fc64a 100644 (file)
@@ -28,7 +28,8 @@ include_HEADERS = \
        silcincludes.h \
        silcwin32.h \
        version.h \
-       version_internal.h
+       version_internal.h \
+       silcdefs.h
 endif
 
 EXTRA_DIST = \
index 6a256dbcfc61a363d0d4187b6baf514a123d8824..62b665df25ce48a1bda5c7554113620e7f36c995 100644 (file)
@@ -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
index 814dea43b6c03b942ea56fab22ddac58bbaf09fd..8d3431ca0c4adbc490307146bddd011705413868 100644 (file)
@@ -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;
index f86ccbd5faaae973ec4d68a2eb7aad022524c994..90642aa251d1f8fa4e9cf4ea34d59e72f3992368 100644 (file)
@@ -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
index 7bb917848aaecbcb56979466ed37ddc979c6bd79..1cb8801c9e0776cd3a10acb1c80f722c6d44e6f8 100644 (file)
@@ -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
  *
index 79419968176b334d0a64a13c514d98dcff7f8ec4..6bab3c22b87409b81408c9943c6c96e5f206faec 100644 (file)
@@ -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;
index 5ad1f929309b8316cbac28c27a40eb80c4cd3eab..1db0c7b0e491fcbb911e38272c3bbb08e007bac2 100644 (file)
@@ -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
  *
index 8a358309446a0309c6c162b3ac49bfaeefdd3243..6095910a699627432ec6a8823cf288afede1eff9 100644 (file)
@@ -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);
 }