Commit f08e4f93 authored by Kai Vehmanen's avatar Kai Vehmanen

Modified the stun_conncheck_reply() API to take local username fragment as a...

Modified the stun_conncheck_reply() API to take local username fragment as a parameter instead of the full username.

darcs-hash:20071119131402-77cd4-ff96d90081976df145d57a5d564f3afffe65e6f2.gz
parent 76f88930
......@@ -79,7 +79,7 @@ int
stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen,
const uint8_t *msg,
const struct sockaddr *restrict src, socklen_t srclen,
const char *username, const char *pass,
const char *local_ufrag, const char *pass,
bool *restrict control, uint64_t tie)
{
size_t len = *plen;
......@@ -128,7 +128,7 @@ stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen,
val = STUN_BAD_REQUEST;
}
else
if (stun_strcmp (msg, STUN_USERNAME, username)
if (stun_verify_username (msg, local_ufrag)
|| stun_verify_password (msg, pass))
{
DBG (" Integrity check failed.\n");
......
......@@ -102,7 +102,7 @@ int
stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen,
const uint8_t *msg,
const struct sockaddr *restrict src, socklen_t srclen,
const char *username, const char *pass,
const char *local_ufrag, const char *pass,
bool *restrict control, uint64_t tie);
/**
......
......@@ -363,6 +363,7 @@ bool stun_match_messages (const uint8_t *restrict resp,
int *restrict error);
int stun_verify_key (const uint8_t *msg, const void *key, size_t keylen);
int stun_verify_password (const uint8_t *msg, const char *pw);
int stun_verify_username (const uint8_t *msg, const char *local_ufrag);
/**
* Looks for an attribute in a *valid* STUN message.
......
......@@ -21,6 +21,7 @@
*
* Contributors:
* Rémi Denis-Courmont, Nokia
* Kai Vehmanen, Nokia
*
* Alternatively, the contents of this file may be used under the terms of the
* the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
......@@ -488,6 +489,39 @@ int stun_verify_password (const uint8_t *msg, const char *pw)
return stun_verify_key (msg, pw, strlen (pw));
}
/**
* @param msg valid STUN message
* @param pw nul-terminated local username fragment
* @return 0 if the username in the message is valid and matches
* the local username fragment, EPERM if the username was incorrect,
* and ENOENT if there was no USERNAME attribute
*/
int stun_verify_username (const uint8_t *msg, const char *local_ufrag)
{
const uint8_t *username, *n;
uint16_t username_len;
assert (msg != NULL);
username = stun_find (msg, STUN_USERNAME, &username_len);
if (username == NULL)
{
DBG ("STUN auth error: no USERNAME attribute!\n");
return ENOENT;
}
n = strchr (username, ':');
if (n == NULL)
{
DBG ("STUN auth error: no colon in USERNAME!\n");
return EPERM;
}
if (strncmp(username, local_ufrag, n - username) != 0)
{
DBG ("STUN auth error: local ufrag doesn't match (uname:%s,ufrag:%s,msg:%s)!\n", username,local_ufrag, n);
return EPERM;
}
return 0;
}
static
int stun_find_errno (const uint8_t *restrict msg, int *restrict code)
......
......@@ -60,7 +60,7 @@ int main (void)
const uint64_t tie = 0x8000000000000000LL;
ssize_t val;
size_t len;
static const char name[] = "admin", pass[] = "secret";
static const char username[] = "L:R", ufrag[] = "L", pass[] = "secret";
int code;
uint16_t alen;
bool control = false;
......@@ -82,19 +82,19 @@ int main (void)
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == EINVAL);
assert (len == 0);
/* Incorrect message method */
stun_init_request (req, 0x666);
len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL);
val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0);
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == EPROTO);
assert (len > 0);
......@@ -109,7 +109,7 @@ int main (void)
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), username, pass, &control, tie);
assert (val == EPROTO);
assert (len > 0);
......@@ -121,7 +121,7 @@ int main (void)
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == EPERM);
assert (len > 0);
assert (stun_match_messages (resp, req, NULL, 0, &code)
......@@ -135,7 +135,7 @@ int main (void)
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == EPERM);
assert (len > 0);
assert (stun_match_messages (resp, req, NULL, 0, &code)
......@@ -150,12 +150,12 @@ int main (void)
val = stun_append_flag (req, sizeof (req), STUN_USE_CANDIDATE);
assert (val == 0);
len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL);
val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0);
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == 0);
assert (len > 0);
assert (stun_match_messages (resp, req, (uint8_t *)pass,
......@@ -176,7 +176,7 @@ int main (void)
/* Bad integrity (bad password) */
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, "bad", &control, tie);
sizeof (ip4), ufrag, "bad", &control, tie);
assert (val == EPERM);
assert (len > 0);
assert (stun_match_messages (resp, req, NULL, 0, &code)
......@@ -187,7 +187,7 @@ int main (void)
ip4.sin_family = AF_UNSPEC;
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == EAFNOSUPPORT);
ip4.sin_family = AF_INET;
......@@ -195,13 +195,13 @@ int main (void)
/* Bad CRC32 */
stun_init_request (req, STUN_BINDING);
len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL);
val = stun_finish_short (req, &len, ufrag, pass, NULL);
assert (val == 0);
((uint8_t *)stun_find (req, STUN_FINGERPRINT, &alen))[0] ^= 1;
len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == EINVAL);
assert (len == 0);
......@@ -210,13 +210,13 @@ int main (void)
val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLING, tie + 1);
assert (val == 0);
len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL);
val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0);
len = sizeof (resp);
control = true;
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == EACCES);
assert (len > 0);
assert (control == false);
......@@ -229,13 +229,13 @@ int main (void)
val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLED, tie - 1);
assert (val == 0);
len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL);
val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0);
len = sizeof (resp);
control = false;
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4,
sizeof (ip4), name, pass, &control, tie);
sizeof (ip4), ufrag, pass, &control, tie);
assert (val == 0);
assert (len > 0);
assert (control == false);
......
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