Browse Source

The FINGERPRINT mechanism MUST be used for connectivity checks

git.mgm/mediaproxy-ng/2.2
Richard Fuchs 13 years ago
parent
commit
4aa3017555
3 changed files with 57 additions and 9 deletions
  1. +2
    -0
      daemon/Makefile
  2. +53
    -8
      daemon/stun.c
  3. +2
    -1
      debian/control

+ 2
- 0
daemon/Makefile View File

@ -2,6 +2,7 @@ CC= gcc
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+= `pcre-config --cflags`
CFLAGS+= -I/lib/modules/`uname -r`/build/include/ -I../kernel-module/
CFLAGS+= -D_GNU_SOURCE
@ -17,6 +18,7 @@ endif
LDFLAGS= -ldl -rdynamic
LDFLAGS+= `pkg-config --libs glib-2.0`
LDFLAGS+= `pkg-config --libs gthread-2.0`
LDFLAGS+= `pkg-config --libs zlib`
LDFLAGS+= `pcre-config --libs`
LDFLAGS+= `xmlrpc-c-config client --libs`


+ 53
- 8
daemon/stun.c View File

@ -3,6 +3,7 @@
#include <sys/types.h>
#include <string.h>
#include <sys/socket.h>
#include <zlib.h>
#include "str.h"
#include "aux.h"
@ -22,7 +23,9 @@ struct tlv {
struct stun_attrs {
str username;
str msg_integrity;
char *fingerprint_attr;
u_int32_t priority;
u_int32_t fingerprint;
int use:1,
controlled:1,
controlling:1;
@ -32,7 +35,12 @@ struct stun_error {
struct stun stun;
struct tlv error_code;
u_int32_t codes;
};
} __attribute__ ((packed));
struct stun_fingerprint {
struct tlv tlv;
u_int32_t crc;
} __attribute__ ((packed));
@ -59,12 +67,21 @@ static int stun_attributes(struct stun_attrs *out, str *s) {
if (str_shift(s, len))
return -1;
if (out->msg_integrity.s && ntohs(tlv->type) != 0x8028)
return -1;
switch (ntohs(tlv->type)) {
case 0x0006: /* username */
out->username = attr;
break;
case 0x0008: /* message-integrity */
out->msg_integrity = attr;
break;
case 0x8028: /* fingerprint */
if (attr.len != 4)
return -1;
out->fingerprint_attr = (void *) tlv;
out->fingerprint = ntohl(*(u_int32_t *) attr.s);
goto out;
case 0x0025: /* use-candidate */
@ -93,8 +110,9 @@ static inline void stun_error_len(int fd, struct sockaddr_in6 *sin, struct stun
int code, char *reason, int len)
{
struct stun_error err;
struct stun_fingerprint fp;
struct msghdr mh;
struct iovec iov[2];
struct iovec iov[3];
err.stun.msg_type = htons(0x0111); /* binding error response */
err.stun.cookie = htonl(STUN_COOKIE);
@ -110,13 +128,22 @@ static inline void stun_error_len(int fd, struct sockaddr_in6 *sin, struct stun
iov[0].iov_len = sizeof(err);
iov[1].iov_base = reason;
iov[1].iov_len = (len + 3) & 0xfffc;
iov[2].iov_base = &fp;
iov[2].iov_len = sizeof(fp);
err.stun.msg_len = htons(iov[1].iov_len + sizeof(err.codes) + sizeof(err.error_code));
err.stun.msg_len = htons(iov[1].iov_len + sizeof(err.codes) + sizeof(err.error_code)
+ iov[2].iov_len);
fp.crc = crc32(0, iov[0].iov_base, iov[0].iov_len);
fp.crc = crc32(fp.crc, iov[1].iov_base, iov[1].iov_len);
fp.crc = htonl(fp.crc ^ 0x5354554eUL);
fp.tlv.type = htons(0x8028);
fp.tlv.len = htons(4);
mh.msg_name = sin;
mh.msg_namelen = sizeof(*sin);
mh.msg_iov = iov;
mh.msg_iovlen = 2;
mh.msg_iovlen = 3;
sendmsg(fd, &mh, 0);
}
@ -124,6 +151,19 @@ static inline void stun_error_len(int fd, struct sockaddr_in6 *sin, struct stun
#define stun_error(fd, sin, str, code, reason) \
stun_error_len(fd, sin, str, code, reason "\0\0\0", strlen(reason))
static int check_fingerprint(str *msg, struct stun_attrs *attrs) {
int len;
u_int32_t crc;
len = attrs->fingerprint_attr - msg->s;
crc = crc32(0, (void *) msg->s, len);
crc ^= 0x5354554eUL;
if (crc != attrs->fingerprint)
return -1;
return 0;
}
/* XXX add error reporting */
int stun(str *b, struct streamrelay *sr, struct sockaddr_in6 *sin) {
struct stun *s = (void *) b->s;
@ -146,10 +186,15 @@ int stun(str *b, struct streamrelay *sr, struct sockaddr_in6 *sin) {
if (stun_attributes(&attrs, &attr_str))
return -1;
if (class == 0x0) { /* request */
if (!attrs.username.s || !attrs.msg_integrity.s)
goto bad_req;
}
if (class != 0x0)
return -1; /* XXX ? */
/* request */
if (!attrs.username.s || !attrs.msg_integrity.s || !attrs.fingerprint_attr)
goto bad_req;
if (check_fingerprint(b, &attrs))
return -1;
return 0;


+ 2
- 1
debian/control View File

@ -8,7 +8,8 @@ Build-Depends: debhelper (>= 5),
libcurl3-openssl-dev | libcurl3-gnutls-dev,
libglib2.0-dev,
libpcre3-dev,
libxmlrpc-c3-dev (>= 1.16.07) | libxmlrpc-core-c3-dev (>= 1.16.07)
libxmlrpc-c3-dev (>= 1.16.07) | libxmlrpc-core-c3-dev (>= 1.16.07),
zlib1g-dev
Standards-Version: 3.9.3
Homepage: http://sipwise.com/


Loading…
Cancel
Save