Changeset 2041


Ignore:
Timestamp:
Jun 21, 2008 12:36:56 PM (11 years ago)
Author:
bennylp
Message:

Fixed bug with authenticating STUN messages when unrecognized/unknown non-mandatory STUN attribute is present in the message

Location:
pjproject/trunk/pjnath
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/include/pjnath/stun_msg.h

    r1997 r2041  
    583583     
    584584    /** 
     585     * Special signature to indicate that this is a valid attribute even 
     586     * though we don't have meta-data to describe this attribute. 
     587     */ 
     588    pj_uint32_t         magic; 
     589 
     590    /** 
    585591     * Length of the data. 
    586592     */ 
  • pjproject/trunk/pjnath/src/pjnath-test/stun.c

    r1877 r2041  
    164164        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
    165165        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
    166         "\x80\xff\x00\x04\x00\x00\x00\x00", 
     166        "\x80\xff\x00\x03\x00\x00\x00\x00", 
    167167        28, 
    168168        NULL, 
     
    370370static int verify2(pj_stun_msg *msg) 
    371371{ 
    372     if (msg->attr_count != 0) { 
    373         PJ_LOG(1,(THIS_FILE, "    expecting zero attribute count")); 
     372    pj_stun_binary_attr *bin_attr; 
     373 
     374    if (msg->attr_count != 1) { 
     375        PJ_LOG(1,(THIS_FILE, "    expecting one attribute count")); 
    374376        return -200; 
    375377    } 
     378 
     379    bin_attr = (pj_stun_binary_attr*)msg->attr[0]; 
     380    if (bin_attr->hdr.type != 0x80ff) { 
     381        PJ_LOG(1,(THIS_FILE, "    expecting attribute type 0x80ff")); 
     382        return -210; 
     383    } 
     384    if (bin_attr->hdr.length != 3) { 
     385        PJ_LOG(1,(THIS_FILE, "    expecting attribute length = 4")); 
     386        return -220; 
     387    } 
     388    if (bin_attr->magic != PJ_STUN_MAGIC) { 
     389        PJ_LOG(1,(THIS_FILE, "    expecting PJ_STUN_MAGIC for unknown attr")); 
     390        return -230; 
     391    } 
     392    if (bin_attr->length != 3) { 
     393        PJ_LOG(1,(THIS_FILE, "    expecting data length 4")); 
     394        return -240; 
     395    } 
     396 
    376397    return 0; 
    377398} 
     
    689710 
    690711 
     712/* Compare two messages */ 
     713static int cmp_msg(const pj_stun_msg *msg1, const pj_stun_msg *msg2) 
     714{ 
     715    unsigned i; 
     716 
     717    if (msg1->hdr.type != msg2->hdr.type) 
     718        return -10; 
     719    if (msg1->hdr.length != msg2->hdr.length) 
     720        return -20; 
     721    if (msg1->hdr.magic != msg2->hdr.magic) 
     722        return -30; 
     723    if (pj_memcmp(msg1->hdr.tsx_id, msg2->hdr.tsx_id, sizeof(msg1->hdr.tsx_id))) 
     724        return -40; 
     725    if (msg1->attr_count != msg2->attr_count) 
     726        return -50; 
     727 
     728    for (i=0; i<msg1->attr_count; ++i) { 
     729        const pj_stun_attr_hdr *a1 = msg1->attr[i]; 
     730        const pj_stun_attr_hdr *a2 = msg2->attr[i]; 
     731 
     732        if (a1->type != a2->type) 
     733            return -60; 
     734        if (a1->length != a2->length) 
     735            return -70; 
     736    } 
     737 
     738    return 0; 
     739} 
     740 
     741/* Decode and authenticate message with unknown non-mandatory attribute */ 
     742static int handle_unknown_non_mandatory(void) 
     743{ 
     744    pj_pool_t *pool = pj_pool_create(mem, NULL, 1000, 1000, NULL); 
     745    pj_stun_msg *msg0, *msg1, *msg2; 
     746    pj_uint8_t data[] = { 1, 2, 3, 4, 5, 6}; 
     747    pj_uint8_t packet[500]; 
     748    pj_stun_auth_cred cred; 
     749    unsigned len; 
     750    pj_status_t rc; 
     751 
     752    PJ_LOG(3,(THIS_FILE, "  handling unknown non-mandatory attr")); 
     753 
     754    PJ_LOG(3,(THIS_FILE, "    encoding")); 
     755    rc = pj_stun_msg_create(pool, PJ_STUN_BINDING_REQUEST, PJ_STUN_MAGIC, NULL, &msg0); 
     756    rc += pj_stun_msg_add_string_attr(pool, msg0, PJ_STUN_ATTR_USERNAME, &USERNAME); 
     757    rc += pj_stun_msg_add_binary_attr(pool, msg0, 0x80ff, data, sizeof(data)); 
     758    rc += pj_stun_msg_add_msgint_attr(pool, msg0); 
     759    rc += pj_stun_msg_encode(msg0, packet, sizeof(packet), 0, &PASSWORD, &len); 
     760 
     761#if 0 
     762    if (1) { 
     763        unsigned i; 
     764        puts(""); 
     765        printf("{ "); 
     766        for (i=0; i<len; ++i) printf("0x%02x, ", packet[i]); 
     767        puts(" }"); 
     768    } 
     769#endif 
     770 
     771    PJ_LOG(3,(THIS_FILE, "    decoding")); 
     772    rc += pj_stun_msg_decode(pool, packet, len, PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, 
     773                             &msg1, NULL, NULL); 
     774 
     775    rc += cmp_msg(msg0, msg1); 
     776 
     777    pj_bzero(&cred, sizeof(cred)); 
     778    cred.type = PJ_STUN_AUTH_CRED_STATIC; 
     779    cred.data.static_cred.username = USERNAME; 
     780    cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; 
     781    cred.data.static_cred.data = PASSWORD; 
     782 
     783    PJ_LOG(3,(THIS_FILE, "    authenticating")); 
     784    rc += pj_stun_authenticate_request(packet, len, msg1, &cred, pool, NULL, NULL); 
     785 
     786    PJ_LOG(3,(THIS_FILE, "    clone")); 
     787    msg2 = pj_stun_msg_clone(pool, msg1); 
     788    rc += cmp_msg(msg0, msg2); 
     789 
     790    pj_pool_release(pool); 
     791 
     792    return rc==0 ? 0 : -4410; 
     793} 
     794 
     795 
    691796int stun_test(void) 
    692797{ 
     
    707812        goto on_return; 
    708813 
     814    rc = handle_unknown_non_mandatory(); 
     815    if (rc != 0) 
     816        goto on_return; 
     817 
    709818on_return: 
    710819    pj_stun_set_padding_char(pad); 
  • pjproject/trunk/pjnath/src/pjnath/stun_msg.c

    r1997 r2041  
    16571657    INIT_ATTR(attr, attr_type, length); 
    16581658 
     1659    attr->magic = PJ_STUN_MAGIC; 
     1660 
    16591661    if (data && length) { 
    16601662        attr->length = length; 
     
    20242026        if (adesc == NULL) { 
    20252027            /* Unrecognized attribute */ 
     2028            pj_stun_binary_attr *attr; 
    20262029 
    20272030            PJ_LOG(4,(THIS_FILE, "Unrecognized attribute type %d",  
     
    20472050                return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_UNKNOWN_ATTRIBUTE); 
    20482051            } 
     2052 
     2053            /* Make sure we have rooms for the new attribute */ 
     2054            if (msg->attr_count >= PJ_STUN_MAX_ATTR) { 
     2055                if (p_response) { 
     2056                    pj_stun_msg_create_response(pool, msg, 
     2057                                                PJ_STUN_SC_SERVER_ERROR, 
     2058                                                NULL, p_response); 
     2059                } 
     2060                return PJNATH_ESTUNTOOMANYATTR; 
     2061            } 
     2062 
     2063            /* Create binary attribute to represent this */ 
     2064            status = pj_stun_binary_attr_create(pool, attr_type, pdu+4,  
     2065                                                GETVAL16H(pdu, 2), &attr); 
     2066            if (status != PJ_SUCCESS) { 
     2067                if (p_response) { 
     2068                    pj_stun_msg_create_response(pool, msg, 
     2069                                                PJ_STUN_SC_SERVER_ERROR, 
     2070                                                NULL, p_response); 
     2071                } 
     2072 
     2073                PJ_LOG(4,(THIS_FILE,  
     2074                          "Error parsing unknown STUN attribute type %d", 
     2075                          attr_type)); 
     2076 
     2077                return status; 
     2078            } 
     2079 
     2080            /* Add the attribute */ 
     2081            msg->attr[msg->attr_count++] = &attr->hdr; 
    20492082 
    20502083        } else { 
     
    21252158                if (p_response) { 
    21262159                    pj_stun_msg_create_response(pool, msg, 
    2127                                                 PJ_STUN_SC_BAD_REQUEST, 
     2160                                                PJ_STUN_SC_SERVER_ERROR, 
    21282161                                                NULL, p_response); 
    21292162                } 
     
    21352168        } 
    21362169 
     2170        /* Next attribute */ 
    21372171        if (attr_val_len + 4 >= pdu_len) { 
    21382172            pdu += pdu_len; 
     
    22402274 
    22412275        adesc = find_attr_desc(attr_hdr->type); 
    2242         PJ_ASSERT_RETURN(adesc != NULL, PJ_EBUG); 
    2243  
    2244         status = adesc->encode_attr(attr_hdr, buf, buf_size, &printed); 
     2276        if (adesc) { 
     2277            status = adesc->encode_attr(attr_hdr, buf, buf_size, &printed); 
     2278        } else { 
     2279            /* This may be a generic attribute */ 
     2280            const pj_stun_binary_attr *bin_attr = (const pj_stun_binary_attr*)  
     2281                                                   attr_hdr; 
     2282            PJ_ASSERT_RETURN(bin_attr->magic == PJ_STUN_MAGIC, PJ_EBUG); 
     2283            status = encode_binary_attr(bin_attr, buf, buf_size, &printed); 
     2284        } 
     2285 
    22452286        if (status != PJ_SUCCESS) 
    22462287            return status; 
     
    24152456    /* Get the attribute descriptor */ 
    24162457    adesc = find_attr_desc(attr->type); 
    2417     PJ_ASSERT_RETURN(adesc != NULL, NULL); 
    2418  
    2419     return (pj_stun_attr_hdr*) (*adesc->clone_attr)(pool, attr); 
    2420 } 
    2421  
    2422  
     2458    if (adesc) { 
     2459        return (pj_stun_attr_hdr*) (*adesc->clone_attr)(pool, attr); 
     2460    } else { 
     2461        /* Clone generic attribute */ 
     2462        const pj_stun_binary_attr *bin_attr = (const pj_stun_binary_attr*) 
     2463                                               attr; 
     2464        PJ_ASSERT_RETURN(bin_attr->magic == PJ_STUN_MAGIC, NULL); 
     2465        if (bin_attr->magic == PJ_STUN_MAGIC) { 
     2466            return (pj_stun_attr_hdr*) clone_binary_attr(pool, attr); 
     2467        } else { 
     2468            return NULL; 
     2469        } 
     2470    } 
     2471} 
     2472 
     2473 
Note: See TracChangeset for help on using the changeset viewer.