STIR/SHAKEN: Option split and response codes.

The stir_shaken configuration option now has 4 different choices to pick
from: off, attest, verify, and on. Off and on behave the same way they
do now. Attest will only perform attestation on the endpoint, and verify
will only perform verification on the endpoint.

Certain responses are required to be sent based on certain conditions
for STIR/SHAKEN. For example, if we get a Date header that is outside of
the time range that is considered valid, a 403 Stale Date response
should be sent. This and several other responses have been added.

Change-Id: I4ac1ecf652cd0e336006b0ca638dc826b5b1ebf7
This commit is contained in:
Ben Ford
2021-09-21 12:09:10 -05:00
committed by Friendly Automation
parent a203769c9d
commit 2e55c0fded
7 changed files with 420 additions and 114 deletions

View File

@@ -717,6 +717,44 @@ static int media_encryption_to_str(const void *obj, const intptr_t *args, char *
return 0;
}
static int stir_shaken_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
struct ast_sip_endpoint *endpoint = obj;
if (!strcasecmp("off", var->value)) {
endpoint->stir_shaken = AST_SIP_STIR_SHAKEN_OFF;
} else if (!strcasecmp("attest", var->value)) {
endpoint->stir_shaken = AST_SIP_STIR_SHAKEN_ATTEST;
} else if (!strcasecmp("verify", var->value)) {
endpoint->stir_shaken = AST_SIP_STIR_SHAKEN_VERIFY;
} else if (!strcasecmp("on", var->value)) {
endpoint->stir_shaken = AST_SIP_STIR_SHAKEN_ON;
} else {
ast_log(LOG_WARNING, "'%s' is not a valid value for option "
"'stir_shaken' for endpoint %s\n",
var->value, ast_sorcery_object_get_id(endpoint));
return -1;
}
return 0;
}
static const char *stir_shaken_map[] = {
[AST_SIP_STIR_SHAKEN_OFF] "off",
[AST_SIP_STIR_SHAKEN_ATTEST] = "attest",
[AST_SIP_STIR_SHAKEN_VERIFY] = "verify",
[AST_SIP_STIR_SHAKEN_ON] = "on",
};
static int stir_shaken_to_str(const void *obj, const intptr_t *args, char **buf)
{
const struct ast_sip_endpoint *endpoint = obj;
if (ARRAY_IN_BOUNDS(endpoint->stir_shaken, stir_shaken_map)) {
*buf = ast_strdup(stir_shaken_map[endpoint->stir_shaken]);
}
return 0;
}
static int group_handler(const struct aco_option *opt,
struct ast_variable *var, void *obj)
{
@@ -2153,7 +2191,7 @@ int ast_res_pjsip_initialize_configuration(void)
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "codec_prefs_outgoing_answer",
"prefer: pending, operation: intersect, keep: all",
codec_prefs_handler, outgoing_answer_codec_prefs_to_str, NULL, 0, 0);
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "stir_shaken", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, stir_shaken));
ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "stir_shaken", "off", stir_shaken_handler, stir_shaken_to_str, NULL, 0, 0);
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_unauthenticated_options", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allow_unauthenticated_options));
if (ast_sip_initialize_sorcery_transport()) {