res_stir_shaken: Allow missing or anonymous CID to continue to the dialplan.

The verification check for missing or anonymous callerid was happening before
the endpoint's profile was retrieved which meant that the failure_action
parameter wasn't available.  Therefore, if verification was enabled and there
was no callerid or it was "anonymous", the call was immediately terminated
instead of giving the dialplan the ability to decide what to do with the call.

* The callerid check now happens after the verification context is created and
  the endpoint's stir_shaken_profile is available.

* The check now processes the callerid failure just as it does for other
  verification failures and respects the failure_action parameter.  If set
  to "continue" or "continue_return_reason", `STIR_SHAKEN(0,verify_result)`
  in the dialplan will return "invalid_or_no_callerid".

* If the endpoint's failure_action is "reject_request", the call will be
  rejected with `433 "Anonymity Disallowed"`.

* If the endpoint's failure_action is "continue_return_reason", the call will
  continue but a `Reason: STIR; cause=433; text="Anonymity Disallowed"`
  header will be added to the next provisional or final response.

Resolves: #1112
pull/1121/head
George Joseph 3 months ago committed by github-actions[bot]
parent 3e74da3224
commit d558818ec1

@ -55,6 +55,7 @@ enum ast_stir_shaken_vs_response_code {
AST_STIR_SHAKEN_VS_NO_DEST_TN,
AST_STIR_SHAKEN_VS_INVALID_HEADER,
AST_STIR_SHAKEN_VS_INVALID_GRANT,
AST_STIR_SHAKEN_VS_INVALID_OR_NO_CID,
AST_STIR_SHAKEN_VS_RESPONSE_CODE_MAX
};
@ -233,6 +234,16 @@ enum stir_shaken_failure_action_enum
int ast_stir_shaken_vs_get_use_rfc9410_responses(
struct ast_stir_shaken_vs_ctx *ctx);
/*!
* \brief Get caller_id from context
*
* \param ctx VS context
*
* \retval Caller ID or NULL
*/
const char *ast_stir_shaken_vs_get_caller_id(
struct ast_stir_shaken_vs_ctx *ctx);
/*!
* \brief Add a STIR/SHAKEN verification result to a channel
*

@ -44,10 +44,10 @@ enum sip_response_code {
SIP_RESPONSE_CODE_OK = 200,
SIP_RESPONSE_CODE_STALE_DATE = 403,
SIP_RESPONSE_CODE_USE_IDENTITY_HEADER = 428,
SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED = 433,
SIP_RESPONSE_CODE_BAD_IDENTITY_INFO = 436,
SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL = 437,
SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER = 438,
SIP_RESPONSE_CODE_USE_SUPPORTED_PASSPORT_FORMAT = 428,
SIP_RESPONSE_CODE_INTERNAL_ERROR = 500,
};
@ -55,7 +55,7 @@ enum sip_response_code {
/* Response strings from RFC8224 */
#define SIP_RESPONSE_CODE_STALE_DATE_STR "Stale Date"
#define SIP_RESPONSE_CODE_USE_IDENTITY_HEADER_STR "Use Identity Header"
#define SIP_RESPONSE_CODE_USE_SUPPORTED_PASSPORT_FORMAT_STR "Use Supported PASSporT Format"
#define SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED_STR "Anonymity Disallowed"
#define SIP_RESPONSE_CODE_BAD_IDENTITY_INFO_STR "Bad Identity Info"
#define SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL_STR "Unsupported Credential"
#define SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER_STR "Invalid Identity Header"
@ -71,6 +71,7 @@ static const char *sip_response_code_to_str(enum sip_response_code code)
response_to_str(SIP_RESPONSE_CODE_OK)
response_to_str(SIP_RESPONSE_CODE_STALE_DATE)
response_to_str(SIP_RESPONSE_CODE_USE_IDENTITY_HEADER)
response_to_str(SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED)
response_to_str(SIP_RESPONSE_CODE_BAD_IDENTITY_INFO)
response_to_str(SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL)
response_to_str(SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER)
@ -127,6 +128,7 @@ static enum sip_response_code vs_code_to_sip_code(
translate_code(INVALID_GRANT, INVALID_IDENTITY_HEADER)
translate_code(INVALID_OR_NO_GRANTS, INVALID_IDENTITY_HEADER)
translate_code(CID_ORIG_TN_MISMATCH, INVALID_IDENTITY_HEADER)
translate_code(INVALID_OR_NO_CID, ANONYMITY_DISALLOWED)
translate_code(RESPONSE_CODE_MAX, INVALID_IDENTITY_HEADER)
}
@ -227,12 +229,10 @@ static int stir_shaken_incoming_request(struct ast_sip_session *session, pjsip_r
}
/*
* Shortcut: If there's no callerid or profile name,
* just bail now.
* Shortcut: If there's no profile name just bail now.
*/
if (ast_strlen_zero(caller_id)
|| ast_strlen_zero(session->endpoint->stir_shaken_profile)) {
SCOPE_EXIT_RTN_VALUE(0, "%s: No callerid or profile name. No action needed\n", session_name);
if (ast_strlen_zero(session->endpoint->stir_shaken_profile)) {
SCOPE_EXIT_RTN_VALUE(0, "%s: No profile name on endpoint. No action needed\n", session_name);
}
vs_rc = ast_stir_shaken_vs_ctx_create(caller_id, chan,
@ -246,6 +246,17 @@ static int stir_shaken_incoming_request(struct ast_sip_session *session, pjsip_r
session_name);
}
if (ast_strlen_zero(ast_stir_shaken_vs_get_caller_id(ctx))) {
p_rc = process_failure(ctx, caller_id, session, rdata,
AST_STIR_SHAKEN_VS_INVALID_OR_NO_CID);
if (p_rc == PROCESS_FAILURE_CONTINUE) {
SCOPE_EXIT_RTN_VALUE(0, "%s: Invalid or no callerid found. Call continuing\n",
session_name);
}
SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Invalid or no callerid found. Call terminated\n",
session_name);
}
identity_hdr_val = ast_sip_rdata_get_header_value(rdata, identity_hdr_str);
if (ast_strlen_zero(identity_hdr_val)) {
p_rc = process_failure(ctx, caller_id, session, rdata,

@ -84,6 +84,7 @@ static const char *vs_rc_map[] = {
[AST_STIR_SHAKEN_VS_NO_DEST_TN] = "missing_dest_tn",
[AST_STIR_SHAKEN_VS_INVALID_HEADER] = "invalid_header",
[AST_STIR_SHAKEN_VS_INVALID_GRANT] = "invalid_grant",
[AST_STIR_SHAKEN_VS_INVALID_OR_NO_CID] = "invalid_or_no_callerid",
};
const char *vs_response_code_to_str(
@ -629,6 +630,12 @@ int ast_stir_shaken_vs_get_use_rfc9410_responses(
return ctx->eprofile->vcfg_common.use_rfc9410_responses;
}
const char *ast_stir_shaken_vs_get_caller_id(
struct ast_stir_shaken_vs_ctx *ctx)
{
return ctx->caller_id;
}
void ast_stir_shaken_vs_ctx_set_response_code(
struct ast_stir_shaken_vs_ctx *ctx,
enum ast_stir_shaken_vs_response_code vs_rc)
@ -687,11 +694,6 @@ enum ast_stir_shaken_vs_response_code
LOG_ERROR, "%s: Must provide tag\n", t);
}
if (ast_strlen_zero(canon_caller_id)) {
SCOPE_EXIT_LOG_RTN_VALUE(AST_STIR_SHAKEN_VS_INVALID_ARGUMENTS,
LOG_ERROR, "%s: Must provide caller_id\n", t);
}
ctx = ao2_alloc_options(sizeof(*ctx), ctx_destructor,
AO2_ALLOC_OPT_LOCK_NOLOCK);
if (!ctx) {

Loading…
Cancel
Save