From c490eec84297d7f79a09e2c6b923664df5db96df Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 7 Oct 2002 15:47:27 +0000 Subject: [PATCH] Remove silc_attribute_payload_encode_list, improved the silc_attribute_payload_encode function to be able to encode list of attributes, and to do automatic encoding of the objects. --- lib/silccore/silcattrs.c | 237 +++++++++++++++++++++++++++++---------- lib/silccore/silcattrs.h | 50 ++++----- 2 files changed, 199 insertions(+), 88 deletions(-) diff --git a/lib/silccore/silcattrs.c b/lib/silccore/silcattrs.c index 9359bf8b..1f38dc68 100644 --- a/lib/silccore/silcattrs.c +++ b/lib/silccore/silcattrs.c @@ -74,29 +74,196 @@ silc_attribute_payload_parse(const unsigned char *payload, return NULL; } -/* Encode one attribute payload */ +/* Encode one attribute payload to buffer */ -SilcBuffer silc_attribute_payload_encode(SilcAttribute attribute, +SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, + SilcAttribute attribute, SilcAttributeFlags flags, - const unsigned char *data, - SilcUInt32 data_len) + void *object, + SilcUInt32 object_size) { - SilcBuffer buffer; + SilcBuffer buffer, tmpbuf = NULL; + unsigned char tmp[4], *str = NULL; + int len; SILC_LOG_DEBUG(("Encoding Attribute Payload")); - buffer = silc_buffer_alloc_size(4 + data_len); - if (!buffer) - return NULL; + /* Encode according to attribute type */ + if (flags & SILC_ATTRIBUTE_FLAG_VALID) { + if (!object || !object_size) + return NULL; + + switch (attribute) { + + case SILC_ATTRIBUTE_NONE: + break; + + case SILC_ATTRIBUTE_USER_INFO: + SILC_NOT_IMPLEMENTED("SILC_ATTRIBUTE_USER_INFO"); + break; + + case SILC_ATTRIBUTE_SERVICE: + { + SilcAttributeObjService *service = object; + if (object_size != sizeof(*service)) + return NULL; + len = strlen(service->address); + str = silc_malloc(7 + len); + if (!str) + return NULL; + SILC_PUT32_MSB(service->port, str); + SILC_PUT16_MSB(len, str + 4); + memcpy(str + 6, service->address, len); + str[6 + len] = service->status; + } + break; + + case SILC_ATTRIBUTE_STATUS_MOOD: + case SILC_ATTRIBUTE_PREFERRED_CONTACT: + { + SilcUInt32 mask = (SilcUInt32)object; + if (object_size != sizeof(SilcUInt32)) + return NULL; + SILC_PUT32_MSB(mask, tmp); + object = tmp; + object_size = sizeof(SilcUInt32); + } + break; + + case SILC_ATTRIBUTE_STATUS_FREETEXT: + case SILC_ATTRIBUTE_PREFERRED_LANGUAGE: + case SILC_ATTRIBUTE_TIMEZONE: + { + unsigned char *string = object; + str = silc_malloc(2 + object_size); + if (!str) + return NULL; + SILC_PUT16_MSB(object_size, str); + memcpy(str + 2, string, object_size); + object = str; + object_size += 2; + } + break; + + case SILC_ATTRIBUTE_STATUS_MESSAGE: + case SILC_ATTRIBUTE_EXTENSION: + { + SilcAttributeObjMime *mime = object; + if (object_size != sizeof(*mime)) + return NULL; + object = (void *)mime->mime; + object_size = mime->mime_len; + } + break; + + case SILC_ATTRIBUTE_GEOLOCATION: + { + SilcAttributeObjGeo *geo = object; + if (object_size != sizeof(*geo)) + return NULL; + len = + (geo->longitude ? strlen(geo->longitude) : 0) + + (geo->latitude ? strlen(geo->latitude) : 0) + + (geo->altitude ? strlen(geo->altitude) : 0) + + (geo->accuracy ? strlen(geo->accuracy) : 0); + if (!len) + return NULL; + tmpbuf = silc_buffer_alloc_size(8 + len); + if (!tmpbuf) + return NULL; + silc_buffer_format(tmpbuf, + SILC_STR_UI16_STRING(geo->longitude), + SILC_STR_UI16_STRING(geo->latitude), + SILC_STR_UI16_STRING(geo->altitude), + SILC_STR_UI16_STRING(geo->accuracy), + SILC_STR_END); + } + break; + + case SILC_ATTRIBUTE_DEVICE_INFO: + { + SilcAttributeObjDevice *dev = object; + if (object_size != sizeof(*dev)) + return NULL; + len = + (dev->manufacturer ? strlen(dev->manufacturer) : 0) + + (dev->version ? strlen(dev->version) : 0) + + (dev->model ? strlen(dev->model) : 0) + + (dev->language ? strlen(dev->language) : 0); + tmpbuf = silc_buffer_alloc_size(4 + 8 + len); + if (!tmpbuf) + return NULL; + silc_buffer_format(tmpbuf, + SILC_STR_UI_INT(dev->type), + SILC_STR_UI16_STRING(dev->manufacturer), + SILC_STR_UI16_STRING(dev->version), + SILC_STR_UI16_STRING(dev->model), + SILC_STR_UI16_STRING(dev->language), + SILC_STR_END); + } + break; + + case SILC_ATTRIBUTE_USER_PUBLIC_KEY: + case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY: + { + SilcAttributeObjPk *pk = object; + if (object_size != sizeof(*pk)) + return NULL; + len = (pk->type ? strlen(pk->type) : 0); + tmpbuf = silc_buffer_alloc_size(2 + len + pk->data_len); + if (!tmpbuf) + return NULL; + silc_buffer_format(tmpbuf, + SILC_STR_UI_SHORT(len), + SILC_STR_UI16_STRING(pk->type), + SILC_STR_UI_XNSTRING(pk->data, pk->data_len), + SILC_STR_END); + } + break; + + case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE: + case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE: + { + SilcAttributeObjPk *pk = object; + if (object_size != sizeof(*pk)) + return NULL; + object = pk->data; + object_size = pk->data_len; + } + break; + + default: + /* Other attributes must be in correct format already */ + break; + } + } + + buffer = attrs; + len = 4 + object_size; + + if (!buffer) { + buffer = silc_buffer_alloc_size(len); + } else { + buffer = silc_buffer_realloc(buffer, + (buffer ? buffer->truelen + len : len)); + silc_buffer_pull_tail(buffer, (buffer->end - buffer->data)); + } - /* Encode the Attribute Payload */ silc_buffer_format(buffer, SILC_STR_UI_CHAR(attribute), SILC_STR_UI_CHAR(flags), - SILC_STR_UI_SHORT((SilcUInt16)data_len), - SILC_STR_UI_XNSTRING(data, data_len), + SILC_STR_UI_SHORT((SilcUInt16)object_size), + SILC_STR_UI_XNSTRING(object, object_size), SILC_STR_END); + silc_buffer_pull(buffer, len); + if (buffer) + silc_buffer_push(buffer, buffer->data - buffer->head); + + if (tmpbuf) + silc_buffer_free(tmpbuf); + silc_free(str); + return buffer; } @@ -148,51 +315,6 @@ SilcDList silc_attribute_payload_parse_list(const unsigned char *payload, return NULL; } -/* Encode list of payloads */ - -SilcBuffer silc_attribute_payload_encode_list(SilcUInt32 num_attrs, ...) -{ - SilcBuffer buffer = NULL; - va_list ap; - int i, len = 0; - SilcAttribute attribute; - SilcAttributeFlags flags; - unsigned char *data; - SilcUInt32 data_len; - - if (!num_attrs) - return NULL; - - va_start(ap, num_attrs); - for (i = 0; i < num_attrs; i++) { - attribute = va_arg(ap, SilcUInt32); - flags = va_arg(ap, SilcUInt32); - data = va_arg(ap, unsigned char *); - data_len = va_arg(ap, SilcUInt32); - - if (data || !data_len) - continue; - - len = 4 + data_len; - buffer = silc_buffer_realloc(buffer, - (buffer ? buffer->truelen + len : len)); - silc_buffer_pull_tail(buffer, (buffer->end - buffer->data)); - silc_buffer_format(buffer, - SILC_STR_UI_CHAR(attribute), - SILC_STR_UI_CHAR(flags), - SILC_STR_UI_SHORT((SilcUInt16)data_len), - SILC_STR_UI_XNSTRING(data, data_len), - SILC_STR_END); - silc_buffer_pull(buffer, len); - } - va_end(ap); - - if (buffer) - silc_buffer_push(buffer, buffer->data - buffer->head); - - return buffer; -} - /* Free Attribute Payload */ void silc_attribute_payload_free(SilcAttributePayload payload) @@ -249,7 +371,8 @@ bool silc_attribute_get_object(SilcAttributePayload payload, SilcUInt16 len; bool ret = FALSE; - if (!attribute || !object || !(*object)) + if (!attribute || payload->attribute != attribute || !object || !(*object) || + payload->flags & SILC_ATTRIBUTE_FLAG_INVALID) return FALSE; switch (attribute) { diff --git a/lib/silccore/silcattrs.h b/lib/silccore/silcattrs.h index 89e6c00a..4df88b58 100644 --- a/lib/silccore/silcattrs.h +++ b/lib/silccore/silcattrs.h @@ -199,22 +199,30 @@ silc_attribute_payload_parse(const unsigned char *payload, * * SYNOPSIS * - * SilcBuffer silc_attribute_payload_encode(SilcAttribute attribute, + * SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, + * SilcAttribute attribute, * SilcAttributeFlags flags, - * const unsigned char *data, - * SilcUInt32 data_len); + * void *object, + * SilcUInt32 object_size); * * DESCRIPTION * - * Encodes one attribute payload and returns allocated buffer. The - * `attributes' is the attribute type with `flags' and the actual - * attribute data indicated by `data' and `data_len'. + * Encodes one attribute payload into the `attrs' buffer and returns + * pointer to the buffer, which may be different in case the buffer + * was reallocated. If `attrs' is NULL for first attribute this + * allocates the buffer and returns it. This can be called multiple + * times to add multiple attributes to the `attrs' buffer. The `flags' + * indicates the validity of the added attribute. + * + * The `object' must always be the same data type as defined with + * SilcAttribute (see the comments) for all attributes. * ***/ -SilcBuffer silc_attribute_payload_encode(SilcAttribute attribute, +SilcBuffer silc_attribute_payload_encode(SilcBuffer attrs, + SilcAttribute attribute, SilcAttributeFlags flags, - const unsigned char *data, - SilcUInt32 data_len); + void *object, + SilcUInt32 object_size); /****f* silccore/SilcAttributesAPI/silc_attribute_payload_parse_list * @@ -229,33 +237,13 @@ SilcBuffer silc_attribute_payload_encode(SilcAttribute attribute, * Parses list of Attribute payloads returning list of payloads. This * is equivalent to the silc_attribute_payload_parse except that the * `buffer' now includes multiple Attribute Payloads one after the other. - * You can produce such a list with silc_attribute_payload_encode_list + * You can produce such a list with silc_attribute_payload_encode * function. * ***/ SilcDList silc_attribute_payload_parse_list(const unsigned char *payload, SilcUInt32 payload_len); -/****f* silccore/SilcAttributesAPI/silc_attribute_payload_encode_list - * - * SYNOPSIS - * - * SilcBuffer silc_attribute_payload_encode(SilcUInt32 num_attrs, ...); - * - * DESCRIPTION - * - * Encodes a list of Attribute payloads. The `num_attrs' indicates the - * number of attributes sent as argument. The variable argument list - * sent as argument includes the attribute, attribute flags, attribute - * data and attribute data length. One attribute is one of these - * { attribute, attribute flags, data and data length } arguments. - * Returns the attribute payloads in data buffer one after the other. - * You can parse such list with silc_attribute_payload_parse_list - * function. - * - ***/ -SilcBuffer silc_attribute_payload_encode_list(SilcUInt32 num_attrs, ...); - /****f* silccore/SilcAttributesAPI/silc_attribute_payload_free * * SYNOPSIS @@ -437,7 +425,7 @@ typedef struct { * * bool silc_attribute_get_object(SilcAttributePayload payload, * SilcAttribute attribute, - * const void **object, + * void **object, * SilcUInt32 object_size); * * DESCRIPTION -- 2.24.0