From c08107c80b816558a1c48ada27eaf23840793157 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Tue, 9 Apr 2002 17:36:10 +0000 Subject: [PATCH] updates. --- CHANGES | 21 +++++++++ TODO | 3 -- apps/irssi/docs/help/in/cumode.in | 9 ++++ apps/irssi/docs/help/in/umode.in | 6 +++ apps/irssi/src/silc/core/client_ops.c | 6 +++ apps/silcd/command.c | 57 +++++++++++++++++++---- apps/silcd/command_reply.c | 7 +-- apps/silcd/packet_receive.c | 23 +++++++-- apps/silcd/packet_send.c | 3 +- apps/silcd/server.c | 17 +++++-- apps/silcd/server.h | 12 +++-- doc/draft-riikonen-silc-commands-03.nroff | 50 ++++++++++++++++++-- lib/silcclient/command.c | 13 ++++++ lib/silccore/silcmode.h | 31 ++++++------ lib/silcutil/silcutil.c | 3 ++ 15 files changed, 212 insertions(+), 49 deletions(-) diff --git a/CHANGES b/CHANGES index 74309ce3..65a89453 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Tue Apr 9 17:15:42 EEST 2002 Pekka Riikonen + + * 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 * Redefined the Status Payload to include now two 8 bit fields, diff --git a/TODO b/TODO index fba20ff2..25f39441 100644 --- 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. diff --git a/apps/irssi/docs/help/in/cumode.in b/apps/irssi/docs/help/in/cumode.in index 9bba22f3..03d24965 100644 --- a/apps/irssi/docs/help/in/cumode.in +++ b/apps/irssi/docs/help/in/cumode.in @@ -31,4 +31,13 @@ are available: Set/unset channel operator. Requires that you are channel operator or channel founder. + b [@] + + 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 diff --git a/apps/irssi/docs/help/in/umode.in b/apps/irssi/docs/help/in/umode.in index fd1102be..757fcfc9 100644 --- a/apps/irssi/docs/help/in/umode.in +++ b/apps/irssi/docs/help/in/umode.in @@ -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 diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 727079c8..3865d702 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -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) diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 974755eb..3a0bd76f 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -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; diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 9c876679..bd4052a4 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -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) diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index e2e98bc6..1a1be10d 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -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; diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index b37f1c7a..ab5b6219 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -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 diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 306cb07f..eb2c0a95 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -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; } diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 4aaa1840..a90e7dd1 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -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, diff --git a/doc/draft-riikonen-silc-commands-03.nroff b/doc/draft-riikonen-silc-commands-03.nroff index f917a612..e8bb6142 100644 --- a/doc/draft-riikonen-silc-commands-03.nroff +++ b/doc/draft-riikonen-silc-commands-03.nroff @@ -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: diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 8fa6fd0e..fa0bfa63 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -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; diff --git a/lib/silccore/silcmode.h b/lib/silccore/silcmode.h index 2bff5795..63b0c2da 100644 --- a/lib/silccore/silcmode.h +++ b/lib/silccore/silcmode.h @@ -58,13 +58,16 @@ * * 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 @@ -76,15 +79,17 @@ * * 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 diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index e322c2af..4ac00f38 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -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); } -- 2.24.0