updates.
authorPekka Riikonen <priikone@silcnet.org>
Tue, 9 Apr 2002 17:36:10 +0000 (17:36 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Tue, 9 Apr 2002 17:36:10 +0000 (17:36 +0000)
15 files changed:
CHANGES
TODO
apps/irssi/docs/help/in/cumode.in
apps/irssi/docs/help/in/umode.in
apps/irssi/src/silc/core/client_ops.c
apps/silcd/command.c
apps/silcd/command_reply.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/server.c
apps/silcd/server.h
doc/draft-riikonen-silc-commands-03.nroff
lib/silcclient/command.c
lib/silccore/silcmode.h
lib/silcutil/silcutil.c

diff --git a/CHANGES b/CHANGES
index 74309ce3538b962247e29e99ed3b4f6659584e75..65a89453e38becd6aa2dd263851af40180a321c7 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,24 @@
+Tue Apr  9 17:15:42 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
+
+       * Added new user modes ANONYMOUS for special anonymous servers
+         that may set the mode for client, and BLOCK_PRIVMSG which
+         client may set to block incoming private messages unless the
+         Private Message Key flag is set (using private keys to protect
+         private messages).  Updated protocol specs and code in client
+         and server and core library.  Protocol TODO #23.  Affected
+         files are lib/silccore/silcmode.h, silcd/server.[ch], 
+         irssi/src/silc/core/client_ops.c, silcd/packet_receive.c,
+         irssi/docs/help/in/umode.in, lib/silcclient/command.c.
+
+       * Added new channel user mode BLOCK_MESSAGES which the client
+         may set to itself to tell server not send channel messages.
+         Other packets such as channel key packets are still sent.
+         Protocol TODO #23.  Updated the protocol specs, client and
+         server.  Affected files are lib/silccore/silcmode.h,
+         irssi/docs/help/in/cumode.in, lib/silcclient/command.c,
+         lib/silcutil/silcutil.c, silcd/command.c, and
+         silcd/packet_send.c.
+
 Mon Apr  8 23:57:32 EEST 2002  Pekka Riikonen <priikone@silcnet.org>
 
        * Redefined the Status Payload to include now two 8 bit fields,
diff --git a/TODO b/TODO
index fba20ff25a1c5cd48bcfbdf12fb392c0f6d81536..25f39441d4899195b8aee07e0236262e96d7ba0f 100644 (file)
--- a/TODO
+++ b/TODO
@@ -132,9 +132,6 @@ describe new stuff to be added to protocol versions 1.x.
 
  22. Session detachment/resume?
 
- 23. Message blocking via user modes (which could be expanded via 
-     services, but basic blocking would be a feature)?
-
  o Inviting and banning by public key should be made possible.  To be
    included in protocol version 1.2.
 
index 9bba22f3feb98fe8c0906f0af4d5728c929a5cf0..03d249654368a891cda476045e8a6f13cffedab0 100644 (file)
@@ -31,4 +31,13 @@ are available:
         Set/unset channel operator.  Requires that 
         you are channel operator or channel founder.
 
+    b <nickname>[@<server>]
+
+        Set/unset channel message blocking.  Client
+        may set this mode only to itself.  When set
+        the server will not send channel message to
+        to the client.  This mode can be used to block
+        unwanted messages if desired.
+
+
 See also: CMODE, UMODE
index fd1102beb38b379cee16ea529ef0a16221f27627..757fcfc9cf12868c23a548daf19e0617c69570ca 100644 (file)
@@ -16,5 +16,11 @@ modes are available:
     p        Set/unset to await paging
     h        Set/unset to be hyper active
     t        Set/unset to be actually robot
+    P        Set/unset to block incoming private messages.
+             If set then only private message secured with
+             private message keys are delivered.  Other
+             private messages server automatically discards.
+             This can be used to block unwanted private
+             messages.
 
 See also: CMODE, CUMODE, AWAY
index 727079c8a63a9a61393d5c179387df4fecc17cc5..3865d702a33d6b24d40336427089fdcd900b721b 100644 (file)
@@ -900,6 +900,10 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
          strcat(buf, " hyper active");
        if (mode & SILC_UMODE_ROBOT)
          strcat(buf, " robot");
+       if (mode & SILC_UMODE_ANONYMOUS)
+         strcat(buf, " anonymous");
+       if (mode & SILC_UMODE_BLOCK_PRIVMSG)
+         strcat(buf, " blocks private messages");
 
        printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
                           SILCTXT_WHOIS_MODES, buf);
@@ -1199,6 +1203,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn,
          strcat(stat, "H");
        else if (e->mode & SILC_UMODE_ROBOT)
          strcat(stat, "R");
+       else if (e->mode & SILC_UMODE_ANONYMOUS)
+         strcat(stat, "?");
        else
          strcat(stat, "A");
        if (mode)
index 974755eb5f6d0246be151b803912861de8f2cd6b..3a0bd76fbe06d7feb456c3a180778a42b030c6a7 100644 (file)
@@ -2480,7 +2480,8 @@ SILC_SERVER_CMD_FUNC(invite)
     }
     
     /* Get route to the client */
-    dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id, &idata);
+    dest_sock = silc_server_get_client_route(server, NULL, 0, dest_id, 
+                                            &idata, NULL);
     if (!dest_sock) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_INVITE,
                                            SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
@@ -3761,6 +3762,21 @@ SILC_SERVER_CMD_FUNC(umode)
     goto out;
   }
 
+  /* Anonymous mode cannot be set by client */
+  if (mask & SILC_UMODE_ANONYMOUS) {
+    if (!(client->mode & SILC_UMODE_ANONYMOUS)) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+                                           SILC_STATUS_ERR_PERM_DENIED);
+      goto out;
+    }
+  } else {
+    if (client->mode & SILC_UMODE_ANONYMOUS) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+                                           SILC_STATUS_ERR_PERM_DENIED);
+      goto out;
+    }
+  }
+
   /* Change the mode */
   client->mode = mask;
 
@@ -4276,18 +4292,18 @@ SILC_SERVER_CMD_FUNC(cumode)
   }
 
   if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
+    if (target_client != client) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                           SILC_STATUS_ERR_NOT_YOU);
+      goto out;
+    }
+
     if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
       /* The client tries to claim the founder rights. */
       unsigned char *tmp_auth;
       SilcUInt32 tmp_auth_len, auth_len;
       void *auth;
       
-      if (target_client != client) {
-       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
-                                             SILC_STATUS_ERR_NOT_YOU);
-       goto out;
-      }
-
       if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
          !channel->founder_key || !idata->public_key ||
          !silc_pkcs_public_key_compare(channel->founder_key, 
@@ -4362,6 +4378,31 @@ SILC_SERVER_CMD_FUNC(cumode)
     }
   }
 
+  if (target_mask & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
+    if (target_client != client) {
+      silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                           SILC_STATUS_ERR_NOT_YOU);
+      goto out;
+    }
+
+    if (!(chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)) {
+      chl->mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
+      notify = TRUE;
+    }
+  } else {
+    if (chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES) {
+      if (target_client != client) {
+       silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+                                             SILC_STATUS_ERR_NOT_YOU);
+       goto out;
+      }
+
+      chl->mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
+      notify = TRUE;
+    }
+  }
+
+
   idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
   tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
 
@@ -5133,7 +5174,7 @@ SILC_SERVER_CMD_FUNC(getkey)
       SilcSocketConnection dest_sock;
       
       dest_sock = silc_server_get_client_route(server, NULL, 0, 
-                                              client_id, NULL);
+                                              client_id, NULL, NULL);
       if (!dest_sock)
        goto out;
       
index 9c8766798e5ab1849991bba87388a0665f38f396..bd4052a47e619e037e1c0c1b76e0006c54014339 100644 (file)
@@ -135,13 +135,8 @@ silc_server_command_reply_whois_save(SilcServerCommandReplyContext cmd)
   nickname = silc_argument_get_arg_type(cmd->args, 3, &len);
   username = silc_argument_get_arg_type(cmd->args, 4, &len);
   realname = silc_argument_get_arg_type(cmd->args, 5, &len);
-  if (!id_data || !nickname || !username || !realname) {
-    SILC_LOG_ERROR(("Incomplete WHOIS info: %s %s %s",
-                   nickname ? nickname : "",
-                   username ? username : "",
-                   realname ? realname : ""));
+  if (!id_data || !nickname || !username || !realname)
     return FALSE;
-  }
 
   tmp = silc_argument_get_arg_type(cmd->args, 7, &len);
   if (tmp)
index e2e98bc66ba2610164323da924698f42eae4e524..1a1be10d11fd3ceadf491f74c762d5ea2ac04cc3 100644 (file)
@@ -69,7 +69,8 @@ void silc_server_notify(SilcServer server,
 
     /* Get the route to the client */
     dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                           packet->dst_id_len, NULL, &idata);
+                                           packet->dst_id_len, NULL, 
+                                           &idata, NULL);
     if (dst_sock)
       /* Relay the packet */
       silc_server_relay_packet(server, dst_sock, idata->send_key,
@@ -1439,6 +1440,7 @@ void silc_server_private_message(SilcServer server,
 {
   SilcSocketConnection dst_sock;
   SilcIDListData idata;
+  SilcClientEntry client;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -1448,7 +1450,8 @@ void silc_server_private_message(SilcServer server,
 
   /* Get the route to the client */
   dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                         packet->dst_id_len, NULL, &idata);
+                                         packet->dst_id_len, NULL, 
+                                         &idata, &client);
   if (!dst_sock) {
     /* Send IDENTIFY command reply with error status to indicate that
        such destination ID does not exist or is invalid */
@@ -1478,6 +1481,13 @@ void silc_server_private_message(SilcServer server,
     return;
   }
 
+  /* Check whether destination client wishes to receive private messages */
+  if (client && !(packet->flags & SILC_PACKET_FLAG_PRIVMSG_KEY) &&
+      client->mode & SILC_UMODE_BLOCK_PRIVMSG) {
+    SILC_LOG_DEBUG(("Client blocks private messages, discarding packet"));
+    return;
+  }
+
   /* Send the private message */
   silc_server_send_private_message(server, dst_sock, idata->send_key,
                                   idata->hmac_send, idata->psn_send++,
@@ -1507,7 +1517,8 @@ void silc_server_private_message_key(SilcServer server,
 
   /* Get the route to the client */
   dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                         packet->dst_id_len, NULL, &idata);
+                                         packet->dst_id_len, NULL, 
+                                         &idata, NULL);
   if (!dst_sock)
     return;
 
@@ -2710,7 +2721,8 @@ void silc_server_key_agreement(SilcServer server,
 
   /* Get the route to the client */
   dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                         packet->dst_id_len, NULL, &idata);
+                                         packet->dst_id_len, NULL, 
+                                         &idata, NULL);
   if (!dst_sock)
     return;
 
@@ -2827,7 +2839,8 @@ void silc_server_ftp(SilcServer server,
 
   /* Get the route to the client */
   dst_sock = silc_server_get_client_route(server, packet->dst_id,
-                                         packet->dst_id_len, NULL, &idata);
+                                         packet->dst_id_len, NULL, 
+                                         &idata, NULL);
   if (!dst_sock)
     return;
 
index b37f1c7af79bd9a31e6acdd95a363eb1f3448bfa..ab5b6219e96f24d9c07f432b06bbbb6a4a100b31 100644 (file)
@@ -781,7 +781,8 @@ void silc_server_packet_relay_to_channel(SilcServer server,
   silc_hash_table_list(channel->user_list, &htl);
   while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
     client = chl->client;
-    if (!client || client == sender_entry)
+    if (!client || client == sender_entry || 
+       chl->mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
       continue;
 
     /* If the client has set router it means that it is not locally
index 306cb07f78f34a9fd2b619bb32fbcc5472c68fd6..eb2c0a95340812b9662662235dbaf7e4c221cfca 100644 (file)
@@ -3961,11 +3961,13 @@ void silc_server_save_users_on_channel(SilcServer server,
    could not be found to the client. If the `client_id' is specified then
    it is used and the `id_data' is ignored. */
 
-SilcSocketConnection silc_server_get_client_route(SilcServer server,
-                                                 unsigned char *id_data,
-                                                 SilcUInt32 id_len,
-                                                 SilcClientID *client_id,
-                                                 SilcIDListData *idata)
+SilcSocketConnection
+silc_server_get_client_route(SilcServer server,
+                            unsigned char *id_data,
+                            SilcUInt32 id_len,
+                            SilcClientID *client_id,
+                            SilcIDListData *idata,
+                            SilcClientEntry *client_entry)
 {
   SilcClientID *id;
   SilcClientEntry client;
@@ -3983,6 +3985,9 @@ SilcSocketConnection silc_server_get_client_route(SilcServer server,
     id = silc_id_dup(client_id, SILC_ID_CLIENT);
   }
 
+  if (client_entry)
+    *client_entry = NULL;
+
   /* If the destination belongs to our server we don't have to route
      the packet anywhere but to send it to the local destination. */
   client = silc_idlist_find_client_by_id(server->local_list, id, TRUE, NULL);
@@ -4003,6 +4008,8 @@ SilcSocketConnection silc_server_get_client_route(SilcServer server,
     /* Seems that client really is directly connected to us */
     if (idata)
       *idata = (SilcIDListData)client;
+    if (client_entry)
+      *client_entry = client;
     return client->connection;
   }
 
index 4aaa18402d8b4b766e75214f85ca164c639dbf9c..a90e7dd166a5217dc25bf029e5fd5da9c94aeebb 100644 (file)
@@ -208,11 +208,13 @@ void silc_server_save_users_on_channel(SilcServer server,
                                       SilcBuffer user_list,
                                       SilcBuffer mode_list,
                                       SilcUInt32 user_count);
-SilcSocketConnection silc_server_get_client_route(SilcServer server,
-                                                 unsigned char *id_data,
-                                                 SilcUInt32 id_len,
-                                                 SilcClientID *client_id,
-                                                 SilcIDListData *idata);
+SilcSocketConnection
+silc_server_get_client_route(SilcServer server,
+                            unsigned char *id_data,
+                            SilcUInt32 id_len,
+                            SilcClientID *client_id,
+                            SilcIDListData *idata,
+                            SilcClientEntry *client_entry);
 SilcBuffer silc_server_get_client_channel_list(SilcServer server,
                                               SilcClientEntry client);
 SilcClientEntry silc_server_get_client_resolve(SilcServer server,
index f917a612e54be0d5ebba578f78471305238e9ad6..e8bb6142e1d54f4c44686ec6650cc18f225b2b59 100644 (file)
@@ -999,8 +999,8 @@ List of all defined commands in SILC follows.
            0x00000002    SILC_UMODE_ROUTER_OPERATOR
 
               Marks the user as router (SILC) operator.  Client
-              MUST NOT this mode itself.  Router sets this mode to
-              the client when client attains the router operator
+              MUST NOT set this mode itself.  Router sets this mode
+              to the client when client attains the router operator
               privileges by SILC_COMMAND_SILCOPER command.  Client
               MAY unset the mode itself.
 
@@ -1048,6 +1048,33 @@ List of all defined commands in SILC follows.
               Client MAY set and unset this mode.
 
 
+           0x00000100    SILC_UMODE_ANONYMOUS
+
+              Marks that the client is anonymous client.  Server
+              that specificly is designed for anonymous services
+              can set and unset this mode.  Client MUST NOT set or
+              unset this mode itself.  A client with this mode set
+              would have the username and the hostname information
+              scrambled by the server which set this mode.
+
+
+           0x00000200    SILC_UMODE_BLOCK_PRIVMSG
+
+              Marks that the client wishes to block private
+              messages sent to the client, unless the Private
+              Message Key flag is set in the SILC packet header.
+              If this mode is set server MUST NOT deliver private
+              messages to the client without the Private Message
+              Key flag being set.
+
+              A separate service could provide additional filtering
+              features for accepting private messages from certain
+              sender.  However, this document does not specify such
+              service.
+
+              The client MAY set and unset this mode.
+
+
         Reply messages to the command:
 
         Max Arguments:  2
@@ -1356,7 +1383,24 @@ List of all defined commands in SILC follows.
 
               Sets channel operator privileges on the channel for a
               client on the channel.  Channel founder and channel operator
-              MAY set/unset this mode.
+              MAY set/unset this mode.  The client MAY remove this mode
+              at any time.
+
+
+           0x00000004    SILC_CUMODE_BLOCK_MESSAGES
+
+              Marks that the client wishes not to receive any channel
+              messages sent for the channel.  Client MAY set and unset
+              this mode to itself.  Client MUST NOT set it to anyone else.
+              When this mode is set server MUST NOT deliver channel
+              messages to this client.  Other packets such as channel
+              key packets are still sent to the client.
+
+              A separate service could provide additional filtering
+              features for accepting channel messages from certain
+              sender.  However, this document does not specify such
+              service.
+
 
         Reply messages to the command:
 
index 8fa6fd0e5934b6544fdb9b5da84515fd78cc1347..fa0bfa633d8414828223d9658839023c45cb11a4 100644 (file)
@@ -1173,6 +1173,12 @@ SILC_CLIENT_CMD_FUNC(umode)
       else
        mode &= ~SILC_UMODE_ROBOT;
       break;
+    case 'P':
+      if (add)
+       mode |= SILC_UMODE_BLOCK_PRIVMSG;
+      else
+       mode &= ~SILC_UMODE_BLOCK_PRIVMSG;
+      break;
     default:
       COMMAND_ERROR;
       goto out;
@@ -1538,6 +1544,7 @@ SILC_CLIENT_CMD_FUNC(cumode)
       if (add) {
        mode |= SILC_CHANNEL_UMODE_CHANFO;
        mode |= SILC_CHANNEL_UMODE_CHANOP;
+       mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
       } else {
        mode = SILC_CHANNEL_UMODE_NONE;
       }
@@ -1568,6 +1575,12 @@ SILC_CLIENT_CMD_FUNC(cumode)
       else
        mode &= ~SILC_CHANNEL_UMODE_CHANOP;
       break;
+    case 'b':
+      if (add)
+       mode |= SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
+      else
+       mode &= ~SILC_CHANNEL_UMODE_BLOCK_MESSAGES;
+      break;
     default:
       COMMAND_ERROR;
       goto out;
index 2bff5795e99225e7e88bdd50799e6e19901d1010..63b0c2da7373692fc9811133ecd128fa45a93a24 100644 (file)
  *
  * DESCRIPTION
  *
- *    All user modes on channel
+ *    All user modes on channel.  These indicate the user's status on the
+ *    channel.  Some of the modes can be set by channel founder and channel
+ *    operator.  Some modes may be set by users themself.
  *
  * SOURCE
  */
-#define SILC_CHANNEL_UMODE_NONE        0x0000 /* Normal user */
-#define SILC_CHANNEL_UMODE_CHANFO      0x0001 /* channel founder */
-#define SILC_CHANNEL_UMODE_CHANOP      0x0002 /* channel operator */
+#define SILC_CHANNEL_UMODE_NONE            0x00000000 /* Normal user */
+#define SILC_CHANNEL_UMODE_CHANFO          0x00000001 /* channel founder */
+#define SILC_CHANNEL_UMODE_CHANOP          0x00000002 /* channel operator */
+#define SILC_CHANNEL_UMODE_BLOCK_MESSAGES  0x00000004 /* messages blocked */
 /***/
 
 /****d* silccore/Modes/SilcUserMode
  *
  * SOURCE
  */
-#define SILC_UMODE_NONE                0x00000000 /* Normal SILC user */
-#define SILC_UMODE_SERVER_OPERATOR     0x00000001 /* Server operator */
-#define SILC_UMODE_ROUTER_OPERATOR     0x00000002 /* Router (SILC) operator */
-#define SILC_UMODE_GONE                0x00000004 /* Client is gone */
-#define SILC_UMODE_INDISPOSED          0x00000008 /* Client is indisposed */
-#define SILC_UMODE_BUSY                0x00000010 /* Client is busy */
-#define SILC_UMODE_PAGE                0x00000020 /* Client requests paging */
-#define SILC_UMODE_HYPER               0x00000040 /* Client is hyper active */
-#define SILC_UMODE_ROBOT               0x00000080 /* Client is a robot */
+#define SILC_UMODE_NONE              0x00000000 /* Normal SILC user */
+#define SILC_UMODE_SERVER_OPERATOR   0x00000001 /* Server operator */
+#define SILC_UMODE_ROUTER_OPERATOR   0x00000002 /* Router (SILC) operator */
+#define SILC_UMODE_GONE              0x00000004 /* Client is gone */
+#define SILC_UMODE_INDISPOSED        0x00000008 /* Client is indisposed */
+#define SILC_UMODE_BUSY              0x00000010 /* Client is busy */
+#define SILC_UMODE_PAGE              0x00000020 /* Client requests paging */
+#define SILC_UMODE_HYPER             0x00000040 /* Client is hyper active */
+#define SILC_UMODE_ROBOT             0x00000080 /* Client is a robot */
+#define SILC_UMODE_ANONYMOUS         0x00000100 /* Client is anonymous */
+#define SILC_UMODE_BLOCK_PRIVMSG     0x00000200 /* Client blocks privmsgs */
 /***/
 
 #endif
index e322c2af84fae0b936e459c7ce2b2402424ae9f2..4ac00f38363803b05857ee774b61ef0a8cb3af86 100644 (file)
@@ -652,6 +652,9 @@ char *silc_client_chumode(SilcUInt32 mode)
   if (mode & SILC_CHANNEL_UMODE_CHANOP)
     strncat(string, "o", 1);
 
+  if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
+    strncat(string, "b", 1);
+
   return strdup(string);
 }