Asterisk - The Open Source Telephony Project GIT-master-7805f28
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
Macros | Enumerations | Functions | Variables
res_pjsip_stir_shaken.c File Reference
#include "asterisk.h"
#include "asterisk/callerid.h"
#include "asterisk/res_pjsip.h"
#include "asterisk/res_pjsip_session.h"
#include "asterisk/module.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/res_stir_shaken.h"
Include dependency graph for res_pjsip_stir_shaken.c:

Go to the source code of this file.

Macros

#define _TRACE_PREFIX_   "pjss",__LINE__, ""
 
#define AST_BUILDOPT_SUM   ""
 
#define response_to_str(_code)
 
#define SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED_STR   "Anonymity Disallowed"
 
#define SIP_RESPONSE_CODE_BAD_IDENTITY_INFO_STR   "Bad Identity Info"
 
#define SIP_RESPONSE_CODE_INTERNAL_ERROR_STR   "Internal Error"
 
#define SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER_STR   "Invalid Identity Header"
 
#define SIP_RESPONSE_CODE_OK_STR   "OK"
 
#define SIP_RESPONSE_CODE_STALE_DATE_STR   "Stale Date"
 
#define SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL_STR   "Unsupported Credential"
 
#define SIP_RESPONSE_CODE_USE_IDENTITY_HEADER_STR   "Use Identity Header"
 
#define translate_code(_vs_rc, _sip_rc)
 

Enumerations

enum  process_failure_rc { PROCESS_FAILURE_CONTINUE = 0 , PROCESS_FAILURE_REJECT , PROCESS_FAILURE_SYSTEM_FAILURE }
 
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_INTERNAL_ERROR = 500
}
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void add_date_header (const struct ast_sip_session *session, pjsip_tx_data *tdata)
 
static void add_fingerprints_if_present (struct ast_sip_session *session, struct ast_stir_shaken_as_ctx *ctx)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static char * get_dest_tn (pjsip_tx_data *tdata, const char *tag)
 
static int load_module (void)
 
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 void reject_incoming_call (struct ast_sip_session *session, enum sip_response_code response_code)
 
static const char * sip_response_code_to_str (enum sip_response_code code)
 
static int stir_shaken_incoming_request (struct ast_sip_session *session, pjsip_rx_data *rdata)
 
static void stir_shaken_outgoing_request (struct ast_sip_session *session, pjsip_tx_data *tdata)
 
static int unload_module (void)
 
static enum sip_response_code vs_code_to_sip_code (enum ast_stir_shaken_vs_response_code vs_rc)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "PJSIP STIR/SHAKEN Module for Asterisk" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .requires = "res_pjsip,res_pjsip_session,res_stir_shaken", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static const pj_str_t date_hdr_str = { "Date", 4 }
 
static const pj_str_t identity_hdr_str = { "Identity", 8 }
 
static struct ast_sip_session_supplement stir_shaken_supplement
 

Macro Definition Documentation

◆ _TRACE_PREFIX_

#define _TRACE_PREFIX_   "pjss",__LINE__, ""

Definition at line 29 of file res_pjsip_stir_shaken.c.

◆ AST_BUILDOPT_SUM

#define AST_BUILDOPT_SUM   ""

Definition at line 503 of file res_pjsip_stir_shaken.c.

◆ response_to_str

#define response_to_str (   _code)
Value:
case _code: \
return _code ## _STR;

Definition at line 64 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED_STR

#define SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED_STR   "Anonymity Disallowed"

Definition at line 58 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_BAD_IDENTITY_INFO_STR

#define SIP_RESPONSE_CODE_BAD_IDENTITY_INFO_STR   "Bad Identity Info"

Definition at line 59 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_INTERNAL_ERROR_STR

#define SIP_RESPONSE_CODE_INTERNAL_ERROR_STR   "Internal Error"

Definition at line 62 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER_STR

#define SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER_STR   "Invalid Identity Header"

Definition at line 61 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_OK_STR

#define SIP_RESPONSE_CODE_OK_STR   "OK"

Definition at line 54 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_STALE_DATE_STR

#define SIP_RESPONSE_CODE_STALE_DATE_STR   "Stale Date"

Definition at line 56 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL_STR

#define SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL_STR   "Unsupported Credential"

Definition at line 60 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_USE_IDENTITY_HEADER_STR

#define SIP_RESPONSE_CODE_USE_IDENTITY_HEADER_STR   "Use Identity Header"

Definition at line 57 of file res_pjsip_stir_shaken.c.

◆ translate_code

#define translate_code (   _vs_rc,
  _sip_rc 
)
Value:
case AST_STIR_SHAKEN_VS_ ## _vs_rc: \
return SIP_RESPONSE_CODE_ ## _sip_rc;

Definition at line 84 of file res_pjsip_stir_shaken.c.

Enumeration Type Documentation

◆ process_failure_rc

Enumerator
PROCESS_FAILURE_CONTINUE 
PROCESS_FAILURE_REJECT 
PROCESS_FAILURE_SYSTEM_FAILURE 

Definition at line 138 of file res_pjsip_stir_shaken.c.

138 {
142};
@ PROCESS_FAILURE_SYSTEM_FAILURE
@ PROCESS_FAILURE_CONTINUE
@ PROCESS_FAILURE_REJECT

◆ sip_response_code

Enumerator
SIP_RESPONSE_CODE_OK 
SIP_RESPONSE_CODE_STALE_DATE 
SIP_RESPONSE_CODE_USE_IDENTITY_HEADER 
SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED 
SIP_RESPONSE_CODE_BAD_IDENTITY_INFO 
SIP_RESPONSE_CODE_UNSUPPORTED_CREDENTIAL 
SIP_RESPONSE_CODE_INVALID_IDENTITY_HEADER 
SIP_RESPONSE_CODE_INTERNAL_ERROR 

Definition at line 43 of file res_pjsip_stir_shaken.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 511 of file res_pjsip_stir_shaken.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 511 of file res_pjsip_stir_shaken.c.

◆ add_date_header()

static void add_date_header ( const struct ast_sip_session session,
pjsip_tx_data *  tdata 
)
static

Definition at line 379 of file res_pjsip_stir_shaken.c.

380{
381 pjsip_fromto_hdr *old_date;
382 const char *session_name = ast_sip_session_get_name(session);
383 SCOPE_ENTER(1, "%s: Enter\n", session_name);
384
385 old_date = pjsip_msg_find_hdr_by_name(tdata->msg, &date_hdr_str, NULL);
386 if (old_date) {
387 SCOPE_EXIT_RTN("Found existing Date header, no need to add one\n");
388 }
389
391 SCOPE_EXIT_RTN("Done\n");
392}
static struct ast_mansession session
#define SCOPE_EXIT_RTN(...)
#define SCOPE_ENTER(level,...)
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
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
static const pj_str_t date_hdr_str
#define NULL
Definition: resample.c:96

References ast_sip_add_date_header(), ast_sip_session_get_name(), date_hdr_str, NULL, SCOPE_ENTER, SCOPE_EXIT_RTN, and session.

Referenced by stir_shaken_outgoing_request().

◆ add_fingerprints_if_present()

static void add_fingerprints_if_present ( struct ast_sip_session session,
struct ast_stir_shaken_as_ctx ctx 
)
static

Definition at line 315 of file res_pjsip_stir_shaken.c.

317{
318 struct ast_sip_session_media_state *ms = session->pending_media_state;
319 struct ast_sip_session_media *m = NULL;
320 struct ast_rtp_engine_dtls *d = NULL;
321 enum ast_rtp_dtls_hash h;
322 int i;
323 const char *tag = ast_sip_session_get_name(session);
324 size_t count = AST_VECTOR_SIZE(&ms->sessions);
325 SCOPE_ENTER(4, "%s: Check %zu media sessions for fingerprints\n",
326 tag, count);
327
329 SCOPE_EXIT_RTN("%s: Fingerprints not needed\n", tag);
330 }
331
332 for (i = 0; i < count; i++) {
333 const char *f;
334
335 m = AST_VECTOR_GET(&ms->sessions, i);
336 if (!m|| !m->rtp) {
337 ast_trace(1, "Session: %d: No session or rtp instance\n", i);
338 continue;
339 }
341 h = d->get_fingerprint_hash(m->rtp);
342 f = d->get_fingerprint(m->rtp);
343
345 h == AST_RTP_DTLS_HASH_SHA256 ? "sha-256" : "sha-1", f);
346 }
347 SCOPE_EXIT_RTN("%s: Done\n", tag);
348}
#define ast_trace(level,...)
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:206
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:200
ast_rtp_dtls_hash
DTLS fingerprint hashes.
Definition: rtp_engine.h:578
@ AST_RTP_DTLS_HASH_SHA256
Definition: rtp_engine.h:579
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:3217
Structure that represents the optional DTLS SRTP support within an RTP engine.
Definition: rtp_engine.h:621
Structure which contains media state information (streams, sessions)
struct ast_sip_session_media_state::@265 sessions
Mapping of stream to media sessions.
A structure containing SIP session media information.
struct ast_rtp_instance * rtp
RTP instance itself.
static struct test_val d
#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

References AST_RTP_DTLS_HASH_SHA256, ast_rtp_instance_get_dtls(), ast_sip_session_get_name(), ast_stir_shaken_as_ctx_add_fingerprint(), ast_stir_shaken_as_ctx_wants_fingerprints(), ast_trace, AST_VECTOR_GET, AST_VECTOR_SIZE, d, NULL, ast_sip_session_media::rtp, SCOPE_ENTER, SCOPE_EXIT_RTN, session, and ast_sip_session_media_state::sessions.

Referenced by stir_shaken_outgoing_request().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 511 of file res_pjsip_stir_shaken.c.

◆ get_dest_tn()

static char * get_dest_tn ( pjsip_tx_data *  tdata,
const char *  tag 
)
static

Definition at line 350 of file res_pjsip_stir_shaken.c.

351{
352 pjsip_fromto_hdr *to;
353 pjsip_sip_uri *uri;
354 char *dest_tn = NULL;
355 SCOPE_ENTER(4, "%s: Enter\n", tag);
356
357 to = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_TO, NULL);
358 if (!to) {
359 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Failed to find To header\n", tag);
360 }
361
362 uri = pjsip_uri_get_uri(to->uri);
363 if (!uri) {
365 "%s: Failed to retrieve URI from To header\n", tag);
366 }
367
368 dest_tn = ast_malloc(uri->user.slen + 1);
369 if (!dest_tn) {
371 "%s: Failed to allocate memory for dest_tn\n", tag);
372 }
373
374 ast_copy_pj_str(dest_tn, &uri->user, uri->user.slen + 1);
375
376 SCOPE_EXIT_RTN_VALUE(dest_tn, "%s: Done\n", tag);
377}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:2201

References ast_copy_pj_str(), ast_malloc, NULL, SCOPE_ENTER, and SCOPE_EXIT_RTN_VALUE.

Referenced by stir_shaken_outgoing_request().

◆ load_module()

static int load_module ( void  )
static

Definition at line 496 of file res_pjsip_stir_shaken.c.

497{
500}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
#define ast_sip_session_register_supplement(supplement)
static struct ast_sip_session_supplement stir_shaken_supplement

References AST_MODULE_LOAD_SUCCESS, ast_sip_session_register_supplement, and stir_shaken_supplement.

◆ process_failure()

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

Definition at line 151 of file res_pjsip_stir_shaken.c.

154{
155 enum sip_response_code response_code = vs_code_to_sip_code(vs_rc);
156 pj_str_t response_str;
157 const char *response_string =
158 sip_response_code_to_str(response_code);
159 enum stir_shaken_failure_action_enum failure_action =
161 const char *tag = ast_sip_session_get_name(session);
162 SCOPE_ENTER(1, "%s: FA: %d RC: %d\n", tag,
163 failure_action, response_code);
164
165 pj_cstr(&response_str, response_string);
166
167 if (failure_action == stir_shaken_failure_action_REJECT_REQUEST) {
168 reject_incoming_call(session, response_code);
170 "%s: Rejecting request and terminating session\n",
171 tag);
172 }
173
176
180 response_code, response_str.ptr);
181 if (rc != 0) {
183 "%s: Failed to add Reason header\n", tag);
184 }
186 "%s: Attaching reason code to session\n", tag);
187 }
189 "%s: Continuing\n", tag);
190}
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.
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)
sip_response_code
static const char * sip_response_code_to_str(enum sip_response_code code)
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 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
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
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:639
stir_shaken_failure_action_enum
@ stir_shaken_failure_action_CONTINUE_RETURN_REASON
@ stir_shaken_failure_action_REJECT_REQUEST

References ast_sip_session_add_reason_header(), ast_sip_session_get_name(), ast_stir_shaken_add_result_to_channel(), ast_stir_shaken_vs_ctx_set_response_code(), ast_stir_shaken_vs_get_failure_action(), ast_stir_shaken_vs_get_use_rfc9410_responses(), PROCESS_FAILURE_CONTINUE, PROCESS_FAILURE_REJECT, PROCESS_FAILURE_SYSTEM_FAILURE, reject_incoming_call(), SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, session, sip_response_code_to_str(), stir_shaken_failure_action_CONTINUE_RETURN_REASON, stir_shaken_failure_action_REJECT_REQUEST, and vs_code_to_sip_code().

Referenced by stir_shaken_incoming_request().

◆ reject_incoming_call()

static void reject_incoming_call ( struct ast_sip_session session,
enum sip_response_code  response_code 
)
static

Definition at line 144 of file res_pjsip_stir_shaken.c.

146{
147 ast_sip_session_terminate(session, response_code);
148 ast_hangup(session->channel);
149}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2510
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.

References ast_hangup(), ast_sip_session_terminate(), and session.

Referenced by process_failure(), and stir_shaken_incoming_request().

◆ sip_response_code_to_str()

static const char * sip_response_code_to_str ( enum sip_response_code  code)
static

◆ stir_shaken_incoming_request()

static int stir_shaken_incoming_request ( struct ast_sip_session session,
pjsip_rx_data *  rdata 
)
static

Definition at line 202 of file res_pjsip_stir_shaken.c.

203{
205 RAII_VAR(char *, header, NULL, ast_free);
206 RAII_VAR(char *, payload, NULL, ast_free);
207 char *identity_hdr_val;
208 char *date_hdr_val;
209 char *caller_id = session->id.number.str;
210 const char *session_name = ast_sip_session_get_name(session);
211 struct ast_channel *chan = session->channel;
213 enum process_failure_rc p_rc;
214 SCOPE_ENTER(1, "%s: Enter\n", session_name);
215
216 if (!session) {
217 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "No session\n");
218 }
219 if (!session->channel) {
220 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No channel\n", session_name);
221 }
222 if (!rdata) {
223 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No rdata\n", session_name);
224 }
225
226 /* Check if this is a reinvite. If it is, we don't need to do anything */
227 if (rdata->msg_info.to->tag.slen) {
228 SCOPE_EXIT_RTN_VALUE(0, "%s: Reinvite. No action needed\n", session_name);
229 }
230
231 /*
232 * Shortcut: If there's no profile name just bail now.
233 */
234 if (ast_strlen_zero(session->endpoint->stir_shaken_profile)) {
235 SCOPE_EXIT_RTN_VALUE(0, "%s: No profile name on endpoint. 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
250 p_rc = process_failure(ctx, caller_id, session, rdata,
252 if (p_rc == PROCESS_FAILURE_CONTINUE) {
253 SCOPE_EXIT_RTN_VALUE(0, "%s: Invalid or no callerid found. Call continuing\n",
254 session_name);
255 }
256 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Invalid or no callerid found. Call terminated\n",
257 session_name);
258 }
259
260 identity_hdr_val = ast_sip_rdata_get_header_value(rdata, identity_hdr_str);
261 if (ast_strlen_zero(identity_hdr_val)) {
262 p_rc = process_failure(ctx, caller_id, session, rdata,
264 if (p_rc == PROCESS_FAILURE_CONTINUE) {
265 SCOPE_EXIT_RTN_VALUE(0, "%s: No Identity header found. Call continuing\n",
266 session_name);
267 }
268 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No Identity header found. Call terminated\n",
269 session_name);
270 }
271
272 vs_rc = ast_stir_shaken_vs_ctx_add_identity_hdr(ctx, identity_hdr_val);
273 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
275 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Unable to add Identity header. Call terminated.\n",
276 session_name);
277 }
278
279 date_hdr_val = ast_sip_rdata_get_header_value(rdata, date_hdr_str);
280 if (ast_strlen_zero(date_hdr_val)) {
281 p_rc = process_failure(ctx, caller_id, session, rdata,
283 if (p_rc == PROCESS_FAILURE_CONTINUE) {
284 SCOPE_EXIT_RTN_VALUE(0, "%s: No Date header found. Call continuing\n",
285 session_name);
286 }
287 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No Date header found. Call terminated\n",
288 session_name);
289 }
290
291 ast_stir_shaken_vs_ctx_add_date_hdr(ctx, date_hdr_val);
292 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
294 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Unable to add Date header. Call terminated.\n",
295 session_name);
296 }
297
298 vs_rc = ast_stir_shaken_vs_verify(ctx);
299 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
300 p_rc = process_failure(ctx, caller_id, session, rdata, vs_rc);
301 if (p_rc == PROCESS_FAILURE_CONTINUE) {
302 SCOPE_EXIT_RTN_VALUE(0, "%s: Verification failed. Call continuing\n",
303 session_name);
304 }
305 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Verification failed. Call terminated\n",
306 session_name);
307
308 }
309
311
312 SCOPE_EXIT_RTN_VALUE(0, "Passed\n");
313}
#define ast_free(a)
Definition: astmm.h:180
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define LOG_ERROR
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
process_failure_rc
static const pj_str_t identity_hdr_str
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)
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
const char * ast_stir_shaken_vs_get_caller_id(struct ast_stir_shaken_vs_ctx *ctx)
Get caller_id from context.
Definition: verification.c:633
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:884
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:657
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
@ AST_STIR_SHAKEN_VS_INVALID_OR_NO_CID
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Main Channel structure associated with a channel.
#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

References ao2_cleanup, ast_free, ast_sip_rdata_get_header_value(), ast_sip_session_get_name(), ast_stir_shaken_add_result_to_channel(), ast_stir_shaken_vs_ctx_add_date_hdr(), ast_stir_shaken_vs_ctx_add_identity_hdr(), ast_stir_shaken_vs_ctx_create(), AST_STIR_SHAKEN_VS_DISABLED, ast_stir_shaken_vs_get_caller_id(), AST_STIR_SHAKEN_VS_INVALID_OR_NO_CID, AST_STIR_SHAKEN_VS_NO_DATE_HDR, AST_STIR_SHAKEN_VS_NO_IDENTITY_HDR, AST_STIR_SHAKEN_VS_SUCCESS, ast_stir_shaken_vs_verify(), ast_strlen_zero(), date_hdr_str, identity_hdr_str, LOG_ERROR, NULL, process_failure(), PROCESS_FAILURE_CONTINUE, RAII_VAR, reject_incoming_call(), SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, and session.

◆ stir_shaken_outgoing_request()

static void stir_shaken_outgoing_request ( struct ast_sip_session session,
pjsip_tx_data *  tdata 
)
static

Definition at line 394 of file res_pjsip_stir_shaken.c.

396{
397 struct ast_party_id effective_id;
398 struct ast_party_id connected_id;
399 pjsip_generic_string_hdr *old_identity;
400 pjsip_generic_string_hdr *identity_hdr;
401 pj_str_t identity_val;
402 char *dest_tn;
403 char *identity_str;
404 struct ast_stir_shaken_as_ctx *ctx = NULL;
406 const char *session_name = ast_sip_session_get_name(session);
407 SCOPE_ENTER(1, "%s: Enter\n", session_name);
408
409 if (!session) {
410 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "No session\n");
411 }
412 if (!session->channel) {
413 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: No channel\n", session_name);
414 }
415 if (!tdata) {
416 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: No tdata\n", session_name);
417 }
418
419 old_identity = pjsip_msg_find_hdr_by_name(tdata->msg, &identity_hdr_str, NULL);
420 if (old_identity) {
421 SCOPE_EXIT_RTN("Found an existing Identity header\n");
422 }
423
424 dest_tn = get_dest_tn(tdata, session_name);
425 if (!dest_tn) {
426 SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Unable to find destination tn\n",
427 session_name);
428 }
429
430 ast_party_id_init(&connected_id);
431 ast_channel_lock(session->channel);
432 effective_id = ast_channel_connected_effective_id(session->channel);
433 ast_party_id_copy(&connected_id, &effective_id);
434 ast_channel_unlock(session->channel);
435
436 if (!ast_sip_can_present_connected_id(session, &connected_id)) {
438 ast_party_id_free(&connected_id);
439 SCOPE_EXIT_RTN("Unable to get caller id\n");
440 }
441
442 as_rc = ast_stir_shaken_as_ctx_create(connected_id.number.str,
443 dest_tn, session->channel,
444 session->endpoint->stir_shaken_profile,
445 session_name, &ctx);
446
448 ast_party_id_free(&connected_id);
449
450 if (as_rc == AST_STIR_SHAKEN_AS_DISABLED) {
451 SCOPE_EXIT_RTN("%s: AS Disabled\n", session_name);
452 } else if (as_rc != AST_STIR_SHAKEN_AS_SUCCESS) {
453 SCOPE_EXIT_RTN("%s: Unable to create context\n",
454 session_name);
455 }
456
457 add_date_header(session, tdata);
459
460 as_rc = ast_stir_shaken_attest(ctx, &identity_str);
461 if (as_rc != AST_STIR_SHAKEN_AS_SUCCESS) {
462 ao2_cleanup(ctx);
464 "%s: Failed to create attestation\n", session_name);
465 }
466
467 ast_trace(1, "%s: Identity header: %s\n", session_name, identity_str);
468 identity_val = pj_str(identity_str);
469 identity_hdr = pjsip_generic_string_hdr_create(tdata->pool, &identity_hdr_str, &identity_val);
470 ast_free(identity_str);
471 if (!identity_hdr) {
472 ao2_cleanup(ctx);
474 "%s: Unable to create Identity header\n", session_name);
475 }
476
477 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)identity_hdr);
478
479 ao2_cleanup(ctx);
480 SCOPE_EXIT_RTN("Done\n");
481}
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:1724
#define ast_channel_lock(chan)
Definition: channel.h:2972
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
Definition: channel.c:1778
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:1732
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition: channel.h:2973
#define SCOPE_EXIT_LOG(__log_level,...)
#define SCOPE_EXIT_LOG_RTN(__log_level,...)
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.
static void add_date_header(const struct ast_sip_session *session, pjsip_tx_data *tdata)
static char * get_dest_tn(pjsip_tx_data *tdata, const char *tag)
static void add_fingerprints_if_present(struct ast_sip_session *session, struct ast_stir_shaken_as_ctx *ctx)
ast_stir_shaken_as_response_code
@ AST_STIR_SHAKEN_AS_DISABLED
@ AST_STIR_SHAKEN_AS_SUCCESS
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_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:364
Information needed to identify an endpoint in a call.
Definition: channel.h:340
const ast_string_field dest_tn
Definition: attestation.h:29

References add_date_header(), add_fingerprints_if_present(), ao2_cleanup, ast_channel_connected_effective_id(), ast_channel_lock, ast_channel_unlock, ast_free, ast_party_id_copy(), ast_party_id_free(), ast_party_id_init(), ast_sip_can_present_connected_id(), ast_sip_session_get_name(), ast_stir_shaken_as_ctx_create(), AST_STIR_SHAKEN_AS_DISABLED, AST_STIR_SHAKEN_AS_SUCCESS, ast_stir_shaken_attest(), ast_trace, ast_stir_shaken_as_ctx::dest_tn, get_dest_tn(), identity_hdr_str, LOG_ERROR, NULL, ast_party_id::number, SCOPE_ENTER, SCOPE_EXIT_LOG, SCOPE_EXIT_LOG_RTN, SCOPE_EXIT_RTN, session, and ast_party_number::str.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 490 of file res_pjsip_stir_shaken.c.

491{
493 return 0;
494}
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

References ast_sip_session_unregister_supplement(), and stir_shaken_supplement.

◆ vs_code_to_sip_code()

static enum sip_response_code vs_code_to_sip_code ( enum ast_stir_shaken_vs_response_code  vs_rc)
static

Definition at line 88 of file res_pjsip_stir_shaken.c.

90{
91 /*
92 * We want to use a switch/case statement here because
93 * it'll spit out an error if VS codes are added to the
94 * enum but aren't present here.
95 */
96 switch (vs_rc) {
98 translate_code(DISABLED, OK)
99 translate_code(INVALID_ARGUMENTS, INTERNAL_ERROR)
100 translate_code(INTERNAL_ERROR, INTERNAL_ERROR)
101 translate_code(NO_IDENTITY_HDR, USE_IDENTITY_HEADER)
102 translate_code(NO_DATE_HDR, STALE_DATE)
103 translate_code(DATE_HDR_PARSE_FAILURE, STALE_DATE)
104 translate_code(DATE_HDR_EXPIRED, STALE_DATE)
105 translate_code(NO_JWT_HDR, INVALID_IDENTITY_HEADER)
106 translate_code(INVALID_OR_NO_X5U, INVALID_IDENTITY_HEADER)
107 translate_code(CERT_CACHE_MISS, INVALID_IDENTITY_HEADER)
108 translate_code(CERT_CACHE_INVALID, INVALID_IDENTITY_HEADER)
109 translate_code(CERT_CACHE_EXPIRED, INVALID_IDENTITY_HEADER)
110 translate_code(CERT_RETRIEVAL_FAILURE, BAD_IDENTITY_INFO)
111 translate_code(CERT_CONTENTS_INVALID, UNSUPPORTED_CREDENTIAL)
112 translate_code(CERT_NOT_TRUSTED, UNSUPPORTED_CREDENTIAL)
113 translate_code(CERT_DATE_INVALID, UNSUPPORTED_CREDENTIAL)
114 translate_code(CERT_NO_TN_AUTH_EXT, UNSUPPORTED_CREDENTIAL)
115 translate_code(CERT_NO_SPC_IN_TN_AUTH_EXT, UNSUPPORTED_CREDENTIAL)
116 translate_code(NO_RAW_KEY, UNSUPPORTED_CREDENTIAL)
117 translate_code(SIGNATURE_VALIDATION, INVALID_IDENTITY_HEADER)
118 translate_code(NO_IAT, INVALID_IDENTITY_HEADER)
119 translate_code(IAT_EXPIRED, STALE_DATE)
120 translate_code(INVALID_OR_NO_PPT, INVALID_IDENTITY_HEADER)
121 translate_code(INVALID_OR_NO_ALG, INVALID_IDENTITY_HEADER)
122 translate_code(INVALID_OR_NO_TYP, INVALID_IDENTITY_HEADER)
123 translate_code(INVALID_OR_NO_ATTEST, INVALID_IDENTITY_HEADER)
124 translate_code(NO_ORIGID, INVALID_IDENTITY_HEADER)
125 translate_code(NO_ORIG_TN, INVALID_IDENTITY_HEADER)
126 translate_code(NO_DEST_TN, INVALID_IDENTITY_HEADER)
127 translate_code(INVALID_HEADER, INVALID_IDENTITY_HEADER)
128 translate_code(INVALID_GRANT, INVALID_IDENTITY_HEADER)
129 translate_code(INVALID_OR_NO_GRANTS, INVALID_IDENTITY_HEADER)
130 translate_code(CID_ORIG_TN_MISMATCH, INVALID_IDENTITY_HEADER)
131 translate_code(INVALID_OR_NO_CID, ANONYMITY_DISALLOWED)
132 translate_code(RESPONSE_CODE_MAX, INVALID_IDENTITY_HEADER)
133 }
134
135 return 500;
136}
@ SUCCESS
#define translate_code(_vs_rc, _sip_rc)

References SUCCESS, and translate_code.

Referenced by process_failure().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "PJSIP STIR/SHAKEN Module for Asterisk" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "" , .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, .requires = "res_pjsip,res_pjsip_session,res_stir_shaken", }
static

Definition at line 511 of file res_pjsip_stir_shaken.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 511 of file res_pjsip_stir_shaken.c.

◆ date_hdr_str

const pj_str_t date_hdr_str = { "Date", 4 }
static

Definition at line 40 of file res_pjsip_stir_shaken.c.

Referenced by add_date_header(), and stir_shaken_incoming_request().

◆ identity_hdr_str

const pj_str_t identity_hdr_str = { "Identity", 8 }
static

◆ stir_shaken_supplement

struct ast_sip_session_supplement stir_shaken_supplement
static

Definition at line 483 of file res_pjsip_stir_shaken.c.

Referenced by load_module(), and unload_module().