From c5ef2b330ec7c6255f06e00bf7e7fb0f8de3d92b Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 7 May 2007 18:34:43 +0000 Subject: [PATCH] Fixed CMODE sending and receiving when it comes to channel public keys. --- CHANGES | 9 +++++++++ TODO | 2 +- lib/silcclient/client_channel.c | 19 ++++++++++++++++++- lib/silcclient/client_channel.h | 3 ++- lib/silcclient/client_entry.c | 13 ++++++++++--- lib/silcclient/client_notify.c | 10 ++++++---- lib/silcclient/client_prvmsg.c | 10 ++++++++++ lib/silcclient/command.c | 6 +++++- lib/silcclient/command_reply.c | 19 +++++++++---------- lib/silcclient/silcclient.h | 20 ++++++++++++++++++++ 10 files changed, 90 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index 5b0ef69c..25e2a1cd 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +Mon May 7 18:18:48 EEST 2007 Pekka Riikonen + + * Fixed CMODE channel auth public key retrieval. Affected + file is lib/silcclient/command.c. + + * Fixed CMODE command reply to return channel public keys + correctly. Affected files are lib/silcclient/command_reply.c + and client_channel.c. + Sun May 6 12:43:19 EEST 2007 Pekka Riikonen * Added current channel key cipher name and HMAC name to diff --git a/TODO b/TODO index f7a6ee6a..b091bdb4 100644 --- a/TODO +++ b/TODO @@ -38,7 +38,7 @@ apps/silcd, The SILC Server ****PARTLY DONE**** SILC Client ****PARTLY DONE**** =========== - o Porting to new Toolkit API and new Client Library API (***TESTING NEEDED) + o Porting to new Toolkit API and new Client Library API (***DONE) o Improve help files, especially /cmode, /cumode and /key. diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 077399b2..1d78d221 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -887,12 +887,29 @@ void silc_client_empty_channel(SilcClient client, SilcBool silc_client_channel_save_public_keys(SilcChannelEntry channel, unsigned char *chpk_list, - SilcUInt32 chpk_list_len) + SilcUInt32 chpk_list_len, + SilcBool remove_all) { SilcArgumentDecodedList a, b; SilcDList chpks; SilcBool found; + if (remove_all) { + /* Remove all channel public keys */ + if (!channel->channel_pubkeys) + return FALSE; + + silc_dlist_start(channel->channel_pubkeys); + while ((b = silc_dlist_get(channel->channel_pubkeys))) + silc_dlist_del(channel->channel_pubkeys, b); + + silc_dlist_uninit(channel->channel_pubkeys); + channel->channel_pubkeys = NULL; + + return TRUE; + } + + /* Parse channel public key list and add or remove public keys */ chpks = silc_argument_list_parse_decoded(chpk_list, chpk_list_len, SILC_ARGUMENT_PUBLIC_KEY); if (!chpks) diff --git a/lib/silcclient/client_channel.h b/lib/silcclient/client_channel.h index 6ec49c6c..0854aa5f 100644 --- a/lib/silcclient/client_channel.h +++ b/lib/silcclient/client_channel.h @@ -47,6 +47,7 @@ void silc_client_empty_channel(SilcClient client, SilcChannelEntry channel); SilcBool silc_client_channel_save_public_keys(SilcChannelEntry channel, unsigned char *chpk_list, - SilcUInt32 chpk_list_len); + SilcUInt32 chpk_list_len, + SilcBool remove_all); #endif /* CLIENT_CHANNEL_H */ diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index f4354a8a..fb6479a7 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -257,8 +257,11 @@ silc_client_get_client_by_id_resolve(SilcClient client, SilcBuffer idp; SilcUInt16 cmd_ident; - if (!client || !conn | !client_id) + if (!client || !conn | !client_id) { + SILC_LOG_ERROR(("Missing arguments to " + "silc_client_get_clients_by_id_resolve call")); return 0; + } SILC_LOG_DEBUG(("Resolve client by ID (%s)", silc_id_render(client_id, SILC_ID_CLIENT))); @@ -326,10 +329,14 @@ static SilcUInt16 silc_client_get_clients_i(SilcClient client, SILC_LOG_DEBUG(("Resolve client by %s command", silc_get_command_name(command))); - if (!client || !conn) + if (!client || !conn) { + SILC_LOG_ERROR(("Missing arguments to silc_client_get_clients call")); return 0; - if (!nickname && !attributes) + } + if (!nickname && !attributes) { + SILC_LOG_ERROR(("Missing arguments to silc_client_get_clients call")); return 0; + } /* Parse server name from the nickname if set */ if (silc_parse_userfqdn(nickname, nick, sizeof(nick), diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index 12d22a8b..10c36a32 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -928,13 +928,15 @@ SILC_FSM_STATE(silc_client_notify_cmode_change) if (!(channel->mode & SILC_CHANNEL_MODE_ULIMIT)) channel->user_limit = 0; - /* Save the new mode */ - channel->mode = mode; - /* Get the channel public key that was added or removed */ tmp = silc_argument_get_arg_type(args, 7, &tmp_len); if (tmp) - silc_client_channel_save_public_keys(channel, tmp, tmp_len); + silc_client_channel_save_public_keys(channel, tmp, tmp_len, FALSE); + else if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) + silc_client_channel_save_public_keys(channel, NULL, 0, TRUE); + + /* Save the new mode */ + channel->mode = mode; silc_rwlock_unlock(channel->internal.lock); diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index 9b6002e5..c9884942 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -624,6 +624,16 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys, silc_free(keys); } +/* Return private message key from the client entry. */ + +SilcBool +silc_client_private_message_key_is_set(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry) +{ + return client_entry->internal.send_key != NULL; +} + /* Sets away `message'. The away message may be set when the client's mode is changed to SILC_UMODE_GONE and the client whishes to reply to anyone who sends private message. The `message' will be sent diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 86ce6acb..f7fd114a 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -1836,10 +1836,14 @@ SILC_FSM_STATE(silc_client_command_cmode) NULL, NULL, 1, 1, silc_buffer_datalen(chidp)); silc_buffer_free(chidp); + silc_client_unref_channel(client, conn, channel); /* Notify application */ COMMAND(SILC_STATUS_OK); - goto out; + + /** Wait for command reply */ + silc_fsm_next(fsm, silc_client_command_reply_wait); + return SILC_FSM_CONTINUE; } if (cmd->argc >= 4) { diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index dd68d9ce..9dda29d3 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -1290,7 +1290,7 @@ SILC_FSM_STATE(silc_client_command_reply_join) /* Get channel public key list */ tmp = silc_argument_get_arg_type(args, 16, &len); if (tmp) - silc_client_channel_save_public_keys(channel, tmp, len); + silc_client_channel_save_public_keys(channel, tmp, len, FALSE); /* Set current channel */ conn->current_channel = channel; @@ -1420,7 +1420,6 @@ SILC_FSM_STATE(silc_client_command_reply_cmode) SilcChannelEntry channel; SilcUInt32 len; SilcPublicKey public_key = NULL; - SilcDList channel_pubkeys = NULL; SilcID id; /* Sanity checks */ @@ -1451,13 +1450,10 @@ SILC_FSM_STATE(silc_client_command_reply_cmode) ERROR_CALLBACK(SILC_STATUS_ERR_NOT_ENOUGH_PARAMS); goto out; } + SILC_GET32_MSB(mode, tmp); silc_rwlock_wrlock(channel->internal.lock); - /* Save the mode */ - SILC_GET32_MSB(mode, tmp); - channel->mode = mode; - /* Get user limit */ tmp = silc_argument_get_arg_type(args, 6, &len); if (tmp && len == 4) @@ -1468,15 +1464,18 @@ SILC_FSM_STATE(silc_client_command_reply_cmode) /* Get channel public key(s) */ tmp = silc_argument_get_arg_type(args, 5, &len); if (tmp) - silc_client_channel_save_public_keys(channel, tmp, len); + silc_client_channel_save_public_keys(channel, tmp, len, FALSE); + else if (channel->mode & SILC_CHANNEL_MODE_CHANNEL_AUTH) + silc_client_channel_save_public_keys(channel, NULL, 0, TRUE); + + /* Save the mode */ + channel->mode = mode; silc_rwlock_unlock(channel->internal.lock); /* Notify application */ silc_client_command_callback(cmd, channel, mode, public_key, - channel_pubkeys, channel->user_limit); - - silc_argument_list_free(channel_pubkeys, SILC_ARGUMENT_PUBLIC_KEY); + channel->channel_pubkeys, channel->user_limit); out: if (public_key) diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index 622670b3..f491e37e 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -1611,6 +1611,26 @@ silc_client_list_private_message_keys(SilcClient client, void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys, SilcUInt32 key_count); +/****f* silcclient/SilcClientAPI/silc_client_private_message_key_is_set + * + * SYNOPSIS + * + * SilcBool + * silc_client_private_message_key_is_set(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry); + * + * DESCRIPTION + * + * Returns TRUE if the private message key has been set for the client + * entry indicated by `client_entry'. + * + ***/ +SilcBool +silc_client_private_message_key_is_set(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry); + /* Channel private key management */ -- 2.24.0