Changeset 4728 for pjproject/trunk/pjsip/src/pjsip/sip_auth_client.c
- Timestamp:
- Feb 4, 2014 10:13:56 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_auth_client.c
r4537 r4728 1 1 /* $Id$ */ 2 /* 2 /* 3 3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) 4 4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org> … … 16 16 * You should have received a copy of the GNU General Public License 17 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 19 */ 20 20 … … 138 138 /* 139 139 * Create response digest based on the parameters and store the 140 * digest ASCII in 'result'. 140 * digest ASCII in 'result'. 141 141 */ 142 142 PJ_DEF(void) pjsip_auth_create_digest( pj_str_t *result, … … 160 160 161 161 if ((cred_info->data_type & PASSWD_MASK) == PJSIP_CRED_DATA_PLAIN_PASSWD) { 162 /*** 163 *** ha1 = MD5(username ":" realm ":" password) 162 /*** 163 *** ha1 = MD5(username ":" realm ":" password) 164 164 ***/ 165 165 pj_md5_init(&pms); … … 183 183 184 184 /*** 185 *** ha2 = MD5(method ":" req_uri) 185 *** ha2 = MD5(method ":" req_uri) 186 186 ***/ 187 187 pj_md5_init(&pms); … … 196 196 /*** 197 197 *** When qop is not used: 198 *** response = MD5(ha1 ":" nonce ":" ha2) 198 *** response = MD5(ha1 ":" nonce ":" ha2) 199 199 *** 200 200 *** When qop=auth is used: … … 218 218 /* This is the final response digest. */ 219 219 pj_md5_final(&pms, digest); 220 220 221 221 /* Convert digest to string and store in chal->response. */ 222 222 result->slen = PJSIP_MD5STRLEN; … … 259 259 260 260 /* 261 * Generate response digest. 261 * Generate response digest. 262 262 * Most of the parameters to generate the digest (i.e. username, realm, uri, 263 263 * and nonce) are expected to be in the credential. Additional parameters (i.e. … … 308 308 if ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) { 309 309 /* Call application callback to create the response digest */ 310 return (*cred_info->ext.aka.cb)(pool, chal, cred_info, 310 return (*cred_info->ext.aka.cb)(pool, chal, cred_info, 311 311 method, cred); 312 } 312 } 313 313 else { 314 314 /* Convert digest to string and store in chal->response. */ 315 pjsip_auth_create_digest( &cred->response, &cred->nonce, NULL, 316 NULL, NULL, uri, &chal->realm, 315 pjsip_auth_create_digest( &cred->response, &cred->nonce, NULL, 316 NULL, NULL, uri, &chal->realm, 317 317 cred_info, method); 318 318 } 319 319 320 320 } else if (has_auth_qop(pool, &chal->qop)) { 321 /* Server requires quality of protection. 321 /* Server requires quality of protection. 322 322 * We respond with selecting "qop=auth" protection. 323 323 */ … … 335 335 if ((cred_info->data_type & EXT_MASK) == PJSIP_CRED_DATA_EXT_AKA) { 336 336 /* Call application callback to create the response digest */ 337 return (*cred_info->ext.aka.cb)(pool, chal, cred_info, 337 return (*cred_info->ext.aka.cb)(pool, chal, cred_info, 338 338 method, cred); 339 339 } 340 340 else { 341 pjsip_auth_create_digest( &cred->response, &cred->nonce, 342 &cred->nc, cnonce, &pjsip_AUTH_STR, 341 pjsip_auth_create_digest( &cred->response, &cred->nonce, 342 &cred->nc, cnonce, &pjsip_AUTH_STR, 343 343 uri, &chal->realm, cred_info, method ); 344 344 } … … 346 346 } else { 347 347 /* Server requires quality protection that we don't support. */ 348 PJ_LOG(4,(THIS_FILE, "Unsupported qop offer %.*s", 348 PJ_LOG(4,(THIS_FILE, "Unsupported qop offer %.*s", 349 349 chal->qop.slen, chal->qop.ptr)); 350 350 return PJSIP_EINVALIDQOP; … … 358 358 * Update authentication session with a challenge. 359 359 */ 360 static void update_digest_session( pj_pool_t *ses_pool, 360 static void update_digest_session( pj_pool_t *ses_pool, 361 361 pjsip_cached_auth *cached_auth, 362 362 const pjsip_www_authenticate_hdr *hdr ) … … 371 371 * than the one in the cache, to reduce memory usage. 372 372 */ 373 const pjsip_digest_challenge *d1 = 373 const pjsip_digest_challenge *d1 = 374 374 &cached_auth->last_chal->challenge.digest; 375 375 const pjsip_digest_challenge *d2 = &hdr->challenge.digest; … … 407 407 */ 408 408 if (cached_auth->realm.slen == 0) { 409 pj_strdup(ses_pool, &cached_auth->realm, 409 pj_strdup(ses_pool, &cached_auth->realm, 410 410 &hdr->challenge.digest.realm); 411 411 } … … 413 413 } else { 414 414 /* Update last_nonce and nonce-count */ 415 if (!pj_strcmp(&hdr->challenge.digest.nonce, 416 &cached_auth->last_chal->challenge.digest.nonce)) 415 if (!pj_strcmp(&hdr->challenge.digest.nonce, 416 &cached_auth->last_chal->challenge.digest.nonce)) 417 417 { 418 418 /* Same nonce, increment nonce-count */ … … 424 424 /* Has the opaque changed? */ 425 425 if (pj_strcmp(&cached_auth->last_chal->challenge.digest.opaque, 426 &hdr->challenge.digest.opaque)) 426 &hdr->challenge.digest.opaque)) 427 427 { 428 pj_strdup(ses_pool, 428 pj_strdup(ses_pool, 429 429 &cached_auth->last_chal->challenge.digest.opaque, 430 430 &hdr->challenge.digest.opaque); … … 485 485 PJ_DEF(pj_status_t) pjsip_auth_clt_init( pjsip_auth_clt_sess *sess, 486 486 pjsip_endpoint *endpt, 487 pj_pool_t *pool, 487 pj_pool_t *pool, 488 488 unsigned options) 489 489 { … … 510 510 511 511 pjsip_auth_clt_init(sess, (pjsip_endpoint*)rhs->endpt, pool, 0); 512 512 513 513 sess->cred_cnt = rhs->cred_cnt; 514 514 sess->cred_info = (pjsip_cred_info*) 515 pj_pool_alloc(pool, 515 pj_pool_alloc(pool, 516 516 sess->cred_cnt*sizeof(pjsip_cred_info)); 517 517 for (i=0; i<rhs->cred_cnt; ++i) { 518 518 pj_strdup(pool, &sess->cred_info[i].realm, &rhs->cred_info[i].realm); 519 519 pj_strdup(pool, &sess->cred_info[i].scheme, &rhs->cred_info[i].scheme); 520 pj_strdup(pool, &sess->cred_info[i].username, 520 pj_strdup(pool, &sess->cred_info[i].username, 521 521 &rhs->cred_info[i].username); 522 522 sess->cred_info[i].data_type = rhs->cred_info[i].data_type; … … 553 553 sess->cred_info[i].data_type = c[i].data_type; 554 554 555 /* When data_type is PJSIP_CRED_DATA_EXT_AKA, 555 /* When data_type is PJSIP_CRED_DATA_EXT_AKA, 556 556 * callback must be specified. 557 557 */ … … 569 569 570 570 /* Verify K len */ 571 PJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN, 571 PJ_ASSERT_RETURN(c[i].ext.aka.k.slen <= PJSIP_AKA_KLEN, 572 572 PJSIP_EAUTHINAKACRED); 573 573 574 574 /* Verify OP len */ 575 PJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN, 575 PJ_ASSERT_RETURN(c[i].ext.aka.op.slen <= PJSIP_AKA_OPLEN, 576 576 PJSIP_EAUTHINAKACRED); 577 577 … … 631 631 632 632 633 /* 633 /* 634 634 * Create Authorization/Proxy-Authorization response header based on the challege 635 635 * in WWW-Authenticate/Proxy-Authenticate header. … … 786 786 if (status != PJ_SUCCESS) 787 787 return status; 788 788 789 789 pjsip_msg_add_hdr( tdata->msg, (pjsip_hdr*)hauth); 790 790 … … 832 832 /* Get the method. */ 833 833 method = &tdata->msg->line.req.method; 834 PJ_UNUSED_ARG(method); /* Warning about unused var caused by #if below */ 834 835 835 836 auth = sess->cached_auth.next; … … 870 871 # endif 871 872 872 } 873 } 873 874 # if defined(PJSIP_AUTH_QOP_SUPPORT) && \ 874 875 defined(PJSIP_AUTH_AUTO_SEND_NEXT) && \ 875 876 (PJSIP_AUTH_QOP_SUPPORT && PJSIP_AUTH_AUTO_SEND_NEXT) 876 877 else if (auth->qop_value == PJSIP_AUTH_QOP_AUTH) { 877 /* For qop="auth", we have to re-create the authorization header. 878 /* For qop="auth", we have to re-create the authorization header. 878 879 */ 879 880 const pjsip_cred_info *cred; … … 881 882 pj_status_t status; 882 883 883 cred = auth_find_cred(sess, &auth->realm, 884 cred = auth_find_cred(sess, &auth->realm, 884 885 &auth->last_chal->scheme); 885 886 if (!cred) { … … 888 889 } 889 890 890 status = auth_respond( tdata->pool, auth->last_chal, 891 tdata->msg->line.req.uri, 891 status = auth_respond( tdata->pool, auth->last_chal, 892 tdata->msg->line.req.uri, 892 893 cred, 893 894 &tdata->msg->line.req.method, … … 895 896 if (status != PJ_SUCCESS) 896 897 return status; 897 898 898 899 //pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hauth); 899 900 pj_list_push_back(&added, hauth); … … 984 985 { 985 986 sent_auth = (pjsip_authorization_hdr*) hdr; 986 if (pj_stricmp(&hchal->challenge.common.realm, 987 if (pj_stricmp(&hchal->challenge.common.realm, 987 988 &sent_auth->credential.common.realm )==0) 988 989 { … … 1055 1056 1056 1057 /* Find credential to be used for the challenge. */ 1057 cred = auth_find_cred( sess, &hchal->challenge.common.realm, 1058 cred = auth_find_cred( sess, &hchal->challenge.common.realm, 1058 1059 &hchal->scheme); 1059 1060 if (!cred) { 1060 1061 const pj_str_t *realm = &hchal->challenge.common.realm; 1061 PJ_LOG(4,(THIS_FILE, 1062 PJ_LOG(4,(THIS_FILE, 1062 1063 "Unable to set auth for %s: can not find credential for %.*s/%.*s", 1063 tdata->obj_name, 1064 tdata->obj_name, 1064 1065 realm->slen, realm->ptr, 1065 1066 hchal->scheme.slen, hchal->scheme.ptr)); … … 1068 1069 1069 1070 /* Respond to authorization challenge. */ 1070 status = auth_respond( req_pool, hchal, uri, cred, 1071 &tdata->msg->line.req.method, 1071 status = auth_respond( req_pool, hchal, uri, cred, 1072 &tdata->msg->line.req.method, 1072 1073 sess->pool, cached_auth, h_auth); 1073 1074 return status; … … 1148 1149 * authorization session. 1149 1150 */ 1150 status = process_auth( tdata->pool, hchal, tdata->msg->line.req.uri, 1151 status = process_auth( tdata->pool, hchal, tdata->msg->line.req.uri, 1151 1152 tdata, sess, cached_auth, &hauth); 1152 1153 if (status != PJ_SUCCESS)
Note: See TracChangeset
for help on using the changeset viewer.