Changeset 4899 for pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
- Timestamp:
- Aug 21, 2014 5:58:36 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c
r4831 r4899 116 116 pj_bool_t end_sess_on_failure); 117 117 118 static pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv, 119 pjsip_event *e); 120 118 121 static void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) = 119 122 { … … 991 994 status = PJSIP_ERRNO_FROM_SIP_STATUS(code); 992 995 goto on_return; 996 } 997 998 /* Ticket #1735: Check Contact/Record-Route header in a secure dialog. */ 999 if (pjsip_cfg()->endpt.disable_secure_dlg_check == PJ_FALSE && 1000 msg && c_hdr && c_hdr->uri) 1001 { 1002 /* Check Contact header */ 1003 if (!PJSIP_URI_SCHEME_IS_SIPS(c_hdr->uri)) 1004 status = PJSIP_ESESSIONINSECURE; 1005 1006 /* Check top Record-Route header */ 1007 if (status == PJ_SUCCESS) { 1008 pjsip_rr_hdr *r = (pjsip_rr_hdr*) 1009 pjsip_msg_find_hdr(msg, PJSIP_H_RECORD_ROUTE, 1010 NULL); 1011 if (r && !PJSIP_URI_SCHEME_IS_SIPS(&r->name_addr)) { 1012 /* Not "sips", check if it is "sip" and has param 1013 * "transport=tls". 1014 */ 1015 if (PJSIP_URI_SCHEME_IS_SIP(&r->name_addr)) { 1016 pjsip_sip_uri *sip_uri = (pjsip_sip_uri*) 1017 pjsip_uri_get_uri(r->name_addr.uri); 1018 if (pj_stricmp2(&sip_uri->transport_param, "tls")!=0) 1019 status = PJSIP_ESESSIONINSECURE; 1020 } else { 1021 /* Not "sips" nor "sip", treat it as insecure? */ 1022 status = PJSIP_ESESSIONINSECURE; 1023 } 1024 } 1025 } 1026 1027 if (status != PJ_SUCCESS) { 1028 pjsip_warning_hdr *w; 1029 pj_str_t warn_text = pj_str("SIPS Required"); 1030 w = pjsip_warning_hdr_create(tmp_pool, 381, 1031 pjsip_endpt_name(endpt), 1032 &warn_text); 1033 if (w) { 1034 pj_list_push_back(&res_hdr_list, w); 1035 } 1036 code = PJSIP_SC_TEMPORARILY_UNAVAILABLE; 1037 goto on_return; 1038 } 993 1039 } 994 1040 … … 3225 3271 */ 3226 3272 static void inv_respond_incoming_update(pjsip_inv_session *inv, 3227 pjsip_ rx_data *rdata)3273 pjsip_event *e) 3228 3274 { 3229 3275 pjmedia_sdp_neg_state neg_state; 3230 3276 pj_status_t status; 3231 3277 pjsip_tx_data *tdata = NULL; 3278 pjsip_rx_data *rdata; 3232 3279 pjsip_status_code st_code; 3280 3281 pj_assert(e->type == PJSIP_EVENT_TSX_STATE && 3282 e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 3283 rdata = e->body.tsx_state.src.rdata; 3284 3285 /* Check routing URI scheme for secure dialog */ 3286 if (!inv_check_secure_dlg(inv, e)) 3287 return; 3233 3288 3234 3289 /* Invoke Session Timers module */ … … 3386 3441 { 3387 3442 pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; 3388 status = handle_timer_response(inv, rdata, PJ_FALSE); 3389 3390 if (rdata->msg_info.msg->body) { 3391 /* Only process remote SDP if we have sent local offer */ 3392 if (inv->neg && pjmedia_sdp_neg_get_state(inv->neg) == 3393 PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 3394 { 3395 status = inv_check_sdp_in_incoming_msg(inv, tsx, rdata); 3396 } else { 3397 PJ_LOG(5,(THIS_FILE, "Ignored message body in %s as no local " 3398 "offer was sent", 3399 pjsip_rx_data_get_info(rdata))); 3443 3444 /* Check routing URI scheme for secure dialog */ 3445 if (inv_check_secure_dlg(inv, e)) { 3446 3447 status = handle_timer_response(inv, rdata, PJ_FALSE); 3448 3449 if (rdata->msg_info.msg->body) { 3450 /* Only process remote SDP if we have sent local offer */ 3451 if (inv->neg && pjmedia_sdp_neg_get_state(inv->neg) == 3452 PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER) 3453 { 3454 status = inv_check_sdp_in_incoming_msg(inv, tsx, rdata); 3455 } else { 3456 PJ_LOG(5,(THIS_FILE, "Ignored message body in %s as no " 3457 "local offer was sent", 3458 pjsip_rx_data_get_info(rdata))); 3459 } 3400 3460 } 3401 3461 } 3402 handled = PJ_TRUE; 3462 3463 handled = PJ_TRUE; 3403 3464 } 3404 3465 … … 3515 3576 } 3516 3577 } 3578 3579 3580 /* Ticket #1735: If this is a secure dialog, make sure that any incoming 3581 * initial/subsequent INVITE/UPDATE request or the 2xx response to INVITE/ 3582 * UPDATE specifies secure Contact and Record-Route headers. 3583 */ 3584 static pj_bool_t inv_check_secure_dlg(pjsip_inv_session *inv, 3585 pjsip_event *e) 3586 { 3587 pjsip_transaction *tsx = e->body.tsx_state.tsx; 3588 pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx); 3589 3590 if (pjsip_cfg()->endpt.disable_secure_dlg_check == PJ_FALSE && 3591 dlg->secure && e->body.tsx_state.type==PJSIP_EVENT_RX_MSG && 3592 (tsx->role==PJSIP_ROLE_UAC && tsx->status_code/100 == 2 || 3593 tsx->role==PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING) && 3594 (tsx->method.id==PJSIP_INVITE_METHOD || 3595 pjsip_method_cmp(&tsx->method, &pjsip_update_method)==0)) 3596 { 3597 const pjsip_msg *msg = e->body.tsx_state.src.rdata->msg_info.msg; 3598 pj_status_t status = PJ_SUCCESS; 3599 pjsip_contact_hdr *c; 3600 3601 /* Check Contact header */ 3602 c = (pjsip_contact_hdr*) 3603 pjsip_msg_find_hdr(msg,PJSIP_H_CONTACT, NULL); 3604 if (!(c && c->uri && PJSIP_URI_SCHEME_IS_SIPS(c->uri))) 3605 status = PJSIP_ESESSIONINSECURE; 3606 3607 /* Check top Record-Route header */ 3608 if (status == PJ_SUCCESS) { 3609 pjsip_rr_hdr *r = (pjsip_rr_hdr*) 3610 pjsip_msg_find_hdr(msg, PJSIP_H_RECORD_ROUTE, 3611 NULL); 3612 if (r && !PJSIP_URI_SCHEME_IS_SIPS(&r->name_addr)) { 3613 /* Not "sips", check if it is "sip" and has param 3614 * "transport=tls". 3615 */ 3616 if (PJSIP_URI_SCHEME_IS_SIP(&r->name_addr)) { 3617 pjsip_sip_uri *sip_uri = (pjsip_sip_uri*) 3618 pjsip_uri_get_uri(r->name_addr.uri); 3619 if (pj_stricmp2(&sip_uri->transport_param, "tls")!=0) 3620 status = PJSIP_ESESSIONINSECURE; 3621 } else { 3622 /* Not "sips" nor "sip", treat it as insecure? */ 3623 status = PJSIP_ESESSIONINSECURE; 3624 } 3625 } 3626 } 3627 3628 if (status == PJSIP_ESESSIONINSECURE) { 3629 /* Found non-SIPS scheme in Contact/Record-Route header */ 3630 3631 pj_str_t warn_text = pj_str("SIPS Required"); 3632 3633 if (tsx->role == PJSIP_ROLE_UAC) { 3634 3635 /* If we are UAC, terminate the session */ 3636 pjsip_tx_data *bye; 3637 3638 PJ_LOG(4,(inv->obj_name, 3639 "Secure dialog requires SIPS scheme in Contact and " 3640 "Record-Route headers, ending the session")); 3641 3642 status = pjsip_inv_end_session(inv, 480, NULL, &bye); 3643 if (status == PJ_SUCCESS && bye) { 3644 pjsip_warning_hdr *w; 3645 w = pjsip_warning_hdr_create(bye->pool, 381, 3646 pjsip_endpt_name(dlg->endpt), 3647 &warn_text); 3648 if (w) 3649 pjsip_msg_add_hdr(bye->msg, (pjsip_hdr*)w); 3650 3651 status = pjsip_inv_send_msg(inv, bye); 3652 } 3653 3654 } else { 3655 3656 /* If we are UAS, reject the request */ 3657 pjsip_rx_data *rdata = e->body.tsx_state.src.rdata; 3658 pjsip_tx_data *tdata; 3659 3660 PJ_LOG(4,(inv->obj_name, 3661 "Secure dialog requires SIPS scheme in Contact and " 3662 "Route headers, rejecting the request")); 3663 3664 status = pjsip_dlg_create_response(inv->dlg, rdata, 480, 3665 NULL, &tdata); 3666 if (status == PJ_SUCCESS) { 3667 pjsip_warning_hdr *w; 3668 w = pjsip_warning_hdr_create(tdata->pool, 381, 3669 pjsip_endpt_name(dlg->endpt), 3670 &warn_text); 3671 if (w) 3672 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)w); 3673 3674 pjsip_dlg_send_response(dlg, tsx, tdata); 3675 } 3676 3677 } 3678 3679 return PJ_FALSE; 3680 } 3681 } 3682 3683 return PJ_TRUE; 3684 } 3685 3517 3686 3518 3687 … … 3866 4035 pj_assert(0); 3867 4036 4037 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 4038 4039 /* Check routing URI scheme for secure dialog */ 4040 if (!inv_check_secure_dlg(inv, e)) 4041 break; 4042 3868 4043 /* Process session timer response. */ 3869 4044 status = handle_timer_response(inv, … … 3873 4048 break; 3874 4049 3875 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);3876 3877 4050 inv_check_sdp_in_incoming_msg(inv, tsx, 3878 4051 e->body.tsx_state.src.rdata); … … 3890 4063 if (tsx->status_code/100 == 2) { 3891 4064 /* This must be receipt of 2xx response */ 4065 pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 4066 4067 /* Set state to CONNECTING */ 4068 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 4069 4070 /* Check routing URI scheme for secure dialog */ 4071 if (!inv_check_secure_dlg(inv, e)) 4072 break; 3892 4073 3893 4074 /* Process session timer response. */ … … 3898 4079 break; 3899 4080 3900 /* Set state to CONNECTING */3901 inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e);3902 3903 4081 inv_check_sdp_in_incoming_msg(inv, tsx, 3904 4082 e->body.tsx_state.src.rdata); 3905 3906 4083 /* Send ACK */ 3907 pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG);3908 3909 4084 inv_send_ack(inv, e); 3910 4085 … … 3943 4118 * Handle a very early UPDATE 3944 4119 */ 3945 inv_respond_incoming_update(inv, e ->body.tsx_state.src.rdata);4120 inv_respond_incoming_update(inv, e); 3946 4121 3947 4122 … … 4061 4236 pj_status_t status; 4062 4237 4238 /* Check routing URI scheme for secure dialog */ 4239 if (!inv_check_secure_dlg(inv, e)) 4240 break; 4241 4063 4242 /* Process session timer response. */ 4064 4243 status = handle_timer_response(inv, … … 4101 4280 pj_status_t status; 4102 4281 4282 /* Check routing URI scheme for secure dialog */ 4283 if (!inv_check_secure_dlg(inv, e)) 4284 break; 4285 4103 4286 /* Process session timer response. */ 4104 4287 status = handle_timer_response(inv, … … 4150 4333 * Handle incoming UPDATE 4151 4334 */ 4152 inv_respond_incoming_update(inv, e ->body.tsx_state.src.rdata);4335 inv_respond_incoming_update(inv, e); 4153 4336 4154 4337 … … 4358 4541 * Handle incoming UPDATE 4359 4542 */ 4360 inv_respond_incoming_update(inv, e ->body.tsx_state.src.rdata);4543 inv_respond_incoming_update(inv, e); 4361 4544 4362 4545 … … 4487 4670 return; 4488 4671 } 4672 4673 /* Check routing URI scheme for secure dialog */ 4674 if (!inv_check_secure_dlg(inv, e)) 4675 return; 4489 4676 4490 4677 /* Save the invite transaction. */ … … 4730 4917 /* Re-INVITE was accepted. */ 4731 4918 4919 /* Check routing URI scheme for secure dialog */ 4920 if (!inv_check_secure_dlg(inv, e)) 4921 return; 4922 4732 4923 /* Process session timer response. */ 4733 4924 status = handle_timer_response(inv, … … 4788 4979 * Handle incoming UPDATE 4789 4980 */ 4790 inv_respond_incoming_update(inv, e ->body.tsx_state.src.rdata);4981 inv_respond_incoming_update(inv, e); 4791 4982 4792 4983 } else if (tsx->role == PJSIP_ROLE_UAC &&
Note: See TracChangeset
for help on using the changeset viewer.