Ignore:
Timestamp:
Mar 19, 2008 11:00:30 PM (14 years ago)
Author:
bennylp
Message:

Related to ticket #485: huge changeset to update STUN relating to managing authentication. See the ticket for the details

File:
1 edited

Legend:

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

    r1869 r1877  
    1818 */ 
    1919#include <pjnath/stun_session.h> 
     20#include <pjnath/errno.h> 
    2021#include <pjlib.h> 
    2122 
     
    3031 
    3132    pj_bool_t            use_fingerprint; 
    32     pj_stun_auth_cred   *cred; 
     33 
     34    char                 dump_buf[1000]; 
     35 
     36    pj_stun_auth_type    auth_type; 
     37    pj_stun_auth_cred    cred; 
     38    int                  auth_retry; 
     39    pj_str_t             next_nonce; 
     40 
    3341    pj_str_t             srv_name; 
    3442 
     
    126134} 
    127135 
    128 static pj_status_t create_request_tdata(pj_stun_session *sess, 
    129                                         unsigned msg_type, 
    130                                         pj_uint32_t magic, 
    131                                         const pj_uint8_t tsx_id[12], 
    132                                         pj_stun_tx_data **p_tdata) 
    133 { 
    134     pj_status_t status; 
    135     pj_stun_tx_data *tdata; 
    136  
    137     status = create_tdata(sess, &tdata); 
    138     if (status != PJ_SUCCESS) 
    139         return status; 
    140  
    141     /* Create STUN message */ 
    142     status = pj_stun_msg_create(tdata->pool, msg_type,  magic,  
    143                                 tsx_id, &tdata->msg); 
    144     if (status != PJ_SUCCESS) { 
    145         pj_pool_release(tdata->pool); 
    146         return status; 
    147     } 
    148  
    149     /* copy the request's transaction ID as the transaction key. */ 
    150     pj_assert(sizeof(tdata->msg_key)==sizeof(tdata->msg->hdr.tsx_id)); 
    151     tdata->msg_magic = tdata->msg->hdr.magic; 
    152     pj_memcpy(tdata->msg_key, tdata->msg->hdr.tsx_id, 
    153               sizeof(tdata->msg->hdr.tsx_id)); 
    154  
    155     *p_tdata = tdata; 
    156  
    157     return PJ_SUCCESS; 
    158 } 
    159  
    160  
    161136static void stun_tsx_on_destroy(pj_stun_client_tsx *tsx) 
    162137{ 
     
    216191} 
    217192 
    218 static pj_status_t get_key(pj_stun_session *sess, pj_pool_t *pool, 
    219                            const pj_stun_msg *msg, pj_str_t *auth_key) 
    220 { 
    221     if (sess->cred == NULL) { 
    222         auth_key->slen = 0; 
    223         return PJ_SUCCESS; 
    224     } else if (sess->cred->type == PJ_STUN_AUTH_CRED_STATIC) { 
    225         pj_stun_create_key(pool, auth_key,  
    226                            &sess->cred->data.static_cred.realm, 
    227                            &sess->cred->data.static_cred.username, 
    228                            &sess->cred->data.static_cred.data); 
    229         return PJ_SUCCESS; 
    230     } else if (sess->cred->type == PJ_STUN_AUTH_CRED_DYNAMIC) { 
    231         pj_str_t realm, username, nonce; 
    232         pj_str_t *password; 
    233         void *user_data = sess->cred->data.dyn_cred.user_data; 
    234         int data_type = 0; 
    235         pj_status_t status; 
    236  
    237         realm.slen = username.slen = nonce.slen = 0; 
    238         password = PJ_POOL_ZALLOC_T(pool, pj_str_t); 
    239         status = (*sess->cred->data.dyn_cred.get_cred)(msg, user_data, pool, 
    240                                                        &realm, &username, 
    241                                                        &nonce, &data_type, 
    242                                                        password); 
    243         if (status != PJ_SUCCESS) 
    244             return status; 
    245  
    246         pj_stun_create_key(pool, auth_key,  
    247                            &realm, &username, password); 
    248  
    249         return PJ_SUCCESS; 
    250  
    251     } else { 
    252         pj_assert(!"Unknown credential type"); 
    253         return PJ_EBUG; 
    254     } 
    255 } 
    256  
    257193static pj_status_t apply_msg_options(pj_stun_session *sess, 
    258194                                     pj_pool_t *pool, 
     195                                     const pj_stun_req_cred_info *auth_info, 
    259196                                     pj_stun_msg *msg) 
    260197{ 
    261198    pj_status_t status = 0; 
    262     pj_bool_t need_auth; 
    263     pj_str_t realm, username, nonce, password; 
    264     int data_type = 0; 
    265  
    266     realm.slen = username.slen = nonce.slen = password.slen = 0; 
     199    pj_str_t realm, username, nonce, auth_key; 
    267200 
    268201    /* The server SHOULD include a SERVER attribute in all responses */ 
     
    272205    } 
    273206 
    274     need_auth = pj_stun_auth_valid_for_msg(msg); 
    275  
    276     if (sess->cred && sess->cred->type == PJ_STUN_AUTH_CRED_STATIC && 
    277         need_auth) 
    278     { 
    279         realm = sess->cred->data.static_cred.realm; 
    280         username = sess->cred->data.static_cred.username; 
    281         data_type = sess->cred->data.static_cred.data_type; 
    282         password = sess->cred->data.static_cred.data; 
    283         nonce = sess->cred->data.static_cred.nonce; 
    284  
    285     } else if (sess->cred && sess->cred->type == PJ_STUN_AUTH_CRED_DYNAMIC && 
    286                need_auth)  
    287     { 
    288         void *user_data = sess->cred->data.dyn_cred.user_data; 
    289  
    290         status = (*sess->cred->data.dyn_cred.get_cred)(msg, user_data, pool, 
    291                                                        &realm, &username, 
    292                                                        &nonce, &data_type, 
    293                                                        &password); 
    294         if (status != PJ_SUCCESS) 
    295             return status; 
    296     } 
    297  
    298  
    299     /* Create and add USERNAME attribute for */ 
     207    if (pj_stun_auth_valid_for_msg(msg) && auth_info) { 
     208        realm = auth_info->realm; 
     209        username = auth_info->username; 
     210        nonce = auth_info->nonce; 
     211        auth_key = auth_info->auth_key; 
     212    } else { 
     213        realm.slen = username.slen = nonce.slen = auth_key.slen = 0; 
     214    } 
     215 
     216    /* Create and add USERNAME attribute if needed */ 
    300217    if (username.slen && PJ_STUN_IS_REQUEST(msg->hdr.type)) { 
    301218        status = pj_stun_msg_add_string_attr(pool, msg, 
     
    324241 
    325242    /* Add MESSAGE-INTEGRITY attribute */ 
    326     if (username.slen && need_auth) { 
     243    if (username.slen && auth_key.slen) { 
    327244        status = pj_stun_msg_add_msgint_attr(pool, msg); 
    328245        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     
    340257} 
    341258 
     259static pj_status_t handle_auth_challenge(pj_stun_session *sess, 
     260                                         const pj_stun_tx_data *request, 
     261                                         const pj_stun_msg *response, 
     262                                         const pj_sockaddr_t *src_addr, 
     263                                         unsigned src_addr_len, 
     264                                         pj_bool_t *notify_user) 
     265{ 
     266    const pj_stun_errcode_attr *ea; 
     267 
     268    *notify_user = PJ_TRUE; 
     269 
     270    if (sess->auth_type != PJ_STUN_AUTH_LONG_TERM) 
     271        return PJ_SUCCESS; 
     272     
     273    if (!PJ_STUN_IS_ERROR_RESPONSE(response->hdr.type)) 
     274        return PJ_SUCCESS; 
     275 
     276    ea = (const pj_stun_errcode_attr*) 
     277         pj_stun_msg_find_attr(response, PJ_STUN_ATTR_ERROR_CODE, 0); 
     278    if (!ea) { 
     279        PJ_LOG(4,(SNAME(sess), "Invalid error response: no ERROR-CODE" 
     280                  " attribute")); 
     281        *notify_user = PJ_FALSE; 
     282        return PJNATH_EINSTUNMSG; 
     283    } 
     284 
     285    if (ea->err_code == PJ_STUN_SC_UNAUTHORIZED ||  
     286        ea->err_code == PJ_STUN_SC_STALE_NONCE) 
     287    { 
     288        const pj_stun_nonce_attr *anonce; 
     289        pj_stun_tx_data *tdata; 
     290        unsigned i; 
     291        pj_status_t status; 
     292 
     293        anonce = (const pj_stun_nonce_attr*) 
     294                 pj_stun_msg_find_attr(response, PJ_STUN_ATTR_NONCE, 0); 
     295        if (!anonce) { 
     296            PJ_LOG(4,(SNAME(sess), "Invalid response: missing NONCE")); 
     297            *notify_user = PJ_FALSE; 
     298            return PJNATH_EINSTUNMSG; 
     299        } 
     300 
     301        /* Bail out if we've supplied the correct nonce */ 
     302        if (pj_strcmp(&anonce->value, &sess->next_nonce)==0) { 
     303            return PJ_SUCCESS; 
     304        } 
     305 
     306        /* Bail out if we've tried too many */ 
     307        if (++sess->auth_retry > 3) { 
     308            PJ_LOG(4,(SNAME(sess), "Error: authentication failed (too " 
     309                      "many retries)")); 
     310            return PJ_STATUS_FROM_STUN_CODE(401); 
     311        } 
     312 
     313        /* Save next_nonce */ 
     314        pj_strdup(sess->pool, &sess->next_nonce, &anonce->value); 
     315 
     316        /* Create new request */ 
     317        status = pj_stun_session_create_req(sess, request->msg->hdr.type, 
     318                                            request->msg->hdr.magic, 
     319                                            NULL, &tdata); 
     320        if (status != PJ_SUCCESS) 
     321            return status; 
     322 
     323        /* Duplicate all the attributes in the old request, except 
     324         * USERNAME, REALM, M-I, and NONCE  
     325         */ 
     326        for (i=0; i<request->msg->attr_count; ++i) { 
     327            const pj_stun_attr_hdr *asrc = request->msg->attr[i]; 
     328 
     329            if (asrc->type == PJ_STUN_ATTR_USERNAME || 
     330                asrc->type == PJ_STUN_ATTR_REALM || 
     331                asrc->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY || 
     332                asrc->type == PJ_STUN_ATTR_NONCE) 
     333            { 
     334                continue; 
     335            } 
     336 
     337            tdata->msg->attr[tdata->msg->attr_count++] =  
     338                pj_stun_attr_clone(tdata->pool, asrc); 
     339        } 
     340 
     341        /* Will retry the request with authentication, no need to 
     342         * notify user. 
     343         */ 
     344        *notify_user = PJ_FALSE; 
     345 
     346        PJ_LOG(4,(SNAME(sess), "Retrying request with new authentication")); 
     347 
     348        /* Retry the request */ 
     349        status = pj_stun_session_send_msg(sess, PJ_TRUE, src_addr,  
     350                                          src_addr_len, tdata); 
     351 
     352    } else { 
     353        sess->auth_retry = 0; 
     354    } 
     355 
     356    return PJ_SUCCESS; 
     357} 
    342358 
    343359static void stun_tsx_on_complete(pj_stun_client_tsx *tsx, 
     
    347363                                 unsigned src_addr_len) 
    348364{ 
     365    pj_stun_session *sess; 
     366    pj_bool_t notify_user = PJ_TRUE; 
    349367    pj_stun_tx_data *tdata; 
    350368 
    351369    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 
    352  
    353     if (tdata->sess->cb.on_request_complete) { 
    354         (*tdata->sess->cb.on_request_complete)(tdata->sess, status, tdata,  
    355                                                response,  
    356                                                src_addr, src_addr_len); 
     370    sess = tdata->sess; 
     371 
     372    /* Handle authentication challenge */ 
     373    handle_auth_challenge(sess, tdata, response, src_addr, 
     374                          src_addr_len, &notify_user); 
     375 
     376    if (notify_user && sess->cb.on_request_complete) { 
     377        (*sess->cb.on_request_complete)(sess, status, tdata,  
     378                                        response,  
     379                                        src_addr, src_addr_len); 
    357380    } 
    358381} 
     
    489512} 
    490513 
    491 PJ_DEF(void) pj_stun_session_set_credential(pj_stun_session *sess, 
    492                                             const pj_stun_auth_cred *cred) 
    493 { 
    494     PJ_ASSERT_ON_FAIL(sess, return); 
     514PJ_DEF(pj_status_t) pj_stun_session_set_credential(pj_stun_session *sess, 
     515                                                 pj_stun_auth_type auth_type, 
     516                                                 const pj_stun_auth_cred *cred) 
     517{ 
     518    PJ_ASSERT_RETURN(sess, PJ_EINVAL); 
     519 
     520    sess->auth_type = auth_type; 
    495521    if (cred) { 
    496         if (!sess->cred) 
    497             sess->cred = PJ_POOL_ALLOC_T(sess->pool, pj_stun_auth_cred); 
    498         pj_stun_auth_cred_dup(sess->pool, sess->cred, cred); 
     522        pj_stun_auth_cred_dup(sess->pool, &sess->cred, cred); 
    499523    } else { 
    500         sess->cred = NULL; 
    501     } 
    502 } 
    503  
     524        sess->auth_type = PJ_STUN_AUTH_NONE; 
     525        pj_bzero(&sess->cred, sizeof(sess->cred)); 
     526    } 
     527 
     528    return PJ_SUCCESS; 
     529} 
     530 
     531 
     532static pj_status_t get_auth(pj_stun_session *sess, 
     533                            pj_stun_tx_data *tdata) 
     534{ 
     535    if (sess->cred.type == PJ_STUN_AUTH_CRED_STATIC) { 
     536        tdata->auth_info.realm = sess->cred.data.static_cred.realm; 
     537        tdata->auth_info.username = sess->cred.data.static_cred.username; 
     538        tdata->auth_info.nonce = sess->cred.data.static_cred.nonce; 
     539 
     540        pj_stun_create_key(tdata->pool, &tdata->auth_info.auth_key,  
     541                           &tdata->auth_info.realm, 
     542                           &tdata->auth_info.username, 
     543                           sess->cred.data.static_cred.data_type, 
     544                           &sess->cred.data.static_cred.data); 
     545 
     546    } else if (sess->cred.type == PJ_STUN_AUTH_CRED_DYNAMIC) { 
     547        pj_str_t password; 
     548        void *user_data = sess->cred.data.dyn_cred.user_data; 
     549        pj_stun_passwd_type data_type = PJ_STUN_PASSWD_PLAIN; 
     550        pj_status_t rc; 
     551 
     552        rc = (*sess->cred.data.dyn_cred.get_cred)(tdata->msg, user_data,  
     553                                                  tdata->pool, 
     554                                                  &tdata->auth_info.realm,  
     555                                                  &tdata->auth_info.username, 
     556                                                  &tdata->auth_info.nonce,  
     557                                                  &data_type, &password); 
     558        if (rc != PJ_SUCCESS) 
     559            return rc; 
     560 
     561        pj_stun_create_key(tdata->pool, &tdata->auth_info.auth_key,  
     562                           &tdata->auth_info.realm, &tdata->auth_info.username, 
     563                           data_type, &password); 
     564 
     565    } else { 
     566        pj_assert(!"Unknown credential type"); 
     567        return PJ_EBUG; 
     568    } 
     569 
     570    return PJ_SUCCESS; 
     571} 
    504572 
    505573PJ_DEF(pj_status_t) pj_stun_session_create_req(pj_stun_session *sess, 
     
    514582    PJ_ASSERT_RETURN(sess && p_tdata, PJ_EINVAL); 
    515583 
    516     status = create_request_tdata(sess, method, magic, tsx_id, &tdata); 
     584    status = create_tdata(sess, &tdata); 
    517585    if (status != PJ_SUCCESS) 
    518586        return status; 
     587 
     588    /* Create STUN message */ 
     589    status = pj_stun_msg_create(tdata->pool, method,  magic,  
     590                                tsx_id, &tdata->msg); 
     591    if (status != PJ_SUCCESS) { 
     592        pj_pool_release(tdata->pool); 
     593        return status; 
     594    } 
     595 
     596    /* copy the request's transaction ID as the transaction key. */ 
     597    pj_assert(sizeof(tdata->msg_key)==sizeof(tdata->msg->hdr.tsx_id)); 
     598    tdata->msg_magic = tdata->msg->hdr.magic; 
     599    pj_memcpy(tdata->msg_key, tdata->msg->hdr.tsx_id, 
     600              sizeof(tdata->msg->hdr.tsx_id)); 
     601 
     602     
     603    /* Get authentication information for the request */ 
     604    if (sess->auth_type == PJ_STUN_AUTH_NONE) { 
     605        /* No authentication */ 
     606 
     607    } else if (sess->auth_type == PJ_STUN_AUTH_SHORT_TERM) { 
     608        /* MUST put authentication in request */ 
     609        status = get_auth(sess, tdata); 
     610        if (status != PJ_SUCCESS) { 
     611            pj_pool_release(tdata->pool); 
     612            return status; 
     613        } 
     614 
     615    } else if (sess->auth_type == PJ_STUN_AUTH_LONG_TERM) { 
     616        /* Only put authentication information if we've received 
     617         * response from server. 
     618         */ 
     619        if (sess->next_nonce.slen != 0) { 
     620            status = get_auth(sess, tdata); 
     621            if (status != PJ_SUCCESS) { 
     622                pj_pool_release(tdata->pool); 
     623                return status; 
     624            } 
     625            tdata->auth_info.nonce = sess->next_nonce; 
     626        } 
     627 
     628    } else { 
     629        pj_assert(!"Invalid authentication type"); 
     630        pj_pool_release(tdata->pool); 
     631        return PJ_EBUG; 
     632    } 
    519633 
    520634    *p_tdata = tdata; 
     
    552666 */ 
    553667PJ_DEF(pj_status_t) pj_stun_session_create_res( pj_stun_session *sess, 
    554                                                 const pj_stun_msg *req, 
     668                                                const pj_stun_rx_data *rdata, 
    555669                                                unsigned err_code, 
    556670                                                const pj_str_t *err_msg, 
     
    565679 
    566680    /* Create STUN response message */ 
    567     status = pj_stun_msg_create_response(tdata->pool, req, err_code, err_msg, 
    568                                          &tdata->msg); 
     681    status = pj_stun_msg_create_response(tdata->pool, rdata->msg,  
     682                                         err_code, err_msg, &tdata->msg); 
    569683    if (status != PJ_SUCCESS) { 
    570684        pj_pool_release(tdata->pool); 
     
    573687 
    574688    /* copy the request's transaction ID as the transaction key. */ 
    575     pj_assert(sizeof(tdata->msg_key)==sizeof(req->hdr.tsx_id)); 
    576     tdata->msg_magic = req->hdr.magic; 
    577     pj_memcpy(tdata->msg_key, req->hdr.tsx_id, sizeof(req->hdr.tsx_id)); 
     689    pj_assert(sizeof(tdata->msg_key)==sizeof(rdata->msg->hdr.tsx_id)); 
     690    tdata->msg_magic = rdata->msg->hdr.magic; 
     691    pj_memcpy(tdata->msg_key, rdata->msg->hdr.tsx_id,  
     692              sizeof(rdata->msg->hdr.tsx_id)); 
     693 
     694    /* copy the credential found in the request */ 
     695    pj_stun_req_cred_info_dup(tdata->pool, &tdata->auth_info, &rdata->info); 
    578696 
    579697    *p_tdata = tdata; 
     
    587705                        unsigned pkt_size, const pj_sockaddr_t *addr) 
    588706{ 
    589     const char *dst_name; 
    590     int dst_port; 
    591     const pj_sockaddr *dst = (const pj_sockaddr*)addr; 
    592     char buf[800]; 
     707    char dst_name[80]; 
    593708     
    594     if (dst->addr.sa_family == pj_AF_INET()) { 
    595         dst_name = pj_inet_ntoa(dst->ipv4.sin_addr); 
    596         dst_port = pj_ntohs(dst->ipv4.sin_port); 
    597     } else if (dst->addr.sa_family == pj_AF_INET6()) { 
    598         dst_name = "IPv6"; 
    599         dst_port = pj_ntohs(dst->ipv6.sin6_port); 
    600     } else { 
    601         LOG_ERR_(sess, "Invalid address family", PJ_EINVAL); 
    602         return; 
    603     } 
     709    pj_sockaddr_print(addr, dst_name, sizeof(dst_name), 3); 
    604710 
    605711    PJ_LOG(5,(SNAME(sess),  
    606               "TX %d bytes STUN message to %s:%d:\n" 
     712              "TX %d bytes STUN message to %s:\n" 
    607713              "--- begin STUN message ---\n" 
    608714              "%s" 
    609715              "--- end of STUN message ---\n", 
    610               pkt_size, dst_name, dst_port, 
    611               pj_stun_msg_dump(msg, buf, sizeof(buf), NULL))); 
     716              pkt_size, dst_name,  
     717              pj_stun_msg_dump(msg, sess->dump_buf, sizeof(sess->dump_buf),  
     718                               NULL))); 
    612719 
    613720} 
     
    632739 
    633740    /* Apply options */ 
    634     status = apply_msg_options(sess, tdata->pool, tdata->msg); 
     741    status = apply_msg_options(sess, tdata->pool, &tdata->auth_info,  
     742                               tdata->msg); 
    635743    if (status != PJ_SUCCESS) { 
    636744        pj_stun_msg_destroy_tdata(sess, tdata); 
     
    640748    } 
    641749 
    642     status = get_key(sess, tdata->pool, tdata->msg, &tdata->auth_key); 
    643     if (status != PJ_SUCCESS) { 
    644         pj_stun_msg_destroy_tdata(sess, tdata); 
    645         pj_lock_release(sess->lock); 
    646         LOG_ERR_(sess, "Error getting creadential's key", status); 
    647         return status; 
    648     } 
    649  
    650750    /* Encode message */ 
    651751    status = pj_stun_msg_encode(tdata->msg, (pj_uint8_t*)tdata->pkt,  
    652752                                tdata->max_len, 0,  
    653                                 &tdata->auth_key, 
     753                                &tdata->auth_info.auth_key, 
    654754                                &tdata->pkt_size); 
    655755    if (status != PJ_SUCCESS) { 
     
    743843 */ 
    744844PJ_DEF(pj_status_t) pj_stun_session_respond( pj_stun_session *sess,  
    745                                              const pj_stun_msg *req, 
     845                                             const pj_stun_rx_data *rdata, 
    746846                                             unsigned code,  
    747847                                             const char *errmsg, 
     
    754854    pj_stun_tx_data *tdata; 
    755855 
    756     status = pj_stun_session_create_res(sess, req, code,  
     856    status = pj_stun_session_create_res(sess, rdata, code,  
    757857                                        (errmsg?pj_cstr(&reason,errmsg):NULL),  
    758858                                        &tdata); 
     
    814914static pj_status_t send_response(pj_stun_session *sess,  
    815915                                 pj_pool_t *pool, pj_stun_msg *response, 
    816                                  const pj_str_t *auth_key, 
     916                                 const pj_stun_req_cred_info *auth_info, 
    817917                                 pj_bool_t retransmission, 
    818918                                 const pj_sockaddr_t *addr, unsigned addr_len) 
     
    824924    /* Apply options */ 
    825925    if (!retransmission) { 
    826         status = apply_msg_options(sess, pool, response); 
     926        status = apply_msg_options(sess, pool, auth_info, response); 
    827927        if (status != PJ_SUCCESS) 
    828928            return status; 
     
    835935    /* Encode */ 
    836936    status = pj_stun_msg_encode(response, out_pkt, out_max_len, 0,  
    837                                 auth_key, &out_len); 
     937                                &auth_info->auth_key, &out_len); 
    838938    if (status != PJ_SUCCESS) { 
    839939        LOG_ERR_(sess, "Error encoding message", status); 
     
    854954                                    const pj_uint8_t *pkt, 
    855955                                    unsigned pkt_len, 
    856                                     const pj_stun_msg *msg, 
     956                                    pj_stun_rx_data *rdata, 
    857957                                    pj_pool_t *tmp_pool, 
    858958                                    const pj_sockaddr_t *src_addr, 
     
    860960{ 
    861961    pj_stun_msg *response; 
    862     pj_str_t auth_key; 
    863962    pj_status_t status; 
    864963 
    865     if (PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type) || sess->cred == NULL) 
     964    if (PJ_STUN_IS_ERROR_RESPONSE(rdata->msg->hdr.type) ||  
     965        sess->auth_type == PJ_STUN_AUTH_NONE) 
     966    { 
    866967        return PJ_SUCCESS; 
    867  
    868     status = pj_stun_authenticate_request(pkt, pkt_len, msg, sess->cred, 
    869                                           tmp_pool, &auth_key, &response); 
     968    } 
     969 
     970    status = pj_stun_authenticate_request(pkt, pkt_len, rdata->msg,  
     971                                          &sess->cred, tmp_pool, &rdata->info, 
     972                                          &response); 
    870973    if (status != PJ_SUCCESS && response != NULL) { 
    871974        PJ_LOG(5,(SNAME(sess), "Message authentication failed")); 
    872         send_response(sess, tmp_pool, response, &auth_key, PJ_FALSE,  
     975        send_response(sess, tmp_pool, response, &rdata->info, PJ_FALSE,  
    873976                      src_addr, src_addr_len); 
    874977    } 
     
    8981001    } 
    8991002 
     1003    if (sess->auth_type == PJ_STUN_AUTH_NONE) 
     1004        options |= PJ_STUN_NO_AUTHENTICATE; 
     1005 
    9001006    /* Authenticate the message, unless PJ_STUN_NO_AUTHENTICATE 
    9011007     * is specified in the option. 
    9021008     */ 
    903     if ((options & PJ_STUN_NO_AUTHENTICATE) == 0 && tdata->auth_key.slen != 0 
    904         && pj_stun_auth_valid_for_msg(msg)) 
     1009    if ((options & PJ_STUN_NO_AUTHENTICATE) == 0 &&  
     1010        tdata->auth_info.auth_key.slen != 0 &&  
     1011        pj_stun_auth_valid_for_msg(msg)) 
    9051012    { 
    9061013        status = pj_stun_authenticate_response(pkt, pkt_len, msg,  
    907                                                &tdata->auth_key); 
     1014                                               &tdata->auth_info.auth_key); 
    9081015        if (status != PJ_SUCCESS) { 
    9091016            PJ_LOG(5,(SNAME(sess),  
     
    9631070                 "Request retransmission, sending cached response")); 
    9641071 
    965         send_response(sess, tmp_pool, t->msg, &t->auth_key, PJ_TRUE,  
     1072        send_response(sess, tmp_pool, t->msg, &t->auth_info, PJ_TRUE,  
    9661073                      src_addr, src_addr_len); 
    9671074        return PJ_SUCCESS; 
     
    9771084                                       const pj_uint8_t *in_pkt, 
    9781085                                       unsigned in_pkt_len, 
    979                                        const pj_stun_msg *msg, 
     1086                                       pj_stun_msg *msg, 
    9801087                                       const pj_sockaddr_t *src_addr, 
    9811088                                       unsigned src_addr_len) 
    9821089{ 
     1090    pj_stun_rx_data rdata; 
    9831091    pj_status_t status; 
     1092 
     1093    /* Init rdata */ 
     1094    rdata.msg = msg; 
     1095    pj_bzero(&rdata.info, sizeof(rdata.info)); 
     1096 
     1097    if (sess->auth_type == PJ_STUN_AUTH_NONE) 
     1098        options |= PJ_STUN_NO_AUTHENTICATE; 
    9841099 
    9851100    /* Authenticate the message, unless PJ_STUN_NO_AUTHENTICATE 
     
    9881103    if ((options & PJ_STUN_NO_AUTHENTICATE) == 0) { 
    9891104        status = authenticate_req(sess, (const pj_uint8_t*) in_pkt, in_pkt_len, 
    990                                   msg, tmp_pool, src_addr, src_addr_len); 
     1105                                  &rdata, tmp_pool, src_addr, src_addr_len); 
    9911106        if (status != PJ_SUCCESS) { 
    9921107            return status; 
     
    9961111    /* Distribute to handler, or respond with Bad Request */ 
    9971112    if (sess->cb.on_rx_request) { 
    998         status = (*sess->cb.on_rx_request)(sess, in_pkt, in_pkt_len, msg, 
     1113        status = (*sess->cb.on_rx_request)(sess, in_pkt, in_pkt_len, &rdata, 
    9991114                                           src_addr, src_addr_len); 
    10001115    } else { 
     1116        pj_str_t err_text; 
    10011117        pj_stun_msg *response; 
    10021118 
     1119        err_text = pj_str("Callback is not set to handle request"); 
    10031120        status = pj_stun_msg_create_response(tmp_pool, msg,  
    1004                                              PJ_STUN_SC_BAD_REQUEST, NULL, 
    1005                                              &response); 
     1121                                             PJ_STUN_SC_BAD_REQUEST,  
     1122                                             &err_text, &response); 
    10061123        if (status == PJ_SUCCESS && response) { 
    10071124            status = send_response(sess, tmp_pool, response,  
Note: See TracChangeset for help on using the changeset viewer.