Ignore:
Timestamp:
Sep 18, 2007 7:33:33 PM (17 years ago)
Author:
bennylp
Message:

Ticket #374: Update STUN specification from rfc3489bis-06 to rfc3489bis-10

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath-test/stun.c

    r1093 r1439  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
    1818 */ 
     19#include "test.h" 
     20 
     21#define THIS_FILE   "stun.c" 
     22 
     23static pj_stun_msg* create1(pj_pool_t*); 
     24static int verify1(pj_stun_msg*); 
     25static int verify2(pj_stun_msg*); 
     26static int verify5(pj_stun_msg*); 
     27 
     28static struct test 
     29{ 
     30    const char    *title; 
     31    char              *pdu; 
     32    unsigned       pdu_len; 
     33    pj_stun_msg* (*create)(pj_pool_t*); 
     34    pj_status_t    expected_status; 
     35    int          (*verify)(pj_stun_msg*); 
     36} tests[] =  
     37{ 
     38    { 
     39        "Invalid message type", 
     40        "\x11\x01\x00\x00\x21\x12\xa4\x42" 
     41        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 
     42        20, 
     43        NULL, 
     44        PJNATH_EINSTUNMSGTYPE, 
     45        NULL 
     46    }, 
     47    { 
     48        "Short message (1) (partial header)", 
     49        "\x00\x01", 
     50        2, 
     51        NULL, 
     52        PJNATH_EINSTUNMSGLEN, 
     53        NULL 
     54    }, 
     55    { 
     56        "Short message (2) (partial header)", 
     57        "\x00\x01\x00\x00\x21\x12\xa4\x42" 
     58        "\x00\x00\x00\x00\x00\x00\x00\x00", 
     59        16, 
     60        NULL, 
     61        PJNATH_EINSTUNMSGLEN, 
     62        NULL 
     63    }, 
     64    { 
     65        "Short message (3), (missing attribute)", 
     66        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     67        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 
     68        20, 
     69        NULL, 
     70        PJNATH_EINSTUNMSGLEN, 
     71        NULL 
     72    }, 
     73    { 
     74        "Short message (4), (partial attribute header)", 
     75        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     76        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     77        "\x80\x28", 
     78        22, 
     79        NULL, 
     80        PJNATH_EINSTUNMSGLEN, 
     81        NULL 
     82    }, 
     83    { 
     84        "Short message (5), (partial attribute header)", 
     85        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     86        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     87        "\x80\x28\x00", 
     88        23, 
     89        NULL, 
     90        PJNATH_EINSTUNMSGLEN, 
     91        NULL 
     92    }, 
     93    { 
     94        "Short message (6), (partial attribute header)", 
     95        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     96        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     97        "\x80\x28\x00\x04", 
     98        24, 
     99        NULL, 
     100        PJNATH_EINSTUNMSGLEN, 
     101        NULL 
     102    }, 
     103    { 
     104        "Short message (7), (partial attribute body)", 
     105        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     106        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     107        "\x80\x28\x00\x04\x00\x00\x00", 
     108        27, 
     109        NULL, 
     110        PJNATH_EINSTUNMSGLEN, 
     111        NULL 
     112    }, 
     113    { 
     114        "Message length in header is too long", 
     115        "\x00\x01\xff\xff\x21\x12\xa4\x42" 
     116        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     117        "\x80\x28\x00\x04\x00\x00\x00", 
     118        27, 
     119        NULL, 
     120        PJNATH_EINSTUNMSGLEN, 
     121        NULL 
     122    }, 
     123    { 
     124        "Message length in header is shorter", 
     125        "\x00\x01\x00\x04\x21\x12\xa4\x42" 
     126        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     127        "\x80\x28\x00\x04\x00\x00\x00\x00", 
     128        28, 
     129        NULL, 
     130        PJNATH_EINSTUNMSGLEN, 
     131        NULL 
     132    }, 
     133    { 
     134        "Invalid magic", 
     135        "\x00\x01\x00\x08\x00\x12\xa4\x42" 
     136        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     137        "\x80\x28\x00\x04\x00\x00\x00\x00", 
     138        28, 
     139        NULL, 
     140        PJ_SUCCESS, 
     141        NULL 
     142    }, 
     143    { 
     144        "Character beyond message", 
     145        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     146        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     147        "\x80\x28\x00\x04\x00\x00\x00\x00\x0a", 
     148        29, 
     149        NULL, 
     150        PJNATH_EINSTUNMSGLEN, 
     151        NULL 
     152    }, 
     153    { 
     154        "Respond unknown mandatory attribute with 420 and " 
     155        "UNKNOWN-ATTRIBUTES attribute", 
     156        NULL, 
     157        0, 
     158        &create1, 
     159        0, 
     160        &verify1 
     161    }, 
     162    { 
     163        "Unknown but non-mandatory should be okay", 
     164        "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     165        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     166        "\x80\xff\x00\x04\x00\x00\x00\x00", 
     167        28, 
     168        NULL, 
     169        PJ_SUCCESS, 
     170        &verify2 
     171    }, 
     172    { 
     173        "String attr length larger than message", 
     174        "\x00\x01\x00\x08\x00\x12\xa4\x42" 
     175        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     176        "\x00\x06\x00\xff\x00\x00\x00\x00", 
     177        28, 
     178        NULL, 
     179        PJNATH_ESTUNINATTRLEN, 
     180        NULL 
     181    }, 
     182    { 
     183        "Attribute other than FINGERPRINT after MESSAGE-INTEGRITY is allowed", 
     184        "\x00\x01\x00\x20\x21\x12\xa4\x42" 
     185        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     186        "\x00\x08\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     187                        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // M-I 
     188        "\x80\x24\x00\x04\x00\x00\x00\x00",  // REFRESH-INTERVAL 
     189        52, 
     190        NULL, 
     191        PJ_SUCCESS, 
     192        NULL 
     193    }, 
     194    { 
     195        "Attribute between MESSAGE-INTEGRITY and FINGERPRINT is allowed",  
     196        "\x00\x01\x00\x28\x21\x12\xa4\x42" 
     197        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     198        "\x00\x08\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     199                        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" // M-I 
     200        "\x80\x24\x00\x04\x00\x00\x00\x00"  // REFRESH-INTERVAL 
     201        "\x80\x28\x00\x04\xc7\xde\xdd\x65", // FINGERPRINT 
     202        60, 
     203        NULL, 
     204        PJ_SUCCESS, 
     205        &verify5 
     206    }, 
     207    { 
     208        "Attribute past FINGERPRINT is not allowed",  
     209        "\x00\x01\x00\x10\x21\x12\xa4\x42" 
     210        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     211        "\x80\x28\x00\x04\x00\x00\x00\x00" 
     212        "\x80\x24\x00\x04\x00\x00\x00\x00", 
     213        36, 
     214        NULL, 
     215        PJNATH_ESTUNFINGERPOS, 
     216        NULL 
     217    } 
     218}; 
     219 
     220static const char *err(pj_status_t status) 
     221{ 
     222    static char errmsg[PJ_ERR_MSG_SIZE]; 
     223    pj_strerror(status, errmsg, sizeof(errmsg)); 
     224    return errmsg; 
     225} 
     226 
     227static const pj_str_t USERNAME = {"user", 4}; 
     228static const pj_str_t PASSWORD = {"password", 8}; 
    19229 
    20230static int decode_test(void) 
    21231{ 
    22     /* Invalid message type */ 
    23  
    24     /* Short message */ 
    25  
    26     /* Long, random message */ 
    27  
    28     /* Message length in header is shorter */ 
    29  
    30     /* Message length in header is longer */ 
    31  
    32     /* Invalid magic */ 
    33  
    34     /* Attribute length is not valid */ 
    35  
    36     /* Unknown mandatory attribute type should generate error */ 
    37  
    38     /* Unknown but non-mandatory should be okay */ 
    39  
    40     /* String/binary attribute length is larger than the message */ 
    41  
    42     /* Valid message with MESSAGE-INTEGRITY */ 
    43  
    44     /* Valid message with FINGERPRINT */ 
    45  
    46     /* Valid message with MESSAGE-INTEGRITY and FINGERPRINT */ 
    47  
    48     /* Another attribute not FINGERPRINT exists after MESSAGE-INTEGRITY */ 
    49  
    50     /* Another attribute exists after FINGERPRINT */ 
     232    unsigned i; 
     233    pj_pool_t *pool; 
     234    int rc = 0; 
     235     
     236    pool = pj_pool_create(mem, "decode_test", 1024, 1024, NULL); 
     237 
     238    PJ_LOG(3,(THIS_FILE, "  STUN decode test")); 
     239 
     240    for (i=0; i<PJ_ARRAY_SIZE(tests); ++i) { 
     241        struct test *t = &tests[i]; 
     242        pj_stun_msg *msg, *msg2; 
     243        pj_uint8_t buf[1500]; 
     244        pj_str_t key; 
     245        unsigned len; 
     246        pj_status_t status; 
     247 
     248        PJ_LOG(3,(THIS_FILE, "   %s", t->title)); 
     249 
     250        if (t->pdu) { 
     251            status = pj_stun_msg_decode(pool, (pj_uint8_t*)t->pdu, t->pdu_len, 
     252                                        PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET,  
     253                                        &msg, NULL, NULL); 
     254 
     255            /* Check expected decode result */ 
     256            if (t->expected_status != status) { 
     257                PJ_LOG(1,(THIS_FILE, "    expecting status %d, got %d", 
     258                          t->expected_status, status)); 
     259                rc = -10; 
     260                goto on_return; 
     261            } 
     262 
     263        } else { 
     264            msg = t->create(pool); 
     265            status = PJ_SUCCESS; 
     266        } 
     267 
     268        if (status != PJ_SUCCESS) 
     269            continue; 
     270 
     271        /* Try to encode message */ 
     272        pj_stun_create_key(pool, &key, NULL, &USERNAME, &PASSWORD); 
     273        status = pj_stun_msg_encode(msg, buf, sizeof(buf), 0, &key, &len); 
     274        if (status != PJ_SUCCESS) { 
     275            PJ_LOG(1,(THIS_FILE, "    encode error: %s", err(status))); 
     276            rc = -40; 
     277            goto on_return; 
     278        } 
     279 
     280        /* Try to decode it once more */ 
     281        status = pj_stun_msg_decode(pool, buf, len,  
     282                                    PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET,  
     283                                    &msg2, NULL, NULL); 
     284        if (status != PJ_SUCCESS) { 
     285            PJ_LOG(1,(THIS_FILE, "    subsequent decoding failed: %s", err(status))); 
     286            rc = -50; 
     287            goto on_return; 
     288        } 
     289 
     290        /* Verify */ 
     291        if (t->verify) { 
     292            rc = t->verify(msg); 
     293            if (rc != 0) { 
     294                goto on_return; 
     295            } 
     296        } 
     297    } 
     298 
     299on_return: 
     300    pj_pool_release(pool); 
     301    if (rc == 0) 
     302        PJ_LOG(3,(THIS_FILE, "...success!")); 
     303    return rc; 
     304} 
     305 
     306/* Create 420 response */ 
     307static pj_stun_msg* create1(pj_pool_t *pool) 
     308{ 
     309    char *pdu = "\x00\x01\x00\x08\x21\x12\xa4\x42" 
     310                "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" 
     311                "\x00\xff\x00\x04\x00\x00\x00\x00"; 
     312    unsigned pdu_len = 28; 
     313    pj_stun_msg *msg, *res; 
     314    pj_status_t status; 
     315 
     316    status = pj_stun_msg_decode(pool, (pj_uint8_t*)pdu, pdu_len, 
     317                                PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, 
     318                                &msg, NULL, &res); 
     319    pj_assert(status != PJ_SUCCESS); 
     320    pj_assert(res != NULL); 
     321 
     322    return res; 
     323} 
     324 
     325/* Error response MUST have ERROR-CODE attribute */ 
     326/* 420 response MUST contain UNKNOWN-ATTRIBUTES */ 
     327static int verify1(pj_stun_msg *msg) 
     328{ 
     329    pj_stun_errcode_attr *aerr; 
     330    pj_stun_unknown_attr *aunk; 
     331 
     332    if (!PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) { 
     333        PJ_LOG(1,(THIS_FILE, "    expecting error message")); 
     334        return -100; 
     335    } 
     336 
     337    aerr = (pj_stun_errcode_attr*) 
     338           pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0); 
     339    if (aerr == NULL) { 
     340        PJ_LOG(1,(THIS_FILE, "    missing ERROR-CODE attribute")); 
     341        return -110; 
     342    } 
     343 
     344    if (aerr->err_code != 420) { 
     345        PJ_LOG(1,(THIS_FILE, "    expecting 420 error")); 
     346        return -120; 
     347    } 
     348 
     349    aunk = (pj_stun_unknown_attr*) 
     350           pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES, 0); 
     351    if (aunk == NULL) { 
     352        PJ_LOG(1,(THIS_FILE, "    missing UNKNOWN-ATTRIBUTE attribute")); 
     353        return -130; 
     354    } 
     355 
     356    if (aunk->attr_count != 1) { 
     357        PJ_LOG(1,(THIS_FILE, "    expecting one unknown attribute")); 
     358        return -140; 
     359    } 
     360 
     361    if (aunk->attrs[0] != 0xff) { 
     362        PJ_LOG(1,(THIS_FILE, "    expecting 0xff as unknown attribute")); 
     363        return -150; 
     364    } 
    51365 
    52366    return 0; 
    53367} 
     368 
     369/* Attribute count should be zero since unknown attribute is not parsed */ 
     370static int verify2(pj_stun_msg *msg) 
     371{ 
     372    if (msg->attr_count != 0) { 
     373        PJ_LOG(1,(THIS_FILE, "    expecting zero attribute count")); 
     374        return -200; 
     375    } 
     376    return 0; 
     377} 
     378 
     379 
     380/* Attribute between MESSAGE-INTEGRITY and FINGERPRINT is allowed */ 
     381static int verify5(pj_stun_msg *msg) 
     382{ 
     383    if (msg->attr_count != 3) { 
     384        PJ_LOG(1,(THIS_FILE, "    expecting 3 attribute count")); 
     385        return -500; 
     386    } 
     387 
     388    if (msg->attr[0]->type != PJ_STUN_ATTR_MESSAGE_INTEGRITY) { 
     389        PJ_LOG(1,(THIS_FILE, "    expecting MESSAGE-INTEGRITY")); 
     390        return -510; 
     391    } 
     392    if (msg->attr[1]->type != PJ_STUN_ATTR_REFRESH_INTERVAL) { 
     393        PJ_LOG(1,(THIS_FILE, "    expecting REFRESH-INTERVAL")); 
     394        return -520; 
     395    } 
     396    if (msg->attr[2]->type != PJ_STUN_ATTR_FINGERPRINT) { 
     397        PJ_LOG(1,(THIS_FILE, "    expecting FINGERPRINT")); 
     398        return -530; 
     399    } 
     400 
     401    return 0; 
     402} 
     403 
    54404 
    55405static int decode_verify(void) 
     
    108458} 
    109459 
     460typedef struct test_vector test_vector; 
     461 
     462static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v); 
     463static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v); 
     464 
     465enum 
     466{ 
     467    USE_MESSAGE_INTEGRITY   = 1, 
     468    USE_FINGERPRINT         = 2 
     469}; 
     470 
     471struct test_vector 
     472{ 
     473    unsigned       msg_type; 
     474    char          *tsx_id; 
     475    char          *pdu; 
     476    unsigned       pdu_len; 
     477    unsigned       options; 
     478    char          *username; 
     479    char          *password; 
     480    pj_stun_msg* (*create)(pj_pool_t*, test_vector*); 
     481} test_vectors[] =  
     482{ 
     483    { 
     484        PJ_STUN_BINDING_REQUEST, 
     485        "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae", 
     486        "\x00\x01\x00\x44\x21\x12\xa4\x42\xb7\xe7" 
     487        "\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" 
     488        "\x00\x24\x00\x04\x6e\x00\x01\xff\x80\x29" 
     489        "\x00\x08\x93\x2f\xf9\xb1\x51\x26\x3b\x36" 
     490        "\x00\x06\x00\x09\x65\x76\x74\x6a\x3a\x68" 
     491        "\x36\x76\x59\x20\x20\x20\x00\x08\x00\x14" 
     492        "\x62\x4e\xeb\xdc\x3c\xc9\x2d\xd8\x4b\x74" 
     493        "\xbf\x85\xd1\xc0\xf5\xde\x36\x87\xbd\x33" 
     494        "\x80\x28\x00\x04\xad\x8a\x85\xff", 
     495        88, 
     496        USE_MESSAGE_INTEGRITY | USE_FINGERPRINT, 
     497        "evtj:h6vY", 
     498        "VOkJxbRl1RmTxUk/WvJxBt", 
     499        &create_msgint1 
     500    }, 
     501    { 
     502        PJ_STUN_BINDING_RESPONSE, 
     503        "\xb7\xe7\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae", 
     504        "\x01\x01\x00\x3c\x21\x12\xa4\x42\xb7\xe7" 
     505        "\xa7\x01\xbc\x34\xd6\x86\xfa\x87\xdf\xae" 
     506        "\x80\x22\x00\x0b\x74\x65\x73\x74\x20\x76" 
     507        "\x65\x63\x74\x6f\x72\x20\x00\x20\x00\x08" 
     508        "\x00\x01\xa1\x47\x5e\x12\xa4\x43\x00\x08" 
     509        "\x00\x14\xab\x4e\x53\x29\x61\x00\x08\x4c" 
     510        "\x89\xf2\x7c\x69\x30\x33\x5c\xa3\x58\x14" 
     511        "\xea\x90\x80\x28\x00\x04\xae\x25\x8d\xf2", 
     512        80, 
     513        USE_MESSAGE_INTEGRITY | USE_FINGERPRINT, 
     514        "evtj:h6vY", 
     515        "VOkJxbRl1RmTxUk/WvJxBt", 
     516        &create_msgint2 
     517    } 
     518}; 
     519 
     520 
     521static char* print_binary(const pj_uint8_t *data, unsigned data_len) 
     522{ 
     523    static char buf[1500]; 
     524    unsigned length = sizeof(buf); 
     525    char *p = buf; 
     526    unsigned i; 
     527 
     528    for (i=0; i<data_len;) { 
     529        unsigned j; 
     530 
     531        pj_ansi_snprintf(p, 1500-(p-buf),  
     532                         "%04d-%04d   ", 
     533                         i, (i+20 < data_len) ? i+20 : data_len); 
     534        p += 12; 
     535 
     536        for (j=0; j<20 && i<data_len && p<(buf+length-10); ++j, ++i) { 
     537            pj_ansi_sprintf(p, "%02x ", (*data) & 0xFF); 
     538            p += 3; 
     539            data++; 
     540        } 
     541 
     542        pj_ansi_sprintf(p, "\n"); 
     543        p++; 
     544    } 
     545 
     546    return buf; 
     547} 
     548 
     549static int cmp_buf(const pj_uint8_t *s1, const pj_uint8_t *s2, unsigned len) 
     550{ 
     551    unsigned i; 
     552    for (i=0; i<len; ++i) { 
     553        if (s1[i] != s2[i]) 
     554            return i; 
     555    } 
     556 
     557    return -1; 
     558} 
     559 
     560static int fingerprint_test_vector() 
     561{ 
     562    pj_pool_t *pool; 
     563    pj_status_t status; 
     564    unsigned i; 
     565    int rc = 0; 
     566 
     567    PJ_LOG(3,(THIS_FILE, "  STUN message test vectors")); 
     568 
     569    pool = pj_pool_create(mem, "fingerprint", 1024, 1024, NULL); 
     570 
     571    for (i=0; i<PJ_ARRAY_SIZE(test_vectors); ++i) { 
     572        struct test_vector *v; 
     573        pj_stun_msg *ref_msg, *msg; 
     574        unsigned parsed_len; 
     575        unsigned len, pos; 
     576        pj_uint8_t buf[1500]; 
     577        char print[1500]; 
     578        pj_str_t key; 
     579 
     580        PJ_LOG(3,(THIS_FILE, "    Running test %d/%d", i,  
     581                  PJ_ARRAY_SIZE(test_vectors))); 
     582 
     583        v = &test_vectors[i]; 
     584 
     585        /* Print reference message */ 
     586        PJ_LOG(4,(THIS_FILE, "Reference message PDU:\n%s", 
     587                  print_binary((pj_uint8_t*)v->pdu, v->pdu_len))); 
     588 
     589        /* Try to parse the reference message first */ 
     590        status = pj_stun_msg_decode(pool, (pj_uint8_t*)v->pdu, v->pdu_len, 
     591                                    PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET,  
     592                                    &ref_msg, &parsed_len, NULL); 
     593        if (status != PJ_SUCCESS) { 
     594            PJ_LOG(1,(THIS_FILE, "    Error decoding reference message")); 
     595            rc = -1010; 
     596            goto on_return; 
     597        } 
     598 
     599        if (parsed_len != v->pdu_len) { 
     600            PJ_LOG(1,(THIS_FILE, "    Parsed len error")); 
     601            rc = -1020; 
     602            goto on_return; 
     603        } 
     604 
     605        /* Print the reference message */ 
     606        pj_stun_msg_dump(ref_msg, print, sizeof(print), NULL); 
     607        PJ_LOG(4,(THIS_FILE, "Reference message:\n%s", print)); 
     608 
     609        /* Create our message */ 
     610        msg = v->create(pool, v); 
     611 
     612        /* Encode message */ 
     613        if (v->options & USE_MESSAGE_INTEGRITY) { 
     614            pj_str_t s1, s2; 
     615 
     616            pj_stun_create_key(pool, &key, NULL, pj_cstr(&s1, v->username),  
     617                               pj_cstr(&s2, v->password)); 
     618            pj_stun_msg_encode(msg, buf, sizeof(buf), 0, &key, &len); 
     619 
     620        } else { 
     621            pj_stun_msg_encode(msg, buf, sizeof(buf), 0, NULL, &len); 
     622        } 
     623 
     624        /* Print our raw message */ 
     625        PJ_LOG(4,(THIS_FILE, "Message PDU:\n%s", 
     626                  print_binary((pj_uint8_t*)buf, len))); 
     627 
     628        /* Print our message */ 
     629        pj_stun_msg_dump(msg, print, sizeof(print), NULL); 
     630        PJ_LOG(4,(THIS_FILE, "Message is:\n%s", print)); 
     631 
     632        /* Compare message length */ 
     633        if (len != v->pdu_len) { 
     634            PJ_LOG(1,(THIS_FILE, "    Message length mismatch")); 
     635            rc = -1050; 
     636            goto on_return; 
     637        } 
     638 
     639        pos = cmp_buf(buf, (const pj_uint8_t*)v->pdu, len); 
     640        if (pos != -1) { 
     641            PJ_LOG(1,(THIS_FILE, "    Message mismatch at byte %d", pos)); 
     642            rc = -1060; 
     643            goto on_return; 
     644        } 
     645 
     646        /* Authenticate the request/response */ 
     647        if (v->options & USE_MESSAGE_INTEGRITY) { 
     648            if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 
     649                pj_stun_auth_cred cred; 
     650                pj_status_t status; 
     651 
     652                pj_bzero(&cred, sizeof(cred)); 
     653                cred.type = PJ_STUN_AUTH_CRED_STATIC; 
     654                cred.data.static_cred.username = pj_str(v->username); 
     655                cred.data.static_cred.data = pj_str(v->password); 
     656 
     657                status = pj_stun_authenticate_request(buf, len, msg,  
     658                                                      &cred, pool, NULL); 
     659                if (status != PJ_SUCCESS) { 
     660                    char errmsg[PJ_ERR_MSG_SIZE]; 
     661                    pj_strerror(status, errmsg, sizeof(errmsg)); 
     662                    PJ_LOG(1,(THIS_FILE,  
     663                              "    Request authentication failed: %s", 
     664                              errmsg)); 
     665                    rc = -1070; 
     666                    goto on_return; 
     667                } 
     668 
     669            } else if (PJ_STUN_IS_RESPONSE(msg->hdr.type)) { 
     670                pj_status_t status; 
     671                status = pj_stun_authenticate_response(buf, len, msg, &key); 
     672                if (status != PJ_SUCCESS) { 
     673                    char errmsg[PJ_ERR_MSG_SIZE]; 
     674                    pj_strerror(status, errmsg, sizeof(errmsg)); 
     675                    PJ_LOG(1,(THIS_FILE,  
     676                              "    Response authentication failed: %s", 
     677                              errmsg)); 
     678                    rc = -1080; 
     679                    goto on_return; 
     680                } 
     681            } 
     682        }        
     683    } 
     684 
     685 
     686on_return: 
     687    pj_pool_release(pool); 
     688    return rc; 
     689} 
     690 
     691static pj_stun_msg* create_msgint1(pj_pool_t *pool, test_vector *v) 
     692{ 
     693    pj_stun_msg *msg; 
     694    pj_timestamp u64; 
     695    pj_str_t s1; 
     696 
     697    pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, 
     698                       (pj_uint8_t*)v->tsx_id, &msg); 
     699 
     700    pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_PRIORITY, 0x6e0001ff); 
     701    u64.u32.hi = 0x932ff9b1; 
     702    u64.u32.lo = 0x51263b36; 
     703    pj_stun_msg_add_uint64_attr(pool, msg, PJ_STUN_ATTR_ICE_CONTROLLED, 
     704                                &u64); 
     705 
     706    pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_USERNAME,  
     707                                pj_cstr(&s1, v->username)); 
     708 
     709    pj_stun_msg_add_msgint_attr(pool, msg); 
     710 
     711    pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); 
     712 
     713    return msg; 
     714} 
     715 
     716static pj_stun_msg* create_msgint2(pj_pool_t *pool, test_vector *v) 
     717{ 
     718    pj_stun_msg *msg; 
     719    pj_sockaddr_in mapped_addr; 
     720    pj_str_t s1; 
     721 
     722    pj_stun_msg_create(pool, v->msg_type, PJ_STUN_MAGIC, 
     723                       (pj_uint8_t*)v->tsx_id, &msg); 
     724 
     725    pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SERVER,  
     726                                pj_cstr(&s1, "test vector")); 
     727 
     728    pj_sockaddr_in_init(&mapped_addr, pj_cstr(&s1, "127.0.0.1"), 32853); 
     729    pj_stun_msg_add_sockaddr_attr(pool, msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
     730                                  PJ_TRUE, &mapped_addr,  
     731                                  sizeof(pj_sockaddr_in)); 
     732 
     733    pj_stun_msg_add_msgint_attr(pool, msg); 
     734    pj_stun_msg_add_uint_attr(pool, msg, PJ_STUN_ATTR_FINGERPRINT, 0); 
     735 
     736    return msg; 
     737} 
     738 
    110739 
    111740int stun_test(void) 
    112741{ 
    113     decode_verify(); 
    114     decode_test(); 
    115     auth_test(); 
    116     return 0; 
    117 } 
    118  
     742    int pad, rc; 
     743 
     744    pad = pj_stun_set_padding_char(32); 
     745 
     746    rc = decode_test(); 
     747    if (rc != 0) 
     748        goto on_return; 
     749 
     750    rc = decode_verify(); 
     751    if (rc != 0) 
     752        goto on_return; 
     753 
     754    rc = auth_test(); 
     755    if (rc != 0) 
     756        goto on_return; 
     757 
     758    rc = fingerprint_test_vector(); 
     759    if (rc != 0) 
     760        goto on_return; 
     761 
     762on_return: 
     763    pj_stun_set_padding_char(pad); 
     764    return rc; 
     765} 
     766 
Note: See TracChangeset for help on using the changeset viewer.