updates.
authorPekka Riikonen <priikone@silcnet.org>
Sun, 14 Apr 2002 17:49:26 +0000 (17:49 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Sun, 14 Apr 2002 17:49:26 +0000 (17:49 +0000)
14 files changed:
CHANGES
TODO
TODO-1.0
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/serverconfig.c
apps/silcd/serverconfig.h
doc/draft-riikonen-silc-commands-03.nroff
doc/draft-riikonen-silc-spec-05.nroff
doc/example_silcd.conf.in
lib/silcclient/client_resume.c
lib/silcclient/command.c
lib/silccore/silcauth.c

diff --git a/CHANGES b/CHANGES
index 089a3c93384d5dbef6efb2616e8c637d552091b2..2054572c01c98977f930758e0c8b965af5159a8d 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+Sat Apr 13 13:09:24 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added detach_disabled and detach_timeout server config
+         options to the server.  Affected files silcd/serverconfig.[ch],
+         silcd/command.c and silcd/packet_receive.c.
+
 Fri Apr 12 20:09:08 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
 
          Added resolve_cmd_ident field to the SilcClientEntry structure
diff --git a/TODO b/TODO
index afa8ad7445eb2783a697ae0979c0098f038b241b..b5037a6f98d5bc2bc3056c97df74696892e82c76 100644 (file)
--- a/TODO
+++ b/TODO
@@ -102,10 +102,6 @@ Manual (Do these to 0.9 and 1.0).
 TODO in SILC Protocol
 =====================
 
-Current protocol version is 1.0.  However, it is far from being perfect,
-and needs to include additional features.  Following protocol TODO entries
-describe new stuff to be added to protocol versions 1.x.
-
  2. Define that WHOIS and IDENTIFY commands must send list of errors
     if multiple Client ID (or Channel ID and Server ID for IDENTIFY) was
     requested and was not found.  Each unfound entry must cause an error
@@ -129,17 +125,3 @@ describe new stuff to be added to protocol versions 1.x.
  20. Services support?
 
  21. Subscription/IRC's notify kind support?
-
- o Inviting and banning by public key should be made possible.  To be
-   included in protocol version 1.2.
-
- o UTF-8 support/requirement for nicknames & channel names.  UTF-8 support
-   in terminals and OS's are so hazy that this matter is left for
-   consideration in next version of the protocol (1.2).  For good UTF-8
-   reference and tutorial see: http://www.cl.cam.ac.uk/~mgk25/unicode.html.
-   What should CLI application do if it receives nickname that it cannot
-   display without messing up the terminal?  If UTF-8 is mandatory in
-   SILC then SILC clients cannot be allowed to start on terminals that do
-   not support UTF-8 (which renders 98% of users unable to use CLI SILC
-   app without hacking their environment).  See also site
-   http://gratrix.net/unicode/
index 1dfbaf494ecf55786e56d21fe4e10a9d55d18f20..731ab4b9a3d9475d4e62628316eb01928f2edc8f 100644 (file)
--- a/TODO-1.0
+++ b/TODO-1.0
@@ -154,3 +154,21 @@ least could be done.
          and debugging is to be disabled on EPOC.
 
  o Check whether we can fully comply with RFC 2779.
+
+
+TODO in SILC Protocol
+=====================
+
+ o Inviting and banning by public key should be made possible.  To be
+   included in protocol version 1.2.
+
+ o UTF-8 support/requirement for nicknames & channel names.  UTF-8 support
+   in terminals and OS's are so hazy that this matter is left for
+   consideration in next version of the protocol (1.2).  For good UTF-8
+   reference and tutorial see: http://www.cl.cam.ac.uk/~mgk25/unicode.html.
+   What should CLI application do if it receives nickname that it cannot
+   display without messing up the terminal?  If UTF-8 is mandatory in 
+   SILC then SILC clients cannot be allowed to start on terminals that do
+   not support UTF-8 (which renders 98% of users unable to use CLI SILC
+   app without hacking their environment).  See also site
+   http://gratrix.net/unicode/
index ee6aa9ba50206fe2c6fdc693297f9a4cc2d5da5b..f49b6b44f41eae31ab4dbb1579543074789b37f6 100644 (file)
@@ -533,10 +533,11 @@ silc_server_command_whois_parse(SilcServerCommandContext cmd,
 
   /* Get the max count of reply messages allowed */
   tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
-  if (tmp)
-    *count = atoi(tmp);
-  else
+  if (tmp) {
+    SILC_GET32_MSB(*count, tmp);
+  } else {
     *count = 0;
+  }
 
   return TRUE;
 }
@@ -1033,10 +1034,11 @@ silc_server_command_whowas_parse(SilcServerCommandContext cmd,
 
   /* Get the max count of reply messages allowed */
   tmp = silc_argument_get_arg_type(cmd->args, 2, NULL);
-  if (tmp)
-    *count = atoi(tmp);
-  else
+  if (tmp) {
+    SILC_GET32_MSB(*count, tmp);
+  } else {
     *count = 0;
+  }
 
   return TRUE;
 }
@@ -1587,10 +1589,11 @@ silc_server_command_identify_parse(SilcServerCommandContext cmd,
   
   /* Get the max count of reply messages allowed */
   tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
-  if (tmp)
-    *count = atoi(tmp);
-  else
+  if (tmp) {
+    SILC_GET32_MSB(*count, tmp);
+  } else {
     *count = 0;
+  }
 
   return 1;
 }
index afdc1a622ecb6bb0111bf3adb6dd6ada4be16ba5..6a6ab5b3acee7131be7647991a3a6dff6f87eda8 100644 (file)
@@ -2971,14 +2971,16 @@ void silc_server_resume_client(SilcServer server,
        silc_server_command_pending(server, SILC_COMMAND_WHOIS,
                                    server->cmd_ident,
                                    silc_server_command_resume_resolve, r);
-      } else {
+       return;
+      }
+      if (server->server_type == SILC_SERVER) {
        SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, "
                        "closing connection", sock->hostname, sock->ip));
        silc_server_disconnect_remote(server, sock, 
                                      "Server closed connection: "
                                      "Incomplete resume information");
+       return;
       }
-      return;
     }
 
     /* Check that we have the public key of the client, if not then we must
@@ -3016,6 +3018,14 @@ void silc_server_resume_client(SilcServer server,
        silc_buffer_free(idp);
       }
       return;
+    } else if (!silc_pkcs_public_key_compare(detached_client->data.public_key,
+                                            idata->public_key)) {
+      /* We require that the connection and resuming authentication data
+        must be using same key pair. */
+      silc_server_disconnect_remote(server, sock, 
+                                   "Server closed connection: "
+                                   "Incomplete resume information");
+      return;
     }
 
     /* Verify the authentication payload.  This has to be successful in
@@ -3033,6 +3043,7 @@ void silc_server_resume_client(SilcServer server,
 
     /* Now resume the client to the network */
 
+    silc_schedule_task_del_by_context(server->schedule, detached_client);
     sock->user_data = detached_client;
     detached_client->connection = sock;
 
@@ -3285,6 +3296,8 @@ void silc_server_resume_client(SilcServer server,
       silc_hash_table_list_reset(&htl);
     }
 
+    silc_schedule_task_del_by_context(server->schedule, detached_client);
+
     /* If the sender of this packet is server and we are router we need to
        broadcast this packet to other routers in the network. */
     if (!server->standalone && server->server_type == SILC_ROUTER &&
index 87de942ec0f1063da4c0d818629e9c2df32879b2..25c719e7777c01b2be7cc3e5db2b52358c4fd317 100644 (file)
@@ -2513,6 +2513,7 @@ void silc_server_free_client_data(SilcServer server,
     server->stat.cell_clients--;
   SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
   SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
+  silc_schedule_task_del_by_context(server->schedule, client);
 
   /* We will not delete the client entry right away. We will take it
      into history (for WHOWAS command) for 5 minutes */
index 4ccfe543a697ef9841fd3ee34ceab7857bc7386d..6252325bbf45f707db7633fe253980e5c8b1b742 100644 (file)
@@ -228,6 +228,12 @@ SILC_CONFIG_CALLBACK(fetch_generic)
     config->param.version_software_vendor =
       (*(char *)val ? strdup((char *) val) : NULL);
   }
+  else if (!strcmp(name, "detach_disabled")) {
+    config->detach_disabled = *(bool *)val;
+  }
+  else if (!strcmp(name, "detach_timeout")) {
+    config->detach_timeout = (SilcUInt32) *(int *)val;
+  }
   else
     return SILC_CONFIG_EINTERNAL;
 
@@ -993,6 +999,8 @@ static const SilcConfigTable table_general[] = {
   { "version_protocol",                SILC_CONFIG_ARG_STR,    fetch_generic,  NULL },
   { "version_software",                SILC_CONFIG_ARG_STR,    fetch_generic,  NULL },
   { "version_software_vendor", SILC_CONFIG_ARG_STR,    fetch_generic,  NULL },
+  { "detach_disabled",         SILC_CONFIG_ARG_TOGGLE, fetch_generic,  NULL },
+  { "detach_timeout",          SILC_CONFIG_ARG_INT,    fetch_generic,  NULL },
   { 0, 0, 0, 0 }
 };
 
index 4b3cd6a3fce8fa76cd02760cf7e5a938e4b14933..91b749d1d7859ab3a5e6d89f463474621c0be6bc 100644 (file)
@@ -158,6 +158,8 @@ typedef struct {
   SilcUInt32 key_exchange_timeout;
   SilcUInt32 conn_auth_timeout;
   SilcServerConfigConnParams param;
+  bool detach_disabled;
+  SilcUInt32 detach_timeout;
   bool logging_quick;
   long logging_flushdelay;
 
index 5f76f8e4de4aff4fb75e90e9d853ce8d42163f26..f0a8c2d29642b14962a9f2e86e38613d6ee337c3 100644 (file)
@@ -227,8 +227,9 @@ List of all defined commands in SILC follows.
    1    SILC_COMMAND_WHOIS
 
         Max Arguments:  256
-            Arguments:  (1) [<nickname>[@<server>]]  (2) [<count>]
-                        (3) [<Client ID>]            (n) [...]
+            Arguments:  (1) [<nickname>[@<server>]]   (2) [<count>]
+                        (3) [<Requested Attributes>]  (4) [<Client ID>]
+                        (n) [...]
 
         Whois command is used to query various information about specific
         user.  The user may be requested by their nickname and server name.
@@ -237,7 +238,7 @@ List of all defined commands in SILC follows.
         down the number of accepted results.  If this is not defined there
         are no limit of accepted results.  The query may also be narrowed
         down by defining the server name of the nickname.  The <count> is
-        int string format.
+        32 bit MSB first order integer.
 
         It is also possible to search the user by Client ID.  If the 
         <Client ID> is provided server MUST use it as the search value
@@ -249,7 +250,7 @@ List of all defined commands in SILC follows.
         To prevent miss-use of this command wildcards in the nickname
         or in the server name are not permitted.  It is not allowed
         to request all users on some server.  The WHOIS requests MUST 
-        be based on specific nickname request.
+        be based on explicit nickname request.
 
         The WHOIS request MUST be always sent to the router by server
         so that all users are searched.  However, the server still MUST
@@ -259,6 +260,9 @@ List of all defined commands in SILC follows.
         replies to the client until it has received the reply from its
         router.
 
+        The <Requested Attributes> is defined in [ATTRS] and can be used
+        to request various information about the client.
+
         Reply messages to the command:
 
         Max Arguments:  10
@@ -328,7 +332,7 @@ List of all defined commands in SILC follows.
         given to narrow down the number of accepted results.  If this
         is not defined there are no limit of accepted results.  The query
         may also be narrowed down by defining the server name of the 
-        nickname.  The <count> is in string format.
+        nickname.  The <count> is 32 bit MSB first order integer.
 
         To prevent miss-use of this command wildcards in the nickname
         or in the server name are not permitted.  The WHOWAS requests MUST 
@@ -380,7 +384,7 @@ List of all defined commands in SILC follows.
         The query may find multiple matching entities.  The <count> option
         may be given to narrow down the number of accepted results.  If
         this is not defined there are no limit of accepted results.  The
-        <count> is in string format.
+        <count> is 32 bit MSB first order integer.
 
         It is also possible to search the entity by its ID.  If the
         <ID Payload> is provided server must use it as the search value
index d98a3ff5fa2706ccf3554f7e2ebea76bf07c89b1..2557e8295f7a416c6dff67f376fe77a30b3781fa 100644 (file)
@@ -1058,7 +1058,7 @@ The connection authentication protocol is described in detail in [SILC3].
 3.9.1 Authentication Payload
 
 Authentication payload is used separately from the SKE and the Connection
-Authentication protocol.  It is used during the session to authenticate
+Authentication protocol.  It can be used during the session to authenticate
 with the remote.  For example, the client can authenticate itself to the
 server to become server operator.  In this case, Authentication Payload is
 used.
@@ -1113,7 +1113,9 @@ o Public Data (variable length) - This is defined only if
   the signature process, described subsequently.
 
 o Authentication Data Length (2 bytes) - Indicates the
-  length of the Authentication Data field.
+  length of the Authentication Data field.  If zero (0)
+  value is found in this field the payload MUST be 
+  discarded.
 
 o Authentication Data (variable length) - Authentication 
   method dependent authentication data.
@@ -1139,15 +1141,15 @@ The hash() and the sign() are the hash function and the public key
 cryptography function selected in the SKE protocol.  The public key
 is SILC style public key unless certificates are used.  The ID is the
 entity's ID (Client or Server ID) which is authenticating itself.  The
-ID is raw ID data.  The random bytes are non-zero random bytes of
-length between 128 and 4096 bytes, and will be included into the
-Public Data field as is.
+ID encoding is described in [SILC2].  The random bytes are non-zero
+random bytes of length between 128 and 4096 bytes, and will be included
+into the Public Data field as is.
 
 The receiver will compute the signature using the random data received
 in the payload, the ID associated to the connection and the public key
 (or certificate) received in the SKE protocol.  After computing the
-receiver MUST verify the signature.  In this case also, the entire
-payload is encrypted.
+receiver MUST verify the signature.  In case of public key authentication
+this payload is also encrypted.
 
 
 .ti 0
@@ -2155,19 +2157,19 @@ private key.  The signature is computed as defined in the section
 authentication.
 
 When server receives the SILC_PACKET_RESUME_CLIENT packet it MUST
-verify that the Client ID is valid client and that it has the
-SILC_UMODE_DETACHED mode set.  It then MUST verify the Authentication
-Payload with the detached client's public key.  If it does not have
-the public key it MUST retrieve it by sending SILC_COMMAND_GETKEY
-command to the server that has the public key from the original
-client connection.  The server MUST NOT use the public key received
-in the SKE protocol for this connection.  If the signature is valid
-the server MUST unset the SILC_UMODE_DETACHED flag, and send the
-SILC_PACKET_RESUME_CLIENT packet to its primary router.  The routers
-MUST broadcast the packet and unset the SILC_UMODE_DETACHED flag
-when the packet is received.  If the server is router server it also
-MUST send the SILC_PACKET_RESUME_CLIENT packet to the original server
-whom owned the detached client.
+do the following:  Server checks that the Client ID is valid client
+and that it has the SILC_UMODE_DETACHED mode set.  Then it verifies
+the Authentication Payload with the detached client's public key.
+If it does not have the public key it retrieves it by sending
+SILC_COMMAND_GETKEY command to the server that has the public key from
+the original client connection.  The server MUST NOT use the public
+key received in the SKE protocol for this connection.  If the
+signature is valid the server unsets the SILC_UMODE_DETACHED flag,
+and sends the SILC_PACKET_RESUME_CLIENT packet to its primary router.
+The routers MUST broadcast the packet and unset the SILC_UMODE_DETACHED
+flag when the packet is received.  If the server is router server it
+also MUST send the SILC_PACKET_RESUME_CLIENT packet to the original
+server whom owned the detached client.
 
 The servers and routers that receives the SILC_PACKET_RESUME_CLIENT
 packet MUST know whether the packet already has been received for
@@ -2186,7 +2188,7 @@ must also understand that the client may not be found behind the
 same server that it originally came from.  They must update their
 caches according this.  The server that now owns the client session
 MUST check whether the Client ID of the resumed client is based
-on the server's Server ID.  If it is not it MUST create new Client
+on the server's Server ID.  If it is not it creates a new Client
 ID and send SILC_NOTIFY_TYPE_NICK_CHANGE to the network.  It MUST
 also send the channel keys of all channels that the client is
 joined to the client since it does not have them.  Whether the
@@ -2195,7 +2197,7 @@ packet to the client.  Only after this the client is resumed back
 to the network and may start sending packets and messages.
 
 It is also possible that the server does not know about the channels
-that the client has joined.  In this case it MUST join client internally
+that the client has joined.  In this case it join the client internally
 to the channels, generate new channel keys and distribute the keys
 to the channels as described in section 4.4.
 
index 53414eb64ba7584176500f51ed0e8322ab756e0a..5a62abee6a320e9959335a7030bc3e2af07c3be1 100644 (file)
@@ -130,6 +130,15 @@ General {
        # someone joins or leaves the channel.
        #channel_rekey_secs = 3600;
 
+       # SILC session detachment disabling and limiting.  By default clients
+       # can detach their sessions from server.  If you set detach_disabled
+       # to true the DETACH command cannot be used by clients.  If you
+       # want to limit for how long the server keeps detached sessions you
+       # can set the time (minutes) in detach_timeout.  After that timeout
+       # the detached session is closed if it is not resumed.  By default
+       # sessions are persistent as long as server is running.
+       #detach_disabled = true;
+       #detach_timeout = 1440;
 };
 
 #
index d3fd7a9dd9f5260f5bc25ac40ca328b4b0b47c70..6cccf3c7cad34053f820a3c5f5e011fa0ebec803 100644 (file)
@@ -317,6 +317,9 @@ void silc_client_resume_session(SilcClient client,
     }
   }
 
+  if (!session->channel_count)
+    RESUME_CALL_COMPLETION(client, session, TRUE);
+
   /* Now, we wait for replies to come back and then continue with USERS,
      CMODE and TOPIC commands. */
 }
index 1e829efa368a0ae4b9b700d873ef7d936f854856..e021c2a422027f779c5dfaade549c362d8a7891f 100644 (file)
@@ -213,6 +213,7 @@ SILC_CLIENT_CMD_FUNC(whois)
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientConnection conn = cmd->conn;
   SilcBuffer buffer;
+  unsigned char count[4];
 
   if (!cmd->conn) {
     SILC_NOT_CONNECTED(cmd->client, cmd->conn);
@@ -230,17 +231,24 @@ SILC_CLIENT_CMD_FUNC(whois)
     goto out;
   }
 
-  buffer = silc_command_payload_encode(SILC_COMMAND_WHOIS,
-                                      cmd->argc - 1, ++cmd->argv,
-                                      ++cmd->argv_lens, ++cmd->argv_types,
-                                      0);
+  if (cmd->argc == 2) {
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
+                                           ++conn->cmd_ident, 1,
+                                           1, cmd->argv[1], 
+                                           cmd->argv_lens[1]);
+  } else {
+    int c = atoi(cmd->argv[2]);
+    memset(count, 0, sizeof(count));
+    SILC_PUT32_MSB(c, count);
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
+                                           ++conn->cmd_ident, 2,
+                                           1, cmd->argv[1], cmd->argv_lens[1],
+                                           2, count, sizeof(count));
+  }
   silc_client_packet_send(cmd->client, cmd->conn->sock,
                          SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
                          buffer->data, buffer->len, TRUE);
   silc_buffer_free(buffer);
-  cmd->argv--;
-  cmd->argv_lens--;
-  cmd->argv_types--;
 
   /* Notify application */
   COMMAND;
@@ -257,6 +265,7 @@ SILC_CLIENT_CMD_FUNC(whowas)
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientConnection conn = cmd->conn;
   SilcBuffer buffer;
+  unsigned char count[4];
 
   if (!cmd->conn) {
     SILC_NOT_CONNECTED(cmd->client, cmd->conn);
@@ -271,17 +280,24 @@ SILC_CLIENT_CMD_FUNC(whowas)
     goto out;
   }
 
-  buffer = silc_command_payload_encode(SILC_COMMAND_WHOWAS,
-                                      cmd->argc - 1, ++cmd->argv,
-                                      ++cmd->argv_lens, ++cmd->argv_types,
-                                      0);
+  if (cmd->argc == 2) {
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOWAS,
+                                           ++conn->cmd_ident, 1,
+                                           1, cmd->argv[1], 
+                                           cmd->argv_lens[1]);
+  } else {
+    int c = atoi(cmd->argv[2]);
+    memset(count, 0, sizeof(count));
+    SILC_PUT32_MSB(c, count);
+    buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOWAS,
+                                           ++conn->cmd_ident, 2,
+                                           1, cmd->argv[1], cmd->argv_lens[1],
+                                           2, count, sizeof(count));
+  }
   silc_client_packet_send(cmd->client, cmd->conn->sock,
                          SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
                          buffer->data, buffer->len, TRUE);
   silc_buffer_free(buffer);
-  cmd->argv--;
-  cmd->argv_lens--;
-  cmd->argv_types--;
 
   /* Notify application */
   COMMAND;
@@ -301,6 +317,7 @@ SILC_CLIENT_CMD_FUNC(identify)
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcClientConnection conn = cmd->conn;
   SilcBuffer buffer;
+  unsigned char count[4];
 
   if (!cmd->conn) {
     SILC_NOT_CONNECTED(cmd->client, cmd->conn);
@@ -310,18 +327,21 @@ SILC_CLIENT_CMD_FUNC(identify)
   if (cmd->argc < 2 || cmd->argc > 3)
     goto out;
 
-  if (cmd->argc == 2)
+  if (cmd->argc == 2) {
     buffer = silc_command_payload_encode_va(SILC_COMMAND_IDENTIFY, 
                                            ++conn->cmd_ident, 1,
                                            1, cmd->argv[1],
                                            cmd->argv_lens[1]);
-  else
+  } else {
+    int c = atoi(cmd->argv[2]);
+    memset(count, 0, sizeof(count));
+    SILC_PUT32_MSB(c, count);
     buffer = silc_command_payload_encode_va(SILC_COMMAND_IDENTIFY, 
                                            ++conn->cmd_ident, 2,
                                            1, cmd->argv[1],
                                            cmd->argv_lens[1],
-                                           4, cmd->argv[2],
-                                           cmd->argv_lens[2]);
+                                           4, count, sizeof(count));
+  }
 
   silc_client_packet_send(cmd->client, cmd->conn->sock,
                          SILC_PACKET_COMMAND, NULL, 0, NULL, NULL,
index 0ac793695fd70b1718f968815934841ca3f0ecb9..2a3f21c91f6274ee1d88a3d1dc0b764c69470706 100644 (file)
@@ -2,15 +2,15 @@
 
   silcauth.c
 
-  Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+  Author: Pekka Riikonen <priikone@silcnet.org>
 
-  Copyright (C) 2001 Pekka Riikonen
+  Copyright (C) 2001 - 2002 Pekka Riikonen
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
-  
+
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -55,7 +55,7 @@ SilcAuthPayload silc_auth_payload_parse(const unsigned char *data,
     return NULL;
 
   /* Parse the payload */
-  ret = silc_buffer_unformat(&buffer, 
+  ret = silc_buffer_unformat(&buffer,
                             SILC_STR_UI_SHORT(&newp->len),
                             SILC_STR_UI_SHORT(&newp->auth_method),
                             SILC_STR_UI16_NSTRING_ALLOC(&newp->random_data,
@@ -73,6 +73,12 @@ SilcAuthPayload silc_auth_payload_parse(const unsigned char *data,
     return NULL;
   }
 
+  /* Authentication data must be provided */
+  if (newp->auth_len < 1)  {
+    silc_auth_payload_free(newp);
+    return NULL;
+  }
+
   /* If password authentication, random data must not be set */
   if (newp->auth_method == SILC_AUTH_PASSWORD && newp->random_len) {
     silc_auth_payload_free(newp);
@@ -178,7 +184,7 @@ unsigned char *silc_auth_get_data(SilcAuthPayload payload,
    dictates. */
 
 static unsigned char *
-silc_auth_public_key_encode_data(SilcPublicKey public_key, 
+silc_auth_public_key_encode_data(SilcPublicKey public_key,
                                 const unsigned char *random,
                                 SilcUInt32 random_len, const void *id,
                                 SilcIdType type, SilcUInt32 *ret_len)
@@ -209,7 +215,7 @@ silc_auth_public_key_encode_data(SilcPublicKey public_key,
                     SILC_STR_UI_XNSTRING(id_data, id_len),
                     SILC_STR_UI_XNSTRING(pk, pk_len),
                     SILC_STR_END);
-  
+
   ret = silc_memdup(buf->data, buf->len);
   if (!ret)
     return NULL;
@@ -250,9 +256,9 @@ SilcBuffer silc_auth_public_key_auth_generate(SilcPublicKey public_key,
     random = silc_rng_global_get_rn_data(256);
   if (!random)
     return NULL;
-  
+
   /* Encode the auth data */
-  tmp = silc_auth_public_key_encode_data(public_key, random, 256, id, type, 
+  tmp = silc_auth_public_key_encode_data(public_key, random, 256, id, type,
                                         &tmp_len);
   if (!tmp)
     return NULL;
@@ -305,8 +311,8 @@ bool silc_auth_public_key_auth_verify(SilcAuthPayload payload,
   SILC_LOG_DEBUG(("Verifying authentication data"));
 
   /* Encode auth data */
-  tmp = silc_auth_public_key_encode_data(public_key, payload->random_data, 
-                                        payload->random_len, 
+  tmp = silc_auth_public_key_encode_data(public_key, payload->random_data,
+                                        payload->random_len,
                                         id, type, &tmp_len);
   if (!tmp) {
     SILC_LOG_DEBUG(("Authentication failed"));
@@ -345,7 +351,7 @@ bool silc_auth_public_key_auth_verify(SilcAuthPayload payload,
 
 bool silc_auth_public_key_auth_verify_data(const unsigned char *payload,
                                           SilcUInt32 payload_len,
-                                          SilcPublicKey public_key, 
+                                          SilcPublicKey public_key,
                                           SilcHash hash,
                                           const void *id, SilcIdType type)
 {
@@ -358,7 +364,7 @@ bool silc_auth_public_key_auth_verify_data(const unsigned char *payload,
     return FALSE;
   }
 
-  ret = silc_auth_public_key_auth_verify(auth_payload, public_key, hash, 
+  ret = silc_auth_public_key_auth_verify(auth_payload, public_key, hash,
                                         id, type);
 
   silc_auth_payload_free(auth_payload);
@@ -366,7 +372,7 @@ bool silc_auth_public_key_auth_verify_data(const unsigned char *payload,
   return ret;
 }
 
-/* Verifies the authentication data directly from the Authentication 
+/* Verifies the authentication data directly from the Authentication
    Payload. Supports all authentication methods. If the authentication
    method is passphrase based then the `auth_data' and `auth_data_len'
    are the passphrase and its length. If the method is public key
@@ -374,12 +380,12 @@ bool silc_auth_public_key_auth_verify_data(const unsigned char *payload,
    `auth_data_len' is ignored. */
 
 bool silc_auth_verify(SilcAuthPayload payload, SilcAuthMethod auth_method,
-                     const void *auth_data, SilcUInt32 auth_data_len, 
+                     const void *auth_data, SilcUInt32 auth_data_len,
                      SilcHash hash, const void *id, SilcIdType type)
 {
   SILC_LOG_DEBUG(("Verifying authentication"));
 
-  if (auth_method != payload->auth_method)
+  if (!payload || auth_method != payload->auth_method)
     return FALSE;
 
   switch (payload->auth_method) {
@@ -391,8 +397,14 @@ bool silc_auth_verify(SilcAuthPayload payload, SilcAuthMethod auth_method,
   case SILC_AUTH_PASSWORD:
     /* Passphrase based authentication. The `pkcs', `hash', `id' and `type'
        arguments are not needed. */
+
+    /* Sanity checks */
+    if ((payload->auth_len == 0) || !auth_data ||
+       payload->auth_len != auth_data_len)
+      break;
+
     if (!memcmp(payload->auth_data, auth_data, auth_data_len)) {
-      SILC_LOG_DEBUG(("Authentication successful"));
+      SILC_LOG_DEBUG(("Passphrase Authentication successful"));
       return TRUE;
     }
     break;
@@ -414,20 +426,20 @@ bool silc_auth_verify(SilcAuthPayload payload, SilcAuthMethod auth_method,
 
 /* Same as above but parses the authentication payload before verify. */
 
-bool silc_auth_verify_data(const unsigned char *payload, 
+bool silc_auth_verify_data(const unsigned char *payload,
                           SilcUInt32 payload_len,
                           SilcAuthMethod auth_method, const void *auth_data,
-                          SilcUInt32 auth_data_len, SilcHash hash, 
+                          SilcUInt32 auth_data_len, SilcHash hash,
                           const void *id, SilcIdType type)
 {
   SilcAuthPayload auth_payload;
-  int ret;
+  bool ret;
 
   auth_payload = silc_auth_payload_parse(payload, payload_len);
-  if (!auth_payload)
+  if (!auth_payload || (auth_payload->auth_len == 0))
     return FALSE;
 
-  ret = silc_auth_verify(auth_payload, auth_method, auth_data, auth_data_len, 
+  ret = silc_auth_verify(auth_payload, auth_method, auth_data, auth_data_len,
                         hash, id, type);
 
   silc_auth_payload_free(auth_payload);
@@ -450,7 +462,7 @@ struct SilcKeyAgreementPayloadStruct {
 
 /* Parses and returns an allocated Key Agreement payload. */
 
-SilcKeyAgreementPayload 
+SilcKeyAgreementPayload
 silc_key_agreement_payload_parse(const unsigned char *payload,
                                 SilcUInt32 payload_len)
 {
@@ -466,7 +478,7 @@ silc_key_agreement_payload_parse(const unsigned char *payload,
     return NULL;
 
   /* Parse the payload */
-  ret = silc_buffer_unformat(&buffer, 
+  ret = silc_buffer_unformat(&buffer,
                             SILC_STR_UI16_NSTRING_ALLOC(&newp->hostname,
                                                         &newp->hostname_len),
                             SILC_STR_UI_INT(&newp->port),