Ignore:
Timestamp:
May 15, 2007 10:42:56 AM (17 years ago)
Author:
bennylp
Message:

Fixed several STUN bugs: USERNAME, REALM etc are not allowed in the response, retransmission timer calculation bug, etc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath/stun_msg.c

    r1266 r1275  
    1818 */ 
    1919#include <pjnath/stun_msg.h> 
    20 #include <pjnath/stun_auth.h> 
    2120#include <pjnath/errno.h> 
    2221#include <pjlib-util/crc32.h> 
     
    19491948 * MD5 digest of username, realm, and password.  
    19501949 */ 
    1951 void pj_stun_calc_md5_key(pj_uint8_t digest[16], 
    1952                           const pj_str_t *realm, 
    1953                           const pj_str_t *username, 
    1954                           const pj_str_t *passwd) 
     1950static void calc_md5_key(pj_uint8_t digest[16], 
     1951                         const pj_str_t *realm, 
     1952                         const pj_str_t *username, 
     1953                         const pj_str_t *passwd) 
    19551954{ 
    19561955    /* The 16-byte key for MESSAGE-INTEGRITY HMAC is formed by taking 
     
    19671966 
    19681967#define REMOVE_QUOTE(s) if (s.slen && *s.ptr=='"') \ 
    1969                     s.ptr++, s.slen--; \ 
    1970                 if (s.slen && s.ptr[s.slen-1]=='"') \ 
    1971                     s.slen--; 
     1968                            s.ptr++, s.slen--; \ 
     1969                        if (s.slen && s.ptr[s.slen-1]=='"') \ 
     1970                            s.slen--; 
    19721971 
    19731972    /* Add username */ 
     
    19981997 
    19991998/* 
     1999 * Create authentication key to be used for encoding the message with 
     2000 * MESSAGE-INTEGRITY.  
     2001 */ 
     2002PJ_DEF(void) pj_stun_create_key(pj_pool_t *pool, 
     2003                                pj_str_t *key, 
     2004                                const pj_str_t *realm, 
     2005                                const pj_str_t *username, 
     2006                                const pj_str_t *passwd) 
     2007{ 
     2008    PJ_ASSERT_ON_FAIL(pool && key && username && passwd, return); 
     2009 
     2010    if (realm && realm->slen) { 
     2011        key->ptr = (char*) pj_pool_alloc(pool, 16); 
     2012        calc_md5_key((pj_uint8_t*)key->ptr, realm, username, passwd); 
     2013        key->slen = 16; 
     2014    } else { 
     2015        pj_strdup(pool, key, passwd); 
     2016    } 
     2017} 
     2018 
     2019 
     2020/* 
    20002021static char *print_binary(const pj_uint8_t *data, unsigned data_len) 
    20012022{ 
     
    20292050                                       pj_uint8_t *buf, unsigned buf_size, 
    20302051                                       unsigned options, 
    2031                                        const pj_str_t *password, 
     2052                                       const pj_str_t *key, 
    20322053                                       unsigned *p_msg_len) 
    20332054{ 
    2034     pj_stun_msg_hdr *hdr; 
    20352055    pj_uint8_t *start = buf; 
    2036     pj_stun_realm_attr *arealm = NULL; 
    2037     pj_stun_username_attr *auname = NULL; 
    20382056    pj_stun_msgint_attr *amsgint = NULL; 
    20392057    pj_stun_fingerprint_attr *afingerprint = NULL; 
    2040     unsigned printed = 0; 
     2058    unsigned printed = 0, body_len; 
    20412059    pj_status_t status; 
    20422060    unsigned i; 
     
    20532071    if (buf_size < sizeof(pj_stun_msg_hdr)) 
    20542072        return PJ_ETOOSMALL; 
    2055     pj_memcpy(buf, &msg->hdr, sizeof(pj_stun_msg_hdr)); 
    2056     hdr = (pj_stun_msg_hdr*) buf; 
    2057     hdr->magic = pj_htonl(hdr->magic); 
    2058     hdr->type = pj_htons(hdr->type); 
    2059     /* We'll fill in the length later */ 
     2073     
     2074    PUTVAL16H(buf, 0, msg->hdr.type); 
     2075    PUTVAL16H(buf, 2, 0);   /* length will be calculated later */ 
     2076    PUTVAL32H(buf, 4, msg->hdr.magic); 
     2077    pj_memcpy(buf+8, msg->hdr.tsx_id, sizeof(msg->hdr.tsx_id)); 
    20602078 
    20612079    buf += sizeof(pj_stun_msg_hdr); 
    20622080    buf_size -= sizeof(pj_stun_msg_hdr); 
    20632081 
    2064     /* Print each attribute */ 
     2082    /* Encode each attribute to the message */ 
    20652083    for (i=0; i<msg->attr_count; ++i) { 
    20662084        const struct attr_desc *adesc; 
     
    20732091            /* Stop when encountering MESSAGE-INTEGRITY */ 
    20742092            break; 
    2075  
    2076         } else if (attr_hdr->type == PJ_STUN_ATTR_USERNAME) { 
    2077             pj_assert(auname == NULL); 
    2078             auname = (pj_stun_username_attr*) attr_hdr; 
    2079  
    2080         } else if (attr_hdr->type == PJ_STUN_ATTR_REALM) { 
    2081             pj_assert(arealm == NULL); 
    2082             arealm = (pj_stun_realm_attr*) attr_hdr; 
    20832093 
    20842094        } else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) { 
     
    21242134     */ 
    21252135    if (amsgint && afingerprint) { 
    2126         msg->hdr.length = (pj_uint16_t)((buf - start) - 20 + 24 + 8); 
     2136        body_len = (pj_uint16_t)((buf - start) - 20 + 24 + 8); 
    21272137    } else if (amsgint) { 
    2128         msg->hdr.length = (pj_uint16_t)((buf - start) - 20 + 24); 
     2138        body_len = (pj_uint16_t)((buf - start) - 20 + 24); 
    21292139    } else if (afingerprint) { 
    2130         msg->hdr.length = (pj_uint16_t)((buf - start) - 20 + 8); 
     2140        body_len = (pj_uint16_t)((buf - start) - 20 + 8); 
    21312141    } else { 
    2132         msg->hdr.length = (pj_uint16_t)((buf - start) - 20); 
     2142        body_len = (pj_uint16_t)((buf - start) - 20); 
    21332143    } 
    21342144 
    21352145    /* hdr->length = pj_htons(length); */ 
    2136     start[2] = (pj_uint8_t)((msg->hdr.length >> 8) & 0x00FF); 
    2137     start[3] = (pj_uint8_t)(msg->hdr.length & 0x00FF); 
     2146    PUTVAL16H(start, 2, (pj_uint16_t)body_len); 
    21382147 
    21392148    /* Calculate message integrity, if present */ 
    21402149    if (amsgint != NULL) { 
    2141  
    2142         pj_uint8_t md5_key_buf[16]; 
    21432150        pj_hmac_sha1_context ctx; 
    2144         pj_str_t key; 
     2151 
     2152        /* Key MUST be specified */ 
     2153        PJ_ASSERT_RETURN(key, PJ_EINVALIDOP); 
    21452154 
    21462155        /* MESSAGE-INTEGRITY must be the last attribute in the message, or 
     
    21622171        } 
    21632172 
    2164         /* Must have USERNAME attribute */ 
    2165         if (auname == NULL) { 
    2166             /* Should not happen for message generated by us */ 
    2167             pj_assert(PJ_FALSE); 
    2168             return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_USERNAME); 
    2169         } 
    2170  
    2171         /* Password must be specified */ 
    2172         PJ_ASSERT_RETURN(password, PJ_EINVAL); 
    2173  
    2174         /* Get the key to sign the message */ 
    2175         if (arealm == NULL ) { 
    2176             /* For short term credential, the key is the password */ 
    2177             key = *password; 
    2178  
    2179         } else { 
    2180             pj_stun_calc_md5_key(md5_key_buf, &arealm->value,  
    2181                                  &auname->value, password); 
    2182             key.ptr = (char*) md5_key_buf; 
    2183             key.slen = 16; 
    2184         } 
    2185  
    21862173        /* Calculate HMAC-SHA1 digest, add zero padding to input 
    21872174         * if necessary to make the input 64 bytes aligned. 
    21882175         */ 
    2189         pj_hmac_sha1_init(&ctx, (pj_uint8_t*)key.ptr, key.slen); 
     2176        pj_hmac_sha1_init(&ctx, (pj_uint8_t*)key->ptr, key->slen); 
    21902177        pj_hmac_sha1_update(&ctx, (pj_uint8_t*)start, buf-start); 
    21912178        if ((buf-start) & 0x3F) { 
     
    22212208    } 
    22222209 
    2223     /* Done */ 
     2210    /* Update message length. */ 
     2211    msg->hdr.length = (pj_uint16_t) ((buf - start) - 20); 
     2212 
     2213    /* Return the length */ 
    22242214    if (p_msg_len) 
    22252215        *p_msg_len = (buf - start); 
Note: See TracChangeset for help on using the changeset viewer.