Merged silc_1_0_branch to trunk.
[silc.git] / lib / silccore / silcattrs.c
index b69a9b6ba06769a8a14c2c444f1527aea76a2a69..7af8f6a052ed5068ee121ee5c3577e6d34b1edd5 100644 (file)
@@ -46,7 +46,7 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
 {
   SilcBuffer tmpbuf = NULL;
   unsigned char tmp[4], *str = NULL, *ret;
-  int len;
+  SilcUInt32 len;
 
   /* Encode according to attribute type */
   if (flags & SILC_ATTRIBUTE_FLAG_VALID) {
@@ -70,18 +70,23 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
     case SILC_ATTRIBUTE_SERVICE:
       {
        SilcAttributeObjService *service = object;
+       SilcUInt32 len2;
        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;
-       object = str;
-       object_size = 7 + len;
+       len2 = strlen(service->signon);
+       tmpbuf = silc_buffer_alloc_size(13 + len + len2);
+       silc_buffer_format(tmpbuf,
+                          SILC_STR_UI_INT(service->port),
+                          SILC_STR_UI_SHORT(len),
+                          SILC_STR_UI_XNSTRING(service->address, len),
+                          SILC_STR_UI_CHAR(service->status),
+                          SILC_STR_UI_SHORT(len2),
+                          SILC_STR_UI_XNSTRING(service->signon, len2),
+                          SILC_STR_UI_INT(service->idle),
+                          SILC_STR_END);
+       object = tmpbuf->data;
+       object_size = tmpbuf->len;
       }
       break;
 
@@ -126,7 +131,7 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
     case SILC_ATTRIBUTE_GEOLOCATION:
       {
        SilcAttributeObjGeo *geo = object;
-       int len1, len2, len3, len4;
+       SilcUInt32 len1, len2, len3, len4;
        if (object_size != sizeof(*geo))
          return NULL;
        len1 = (geo->longitude ? strlen(geo->longitude) : 0);
@@ -143,7 +148,7 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
                           SILC_STR_UI_SHORT(len1),
                           SILC_STR_UI16_STRING(len1 ? geo->longitude : ""),
                           SILC_STR_UI_SHORT(len2),
-                          SILC_STR_UI16_STRING(len ? geo->latitude : ""),
+                          SILC_STR_UI16_STRING(len2 ? geo->latitude : ""),
                           SILC_STR_UI_SHORT(len3),
                           SILC_STR_UI16_STRING(len3 ? geo->altitude : ""),
                           SILC_STR_UI_SHORT(len4),
@@ -157,7 +162,7 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
     case SILC_ATTRIBUTE_DEVICE_INFO:
       {
        SilcAttributeObjDevice *dev = object;
-       int len1, len2, len3, len4;
+       SilcUInt32 len1, len2, len3, len4;
        if (object_size != sizeof(*dev))
          return NULL;
        len1 = (dev->manufacturer ? strlen(dev->manufacturer) : 0);
@@ -173,9 +178,9 @@ silc_attribute_payload_encode_int(SilcAttribute attribute,
        silc_buffer_format(tmpbuf,
                           SILC_STR_UI_INT(dev->type),
                           SILC_STR_UI_SHORT(len1),
-                          SILC_STR_UI16_STRING(len ? dev->manufacturer : ""),
+                          SILC_STR_UI16_STRING(len1 ? dev->manufacturer : ""),
                           SILC_STR_UI_SHORT(len2),
-                          SILC_STR_UI16_STRING(len ? dev->version : ""),
+                          SILC_STR_UI16_STRING(len2 ? dev->version : ""),
                           SILC_STR_UI_SHORT(len3),
                           SILC_STR_UI16_STRING(len3 ? dev->model : ""),
                           SILC_STR_UI_SHORT(len4),
@@ -245,6 +250,7 @@ SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute,
                                                  SilcUInt32 object_size)
 {
   SilcAttributePayload attr;
+  SilcUInt32 tmp_len;
 
   attr = silc_calloc(1, sizeof(*attr));
   if (!attr)
@@ -254,8 +260,8 @@ SilcAttributePayload silc_attribute_payload_alloc(SilcAttribute attribute,
   attr->flags = flags;
   attr->data =
     silc_attribute_payload_encode_int(attribute, flags, object,
-                                     object_size,
-                                     (SilcUInt32 *)&attr->data_len);
+                                     object_size, &tmp_len);
+  attr->data_len = (SilcUInt16)tmp_len;
   if (!attr->data) {
     silc_free(attr);
     return NULL;
@@ -272,7 +278,8 @@ SilcDList silc_attribute_payload_parse(const unsigned char *payload,
   SilcBufferStruct buffer;
   SilcDList list;
   SilcAttributePayload newp;
-  int len, ret;
+  SilcUInt32 len;
+  int ret;
 
   SILC_LOG_DEBUG(("Parsing Attribute Payload list"));
 
@@ -292,7 +299,7 @@ SilcDList silc_attribute_payload_parse(const unsigned char *payload,
     if (ret == -1)
       goto err;
 
-    if (newp->data_len > buffer.len) {
+    if (newp->data_len > buffer.len - 4) {
       SILC_LOG_ERROR(("Incorrect attribute payload in list"));
       goto err;
     }
@@ -338,9 +345,9 @@ SilcBuffer silc_attribute_payload_encode_data(SilcBuffer attrs,
                                              SilcUInt32 data_len)
 {
   SilcBuffer buffer = attrs;
-  int len;
+  SilcUInt32 len;
 
-  len = 4 + data_len;
+  len = 4 + (SilcUInt16)data_len;
   buffer = silc_buffer_realloc(buffer,
                               (buffer ? buffer->truelen + len : len));
   if (!buffer)
@@ -351,7 +358,7 @@ SilcBuffer silc_attribute_payload_encode_data(SilcBuffer attrs,
                     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_XNSTRING(data, (SilcUInt16)data_len),
                     SILC_STR_END);
   silc_buffer_push(buffer, buffer->data - buffer->head);
 
@@ -401,7 +408,7 @@ const unsigned char *silc_attribute_get_data(SilcAttributePayload payload,
                                             SilcUInt32 *data_len)
 {
   if (data_len)
-    *data_len = payload->data_len;
+    *data_len = (SilcUInt32)payload->data_len;
   return (const unsigned char *)payload->data;
 }
 
@@ -480,18 +487,32 @@ bool silc_attribute_get_object(SilcAttributePayload payload,
   case SILC_ATTRIBUTE_SERVICE:
     {
       SilcAttributeObjService *service = object;
+      SilcBufferStruct buf;
+      SilcUInt16 addr_len, signon_len;
+      char *addr, *signon;
+      int res;
       if (object_size != sizeof(*service))
        break;
-      if (payload->data_len < 7)
+      if (payload->data_len < 13)
        break;
-      SILC_GET32_MSB(service->port, payload->data);
-      SILC_GET16_MSB(len, payload->data + 4);
-      if (payload->data_len < 7 + len)
+      silc_buffer_set(&buf, payload->data, payload->data_len);
+      res = silc_buffer_unformat(&buf,
+                                SILC_STR_UI_INT(&service->port),
+                                SILC_STR_UI16_NSTRING(&addr, &addr_len),
+                                SILC_STR_UI_CHAR(&service->status),
+                                SILC_STR_UI16_NSTRING(&signon, &signon_len),
+                                SILC_STR_UI_INT(&service->idle),
+                                SILC_STR_END);
+      if (res == -1)
        break;
-      memcpy(service->address, payload->data + 6,
-            (len < sizeof(service->address) - 1 ? len :
+      memset(service->address, 0, sizeof(service->address));
+      memset(service->signon, 0, sizeof(service->signon));
+      memcpy(service->address, addr,
+            (addr_len < sizeof(service->address) - 1 ? addr_len :
              sizeof(service->address) - 1));
-      service->status = payload->data[6 + len] ? TRUE : FALSE;
+      memcpy(service->signon, signon,
+            (signon_len < sizeof(service->signon) - 1 ? signon_len :
+             sizeof(service->signon) - 1));
       ret = TRUE;
     }
     break;
@@ -598,7 +619,7 @@ bool silc_attribute_get_object(SilcAttributePayload payload,
        silc_buffer_unformat(&buffer,
                             SILC_STR_UI16_NSTRING_ALLOC(&pk->type, &len),
                             SILC_STR_END);
-      if (res == -1)
+      if (res == -1 || len > buffer.len - 2)
        break;
       pk->data = silc_memdup(payload->data + 2 + len,
                             payload->data_len - 2 - len);