Hello!
That's the *complete* patch for Asterisk 16.3 (can be applied to asterisk 16.4,
too). Logging has been changed to ast_debug(3,).
See previous posts for information about usage.
Regards,
Michael
diff -urN asterisk-16.3.0.orig/res/res_pjsip/pjsip_options.c asterisk-16.3.0/res/res_pjsip/pjsip_options.c
--- asterisk-16.3.0.orig/res/res_pjsip/pjsip_options.c 2019-04-04 16:49:57.000000000 +0200
+++ asterisk-16.3.0/res/res_pjsip/pjsip_options.c 2019-06-01 02:15:11.339000000 +0200
@@ -212,6 +212,8 @@
*/
static struct ast_taskprocessor *management_serializer;
+static int sip_options_qualify_contact(void *obj, void *arg, int flags);
+
static pj_status_t send_options_response(pjsip_rx_data *rdata, int code)
{
pjsip_endpoint *endpt = ast_sip_get_pjsip_endpoint();
@@ -801,6 +803,14 @@
break;
}
+ /* check for 494 */
+ if (status == AVAILABLE && e->body.tsx_state.src.rdata->msg_info.msg->line.status.code == 494) {
+ /* need to resend the options request with mediasec headers */
+ ast_debug(3,"detected 494 - call sip_options_qualify_contact again with mediasec header\n");
+ sip_options_qualify_contact(contact_callback_data->contact, contact_callback_data->aor_options, 494);
+ return;
+ }
+
/* Update the callback data with the new status, this will get handled in the AOR serializer */
contact_callback_data->status = status;
@@ -905,6 +915,14 @@
return 0;
}
+ if (flags && flags == 494) {
+ /* add mediasec header */
+ ast_debug(3,"OPTIONS: adding MEDIASEC headers\n");
+ ast_sip_add_header(tdata,"Security-Verify","msrp-tls;mediasec");
+ ast_sip_add_header(tdata,"Security-Verify","sdes-srtp;mediasec");
+ ast_sip_add_header(tdata,"Security-Verify","dtls-srtp;mediasec");
+ }
+
if (ast_sip_send_out_of_dialog_request(tdata, endpoint,
(int)(aor_options->qualify_timeout * 1000), contact_callback_data,
qualify_contact_cb)) {
diff -urN asterisk-16.3.0.orig/res/res_pjsip_outbound_registration.c asterisk-16.3.0/res/res_pjsip_outbound_registration.c
--- asterisk-16.3.0.orig/res/res_pjsip_outbound_registration.c 2019-04-04 16:49:57.000000000 +0200
+++ asterisk-16.3.0/res/res_pjsip_outbound_registration.c 2019-06-01 02:16:14.683000000 +0200
@@ -361,6 +361,10 @@
char *transport_name;
/*! \brief The name of the registration sorcery object */
char *registration_name;
+ /*! \brief Indicator if it's the first Register in a call. Hast to be set to 0 if the OK response has been seen. Has to be set to 1 on unregister and initial try. */
+ unsigned int initial_reg;
+ /*! \brief Indicator, if there was a 494 response before */
+ unsigned int is494;
};
/*! \brief Outbound registration state information (persists for lifetime that registration should exist) */
@@ -597,6 +601,23 @@
pj_strassign(&hdr->values[hdr->count++], &PATH_NAME);
}
+ /* todo: check for config variable */
+ /* Add some header for mediasec */
+ /* only, if it's the first time - SIP_REGISTRATION_REJECTED_TEMPORARY could be initial, too (retry e.g.) - that's why there is an additional initial_reg */
+ if (client_state->status == SIP_REGISTRATION_UNREGISTERED || client_state->initial_reg) {
+ client_state->initial_reg = 1;
+ ast_sip_add_header(tdata,"Security-Client","sdes-srtp;mediasec");
+ ast_sip_add_header(tdata,"Proxy-Require","mediasec");
+ ast_sip_add_header(tdata,"Require","mediasec");
+ }
+
+ /* answer for 494 */
+ if (client_state->is494) {
+ ast_sip_add_header(tdata,"Security-Verify","msrp-tls;mediasec");
+ ast_sip_add_header(tdata,"Security-Verify","sdes-srtp;mediasec");
+ ast_sip_add_header(tdata,"Security-Verify","dtls-srtp;mediasec");
+ }
+
registration_client_send(client_state, tdata);
return 0;
@@ -918,6 +939,32 @@
ast_debug(1, "Sending authenticated REGISTER to server '%s' from client '%s'\n",
server_uri, client_uri);
pjsip_tx_data_add_ref(tdata);
+
+ /* Add MEDIASEC headers */
+ static const pj_str_t headerName = { "Security-Server", 15 };
+ pjsip_generic_string_hdr *secSrv;
+ secSrv = pjsip_msg_find_hdr_by_name(response->rdata->msg_info.msg, &headerName, NULL);
+ if (secSrv) {
+ response->client_state->is494=0;
+ /* Not needed - they are already there from initial REGISTER
+ ast_sip_add_header(tdata,"Security-Client","sdes-srtp;mediasec");
+ ast_sip_add_header(tdata,"Proxy-Require","mediasec");
+ ast_sip_add_header(tdata,"Require","mediasec"); */
+
+ static const pj_str_t headerNameVrfy = { "Security-Verify", 15 };
+ pjsip_generic_string_hdr *secVrfy;
+ secVrfy = pjsip_msg_find_hdr_by_name(tdata->msg, &headerNameVrfy, NULL);
+
+ /* This happens, if 494 was the reason for the 401 - because the Re-REGISTER already contained it */
+ /* but the original Register didn't contain it - therefore we have to check for the originating Register */
+ if (! secVrfy) {
+ ast_debug(3, "Adding MEDIASEC headers\n");
+ ast_sip_add_header(tdata,"Security-Verify","msrp-tls;mediasec");
+ ast_sip_add_header(tdata,"Security-Verify","sdes-srtp;mediasec");
+ ast_sip_add_header(tdata,"Security-Verify","dtls-srtp;mediasec");
+ }
+ }
+
res = registration_client_send(response->client_state, tdata);
/* Save the cseq that actually got sent. */
@@ -943,6 +990,10 @@
if (response->expiration) {
int next_registration_round;
+ /* following Registers aren't initial-Registers any more */
+ response->client_state->initial_reg=0;
+ response->client_state->is494=0;
+
/* If the registration went fine simply reschedule registration for the future */
ast_debug(1, "Outbound registration to '%s' with client '%s' successful\n", server_uri, client_uri);
update_client_state_status(response->client_state, SIP_REGISTRATION_REGISTERED);
@@ -959,6 +1010,10 @@
response->client_state->registration_name);
} else {
ast_debug(1, "Outbound unregistration to '%s' with client '%s' successful\n", server_uri, client_uri);
+ /* following Registers are initial-Registers */
+ response->client_state->initial_reg=1;
+ response->client_state->is494=0;
+
update_client_state_status(response->client_state, SIP_REGISTRATION_UNREGISTERED);
ast_sip_transport_monitor_unregister(response->rdata->tp_info.transport,
registration_transport_shutdown_cb, response->client_state->registration_name,
@@ -966,6 +1021,20 @@
}
} else if (response->client_state->destroy) {
/* We need to deal with the pending destruction instead. */
+ } else if (response->code == 494) {
+ if (response->client_state->is494) {
+ ast_log(LOG_WARNING, "MEDIASEC registration to '%s' with client '%s' failed (494-loop detected), stopping registration attempt\n",
+ server_uri, client_uri);
+ /* 494 loop detected! This is fatal! */
+ update_client_state_status(response->client_state, SIP_REGISTRATION_REJECTED_PERMANENT);
+ /* reset is494 */
+ response->client_state->is494=0;
+ } else {
+ /* Try (initial) registration again - but now with additional headers */
+ response->client_state->is494=1;
+ handle_client_registration(response->client_state);
+ return 0;
+ }
} else if (response->retry_after) {
/* If we have been instructed to retry after a period of time, schedule it as such */
schedule_retry(response, response->retry_after, server_uri, client_uri);
diff -urN asterisk-16.3.0.orig/res/res_pjsip_sdp_rtp.c asterisk-16.3.0/res/res_pjsip_sdp_rtp.c
--- asterisk-16.3.0.orig/res/res_pjsip_sdp_rtp.c 2019-04-04 16:49:57.000000000 +0200
+++ asterisk-16.3.0/res/res_pjsip_sdp_rtp.c 2019-05-27 04:13:23.769000000 +0200
@@ -1418,6 +1418,7 @@
static const pj_str_t STR_PASSIVE = { "passive", 7 };
static const pj_str_t STR_ACTPASS = { "actpass", 7 };
static const pj_str_t STR_HOLDCONN = { "holdconn", 8 };
+ static const pj_str_t STR_MEDSECREQ = { "requested", 9 };
enum ast_rtp_dtls_setup setup;
switch (session_media->encryption) {
@@ -1433,6 +1434,8 @@
}
tmp = session_media->srtp;
+ attr = pjmedia_sdp_attr_create(pool, "3ge2ae", &STR_MEDSECREQ);
+ media->attr[media->attr_count++] = attr;
do {
crypto_attribute = ast_sdp_srtp_get_attrib(tmp,
diff -urN asterisk-16.3.0.orig/res/res_pjsip_session.c asterisk-16.3.0/res/res_pjsip_session.c
--- asterisk-16.3.0.orig/res/res_pjsip_session.c 2019-04-04 16:49:57.000000000 +0200
+++ asterisk-16.3.0/res/res_pjsip_session.c 2019-06-01 02:16:49.019000000 +0200
@@ -2109,6 +2109,13 @@
return -1;
}
+ if (session->endpoint->media.rtp.encryption == AST_SIP_MEDIA_ENCRYPT_SDES) {
+ ast_debug(3, "INVITE: Adding MEDIASEC headers\n");
+ ast_sip_add_header(*tdata,"Security-Verify","msrp-tls;mediasec");
+ ast_sip_add_header(*tdata,"Security-Verify","sdes-srtp;mediasec");
+ ast_sip_add_header(*tdata,"Security-Verify","dtls-srtp;mediasec");
+ }
+
return 0;
}
--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --
asterisk-dev mailing list
To UNSUBSCRIBE or update options visit:
http://lists.digium.com/mailman/listinfo/asterisk-dev