From b748967dcf55728dfd621773467499808cd3b47b Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 14 Oct 2002 19:04:35 +0000 Subject: [PATCH] Fixed some bugs in Requested Attributes support. Moved sha1hash and md5hash from internal context SilcClient for application usage. --- lib/silcclient/client.c | 4 +- lib/silcclient/client.h | 4 ++ lib/silcclient/client_attrs.c | 65 ++++++++++++++++++++++++++------ lib/silcclient/client_channel.c | 5 +-- lib/silcclient/client_internal.h | 2 - lib/silcclient/client_prvmsg.c | 2 +- lib/silcclient/command.c | 9 ++--- lib/silcclient/silcclient.h | 14 +++++-- 8 files changed, 76 insertions(+), 29 deletions(-) diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 45d81d04..8b50fa4a 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -103,8 +103,8 @@ int silc_client_init(SilcClient client) SILC_LOG_DEBUG(("Initializing client")); /* Initialize hash functions for client to use */ - silc_hash_alloc("md5", &client->internal->md5hash); - silc_hash_alloc("sha1", &client->internal->sha1hash); + silc_hash_alloc("md5", &client->md5hash); + silc_hash_alloc("sha1", &client->sha1hash); /* Initialize none cipher */ silc_cipher_alloc("none", &client->internal->none_cipher); diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index 6fbdbd4a..6b9965be 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -167,6 +167,10 @@ struct SilcClientStruct { touch this. This the context sent as argument to silc_client_alloc. */ void *application; + /* Generic hash context for application usage */ + SilcHash md5hash; + SilcHash sha1hash; + /* Internal data for client library. Application cannot access this data at all. */ SilcClientInternal internal; diff --git a/lib/silcclient/client_attrs.c b/lib/silcclient/client_attrs.c index 53693106..4a28d9e8 100644 --- a/lib/silcclient/client_attrs.c +++ b/lib/silcclient/client_attrs.c @@ -22,6 +22,10 @@ #include "silcclient.h" #include "client_internal.h" +typedef struct { + SilcBuffer buffer; +} SilcAttrForeach; + /* Add one attribute that was found from hash table */ static void silc_client_attributes_process_foreach(void *key, void *context, @@ -29,7 +33,7 @@ static void silc_client_attributes_process_foreach(void *key, void *context, { SilcAttribute attribute = (SilcAttribute)(SilcUInt32)key; SilcAttributePayload attr = context; - SilcBuffer buffer = user_context; + SilcAttrForeach *f = user_context; const unsigned char *data; SilcUInt32 data_len; @@ -41,17 +45,28 @@ static void silc_client_attributes_process_foreach(void *key, void *context, return; /* The requested attribute was not found */ - buffer = silc_attribute_payload_encode(buffer, attribute, - SILC_ATTRIBUTE_FLAG_INVALID, - NULL, 0); + f->buffer = silc_attribute_payload_encode(f->buffer, attribute, + SILC_ATTRIBUTE_FLAG_INVALID, + NULL, 0); return; } SILC_LOG_DEBUG(("Attribute %d found", attribute)); data = silc_attribute_get_data(attr, &data_len); - buffer = silc_attribute_payload_encode_data(buffer, attribute, + + /* We replace the TIMEZONE with valid value here */ + if (attribute == SILC_ATTRIBUTE_TIMEZONE) { + data = (const unsigned char *)silc_get_time(0); + data_len = strlen(data); + f->buffer = silc_attribute_payload_encode(f->buffer, attribute, SILC_ATTRIBUTE_FLAG_VALID, - data, data_len); + (void *)data, data_len); + return; + } + + f->buffer = silc_attribute_payload_encode_data(f->buffer, attribute, + SILC_ATTRIBUTE_FLAG_VALID, + data, data_len); } /* Process list of attributes. Returns reply to the requested attributes. */ @@ -62,6 +77,7 @@ SilcBuffer silc_client_attributes_process(SilcClient client, { SilcClientConnection conn = sock->user_data; SilcBuffer buffer = NULL; + SilcAttrForeach f; SilcAttribute attribute; SilcAttributePayload attr; SilcAttributeObjPk pk; @@ -86,6 +102,7 @@ SilcBuffer silc_client_attributes_process(SilcClient client, silc_free(pk.data); /* Go through all requested attributes */ + f.buffer = buffer; silc_dlist_start(attrs); while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) { /* Put all attributes of this type */ @@ -97,11 +114,12 @@ SilcBuffer silc_client_attributes_process(SilcClient client, silc_hash_table_find_foreach(conn->attrs, (void *)(SilcUInt32)attribute, silc_client_attributes_process_foreach, - buffer); + &f); } + buffer = f.buffer; /* Finally compute the digital signature of all the data we provided. */ - if (silc_pkcs_sign_with_hash(client->pkcs, client->internal->sha1hash, + if (silc_pkcs_sign_with_hash(client->pkcs, client->sha1hash, buffer->data, buffer->len, sign, &sign_len)) { pk.type = NULL; @@ -146,17 +164,42 @@ SilcAttributePayload silc_client_attribute_add(SilcClient client, return attr; } +static void silc_client_attribute_del_foreach(void *key, void *context, + void *user_context) +{ + SilcClientConnection conn = user_context; + SilcAttributePayload attr = context; + SilcAttribute attribute; + if (!attr) + return; + attribute = silc_attribute_get_attribute(attr); + silc_hash_table_del_by_context(conn->attrs, + (void *)(SilcUInt32)attribute, attr); +} + /* Delete one attribute */ bool silc_client_attribute_del(SilcClient client, SilcClientConnection conn, + SilcAttribute attribute, SilcAttributePayload attr) { - SilcAttribute attribute = silc_attribute_get_attribute(attr); bool ret; - ret = silc_hash_table_del_by_context(conn->attrs, - (void *)(SilcUInt32)attribute, attr); + if (!conn->attrs) + return FALSE; + + if (attr) { + attribute = silc_attribute_get_attribute(attr); + ret = silc_hash_table_del_by_context(conn->attrs, + (void *)(SilcUInt32)attribute, attr); + } else if (attribute) { + silc_hash_table_find_foreach(conn->attrs, (void *)(SilcUInt32)attribute, + silc_client_attribute_del_foreach, conn); + ret = TRUE; + } else{ + return FALSE; + } if (ret) if (!silc_hash_table_count(conn->attrs)) { diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 6d38c42d..f72d4def 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -114,8 +114,7 @@ void silc_client_send_channel_message(SilcClient client, for (i = 0; i < iv_len; i++) channel->iv[i] = silc_rng_get_byte(client->rng); else - silc_hash_make(client->internal->md5hash, channel->iv, iv_len, - channel->iv); + silc_hash_make(client->md5hash, channel->iv, iv_len, channel->iv); /* Encode the channel payload. This also encrypts the message payload. */ payload = silc_channel_message_payload_encode(flags, data_len, data, iv_len, @@ -513,7 +512,7 @@ int silc_client_add_channel_private_key(SilcClient client, /* Produce the key material */ keymat = silc_calloc(1, sizeof(*keymat)); if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, - client->internal->md5hash, keymat) + client->md5hash, keymat) != SILC_SKE_STATUS_OK) return FALSE; diff --git a/lib/silcclient/client_internal.h b/lib/silcclient/client_internal.h index d5e6fc78..540795d5 100644 --- a/lib/silcclient/client_internal.h +++ b/lib/silcclient/client_internal.h @@ -75,8 +75,6 @@ struct SilcClientInternalStruct { /* Generic cipher and hash objects. */ SilcCipher none_cipher; - SilcHash md5hash; - SilcHash sha1hash; SilcHmac md5hmac; SilcHmac sha1hmac; diff --git a/lib/silcclient/client_prvmsg.c b/lib/silcclient/client_prvmsg.c index dca5d000..2d065abe 100644 --- a/lib/silcclient/client_prvmsg.c +++ b/lib/silcclient/client_prvmsg.c @@ -357,7 +357,7 @@ int silc_client_add_private_message_key(SilcClient client, /* Produce the key material as the protocol defines */ keymat = silc_calloc(1, sizeof(*keymat)); if (silc_ske_process_key_material_data(key, key_len, 16, 256, 16, - client->internal->md5hash, keymat) + client->md5hash, keymat) != SILC_SKE_STATUS_OK) return FALSE; diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 83e6bb69..f7b3ec0e 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -1018,8 +1018,7 @@ SILC_CLIENT_CMD_FUNC(join) auth = silc_auth_public_key_auth_generate(cmd->client->public_key, cmd->client->private_key, cmd->client->rng, - cmd->client->internal-> - sha1hash, + cmd->client->sha1hash, conn->local_id, SILC_ID_CLIENT); i++; @@ -1431,8 +1430,7 @@ SILC_CLIENT_CMD_FUNC(cmode) auth = silc_auth_public_key_auth_generate(cmd->client->public_key, cmd->client->private_key, cmd->client->rng, - cmd->client->internal-> - sha1hash, + cmd->client->sha1hash, conn->local_id, SILC_ID_CLIENT); arg = auth->data; @@ -1583,8 +1581,7 @@ SILC_CLIENT_CMD_FUNC(cumode) auth = silc_auth_public_key_auth_generate(cmd->client->public_key, cmd->client->private_key, cmd->client->rng, - cmd->client->internal-> - sha1hash, + cmd->client->sha1hash, conn->local_id, SILC_ID_CLIENT); mode |= SILC_CHANNEL_UMODE_CHANFO; diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index e301f158..d3e8929f 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -2242,18 +2242,24 @@ SilcAttributePayload silc_client_attribute_add(SilcClient client, * * bool silc_client_attribute_del(SilcClient client, * SilcClientConnection conn, + * SilcAttribute attribute, * SilcAttributePayload attr); * * DESCRIPTION * - * Delete the Requested Attribute indicated by `attribute' from the - * client. You may get all added attributes with the function - * silc_client_attributes_get. Returns TRUE if the attribute was - * found and deleted. + * Delete a Requested Attribute from the client. If the `attribute' + * is non-zero then all attributes of that type are deleted and the + * `attr' is ignored. If `attr' is non-NULL then that specific + * attribute is deleted and `attribute' is ignored. + * + * You may get all added attributes with the function + * silc_client_attributes_get and to get the SilcAttributePayload. + * This function Returns TRUE if the attribute was found and deleted. * ***/ bool silc_client_attribute_del(SilcClient client, SilcClientConnection conn, + SilcAttribute attribute, SilcAttributePayload attr); /****f* silcclient/SilcClientAPI/silc_client_attributes_get -- 2.24.0