Asterisk - The Open Source Telephony Project  21.4.1
Functions
security_agreements.c File Reference

Interact with security agreement negotiations and mechanisms. More...

#include "asterisk.h"
#include <pjsip.h>
#include "asterisk/res_pjsip.h"

Go to the source code of this file.

Functions

int ast_sip_add_security_headers (struct ast_sip_security_mechanism_vector *security_mechanisms, const char *header_name, int add_qval, pjsip_tx_data *tdata)
 Add security headers to transmission data. More...
 
void ast_sip_header_to_security_mechanism (const pjsip_generic_string_hdr *hdr, struct ast_sip_security_mechanism_vector *security_mechanisms)
 Append to security mechanism vector from SIP header. More...
 
void ast_sip_remove_headers_by_name_and_value (pjsip_msg *msg, const pj_str_t *hdr_name, const char *value)
 Removes all headers of a specific name and value from a pjsip_msg. More...
 
static char * ast_sip_security_mechanism_type_to_str (enum ast_sip_security_mechanism_type mech_type)
 
int ast_sip_security_mechanism_vector_init (struct ast_sip_security_mechanism_vector *security_mechanisms, const char *value)
 Initialize security mechanism vector from string of security mechanisms. More...
 
static struct ast_sip_security_mechanismast_sip_security_mechanisms_alloc (size_t n_params)
 
static struct ast_sip_security_mechanismast_sip_security_mechanisms_copy (const struct ast_sip_security_mechanism *src)
 
static void ast_sip_security_mechanisms_destroy (struct ast_sip_security_mechanism *mech)
 
int ast_sip_security_mechanisms_to_str (const struct ast_sip_security_mechanism_vector *security_mechanisms, int add_qvalue, char **buf)
 Writes the security mechanisms of an endpoint into a buffer as a string and returns the buffer. More...
 
void ast_sip_security_mechanisms_vector_copy (struct ast_sip_security_mechanism_vector *dst, const struct ast_sip_security_mechanism_vector *src)
 Duplicate a security mechanism. More...
 
void ast_sip_security_mechanisms_vector_destroy (struct ast_sip_security_mechanism_vector *security_mechanisms)
 Free contents of a security mechanism vector. More...
 
int ast_sip_str_to_security_mechanism (struct ast_sip_security_mechanism **security_mechanism, const char *value)
 Allocate a security mechanism from a string. More...
 
static int ast_sip_str_to_security_mechanism_type (const char *security_mechanism)
 
static float parse_qvalue (const char *q_value)
 
static int security_mechanism_to_str (const struct ast_sip_security_mechanism *security_mechanism, int add_qvalue, char **buf)
 

Detailed Description

Interact with security agreement negotiations and mechanisms.

Author
Maximilian Fridrich m.fri.nosp@m.dric.nosp@m.h@com.nosp@m.mend.nosp@m..com

Definition in file security_agreements.c.

Function Documentation

int ast_sip_add_security_headers ( struct ast_sip_security_mechanism_vector security_mechanisms,
const char *  header_name,
int  add_qval,
pjsip_tx_data *  tdata 
)

Add security headers to transmission data.

Parameters
security_mechanismsVector of security mechanisms.
header_nameThe header name under which to add the security mechanisms. One of Security-Client, Security-Server, Security-Verify.
add_qvalIf zero, don't add the q-value to the header.
tdataThe transmission data.
Return values
0Success
non-zeroFailure

Definition at line 286 of file security_agreements.c.

References AST_VECTOR_GET, and AST_VECTOR_SIZE.

287  {
288  struct ast_sip_security_mechanism *mech;
289  char *buf;
290  int mech_cnt;
291  int i;
292  int add_qvalue = 1;
293  static const pj_str_t proxy_require = { "Proxy-Require", 13 };
294  static const pj_str_t require = { "Require", 7 };
295 
296  if (!security_mechanisms || !tdata) {
297  return EINVAL;
298  }
299 
300  if (!strcmp(header_name, "Security-Client")) {
301  add_qvalue = 0;
302  } else if (strcmp(header_name, "Security-Server") &&
303  strcmp(header_name, "Security-Verify")) {
304  return EINVAL;
305  }
306  /* If we're adding Security-Client headers, don't add q-value
307  * even if the function caller requested it. */
308  add_qvalue = add_qvalue && add_qval;
309 
310  mech_cnt = AST_VECTOR_SIZE(security_mechanisms);
311  for (i = 0; i < mech_cnt; ++i) {
312  mech = AST_VECTOR_GET(security_mechanisms, i);
313  if (security_mechanism_to_str(mech, add_qvalue, &buf)) {
314  continue;
315  }
316  ast_sip_add_header(tdata, header_name, buf);
317  ast_free(buf);
318  }
319 
320  if (pjsip_msg_find_hdr_by_name(tdata->msg, &require, NULL) == NULL) {
321  ast_sip_add_header(tdata, "Require", "mediasec");
322  }
323  if (pjsip_msg_find_hdr_by_name(tdata->msg, &proxy_require, NULL) == NULL) {
324  ast_sip_add_header(tdata, "Proxy-Require", "mediasec");
325  }
326  return 0;
327 }
Structure representing a security mechanism as defined in RFC 3329.
Definition: res_pjsip.h:378
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
void ast_sip_header_to_security_mechanism ( const pjsip_generic_string_hdr *  hdr,
struct ast_sip_security_mechanism_vector security_mechanisms 
)

Append to security mechanism vector from SIP header.

Parameters
hdrThe header of the security mechanisms.
security_mechanismsVector of security mechanisms to append to. Header name must be one of Security-Client, Security-Server, Security-Verify.

Definition at line 329 of file security_agreements.c.

References ast_sip_str_to_security_mechanism(), ast_skip_blanks(), ast_strsep(), AST_STRSEP_ALL, and AST_VECTOR_APPEND.

330  {
331 
332  struct ast_sip_security_mechanism *mech;
333  char buf[512];
334  char *hdr_val;
335  char *mechanism;
336 
337  if (!security_mechanisms || !hdr) {
338  return;
339  }
340 
341  if (pj_stricmp2(&hdr->name, "Security-Client") && pj_stricmp2(&hdr->name, "Security-Server") &&
342  pj_stricmp2(&hdr->name, "Security-Verify")) {
343  return;
344  }
345 
346  ast_copy_pj_str(buf, &hdr->hvalue, sizeof(buf));
347  hdr_val = ast_skip_blanks(buf);
348 
349  while ((mechanism = ast_strsep(&hdr_val, ',', AST_STRSEP_ALL))) {
350  if (!ast_sip_str_to_security_mechanism(&mech, mechanism)) {
351  AST_VECTOR_APPEND(security_mechanisms, mech);
352  }
353  }
354 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
Structure representing a security mechanism as defined in RFC 3329.
Definition: res_pjsip.h:378
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:161
int ast_sip_str_to_security_mechanism(struct ast_sip_security_mechanism **security_mechanism, const char *value)
Allocate a security mechanism from a string.
void ast_sip_remove_headers_by_name_and_value ( pjsip_msg *  msg,
const pj_str_t *  hdr_name,
const char *  value 
)

Removes all headers of a specific name and value from a pjsip_msg.

Parameters
msgPJSIP message from which to remove headers.
hdr_nameName of the header to remove.
valueOptional string value of the header to remove. If NULL, remove all headers of given hdr_name.

Definition at line 199 of file security_agreements.c.

200 {
201  struct pjsip_generic_string_hdr *hdr = pjsip_msg_find_hdr_by_name(msg, hdr_name, NULL);
202  for (; hdr; hdr = pjsip_msg_find_hdr_by_name(msg, hdr_name, hdr->next)) {
203  if (value == NULL || !pj_strcmp2(&hdr->hvalue, value)) {
204  pj_list_erase(hdr);
205  }
206  if (hdr->next == hdr) {
207  break;
208  }
209  }
210 }
int ast_sip_security_mechanism_vector_init ( struct ast_sip_security_mechanism_vector security_mechanism,
const char *  value 
)

Initialize security mechanism vector from string of security mechanisms.

Parameters
security_mechanismPointer to vector of security mechanisms to initialize.
valueString of security mechanisms as defined in RFC 3329.
Return values
0Success
non-zeroFailure

Definition at line 356 of file security_agreements.c.

References ast_sip_security_mechanisms_vector_destroy(), ast_sip_str_to_security_mechanism(), ast_strdupa, ast_strsep(), AST_STRSEP_ALL, AST_VECTOR_APPEND, and AST_VECTOR_INIT.

357 {
358  char *val = value ? ast_strdupa(value) : NULL;
359  struct ast_sip_security_mechanism *mech;
360  char *mechanism;
361 
362  ast_sip_security_mechanisms_vector_destroy(security_mechanisms);
363  if (AST_VECTOR_INIT(security_mechanisms, 1)) {
364  return -1;
365  }
366 
367  if (!val) {
368  return 0;
369  }
370 
371  while ((mechanism = ast_strsep(&val, ',', AST_STRSEP_ALL))) {
372  if (!ast_sip_str_to_security_mechanism(&mech, mechanism)) {
373  AST_VECTOR_APPEND(security_mechanisms, mech);
374  }
375  }
376 
377  return 0;
378 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
Structure representing a security mechanism as defined in RFC 3329.
Definition: res_pjsip.h:378
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835
int ast_sip_str_to_security_mechanism(struct ast_sip_security_mechanism **security_mechanism, const char *value)
Allocate a security mechanism from a string.
void ast_sip_security_mechanisms_vector_destroy(struct ast_sip_security_mechanism_vector *security_mechanisms)
Free contents of a security mechanism vector.
int ast_sip_security_mechanisms_to_str ( const struct ast_sip_security_mechanism_vector security_mechanisms,
int  add_qvalue,
char **  buf 
)

Writes the security mechanisms of an endpoint into a buffer as a string and returns the buffer.

Note
The buffer must be freed by the caller.
Parameters
endpointPointer to endpoint.
add_qvalueIf non-zero, the q-value is printed as well
bufThe buffer to write the string into
Return values
0Success
non-zeroFailure

Definition at line 169 of file security_agreements.c.

References ast_strdup, AST_VECTOR_GET, and AST_VECTOR_SIZE.

170 {
171  size_t vec_size;
172  struct ast_sip_security_mechanism *mech;
173  char *tmp_buf;
174  char ret[512];
175  size_t i;
176 
177  if (!security_mechanisms) {
178  return -1;
179  }
180 
181  vec_size = AST_VECTOR_SIZE(security_mechanisms);
182  ret[0] = '\0';
183 
184  for (i = 0; i < vec_size; ++i) {
185  mech = AST_VECTOR_GET(security_mechanisms, i);
186  if (security_mechanism_to_str(mech, add_qvalue, &tmp_buf)) {
187  continue;
188  }
189  snprintf(ret + strlen(ret), sizeof(ret) - 1, "%s%s",
190  tmp_buf, i == vec_size - 1 ? "" : ", ");
191  ast_free(tmp_buf);
192  }
193 
194  *buf = ast_strdup(ret);
195 
196  return 0;
197 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure representing a security mechanism as defined in RFC 3329.
Definition: res_pjsip.h:378
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
void ast_sip_security_mechanisms_vector_copy ( struct ast_sip_security_mechanism_vector dst,
const struct ast_sip_security_mechanism_vector src 
)

Duplicate a security mechanism.

Parameters
dstSecurity mechanism to duplicate to.
srcSecurity mechanism to duplicate.

Definition at line 85 of file security_agreements.c.

References ast_sip_security_mechanisms_vector_destroy(), AST_VECTOR_APPEND, AST_VECTOR_GET, and AST_VECTOR_SIZE.

87 {
88  struct ast_sip_security_mechanism *mech;
89  int i;
90 
92  for (i = 0; i < AST_VECTOR_SIZE(src); i++) {
93  mech = AST_VECTOR_GET(src, i);
94  AST_VECTOR_APPEND(dst, ast_sip_security_mechanisms_copy(mech));
95  }
96 };
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
Structure representing a security mechanism as defined in RFC 3329.
Definition: res_pjsip.h:378
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
void ast_sip_security_mechanisms_vector_destroy(struct ast_sip_security_mechanism_vector *security_mechanisms)
Free contents of a security mechanism vector.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
void ast_sip_security_mechanisms_vector_destroy ( struct ast_sip_security_mechanism_vector security_mechanisms)

Free contents of a security mechanism vector.

Parameters
security_mechanismsVector whose contents are to be freed

Definition at line 98 of file security_agreements.c.

References AST_VECTOR_FREE, AST_VECTOR_GET, and AST_VECTOR_SIZE.

Referenced by ast_sip_security_mechanism_vector_init(), and ast_sip_security_mechanisms_vector_copy().

99 {
100  struct ast_sip_security_mechanism *mech;
101  int i;
102 
103  if (!security_mechanisms) {
104  return;
105  }
106 
107  for (i = 0; i < AST_VECTOR_SIZE(security_mechanisms); i++) {
108  mech = AST_VECTOR_GET(security_mechanisms, i);
109  ast_sip_security_mechanisms_destroy(mech);
110  }
111  AST_VECTOR_FREE(security_mechanisms);
112 }
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
Structure representing a security mechanism as defined in RFC 3329.
Definition: res_pjsip.h:378
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:680
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
int ast_sip_str_to_security_mechanism ( struct ast_sip_security_mechanism **  security_mechanism,
const char *  value 
)

Allocate a security mechanism from a string.

Parameters
security_mechanismPointer-pointer to the security mechanism to allocate.
valueThe security mechanism string as defined in RFC 3329 (section 2.2) in the form <mechanism_name>;q=<q_value>;<mechanism_parameters>
Return values
0Success
non-zeroFailure

Definition at line 238 of file security_agreements.c.

References ast_strdup, ast_strdupa, ast_strsep(), AST_STRSEP_ALL, and AST_VECTOR_APPEND.

Referenced by ast_sip_header_to_security_mechanism(), and ast_sip_security_mechanism_vector_init().

238  {
239  struct ast_sip_security_mechanism *mech;
240  char *param;
241  char *tmp;
242  char *mechanism = ast_strdupa(value);
243  int err = 0;
244  int type = -1;
245 
246  mech = ast_sip_security_mechanisms_alloc(1);
247  if (!mech) {
248  err = ENOMEM;
249  goto out;
250  }
251 
252  tmp = ast_strsep(&mechanism, ';', AST_STRSEP_ALL);
253  type = ast_sip_str_to_security_mechanism_type(tmp);
254  if (type == -1) {
255  err = EINVAL;
256  goto out;
257  }
258 
259  mech->type = type;
260  while ((param = ast_strsep(&mechanism, ';', AST_STRSEP_ALL))) {
261  if (!param) {
262  err = EINVAL;
263  goto out;
264  }
265  if (!strncmp(param, "q=", 2)) {
266  mech->qvalue = parse_qvalue(&param[2]);
267  if (mech->qvalue < 0.0) {
268  err = EINVAL;
269  goto out;
270  }
271  continue;
272  }
273  param = ast_strdup(param);
274  AST_VECTOR_APPEND(&mech->mechanism_parameters, param);
275  }
276 
277  *security_mechanism = mech;
278 
279 out:
280  if (err && (mech != NULL)) {
281  ast_sip_security_mechanisms_destroy(mech);
282  }
283  return err;
284 }
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure representing a security mechanism as defined in RFC 3329.
Definition: res_pjsip.h:378
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Definition: utils.c:1835