5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "silcincludes.h"
22 #include "silcclient.h"
23 #include "client_internal.h"
25 /* Add one attribute that was found from hash table */
27 static void silc_client_attributes_process_foreach(void *key, void *context,
30 SilcAttribute attribute = (SilcAttribute)(SilcUInt32)key;
31 SilcAttributePayload attr = context;
32 SilcBuffer buffer = user_context;
33 const unsigned char *data;
37 SILC_LOG_DEBUG(("Attribute %d was not set", attribute));
39 /* USER_PUBLIC_KEY we have set earlier */
40 if (attribute == SILC_ATTRIBUTE_USER_PUBLIC_KEY)
43 /* The requested attribute was not found */
44 buffer = silc_attribute_payload_encode(buffer, attribute,
45 SILC_ATTRIBUTE_FLAG_INVALID,
50 SILC_LOG_DEBUG(("Attribute %d found", attribute));
51 data = silc_attribute_get_data(attr, &data_len);
52 buffer = silc_attribute_payload_encode_data(buffer, attribute,
53 SILC_ATTRIBUTE_FLAG_VALID,
57 /* Process list of attributes. Returns reply to the requested attributes. */
59 SilcBuffer silc_client_attributes_process(SilcClient client,
60 SilcSocketConnection sock,
63 SilcClientConnection conn = sock->user_data;
64 SilcBuffer buffer = NULL;
65 SilcAttribute attribute;
66 SilcAttributePayload attr;
67 SilcAttributeObjPk pk;
68 unsigned char sign[2048];
71 SILC_LOG_DEBUG(("Process Requested Attributes"));
73 /* If nothing is set by application assume that we don't want to use
74 attributes, ignore the request. */
78 /* Always put our public key. */
80 pk.data = silc_pkcs_public_key_encode(client->public_key, &pk.data_len);
81 buffer = silc_attribute_payload_encode(buffer,
82 SILC_ATTRIBUTE_USER_PUBLIC_KEY,
83 pk.data ? SILC_ATTRIBUTE_FLAG_VALID :
84 SILC_ATTRIBUTE_FLAG_INVALID,
88 /* Go through all requested attributes */
89 silc_dlist_start(attrs);
90 while ((attr = silc_dlist_get(attrs)) != SILC_LIST_END) {
91 /* Put all attributes of this type */
92 attribute = silc_attribute_get_attribute(attr);
94 /* Ignore signature since we will compute it later */
95 if (attribute == SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE)
98 silc_hash_table_find_foreach(conn->attrs, (void *)(SilcUInt32)attribute,
99 silc_client_attributes_process_foreach,
103 /* Finally compute the digital signature of all the data we provided. */
104 if (silc_pkcs_sign_with_hash(client->pkcs, client->internal->sha1hash,
105 buffer->data, buffer->len,
109 pk.data_len = sign_len;
111 silc_attribute_payload_encode(buffer,
112 SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE,
113 SILC_ATTRIBUTE_FLAG_VALID,
120 static void silc_client_attribute_destruct(void *key, void *context,
123 silc_attribute_payload_free(context);
126 /* Add new attribute */
128 SilcAttributePayload silc_client_attribute_add(SilcClient client,
129 SilcClientConnection conn,
130 SilcAttribute attribute,
132 SilcUInt32 object_size)
134 SilcAttributePayload attr;
136 attr = silc_attribute_payload_alloc(attribute, SILC_ATTRIBUTE_FLAG_VALID,
137 object, object_size);
142 conn->attrs = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL,
143 NULL, silc_client_attribute_destruct,
145 silc_hash_table_add(conn->attrs, (void *)(SilcUInt32)attribute, attr);
149 /* Delete one attribute */
151 bool silc_client_attribute_del(SilcClient client,
152 SilcClientConnection conn,
153 SilcAttributePayload attr)
155 SilcAttribute attribute = silc_attribute_get_attribute(attr);
158 ret = silc_hash_table_del_by_context(conn->attrs,
159 (void *)(SilcUInt32)attribute, attr);
162 if (!silc_hash_table_count(conn->attrs)) {
163 silc_hash_table_free(conn->attrs);
170 /* Return all attributes */
172 const SilcHashTable silc_client_attributes_get(SilcClient client,
173 SilcClientConnection conn)
175 return (const SilcHashTable)conn->attrs;
178 /* Construct a Requested Attributes buffer. If the `attribute' is zero (0)
179 then all attributes are requested. Additionally `attribute' and
180 all variable arguments can be one requested attribute. Always set
181 the last requested attribute to zero (0) to complete list of
182 requested attribute. */
184 SilcBuffer silc_client_attributes_request(SilcAttribute attribute, ...)
187 SilcBuffer buffer = NULL;
190 return silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO,
191 SILC_ATTRIBUTE_SERVICE,
192 SILC_ATTRIBUTE_STATUS_MOOD,
193 SILC_ATTRIBUTE_STATUS_FREETEXT,
194 SILC_ATTRIBUTE_STATUS_MESSAGE,
195 SILC_ATTRIBUTE_PREFERRED_LANGUAGE,
196 SILC_ATTRIBUTE_PREFERRED_CONTACT,
197 SILC_ATTRIBUTE_TIMEZONE,
198 SILC_ATTRIBUTE_GEOLOCATION,
199 SILC_ATTRIBUTE_DEVICE_INFO,
200 SILC_ATTRIBUTE_USER_PUBLIC_KEY, 0);
202 va_start(va, attribute);
204 buffer = silc_attribute_payload_encode(buffer, attribute, 0, NULL, 0);
205 attribute = (SilcAttribute)va_arg(va, SilcUInt32);