]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_stir_shaken: Allow missing or anonymous CID to continue to the dialplan.
authorGeorge Joseph <gjoseph@sangoma.com>
Wed, 5 Feb 2025 17:33:10 +0000 (10:33 -0700)
committerAsterisk Development Team <asteriskteam@digium.com>
Thu, 20 Mar 2025 18:29:21 +0000 (18:29 +0000)
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
(cherry picked from commit 71551013c413189179cc481861c3789c169d107f)

include/asterisk/res_stir_shaken.h
res/res_pjsip_stir_shaken.c
res/res_stir_shaken/verification.c

index 81e330c41dfecc74b00125774989ebafa6777606..7db676fc56c17517e7c779ab44709c19d0557bac 100644 (file)
@@ -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
  *
index f64152f3a23319672ab25703e9f5d41fa3693982..ea498942ebbef48e7e8777b71e7d9fa52bbc3029 100644 (file)
@@ -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,
index 6e8366585c5a3671ee5da0a416d9b3df2da98d4b..f6609e6236cc6e16a74b64e1c02c8f74ab12a020 100644 (file)
@@ -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) {