From 54756d9cd19d09d28e1b317810faa961a6ff5d51 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 6 May 2007 11:27:21 +0000 Subject: [PATCH] Allows formatted nicknames as input for silc_client_get_clients and silc_client_get_clients_whois. Fixed channel message private key setting. Addec current channel key cipher and HMAC algorithm names to SilcClientEntry. --- CHANGES | 11 ++++++++ lib/silcclient/client_channel.c | 47 +++++++++++++++++++++++-------- lib/silcclient/client_connect.c | 1 - lib/silcclient/client_entry.c | 20 +++++++++++-- lib/silcclient/silcclient.h | 10 ++++--- lib/silcclient/silcclient_entry.h | 8 ++++++ 6 files changed, 78 insertions(+), 19 deletions(-) diff --git a/CHANGES b/CHANGES index 7766698d..64d51c8e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,14 @@ +Sun May 6 12:43:19 EEST 2007 Pekka Riikonen + + * Added current channel key cipher name and HMAC name to + SilcChannelEntry. Fixed channel private key creation. + Affected files are lib/silcclient/client_channel.c, + client_entry and silcclient_entry.h. + + * Allow formatted nicknames as input to silc_client_get_clients + and silc_client_get_clients_whois. Affected file is + lib/silcclient/client_entry.c. + Thu May 3 18:07:50 EEST 2007 Pekka Riikonen * Imported libtommath 0.41. Renamed all mp_* functions to diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 7143c0e7..077399b2 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -74,12 +74,12 @@ SilcBool silc_client_send_channel_message(SilcClient client, if (channel->internal.private_keys) { if (key) { /* Use key application specified */ - cipher = key->cipher; + cipher = key->send_key; hmac = key->hmac; } else if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY && channel->internal.curr_key) { /* Use current private key */ - cipher = channel->internal.curr_key->cipher; + cipher = channel->internal.curr_key->send_key; hmac = channel->internal.curr_key->hmac; } else if (channel->mode & SILC_CHANNEL_MODE_PRIVKEY && !channel->internal.curr_key && @@ -88,7 +88,7 @@ SilcBool silc_client_send_channel_message(SilcClient client, and private keys are set. */ silc_dlist_start(channel->internal.private_keys); key = silc_dlist_get(channel->internal.private_keys); - cipher = key->cipher; + cipher = key->send_key; hmac = key->hmac; /* Use this key as current private key */ @@ -291,7 +291,7 @@ SILC_FSM_STATE(silc_client_channel_message) /* Parse the message payload. This also decrypts the payload */ payload = silc_message_payload_parse(silc_buffer_data(buffer), silc_buffer_len(buffer), - FALSE, FALSE, key->cipher, + FALSE, FALSE, key->receive_key, key->hmac, packet->src_id, packet->src_id_len, packet->dst_id, @@ -463,6 +463,9 @@ SilcBool silc_client_save_channel_key(SilcClient client, return FALSE; } + channel->cipher = silc_cipher_get_name(channel->internal.send_key); + channel->hmac = silc_hmac_get_name(channel->internal.hmac); + /* Set HMAC key */ silc_hash_make(silc_hmac_get_hash(channel->internal.hmac), key, tmp_len, hash); @@ -545,20 +548,30 @@ SilcBool silc_client_add_channel_private_key(SilcClient client, entry->name = name ? strdup(name) : NULL; /* Allocate the cipher and set the key */ - if (!silc_cipher_alloc(cipher, &entry->cipher)) { + if (!silc_cipher_alloc(cipher, &entry->send_key)) { + silc_free(entry); + silc_free(entry->name); + silc_ske_free_key_material(keymat); + return FALSE; + } + if (!silc_cipher_alloc(cipher, &entry->receive_key)) { silc_free(entry); silc_free(entry->name); + silc_cipher_free(entry->send_key); silc_ske_free_key_material(keymat); return FALSE; } - silc_cipher_set_key(entry->cipher, keymat->send_enc_key, + silc_cipher_set_key(entry->send_key, keymat->send_enc_key, keymat->enc_key_len, TRUE); + silc_cipher_set_key(entry->receive_key, keymat->send_enc_key, + keymat->enc_key_len, FALSE); /* Generate HMAC key from the channel key data and set it */ if (!silc_hmac_alloc(hmac, NULL, &entry->hmac)) { silc_free(entry); silc_free(entry->name); - silc_cipher_free(entry->cipher); + silc_cipher_free(entry->send_key); + silc_cipher_free(entry->receive_key); silc_ske_free_key_material(keymat); return FALSE; } @@ -571,8 +584,11 @@ SilcBool silc_client_add_channel_private_key(SilcClient client, /* Add to the private keys list */ silc_dlist_add(channel->internal.private_keys, entry); - if (!channel->internal.curr_key) + if (!channel->internal.curr_key) { channel->internal.curr_key = entry; + channel->cipher = silc_cipher_get_name(entry->send_key); + channel->hmac = silc_cipher_get_name(entry->send_key); + } /* Free the key material */ silc_ske_free_key_material(keymat); @@ -603,12 +619,15 @@ SilcBool silc_client_del_channel_private_keys(SilcClient client, while ((entry = silc_dlist_get(channel->internal.private_keys))) { silc_dlist_del(channel->internal.private_keys, entry); silc_free(entry->name); - silc_cipher_free(entry->cipher); + silc_cipher_free(entry->send_key); + silc_cipher_free(entry->receive_key); silc_hmac_free(entry->hmac); silc_free(entry); } channel->internal.curr_key = NULL; + channel->cipher = silc_cipher_get_name(channel->internal.send_key); + channel->hmac = silc_hmac_get_name(channel->internal.hmac); silc_dlist_uninit(channel->internal.private_keys); channel->internal.private_keys = NULL; @@ -640,12 +659,16 @@ SilcBool silc_client_del_channel_private_key(SilcClient client, if (entry != key) continue; - if (channel->internal.curr_key == entry) + if (channel->internal.curr_key == entry) { channel->internal.curr_key = NULL; + channel->cipher = silc_cipher_get_name(channel->internal.send_key); + channel->hmac = silc_hmac_get_name(channel->internal.hmac); + } silc_dlist_del(channel->internal.private_keys, entry); silc_free(entry->name); - silc_cipher_free(entry->cipher); + silc_cipher_free(entry->send_key); + silc_cipher_free(entry->receive_key); silc_hmac_free(entry->hmac); silc_free(entry); @@ -702,6 +725,8 @@ void silc_client_current_channel_private_key(SilcClient client, if (!channel) return; channel->internal.curr_key = key; + channel->cipher = silc_cipher_get_name(key->send_key); + channel->hmac = silc_hmac_get_name(key->hmac); } /***************************** Utility routines *****************************/ diff --git a/lib/silcclient/client_connect.c b/lib/silcclient/client_connect.c index f43e13d3..f1aedcbb 100644 --- a/lib/silcclient/client_connect.c +++ b/lib/silcclient/client_connect.c @@ -176,7 +176,6 @@ static void silc_client_ke_completion(SilcSKE ske, silc_ske_map_status(status)); conn->internal->status = SILC_CLIENT_CONN_ERROR_KE; - conn->internal->error = status; silc_ske_free_rekey_material(rekey); silc_fsm_next(fsm, silc_client_st_connect_error); diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index 0835408a..f4354a8a 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -77,7 +77,7 @@ SilcDList silc_client_get_clients_local_ext(SilcClient client, if (!client || !conn || !nickname) return NULL; - /* Parse nickname if it is formatted */ + /* Parse nickname in case it is formatted */ if (!silc_client_nickname_parse(client, conn, (char *)nickname, &parsed)) return NULL; @@ -320,7 +320,7 @@ static SilcUInt16 silc_client_get_clients_i(SilcClient client, void *context) { SilcClientGetClientInternal i; - char userhost[768 + 1]; + char nick[128 + 1], serv[256 + 1], userhost[768 + 1], *parsed = NULL; int len; SILC_LOG_DEBUG(("Resolve client by %s command", @@ -331,11 +331,24 @@ static SilcUInt16 silc_client_get_clients_i(SilcClient client, if (!nickname && !attributes) return 0; + /* Parse server name from the nickname if set */ + if (silc_parse_userfqdn(nickname, nick, sizeof(nick), + serv, sizeof(serv) == 2)) + server = (const char *)serv; + nickname = (const char *)nick; + + /* Parse nickname in case it is formatted */ + if (silc_client_nickname_parse(client, conn, (char *)nickname, &parsed)) + nickname = (const char *)parsed; + i = silc_calloc(1, sizeof(*i)); - if (!i) + if (!i) { + silc_free(parsed); return 0; + } i->clients = silc_dlist_init(); if (!i->clients) { + silc_free(parsed); silc_free(i); return 0; } @@ -351,6 +364,7 @@ static SilcUInt16 silc_client_get_clients_i(SilcClient client, } else if (nickname) { silc_strncat(userhost, sizeof(userhost) - 1, nickname, strlen(nickname)); } + silc_free(parsed); /* Send the command */ if (command == SILC_COMMAND_IDENTIFY) diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index 4a13dd7a..21b4dc82 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -391,7 +391,8 @@ typedef struct { */ struct SilcChannelPrivateKeyStruct { char *name; /* Application given name */ - SilcCipher cipher; /* The cipher and key */ + SilcCipher send_key; /* The cipher and key */ + SilcCipher receive_key; /* The cipher and key */ SilcHmac hmac; /* The HMAC and hmac key */ }; /***/ @@ -1552,9 +1553,10 @@ SilcBool silc_client_add_private_message_key_ske(SilcClient client, * * SYNOPSIS * - * SilcBool silc_client_del_private_message_key(SilcClient client, - * SilcClientConnection conn, - * SilcClientEntry client_entry); + * SilcBool + * silc_client_del_private_message_key(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry); * * DESCRIPTION * diff --git a/lib/silcclient/silcclient_entry.h b/lib/silcclient/silcclient_entry.h index 20f6e9e3..94106bad 100644 --- a/lib/silcclient/silcclient_entry.h +++ b/lib/silcclient/silcclient_entry.h @@ -133,6 +133,8 @@ struct SilcChannelEntryStruct { SilcHashTable user_list; /* Joined users. Key to hash table is SilcClientEntry, context is SilcChannelUser. */ + const char *cipher; /* Current channel cipher algorithm*/ + const char *hmac; /* Current channel HMAC algorithm */ void *context; /* Application specific context */ SilcChannelEntryInternal internal; @@ -327,6 +329,9 @@ void silc_client_list_free(SilcClient client, SilcClientConnection conn, * and can be accesses locally at a later time. The resolving is done * with IDENTIFY command. The `server' may be NULL. The server * associated with the nickname may be in the `nickname' (nick@server). + * The `nickname' may also be a formatted nickname in which case the + * formatting is ignored and the base nickname is used. If the nickname + * is formatted it must be formatted as defined in SilcClientParams. * Returns 0 on error and the command identifier used with the command * otherwise. * @@ -372,6 +377,9 @@ SilcUInt16 silc_client_get_clients(SilcClient client, * and can be accesses locally at a later time. The resolving is done * with WHOIS command. The `server' may be NULL. The server * associated with the nickname may be in the `nickname' (nick@server). + * The `nickname' may also be a formatted nickname in which case the + * formatting is ignored and the base nickname is used. If the nickname + * is formatted it must be formatted as defined in SilcClientParams. * Returns 0 on error and the command identifier used with the command * otherwise. * -- 2.24.0