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 ...@@ -79,7 +79,7 @@ int
stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen, stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen,
const uint8_t *msg, const uint8_t *msg,
const struct sockaddr *restrict src, socklen_t srclen, 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) bool *restrict control, uint64_t tie)
{ {
size_t len = *plen; size_t len = *plen;
...@@ -128,7 +128,7 @@ stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen, ...@@ -128,7 +128,7 @@ stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen,
val = STUN_BAD_REQUEST; val = STUN_BAD_REQUEST;
} }
else else
if (stun_strcmp (msg, STUN_USERNAME, username) if (stun_verify_username (msg, local_ufrag)
|| stun_verify_password (msg, pass)) || stun_verify_password (msg, pass))
{ {
DBG (" Integrity check failed.\n"); DBG (" Integrity check failed.\n");
......
...@@ -102,7 +102,7 @@ int ...@@ -102,7 +102,7 @@ int
stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen, stun_conncheck_reply (uint8_t *restrict buf, size_t *restrict plen,
const uint8_t *msg, const uint8_t *msg,
const struct sockaddr *restrict src, socklen_t srclen, 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); bool *restrict control, uint64_t tie);
/** /**
......
...@@ -363,6 +363,7 @@ bool stun_match_messages (const uint8_t *restrict resp, ...@@ -363,6 +363,7 @@ bool stun_match_messages (const uint8_t *restrict resp,
int *restrict error); int *restrict error);
int stun_verify_key (const uint8_t *msg, const void *key, size_t keylen); 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_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. * Looks for an attribute in a *valid* STUN message.
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
* *
* Contributors: * Contributors:
* Rémi Denis-Courmont, Nokia * Rémi Denis-Courmont, Nokia
* Kai Vehmanen, Nokia
* *
* Alternatively, the contents of this file may be used under the terms of the * 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 * 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) ...@@ -488,6 +489,39 @@ int stun_verify_password (const uint8_t *msg, const char *pw)
return stun_verify_key (msg, pw, strlen (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 static
int stun_find_errno (const uint8_t *restrict msg, int *restrict code) int stun_find_errno (const uint8_t *restrict msg, int *restrict code)
......
...@@ -60,7 +60,7 @@ int main (void) ...@@ -60,7 +60,7 @@ int main (void)
const uint64_t tie = 0x8000000000000000LL; const uint64_t tie = 0x8000000000000000LL;
ssize_t val; ssize_t val;
size_t len; size_t len;
static const char name[] = "admin", pass[] = "secret"; static const char username[] = "L:R", ufrag[] = "L", pass[] = "secret";
int code; int code;
uint16_t alen; uint16_t alen;
bool control = false; bool control = false;
...@@ -82,19 +82,19 @@ int main (void) ...@@ -82,19 +82,19 @@ int main (void)
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EINVAL);
assert (len == 0); assert (len == 0);
/* Incorrect message method */ /* Incorrect message method */
stun_init_request (req, 0x666); stun_init_request (req, 0x666);
len = sizeof (req); len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL); val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0); assert (val == 0);
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EPROTO);
assert (len > 0); assert (len > 0);
...@@ -109,7 +109,7 @@ int main (void) ...@@ -109,7 +109,7 @@ int main (void)
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EPROTO);
assert (len > 0); assert (len > 0);
...@@ -121,7 +121,7 @@ int main (void) ...@@ -121,7 +121,7 @@ int main (void)
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EPERM);
assert (len > 0); assert (len > 0);
assert (stun_match_messages (resp, req, NULL, 0, &code) assert (stun_match_messages (resp, req, NULL, 0, &code)
...@@ -135,7 +135,7 @@ int main (void) ...@@ -135,7 +135,7 @@ int main (void)
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EPERM);
assert (len > 0); assert (len > 0);
assert (stun_match_messages (resp, req, NULL, 0, &code) assert (stun_match_messages (resp, req, NULL, 0, &code)
...@@ -150,12 +150,12 @@ int main (void) ...@@ -150,12 +150,12 @@ int main (void)
val = stun_append_flag (req, sizeof (req), STUN_USE_CANDIDATE); val = stun_append_flag (req, sizeof (req), STUN_USE_CANDIDATE);
assert (val == 0); assert (val == 0);
len = sizeof (req); len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL); val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0); assert (val == 0);
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == 0);
assert (len > 0); assert (len > 0);
assert (stun_match_messages (resp, req, (uint8_t *)pass, assert (stun_match_messages (resp, req, (uint8_t *)pass,
...@@ -176,7 +176,7 @@ int main (void) ...@@ -176,7 +176,7 @@ int main (void)
/* Bad integrity (bad password) */ /* Bad integrity (bad password) */
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EPERM);
assert (len > 0); assert (len > 0);
assert (stun_match_messages (resp, req, NULL, 0, &code) assert (stun_match_messages (resp, req, NULL, 0, &code)
...@@ -187,7 +187,7 @@ int main (void) ...@@ -187,7 +187,7 @@ int main (void)
ip4.sin_family = AF_UNSPEC; ip4.sin_family = AF_UNSPEC;
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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); assert (val == EAFNOSUPPORT);
ip4.sin_family = AF_INET; ip4.sin_family = AF_INET;
...@@ -195,13 +195,13 @@ int main (void) ...@@ -195,13 +195,13 @@ int main (void)
/* Bad CRC32 */ /* Bad CRC32 */
stun_init_request (req, STUN_BINDING); stun_init_request (req, STUN_BINDING);
len = sizeof (req); len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL); val = stun_finish_short (req, &len, ufrag, pass, NULL);
assert (val == 0); assert (val == 0);
((uint8_t *)stun_find (req, STUN_FINGERPRINT, &alen))[0] ^= 1; ((uint8_t *)stun_find (req, STUN_FINGERPRINT, &alen))[0] ^= 1;
len = sizeof (resp); len = sizeof (resp);
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EINVAL);
assert (len == 0); assert (len == 0);
...@@ -210,13 +210,13 @@ int main (void) ...@@ -210,13 +210,13 @@ int main (void)
val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLING, tie + 1); val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLING, tie + 1);
assert (val == 0); assert (val == 0);
len = sizeof (req); len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL); val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0); assert (val == 0);
len = sizeof (resp); len = sizeof (resp);
control = true; control = true;
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == EACCES);
assert (len > 0); assert (len > 0);
assert (control == false); assert (control == false);
...@@ -229,13 +229,13 @@ int main (void) ...@@ -229,13 +229,13 @@ int main (void)
val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLED, tie - 1); val = stun_append64 (req, sizeof (req), STUN_ICE_CONTROLLED, tie - 1);
assert (val == 0); assert (val == 0);
len = sizeof (req); len = sizeof (req);
val = stun_finish_short (req, &len, name, pass, NULL); val = stun_finish_short (req, &len, username, pass, NULL);
assert (val == 0); assert (val == 0);
len = sizeof (resp); len = sizeof (resp);
control = false; control = false;
val = stun_conncheck_reply (resp, &len, req, (struct sockaddr *)&ip4, 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 (val == 0);
assert (len > 0); assert (len > 0);
assert (control == false); 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