summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2015-04-28 19:18:16 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2015-04-28 19:18:16 -0500
commit0e70dc0dc82e4c36eb120cac670a1a1954ceffb2 (patch)
tree9dafa96eb338acd787bd592c6b0924d58b305844
parent7ee05892d63d607d3c6fa2811d46015d59aabbd1 (diff)
parente39bd6ba463f25be2265228f835957424563642b (diff)
Merge "res_pjsip_outbound_registration: Don't fail on delayed processing: 13." into 13
-rw-r--r--include/asterisk/res_pjsip.h23
-rw-r--r--res/res_pjsip.c10
-rw-r--r--res/res_pjsip_outbound_authenticator_digest.c14
-rw-r--r--res/res_pjsip_outbound_registration.c17
4 files changed, 55 insertions, 9 deletions
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index a15e967b8..cbae5955e 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -702,6 +702,18 @@ struct ast_sip_outbound_authenticator {
*/
int (*create_request_with_auth)(const struct ast_sip_auth_vector *auths, struct pjsip_rx_data *challenge,
struct pjsip_transaction *tsx, struct pjsip_tx_data **new_request);
+ /*!
+ * \brief Create a new request with authentication credentials based on old request
+ *
+ * \param auths A vector of IDs of auth sorcery objects
+ * \param challenge The SIP response with authentication challenge(s)
+ * \param old_request The request that resulted in challenge(s)
+ * \param new_request The new SIP request with challenge response(s)
+ * \retval 0 Successfully created new request
+ * \retval -1 Failed to create a new request
+ */
+ int (*create_request_with_auth_from_old)(const struct ast_sip_auth_vector *auths, struct pjsip_rx_data *challenge,
+ struct pjsip_tx_data *old_request, struct pjsip_tx_data **new_request);
};
/*!
@@ -1397,6 +1409,17 @@ int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pj
pjsip_transaction *tsx, pjsip_tx_data **new_request);
/*!
+ * \brief Create a response to an authentication challenge
+ *
+ * This will call into an outbound authenticator's create_request_with_auth callback
+ * to create a new request with authentication credentials. See the create_request_with_auth_from_old
+ * callback in the \ref ast_sip_outbound_authenticator structure for details about
+ * the parameters and return values.
+ */
+int ast_sip_create_request_with_auth_from_old(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge,
+ pjsip_tx_data *old_request, pjsip_tx_data **new_request);
+
+/*!
* \brief Determine the endpoint that has sent a SIP message
*
* This will call into each of the registered endpoint identifiers'
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index bde0de1ec..5f68c4440 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -2012,6 +2012,16 @@ int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pj
return registered_outbound_authenticator->create_request_with_auth(auths, challenge, tsx, new_request);
}
+int ast_sip_create_request_with_auth_from_old(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge,
+ pjsip_tx_data *old_request, pjsip_tx_data **new_request)
+{
+ if (!registered_outbound_authenticator) {
+ ast_log(LOG_WARNING, "No SIP outbound authenticator registered. Cannot respond to authentication challenge\n");
+ return -1;
+ }
+ return registered_outbound_authenticator->create_request_with_auth_from_old(auths, challenge, old_request, new_request);
+}
+
struct endpoint_identifier_list {
const char *name;
unsigned int priority;
diff --git a/res/res_pjsip_outbound_authenticator_digest.c b/res/res_pjsip_outbound_authenticator_digest.c
index 35e59f21a..aa35fbac0 100644
--- a/res/res_pjsip_outbound_authenticator_digest.c
+++ b/res/res_pjsip_outbound_authenticator_digest.c
@@ -101,14 +101,14 @@ cleanup:
return res;
}
-static int digest_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge,
- pjsip_transaction *tsx, pjsip_tx_data **new_request)
+static int digest_create_request_with_auth_from_old(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge,
+ pjsip_tx_data *old_request, pjsip_tx_data **new_request)
{
pjsip_auth_clt_sess auth_sess;
pjsip_cseq_hdr *cseq;
if (pjsip_auth_clt_init(&auth_sess, ast_sip_get_pjsip_endpoint(),
- tsx->pool, 0) != PJ_SUCCESS) {
+ old_request->pool, 0) != PJ_SUCCESS) {
ast_log(LOG_WARNING, "Failed to initialize client authentication session\n");
return -1;
}
@@ -119,7 +119,7 @@ static int digest_create_request_with_auth(const struct ast_sip_auth_vector *aut
}
switch (pjsip_auth_clt_reinit_req(&auth_sess, challenge,
- tsx->last_tx, new_request)) {
+ old_request, new_request)) {
case PJ_SUCCESS:
/* PJSIP creates a new transaction for new_request (meaning it creates a new
* branch). However, it recycles the Call-ID, from-tag, and CSeq from the
@@ -150,6 +150,12 @@ static int digest_create_request_with_auth(const struct ast_sip_auth_vector *aut
return -1;
}
+static int digest_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge,
+ pjsip_transaction *tsx, pjsip_tx_data **new_request)
+{
+ return digest_create_request_with_auth_from_old(auths, challenge, tsx->last_tx, new_request);
+}
+
static struct ast_sip_outbound_authenticator digest_authenticator = {
.create_request_with_auth = digest_create_request_with_auth,
};
diff --git a/res/res_pjsip_outbound_registration.c b/res/res_pjsip_outbound_registration.c
index b8f7112e4..1c00473fb 100644
--- a/res/res_pjsip_outbound_registration.c
+++ b/res/res_pjsip_outbound_registration.c
@@ -487,8 +487,8 @@ struct registration_response {
struct sip_outbound_registration_client_state *client_state;
/*! \brief The response message */
pjsip_rx_data *rdata;
- /*! \brief The response transaction */
- pjsip_transaction *tsx;
+ /*! \brief Request for which the response was received */
+ pjsip_tx_data *old_request;
};
/*! \brief Registration response structure destructor */
@@ -500,6 +500,10 @@ static void registration_response_destroy(void *obj)
pjsip_rx_data_free_cloned(response->rdata);
}
+ if (response->old_request) {
+ pjsip_tx_data_dec_ref(response->old_request);
+ }
+
ao2_cleanup(response->client_state);
}
@@ -558,8 +562,8 @@ static int handle_registration_response(void *data)
if (!response->client_state->auth_attempted &&
(response->code == 401 || response->code == 407)) {
pjsip_tx_data *tdata;
- if (!ast_sip_create_request_with_auth(&response->client_state->outbound_auths,
- response->rdata, response->tsx, &tdata)) {
+ if (!ast_sip_create_request_with_auth_from_old(&response->client_state->outbound_auths,
+ response->rdata, response->old_request, &tdata)) {
ao2_ref(response->client_state, +1);
response->client_state->auth_attempted = 1;
if (pjsip_regc_send(response->client_state->client, tdata) != PJ_SUCCESS) {
@@ -650,9 +654,12 @@ static void sip_outbound_registration_response_cb(struct pjsip_regc_cbparam *par
if (param->rdata) {
struct pjsip_retry_after_hdr *retry_after = pjsip_msg_find_hdr(param->rdata->msg_info.msg, PJSIP_H_RETRY_AFTER, NULL);
+ pjsip_transaction *tsx;
response->retry_after = retry_after ? retry_after->ivalue : 0;
- response->tsx = pjsip_rdata_get_tsx(param->rdata);
+ tsx = pjsip_rdata_get_tsx(param->rdata);
+ response->old_request = tsx->last_tx;
+ pjsip_tx_data_add_ref(response->old_request);
pjsip_rx_data_clone(param->rdata, 0, &response->rdata);
}