From cbd26eb124e6d49c10f9bc5816d5b5e11f579f71 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Thu, 28 Feb 2013 16:50:56 -0500 Subject: [PATCH] perform message integrity check aka auth --- daemon/Makefile | 2 ++ daemon/stun.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++--- debian/control | 1 + 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/daemon/Makefile b/daemon/Makefile index 6a7a0b6ff..527963de3 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -3,6 +3,7 @@ CFLAGS= -g -Wall -pthread -fno-strict-aliasing CFLAGS+= `pkg-config --cflags glib-2.0` CFLAGS+= `pkg-config --cflags gthread-2.0` CFLAGS+= `pkg-config --cflags zlib` +CFLAGS+= `pkg-config --cflags openssl` CFLAGS+= `pcre-config --cflags` CFLAGS+= -I/lib/modules/`uname -r`/build/include/ -I../kernel-module/ CFLAGS+= -D_GNU_SOURCE @@ -19,6 +20,7 @@ LDFLAGS= -ldl -rdynamic LDFLAGS+= `pkg-config --libs glib-2.0` LDFLAGS+= `pkg-config --libs gthread-2.0` LDFLAGS+= `pkg-config --libs zlib` +LDFLAGS+= `pkg-config --libs openssl` LDFLAGS+= `pcre-config --libs` LDFLAGS+= `xmlrpc-c-config client --libs` diff --git a/daemon/stun.c b/daemon/stun.c index e8abf66de..b56f08a08 100644 --- a/daemon/stun.c +++ b/daemon/stun.c @@ -4,6 +4,7 @@ #include #include #include +#include #include "str.h" #include "aux.h" @@ -11,6 +12,8 @@ #define STUN_CRC_XOR 0x5354554eUL +#define STUN_USERNAME 0x0006 +#define STUN_MESSAGE_INTEGRITY 0x0008 #define STUN_FINGERPRINT 0x8028 @@ -28,9 +31,10 @@ struct tlv { struct stun_attrs { str username; + char *msg_integrity_attr; str msg_integrity; - char *fingerprint_attr; u_int32_t priority; + char *fingerprint_attr; u_int32_t fingerprint; int use:1, controlled:1, @@ -77,10 +81,13 @@ static int stun_attributes(struct stun_attrs *out, str *s) { return -1; switch (ntohs(tlv->type)) { - case 0x0006: /* username */ + case STUN_USERNAME: out->username = attr; break; - case 0x0008: /* message-integrity */ + case STUN_MESSAGE_INTEGRITY: + if (attr.len != 20) + return -1; + out->msg_integrity_attr = (void *) tlv; out->msg_integrity = attr; break; case STUN_FINGERPRINT: @@ -172,6 +179,46 @@ static int check_fingerprint(str *msg, struct stun_attrs *attrs) { return 0; } +static int check_auth(str *msg, struct stun_attrs *attrs, struct peer *peer) { + HMAC_CTX ctx; + u_int16_t lenX; + unsigned char digest[20]; + int ret; + str ufrag[2]; + + if (!peer->ice_ufrag[0].s || !peer->ice_ufrag[0].len) + return -1; + if (!peer->ice_pwd.s || !peer->ice_pwd.len) + return -1; + + ufrag[0] = attrs->username; + str_chr_str(&ufrag[1], &ufrag[0], ':'); + if (!ufrag[1].s) + return -1; + ufrag[0].len -= ufrag[1].len; + str_shift(&ufrag[1], 1); + + if (!ufrag[0].len || !ufrag[1].len) + return -1; + if (str_cmp_str(&ufrag[0], &peer->ice_ufrag[0])) + return -1; + + HMAC_CTX_init(&ctx); + HMAC_Init(&ctx, peer->ice_pwd.s, peer->ice_pwd.len, EVP_sha1()); + HMAC_Update(&ctx, (void *) msg->s, OFFSET_OF(struct stun, msg_len)); + lenX = htons((attrs->msg_integrity_attr - msg->s) - 20 + 24); + HMAC_Update(&ctx, (void *) &lenX, sizeof(lenX)); + HMAC_Update(&ctx, (void *) msg->s + OFFSET_OF(struct stun, cookie), + ntohs(lenX) + - 24 + 20 - OFFSET_OF(struct stun, cookie)); + HMAC_Final(&ctx, digest, NULL); + + ret = memcmp(digest, attrs->msg_integrity.s, 20) ? -1 : 0; + + HMAC_CTX_cleanup(&ctx); + + return ret; +} + /* XXX add error reporting */ int stun(str *b, struct streamrelay *sr, struct sockaddr_in6 *sin) { struct stun *s = (void *) b->s; @@ -203,10 +250,15 @@ int stun(str *b, struct streamrelay *sr, struct sockaddr_in6 *sin) { if (check_fingerprint(b, &attrs)) return -1; + if (check_auth(b, &attrs, sr->up)) + goto unauth; return 0; bad_req: stun_error(sr->fd.fd, sin, s, 400, "Bad request"); return 0; +unauth: + stun_error(sr->fd.fd, sin, s, 401, "Unauthorized"); + return 0; } diff --git a/debian/control b/debian/control index 9224a2e4b..199c2c72b 100644 --- a/debian/control +++ b/debian/control @@ -8,6 +8,7 @@ Build-Depends: debhelper (>= 5), libcurl3-openssl-dev | libcurl3-gnutls-dev, libglib2.0-dev, libpcre3-dev, + libssl-dev, libxmlrpc-c3-dev (>= 1.16.07) | libxmlrpc-core-c3-dev (>= 1.16.07), zlib1g-dev Standards-Version: 3.9.3