updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 7 May 2002 09:22:03 +0000 (09:22 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 7 May 2002 09:22:03 +0000 (09:22 +0000)
12 files changed:
CHANGES
apps/irssi/src/silc/core/silc-servers.c
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
apps/silcd/server.c
apps/silcd/server_util.c
doc/draft-riikonen-silc-commands-03.nroff
doc/draft-riikonen-silc-pp-05.nroff
doc/draft-riikonen-silc-spec-05.nroff
lib/silcclient/command.c

diff --git a/CHANGES b/CHANGES
index 688fb222cc03348e37795fea82f8591e826f3e91..11aede39025c01fee07f31b7bb585892ca7cb4c5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+Tue May  7 11:07:16 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+       * Added the founder's public key delivery to the
+         CUMODE_CHANGE notify type as well.  Updated the protocol
+         specs and the code.  Affected files are silcd/packet_send.[ch],
+         silcd/packet_receive.c and silcd/command.c.
+
 Mon May  6 19:46:12 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Added silc_pkcs_public_key_copy function into the
index ba829c82c4f96e93d331440131f0369b0d47661a..c0897f299cfe76ed5b91f8c9fc2ee605be81056d 100644 (file)
@@ -347,7 +347,7 @@ char *silc_server_get_channels(SILC_SERVER_REC *server)
 /* SYNTAX: FILE RECEIVE [<nickname>] */
 /* SYNTAX: FILE CLOSE [<nickname>] */
 /* SYNTAX: FILE */
-/* SYNTAX: JOIN <channel> [<passphrase>] [-cipher <cipher>] [-hmac <hmac>] [-founder <-pubkey|passwd>] */
+/* SYNTAX: JOIN <channel> [<passphrase>] [-cipher <cipher>] [-hmac <hmac>] [-founder] */
 /* SYNTAX: DETACH */
 /* SYNTAX: WATCH [<-add | -del> <nickname>] */
 
index 653996dccfbee45aaca632af43710daf34a1d027..be654fdb0c743c99dd903ab1e76d0ac3bf64628f 100644 (file)
@@ -3223,8 +3223,8 @@ static void silc_server_command_join_channel(SilcServer server,
                                     idata->public_key)) {
       /* Check whether the client is to become founder */
       if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
-                               channel->founder_key, 0,
-                               idata->hash, client->id, SILC_ID_CLIENT)) {
+                               channel->founder_key, 0, server->sha1hash,
+                               client->id, SILC_ID_CLIENT)) {
        umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
        founder = TRUE;
       }
@@ -3424,24 +3424,27 @@ static void silc_server_command_join_channel(SilcServer server,
       /* Distribute the channel key to all backup routers. */
       silc_server_backup_send(server, NULL, SILC_PACKET_CHANNEL_KEY, 0,
                              keyp->data, keyp->len, FALSE, TRUE);
-  }
 
-  /* If client became founder by providing correct founder auth data
-     notify the mode change to the channel. */
-  if (founder) {
-    SILC_PUT32_MSB(chl->mode, mode);
-    silc_server_send_notify_to_channel(server, NULL, channel, FALSE, 
-                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
-                                      clidp->data, clidp->len,
-                                      mode, 4, clidp->data, clidp->len);
+    /* If client became founder by providing correct founder auth data
+       notify the mode change to the channel. */
+    if (founder) {
+      SILC_PUT32_MSB(chl->mode, mode);
+      tmp = silc_pkcs_public_key_encode(channel->founder_key, &tmp_len);
+      silc_server_send_notify_to_channel(server, NULL, channel, FALSE, 
+                                        SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
+                                        clidp->data, clidp->len,
+                                        mode, 4, clidp->data, clidp->len,
+                                        tmp, tmp_len);
+      silc_free(tmp);
       
-    /* Set CUMODE notify type to network */
-    if (!server->standalone)
-      silc_server_send_notify_cumode(server, server->router->connection,
-                                    server->server_type == SILC_ROUTER ? 
-                                    TRUE : FALSE, channel,
-                                    chl->mode, client->id, SILC_ID_CLIENT,
-                                    client->id);
+      /* Set CUMODE notify type to network */
+      if (!server->standalone)
+       silc_server_send_notify_cumode(server, server->router->connection,
+                                      server->server_type == SILC_ROUTER ? 
+                                      TRUE : FALSE, channel,
+                                      chl->mode, client->id, SILC_ID_CLIENT,
+                                      client->id, channel->founder_key);
+    }
   }
 
   silc_buffer_free(reply);
@@ -4193,7 +4196,7 @@ SILC_SERVER_CMD_FUNC(cmode)
 
        /* Verify the payload before setting the mode */
        if (!silc_auth_verify_data(tmp, tmp_len, SILC_AUTH_PUBLIC_KEY, 
-                                  idata->public_key, 0, idata->hash,
+                                  idata->public_key, 0, server->sha1hash,
                                   client->id, SILC_ID_CLIENT)) {
          silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
                                                SILC_STATUS_ERR_AUTH_FAILED,
@@ -4275,6 +4278,9 @@ SILC_SERVER_CMD_FUNC(cumode)
   SilcUInt32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
   int notify = FALSE;
   SilcUInt16 ident = silc_command_get_ident(cmd->payload);
+  SilcPublicKey founder_key = NULL;
+  unsigned char *fkey = NULL;
+  SilcUInt32 fkey_len = 0;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_CUMODE, cmd, 3, 4);
 
@@ -4406,7 +4412,7 @@ SILC_SERVER_CMD_FUNC(cumode)
 
       /* Verify the authentication payload */
       if (!silc_auth_verify_data(tmp_auth, tmp_auth_len, SILC_AUTH_PUBLIC_KEY,
-                                channel->founder_key, 0, idata->hash,
+                                channel->founder_key, 0, server->sha1hash,
                                 client->id, SILC_ID_CLIENT)) {
        silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
                                              SILC_STATUS_ERR_AUTH_FAILED, 0);
@@ -4415,6 +4421,8 @@ SILC_SERVER_CMD_FUNC(cumode)
 
       sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
       notify = TRUE;
+      founder_key = channel->founder_key;
+      fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
     }
   } else {
     if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
@@ -4538,10 +4546,11 @@ SILC_SERVER_CMD_FUNC(cumode)
   /* Send notify to channel, notify only if mode was actually changed. */
   if (notify) {
     silc_server_send_notify_to_channel(server, NULL, channel, FALSE, 
-                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3,
+                                      SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
                                       idp->data, idp->len,
                                       tmp_mask, 4, 
-                                      tmp_id, tmp_len);
+                                      tmp_id, tmp_len,
+                                      fkey, fkey_len);
 
     /* Set CUMODE notify type to network */
     if (!server->standalone)
@@ -4550,7 +4559,7 @@ SILC_SERVER_CMD_FUNC(cumode)
                                     TRUE : FALSE, channel,
                                     target_mask, client->id, 
                                     SILC_ID_CLIENT,
-                                    target_client->id);
+                                    target_client->id, founder_key);
   }
 
   /* Send command reply to sender */
@@ -4568,6 +4577,7 @@ SILC_SERVER_CMD_FUNC(cumode)
   silc_buffer_free(idp);
 
  out:
+  silc_free(fkey);
   silc_server_command_free(cmd);
 }
 
index 03fcde91e8430f7cb9e16d2072bb163e618e7920..ff021166d0386dde784634d0addc0efcd4ea708e 100644 (file)
@@ -757,6 +757,7 @@ void silc_server_notify(SilcServer server,
          server->server_type == SILC_ROUTER) {
        /* Check whether this client is allowed to be channel founder on
           this channel. */
+       SilcPublicKey founder_key;
 
        /* If channel doesn't have founder auth mode then it's impossible
           that someone would be getting founder rights with CUMODE command.
@@ -784,14 +785,29 @@ void silc_server_notify(SilcServer server,
        if (!(mode & SILC_CHANNEL_UMODE_CHANFO))
          break;
 
-       /* XXX Founder not found of the channel.  Since the founder auth mode
+       /* Founder not found of the channel.  Since the founder auth mode
           is set on the channel now check whether this is the client that
-          originally set the mode. If we don't have the public key it
-          is resolved first.
+          originally set the mode. */
+
+       /* Get public key that must be present in notify */
+       tmp = silc_argument_get_arg_type(args, 4, &tmp_len);
+       if (!tmp || !silc_pkcs_public_key_decode(tmp, tmp_len,
+                                                &founder_key)) {
+         mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+         silc_server_force_cumode_change(server, sock, channel, chl, mode);
+         notify_sent = TRUE;
+         break;
+       }
+
+       /* Now match the public key we have cached and publick key sent.
+          They must match. */
        if (!silc_pkcs_public_key_compare(channel->founder_key,
-                                         client->data.public_key))
-       */
+                                         client->data.public_key)) {
+         mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+         silc_server_force_cumode_change(server, sock, channel, chl, mode);
+         notify_sent = TRUE;
+         break;
+       }
       }
 
       SILC_LOG_DEBUG(("Changing the channel user mode"));
@@ -3169,7 +3185,8 @@ void silc_server_resume_client(SilcServer server,
 
     /* Verify the authentication payload.  This has to be successful in
        order to allow the resuming */
-    if (!silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
+    if (!idata->hash ||
+       !silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
                               detached_client->data.public_key, 0,
                               idata->hash, detached_client->id, 
                               SILC_ID_CLIENT)) {
index 3836144f068571fcbc0c6316d4188e0f3acbdc22..14e46bd5cf53e9f82feae2a0191cd4b04a174cca 100644 (file)
@@ -1190,7 +1190,7 @@ void silc_server_send_notify_cmode(SilcServer server,
 
   silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
                               SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_CMODE_CHANGE,
-                              5, idp->data, idp->len,
+                              6, idp->data, idp->len,
                               mode, 4,
                               cipher, cipher ? strlen(cipher) : 0,
                               hmac, hmac ? strlen(hmac) : 0,
@@ -1211,21 +1211,27 @@ void silc_server_send_notify_cumode(SilcServer server,
                                    SilcChannelEntry channel,
                                    SilcUInt32 mode_mask,
                                    void *id, SilcIdType id_type,
-                                   SilcClientID *target)
+                                   SilcClientID *target,
+                                   SilcPublicKey founder_key)
 {
   SilcBuffer idp1, idp2;
-  unsigned char mode[4];
+  unsigned char mode[4], *key = NULL;
+  SilcUInt32 key_len = 0;
 
   idp1 = silc_id_payload_encode((void *)id, id_type);
   idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT);
   SILC_PUT32_MSB(mode_mask, mode);
+  if (founder_key)
+    key = silc_pkcs_public_key_encode(founder_key, &key_len);
 
   silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id,
                               SILC_ID_CHANNEL, 
-                              SILC_NOTIFY_TYPE_CUMODE_CHANGE, 3
+                              SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4
                               idp1->data, idp1->len,
                               mode, 4,
-                              idp2->data, idp2->len);
+                              idp2->data, idp2->len,
+                              key, key_len);
+  silc_free(key);
   silc_buffer_free(idp1);
   silc_buffer_free(idp2);
 }
index 491fc5dba8d4c3b8d18da2731073da3f779212ef..8e8ca9c92aeaba00eafc1469288cf87d3abfd0b5 100644 (file)
@@ -150,7 +150,8 @@ void silc_server_send_notify_cumode(SilcServer server,
                                    SilcChannelEntry channel,
                                    SilcUInt32 mode_mask,
                                    void *id, SilcIdType id_type,
-                                   SilcClientID *target);
+                                   SilcClientID *target,
+                                   SilcPublicKey founder_key);
 void silc_server_send_notify_signoff(SilcServer server,
                                     SilcSocketConnection sock,
                                     bool broadcast,
index beecd96a0d522c8b1d8e9187d163e2cd97e528d7..c1d097e8c3bcd8d4a7f9b759bf0ae479378a1fd0 100644 (file)
@@ -2790,7 +2790,6 @@ void silc_server_remove_from_channels(SilcServer server,
 
       silc_schedule_task_del_by_context(server->schedule, channel->rekey);
       silc_server_channel_delete(server, channel);
-      silc_buffer_free(clidp);
       continue;
     }
 
@@ -3551,7 +3550,8 @@ void silc_server_announce_get_channel_users(SilcServer server,
   SilcBuffer chidp, clidp;
   SilcBuffer tmp;
   int len;
-  unsigned char mode[4];
+  unsigned char mode[4], *fkey = NULL;
+  SilcUInt32 fkey_len = 0;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -3580,10 +3580,13 @@ void silc_server_announce_get_channel_users(SilcServer server,
 
     /* CUMODE notify for mode change on the channel */
     SILC_PUT32_MSB(chl->mode, mode);
+    if (chl->mode & SILC_CHANNEL_UMODE_CHANFO && channel->founder_key)
+      fkey = silc_pkcs_public_key_encode(channel->founder_key, &fkey_len);
     tmp = silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_CUMODE_CHANGE,
-                                            3, clidp->data, clidp->len,
+                                            4, clidp->data, clidp->len,
                                             mode, 4,
-                                            clidp->data, clidp->len);
+                                            clidp->data, clidp->len,
+                                            fkey, fkey_len);
     len = tmp->len;
     *channel_users_modes =
       silc_buffer_realloc(*channel_users_modes,
@@ -3596,7 +3599,7 @@ void silc_server_announce_get_channel_users(SilcServer server,
     silc_buffer_put(*channel_users_modes, tmp->data, tmp->len);
     silc_buffer_pull(*channel_users_modes, len);
     silc_buffer_free(tmp);
-
+    silc_free(fkey);
     silc_buffer_free(clidp);
   }
   silc_hash_table_list_reset(&htl);
index 2a7cb7a74a36de7c7b6912b76c96000ce5df82e6..4cb11f4b76d1c40b032d5dc69b40b5966443172a 100644 (file)
@@ -1208,6 +1208,9 @@ void silc_server_kill_client(SilcServer server,
 {
   SilcBuffer killed, killer;
 
+  SILC_LOG_DEBUG(("Killing client %s", 
+                 silc_id_render(remote_client->id, SILC_ID_CLIENT)));
+
   /* Send the KILL notify packets. First send it to the channel, then
      to our primary router and then directly to the client who is being
      killed right now. */
@@ -1390,9 +1393,11 @@ bool silc_server_force_cumode_change(SilcServer server,
   SilcBuffer idp1, idp2;
   unsigned char cumode[4];
 
+  SILC_LOG_DEBUG(("Start"));
+
   silc_server_send_notify_cumode(server, sock, FALSE, channel, forced_mode,
                                 server->id, SILC_ID_SERVER,
-                                chl->client->id);
+                                chl->client->id, NULL);
 
   idp1 = silc_id_payload_encode(server->id, SILC_ID_SERVER);
   idp2 = silc_id_payload_encode(chl->client->id, SILC_ID_CLIENT);
@@ -1404,4 +1409,6 @@ bool silc_server_force_cumode_change(SilcServer server,
                                     idp2->data, idp2->len);
   silc_buffer_free(idp1);
   silc_buffer_free(idp2);
+
+  return TRUE;
 }
index d4979d53242752fd706b48d8336a67507b64edf1..1db9bc3d66de1ca1dbd0fce313790cde11029a70 100644 (file)
@@ -893,7 +893,8 @@ List of all defined commands in SILC follows.
         privileges the same way as the client had given the
         SILC_COMMAND_CUMODE command to gain founder privileges.  The
         client is still able to join the channel even if the founder
-        privileges could not be gained.
+        privileges could not be gained.  The hash function used with
+        the <founder payload> MUST be sha1.
 
         The server MUST check whether the user is allowed to join to
         the requested channel.  Various modes set to the channel affect
@@ -1338,7 +1339,8 @@ List of all defined commands in SILC follows.
               used to verify the payload is the public key of the
               client sending this command.  The mode may be set only
               if the <auth payload> was verified successfully.  The
-              server also MUST save the founder's public key.
+              server also MUST save the founder's public key.  The
+              hash function used with the <auth payload> MUST be sha1.
 
               The public key of the founder is sent in the
               SILC_NOTIFY_TYPE_CMODE_CHANGE notify type so that other
index db9cbb005bdcfe79539d3da92fa5e0669d6c817e..597b95869554283d9762b42533fded1faf16a602 100644 (file)
@@ -1375,15 +1375,18 @@ UTF-8 [RFC2279] encoded.
       sent only to the clients which is joined on the channel where
       the target client is on.
 
-      Max Arguments:  3
-          Arguments:  (1) <ID Payload>  (2) <mode mask>
-                      (3) <Target Client ID>
+      Max Arguments:  4
+          Arguments:  (1) <ID Payload>        (2) <mode mask>
+                      (3) <Target Client ID>  (3) [<founder pubkey>]
 
       The <ID Payload> is the ID (usually Client ID but it can be
       Server ID as well when the router is enforcing user's mode
       change) of the entity which changed the mode.  The <mode mask>
       is the new mode mask of the channel.  The <Target Client ID>
-      is the client which mode was changed.
+      is the client which mode was changed.  The <founder pubkey>
+      is the public key of the channel founder and is sent only
+      when first setting the channel founder mode using the
+      SILC_COMMAND_CUMODE command, and when sending this notify.
 
 
 9     SILC_NOTIFY_TYPE_MOTD
index 9bcdb4a48ec7f84a1c663fe567a6a7fb6805ac3e..0e8a5ee551337c52bcf93285aa222a3db4102bd1 100644 (file)
@@ -1157,7 +1157,8 @@ the Authentication Data is computed as follows:
   Authentication Data = sign(HASH);
 
 The hash() and the sign() are the hash function and the public key
-cryptography function selected in the SKE protocol.  The public key
+cryptography function selected in the SKE protocol, unless otherwise
+stated in the context where this payload is used.  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 encoding is described in [SILC2].  The random bytes are non-zero
index b62a72fe67120e49346b83320c836d527d866b62..88f5ac40b3addbcbcfd2b7113ce30b1c9016ec2e 100644 (file)
@@ -991,18 +991,14 @@ SILC_CLIENT_CMD_FUNC(join)
     } else if (!strcasecmp(cmd->argv[i], "-hmac") && cmd->argc > i + 1) {
       hmac = cmd->argv[i + 1];
       i++;
-    } else if (!strcasecmp(cmd->argv[i], "-founder") && cmd->argc > i + 1) {
-      if (!strcasecmp(cmd->argv[i + 1], "-pubkey")) {
-       auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
-                                                 cmd->client->private_key,
-                                                 cmd->client->rng, conn->hash,
-                                                 conn->local_id,
-                                                 SILC_ID_CLIENT);
-      } else {
-       auth = silc_auth_payload_encode(SILC_AUTH_PASSWORD, NULL, 0,
-                                       cmd->argv[i + 1], 
-                                       cmd->argv_lens[i + 1]);
-      }
+    } else if (!strcasecmp(cmd->argv[i], "-founder")) {
+      auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
+                                               cmd->client->private_key,
+                                               cmd->client->rng, 
+                                               cmd->client->internal->
+                                               sha1hash,
+                                               conn->local_id,
+                                               SILC_ID_CLIENT);
       i++;
     } else {
       /* Passphrases must be UTF-8 encoded, so encode if it is not */
@@ -1416,7 +1412,8 @@ SILC_CLIENT_CMD_FUNC(cmode)
        auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
                                                  cmd->client->private_key,
                                                  cmd->client->rng, 
-                                                 conn->hash,
+                                                 cmd->client->internal->
+                                                 sha1hash,
                                                  conn->local_id,
                                                  SILC_ID_CLIENT);
        arg = auth->data;
@@ -1568,19 +1565,13 @@ SILC_CLIENT_CMD_FUNC(cumode)
       break;
     case 'f':
       if (add) {
-       if (cmd->argc == 5) {
-         if (!strcasecmp(cmd->argv[4], "-pubkey")) {
-           auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
-                                                     cmd->client->private_key,
-                                                     cmd->client->rng,
-                                                     conn->hash,
-                                                     conn->local_id,
-                                                     SILC_ID_CLIENT);
-         } else {
-           auth = silc_auth_payload_encode(SILC_AUTH_PASSWORD, NULL, 0,
-                                           cmd->argv[4], cmd->argv_lens[4]);
-         }
-       }
+       auth = silc_auth_public_key_auth_generate(cmd->client->public_key,
+                                                 cmd->client->private_key,
+                                                 cmd->client->rng,
+                                                 cmd->client->internal->
+                                                 sha1hash,
+                                                 conn->local_id,
+                                                 SILC_ID_CLIENT);
        mode |= SILC_CHANNEL_UMODE_CHANFO;
       } else {
        mode &= ~SILC_CHANNEL_UMODE_CHANFO;