[Asterisk-code-review] res_pjsip_session: Use Caller ID for extension matching. (asterisk[master])

N A asteriskteam at digium.com
Sat Nov 26 06:58:09 CST 2022


N A has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/19604 )


Change subject: res_pjsip_session: Use Caller ID for extension matching.
......................................................................

res_pjsip_session: Use Caller ID for extension matching.

Currently, there is no Caller ID available to us when
checking for an extension match when handling INVITEs.
As a result, extension patterns that depend on the Caller ID
are not matched and calls may be incorrectly rejected.

The Caller ID is not available because the supplement that
adds Caller ID to the session does not execute until after
this check. Supplement callbacks cannot yet be executed
at this point since the session is not yet in the appropriate
state.

To fix this without impacting existing behavior, the Caller ID
number is now retrieved before attempting to pattern match.
This ensures pattern matching works correctly and there is
no behavior change to the way supplements are called.

ASTERISK-28767 #close

Change-Id: Iec7f5a3b90e51b65ccf74342f96bf80314b7cfc7
---
M res/res_pjsip_session.c
1 file changed, 100 insertions(+), 2 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/04/19604/1

diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index c5890e0..04a24ec 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -3641,6 +3641,74 @@
 	return session;
 }
 
+static pjsip_fromto_hdr *get_id_header(pjsip_rx_data *rdata, const pj_str_t *header_name)
+{
+	static const pj_str_t from = { "From", 4 };
+	pj_str_t header_content;
+	pjsip_fromto_hdr *parsed_hdr;
+	pjsip_generic_string_hdr *ident = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, header_name, NULL);
+	int parsed_len;
+
+	if (!ident) {
+		return NULL;
+	}
+
+	pj_strdup_with_null(rdata->tp_info.pool, &header_content, &ident->hvalue);
+	parsed_hdr = pjsip_parse_hdr(rdata->tp_info.pool, &from, header_content.ptr,
+			pj_strlen(&header_content), &parsed_len);
+
+	return parsed_hdr;
+}
+
+static int set_id_from_hdr(pjsip_fromto_hdr *hdr, char *buf, size_t len)
+{
+	char cid_num[AST_CHANNEL_NAME];
+
+	if (!hdr) {
+		return -1;
+	}
+
+	ast_copy_pj_str(cid_num, ast_sip_pjsip_uri_get_username(hdr->uri), sizeof(cid_num));
+
+	/* Always truncate caller-id number at a semicolon. */
+	AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(cid_num);
+
+	if (ast_strlen_zero(cid_num)) {
+		return -1;
+	}
+
+	ast_copy_string(buf, cid_num, len);
+	return 0;
+}
+
+/*! \brief Fetch just the Caller ID number in order of PAI, RPID, From */
+static int fetch_callerid_num(struct ast_sip_session *session, pjsip_rx_data *rdata, char *buf, size_t len)
+{
+	/* The Caller ID supplement hasn't yet been called to fill in the session ID,
+	 * and we can't execute the supplement earlier than we do,
+	 * so minimally grab the number so dialplan pattern matching against Caller ID number works. */
+	pjsip_fromto_hdr *from, *pai, *rpid;
+	static const pj_str_t pai_str = { "P-Asserted-Identity", 19 };
+	static const pj_str_t rpid_str = { "Remote-Party-ID", 15 };
+
+	if (session->endpoint->id.trust_inbound) {
+		pai = get_id_header(rdata, &pai_str);
+		if (!set_id_from_hdr(pai, buf, len)) {
+			return 0;
+		}
+		rpid = get_id_header(rdata, &rpid_str);
+		if (!set_id_from_hdr(rpid, buf, len)) {
+			return 0;
+		}
+	}
+	if (session->endpoint->id.self.number.valid) {
+		ast_copy_string(buf, session->endpoint->id.self.number.str, len);
+		return 0;
+	}
+	from = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_FROM, rdata->msg_info.msg->hdr.next);
+	return set_id_from_hdr(from, buf, len);
+}
+
 enum sip_get_destination_result {
 	/*! The extension was successfully found */
 	SIP_GET_DEST_EXTEN_FOUND,
@@ -3664,6 +3732,7 @@
  */
 static enum sip_get_destination_result get_destination(struct ast_sip_session *session, pjsip_rx_data *rdata)
 {
+	char cid_num[AST_CHANNEL_NAME];
 	pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
 	struct ast_features_pickup_config *pickup_cfg;
 	const char *pickupexten;
@@ -3690,8 +3759,10 @@
 		ao2_ref(pickup_cfg, -1);
 	}
 
+	fetch_callerid_num(session, rdata, cid_num, sizeof(cid_num));
+
 	if (!strcmp(session->exten, pickupexten) ||
-		ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, NULL)) {
+		ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, S_OR(cid_num, NULL))) {
 		/*
 		 * Save off the INVITE Request-URI in case it is
 		 * needed: CHANNEL(pjsip,request_uri)
@@ -3706,7 +3777,7 @@
 	 */
 	if (session->endpoint->allow_overlap && (
 		!strncmp(session->exten, pickupexten, strlen(session->exten)) ||
-		ast_canmatch_extension(NULL, session->endpoint->context, session->exten, 1, NULL))) {
+		ast_canmatch_extension(NULL, session->endpoint->context, session->exten, 1, S_OR(cid_num, NULL)))) {
 		/* Overlap partial match */
 		return SIP_GET_DEST_EXTEN_PARTIAL;
 	}

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/19604
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: Iec7f5a3b90e51b65ccf74342f96bf80314b7cfc7
Gerrit-Change-Number: 19604
Gerrit-PatchSet: 1
Gerrit-Owner: N A <asterisk at phreaknet.org>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20221126/730fcb9e/attachment.html>


More information about the asterisk-code-review mailing list