Asterisk - The Open Source Telephony Project GIT-master-7e7a603
res_pjsip_stir_shaken.c
Go to the documentation of this file.
1/*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2020, Sangoma Technologies Corporation
5 *
6 * Ben Ford <bford@sangoma.com>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18
19/*** MODULEINFO
20 <depend>pjproject</depend>
21 <depend>res_pjsip</depend>
22 <depend>res_pjsip_session</depend>
23 <depend>res_stir_shaken</depend>
24 <support_level>core</support_level>
25 ***/
26
27#include "asterisk.h"
28
29#define _TRACE_PREFIX_ "pjss",__LINE__, ""
30
31#include "asterisk/callerid.h"
32#include "asterisk/res_pjsip.h"
34#include "asterisk/module.h"
35#include "asterisk/rtp_engine.h"
36
38
39static const pj_str_t identity_hdr_str = { "Identity", 8 };
40static const pj_str_t date_hdr_str = { "Date", 4 };
41
42/* Response codes from RFC8224 */
52};
53
54#define SIP_RESPONSE_CODE_OK_STR "OK"
55/* Response strings from RFC8224 */
56#define SIP_RESPONSE_CODE_STALE_DATE_STR "Stale Date"
57#define SIP_RESPONSE_CODE_USE_IDENTITY_HEADER_STR "Use Identity Header"
58#define SIP_RESPONSE_CODE_USE_SUPPORTED_PASSPORT_FORMAT_STR "Use Supported PASSporT Format"
59#define SIP_RESPONSE_CODE_BAD_IDENTITY_INFO_STR "Bad Identity Info"
60#define SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL_STR "Unsupported Credential"
61#define SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER_STR "Invalid Identity Header"
62#define SIP_RESPONSE_CODE_INTERNAL_ERROR_STR "Internal Error"
63
64#define response_to_str(_code) \
65case _code: \
66 return _code ## _STR;
67
68static const char *sip_response_code_to_str(enum sip_response_code code)
69{
70 switch (code) {
77 default:
78 break;
79 }
80 return "";
81}
82
83#define translate_code(_vs_rc, _sip_rc) \
84case AST_STIR_SHAKEN_VS_ ## _vs_rc: \
85 return SIP_RESPONSE_CODE_ ## _sip_rc;
86
89{
90 /*
91 * We want to use a switch/case statement here because
92 * it'll spit out an error if VS codes are added to the
93 * enum but aren't present here.
94 */
95 switch (vs_rc) {
97 translate_code(DISABLED, OK)
98 translate_code(INVALID_ARGUMENTS, INTERNAL_ERROR)
99 translate_code(INTERNAL_ERROR, INTERNAL_ERROR)
100 translate_code(NO_IDENTITY_HDR, USE_IDENTITY_HEADER)
101 translate_code(NO_DATE_HDR, STALE_DATE)
102 translate_code(DATE_HDR_PARSE_FAILURE, STALE_DATE)
103 translate_code(DATE_HDR_EXPIRED, STALE_DATE)
104 translate_code(NO_JWT_HDR, INVALID_IDENTITY_HEADER)
105 translate_code(INVALID_OR_NO_X5U, INVALID_IDENTITY_HEADER)
106 translate_code(CERT_CACHE_MISS, INVALID_IDENTITY_HEADER)
107 translate_code(CERT_CACHE_INVALID, INVALID_IDENTITY_HEADER)
108 translate_code(CERT_CACHE_EXPIRED, INVALID_IDENTITY_HEADER)
109 translate_code(CERT_RETRIEVAL_FAILURE, BAD_IDENTITY_INFO)
110 translate_code(CERT_CONTENTS_INVALID, UNSUPPORTED_CREDENTIAL)
111 translate_code(CERT_NOT_TRUSTED, UNSUPPORTED_CREDENTIAL)
112 translate_code(CERT_DATE_INVALID, UNSUPPORTED_CREDENTIAL)
113 translate_code(CERT_NO_TN_AUTH_EXT, UNSUPPORTED_CREDENTIAL)
114 translate_code(CERT_NO_SPC_IN_TN_AUTH_EXT, UNSUPPORTED_CREDENTIAL)
115 translate_code(NO_RAW_KEY, UNSUPPORTED_CREDENTIAL)
116 translate_code(SIGNATURE_VALIDATION, INVALID_IDENTITY_HEADER)
117 translate_code(NO_IAT, INVALID_IDENTITY_HEADER)
118 translate_code(IAT_EXPIRED, STALE_DATE)
119 translate_code(INVALID_OR_NO_PPT, INVALID_IDENTITY_HEADER)
120 translate_code(INVALID_OR_NO_ALG, INVALID_IDENTITY_HEADER)
121 translate_code(INVALID_OR_NO_TYP, INVALID_IDENTITY_HEADER)
122 translate_code(INVALID_OR_NO_ATTEST, INVALID_IDENTITY_HEADER)
123 translate_code(NO_ORIGID, INVALID_IDENTITY_HEADER)
124 translate_code(NO_ORIG_TN, INVALID_IDENTITY_HEADER)
125 translate_code(NO_DEST_TN, INVALID_IDENTITY_HEADER)
126 translate_code(INVALID_HEADER, INVALID_IDENTITY_HEADER)
127 translate_code(INVALID_GRANT, INVALID_IDENTITY_HEADER)
128 translate_code(INVALID_OR_NO_GRANTS, INVALID_IDENTITY_HEADER)
129 translate_code(CID_ORIG_TN_MISMATCH, INVALID_IDENTITY_HEADER)
130 translate_code(RESPONSE_CODE_MAX, INVALID_IDENTITY_HEADER)
131 }
132
133 return 500;
134}
135
140};
141
143 enum sip_response_code response_code)
144{
145 ast_sip_session_terminate(session, response_code);
146 ast_hangup(session->channel);
147}
148
150 const char *caller_id, struct ast_sip_session *session,
151 pjsip_rx_data *rdata, enum ast_stir_shaken_vs_response_code vs_rc)
152{
153 enum sip_response_code response_code = vs_code_to_sip_code(vs_rc);
154 pj_str_t response_str;
155 const char *response_string =
156 sip_response_code_to_str(response_code);
157 enum stir_shaken_failure_action_enum failure_action =
159 const char *tag = ast_sip_session_get_name(session);
160 SCOPE_ENTER(1, "%s: FA: %d RC: %d\n", tag,
161 failure_action, response_code);
162
163 pj_cstr(&response_str, response_string);
164
165 if (failure_action == stir_shaken_failure_action_REJECT_REQUEST) {
166 reject_incoming_call(session, response_code);
168 "%s: Rejecting request and terminating session\n",
169 tag);
170 }
171
174
178 response_code, response_str.ptr);
179 if (rc != 0) {
181 "%s: Failed to add Reason header\n", tag);
182 }
184 "%s: Attaching reason code to session\n", tag);
185 }
187 "%s: Continuing\n", tag);
188}
189
190/*!
191 * \internal
192 * \brief Session supplement callback on an incoming INVITE request
193 *
194 * When we receive an INVITE, check it for STIR/SHAKEN information and
195 * decide what to do from there
196 *
197 * \param session The session that has received an INVITE
198 * \param rdata The incoming INVITE
199 */
200static int stir_shaken_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
201{
203 RAII_VAR(char *, header, NULL, ast_free);
204 RAII_VAR(char *, payload, NULL, ast_free);
205 char *identity_hdr_val;
206 char *date_hdr_val;
207 char *caller_id = session->id.number.str;
208 const char *session_name = ast_sip_session_get_name(session);
209 struct ast_channel *chan = session->channel;
211 enum process_failure_rc p_rc;
212 SCOPE_ENTER(1, "%s: Enter\n", session_name);
213
214 if (!session) {
215 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "No session\n");
216 }
217 if (!session->channel) {
218 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No channel\n", session_name);
219 }
220 if (!rdata) {
221 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No rdata\n", session_name);
222 }
223
224 /* Check if this is a reinvite. If it is, we don't need to do anything */
225 if (rdata->msg_info.to->tag.slen) {
226 SCOPE_EXIT_RTN_VALUE(0, "%s: Reinvite. No action needed\n", session_name);
227 }
228
229 /*
230 * Shortcut: If there's no callerid or profile name,
231 * just bail now.
232 */
233 if (ast_strlen_zero(caller_id)
234 || ast_strlen_zero(session->endpoint->stir_shaken_profile)) {
235 SCOPE_EXIT_RTN_VALUE(0, "%s: No callerid or profile name. No action needed\n", session_name);
236 }
237
238 vs_rc = ast_stir_shaken_vs_ctx_create(caller_id, chan,
239 session->endpoint->stir_shaken_profile,
240 session_name, &ctx);
241 if (vs_rc == AST_STIR_SHAKEN_VS_DISABLED) {
242 SCOPE_EXIT_RTN_VALUE(0, "%s: VS Disabled\n", session_name);
243 } else if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
245 SCOPE_EXIT_RTN_VALUE(1, "%s: Unable to create context. Call terminated\n",
246 session_name);
247 }
248
249 identity_hdr_val = ast_sip_rdata_get_header_value(rdata, identity_hdr_str);
250 if (ast_strlen_zero(identity_hdr_val)) {
251 p_rc = process_failure(ctx, caller_id, session, rdata,
253 if (p_rc == PROCESS_FAILURE_CONTINUE) {
254 SCOPE_EXIT_RTN_VALUE(0, "%s: No Identity header found. Call continuing\n",
255 session_name);
256 }
257 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No Identity header found. Call terminated\n",
258 session_name);
259 }
260
261 vs_rc = ast_stir_shaken_vs_ctx_add_identity_hdr(ctx, identity_hdr_val);
262 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
264 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Unable to add Identity header. Call terminated.\n",
265 session_name);
266 }
267
268 date_hdr_val = ast_sip_rdata_get_header_value(rdata, date_hdr_str);
269 if (ast_strlen_zero(date_hdr_val)) {
270 p_rc = process_failure(ctx, caller_id, session, rdata,
272 if (p_rc == PROCESS_FAILURE_CONTINUE) {
273 SCOPE_EXIT_RTN_VALUE(0, "%s: No Date header found. Call continuing\n",
274 session_name);
275 }
276 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No Date header found. Call terminated\n",
277 session_name);
278 }
279
280 ast_stir_shaken_vs_ctx_add_date_hdr(ctx, date_hdr_val);
281 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
283 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Unable to add Date header. Call terminated.\n",
284 session_name);
285 }
286
287 vs_rc = ast_stir_shaken_vs_verify(ctx);
288 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
289 p_rc = process_failure(ctx, caller_id, session, rdata, vs_rc);
290 if (p_rc == PROCESS_FAILURE_CONTINUE) {
291 SCOPE_EXIT_RTN_VALUE(0, "%s: Verification failed. Call continuing\n",
292 session_name);
293 }
294 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Verification failed. Call terminated\n",
295 session_name);
296
297 }
298
300
301 SCOPE_EXIT_RTN_VALUE(0, "Passed\n");
302}
303
305 struct ast_stir_shaken_as_ctx *ctx)
306{
307 struct ast_sip_session_media_state *ms = session->pending_media_state;
308 struct ast_sip_session_media *m = NULL;
309 struct ast_rtp_engine_dtls *d = NULL;
310 enum ast_rtp_dtls_hash h;
311 int i;
312 const char *tag = ast_sip_session_get_name(session);
313 size_t count = AST_VECTOR_SIZE(&ms->sessions);
314 SCOPE_ENTER(4, "%s: Check %zu media sessions for fingerprints\n",
315 tag, count);
316
318 SCOPE_EXIT_RTN("%s: Fingerprints not needed\n", tag);
319 }
320
321 for (i = 0; i < count; i++) {
322 const char *f;
323
324 m = AST_VECTOR_GET(&ms->sessions, i);
325 if (!m|| !m->rtp) {
326 ast_trace(1, "Session: %d: No session or rtp instance\n", i);
327 continue;
328 }
330 h = d->get_fingerprint_hash(m->rtp);
331 f = d->get_fingerprint(m->rtp);
332
334 h == AST_RTP_DTLS_HASH_SHA256 ? "sha-256" : "sha-1", f);
335 }
336 SCOPE_EXIT_RTN("%s: Done\n", tag);
337}
338
339static char *get_dest_tn(pjsip_tx_data *tdata, const char *tag)
340{
341 pjsip_fromto_hdr *to;
342 pjsip_sip_uri *uri;
343 char *dest_tn = NULL;
344 SCOPE_ENTER(4, "%s: Enter\n", tag);
345
346 to = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_TO, NULL);
347 if (!to) {
348 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Failed to find To header\n", tag);
349 }
350
351 uri = pjsip_uri_get_uri(to->uri);
352 if (!uri) {
354 "%s: Failed to retrieve URI from To header\n", tag);
355 }
356
357 dest_tn = ast_malloc(uri->user.slen + 1);
358 if (!dest_tn) {
360 "%s: Failed to allocate memory for dest_tn\n", tag);
361 }
362
363 /* Remove everything except 0-9, *, and # in telephone number according to RFC 8224
364 * (required by RFC 8225 as part of canonicalization) */
365 {
366 int i;
367 const char *s = uri->user.ptr;
368 char *new_tn = dest_tn;
369 /* We're only removing characters, if anything, so the buffer is guaranteed to be large enough */
370 for (i = 0; i < uri->user.slen; i++) {
371 if (isdigit(*s) || *s == '#' || *s == '*') { /* Only characters allowed */
372 *new_tn++ = *s;
373 }
374 s++;
375 }
376 *new_tn = '\0';
377 ast_trace(2, "Canonicalized telephone number " PJSTR_PRINTF_SPEC " -> %s\n",
378 PJSTR_PRINTF_VAR(uri->user), dest_tn);
379 }
380
381 SCOPE_EXIT_RTN_VALUE(dest_tn, "%s: Done\n", tag);
382}
383
384static void add_date_header(const struct ast_sip_session *session, pjsip_tx_data *tdata)
385{
386 pjsip_fromto_hdr *old_date;
387 const char *session_name = ast_sip_session_get_name(session);
388 SCOPE_ENTER(1, "%s: Enter\n", session_name);
389
390 old_date = pjsip_msg_find_hdr_by_name(tdata->msg, &date_hdr_str, NULL);
391 if (old_date) {
392 SCOPE_EXIT_RTN("Found existing Date header, no need to add one\n");
393 }
394
396 SCOPE_EXIT_RTN("Done\n");
397}
398
400 pjsip_tx_data *tdata)
401{
402 struct ast_party_id effective_id;
403 struct ast_party_id connected_id;
404 pjsip_generic_string_hdr *old_identity;
405 pjsip_generic_string_hdr *identity_hdr;
406 pj_str_t identity_val;
407 char *dest_tn;
408 char *identity_str;
409 struct ast_stir_shaken_as_ctx *ctx = NULL;
411 const char *session_name = ast_sip_session_get_name(session);
412 SCOPE_ENTER(1, "%s: Enter\n", session_name);
413
414 if (!session) {
415 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "No session\n");
416 }
417 if (!session->channel) {
418 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: No channel\n", session_name);
419 }
420 if (!tdata) {
421 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: No tdata\n", session_name);
422 }
423
424 old_identity = pjsip_msg_find_hdr_by_name(tdata->msg, &identity_hdr_str, NULL);
425 if (old_identity) {
426 SCOPE_EXIT_RTN("Found an existing Identity header\n");
427 }
428
429 dest_tn = get_dest_tn(tdata, session_name);
430 if (!dest_tn) {
431 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Unable to find destination tn\n",
432 session_name);
433 }
434
435 ast_party_id_init(&connected_id);
436 ast_channel_lock(session->channel);
437 effective_id = ast_channel_connected_effective_id(session->channel);
438 ast_party_id_copy(&connected_id, &effective_id);
439 ast_channel_unlock(session->channel);
440
441 if (!ast_sip_can_present_connected_id(session, &connected_id)) {
443 ast_party_id_free(&connected_id);
444 SCOPE_EXIT_RTN("Unable to get caller id\n");
445 }
446
447 as_rc = ast_stir_shaken_as_ctx_create(connected_id.number.str,
448 dest_tn, session->channel,
449 session->endpoint->stir_shaken_profile,
450 session_name, &ctx);
451
453 ast_party_id_free(&connected_id);
454
455 if (as_rc == AST_STIR_SHAKEN_AS_DISABLED) {
456 SCOPE_EXIT_RTN("%s: AS Disabled\n", session_name);
457 } else if (as_rc != AST_STIR_SHAKEN_AS_SUCCESS) {
458 SCOPE_EXIT_RTN("%s: Unable to create context\n",
459 session_name);
460 }
461
462 add_date_header(session, tdata);
464
465 as_rc = ast_stir_shaken_attest(ctx, &identity_str);
466 if (as_rc != AST_STIR_SHAKEN_AS_SUCCESS) {
467 ao2_cleanup(ctx);
469 "%s: Failed to create attestation\n", session_name);
470 }
471
472 ast_trace(1, "%s: Identity header: %s\n", session_name, identity_str);
473 identity_val = pj_str(identity_str);
474 identity_hdr = pjsip_generic_string_hdr_create(tdata->pool, &identity_hdr_str, &identity_val);
475 ast_free(identity_str);
476 if (!identity_hdr) {
477 ao2_cleanup(ctx);
479 "%s: Unable to create Identity header\n", session_name);
480 }
481
482 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)identity_hdr);
483
484 ao2_cleanup(ctx);
485 SCOPE_EXIT_RTN("Done\n");
486}
487
489 .method = "INVITE",
490 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1, /* Run AFTER channel creation */
491 .incoming_request = stir_shaken_incoming_request,
492 .outgoing_request = stir_shaken_outgoing_request,
493};
494
495static int unload_module(void)
496{
498 return 0;
499}
500
501static int load_module(void)
502{
505}
506
507#undef AST_BUILDOPT_SUM
508#define AST_BUILDOPT_SUM ""
509
511 .support_level = AST_MODULE_SUPPORT_CORE,
512 .load = load_module,
513 .unload = unload_module,
514 .load_pri = AST_MODPRI_DEFAULT,
515 .requires = "res_pjsip,res_pjsip_session,res_stir_shaken",
Asterisk main include file. File version handling, generic pbx functions.
static struct ast_mansession session
#define ast_free(a)
Definition: astmm.h:180
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:1757
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541
#define ast_channel_lock(chan)
Definition: channel.h:2922
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
Definition: channel.c:1811
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition: channel.c:1765
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2923
#define SCOPE_EXIT_LOG(__log_level,...)
#define SCOPE_EXIT_RTN(...)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_ENTER(level,...)
#define SCOPE_EXIT_LOG_RTN(__log_level,...)
#define ast_trace(level,...)
#define LOG_ERROR
Asterisk module definitions.
@ AST_MODFLAG_LOAD_ORDER
Definition: module.h:317
@ AST_MODFLAG_GLOBAL_SYMBOLS
Definition: module.h:316
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:543
@ AST_MODPRI_DEFAULT
Definition: module.h:332
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
char * ast_sip_rdata_get_header_value(pjsip_rx_data *rdata, const pj_str_t str)
Get a specific header value from rdata.
Definition: res_pjsip.c:345
void ast_sip_add_date_header(pjsip_tx_data *tdata)
Adds a Date header to the tdata, formatted like: Date: Wed, 01 Jan 2021 14:53:01 GMT.
Definition: res_pjsip.c:90
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
Definition: res_pjsip.h:3186
#define PJSTR_PRINTF_VAR(_v)
Definition: res_pjsip.h:72
#define PJSTR_PRINTF_SPEC
Definition: res_pjsip.h:71
@ SUCCESS
int ast_sip_can_present_connected_id(const struct ast_sip_session *session, const struct ast_party_id *id)
Determines if the Connected Line info can be presented for this session.
#define ast_sip_session_register_supplement(supplement)
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.
Definition: pjsip_session.c:63
int ast_sip_session_add_reason_header(struct ast_sip_session *session, const char *protocol, int code, const char *text)
Adds a Reason header in the next reponse to an incoming INVITE.
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
process_failure_rc
@ PROCESS_FAILURE_SYSTEM_FAILURE
@ PROCESS_FAILURE_CONTINUE
@ PROCESS_FAILURE_REJECT
static void reject_incoming_call(struct ast_sip_session *session, enum sip_response_code response_code)
static enum sip_response_code vs_code_to_sip_code(enum ast_stir_shaken_vs_response_code vs_rc)
static void stir_shaken_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
static int stir_shaken_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
static const pj_str_t identity_hdr_str
static void add_date_header(const struct ast_sip_session *session, pjsip_tx_data *tdata)
sip_response_code
@ SIP_RESPONSE_CODE_USE_IDENTITY_HEADER
@ SIP_RESPONSE_CODE_INTERNAL_ERROR
@ SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER
@ SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL
@ SIP_RESPONSE_CODE_BAD_IDENTITY_INFO
@ SIP_RESPONSE_CODE_USE_SUPPORTED_PASSPORT_FORMAT
@ SIP_RESPONSE_CODE_STALE_DATE
@ SIP_RESPONSE_CODE_OK
#define response_to_str(_code)
static enum process_failure_rc process_failure(struct ast_stir_shaken_vs_ctx *ctx, const char *caller_id, struct ast_sip_session *session, pjsip_rx_data *rdata, enum ast_stir_shaken_vs_response_code vs_rc)
static struct ast_sip_session_supplement stir_shaken_supplement
static const char * sip_response_code_to_str(enum sip_response_code code)
static int load_module(void)
static int unload_module(void)
static char * get_dest_tn(pjsip_tx_data *tdata, const char *tag)
static const pj_str_t date_hdr_str
#define translate_code(_vs_rc, _sip_rc)
static void add_fingerprints_if_present(struct ast_sip_session *session, struct ast_stir_shaken_as_ctx *ctx)
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_ctx_add_date_hdr(struct ast_stir_shaken_vs_ctx *ctx, const char *date_hdr)
Add the received Date header value to the VS context.
Definition: verification.c:613
int ast_stir_shaken_add_result_to_channel(struct ast_stir_shaken_vs_ctx *ctx)
Add a STIR/SHAKEN verification result to a channel.
enum ast_stir_shaken_as_response_code ast_stir_shaken_as_ctx_add_fingerprint(struct ast_stir_shaken_as_ctx *ctx, const char *alg, const char *fingerprint)
Add DTLS fingerprints to AS context.
Definition: attestation.c:202
ast_stir_shaken_as_response_code
@ AST_STIR_SHAKEN_AS_DISABLED
@ AST_STIR_SHAKEN_AS_SUCCESS
enum stir_shaken_failure_action_enum ast_stir_shaken_vs_get_failure_action(struct ast_stir_shaken_vs_ctx *ctx)
Get failure_action from context.
Definition: verification.c:621
enum ast_stir_shaken_as_response_code ast_stir_shaken_as_ctx_create(const char *caller_id, const char *dest_tn, struct ast_channel *chan, const char *profile_name, const char *tag, struct ast_stir_shaken_as_ctx **ctxout)
Create Attestation Service Context.
Definition: attestation.c:66
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_verify(struct ast_stir_shaken_vs_ctx *ctx)
Perform incoming call verification.
Definition: verification.c:881
int ast_stir_shaken_vs_get_use_rfc9410_responses(struct ast_stir_shaken_vs_ctx *ctx)
Get use_rfc9410_responses from context.
Definition: verification.c:627
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_ctx_create(const char *caller_id, struct ast_channel *chan, const char *profile_name, const char *tag, struct ast_stir_shaken_vs_ctx **ctxout)
Create Verification Service context.
Definition: verification.c:651
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_ctx_add_identity_hdr(struct ast_stir_shaken_vs_ctx *ctx, const char *identity_hdr)
Add the received Identity header value to the VS context.
Definition: verification.c:605
ast_stir_shaken_vs_response_code
@ AST_STIR_SHAKEN_VS_NO_DATE_HDR
@ AST_STIR_SHAKEN_VS_SUCCESS
@ AST_STIR_SHAKEN_VS_NO_IDENTITY_HDR
@ AST_STIR_SHAKEN_VS_DISABLED
enum ast_stir_shaken_as_response_code ast_stir_shaken_attest(struct ast_stir_shaken_as_ctx *ctx, char **header)
Attest and return Identity header value.
Definition: attestation.c:360
int ast_stir_shaken_as_ctx_wants_fingerprints(struct ast_stir_shaken_as_ctx *ctx)
Indicates if the AS context needs DTLS fingerprints.
Definition: attestation.c:196
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)
Sets response code on VS context.
Definition: verification.c:633
stir_shaken_failure_action_enum
@ stir_shaken_failure_action_CONTINUE_RETURN_REASON
@ stir_shaken_failure_action_REJECT_REQUEST
#define NULL
Definition: resample.c:96
Pluggable RTP Architecture.
ast_rtp_dtls_hash
DTLS fingerprint hashes.
Definition: rtp_engine.h:573
@ AST_RTP_DTLS_HASH_SHA256
Definition: rtp_engine.h:574
struct ast_rtp_engine_dtls * ast_rtp_instance_get_dtls(struct ast_rtp_instance *instance)
Obtain a pointer to the DTLS support present on an RTP instance.
Definition: rtp_engine.c:3048
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Main Channel structure associated with a channel.
Information needed to identify an endpoint in a call.
Definition: channel.h:338
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:342
char * str
Subscriber phone number (Malloced)
Definition: channel.h:291
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:616
Structure which contains media state information (streams, sessions)
struct ast_sip_session_media_state::@263 sessions
Mapping of stream to media sessions.
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
A supplement to SIP message processing.
A structure describing a SIP session.
const ast_string_field dest_tn
Definition: attestation.h:29
static struct test_val d
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680