+Thu Oct 18 20:58:13 EDT 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Resolve the client info when received private message or
+ channel message for a client which nickname we don't know.
+ Affected files lib/silcclient/client_prvmsg.c and
+ lib/silcclient/client_channel.c.
+
+ * Do not crash in /KEY if client is not connected. Affected
+ file irssi/src/silc/core/silc-channels.c.
+
+ * Added SilcClientStatus field to the SilcClientEntry in the
+ lib/silcclient/idlist.h.
+
+ Added SILC_CLIENT_STATUS_RESOLVING to mark that the entry
+ is incomplete and is being resolved, it won't be resolved
+ twice.
+
+ Make sure also that USERS command reply does not resolve
+ twice information. Affected file is
+ lib/silcclient/command_reply.c.
+
+ Make sure that silc_client_get_clients_by_list does not
+ resolve twice same information.
+
+ * Check for valid client->id in the silc_server_free_client_data.
+ Affected file silcd/server.c.
+
+ * Fixed /GETKEY nick@server not to crash if the server entry
+ is not found. Affected file lib/silcclient/command.c.
+
+ * Fixed the silc_server_check_cmode_rights to check the
+ requested modes correctly. Affected file silcd/command.c.
+
Thu Oct 18 12:10:22 CEST 2001 Pekka Riikonen <priikone@silcnet.org>
* Better checks for non-printable chars in nick added.
TODO/bugs in Irssi SILC client
==============================
- o /key msg * list crashes the client
+ o Add the SFTP support.
o Add local command to switch the channel's private key when channel has
several private keys. Currently sending channel messages with many
that the user has. And a local command to dump the contents of the
public key to the screen. Something like LISTKEYS, SHOWKEY...
- o The QUIT command should wait for server's disconnection (at least for
- a while) before exiting the application.
-
o The JOIN command's HELP is generated from Irssi IRCs JOIN help and
the syntax is not same in SILC. This must be fixed. Most likely
we must forget the Irssi's JOIN command and mimic it to get our
TODO/bugs In SILC Client Library
================================
+ o Add the SFTP support.
+
o JOIN command's argument handling is buggy. See the XXX in the code.
o Channel user mode changes are notified unnecessarely when switching
to backup router on router crash.
- o Change the sever to connect to another server from low ports (706)
+ o Change the server to connect to another server from low ports (706)
and not from high ports. Currently we cannot do incoming connection
checking by remote port because the port is not fixed.
TODO/bugs In SILC Libraries
===========================
+ o Add some silc_rng_get_byte_fast that read directly from /dev/urandom.
+ That can be used for padding generation. The current is too slow.
+
o Compression routines are missing. The protocol supports packet
compression thus it must be implemented. SILC Comp API must be
defined. zlib package is already included into the lib dir (in CVS,
return;
nick = silc_nicklist_find(chanrec, sender);
+ if (!nick) {
+ /* We didn't find client but it clearly exists, add it. */
+ SilcChannelUser chu;
+
+ silc_list_start(channel->clients);
+ while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ if (chu->client == sender) {
+ nick = silc_nicklist_insert(chanrec, chu, FALSE);
+ break;
+ }
+ }
+ }
if (flags & SILC_MESSAGE_FLAG_ACTION)
printformat_module("fe-common/silc", server, channel->channel_name,
silc_list_start(channel->clients);
while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ if (!chu->client->nickname)
+ continue;
if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
founder = chu->client;
silc_nicklist_insert(chanrec, chu, FALSE);
while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
SilcClientEntry e = chu->client;
char stat[5], *mode;
+
+ if (!e->nickname)
+ continue;
memset(stat, 0, sizeof(stat));
mode = silc_client_chumode_char(chu->mode);
printformat_module("fe-common/silc", server, channel->channel_name,
MSGLEVEL_CRAP, SILCTXT_USERS,
- e->nickname, stat, e->username,
- e->hostname, e->realname ? e->realname : "");
+ e->nickname, stat,
+ e->username ? e->username : "",
+ e->hostname ? e->hostname : "",
+ e->realname ? e->realname : "");
if (mode)
silc_free(mode);
}
static void command_key(const char *data, SILC_SERVER_REC *server,
WI_ITEM_REC *item)
{
- SilcClientConnection conn = server->conn;
+ SilcClientConnection conn;
SilcClientEntry client_entry = NULL;
SilcChannelEntry channel_entry = NULL;
char *nickname = NULL, *tmp;
unsigned char **argv;
uint32 *argv_lens, *argv_types;
- if (!IS_SILC_SERVER(server) || !server->connected)
+ if (!server || !IS_SILC_SERVER(server) || !server->connected)
cmd_return_error(CMDERR_NOT_CONNECTED);
+ conn = server->conn;
+
/* Now parse all arguments */
tmp = g_strconcat("KEY", " ", data, NULL);
silc_parse_command_line(tmp, &argv, &argv_lens, &argv_types, &argc, 7);
if (type == 1) {
if (argv[2][0] == '*') {
- nickname = "*";
+ nickname = strdup("*");
} else {
/* Parse the typed nickname. */
if (!silc_parse_userfqdn(argv[2], &nickname, NULL)) {
}
silc_client_free_private_message_keys(keys, keys_count);
+
} else if (type == 2) {
SilcChannelPrivateKey *keys;
uint32 keys_count;
keys = silc_client_list_channel_private_keys(silc_client, conn,
channel_entry,
&keys_count);
- if (!keys)
- goto out;
-
+
printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
SILCTXT_CH_PRIVATE_KEY_LIST,
channel_entry->channel_name);
+
+ if (!keys)
+ goto out;
+
for (k = 0; k < keys_count; k++) {
memset(buf, 0, sizeof(buf));
strncat(buf, " ", 2);
modes are available automatically for channel operator. */
if (mode & SILC_CHANNEL_MODE_PRIVKEY) {
- if (is_op && !is_fo)
- return FALSE;
+ if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY))
+ if (is_op && !is_fo)
+ return FALSE;
} else {
if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY) {
if (is_op && !is_fo)
}
if (mode & SILC_CHANNEL_MODE_PASSPHRASE) {
- if (is_op && !is_fo)
- return FALSE;
+ if (!(channel->mode & SILC_CHANNEL_MODE_PASSPHRASE))
+ if (is_op && !is_fo)
+ return FALSE;
} else {
if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
if (is_op && !is_fo)
}
if (mode & SILC_CHANNEL_MODE_CIPHER) {
- if (is_op && !is_fo)
- return FALSE;
+ if (!(channel->mode & SILC_CHANNEL_MODE_CIPHER))
+ if (is_op && !is_fo)
+ return FALSE;
} else {
if (channel->mode & SILC_CHANNEL_MODE_CIPHER) {
if (is_op && !is_fo)
}
if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
- if (is_op && !is_fo)
- return FALSE;
+ if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH))
+ if (is_op && !is_fo)
+ return FALSE;
} else {
if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
if (is_op && !is_fo)
to the network before removing the client entry. */
silc_server_packet_queue_purge(server, sock);
+ if (!client->id)
+ return;
+
/* Send SIGNOFF notify to routers. */
if (notify && !server->standalone && server->router)
silc_server_send_notify_signoff(server, server->router->connection,
server->server_type == SILC_SERVER ?
FALSE : TRUE, client->id, signoff);
-
+
/* Remove client from all channels */
if (notify)
silc_server_remove_from_channels(server, NULL, client,
else
silc_server_remove_from_channels(server, NULL, client,
FALSE, NULL, FALSE);
-
+
/* We will not delete the client entry right away. We will take it
into history (for WHOWAS command) for 5 minutes */
i->server = server;
/* Find client entry */
silc_list_start(channel->clients);
while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
- if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id)) {
+ if (SILC_ID_CLIENT_COMPARE(chu->client->id, client_id) &&
+ chu->client->nickname) {
found = TRUE;
break;
}
/* If nickname or username hasn't been resolved, do so */
if (!client_entry->nickname || !client_entry->username) {
- if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING)
+ if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING) {
+ client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
goto out;
+ }
client_entry->status |= SILC_CLIENT_STATUS_RESOLVING;
silc_client_notify_by_server_resolve(client, conn, packet, client_id);
goto out;
if (!silc_idcache_find_by_id_one_ext(conn->client_cache, (void *)remote_id,
NULL, NULL,
silc_hash_client_id_compare, NULL,
- &id_cache)) {
+ &id_cache) ||
+ ((SilcClientEntry)id_cache->context)->nickname == NULL) {
/* Resolve the client info */
silc_client_get_client_by_id_resolve(client, conn, remote_id,
silc_client_private_message_cb,
/* Check whether user requested server actually */
server_entry = silc_client_get_server(client, conn, cmd->argv[1]);
- if (!server_entry && !cmd->pending) {
+ if (!server_entry) {
+ if (cmd->pending) {
+ COMMAND_ERROR;
+ goto out;
+ }
+
/* No. what ever user wants we don't have it, so resolve it. We
will try to resolve both client and server, one of them is
bound to be wrong. */
if (id_cache && id_cache->context) {
SilcClientEntry client_entry = (SilcClientEntry)id_cache->context;
if (client_entry->status & SILC_CLIENT_STATUS_RESOLVING) {
+ client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
silc_buffer_pull(client_id_list, idp_len);
silc_buffer_pull(client_mode_list, 4);
continue;
if (entry) {
if (entry->status & SILC_CLIENT_STATUS_RESOLVING) {
+ client_entry->status &= ~SILC_CLIENT_STATUS_RESOLVING;
silc_free(client_id);
silc_buffer_pull(client_id_list, idp_len);
continue;
#ifndef IDLIST_H
#define IDLIST_H
+typedef enum {
+ SILC_CLIENT_STATUS_NONE = 0x0000,
+ SILC_CLIENT_STATUS_RESOLVING = 0x0001,
+} SilcClientStatus;
+
/* Client entry context. When client receives information about new client
(it receives its ID, for example, by IDENTIFY request) we create new
client entry. This entry also includes the private message keys if
uint32 key_len;
bool generated; /* TRUE if library generated the key */
SilcClientKeyAgreement ke; /* Current key agreement context or NULL */
+ SilcClientStatus status; /* Status mask */
} *SilcClientEntry;
/* Client and its mode on a channel */
silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
paddedlen + mac_len);
- SILC_LOG_HEXDUMP(("Incoming packet (%d) (%d bytes decrypted), len %d",
+ SILC_LOG_HEXDUMP(("Incoming packet (%d) (%dB decrypted), len %d",
sequence - 1, block_len, paddedlen + mac_len),
sock->inbuf->data, paddedlen + mac_len);
uint8 dst_id_len;
uint8 dst_id_type;
- /* Back pointers */
- void *context;
- SilcSocketConnection sock;
-
int users;
bool long_pad; /* Set to TRUE to use maximum padding
in packet (up to 256 bytes). */