Skip to content

Commit c406687

Browse files
InterLinked1Friendly Automation
authored and
Friendly Automation
committed
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
1 parent f86d2a2 commit c406687

File tree

4 files changed

+271
-226
lines changed

4 files changed

+271
-226
lines changed

include/asterisk/res_pjsip.h

+19
Original file line numberDiff line numberDiff line change
@@ -3603,6 +3603,25 @@ struct ast_sip_service_route_vector *ast_sip_service_route_vector_alloc(void);
36033603
*/
36043604
void ast_sip_service_route_vector_destroy(struct ast_sip_service_route_vector *service_routes);
36053605

3606+
/*!
3607+
* \brief Set the ID for a connected line update
3608+
*
3609+
* \retval -1 on failure, 0 on success
3610+
*/
3611+
int ast_sip_set_id_connected_line(struct pjsip_rx_data *rdata, struct ast_party_id *id);
3612+
3613+
/*!
3614+
* \brief Set the ID from an INVITE
3615+
*
3616+
* \param rdata
3617+
* \param id ID structure to fill
3618+
* \param default_id Default ID structure with data to use (for non-trusted endpoints)
3619+
* \param trusted_inbound Whether or not the endpoint is trusted (controls whether PAI or RPID can be used)
3620+
*
3621+
* \retval -1 on failure, 0 on success
3622+
*/
3623+
int ast_sip_set_id_from_invite(struct pjsip_rx_data *rdata, struct ast_party_id *id, struct ast_party_id *default_id, int trust_inbound);
3624+
36063625
/*!
36073626
* \brief Set name and number information on an identity header.
36083627
*

res/res_pjsip.c

+229
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "asterisk/sorcery.h"
4242
#include "asterisk/file.h"
4343
#include "asterisk/cli.h"
44+
#include "asterisk/callerid.h"
4445
#include "asterisk/res_pjsip_cli.h"
4546
#include "asterisk/test.h"
4647
#include "asterisk/res_pjsip_presence_xml.h"
@@ -2449,6 +2450,234 @@ int ast_sip_call_codec_str_to_pref(struct ast_flags *pref, const char *pref_str,
24492450
return 0;
24502451
}
24512452

2453+
/*!
2454+
* \internal
2455+
* \brief Set an ast_party_id name and number based on an identity header.
2456+
* \param hdr From, P-Asserted-Identity, or Remote-Party-ID header on incoming message
2457+
* \param[out] id The ID to set data on
2458+
*/
2459+
static void set_id_from_hdr(pjsip_fromto_hdr *hdr, struct ast_party_id *id)
2460+
{
2461+
char cid_name[AST_CHANNEL_NAME];
2462+
char cid_num[AST_CHANNEL_NAME];
2463+
pjsip_name_addr *id_name_addr = (pjsip_name_addr *) hdr->uri;
2464+
char *semi;
2465+
2466+
ast_copy_pj_str(cid_name, &id_name_addr->display, sizeof(cid_name));
2467+
ast_copy_pj_str(cid_num, ast_sip_pjsip_uri_get_username(hdr->uri), sizeof(cid_num));
2468+
2469+
/* Always truncate caller-id number at a semicolon. */
2470+
semi = strchr(cid_num, ';');
2471+
if (semi) {
2472+
/*
2473+
* We need to be able to handle URI's looking like
2474+
* "sip:1235557890;phone-context=national@x.x.x.x;user=phone"
2475+
*
2476+
* Where the uri->user field will result in:
2477+
* "1235557890;phone-context=national"
2478+
*
2479+
* People don't care about anything after the semicolon
2480+
* showing up on their displays even though the RFC
2481+
* allows the semicolon.
2482+
*/
2483+
*semi = '\0';
2484+
}
2485+
2486+
ast_free(id->name.str);
2487+
id->name.str = ast_strdup(cid_name);
2488+
if (!ast_strlen_zero(cid_name)) {
2489+
id->name.valid = 1;
2490+
}
2491+
ast_free(id->number.str);
2492+
id->number.str = ast_strdup(cid_num);
2493+
if (!ast_strlen_zero(cid_num)) {
2494+
id->number.valid = 1;
2495+
}
2496+
}
2497+
2498+
/*!
2499+
* \internal
2500+
* \brief Get a P-Asserted-Identity or Remote-Party-ID header from an incoming message
2501+
*
2502+
* This function will parse the header as if it were a From header. This allows for us
2503+
* to easily manipulate the URI, as well as add, modify, or remove parameters from the
2504+
* header
2505+
*
2506+
* \param rdata The incoming message
2507+
* \param header_name The name of the ID header to find
2508+
* \retval NULL No ID header present or unable to parse ID header
2509+
* \retval non-NULL The parsed ID header
2510+
*/
2511+
static pjsip_fromto_hdr *get_id_header(pjsip_rx_data *rdata, const pj_str_t *header_name)
2512+
{
2513+
static const pj_str_t from = { "From", 4 };
2514+
pj_str_t header_content;
2515+
pjsip_fromto_hdr *parsed_hdr;
2516+
pjsip_generic_string_hdr *ident = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
2517+
header_name, NULL);
2518+
int parsed_len;
2519+
2520+
if (!ident) {
2521+
return NULL;
2522+
}
2523+
2524+
pj_strdup_with_null(rdata->tp_info.pool, &header_content, &ident->hvalue);
2525+
2526+
parsed_hdr = pjsip_parse_hdr(rdata->tp_info.pool, &from, header_content.ptr,
2527+
pj_strlen(&header_content), &parsed_len);
2528+
2529+
if (!parsed_hdr) {
2530+
return NULL;
2531+
}
2532+
2533+
return parsed_hdr;
2534+
}
2535+
2536+
/*!
2537+
* \internal
2538+
* \brief Set an ast_party_id structure based on data in a P-Asserted-Identity header
2539+
*
2540+
* This makes use of \ref set_id_from_hdr for setting name and number. It uses
2541+
* the contents of a Privacy header in order to set presentation information.
2542+
*
2543+
* \param rdata The incoming message
2544+
* \param[out] id The ID to set
2545+
* \retval 0 Successfully set the party ID
2546+
* \retval non-zero Could not set the party ID
2547+
*/
2548+
static int set_id_from_pai(pjsip_rx_data *rdata, struct ast_party_id *id)
2549+
{
2550+
static const pj_str_t pai_str = { "P-Asserted-Identity", 19 };
2551+
static const pj_str_t privacy_str = { "Privacy", 7 };
2552+
pjsip_fromto_hdr *pai_hdr = get_id_header(rdata, &pai_str);
2553+
pjsip_generic_string_hdr *privacy;
2554+
2555+
if (!pai_hdr) {
2556+
return -1;
2557+
}
2558+
2559+
set_id_from_hdr(pai_hdr, id);
2560+
2561+
if (!id->number.valid) {
2562+
return -1;
2563+
}
2564+
2565+
privacy = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &privacy_str, NULL);
2566+
if (!privacy || !pj_stricmp2(&privacy->hvalue, "none")) {
2567+
id->number.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
2568+
id->name.presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
2569+
} else {
2570+
id->number.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
2571+
id->name.presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
2572+
}
2573+
2574+
return 0;
2575+
}
2576+
2577+
/*!
2578+
* \internal
2579+
* \brief Set an ast_party_id structure based on data in a Remote-Party-ID header
2580+
*
2581+
* This makes use of \ref set_id_from_hdr for setting name and number. It uses
2582+
* the privacy and screen parameters in order to set presentation information.
2583+
*
2584+
* \param rdata The incoming message
2585+
* \param[out] id The ID to set
2586+
* \retval 0 Succesfully set the party ID
2587+
* \retval non-zero Could not set the party ID
2588+
*/
2589+
static int set_id_from_rpid(pjsip_rx_data *rdata, struct ast_party_id *id)
2590+
{
2591+
static const pj_str_t rpid_str = { "Remote-Party-ID", 15 };
2592+
static const pj_str_t privacy_str = { "privacy", 7 };
2593+
static const pj_str_t screen_str = { "screen", 6 };
2594+
pjsip_fromto_hdr *rpid_hdr = get_id_header(rdata, &rpid_str);
2595+
pjsip_param *screen;
2596+
pjsip_param *privacy;
2597+
2598+
if (!rpid_hdr) {
2599+
return -1;
2600+
}
2601+
2602+
set_id_from_hdr(rpid_hdr, id);
2603+
2604+
if (!id->number.valid) {
2605+
return -1;
2606+
}
2607+
2608+
privacy = pjsip_param_find(&rpid_hdr->other_param, &privacy_str);
2609+
screen = pjsip_param_find(&rpid_hdr->other_param, &screen_str);
2610+
if (privacy && !pj_stricmp2(&privacy->value, "full")) {
2611+
id->number.presentation = AST_PRES_RESTRICTED;
2612+
id->name.presentation = AST_PRES_RESTRICTED;
2613+
} else {
2614+
id->number.presentation = AST_PRES_ALLOWED;
2615+
id->name.presentation = AST_PRES_ALLOWED;
2616+
}
2617+
if (screen && !pj_stricmp2(&screen->value, "yes")) {
2618+
id->number.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
2619+
id->name.presentation |= AST_PRES_USER_NUMBER_PASSED_SCREEN;
2620+
} else {
2621+
id->number.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
2622+
id->name.presentation |= AST_PRES_USER_NUMBER_UNSCREENED;
2623+
}
2624+
2625+
return 0;
2626+
}
2627+
2628+
/*!
2629+
* \internal
2630+
* \brief Set an ast_party_id structure based on data in a From
2631+
*
2632+
* This makes use of \ref set_id_from_hdr for setting name and number. It uses
2633+
* no information from the message in order to set privacy. It relies on endpoint
2634+
* configuration for privacy information.
2635+
*
2636+
* \param rdata The incoming message
2637+
* \param[out] id The ID to set
2638+
* \retval 0 Succesfully set the party ID
2639+
* \retval non-zero Could not set the party ID
2640+
*/
2641+
static int set_id_from_from(struct pjsip_rx_data *rdata, struct ast_party_id *id)
2642+
{
2643+
pjsip_fromto_hdr *from = pjsip_msg_find_hdr(rdata->msg_info.msg,
2644+
PJSIP_H_FROM, rdata->msg_info.msg->hdr.next);
2645+
2646+
if (!from) {
2647+
/* This had better not happen */
2648+
return -1;
2649+
}
2650+
2651+
set_id_from_hdr(from, id);
2652+
2653+
if (!id->number.valid) {
2654+
return -1;
2655+
}
2656+
2657+
return 0;
2658+
}
2659+
2660+
int ast_sip_set_id_connected_line(struct pjsip_rx_data *rdata, struct ast_party_id *id)
2661+
{
2662+
return !set_id_from_pai(rdata, id) || !set_id_from_rpid(rdata, id) ? 0 : -1;
2663+
}
2664+
2665+
int ast_sip_set_id_from_invite(struct pjsip_rx_data *rdata, struct ast_party_id *id, struct ast_party_id *default_id, int trust_inbound)
2666+
{
2667+
if (trust_inbound && (!set_id_from_pai(rdata, id) || !set_id_from_rpid(rdata, id))) {
2668+
/* Trusted: Check PAI and RPID */
2669+
ast_free(id->tag);
2670+
id->tag = ast_strdup(default_id->tag);
2671+
return 0;
2672+
}
2673+
/* Not trusted: check the endpoint config or use From. */
2674+
ast_party_id_copy(id, default_id);
2675+
if (!default_id->number.valid) {
2676+
set_id_from_from(rdata, id);
2677+
}
2678+
return 0;
2679+
}
2680+
24522681
/*!
24532682
* \brief Set name and number information on an identity header.
24542683
*

0 commit comments

Comments
 (0)