From: Pekka Riikonen Date: Mon, 8 Apr 2002 20:56:46 +0000 (+0000) Subject: updates. X-Git-Tag: silc.client.0.8.6~4^2~18 X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=025071b92db9e9933a00aafef1e60baef53fec08 updates. --- diff --git a/CHANGES b/CHANGES index 1b200a49..74309ce3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +Mon Apr 8 23:57:32 EEST 2002 Pekka Riikonen + + * Redefined the Status Payload to include now two 8 bit fields, + instead of one 16 bit field. This now makes it possible to + send list of errors. Updated the protocol specs and the code + in core library, client library and server. Protocol TODO #1. + Affected files are lib/silccore/silccommand.[ch], + lib/silcclient/command_reply.[ch], silcd/command.c, + silcd/command_reply.c and silcd/packet_receive.[ch]. + Mon Apr 8 19:57:40 CEST 2002 Johnny Mnemonic * Added config parse status SILC_CONFIG_EPRINTLINE, this status @@ -16,6 +26,15 @@ Mon Apr 8 19:57:40 CEST 2002 Johnny Mnemonic * Drop root privileges when started in foreground. Don't drop them if debugging also. Affected file is silcd/silcd.c. +Mon Apr 8 17:00:41 EEST 2002 Pekka Riikonen + + * Added more IM-like features by introducing new user modes + for setting various presence information. Added new modes: + INDISPOSED, BUSY, PAGE, HYPER and ROBOT. Updated protocol + specs and code. Protocol TODO #19. Affected files are + lib/silccore/silcmode.h, irssi/src/silc/core/client_ops.c, + irssi/docs/help/in/umode.in and lib/silcclient/command.c. + Sun Apr 7 17:07:59 EEST 2002 Pekka Riikonen * Added STATS command to the protocol after all, to return diff --git a/TODO b/TODO index 26c76605..7e80cecf 100644 --- a/TODO +++ b/TODO @@ -106,18 +106,6 @@ 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. - 1. Re-define the Status Payload: it is now 16 bits, split it into two - 8 bits fields. First field includes status types from 0 - 9 and - 10 - n *if* it is not an list of errors. If it is list of errors then - the first field includes 1, 2 and/or 3, and the second field includes - the error status 10 - n. This way it is possible to send multiple - errors (list of errors) and we have a way to tell the receiver that - there will be other errors as well. The second field is used only - if there is list of errors. If normal status, or normal (single) - error status the second field is set to zero, and must be ignored. - Hence, the status works same way as now except for list of errors. - To be included in protocol version 1.1. - 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 @@ -138,9 +126,6 @@ describe new stuff to be added to protocol versions 1.x. 17. Cell wide channel founder support, and permanent channels when founder mode set. - 18. Describe the SSH public key, X509, OpenPGP and SPKI certificates - encoding format in SKE (from their respective definitions). - o Inviting and banning by public key should be made possible. To be included in protocol version 1.2. diff --git a/TODO-1.0 b/TODO-1.0 index 2bd59736..1dfbaf49 100644 --- a/TODO-1.0 +++ b/TODO-1.0 @@ -152,3 +152,5 @@ least could be done. o Something needs to be thought to the logging globals as well, like silc_debug etc. They won't work on EPOC. Perhaps logging and debugging is to be disabled on EPOC. + + o Check whether we can fully comply with RFC 2779. diff --git a/apps/irssi/docs/help/in/umode.in b/apps/irssi/docs/help/in/umode.in index a833a0d0..fd1102be 100644 --- a/apps/irssi/docs/help/in/umode.in +++ b/apps/irssi/docs/help/in/umode.in @@ -11,5 +11,10 @@ modes are available: s Unset server operator privileges r Unset router operator privileges g Set/unset to be gone (or use /AWAY command) + i Set/unset to be indisposed + b Set/unset to be busy + p Set/unset to await paging + h Set/unset to be hyper active + t Set/unset to be actually robot 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 b76c467d..727079c8 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -884,12 +884,22 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, if ((mode & SILC_UMODE_SERVER_OPERATOR) || (mode & SILC_UMODE_ROUTER_OPERATOR)) { strcat(buf, (mode & SILC_UMODE_SERVER_OPERATOR) ? - "Server Operator " : + "Server Operator" : (mode & SILC_UMODE_ROUTER_OPERATOR) ? - "SILC Operator " : "[Unknown mode] "); + "SILC Operator" : "[Unknown mode]"); } if (mode & SILC_UMODE_GONE) - strcat(buf, "away"); + strcat(buf, " away"); + if (mode & SILC_UMODE_INDISPOSED) + strcat(buf, " indisposed"); + if (mode & SILC_UMODE_BUSY) + strcat(buf, " busy"); + if (mode & SILC_UMODE_PAGE) + strcat(buf, " page to reach"); + if (mode & SILC_UMODE_HYPER) + strcat(buf, " hyper active"); + if (mode & SILC_UMODE_ROBOT) + strcat(buf, " robot"); printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP, SILCTXT_WHOIS_MODES, buf); @@ -1179,8 +1189,18 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, mode = silc_client_chumode_char(chu->mode); if (e->mode & SILC_UMODE_GONE) strcat(stat, "G"); - else + else if (e->mode & SILC_UMODE_INDISPOSED) + strcat(stat, "I"); + else if (e->mode & SILC_UMODE_BUSY) + strcat(stat, "B"); + else if (e->mode & SILC_UMODE_PAGE) + strcat(stat, "P"); + else if (e->mode & SILC_UMODE_HYPER) strcat(stat, "H"); + else if (e->mode & SILC_UMODE_ROBOT) + strcat(stat, "R"); + else + strcat(stat, "A"); if (mode) strcat(stat, mode); diff --git a/apps/silcd/command.c b/apps/silcd/command.c index d2622a08..974755eb 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -395,7 +395,7 @@ silc_server_command_send_status_reply(SilcServerCommandContext cmd, SILC_LOG_DEBUG(("Sending command status %d", status)); buffer = - silc_command_reply_payload_encode_va(command, status, + silc_command_reply_payload_encode_va(command, status, 0, silc_command_get_ident(cmd->payload), 0); silc_server_packet_send(cmd->server, cmd->sock, @@ -420,7 +420,7 @@ silc_server_command_send_status_data(SilcServerCommandContext cmd, SILC_LOG_DEBUG(("Sending command status %d", status)); buffer = - silc_command_reply_payload_encode_va(command, status, + silc_command_reply_payload_encode_va(command, status, 0, silc_command_get_ident(cmd->payload), 1, arg_type, arg, arg_len); silc_server_packet_send(cmd->server, cmd->sock, @@ -439,16 +439,10 @@ silc_server_command_pending_error_check(SilcServerCommandContext cmd, SilcServerCommandReplyContext cmdr, SilcCommand command) { - SilcCommandStatus status; - if (!cmd->pending || !cmdr) return FALSE; - SILC_GET16_MSB(status, silc_argument_get_arg_type(cmdr->args, 1, NULL)); - if (status != SILC_STATUS_OK && - status != SILC_STATUS_LIST_START && - status != SILC_STATUS_LIST_ITEM && - status != SILC_STATUS_LIST_END) { + if (!silc_command_get_status(cmdr->payload, NULL, NULL)) { SilcBuffer buffer; /* Send the same command reply payload */ @@ -802,7 +796,7 @@ silc_server_command_whois_send_reply(SilcServerCommandContext cmd, packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOIS, - status, ident, 8, + status, 0, ident, 8, 2, idp->data, idp->len, 3, nh, strlen(nh), 4, uh, strlen(uh), @@ -1160,7 +1154,7 @@ silc_server_command_whowas_send_reply(SilcServerCommandContext cmd, packet = silc_command_reply_payload_encode_va(SILC_COMMAND_WHOWAS, - status, ident, 4, + status, 0, ident, 4, 2, idp->data, idp->len, 3, nh, strlen(nh), 4, uh, strlen(uh), @@ -1819,7 +1813,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd, if (!entry->username) { packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY, - status, ident, 2, + status, 0, ident, 2, 2, idp->data, idp->len, 3, nh, strlen(nh)); } else { @@ -1832,7 +1826,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd, } packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY, - status, ident, 3, + status, 0, ident, 3, 2, idp->data, idp->len, 3, nh, strlen(nh), 4, uh, strlen(uh)); @@ -1870,7 +1864,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd, idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER); packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY, - status, ident, 2, + status, 0, ident, 2, 2, idp->data, idp->len, 3, entry->server_name, entry->server_name ? @@ -1907,7 +1901,7 @@ silc_server_command_identify_send_reply(SilcServerCommandContext cmd, idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL); packet = silc_command_reply_payload_encode_va(SILC_COMMAND_IDENTIFY, - status, ident, 2, + status, 0, ident, 2, 2, idp->data, idp->len, 3, entry->channel_name, entry->channel_name ? @@ -2062,7 +2056,7 @@ SILC_SERVER_CMD_FUNC(nick) send_reply: /* Send the new Client ID as reply command back to client */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_NICK, - SILC_STATUS_OK, ident, 1, + SILC_STATUS_OK, 0, ident, 1, 2, nidp->data, nidp->len); silc_server_packet_send(cmd->server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); @@ -2137,7 +2131,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd, /* Send the reply */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_LIST, - status, ident, 4, + status, 0, ident, 4, 2, idp->data, idp->len, 3, entry->channel_name, strlen(entry->channel_name), @@ -2176,7 +2170,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd, /* Send the reply */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_LIST, - status, ident, 4, + status, 0, ident, 4, 2, idp->data, idp->len, 3, entry->channel_name, strlen(entry->channel_name), @@ -2362,7 +2356,7 @@ SILC_SERVER_CMD_FUNC(topic) /* Send the topic to client as reply packet */ idp = silc_id_payload_encode(channel_id, SILC_ID_CHANNEL); packet = silc_command_reply_payload_encode_va(SILC_COMMAND_TOPIC, - SILC_STATUS_OK, ident, 2, + SILC_STATUS_OK, 0, ident, 2, 2, idp->data, idp->len, 3, channel->topic, channel->topic ? @@ -2582,7 +2576,7 @@ SILC_SERVER_CMD_FUNC(invite) if (add || del) packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE, - SILC_STATUS_OK, ident, 2, + SILC_STATUS_OK, 0, ident, 2, 2, tmp, len, 3, channel->invite_list, channel->invite_list ? @@ -2590,7 +2584,7 @@ SILC_SERVER_CMD_FUNC(invite) else packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INVITE, - SILC_STATUS_OK, ident, 1, + SILC_STATUS_OK, 0, ident, 1, 2, tmp, len); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); @@ -2935,7 +2929,7 @@ SILC_SERVER_CMD_FUNC(info) /* Send the reply */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_INFO, - SILC_STATUS_OK, ident, 3, + SILC_STATUS_OK, 0, ident, 3, 2, idp->data, idp->len, 3, server_name, strlen(server_name), @@ -3075,7 +3069,7 @@ SILC_SERVER_CMD_FUNC(stats) SILC_STR_END); packet = silc_command_reply_payload_encode_va(SILC_COMMAND_STATS, - SILC_STATUS_OK, ident, 2, + SILC_STATUS_OK, 0, ident, 2, 2, tmp, tmp_len, 3, stats->data, stats->len); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, @@ -3312,7 +3306,7 @@ static void silc_server_command_join_channel(SilcServer server, reply = silc_command_reply_payload_encode_va(SILC_COMMAND_JOIN, - SILC_STATUS_OK, ident, 13, + SILC_STATUS_OK, 0, ident, 13, 2, channel->channel_name, strlen(channel->channel_name), 3, chidp->data, chidp->len, @@ -3633,13 +3627,15 @@ SILC_SERVER_CMD_FUNC(motd) motd[motd_len] = 0; packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD, - SILC_STATUS_OK, ident, 2, + SILC_STATUS_OK, 0, + ident, 2, 2, idp, idp->len, 3, motd, motd_len); } else { /* No motd */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD, - SILC_STATUS_OK, ident, 1, + SILC_STATUS_OK, 0, + ident, 1, 2, idp, idp->len); } @@ -3715,7 +3711,7 @@ SILC_SERVER_CMD_FUNC(motd) idp = silc_id_payload_encode(server->id_entry->id, SILC_ID_SERVER); packet = silc_command_reply_payload_encode_va(SILC_COMMAND_MOTD, - SILC_STATUS_OK, ident, 2, + SILC_STATUS_OK, 0, ident, 2, 2, idp, idp->len, 3, entry->motd, entry->motd ? @@ -3775,7 +3771,7 @@ SILC_SERVER_CMD_FUNC(umode) /* Send command reply to sender */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE, - SILC_STATUS_OK, ident, 1, + SILC_STATUS_OK, 0, ident, 1, 2, tmp_mask, 4); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, FALSE); @@ -4149,7 +4145,7 @@ SILC_SERVER_CMD_FUNC(cmode) /* Send command reply to sender */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CMODE, - SILC_STATUS_OK, ident, 2, + SILC_STATUS_OK, 0, ident, 2, 2, tmp_id, tmp_len2, 3, tmp_mask, 4); silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0, @@ -4389,7 +4385,7 @@ SILC_SERVER_CMD_FUNC(cumode) /* Send command reply to sender */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_CUMODE, - SILC_STATUS_OK, ident, 3, + SILC_STATUS_OK, 0, ident, 3, 2, tmp_mask, 4, 3, tmp_ch_id, tmp_ch_len, 4, tmp_id, tmp_len); @@ -4848,7 +4844,7 @@ SILC_SERVER_CMD_FUNC(ban) /* Send the reply back to the client */ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_BAN, - SILC_STATUS_OK, ident, 2, + SILC_STATUS_OK, 0, ident, 2, 2, id, id_len, 3, channel->ban_list, channel->ban_list ? @@ -5062,7 +5058,7 @@ SILC_SERVER_CMD_FUNC(users) /* Send reply */ idp = silc_id_payload_encode(channel->id, SILC_ID_CHANNEL); packet = silc_command_reply_payload_encode_va(SILC_COMMAND_USERS, - SILC_STATUS_OK, ident, 4, + SILC_STATUS_OK, 0, ident, 4, 2, idp->data, idp->len, 3, lc, 4, 4, client_id_list->data, @@ -5257,7 +5253,7 @@ SILC_SERVER_CMD_FUNC(getkey) tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len); packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY, - SILC_STATUS_OK, ident, + SILC_STATUS_OK, 0, ident, pkdata ? 2 : 1, 2, tmp, tmp_len, 3, pkdata, pklen); diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 6300ebc1..9c876679 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -23,26 +23,14 @@ #include "server_internal.h" #include "command_reply.h" -/* All functions that call the COMMAND_CHECK_STATUS or the - COMMAND_CHECK_STATUS_LIST macros must have out: goto label. */ - -#define COMMAND_CHECK_STATUS \ -do { \ - SILC_LOG_DEBUG(("Start")); \ - SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); \ - if (status != SILC_STATUS_OK) \ - goto out; \ -} while(0) - -#define COMMAND_CHECK_STATUS_LIST \ -do { \ - SILC_LOG_DEBUG(("Start")); \ - SILC_GET16_MSB(status, silc_argument_get_arg_type(cmd->args, 1, NULL)); \ - if (status != SILC_STATUS_OK && \ - status != SILC_STATUS_LIST_START && \ - status != SILC_STATUS_LIST_ITEM && \ - status != SILC_STATUS_LIST_END) \ - goto out; \ +/* All functions that call the COMMAND_CHECK_STATUS macros must have + out: goto label. */ + +#define COMMAND_CHECK_STATUS \ +do { \ + SILC_LOG_DEBUG(("Start")); \ + if (!silc_command_get_status(cmd->payload, &status, &error)) \ + goto out; \ } while(0) /* Server command reply list. Not all commands have reply function as @@ -256,9 +244,9 @@ SILC_SERVER_CMD_REPLY_FUNC(whois) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; if (!silc_server_command_reply_whois_save(cmd)) goto out; @@ -273,7 +261,7 @@ SILC_SERVER_CMD_REPLY_FUNC(whois) out: /* If we received notify for invalid ID we'll remove the ID if we have it cached. */ - if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && + if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) { SilcClientEntry client; SilcUInt32 tmp_len; @@ -392,9 +380,9 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) SILC_SERVER_CMD_REPLY_FUNC(whowas) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; - SilcCommandStatus status; + SilcCommandStatus status, error; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; if (!silc_server_command_reply_whowas_save(cmd)) goto out; @@ -617,9 +605,9 @@ SILC_SERVER_CMD_REPLY_FUNC(identify) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; if (!silc_server_command_reply_identify_save(cmd)) goto out; @@ -634,7 +622,7 @@ SILC_SERVER_CMD_REPLY_FUNC(identify) out: /* If we received notify for invalid ID we'll remove the ID if we have it cached. */ - if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && + if (error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID && cmd->sock->type == SILC_SOCKET_TYPE_ROUTER) { SilcClientEntry client; SilcUInt32 tmp_len; @@ -666,7 +654,7 @@ SILC_SERVER_CMD_REPLY_FUNC(info) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; SilcServerEntry entry; SilcServerID *server_id; SilcUInt32 tmp_len; @@ -723,7 +711,7 @@ SILC_SERVER_CMD_REPLY_FUNC(motd) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; SilcServerEntry entry = NULL; SilcServerID *server_id; SilcUInt32 tmp_len; @@ -772,7 +760,7 @@ SILC_SERVER_CMD_REPLY_FUNC(join) SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; SilcIDCacheEntry cache = NULL; - SilcCommandStatus status; + SilcCommandStatus status, error; SilcChannelID *id; SilcClientID *client_id = NULL; SilcChannelEntry entry; @@ -974,7 +962,7 @@ SILC_SERVER_CMD_REPLY_FUNC(stats) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; unsigned char *tmp; SilcUInt32 tmp_len; SilcBufferStruct buf; @@ -1012,7 +1000,7 @@ SILC_SERVER_CMD_REPLY_FUNC(users) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; SilcChannelEntry channel; SilcChannelID *channel_id = NULL; SilcBuffer client_id_list; @@ -1101,7 +1089,7 @@ SILC_SERVER_CMD_REPLY_FUNC(getkey) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; SilcClientEntry client = NULL; SilcServerEntry server_entry = NULL; SilcClientID *client_id = NULL; @@ -1186,7 +1174,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list) { SilcServerCommandReplyContext cmd = (SilcServerCommandReplyContext)context; SilcServer server = cmd->server; - SilcCommandStatus status; + SilcCommandStatus status, error; SilcChannelID *channel_id = NULL; SilcChannelEntry channel; SilcIDCacheEntry cache; @@ -1195,7 +1183,7 @@ SILC_SERVER_CMD_REPLY_FUNC(list) SilcUInt32 usercount = 0; bool global_list = FALSE; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; tmp = silc_argument_get_arg_type(cmd->args, 2, &len); channel_id = silc_id_payload_parse_id(tmp, len, NULL); diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index f58aadcb..e2e98bc6 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1466,11 +1466,11 @@ void silc_server_private_message(SilcServer server, client_id, SILC_ID_CLIENT, SILC_COMMAND_IDENTIFY, SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, - 0, 1, 2, idp->data, idp->len); + 0, 0, 1, 2, idp->data, idp->len); silc_free(client_id); } else { silc_server_send_command_reply(server, sock, SILC_COMMAND_IDENTIFY, - SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, + SILC_STATUS_ERR_NO_SUCH_CLIENT_ID, 0, 0, 1, 2, idp->data, idp->len); } diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 424a2733..b37f1c7a 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -1720,6 +1720,7 @@ void silc_server_send_command_reply(SilcServer server, SilcSocketConnection sock, SilcCommand command, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, ...) { @@ -1728,8 +1729,8 @@ void silc_server_send_command_reply(SilcServer server, va_start(ap, argc); - packet = silc_command_reply_payload_encode_vap(command, status, ident, - argc, ap); + packet = silc_command_reply_payload_encode_vap(command, status, error, + ident, argc, ap); silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, packet->data, packet->len, TRUE); silc_buffer_free(packet); @@ -1745,6 +1746,7 @@ void silc_server_send_dest_command_reply(SilcServer server, SilcIdType dst_id_type, SilcCommand command, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, ...) { @@ -1753,8 +1755,8 @@ void silc_server_send_dest_command_reply(SilcServer server, va_start(ap, argc); - packet = silc_command_reply_payload_encode_vap(command, status, ident, - argc, ap); + packet = silc_command_reply_payload_encode_vap(command, status, error, + ident, argc, ap); silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0, dst_id, dst_id_type, packet->data, packet->len, TRUE); diff --git a/apps/silcd/packet_send.h b/apps/silcd/packet_send.h index b2cbc8aa..17dc349e 100644 --- a/apps/silcd/packet_send.h +++ b/apps/silcd/packet_send.h @@ -233,6 +233,7 @@ void silc_server_send_command_reply(SilcServer server, SilcSocketConnection sock, SilcCommand command, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, ...); void silc_server_send_dest_command_reply(SilcServer server, @@ -241,6 +242,7 @@ void silc_server_send_dest_command_reply(SilcServer server, SilcIdType dst_id_type, SilcCommand command, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, ...); void silc_server_send_heartbeat(SilcServer server, diff --git a/doc/draft-riikonen-silc-commands-03.nroff b/doc/draft-riikonen-silc-commands-03.nroff index 6bf956d6..f917a612 100644 --- a/doc/draft-riikonen-silc-commands-03.nroff +++ b/doc/draft-riikonen-silc-commands-03.nroff @@ -984,7 +984,7 @@ List of all defined commands in SILC follows. No specific mode for client. This is the initial setting when new client is created. The client is - normal client now. + normal client and is present in the network. 0x00000001 SILC_UMODE_SERVER_OPERATOR @@ -1010,6 +1010,44 @@ List of all defined commands in SILC follows. Marks that the user is not currently present in the SILC Network. Client MAY set and unset this mode. + + 0x00000008 SILC_UMODE_INDISPOSED + + Marks that the user is currently indisposed and may + not be able to receive any messages, and that user may + not be present in the network. Client MAY set and + unset this mode. + + + 0x00000010 SILC_UMODE_BUSY + + Marks that the user is currently busy and may not + want to receive any messages, and that user may not + be present in the network. Client MAY set and unset + this mode. + + + 0x00000020 SILC_UMODE_PAGE + + User is not currently present or is unable to receive + messages, and prefers to be paged in some mechanism + if the user needs to be reached. Client MAY set and + unset this mode. + + + 0x00000040 SILC_UMODE_HYPER + + Marks that the user is hyper active and is eager to + receive and send messages. Client MAY set and unset + this mode. + + + 0x00000080 SILC_UMODE_ROBOT + + Marks that the client is actually a robot program. + Client MAY set and unset this mode. + + Reply messages to the command: Max Arguments: 2 @@ -1625,7 +1663,7 @@ represents the Command Status Payload (field is always in MSB order). 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Status Message | +| Status | Error | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ .in 3 @@ -1634,10 +1672,49 @@ Figure 6: SILC Command Status Payload .in 6 -o Status Message (2 bytes) - Indicates the status message. - All Status messages are described in the next section. +o Status (1 byte) - Indicates the status message type, + error, start of list, entry of list or end of list. + +o Error (1 byte) - Indicates the error if the Status + field is some list status, which means there are list + of errors. +.in 3 + +The values in Status and Error fields are set according +the following rules: + +.in 6 +o If there is single reply and error has not occurred + then Status field includes value SILC_STATUS_OK, and + the Error field MUST be ignored (and set to zero + value). + +o If there is single error, then Status field includes + one of the error values, and the Error field MUST be + ignored (and set to zero value). + +o If there will be multiple successful command replies + then Status field includes SILC_STATUS_LIST_START, + SILC_STATUS_LIST_ITEM or SILC_STATUS_LIST_END value, + and Error field is set to SILC_STATUS_OK. + +o If there are multiple error replies then Status field + includes SILC_STATUS_LIST_START, SILC_STATUS_LIST_ITEM + or SILC_STATUS_LIST_END value, and the Error field + includes the error value. .in 3 +This way it is possible to send single successful or +single error reply, but also multiple successful and +multiple error replies. Note that it is possible to +send both list of successful replies and list of error +replies at the same time, however in this case the +list of error replies MUST be sent after the successful +replies. This way the recipient may ignore the multiple +errors if it wishes to do so. + +All Status messages are described in the next section. + .ti 0 2.3.2 SILC Command Status List diff --git a/doc/draft-riikonen-silc-flags-payloads-00.nroff b/doc/draft-riikonen-silc-flags-payloads-00.nroff index 8ba7d451..9abce0d4 100644 --- a/doc/draft-riikonen-silc-flags-payloads-00.nroff +++ b/doc/draft-riikonen-silc-flags-payloads-00.nroff @@ -215,9 +215,9 @@ Hence, the MIME Header in the message payload may be as follows: .in 8 .nf -MIME-Version: 1.0 -Content-Type: discrete/composite -Content-Transfer-Encoding: binary +MIME-Version: 1.0\\r +Content-Type: discrete/composite\\r +Content-Transfer-Encoding: binary\\r .in 3 The Content-Transfer-Encoding field behaves as defined in [RFC2045] and diff --git a/doc/draft-riikonen-silc-ke-auth-05.nroff b/doc/draft-riikonen-silc-ke-auth-05.nroff index 495647ba..7089aa48 100644 --- a/doc/draft-riikonen-silc-ke-auth-05.nroff +++ b/doc/draft-riikonen-silc-ke-auth-05.nroff @@ -483,7 +483,9 @@ o Public Key Type (2 bytes) - The public key (or certificate) be closed immediately. o Public Key (or certificate) (variable length) - The - public key or certificate. + public key or certificate. The public key or certificate + in this field is encoded in the manner as defined in their + respective definitions; see previous field. o Public Data Length (2 bytes) - The length of the Public Data field, not including any other field. @@ -824,6 +826,7 @@ are defined: Provided version string was not acceptable. + 11 SILC_SKE_STATUS_INVALID_COOKIE The cookie in the Key Exchange Start Payload was malformed, diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index 80182f5a..24e8854e 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -55,11 +55,8 @@ static void silc_client_notify_by_server_pending(void *context, void *context2) SILC_LOG_DEBUG(("Start")); - if (reply) { - SilcCommandStatus status = silc_command_get_status(reply->payload); - if (status != SILC_STATUS_OK) - goto out; - } + if (reply && !silc_command_get_status(reply->payload, NULL, NULL)) + goto out; silc_client_notify_by_server(res->context, res->sock, res->packet); diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 48b7cd27..8fa6fd0e 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -322,8 +322,9 @@ SILC_CLIENT_CMD_FUNC(nick_change) SilcClientConnection conn = cmd->conn; SilcClientCommandReplyContext reply = (SilcClientCommandReplyContext)context2; - SilcCommandStatus status = silc_command_get_status(reply->payload); + SilcCommandStatus status; + silc_command_get_status(reply->payload, &status, NULL); if (status == SILC_STATUS_OK) { /* Set the nickname */ silc_idcache_del_by_context(conn->client_cache, conn->local_entry); @@ -748,8 +749,9 @@ SILC_CLIENT_CMD_FUNC(kill_remove) SilcClientCommandContext cmd = (SilcClientCommandContext)context; SilcClientCommandReplyContext reply = (SilcClientCommandReplyContext)context2; - SilcCommandStatus status = silc_command_get_status(reply->payload); + SilcCommandStatus status; + silc_command_get_status(reply->payload, &status, NULL); if (status == SILC_STATUS_OK) { /* Remove with timeout */ silc_schedule_task_add(cmd->client->schedule, cmd->conn->sock->sock, @@ -1141,6 +1143,36 @@ SILC_CLIENT_CMD_FUNC(umode) else mode &= ~SILC_UMODE_GONE; break; + case 'i': + if (add) + mode |= SILC_UMODE_INDISPOSED; + else + mode &= ~SILC_UMODE_INDISPOSED; + break; + case 'b': + if (add) + mode |= SILC_UMODE_BUSY; + else + mode &= ~SILC_UMODE_BUSY; + break; + case 'p': + if (add) + mode |= SILC_UMODE_PAGE; + else + mode &= ~SILC_UMODE_PAGE; + break; + case 'h': + if (add) + mode |= SILC_UMODE_HYPER; + else + mode &= ~SILC_UMODE_HYPER; + break; + case 't': + if (add) + mode |= SILC_UMODE_ROBOT; + else + mode &= ~SILC_UMODE_ROBOT; + break; default: COMMAND_ERROR; goto out; @@ -2070,10 +2102,11 @@ SILC_CLIENT_CMD_FUNC(getkey) } else { SilcClientCommandReplyContext reply = (SilcClientCommandReplyContext)context2; - SilcCommandStatus status = silc_command_get_status(reply->payload); - + SilcCommandStatus error; + /* If nickname was not found, then resolve the server. */ - if (status == SILC_STATUS_ERR_NO_SUCH_NICK) { + silc_command_get_status(reply->payload, NULL, &error); + if (error == SILC_STATUS_ERR_NO_SUCH_NICK) { /* This sends the IDENTIFY command to resolve the server. */ silc_client_command_register(client, SILC_COMMAND_IDENTIFY, NULL, NULL, @@ -2091,11 +2124,11 @@ SILC_CLIENT_CMD_FUNC(getkey) /* If server was not found, then we've resolved both nickname and server and did not find anybody. */ - if (status == SILC_STATUS_ERR_NO_SUCH_SERVER) { + if (error == SILC_STATUS_ERR_NO_SUCH_SERVER) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", silc_client_command_status_message(SILC_STATUS_ERR_NO_SUCH_NICK)); SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", - silc_client_command_status_message(status)); + silc_client_command_status_message(error)); COMMAND_ERROR; goto out; } diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 616b2d86..097bdc09 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -92,28 +92,16 @@ const SilcCommandStatusMessage silc_command_status_messages[] = { #define SAY cmd->client->internal->ops->say -/* All functions that call the COMMAND_CHECK_STATUS or the - COMMAND_CHECK_STATUS_LIST macros must have out: goto label. */ - -#define COMMAND_CHECK_STATUS \ -do { \ - SILC_LOG_DEBUG(("Start")); \ - if (cmd->status != SILC_STATUS_OK) { \ - COMMAND_REPLY_ERROR; \ - goto out; \ - } \ -} while(0) - -#define COMMAND_CHECK_STATUS_LIST \ -do { \ - SILC_LOG_DEBUG(("Start")); \ - if (cmd->status != SILC_STATUS_OK && \ - cmd->status != SILC_STATUS_LIST_START && \ - cmd->status != SILC_STATUS_LIST_ITEM && \ - cmd->status != SILC_STATUS_LIST_END) { \ - COMMAND_REPLY_ERROR; \ - goto out; \ - } \ +/* All functions that call the COMMAND_CHECK_STATUS macro must have + out: goto label. */ + +#define COMMAND_CHECK_STATUS \ +do { \ + SILC_LOG_DEBUG(("Start")); \ + if (!silc_command_get_status(cmd->payload, NULL, NULL)) { \ + COMMAND_REPLY_ERROR; \ + goto out; \ + } \ } while(0) /* Process received command reply. */ @@ -143,10 +131,10 @@ void silc_client_command_reply_process(SilcClient client, ctx->client = client; ctx->sock = sock; ctx->payload = payload; - ctx->status = silc_command_get_status(ctx->payload); ctx->args = silc_command_get_args(ctx->payload); ctx->packet = packet; ctx->ident = silc_command_get_ident(ctx->payload); + silc_command_get_status(ctx->payload, &ctx->status, &ctx->error); /* Check for pending commands and mark to be exeucted */ silc_client_command_pending_check(sock->user_data, ctx, @@ -302,7 +290,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; /* Save WHOIS info */ silc_client_command_reply_whois_save(cmd, cmd->status, TRUE); @@ -319,7 +307,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois) /* If we received notify for invalid ID we'll remove the ID if we have it cached. */ - if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { + if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { SilcClientEntry client_entry; SilcUInt32 tmp_len; unsigned char *tmp = @@ -353,7 +341,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whowas) char *nickname, *username; char *realname = NULL; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; id_data = silc_argument_get_arg_type(cmd->args, 2, &len); if (!id_data) { @@ -523,7 +511,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; /* Save IDENTIFY info */ silc_client_command_reply_identify_save(cmd, cmd->status, TRUE); @@ -540,7 +528,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify) /* If we received notify for invalid ID we'll remove the ID if we have it cached. */ - if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { + if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { SilcClientEntry client_entry; SilcUInt32 tmp_len; unsigned char *tmp = @@ -574,10 +562,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot set nickname: %s", - silc_client_command_status_message(cmd->status)); + silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -621,7 +609,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(list) SilcChannelID *channel_id = NULL; SilcChannelEntry channel_entry; - COMMAND_CHECK_STATUS_LIST; + COMMAND_CHECK_STATUS; tmp = silc_argument_get_arg_type(cmd->args, 2, &len); if (!tmp) { @@ -688,9 +676,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(topic) char *topic; SilcUInt32 argc, len; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -742,9 +730,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(invite) unsigned char *tmp; SilcUInt32 len; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -784,9 +772,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(kill) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -814,9 +802,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(info) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", - silc_client_command_status_message(cmd->status)); + silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -870,9 +858,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping) int i; time_t diff, curtime; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -930,10 +918,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK) { - if (cmd->status != SILC_STATUS_ERR_USER_ON_CHANNEL) + if (cmd->error != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_ERR_USER_ON_CHANNEL) SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1110,9 +1098,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(motd) SilcUInt32 argc, i; char *motd = NULL, *cp, line[256]; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; return; } @@ -1167,9 +1155,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(umode) unsigned char *tmp; SilcUInt32 mode; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1203,9 +1191,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(cmode) SilcChannelEntry channel; SilcUInt32 len; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1262,9 +1250,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode) unsigned char *modev, *tmp, *id; SilcUInt32 len, mode; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1336,9 +1324,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(kick) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1356,9 +1344,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(silcoper) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1376,9 +1364,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(oper) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1400,9 +1388,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(ban) unsigned char *tmp; SilcUInt32 len; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1446,9 +1434,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(leave) unsigned char *tmp; SilcUInt32 len; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1490,10 +1478,10 @@ static void silc_client_command_reply_users_cb(SilcClient client, if (!channels_count) { SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - SilcCommandStatus status = SILC_STATUS_ERR_NO_SUCH_CHANNEL; + cmd->status = cmd->error = SILC_STATUS_ERR_NO_SUCH_CHANNEL; SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_USERS); silc_client_command_reply_free(cmd); @@ -1524,9 +1512,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1718,9 +1706,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1804,10 +1792,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois_i) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK && - cmd->status != SILC_STATUS_LIST_START && - cmd->status != SILC_STATUS_LIST_ITEM && - cmd->status != SILC_STATUS_LIST_END) + if (cmd->error != SILC_STATUS_OK) goto out; /* Save WHOIS info */ @@ -1825,7 +1810,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(whois_i) /* If we received notify for invalid ID we'll remove the ID if we have it cached. */ - if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { + if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { SilcClientEntry client_entry; SilcUInt32 tmp_len; unsigned char *tmp = @@ -1858,10 +1843,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify_i) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK && - cmd->status != SILC_STATUS_LIST_START && - cmd->status != SILC_STATUS_LIST_ITEM && - cmd->status != SILC_STATUS_LIST_END) + if (cmd->error != SILC_STATUS_OK) goto out; /* Save IDENTIFY info */ @@ -1879,7 +1861,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify_i) /* If we received notify for invalid ID we'll remove the ID if we have it cached. */ - if (cmd->status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { + if (cmd->error == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { SilcClientEntry client_entry; SilcUInt32 tmp_len; unsigned char *tmp = @@ -1917,7 +1899,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(info_i) SILC_LOG_DEBUG(("Start")); - if (cmd->status != SILC_STATUS_OK) + if (cmd->error != SILC_STATUS_OK) goto out; /* Get server ID */ @@ -1962,9 +1944,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(connect) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1982,9 +1964,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(close) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -2002,9 +1984,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(shutdown) SilcClientCommandReplyContext cmd = (SilcClientCommandReplyContext)context; SilcClientConnection conn = (SilcClientConnection)cmd->sock->user_data; - if (cmd->status != SILC_STATUS_OK) { + if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_command_status_message(cmd->status)); + "%s", silc_client_command_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } diff --git a/lib/silcclient/command_reply.h b/lib/silcclient/command_reply.h index afc14f9a..1d1d2083 100644 --- a/lib/silcclient/command_reply.h +++ b/lib/silcclient/command_reply.h @@ -32,6 +32,7 @@ struct SilcClientCommandReplyContextStruct { SilcSocketConnection sock; SilcCommandPayload payload; SilcCommandStatus status; + SilcCommandStatus error; SilcArgumentPayload args; SilcPacketContext *packet; diff --git a/lib/silccore/silcchannel.c b/lib/silccore/silcchannel.c index 2bd7eb6f..5254c9ed 100644 --- a/lib/silccore/silcchannel.c +++ b/lib/silccore/silcchannel.c @@ -304,9 +304,18 @@ bool silc_channel_message_payload_decrypt(unsigned char *data, silc_hmac_update(hmac, data + (data_len - iv_len), iv_len); silc_hmac_final(hmac, mac2, &mac_len); if (memcmp(mac, mac2, mac_len)) { +#if 1 + /* Backwards support for old mac checking, remove in 1.0 */ + silc_hmac_make(hmac, dst, (data_len - iv_len - mac_len), mac2, &mac_len); + if (memcmp(mac, mac2, mac_len)) { +#endif + SILC_LOG_DEBUG(("Channel message MACs does not match")); silc_free(dst); return FALSE; +#if 1 + } +#endif } SILC_LOG_DEBUG(("MAC is Ok")); diff --git a/lib/silccore/silccommand.c b/lib/silccore/silccommand.c index 3be0583e..20b90c66 100644 --- a/lib/silccore/silccommand.c +++ b/lib/silccore/silccommand.c @@ -82,7 +82,8 @@ SilcCommandPayload silc_command_payload_parse(const unsigned char *payload, silc_buffer_pull(&buffer, SILC_COMMAND_PAYLOAD_LEN); if (args_num) { - newp->args = silc_argument_payload_parse(buffer.data, buffer.len, args_num); + newp->args = silc_argument_payload_parse(buffer.data, buffer.len, + args_num); if (!newp->args) { silc_free(newp); return NULL; @@ -271,6 +272,7 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd, SilcBuffer silc_command_reply_payload_encode_va(SilcCommand cmd, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, ...) { @@ -278,7 +280,8 @@ silc_command_reply_payload_encode_va(SilcCommand cmd, SilcBuffer buffer; va_start(ap, argc); - buffer = silc_command_reply_payload_encode_vap(cmd, status, ident, argc, ap); + buffer = silc_command_reply_payload_encode_vap(cmd, status, error, + ident, argc, ap); va_end(ap); return buffer; @@ -287,6 +290,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd, SilcBuffer silc_command_reply_payload_encode_vap(SilcCommand cmd, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, va_list ap) { @@ -315,7 +319,8 @@ silc_command_reply_payload_encode_vap(SilcCommand cmd, return NULL; } - SILC_PUT16_MSB(status, status_data); + status_data[0] = status; + status_data[1] = error; argv[0] = silc_memdup(status_data, sizeof(status_data)); if (!argv[0]) { silc_free(argv_types); @@ -388,19 +393,45 @@ SilcUInt16 silc_command_get_ident(SilcCommandPayload payload) /* Return command status */ -SilcCommandStatus silc_command_get_status(SilcCommandPayload payload) +bool silc_command_get_status(SilcCommandPayload payload, + SilcCommandStatus *status, + SilcCommandStatus *error) { unsigned char *tmp; - SilcCommandStatus status; + SilcUInt32 tmp_len; if (!payload->args) return 0; - tmp = silc_argument_get_arg_type(payload->args, 1, NULL); - if (!tmp) + tmp = silc_argument_get_arg_type(payload->args, 1, &tmp_len); + if (!tmp || tmp_len != 2) return 0; - SILC_GET16_MSB(status, tmp); - return status; + /* Check for 1.0 protocol version which didn't have `error' */ + if (tmp[0] == 0 && tmp[1] != 0) { + /* Protocol 1.0 version */ + SilcCommandStatus s; + SILC_GET16_MSB(s, tmp); + if (status) + *status = s; + if (error) + *error = 0; + if (s >= SILC_STATUS_ERR_NO_SUCH_NICK && error) + *error = s; + return (s < SILC_STATUS_ERR_NO_SUCH_NICK); + } + + /* Take both status and possible error */ + if (status) + *status = (SilcCommandStatus)tmp[0]; + if (error) + *error = (SilcCommandStatus)tmp[1]; + + /* If single error occurred have the both `status' and `error' indicate + the error value for convenience. */ + if (tmp[0] >= SILC_STATUS_ERR_NO_SUCH_NICK && error) + *error = tmp[0]; + + return (tmp[0] < SILC_STATUS_ERR_NO_SUCH_NICK && tmp[1] == SILC_STATUS_OK); } /* Function to set identifier to already allocated Command Payload. Command diff --git a/lib/silccore/silccommand.h b/lib/silccore/silccommand.h index d1888553..a7842622 100644 --- a/lib/silccore/silccommand.h +++ b/lib/silccore/silccommand.h @@ -162,7 +162,7 @@ typedef unsigned char SilcCommand; * * NAME * - * typedef SilcUInt16 SilcCommandStatus; + * typedef SilcUInt8 SilcCommandStatus; * * DESCRIPTION * @@ -172,7 +172,7 @@ typedef unsigned char SilcCommand; * * SOURCE */ -typedef SilcUInt16 SilcCommandStatus; +typedef SilcUInt8 SilcCommandStatus; /* Command Status messages */ #define SILC_STATUS_OK 0 @@ -324,20 +324,35 @@ SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd, * SilcBuffer * silc_command_reply_payload_encode_va(SilcCommand cmd, * SilcCommandStatus status, + * SilcCommandStatus error, * SilcUInt16 ident, * SilcUInt32 argc, ...); * * DESCRIPTION * * Same as silc_command_payload_encode_va except that this is used to - * encode strictly command reply packets. The command status message - * to be returned is sent as extra argument to this function. The `argc' - * must not count `status' as on argument. + * encode strictly command reply packets. The `argc' must not count + * `status' and `error' as arguments. The `status' includes the + * command reply status. If single reply will be sent then it includes + * SILC_STATUS_OK if error did not occur. It includes an error value + * if error did occur. In this case `error' field is ignored. If + * there will be multiple successful command replies then the `status' + * includes a list value and `error' is ignored. If there will + * multiple error replies the `status' includes a list value, and + * the `error' includes an error value. Thus, the `error' value is + * specified only if there will be list of errors. + * + * NOTES + * + * Protocol defines that it is possible to send both list of successful + * and list of error replies at the same time, as long as the error + * replies are sent after the successful replies. * ***/ SilcBuffer silc_command_reply_payload_encode_va(SilcCommand cmd, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, ...); @@ -348,6 +363,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd, * SilcBuffer * silc_command_reply_payload_encode_vap(SilcCommand cmd, * SilcCommandStatus status, + * SilcCommandStatus error, * SilcUInt16 ident, SilcUInt32 argc, * va_list ap); * @@ -360,6 +376,7 @@ silc_command_reply_payload_encode_va(SilcCommand cmd, SilcBuffer silc_command_reply_payload_encode_vap(SilcCommand cmd, SilcCommandStatus status, + SilcCommandStatus error, SilcUInt16 ident, SilcUInt32 argc, va_list ap); @@ -423,15 +440,23 @@ SilcUInt16 silc_command_get_ident(SilcCommandPayload payload); * * SYNOPSIS * - * SilcCommandStatus silc_command_get_status(SilcCommandPayload payload); + * bool silc_command_get_status(SilcCommandPayload payload, + * SilcCommandStatus *status, + * SilcCommandStatus *error); * * DESCRIPTION * - * Returns the SilcCommandStatus from command reply payload's argument - * payload. Status can be returned only from command reply payload. + * This function returns the command reply status into `status' and + * error status, if error occurred into the `error'. The function + * returns TRUE if command reply status is not error, and FALSE if + * error occurred. In this case the `error' will include the actual + * error status. The `status' can be in this case some list value + * which indicates that there will be list of errors. * ***/ -SilcCommandStatus silc_command_get_status(SilcCommandPayload payload); +bool silc_command_get_status(SilcCommandPayload payload, + SilcCommandStatus *status, + SilcCommandStatus *error); /****f* silccore/SilcCommandAPI/silc_command_set_ident * diff --git a/lib/silccore/silcmode.h b/lib/silccore/silcmode.h index 6f47e7f8..df2ce260 100644 --- a/lib/silccore/silcmode.h +++ b/lib/silccore/silcmode.h @@ -71,15 +71,20 @@ * * DESCRIPTION * - * SILC User modes. These indicate the status of the client in the - * SILC network. + * SILC User modes. These indicate the status and presence of the client + * in the SILC network. * * SOURCE */ -#define SILC_UMODE_NONE 0x0000 /* Normal SILC user */ -#define SILC_UMODE_SERVER_OPERATOR 0x0001 /* Server operator */ -#define SILC_UMODE_ROUTER_OPERATOR 0x0002 /* Router (SILC) operator */ -#define SILC_UMODE_GONE 0x0004 /* Client is gone */ +#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 really robot */ /***/ #endif