Commit 1c04b65d authored by Dafydd Harries's avatar Dafydd Harries

validate lengths of STUN attributes

darcs-hash:20070126083620-c9803-22d03fb3d1af72a45b84fe0210f12640e3628661.gz
parent 79fa3296
...@@ -35,21 +35,36 @@ stun_attribute_free (StunAttribute *attr) ...@@ -35,21 +35,36 @@ stun_attribute_free (StunAttribute *attr)
static gboolean static gboolean
_stun_attribute_unpack (StunAttribute *attr, guint length, const gchar *s) _stun_attribute_unpack (StunAttribute *attr, guint length, const gchar *s)
{ {
attr->type = ntohs (*(guint16 *) s); guint type;
switch (attr->type) if (length < 4)
/* must start with 16 bit type, 16 bit length */
return FALSE;
if (length % 4 != 0)
/* attributes must be aligned to 32 bits */
return FALSE;
type = ntohs (*(guint16 *) s);
switch (type)
{ {
case STUN_ATTRIBUTE_MAPPED_ADDRESS: case STUN_ATTRIBUTE_MAPPED_ADDRESS:
if (length != 12)
return FALSE;
attr->address.af = (guint8) s[5]; attr->address.af = (guint8) s[5];
g_assert (attr->address.af == 1); g_assert (attr->address.af == 1);
attr->address.port = ntohs (*(guint16 *)(s + 6)); attr->address.port = ntohs (*(guint16 *)(s + 6));
attr->address.ip = ntohl (*(guint32 *)(s + 8)); attr->address.ip = ntohl (*(guint32 *)(s + 8));
break; break;
default: default:
/* unknown attribute; we can only unpack the type */ /* unknown attribute; we can only unpack the type */
break; break;
} }
attr->type = type;
return TRUE; return TRUE;
} }
...@@ -58,7 +73,6 @@ stun_attribute_unpack (guint length, const gchar *s) ...@@ -58,7 +73,6 @@ stun_attribute_unpack (guint length, const gchar *s)
{ {
StunAttribute *attr; StunAttribute *attr;
g_assert (length);
attr = stun_attribute_new (0); attr = stun_attribute_new (0);
if (_stun_attribute_unpack (attr, length, s)) if (_stun_attribute_unpack (attr, length, s))
......
...@@ -108,6 +108,28 @@ START_TEST (test_attribute_unpack_unknown) ...@@ -108,6 +108,28 @@ START_TEST (test_attribute_unpack_unknown)
} }
END_TEST END_TEST
START_TEST (test_attribute_unpack_wrong_length)
{
StunAttribute *attr;
// attributes must be at least 4 bytes long
attr = stun_attribute_unpack (0, NULL);
fail_unless (NULL == attr);
// attributes must aligned to 32 bits
attr = stun_attribute_unpack (33, NULL);
fail_unless (NULL == attr);
attr = stun_attribute_unpack (8,
"\x00\x01" // type = MAPPED-ADDRESS
"\x00\x04" // length = 4 (invalid!)
"\x00\x01" // padding, address family
"\x09\x29" // port
);
fail_unless (NULL == attr);
}
END_TEST
START_TEST (test_message_pack) START_TEST (test_message_pack)
{ {
StunMessage *msg = stun_message_binding_request_new (); StunMessage *msg = stun_message_binding_request_new ();
...@@ -218,6 +240,10 @@ stun_suite (void) ...@@ -218,6 +240,10 @@ stun_suite (void)
tcase_add_test (tcase, test_attribute_unpack_unknown); tcase_add_test (tcase, test_attribute_unpack_unknown);
suite_add_tcase (suite, tcase); suite_add_tcase (suite, tcase);
tcase = tcase_create ("attribute unpack unknown wrong length");
tcase_add_test (tcase, test_attribute_unpack_wrong_length);
suite_add_tcase (suite, tcase);
tcase = tcase_create ("message pack"); tcase = tcase_create ("message pack");
tcase_add_test (tcase, test_message_pack); tcase_add_test (tcase, test_message_pack);
suite_add_tcase (suite, tcase); suite_add_tcase (suite, tcase);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment