Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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/datastore.h"
#include "res_stir_shaken/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 = ASTERISK_GPL_KEY , .buildopt_sum = AST_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 505 of file res_pjsip_stir_shaken.c.

◆ response_to_str

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

Definition at line 65 of file res_pjsip_stir_shaken.c.

66 : \
67 return _code ## _STR;

◆ SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED_STR

#define SIP_RESPONSE_CODE_ANONYMITY_DISALLOWED_STR   "Anonymity Disallowed"

Definition at line 59 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 60 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 63 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 62 of file res_pjsip_stir_shaken.c.

◆ SIP_RESPONSE_CODE_OK_STR

#define SIP_RESPONSE_CODE_OK_STR   "OK"

Definition at line 55 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 57 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 61 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 58 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 85 of file res_pjsip_stir_shaken.c.

86 : \
87 return SIP_RESPONSE_CODE_ ## _sip_rc;

Enumeration Type Documentation

◆ process_failure_rc

Enumerator
PROCESS_FAILURE_CONTINUE 
PROCESS_FAILURE_REJECT 
PROCESS_FAILURE_SYSTEM_FAILURE 

Definition at line 139 of file res_pjsip_stir_shaken.c.

◆ 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 44 of file res_pjsip_stir_shaken.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 513 of file res_pjsip_stir_shaken.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 513 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 371 of file res_pjsip_stir_shaken.c.

372{
373 pjsip_fromto_hdr *old_date;
374 const char *session_name = ast_sip_session_get_name(session);
375 SCOPE_ENTER(1, "%s: Enter\n", session_name);
376
377 old_date = pjsip_msg_find_hdr_by_name(tdata->msg, &date_hdr_str, NULL);
378 if (old_date) {
379 SCOPE_EXIT_RTN("Found existing Date header, no need to add one\n");
380 }
381
383 SCOPE_EXIT_RTN("Done\n");
384}
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 307 of file res_pjsip_stir_shaken.c.

309{
310 struct ast_sip_session_media_state *ms = session->pending_media_state;
311 struct ast_sip_session_media *m = NULL;
312 struct ast_rtp_engine_dtls *d = NULL;
313 enum ast_rtp_dtls_hash h;
314 int i;
315 const char *tag = ast_sip_session_get_name(session);
316 size_t count = AST_VECTOR_SIZE(&ms->sessions);
317 SCOPE_ENTER(4, "%s: Check %zu media sessions for fingerprints\n",
318 tag, count);
319
321 SCOPE_EXIT_RTN("%s: Fingerprints not needed\n", tag);
322 }
323
324 for (i = 0; i < count; i++) {
325 const char *f;
326
327 m = AST_VECTOR_GET(&ms->sessions, i);
328 if (!m|| !m->rtp) {
329 ast_trace(1, "Session: %d: No session or rtp instance\n", i);
330 continue;
331 }
333 h = d->get_fingerprint_hash(m->rtp);
334 f = d->get_fingerprint(m->rtp);
335
337 h == AST_RTP_DTLS_HASH_SHA256 ? "sha-256" : "sha-1", f);
338 }
339 SCOPE_EXIT_RTN("%s: Done\n", tag);
340}
#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.
int ast_stir_shaken_as_ctx_wants_fingerprints(struct ast_stir_shaken_as_ctx *ctx)
Indicates if the AS context needs DTLS fingerprints.
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.
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::@282 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:620
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition vector.h:691

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 513 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 342 of file res_pjsip_stir_shaken.c.

343{
344 pjsip_fromto_hdr *to;
345 pjsip_sip_uri *uri;
346 char *dest_tn = NULL;
347 SCOPE_ENTER(4, "%s: Enter\n", tag);
348
349 to = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_TO, NULL);
350 if (!to) {
351 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Failed to find To header\n", tag);
352 }
353
354 uri = pjsip_uri_get_uri(to->uri);
355 if (!uri) {
357 "%s: Failed to retrieve URI from To header\n", tag);
358 }
359
360 dest_tn = ast_malloc(uri->user.slen + 1);
361 if (!dest_tn) {
363 "%s: Failed to allocate memory for dest_tn\n", tag);
364 }
365
366 ast_copy_pj_str(dest_tn, &uri->user, uri->user.slen + 1);
367
368 SCOPE_EXIT_RTN_VALUE(dest_tn, "%s: Done\n", tag);
369}
#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 498 of file res_pjsip_stir_shaken.c.

499{
502}
@ 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 152 of file res_pjsip_stir_shaken.c.

155{
156 enum sip_response_code response_code = vs_code_to_sip_code(vs_rc);
157 pj_str_t response_str;
158 const char *response_string =
159 sip_response_code_to_str(response_code);
160 enum stir_shaken_failure_action_enum failure_action =
162 const char *tag = ast_sip_session_get_name(session);
163 SCOPE_ENTER(1, "%s: FA: %d RC: %d\n", tag,
164 failure_action, response_code);
165
166 pj_cstr(&response_str, response_string);
167
168 if (failure_action == stir_shaken_failure_action_REJECT_REQUEST) {
169 reject_incoming_call(session, response_code);
171 "%s: Rejecting request and terminating session\n",
172 tag);
173 }
174
177
181 response_code, response_str.ptr);
182 if (rc != 0) {
184 "%s: Failed to add Reason header\n", tag);
185 }
187 "%s: Attaching reason code to session\n", tag);
188 }
190 "%s: Continuing\n", tag);
191}
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)
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.
int ast_stir_shaken_vs_get_use_rfc9410_responses(struct ast_stir_shaken_vs_ctx *ctx)
Get use_rfc9410_responses from context.
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.
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 145 of file res_pjsip_stir_shaken.c.

147{
148 ast_sip_session_terminate(session, response_code);
149 ast_hangup(session->channel);
150}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition channel.c:2538
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 203 of file res_pjsip_stir_shaken.c.

204{
206 RAII_VAR(char *, header, NULL, ast_free);
207 RAII_VAR(char *, payload, NULL, ast_free);
208 char *identity_hdr_val;
209 char *date_hdr_val;
210 char *caller_id = session->id.number.str;
211 const char *session_name = ast_sip_session_get_name(session);
212 struct ast_channel *chan = session->channel;
214 enum process_failure_rc p_rc;
215 SCOPE_ENTER(1, "%s: Enter\n", session_name);
216
217 if (!session) {
218 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "No session\n");
219 }
220 if (!session->channel) {
221 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No channel\n", session_name);
222 }
223 if (!rdata) {
224 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No rdata\n", session_name);
225 }
226
227 /* Check if this is a reinvite. If it is, we don't need to do anything */
228 if (rdata->msg_info.to->tag.slen) {
229 SCOPE_EXIT_RTN_VALUE(0, "%s: Reinvite. No action needed\n", session_name);
230 }
231
232 /*
233 * Shortcut: If there's no profile name just bail now.
234 */
235 if (ast_strlen_zero(session->endpoint->stir_shaken_profile)) {
236 SCOPE_EXIT_RTN_VALUE(0, "%s: No profile name on endpoint. No action needed\n", session_name);
237 }
238
239 vs_rc = ast_stir_shaken_vs_ctx_create(caller_id, chan,
240 session->endpoint->stir_shaken_profile,
241 session_name, &ctx);
242 if (vs_rc == AST_STIR_SHAKEN_VS_DISABLED) {
243 SCOPE_EXIT_RTN_VALUE(0, "%s: VS Disabled\n", session_name);
244 } else if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
246 SCOPE_EXIT_RTN_VALUE(1, "%s: Unable to create context. Call terminated\n",
247 session_name);
248 }
249
251 p_rc = process_failure(ctx, caller_id, session, rdata,
253 if (p_rc == PROCESS_FAILURE_CONTINUE) {
254 SCOPE_EXIT_RTN_VALUE(0, "%s: Invalid or no callerid found. Call continuing\n",
255 session_name);
256 }
257 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Invalid or no callerid found. Call terminated\n",
258 session_name);
259 }
260
261 identity_hdr_val = ast_sip_rdata_get_header_value(rdata, identity_hdr_str);
262 if (ast_strlen_zero(identity_hdr_val)) {
263 p_rc = process_failure(ctx, caller_id, session, rdata,
265 if (p_rc == PROCESS_FAILURE_CONTINUE) {
266 SCOPE_EXIT_RTN_VALUE(0, "%s: No Identity header found. Call continuing\n",
267 session_name);
268 }
269 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: No Identity header found. Call terminated\n",
270 session_name);
271 }
272
273 vs_rc = ast_stir_shaken_vs_ctx_add_identity_hdr(ctx, identity_hdr_val);
274 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
276 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Unable to add Identity header. Call terminated.\n",
277 session_name);
278 }
279
280 date_hdr_val = ast_sip_rdata_get_header_value(rdata, date_hdr_str);
281 if (!ast_strlen_zero(date_hdr_val)) {
282 vs_rc = ast_stir_shaken_vs_ctx_add_date_hdr(ctx, date_hdr_val);
283 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
285 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Unable to add Date header. Call terminated.\n",
286 session_name);
287 }
288 }
289
290 vs_rc = ast_stir_shaken_vs_verify(ctx);
291 if (vs_rc != AST_STIR_SHAKEN_VS_SUCCESS) {
292 p_rc = process_failure(ctx, caller_id, session, rdata, vs_rc);
293 if (p_rc == PROCESS_FAILURE_CONTINUE) {
294 SCOPE_EXIT_RTN_VALUE(0, "%s: Verification failed. Call continuing\n",
295 session_name);
296 }
297 SCOPE_EXIT_LOG_RTN_VALUE(1, LOG_ERROR, "%s: Verification failed. Call terminated\n",
298 session_name);
299
300 }
301
303
304 SCOPE_EXIT_RTN_VALUE(0, "Passed\n");
305}
#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
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.
const char * ast_stir_shaken_vs_get_caller_id(struct ast_stir_shaken_vs_ctx *ctx)
Get caller_id from context.
enum ast_stir_shaken_vs_response_code ast_stir_shaken_vs_verify(struct ast_stir_shaken_vs_ctx *ctx)
Perform incoming call verification.
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.
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.
ast_stir_shaken_vs_response_code
@ 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:981

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_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 386 of file res_pjsip_stir_shaken.c.

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

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_stir_shaken_get_attestation_datastore(), ast_trace, 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, ast_party_number::str, and stir_shaken_attestation_ds::suppress.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 492 of file res_pjsip_stir_shaken.c.

493{
495 return 0;
496}
void ast_sip_session_unregister_supplement(struct ast_sip_session_supplement *supplement)
Unregister a an supplement to SIP session processing.

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 89 of file res_pjsip_stir_shaken.c.

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

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 513 of file res_pjsip_stir_shaken.c.

◆ date_hdr_str

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

Definition at line 41 of file res_pjsip_stir_shaken.c.

41{ "Date", 4 };

Referenced by add_date_header(), and stir_shaken_incoming_request().

◆ identity_hdr_str

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

Definition at line 40 of file res_pjsip_stir_shaken.c.

40{ "Identity", 8 };

Referenced by stir_shaken_incoming_request(), and stir_shaken_outgoing_request().

◆ stir_shaken_supplement

struct ast_sip_session_supplement stir_shaken_supplement
static

Definition at line 485 of file res_pjsip_stir_shaken.c.

485 {
486 .method = "INVITE",
487 .priority = AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL + 1, /* Run AFTER channel creation */
488 .incoming_request = stir_shaken_incoming_request,
489 .outgoing_request = stir_shaken_outgoing_request,
490};
@ AST_SIP_SUPPLEMENT_PRIORITY_CHANNEL
Definition res_pjsip.h:3339
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)

Referenced by load_module(), and unload_module().