Merge "res_pjsip_session: Fix in-dialog authentication." into 13

changes/70/570/1
Matt Jordan 10 years ago committed by Gerrit Code Review
commit bc70904c05

@ -1418,16 +1418,95 @@ void ast_sip_session_unsuspend(struct ast_sip_session *session)
ao2_ref(suspender, -1);
}
static int session_outbound_auth(pjsip_dialog *dlg, pjsip_tx_data *tdata, void *user_data)
/*!
* \internal
* \brief Handle initial INVITE challenge response message.
* \since 13.5.0
*
* \param rdata PJSIP receive response message data.
*
* \retval PJ_FALSE Did not handle message.
* \retval PJ_TRUE Handled message.
*/
static pj_bool_t outbound_invite_auth(pjsip_rx_data *rdata)
{
pjsip_inv_session *inv = pjsip_dlg_get_inv_session(dlg);
struct ast_sip_session *session = inv->mod_data[session_module.id];
pjsip_transaction *tsx;
pjsip_dialog *dlg;
pjsip_inv_session *inv;
pjsip_tx_data *tdata;
struct ast_sip_session *session;
if (rdata->msg_info.msg->line.status.code != 401
&& rdata->msg_info.msg->line.status.code != 407) {
/* Doesn't pertain to us. Move on */
return PJ_FALSE;
}
tsx = pjsip_rdata_get_tsx(rdata);
dlg = pjsip_rdata_get_dlg(rdata);
if (!dlg || !tsx) {
return PJ_FALSE;
}
if (inv->state < PJSIP_INV_STATE_CONFIRMED && tdata->msg->line.req.method.id == PJSIP_INVITE_METHOD) {
pjsip_inv_uac_restart(inv, PJ_FALSE);
if (tsx->method.id != PJSIP_INVITE_METHOD) {
/* Not an INVITE that needs authentication */
return PJ_FALSE;
}
inv = pjsip_dlg_get_inv_session(dlg);
if (PJSIP_INV_STATE_CONFIRMED <= inv->state) {
/*
* We cannot handle reINVITE authentication at this
* time because the reINVITE transaction is still in
* progress.
*/
ast_debug(1, "A reINVITE is being challenged.\n");
return PJ_FALSE;
}
ast_debug(1, "Initial INVITE is being challenged.\n");
session = inv->mod_data[session_module.id];
if (ast_sip_create_request_with_auth(&session->endpoint->outbound_auths, rdata, tsx,
&tdata)) {
return PJ_FALSE;
}
/*
* Restart the outgoing initial INVITE transaction to deal
* with authentication.
*/
pjsip_inv_uac_restart(inv, PJ_FALSE);
ast_sip_session_send_request(session, tdata);
return 0;
return PJ_TRUE;
}
static pjsip_module outbound_invite_auth_module = {
.name = {"Outbound INVITE Auth", 20},
.priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE,
.on_rx_response = outbound_invite_auth,
};
/*!
* \internal
* \brief Setup outbound initial INVITE authentication.
* \since 13.5.0
*
* \param dlg PJSIP dialog to attach outbound authentication.
*
* \retval 0 on success.
* \retval -1 on error.
*/
static int setup_outbound_invite_auth(pjsip_dialog *dlg)
{
pj_status_t status;
++dlg->sess_count;
status = pjsip_dlg_add_usage(dlg, &outbound_invite_auth_module, NULL);
--dlg->sess_count;
return status != PJ_SUCCESS ? -1 : 0;
}
struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint,
@ -1465,7 +1544,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
return NULL;
}
if (ast_sip_dialog_setup_outbound_authentication(dlg, endpoint, session_outbound_auth, NULL)) {
if (setup_outbound_invite_auth(dlg)) {
pjsip_dlg_terminate(dlg);
return NULL;
}
@ -1505,7 +1584,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
ao2_cleanup(joint_caps);
}
if ((pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS)) {
if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
/* Since we are not notifying ourselves that the INVITE session is being terminated
* we need to manually drop its reference to session
@ -2254,6 +2333,7 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
{
ast_sip_session_response_cb cb;
struct ast_sip_session *session = inv->mod_data[session_module.id];
pjsip_tx_data *tdata;
print_debug_details(inv, tsx, e);
if (!session) {
@ -2283,12 +2363,23 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
reschedule_reinvite(session, cb);
return;
} else if (inv->state == PJSIP_INV_STATE_CONFIRMED &&
tsx->status_code != 488) {
/* Other reinvite failures (except 488) result in destroying the session. */
pjsip_tx_data *tdata;
if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
ast_sip_session_send_request(session, tdata);
}
if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
ast_debug(1, "reINVITE received final response code %d\n",
tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407)
&& !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx, &tdata)) {
/* Send authed reINVITE */
ast_sip_session_send_request_with_cb(session, tdata, cb);
return;
}
if (tsx->status_code != 488) {
/* Other reinvite failures (except 488) result in destroying the session. */
if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
ast_sip_session_send_request(session, tdata);
}
}
}
} else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
@ -2299,14 +2390,30 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
* a cancelled call. Our role is to immediately send a BYE to end the
* dialog.
*/
pjsip_tx_data *tdata;
if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
ast_sip_session_send_request(session, tdata);
}
}
}
}
} else {
/* All other methods */
if (tsx->role == PJSIP_ROLE_UAC) {
if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
/* This means we got a final response to our outgoing method */
ast_debug(1, "%.*s received final response code %d\n",
(int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
tsx->status_code);
if ((tsx->status_code == 401 || tsx->status_code == 407)
&& !ast_sip_create_request_with_auth(
&session->endpoint->outbound_auths,
e->body.tsx_state.src.rdata, tsx, &tdata)) {
/* Send authed version of the method */
ast_sip_session_send_request_with_cb(session, tdata, cb);
return;
}
}
}
}
if (cb) {
cb(session, e->body.tsx_state.src.rdata);
@ -2640,6 +2747,7 @@ static int load_module(void)
return AST_MODULE_LOAD_DECLINE;
}
ast_sip_register_service(&session_reinvite_module);
ast_sip_register_service(&outbound_invite_auth_module);
ast_module_shutdown_ref(ast_module_info->self);
@ -2648,6 +2756,7 @@ static int load_module(void)
static int unload_module(void)
{
ast_sip_unregister_service(&outbound_invite_auth_module);
ast_sip_unregister_service(&session_reinvite_module);
ast_sip_unregister_service(&session_module);
ast_sorcery_delete(ast_sip_get_sorcery(), nat_hook);

Loading…
Cancel
Save