summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2007-11-08 09:24:30 +0000
committerBenny Prijono <bennylp@teluu.com>2007-11-08 09:24:30 +0000
commit3c4737b86e55b69670b9fc4c014e77fa6fa00194 (patch)
tree6489d04d93e86f329f490d57963251fb31be0633
parent11ace76446c9ff2c2afc0b0d6eab9c2b5ecc30b9 (diff)
- 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 git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@1561 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip-apps/src/pjsua/pjsua_app.c43
-rw-r--r--pjsip/include/pjsip-ua/sip_regc.h11
-rw-r--r--pjsip/include/pjsip/sip_auth.h46
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h12
-rw-r--r--pjsip/src/pjsip-ua/sip_inv.c36
-rw-r--r--pjsip/src/pjsip-ua/sip_reg.c7
-rw-r--r--pjsip/src/pjsip/sip_auth_client.c122
-rw-r--r--pjsip/src/pjsua-lib/pjsua_acc.c7
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c6
-rw-r--r--pjsip/src/pjsua-lib/pjsua_im.c6
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c6
11 files changed, 280 insertions, 22 deletions
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index d478da77..fe92fa2d 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -117,6 +117,7 @@ static void usage(void)
puts (" --app-log-level=N Set log max level for stdout display (default=4)");
puts ("");
puts ("SIP Account options:");
+ puts (" --use-ims Enable 3GPP/IMS related settings on this account");
puts (" --registrar=url Set the URL of registrar server");
puts (" --id=url Set the URL of local ID (used in From header)");
puts (" --contact=url Optionally override the Contact information");
@@ -128,7 +129,6 @@ static void usage(void)
puts (" --password=string Set authentication password");
puts (" --publish Send presence PUBLISH for this account");
puts (" --use-100rel Require reliable provisional response (100rel)");
- puts (" --service-route Enable Service-Route processing");
puts (" --next-cred Add another credentials");
puts ("");
puts ("SIP Account Control:");
@@ -372,7 +372,7 @@ static pj_status_t parse_args(int argc, char *argv[],
OPT_HELP, OPT_VERSION, OPT_NULL_AUDIO,
OPT_LOCAL_PORT, OPT_IP_ADDR, OPT_PROXY, OPT_OUTBOUND_PROXY,
OPT_REGISTRAR, OPT_REG_TIMEOUT, OPT_PUBLISH, OPT_ID, OPT_CONTACT,
- OPT_100REL, OPT_SERVICE_ROUTE, OPT_REALM, OPT_USERNAME, OPT_PASSWORD,
+ OPT_100REL, OPT_USE_IMS, OPT_REALM, OPT_USERNAME, OPT_PASSWORD,
OPT_NAMESERVER, OPT_STUN_DOMAIN, OPT_STUN_SRV,
OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE,
OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY, OPT_AUTO_LOOP,
@@ -409,7 +409,7 @@ static pj_status_t parse_args(int argc, char *argv[],
{ "reg-timeout",1, 0, OPT_REG_TIMEOUT},
{ "publish", 0, 0, OPT_PUBLISH},
{ "use-100rel", 0, 0, OPT_100REL},
- { "service-route", 0, 0, OPT_SERVICE_ROUTE},
+ { "use-ims", 0, 0, OPT_USE_IMS},
{ "id", 1, 0, OPT_ID},
{ "contact", 1, 0, OPT_CONTACT},
{ "realm", 1, 0, OPT_REALM},
@@ -636,8 +636,8 @@ static pj_status_t parse_args(int argc, char *argv[],
cfg->cfg.require_100rel = PJ_TRUE;
break;
- case OPT_SERVICE_ROUTE: /* Service-Route processing */
- cur_acc->enable_service_route = PJ_TRUE;
+ case OPT_USE_IMS: /* Activate IMS settings */
+ cur_acc->auth_pref.initial_auth = PJ_TRUE;
break;
case OPT_ID: /* id */
@@ -667,7 +667,7 @@ static pj_status_t parse_args(int argc, char *argv[],
case OPT_USERNAME: /* Default authentication user */
cur_acc->cred_info[cur_acc->cred_count].username = pj_str(pj_optarg);
- cur_acc->cred_info[cur_acc->cred_count].scheme = pj_str("digest");
+ cur_acc->cred_info[cur_acc->cred_count].scheme = pj_str("Digest");
break;
case OPT_REALM: /* Default authentication realm. */
@@ -992,9 +992,34 @@ static pj_status_t parse_args(int argc, char *argv[],
cfg->acc_cnt++;
for (i=0; i<cfg->acc_cnt; ++i) {
- if (cfg->acc_cfg[i].cred_info[cfg->acc_cfg[i].cred_count].username.slen)
+ pjsua_acc_config *acfg = &cfg->acc_cfg[i];
+
+ if (acfg->cred_info[acfg->cred_count].username.slen)
{
- cfg->acc_cfg[i].cred_count++;
+ acfg->cred_count++;
+ }
+
+ /* When IMS mode is enabled for the account, verify that settings
+ * are okay.
+ */
+ /* For now we check if IMS mode is activated by looking if
+ * initial_auth is set.
+ */
+ if (acfg->auth_pref.initial_auth && acfg->cred_count) {
+ /* Realm must point to the real domain */
+ if (*acfg->cred_info[0].realm.ptr=='*') {
+ PJ_LOG(1,(THIS_FILE,
+ "Error: cannot use '*' as realm with IMS"));
+ return PJ_EINVAL;
+ }
+
+ /* Username for authentication must be in a@b format */
+ if (strchr(acfg->cred_info[0].username.ptr, '@')==0) {
+ PJ_LOG(1,(THIS_FILE,
+ "Error: Username for authentication must "
+ "be in user@domain format with IMS"));
+ return PJ_EINVAL;
+ }
}
}
@@ -2685,7 +2710,7 @@ void console_app_main(const pj_str_t *uri_to_call)
acc_cfg.id = pj_str(id);
acc_cfg.reg_uri = pj_str(registrar);
acc_cfg.cred_count = 1;
- acc_cfg.cred_info[0].scheme = pj_str("digest");
+ acc_cfg.cred_info[0].scheme = pj_str("Digest");
acc_cfg.cred_info[0].realm = pj_str(realm);
acc_cfg.cred_info[0].username = pj_str(uname);
acc_cfg.cred_info[0].data_type = 0;
diff --git a/pjsip/include/pjsip-ua/sip_regc.h b/pjsip/include/pjsip-ua/sip_regc.h
index be2e37a5..62d2336f 100644
--- a/pjsip/include/pjsip-ua/sip_regc.h
+++ b/pjsip/include/pjsip-ua/sip_regc.h
@@ -189,6 +189,17 @@ PJ_DECL(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,
const pjsip_cred_info cred[] );
/**
+ * Set authentication preference.
+ *
+ * @param regc The registration structure.
+ * @param pref Authentication preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc,
+ const pjsip_auth_clt_pref *pref);
+
+/**
* Set route set to be used for outgoing requests.
*
* @param regc The client registration structure.
diff --git a/pjsip/include/pjsip/sip_auth.h b/pjsip/include/pjsip/sip_auth.h
index 466e85c2..155c180c 100644
--- a/pjsip/include/pjsip/sip_auth.h
+++ b/pjsip/include/pjsip/sip_auth.h
@@ -183,6 +183,28 @@ typedef struct pjsip_cached_auth
/**
+ * This structure describes client authentication session preference.
+ * The preference can be set by calling #pjsip_auth_clt_set_prefs().
+ */
+typedef struct pjsip_auth_clt_pref
+{
+ /**
+ * If this flag is set, the authentication client framework will
+ * send an empty Authorization header in each initial request.
+ * Default is no.
+ */
+ pj_bool_t initial_auth;
+
+ /**
+ * Specify the algorithm to use when empty Authorization header
+ * is to be sent for each initial request (see above)
+ */
+ pj_str_t algorithm;
+
+} pjsip_auth_clt_pref;
+
+
+/**
* This structure describes client authentication sessions. It keeps
* all the information needed to authorize the client against all downstream
* servers.
@@ -191,6 +213,7 @@ typedef struct pjsip_auth_clt_sess
{
pj_pool_t *pool; /**< Pool to use. */
pjsip_endpoint *endpt; /**< Endpoint where this belongs. */
+ pjsip_auth_clt_pref pref; /**< Preference/options. */
unsigned cred_cnt; /**< Number of credentials. */
pjsip_cred_info *cred_info; /**< Array of credential information*/
pjsip_cached_auth cached_auth; /**< Cached authorization info. */
@@ -289,6 +312,29 @@ PJ_DECL(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
/**
+ * Set the preference for the client authentication session.
+ *
+ * @param sess The client authentication session.
+ * @param p Preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,
+ const pjsip_auth_clt_pref *p);
+
+
+/**
+ * Get the preference for the client authentication session.
+ *
+ * @param sess The client authentication session.
+ * @param p Pointer to receive the preference.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
+ pjsip_auth_clt_pref *p);
+
+/**
* Initialize new request message with authorization headers.
* This function will put Authorization/Proxy-Authorization headers to the
* outgoing request message. If caching is enabled (PJSIP_AUTH_HEADER_CACHING)
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 369f7015..db5a6496 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1840,10 +1840,17 @@ typedef struct pjsua_acc_config
/**
* If this flag is set, the presence information of this account will
* be PUBLISH-ed to the server where the account belongs.
+ *
+ * Default: PJ_FALSE
*/
pj_bool_t publish_enabled;
/**
+ * Authentication preference.
+ */
+ pjsip_auth_clt_pref auth_pref;
+
+ /**
* Optional PIDF tuple ID for outgoing PUBLISH and NOTIFY. If this value
* is not specified, a random string will be used.
*/
@@ -1890,11 +1897,6 @@ typedef struct pjsua_acc_config
*/
pj_str_t proxy[PJSUA_ACC_MAX_PROXIES];
- /**
- * Enable Service-Route processing for this account.
- */
- pj_bool_t enable_service_route;
-
/**
* Optional interval for registration, in seconds. If the value is zero,
* default interval will be used (PJSUA_REG_INTERVAL, 300 seconds).
diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c
index 5ce657d4..8250b04a 100644
--- a/pjsip/src/pjsip-ua/sip_inv.c
+++ b/pjsip/src/pjsip-ua/sip_inv.c
@@ -1563,9 +1563,19 @@ static pj_status_t process_answer( pjsip_inv_session *inv,
/* Include SDP when it's available for 2xx and 18x (but not 180) response.
* Subsequent response will include this SDP.
+ *
+ * Note note:
+ * - When offer/answer has been completed in reliable 183, we MUST NOT
+ * send SDP in 2xx response. So if we don't have SDP to send, clear
+ * the SDP in the message body ONLY if 100rel is active in this
+ * session.
*/
if (sdp) {
tdata->msg->body = create_sdp_body(tdata->pool, sdp);
+ } else {
+ if (inv->options & PJSIP_INV_REQUIRE_100REL) {
+ tdata->msg->body = NULL;
+ }
}
@@ -2226,8 +2236,32 @@ static void inv_handle_update_response( pjsip_inv_session *inv,
struct tsx_inv_data *tsx_inv_data = NULL;
pj_status_t status = -1;
- /* Process 2xx response */
+ /* Handle 401/407 challenge. */
if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&
+ (tsx->status_code == 401 || tsx->status_code == 407)) {
+
+ pjsip_tx_data *tdata;
+
+ status = pjsip_auth_clt_reinit_req( &inv->dlg->auth_sess,
+ e->body.tsx_state.src.rdata,
+ tsx->last_tx,
+ &tdata);
+
+ if (status != PJ_SUCCESS) {
+
+ /* Does not have proper credentials.
+ * End the session anyway.
+ */
+ inv_set_cause(inv, PJSIP_SC_OK, NULL);
+ inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e);
+
+ } else {
+ /* Re-send BYE. */
+ status = pjsip_inv_send_msg(inv, tdata);
+ }
+
+ /* Process 2xx response */
+ } else if (tsx->state == PJSIP_TSX_STATE_COMPLETED &&
tsx->status_code/100 == 2 &&
e->body.tsx_state.src.rdata->msg_info.msg->body)
{
diff --git a/pjsip/src/pjsip-ua/sip_reg.c b/pjsip/src/pjsip-ua/sip_reg.c
index 3a257473..0a8e6d0d 100644
--- a/pjsip/src/pjsip-ua/sip_reg.c
+++ b/pjsip/src/pjsip-ua/sip_reg.c
@@ -307,6 +307,13 @@ PJ_DEF(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc,
return pjsip_auth_clt_set_credentials(&regc->auth_sess, count, cred);
}
+PJ_DEF(pj_status_t) pjsip_regc_set_prefs( pjsip_regc *regc,
+ const pjsip_auth_clt_pref *pref)
+{
+ PJ_ASSERT_RETURN(regc && pref, PJ_EINVAL);
+ return pjsip_auth_clt_set_prefs(&regc->auth_sess, pref);
+}
+
PJ_DEF(pj_status_t) pjsip_regc_set_route_set( pjsip_regc *regc,
const pjsip_route_hdr *route_set)
{
diff --git a/pjsip/src/pjsip/sip_auth_client.c b/pjsip/src/pjsip/sip_auth_client.c
index 1c8457b9..7fcc1ec6 100644
--- a/pjsip/src/pjsip/sip_auth_client.c
+++ b/pjsip/src/pjsip/sip_auth_client.c
@@ -532,6 +532,36 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
}
+/*
+ * Set the preference for the client authentication session.
+ */
+PJ_DEF(pj_status_t) pjsip_auth_clt_set_prefs(pjsip_auth_clt_sess *sess,
+ const pjsip_auth_clt_pref *p)
+{
+ PJ_ASSERT_RETURN(sess && p, PJ_EINVAL);
+
+ pj_memcpy(&sess->pref, p, sizeof(*p));
+ pj_strdup(sess->pool, &sess->pref.algorithm, &p->algorithm);
+ //if (sess->pref.algorithm.slen == 0)
+ // sess->pref.algorithm = pj_str("md5");
+
+ return PJ_SUCCESS;
+}
+
+
+/*
+ * Get the preference for the client authentication session.
+ */
+PJ_DEF(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
+ pjsip_auth_clt_pref *p)
+{
+ PJ_ASSERT_RETURN(sess && p, PJ_EINVAL);
+
+ pj_memcpy(p, &sess->pref, sizeof(pjsip_auth_clt_pref));
+ return PJ_SUCCESS;
+}
+
+
/*
* Create Authorization/Proxy-Authorization response header based on the challege
* in WWW-Authenticate/Proxy-Authenticate header.
@@ -698,6 +728,22 @@ static pj_status_t new_auth_for_req( pjsip_tx_data *tdata,
#endif
+/* Find credential in list of (Proxy-)Authorization headers */
+static pjsip_authorization_hdr* get_header_for_realm(const pjsip_hdr *hdr_list,
+ const pj_str_t *realm)
+{
+ pjsip_authorization_hdr *h;
+
+ h = (pjsip_authorization_hdr*)hdr_list->next;
+ while (h != (pjsip_authorization_hdr*)hdr_list) {
+ if (pj_stricmp(&h->credential.digest.realm, realm)==0)
+ return h;
+ h = h->next;
+ }
+
+ return NULL;
+}
+
/* Initialize outgoing request. */
PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
@@ -705,12 +751,16 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
{
const pjsip_method *method;
pjsip_cached_auth *auth;
+ pjsip_hdr added;
PJ_ASSERT_RETURN(sess && tdata, PJ_EINVAL);
PJ_ASSERT_RETURN(sess->pool, PJSIP_ENOTINITIALIZED);
PJ_ASSERT_RETURN(tdata->msg->type==PJSIP_REQUEST_MSG,
PJSIP_ENOTREQUESTMSG);
+ /* Init list */
+ pj_list_init(&added);
+
/* Get the method. */
method = &tdata->msg->line.req.method;
@@ -728,7 +778,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
if (pjsip_method_cmp(&entry->method, method)==0) {
pjsip_authorization_hdr *hauth;
hauth = pjsip_hdr_shallow_clone(tdata->pool, entry->hdr);
- pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
+ //pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
+ pj_list_push_back(&added, hauth);
break;
}
entry = entry->next;
@@ -776,13 +827,80 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_init_req( pjsip_auth_clt_sess *sess,
if (status != PJ_SUCCESS)
return status;
- pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
+ //pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth);
+ pj_list_push_back(&added, hauth);
}
# endif /* PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT */
auth = auth->next;
}
+ if (sess->pref.initial_auth == PJ_FALSE) {
+ pjsip_hdr *h;
+
+ /* Don't want to send initial empty Authorization header, so
+ * just send whatever available in the list (maybe empty).
+ */
+
+ h = added.next;
+ while (h != &added) {
+ pjsip_hdr *next = h->next;
+ pjsip_msg_add_hdr(tdata->msg, h);
+ h = next;
+ }
+ } else {
+ /* For each realm, add either the cached authorization header
+ * or add an empty authorization header.
+ */
+ unsigned i;
+ char *uri_str;
+ int len;
+
+ uri_str = pj_pool_alloc(tdata->pool, PJSIP_MAX_URL_SIZE);
+ len = pjsip_uri_print(PJSIP_URI_IN_REQ_URI, tdata->msg->line.req.uri,
+ uri_str, PJSIP_MAX_URL_SIZE);
+ if (len < 1 || len >= PJSIP_MAX_URL_SIZE)
+ return PJSIP_EURITOOLONG;
+
+ for (i=0; i<sess->cred_cnt; ++i) {
+ pjsip_cred_info *c = &sess->cred_info[i];
+ pjsip_authorization_hdr *h;
+
+ h = get_header_for_realm(&added, &c->realm);
+ if (h) {
+ pj_list_erase(h);
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)h);
+ } else {
+ enum { HDRLEN = 256 };
+ const pj_str_t hname = pj_str("Authorization");
+ pj_str_t hval;
+ pjsip_generic_string_hdr *hs;
+ char *hdr;
+
+ hdr = pj_pool_alloc(tdata->pool, HDRLEN);
+ len = pj_ansi_snprintf(
+ hdr, HDRLEN,
+ "%.*s username=\"%.*s\", realm=\"%.*s\","
+ " nonce=\"\", uri=\"%s\",%s%.*s%s response=\"\"",
+ (int)c->scheme.slen, c->scheme.ptr,
+ (int)c->username.slen, c->username.ptr,
+ (int)c->realm.slen, c->realm.ptr,
+ uri_str,
+ (sess->pref.algorithm.slen ? " algorithm=" : ""),
+ (int)sess->pref.algorithm.slen, sess->pref.algorithm.ptr,
+ (sess->pref.algorithm.slen ? "," : ""));
+
+ PJ_ASSERT_RETURN(len>0 && len<HDRLEN, PJ_ETOOBIG);
+
+ hval.ptr = hdr;
+ hval.slen = len;
+ hs = pjsip_generic_string_hdr_create(tdata->pool, &hname,
+ &hval);
+ pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hs);
+ }
+ }
+ }
+
return PJ_SUCCESS;
}
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index 4262d410..6e988f09 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -544,10 +544,6 @@ void update_service_route(pjsua_acc *acc, pjsip_rx_data *rdata)
pjsip_uri *uri[PJSUA_ACC_MAX_PROXIES];
unsigned i, uri_cnt = 0, rcnt;
- /* Skip processing is enable_service_route is not set */
- if (!acc->cfg.enable_service_route)
- return;
-
/* Find and parse Service-Route headers */
for (;;) {
char saved;
@@ -916,6 +912,9 @@ static pj_status_t pjsua_regc_init(int acc_id)
pjsip_regc_set_credentials( acc->regc, acc->cred_cnt, acc->cred);
}
+ /* Set authentication preference */
+ pjsip_regc_set_prefs(acc->regc, &acc->cfg.auth_pref);
+
/* Set route-set
*/
if (!pj_list_empty(&acc->route_set)) {
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index f0f5a611..a7882b0c 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -383,6 +383,8 @@ PJ_DEF(pj_status_t) pjsua_call_make_call( pjsua_acc_id acc_id,
acc->cred_cnt, acc->cred);
}
+ /* Set authentication preference */
+ pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref);
/* Create initial INVITE: */
@@ -666,6 +668,10 @@ pj_bool_t pjsua_call_on_incoming(pjsip_rx_data *rdata)
pjsua_var.acc[acc_id].cred);
}
+ /* Set preference */
+ pjsip_auth_clt_set_prefs(&dlg->auth_sess,
+ &pjsua_var.acc[acc_id].cfg.auth_pref);
+
/* Create invite session: */
status = pjsip_inv_create_uas( dlg, rdata, answer, options, &inv);
if (status != PJ_SUCCESS) {
diff --git a/pjsip/src/pjsua-lib/pjsua_im.c b/pjsip/src/pjsua-lib/pjsua_im.c
index 48cb802a..6eaf2b4c 100644
--- a/pjsip/src/pjsua-lib/pjsua_im.c
+++ b/pjsip/src/pjsua-lib/pjsua_im.c
@@ -321,6 +321,9 @@ static void im_callback(void *token, pjsip_event *e)
pjsua_var.acc[im_data->acc_id].cred_cnt,
pjsua_var.acc[im_data->acc_id].cred);
+ pjsip_auth_clt_set_prefs(&auth,
+ &pjsua_var.acc[im_data->acc_id].cfg.auth_pref);
+
status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx,
&tdata);
if (status == PJ_SUCCESS) {
@@ -417,6 +420,9 @@ static void typing_callback(void *token, pjsip_event *e)
pjsua_var.acc[im_data->acc_id].cred_cnt,
pjsua_var.acc[im_data->acc_id].cred);
+ pjsip_auth_clt_set_prefs(&auth,
+ &pjsua_var.acc[im_data->acc_id].cfg.auth_pref);
+
status = pjsip_auth_clt_reinit_req(&auth, rdata, tsx->last_tx,
&tdata);
if (status == PJ_SUCCESS) {
diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c
index 1df81eab..d73a00d6 100644
--- a/pjsip/src/pjsua-lib/pjsua_pres.c
+++ b/pjsip/src/pjsua-lib/pjsua_pres.c
@@ -571,8 +571,9 @@ static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata)
return PJ_TRUE;
}
- /* Set credentials. */
+ /* Set credentials and preference. */
pjsip_auth_clt_set_credentials(&dlg->auth_sess, acc->cred_cnt, acc->cred);
+ pjsip_auth_clt_set_prefs(&dlg->auth_sess, &acc->cfg.auth_pref);
/* Init callback: */
pj_bzero(&pres_cb, sizeof(pres_cb));
@@ -1173,6 +1174,9 @@ static void subscribe_buddy_presence(unsigned index)
acc->cred_cnt, acc->cred);
}
+ /* Set authentication preference */
+ pjsip_auth_clt_set_prefs(&buddy->dlg->auth_sess, &acc->cfg.auth_pref);
+
pjsip_evsub_set_mod_data(buddy->sub, pjsua_var.mod.id, buddy);
status = pjsip_pres_initiate(buddy->sub, -1, &tdata);