Changeset 1561 for pjproject/trunk


Ignore:
Timestamp:
Nov 8, 2007 9:24:30 AM (17 years ago)
Author:
bennylp
Message:
  • Added option to send empty Authorization header in outgoing requests
  • When UAS has sent answer in reliable 1xx, do not put SDP in 2xx
  • Handle the case when UPDATE is challenged with 401/407
  • Obsolete --service-route option in pjsua
Location:
pjproject/trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c

    r1543 r1561  
    118118    puts  (""); 
    119119    puts  ("SIP Account options:"); 
     120    puts  ("  --use-ims           Enable 3GPP/IMS related settings on this account"); 
    120121    puts  ("  --registrar=url     Set the URL of registrar server"); 
    121122    puts  ("  --id=url            Set the URL of local ID (used in From header)"); 
     
    129130    puts  ("  --publish           Send presence PUBLISH for this account"); 
    130131    puts  ("  --use-100rel        Require reliable provisional response (100rel)"); 
    131     puts  ("  --service-route     Enable Service-Route processing"); 
    132132    puts  ("  --next-cred         Add another credentials"); 
    133133    puts  (""); 
     
    373373           OPT_LOCAL_PORT, OPT_IP_ADDR, OPT_PROXY, OPT_OUTBOUND_PROXY,  
    374374           OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT, 
    375            OPT_100REL, OPT_SERVICE_ROUTE, OPT_REALM, OPT_USERNAME, OPT_PASSWORD, 
     375           OPT_100REL, OPT_USE_IMS, OPT_REALM, OPT_USERNAME, OPT_PASSWORD, 
    376376           OPT_NAMESERVER, OPT_STUN_DOMAIN, OPT_STUN_SRV, 
    377377           OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE, 
     
    410410        { "publish",    0, 0, OPT_PUBLISH}, 
    411411        { "use-100rel", 0, 0, OPT_100REL}, 
    412         { "service-route", 0, 0, OPT_SERVICE_ROUTE}, 
     412        { "use-ims",    0, 0, OPT_USE_IMS}, 
    413413        { "id",         1, 0, OPT_ID}, 
    414414        { "contact",    1, 0, OPT_CONTACT}, 
     
    637637            break; 
    638638 
    639         case OPT_SERVICE_ROUTE: /* Service-Route processing */ 
    640             cur_acc->enable_service_route = PJ_TRUE; 
     639        case OPT_USE_IMS: /* Activate IMS settings */ 
     640            cur_acc->auth_pref.initial_auth = PJ_TRUE; 
    641641            break; 
    642642 
     
    668668        case OPT_USERNAME:   /* Default authentication user */ 
    669669            cur_acc->cred_info[cur_acc->cred_count].username = pj_str(pj_optarg); 
    670             cur_acc->cred_info[cur_acc->cred_count].scheme = pj_str("digest"); 
     670            cur_acc->cred_info[cur_acc->cred_count].scheme = pj_str("Digest"); 
    671671            break; 
    672672 
     
    993993 
    994994    for (i=0; i<cfg->acc_cnt; ++i) { 
    995         if (cfg->acc_cfg[i].cred_info[cfg->acc_cfg[i].cred_count].username.slen) 
     995        pjsua_acc_config *acfg = &cfg->acc_cfg[i]; 
     996 
     997        if (acfg->cred_info[acfg->cred_count].username.slen) 
    996998        { 
    997             cfg->acc_cfg[i].cred_count++; 
     999            acfg->cred_count++; 
     1000        } 
     1001 
     1002        /* When IMS mode is enabled for the account, verify that settings 
     1003         * are okay. 
     1004         */ 
     1005        /* For now we check if IMS mode is activated by looking if 
     1006         * initial_auth is set. 
     1007         */ 
     1008        if (acfg->auth_pref.initial_auth && acfg->cred_count) { 
     1009            /* Realm must point to the real domain */ 
     1010            if (*acfg->cred_info[0].realm.ptr=='*') { 
     1011                PJ_LOG(1,(THIS_FILE,  
     1012                          "Error: cannot use '*' as realm with IMS")); 
     1013                return PJ_EINVAL; 
     1014            } 
     1015 
     1016            /* Username for authentication must be in a@b format */ 
     1017            if (strchr(acfg->cred_info[0].username.ptr, '@')==0) { 
     1018                PJ_LOG(1,(THIS_FILE,  
     1019                          "Error: Username for authentication must " 
     1020                          "be in user@domain format with IMS")); 
     1021                return PJ_EINVAL; 
     1022            } 
    9981023        } 
    9991024    } 
     
    26862711                acc_cfg.reg_uri = pj_str(registrar); 
    26872712                acc_cfg.cred_count = 1; 
    2688                 acc_cfg.cred_info[0].scheme = pj_str("digest"); 
     2713                acc_cfg.cred_info[0].scheme = pj_str("Digest"); 
    26892714                acc_cfg.cred_info[0].realm = pj_str(realm); 
    26902715                acc_cfg.cred_info[0].username = pj_str(uname); 
  • pjproject/trunk/pjsip/include/pjsip-ua/sip_regc.h

    r974 r1561  
    190190 
    191191/** 
     192 * Set authentication preference. 
     193 * 
     194 * @param regc      The registration structure. 
     195 * @param pref      Authentication preference. 
     196 * 
     197 * @return          PJ_SUCCESS on success. 
     198 */ 
     199PJ_DECL(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc, 
     200                                           const pjsip_auth_clt_pref *pref); 
     201 
     202/** 
    192203 * Set route set to be used for outgoing requests. 
    193204 * 
  • pjproject/trunk/pjsip/include/pjsip/sip_auth.h

    r1500 r1561  
    184184 
    185185/** 
     186 * This structure describes client authentication session preference. 
     187 * The preference can be set by calling #pjsip_auth_clt_set_prefs(). 
     188 */ 
     189typedef struct pjsip_auth_clt_pref 
     190{ 
     191    /** 
     192     * If this flag is set, the authentication client framework will 
     193     * send an empty Authorization header in each initial request. 
     194     * Default is no. 
     195     */ 
     196    pj_bool_t   initial_auth; 
     197 
     198    /** 
     199     * Specify the algorithm to use when empty Authorization header  
     200     * is to be sent for each initial request (see above) 
     201     */ 
     202    pj_str_t    algorithm; 
     203 
     204} pjsip_auth_clt_pref; 
     205 
     206 
     207/** 
    186208 * This structure describes client authentication sessions. It keeps 
    187209 * all the information needed to authorize the client against all downstream  
     
    192214    pj_pool_t           *pool;          /**< Pool to use.                   */ 
    193215    pjsip_endpoint      *endpt;         /**< Endpoint where this belongs.   */ 
     216    pjsip_auth_clt_pref  pref;          /**< Preference/options.            */ 
    194217    unsigned             cred_cnt;      /**< Number of credentials.         */ 
    195218    pjsip_cred_info     *cred_info;     /**< Array of credential information*/ 
     
    288311                                                     const pjsip_cred_info *c); 
    289312 
     313 
     314/** 
     315 * Set the preference for the client authentication session. 
     316 * 
     317 * @param sess          The client authentication session. 
     318 * @param p             Preference. 
     319 * 
     320 * @return              PJ_SUCCESS on success. 
     321 */ 
     322PJ_DECL(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess, 
     323                                              const pjsip_auth_clt_pref *p); 
     324 
     325 
     326/** 
     327 * Get the preference for the client authentication session. 
     328 * 
     329 * @param sess          The client authentication session. 
     330 * @param p             Pointer to receive the preference. 
     331 * 
     332 * @return              PJ_SUCCESS on success. 
     333 */ 
     334PJ_DECL(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess, 
     335                                              pjsip_auth_clt_pref *p); 
    290336 
    291337/** 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r1541 r1561  
    18411841     * If this flag is set, the presence information of this account will 
    18421842     * be PUBLISH-ed to the server where the account belongs. 
     1843     * 
     1844     * Default: PJ_FALSE 
    18431845     */ 
    18441846    pj_bool_t       publish_enabled; 
     1847 
     1848    /** 
     1849     * Authentication preference. 
     1850     */ 
     1851    pjsip_auth_clt_pref auth_pref; 
    18451852 
    18461853    /** 
     
    18901897     */ 
    18911898    pj_str_t        proxy[PJSUA_ACC_MAX_PROXIES]; 
    1892  
    1893     /** 
    1894      * Enable Service-Route processing for this account. 
    1895      */ 
    1896     pj_bool_t       enable_service_route; 
    18971899 
    18981900    /**  
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r1554 r1561  
    15641564    /* Include SDP when it's available for 2xx and 18x (but not 180) response. 
    15651565     * Subsequent response will include this SDP. 
     1566     * 
     1567     * Note note: 
     1568     *  - When offer/answer has been completed in reliable 183, we MUST NOT 
     1569     *    send SDP in 2xx response. So if we don't have SDP to send, clear 
     1570     *    the SDP in the message body ONLY if 100rel is active in this  
     1571     *    session. 
    15661572     */ 
    15671573    if (sdp) { 
    15681574        tdata->msg->body = create_sdp_body(tdata->pool, sdp); 
     1575    } else { 
     1576        if (inv->options & PJSIP_INV_REQUIRE_100REL) { 
     1577            tdata->msg->body = NULL; 
     1578        } 
    15691579    } 
    15701580 
     
    22272237    pj_status_t status = -1; 
    22282238 
     2239    /* Handle 401/407 challenge. */ 
     2240    if (tsx->state == PJSIP_TSX_STATE_COMPLETED && 
     2241        (tsx->status_code == 401 || tsx->status_code == 407)) { 
     2242 
     2243        pjsip_tx_data *tdata; 
     2244         
     2245        status = pjsip_auth_clt_reinit_req( &inv->dlg->auth_sess,  
     2246                                            e->body.tsx_state.src.rdata, 
     2247                                            tsx->last_tx, 
     2248                                            &tdata); 
     2249         
     2250        if (status != PJ_SUCCESS) { 
     2251             
     2252            /* Does not have proper credentials.  
     2253             * End the session anyway. 
     2254             */ 
     2255            inv_set_cause(inv, PJSIP_SC_OK, NULL); 
     2256            inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
     2257             
     2258        } else { 
     2259            /* Re-send BYE. */ 
     2260            status = pjsip_inv_send_msg(inv, tdata); 
     2261        } 
     2262 
    22292263    /* Process 2xx response */ 
    2230     if (tsx->state == PJSIP_TSX_STATE_COMPLETED && 
     2264    } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED && 
    22312265        tsx->status_code/100 == 2 && 
    22322266        e->body.tsx_state.src.rdata->msg_info.msg->body) 
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_reg.c

    r1547 r1561  
    308308} 
    309309 
     310PJ_DEF(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc, 
     311                                          const pjsip_auth_clt_pref *pref) 
     312{ 
     313    PJ_ASSERT_RETURN(regc && pref, PJ_EINVAL); 
     314    return pjsip_auth_clt_set_prefs(&regc->auth_sess, pref); 
     315} 
     316 
    310317PJ_DEF(pj_status_t) pjsip_regc_set_route_set( pjsip_regc *regc, 
    311318                                              const pjsip_route_hdr *route_set) 
  • pjproject/trunk/pjsip/src/pjsip/sip_auth_client.c

    r1539 r1561  
    533533 
    534534 
     535/* 
     536 * Set the preference for the client authentication session. 
     537 */ 
     538PJ_DEF(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess, 
     539                                             const pjsip_auth_clt_pref *p) 
     540{ 
     541    PJ_ASSERT_RETURN(sess && p, PJ_EINVAL); 
     542 
     543    pj_memcpy(&sess->pref, p, sizeof(*p)); 
     544    pj_strdup(sess->pool, &sess->pref.algorithm, &p->algorithm); 
     545    //if (sess->pref.algorithm.slen == 0) 
     546    //  sess->pref.algorithm = pj_str("md5"); 
     547 
     548    return PJ_SUCCESS; 
     549} 
     550 
     551 
     552/* 
     553 * Get the preference for the client authentication session. 
     554 */ 
     555PJ_DEF(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess, 
     556                                             pjsip_auth_clt_pref *p) 
     557{ 
     558    PJ_ASSERT_RETURN(sess && p, PJ_EINVAL); 
     559 
     560    pj_memcpy(p, &sess->pref, sizeof(pjsip_auth_clt_pref)); 
     561    return PJ_SUCCESS; 
     562} 
     563 
     564 
    535565/*  
    536566 * Create Authorization/Proxy-Authorization response header based on the challege 
     
    699729 
    700730 
     731/* Find credential in list of (Proxy-)Authorization headers */ 
     732static pjsip_authorization_hdr* get_header_for_realm(const pjsip_hdr *hdr_list, 
     733                                                     const pj_str_t *realm) 
     734{ 
     735    pjsip_authorization_hdr *h; 
     736 
     737    h = (pjsip_authorization_hdr*)hdr_list->next; 
     738    while (h != (pjsip_authorization_hdr*)hdr_list) { 
     739        if (pj_stricmp(&h->credential.digest.realm, realm)==0) 
     740            return h; 
     741        h = h->next; 
     742    } 
     743 
     744    return NULL; 
     745} 
     746 
    701747 
    702748/* Initialize outgoing request. */ 
     
    706752    const pjsip_method *method; 
    707753    pjsip_cached_auth *auth; 
     754    pjsip_hdr added; 
    708755 
    709756    PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL); 
     
    711758    PJ_ASSERT_RETURN(tdata->msg->type==PJSIP_REQUEST_MSG, 
    712759                     PJSIP_ENOTREQUESTMSG); 
     760 
     761    /* Init list */ 
     762    pj_list_init(&added); 
    713763 
    714764    /* Get the method. */ 
     
    729779                        pjsip_authorization_hdr *hauth; 
    730780                        hauth = pjsip_hdr_shallow_clone(tdata->pool, entry->hdr); 
    731                         pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth); 
     781                        //pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth); 
     782                        pj_list_push_back(&added, hauth); 
    732783                        break; 
    733784                    } 
     
    777828                return status; 
    778829             
    779             pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth); 
     830            //pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth); 
     831            pj_list_push_back(&added, hauth); 
    780832        } 
    781833#       endif   /* PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT */ 
    782834 
    783835        auth = auth->next; 
     836    } 
     837 
     838    if (sess->pref.initial_auth == PJ_FALSE) { 
     839        pjsip_hdr *h; 
     840 
     841        /* Don't want to send initial empty Authorization header, so 
     842         * just send whatever available in the list (maybe empty). 
     843         */ 
     844 
     845        h = added.next; 
     846        while (h != &added) { 
     847            pjsip_hdr *next = h->next; 
     848            pjsip_msg_add_hdr(tdata->msg, h); 
     849            h = next; 
     850        } 
     851    } else { 
     852        /* For each realm, add either the cached authorization header 
     853         * or add an empty authorization header. 
     854         */ 
     855        unsigned i; 
     856        char *uri_str; 
     857        int len; 
     858 
     859        uri_str = pj_pool_alloc(tdata->pool, PJSIP_MAX_URL_SIZE); 
     860        len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, tdata->msg->line.req.uri, 
     861                              uri_str, PJSIP_MAX_URL_SIZE); 
     862        if (len < 1 || len >= PJSIP_MAX_URL_SIZE) 
     863            return PJSIP_EURITOOLONG; 
     864 
     865        for (i=0; i<sess->cred_cnt; ++i) { 
     866            pjsip_cred_info *c = &sess->cred_info[i]; 
     867            pjsip_authorization_hdr *h; 
     868 
     869            h = get_header_for_realm(&added, &c->realm); 
     870            if (h) { 
     871                pj_list_erase(h); 
     872                pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)h); 
     873            } else { 
     874                enum { HDRLEN = 256 }; 
     875                const pj_str_t hname = pj_str("Authorization"); 
     876                pj_str_t hval; 
     877                pjsip_generic_string_hdr *hs; 
     878                char *hdr; 
     879 
     880                hdr = pj_pool_alloc(tdata->pool, HDRLEN); 
     881                len = pj_ansi_snprintf( 
     882                    hdr, HDRLEN, 
     883                    "%.*s username=\"%.*s\", realm=\"%.*s\"," 
     884                    " nonce=\"\", uri=\"%s\",%s%.*s%s response=\"\"", 
     885                    (int)c->scheme.slen, c->scheme.ptr, 
     886                    (int)c->username.slen, c->username.ptr, 
     887                    (int)c->realm.slen, c->realm.ptr, 
     888                    uri_str, 
     889                    (sess->pref.algorithm.slen ? " algorithm=" : ""), 
     890                    (int)sess->pref.algorithm.slen, sess->pref.algorithm.ptr, 
     891                    (sess->pref.algorithm.slen ? "," : "")); 
     892 
     893                PJ_ASSERT_RETURN(len>0 && len<HDRLEN, PJ_ETOOBIG); 
     894 
     895                hval.ptr = hdr; 
     896                hval.slen = len; 
     897                hs = pjsip_generic_string_hdr_create(tdata->pool, &hname,  
     898                                                     &hval); 
     899                pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hs); 
     900            } 
     901        } 
    784902    } 
    785903 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r1542 r1561  
    545545    unsigned i, uri_cnt = 0, rcnt; 
    546546 
    547     /* Skip processing is enable_service_route is not set */ 
    548     if (!acc->cfg.enable_service_route) 
    549         return; 
    550  
    551547    /* Find and parse Service-Route headers */ 
    552548    for (;;) { 
     
    916912        pjsip_regc_set_credentials( acc->regc, acc->cred_cnt, acc->cred); 
    917913    } 
     914 
     915    /* Set authentication preference */ 
     916    pjsip_regc_set_prefs(acc->regc, &acc->cfg.auth_pref); 
    918917 
    919918    /* Set route-set 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c

    r1553 r1561  
    384384    } 
    385385 
     386    /* Set authentication preference */ 
     387    pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref); 
    386388 
    387389    /* Create initial INVITE: */ 
     
    666668                                       pjsua_var.acc[acc_id].cred); 
    667669    } 
     670 
     671    /* Set preference */ 
     672    pjsip_auth_clt_set_prefs(&dlg->auth_sess,  
     673                             &pjsua_var.acc[acc_id].cfg.auth_pref); 
    668674 
    669675    /* Create invite session: */ 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_im.c

    r1367 r1561  
    322322                pjsua_var.acc[im_data->acc_id].cred); 
    323323 
     324            pjsip_auth_clt_set_prefs(&auth,  
     325                                     &pjsua_var.acc[im_data->acc_id].cfg.auth_pref); 
     326 
    324327            status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, 
    325328                                               &tdata); 
     
    418421                pjsua_var.acc[im_data->acc_id].cred); 
    419422 
     423            pjsip_auth_clt_set_prefs(&auth,  
     424                                     &pjsua_var.acc[im_data->acc_id].cfg.auth_pref); 
     425 
    420426            status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx, 
    421427                                               &tdata); 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_pres.c

    r1556 r1561  
    572572    } 
    573573 
    574     /* Set credentials. */ 
     574    /* Set credentials and preference. */ 
    575575    pjsip_auth_clt_set_credentials(&dlg->auth_sess, acc->cred_cnt, acc->cred); 
     576    pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref); 
    576577 
    577578    /* Init callback: */ 
     
    11741175    } 
    11751176 
     1177    /* Set authentication preference */ 
     1178    pjsip_auth_clt_set_prefs(&buddy->dlg->auth_sess, &acc->cfg.auth_pref); 
     1179 
    11761180    pjsip_evsub_set_mod_data(buddy->sub, pjsua_var.mod.id, buddy); 
    11771181 
Note: See TracChangeset for help on using the changeset viewer.