Asterisk - The Open Source Telephony Project  GIT-master-44aef04
Data Structures | Macros | Enumerations | Functions
acl.h File Reference

Access Control of various sorts. More...

#include "asterisk/network.h"
#include "asterisk/linkedlists.h"
#include "asterisk/netsock2.h"
#include "asterisk/io.h"

Go to the source code of this file.

Data Structures

struct  ast_acl
 an ast_acl is a linked list node of ast_ha structs which may have names. More...
 
struct  ast_acl_list
 Wrapper for an ast_acl linked list. More...
 
struct  ast_ha
 internal representation of ACL entries In principle user applications would have no need for this, but there is sometimes a need to extract individual items, e.g. to print them, and rather than defining iterators to navigate the list, and an externally visible 'struct ast_ha_entry', at least in the short term it is more convenient to make the whole thing public and let users play with them. More...
 

Macros

#define ACL_NAME_LENGTH   80
 

Enumerations

enum  ast_acl_sense { AST_SENSE_DENY, AST_SENSE_ALLOW }
 

Functions

int ast_acl_list_is_empty (struct ast_acl_list *acl_list)
 Determines if an ACL is empty or if it contains entries. More...
 
void ast_acl_output (int fd, struct ast_acl_list *acl, const char *prefix)
 output an ACL to the provided fd More...
 
void ast_append_acl (const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
 Add a rule to an ACL struct. More...
 
struct ast_haast_append_ha (const char *sense, const char *stuff, struct ast_ha *path, int *error)
 Add a new rule to a list of HAs. More...
 
struct ast_haast_append_ha_with_port (const char *sense, const char *stuff, struct ast_ha *path, int *error)
 Add a new rule with optional port to a list of HAs. More...
 
enum ast_acl_sense ast_apply_acl (struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
 Apply a set of rules to a given IP address. More...
 
enum ast_acl_sense ast_apply_acl_nolog (struct ast_acl_list *acl_list, const struct ast_sockaddr *addr)
 Apply a set of rules to a given IP address, don't log failure. More...
 
enum ast_acl_sense ast_apply_ha (const struct ast_ha *ha, const struct ast_sockaddr *addr)
 Apply a set of rules to a given IP address. More...
 
void ast_copy_ha (const struct ast_ha *from, struct ast_ha *to)
 Copy the contents of one HA to another. More...
 
struct ast_acl_listast_duplicate_acl_list (struct ast_acl_list *original)
 Duplicates the contests of a list of lists of host access rules. More...
 
struct ast_haast_duplicate_ha_list (struct ast_ha *original)
 Duplicate the contents of a list of host access rules. More...
 
int ast_find_ourip (struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
 Find our IP address. More...
 
struct ast_acl_listast_free_acl_list (struct ast_acl_list *acl)
 Free a list of ACLs. More...
 
void ast_free_ha (struct ast_ha *ha)
 Free a list of HAs. More...
 
int ast_get_ip (struct ast_sockaddr *addr, const char *hostname)
 Get the IP address given a hostname. More...
 
int ast_get_ip_or_srv (struct ast_sockaddr *addr, const char *hostname, const char *service)
 Get the IP address given a hostname and optional service. More...
 
void ast_ha_join (const struct ast_ha *ha, struct ast_str **buf)
 Convert HAs to a comma separated string value. More...
 
void ast_ha_join_cidr (const struct ast_ha *ha, struct ast_str **buf)
 Convert HAs to a comma separated string value using CIDR notation. More...
 
void ast_ha_output (int fd, const struct ast_ha *ha, const char *prefix)
 output an HA to the provided fd More...
 
int ast_lookup_iface (char *iface, struct ast_sockaddr *address)
 Find an IP address associated with a specific interface. More...
 
struct stasis_message_typeast_named_acl_change_type (void)
 a stasis_message_type for changes against a named ACL or the set of all named ACLs More...
 
struct ast_haast_named_acl_find (const char *name, int *is_realtime, int *is_undefined)
 Retrieve a named ACL. More...
 
int ast_ouraddrfor (const struct ast_sockaddr *them, struct ast_sockaddr *us)
 Get our local IP address when contacting a remote host. More...
 
int ast_str2cos (const char *value, unsigned int *cos)
 Convert a string to the appropriate COS value. More...
 
int ast_str2tos (const char *value, unsigned int *tos)
 Convert a string to the appropriate TOS value. More...
 
const char * ast_tos2str (unsigned int tos)
 Convert a TOS value into its string representation. More...
 

Detailed Description

Access Control of various sorts.

Definition in file acl.h.

Macro Definition Documentation

◆ ACL_NAME_LENGTH

#define ACL_NAME_LENGTH   80

Definition at line 59 of file acl.h.

Referenced by acl_new().

Enumeration Type Documentation

◆ ast_acl_sense

Enumerator
AST_SENSE_DENY 
AST_SENSE_ALLOW 

Definition at line 36 of file acl.h.

36  {
39 };

Function Documentation

◆ ast_acl_list_is_empty()

int ast_acl_list_is_empty ( struct ast_acl_list acl_list)

Determines if an ACL is empty or if it contains entries.

Parameters
acl_listThe ACL list being checked
Return values
0- the list is not empty
1- the list is empty

Definition at line 541 of file acl.c.

References AST_LIST_FIRST, AST_LIST_LOCK, and AST_LIST_UNLOCK.

Referenced by _sip_show_peer(), _sip_show_peers_one(), acl_to_str(), apply_acl(), apply_contact_acl(), apply_endpoint_acl(), apply_endpoint_contact_acl(), contact_acl_to_str(), handle_cli_iax2_show_peer(), handle_cli_iax2_show_users(), handle_showmanager(), sip_show_user(), and sip_show_users().

542 {
543  struct ast_acl *head;
544 
545  if (!acl_list) {
546  return 1;
547  }
548 
549  AST_LIST_LOCK(acl_list);
550  head = AST_LIST_FIRST(acl_list);
551  AST_LIST_UNLOCK(acl_list);
552 
553  if (head) {
554  return 0;
555  }
556 
557  return 1;
558 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
an ast_acl is a linked list node of ast_ha structs which may have names.
Definition: acl.h:67

◆ ast_acl_output()

void ast_acl_output ( int  fd,
struct ast_acl_list acl,
const char *  prefix 
)

output an ACL to the provided fd

This function can be used centrally to output HAs as used in ACLs from other modules. It follows the format as originally used for named ACLs in named_acl.c.

Parameters
fdThe file-descriptor to which to output the ACL.
aclThe ACL to output.
prefixIf you need a specific prefix output on each line, give it here, may be NULL.
Since
13.33.0, 16.10.0, 17.4.0

Definition at line 1099 of file acl.c.

References ast_acl::acl, ast_cli(), ast_ha_output(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero, ast_acl::is_realtime, ast_acl::list, and ast_acl::name.

Referenced by handle_showmanager().

1100 {
1101  struct ast_acl *acl;
1102 
1103  AST_LIST_LOCK(acl_list);
1104  AST_LIST_TRAVERSE(acl_list, acl, list) {
1105  ast_cli(fd, "%sACL: %s%s\n---------------------------------------------\n",
1106  prefix ?: "", ast_strlen_zero(acl->name) ? "(unnamed)" : acl->name,
1107  acl->is_realtime ? " (realtime)" : "");
1108 
1109  ast_ha_output(fd, acl->acl, prefix);
1110  }
1111  AST_LIST_UNLOCK(acl_list);
1112 
1113 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char name[ACL_NAME_LENGTH]
Definition: acl.h:71
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
int is_realtime
Definition: acl.h:69
struct ast_ha * acl
Definition: acl.h:68
an ast_acl is a linked list node of ast_ha structs which may have names.
Definition: acl.h:67
struct ast_acl::@212 list
void ast_ha_output(int fd, const struct ast_ha *ha, const char *prefix)
output an HA to the provided fd
Definition: acl.c:1087
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_append_acl()

void ast_append_acl ( const char *  sense,
const char *  stuff,
struct ast_acl_list **  path,
int *  error,
int *  named_acl_flag 
)

Add a rule to an ACL struct.

This adds a named ACL or an ACL rule to an ast_acl container. It works in a similar way to ast_append_ha.

Parameters
senseCan be any among "permit", "deny", or "acl" this controls whether the rule being added will simply modify the unnamed ACL at the head of the list or if a new named ACL will be added to that ast_acl.
stuffIf sense is 'permit'/'deny', this is the ip address and subnet mask separated with a '/' like in ast_append ha. If it sense is 'acl', then this will be the name of the ACL being appended to the container.
pathAddress of the ACL list being appended
[out]errorThe int that error points to will be set to 1 if an error occurs.
[out]named_acl_flagThis will raise a flag under certain conditions to indicate that a named ACL has been added by this operation. This may be used to indicate that an event subscription should be made against the named ACL subsystem. Note: This flag may be raised by this function, but it will never be lowered by it.

Definition at line 430 of file acl.c.

References ast_acl::acl, acl_new(), ast_append_ha(), ast_calloc, AST_LIST_FIRST, AST_LIST_HEAD_INIT, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_named_acl_find(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero, ast_acl::is_invalid, ast_acl::is_realtime, LOG_ERROR, ast_acl::name, NULL, strsep(), and tmp().

Referenced by __init_manager(), acl_handler(), build_peer(), build_user(), endpoint_acl_handler(), reload_config(), and rtp_reload().

431 {
432  struct ast_acl *acl = NULL;
433  struct ast_acl *current;
434  struct ast_acl_list *working_list;
435 
436  char *tmp, *list;
437 
438  /* If the ACL list is currently uninitialized, it must be initialized. */
439  if (*path == NULL) {
440  struct ast_acl_list *list;
441  list = ast_calloc(1, sizeof(*list));
442  if (!list) {
443  /* Allocation Error */
444  if (error) {
445  *error = 1;
446  }
447  return;
448  }
449 
450  AST_LIST_HEAD_INIT(list);
451  *path = list;
452  }
453 
454  working_list = *path;
455 
456  AST_LIST_LOCK(working_list);
457 
458  /* First we need to determine if we will need to add a new ACL node or if we can use an existing one. */
459  if (strncasecmp(sense, "a", 1)) {
460  /* The first element in the path should be the unnamed, base ACL. If that's the case, we use it. If not,
461  * we have to make one and link it up appropriately. */
462  current = AST_LIST_FIRST(working_list);
463 
464  if (!current || !ast_strlen_zero(current->name)) {
465  if (acl_new(&acl, "")) {
466  if (error) {
467  *error = 1;
468  }
469  AST_LIST_UNLOCK(working_list);
470  return;
471  }
472  // Need to INSERT the ACL at the head here.
473  AST_LIST_INSERT_HEAD(working_list, acl, list);
474  } else {
475  /* If the first element was already the unnamed base ACL, we just use that one. */
476  acl = current;
477  }
478 
479  /* With the proper ACL set for modification, we can just pass this off to the ast_ha append function. */
480  acl->acl = ast_append_ha(sense, stuff, acl->acl, error);
481 
482  AST_LIST_UNLOCK(working_list);
483  return;
484  }
485 
486  /* We are in ACL append mode, so we know we'll be adding one or more named ACLs. */
487  list = ast_strdupa(stuff);
488 
489  while ((tmp = strsep(&list, ","))) {
490  struct ast_ha *named_ha;
491  int already_included = 0;
492 
493  /* Remove leading whitespace from the string in case the user put spaces between items */
494  tmp = ast_skip_blanks(tmp);
495 
496  /* The first step is to check for a duplicate */
497  AST_LIST_TRAVERSE(working_list, current, list) {
498  if (!strcasecmp(current->name, tmp)) { /* ACL= */
499  /* Inclusion of the same ACL multiple times isn't a catastrophic error, but it will raise the error flag and skip the entry. */
500  ast_log(LOG_ERROR, "Named ACL '%s' occurs multiple times in ACL definition. "
501  "Please update your ACL configuration.\n", tmp);
502  if (error) {
503  *error = 1;
504  }
505  already_included = 1;
506  break;
507  }
508  }
509 
510  if (already_included) {
511  continue;
512  }
513 
514  if (acl_new(&acl, tmp)) {
515  /* This is a catastrophic allocation error and we'll return immediately if this happens. */
516  if (error) {
517  *error = 1;
518  }
519  AST_LIST_UNLOCK(working_list);
520  return;
521  }
522 
523  /* Attempt to grab the Named ACL we are looking for. */
524  named_ha = ast_named_acl_find(tmp, &acl->is_realtime, &acl->is_invalid);
525 
526  /* Set the ACL's ast_ha to the duplicated named ACL retrieved above. */
527  acl->acl = named_ha;
528 
529  /* Raise the named_acl_flag since we are adding a named ACL to the ACL container. */
530  if (named_acl_flag) {
531  *named_acl_flag = 1;
532  }
533 
534  /* Now insert the new ACL at the end of the list. */
535  AST_LIST_INSERT_TAIL(working_list, acl, list);
536  }
537 
538  AST_LIST_UNLOCK(working_list);
539 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
static int tmp()
Definition: bt_open.c:389
char name[ACL_NAME_LENGTH]
Definition: acl.h:71
struct ast_ha * ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
Add a new rule to a list of HAs.
Definition: acl.c:713
Wrapper for an ast_acl linked list.
Definition: acl.h:76
#define NULL
Definition: resample.c:96
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
int is_realtime
Definition: acl.h:69
#define ast_log
Definition: astobj2.c:42
int is_invalid
Definition: acl.h:70
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
struct ast_ha * acl
Definition: acl.h:68
an ast_acl is a linked list node of ast_ha structs which may have names.
Definition: acl.h:67
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
char * ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Definition: strings.h:157
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define ast_strlen_zero(a)
Definition: muted.c:73
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
Definition: test_acl.c:111
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct ast_ha * ast_named_acl_find(const char *name, int *is_realtime, int *is_undefined)
Retrieve a named ACL.
Definition: named_acl.c:293
char * strsep(char **str, const char *delims)
int error(const char *format,...)
Definition: utils/frame.c:999
static int acl_new(struct ast_acl **pointer, const char *name)
Definition: acl.c:305

◆ ast_append_ha()

struct ast_ha* ast_append_ha ( const char *  sense,
const char *  stuff,
struct ast_ha path,
int *  error 
)

Add a new rule to a list of HAs.

This adds the new host access rule to the end of the list whose head is specified by the path parameter. Rules are evaluated in a way such that if multiple rules apply to a single IP address/subnet mask, then the rule latest in the list will be used.

Parameters
senseEither "permit" or "deny" (Actually any 'p' word will result in permission, and any other word will result in denial)
stuffThe IP address and subnet mask, separated with a '/'. The subnet mask can either be in dotted-decimal format or in CIDR notation (i.e. 0-32).
pathThe head of the HA list to which we wish to append our new rule. If NULL is passed, then the new rule will become the head of the list
[out]errorThe integer error points to will be set non-zero if an error occurs
Returns
The head of the HA list

Definition at line 713 of file acl.c.

References append_ha_core(), and PARSE_PORT_FORBID.

Referenced by acl_handler_fn(), add_calltoken_ignore(), ast_append_acl(), AST_TEST_DEFINE(), build_callno_limits(), build_device(), build_gateway(), build_ha(), config_parse_variables(), named_acl_find_realtime(), reload_config(), and transport_localnet_handler().

714 {
715  return append_ha_core(sense, stuff, path, error, PARSE_PORT_FORBID);
716 }
static struct ast_ha * append_ha_core(const char *sense, const char *stuff, struct ast_ha *path, int *error, int port_flags)
Definition: acl.c:576
enum ast_acl_sense sense
Definition: acl.h:55
int error(const char *format,...)
Definition: utils/frame.c:999

◆ ast_append_ha_with_port()

struct ast_ha* ast_append_ha_with_port ( const char *  sense,
const char *  stuff,
struct ast_ha path,
int *  error 
)

Add a new rule with optional port to a list of HAs.

Since
13.31.0, 16.8.0, 17.2.0

This adds the new host access rule to the end of the list whose head is specified by the path parameter. Rules are evaluated in a way such that if multiple rules apply to a single IP address/subnet mask, then the rule latest in the list will be used.

Parameters
senseEither "permit" or "deny" (Actually any 'p' word will result in permission, and any other word will result in denial)
stuffThe IP address and subnet mask, separated with a '/'. The subnet mask can either be in dotted-decimal format or in CIDR notation (i.e. 0-32). A port can be provided by placing it after the IP address, separated with a ':'.
pathThe head of the HA list to which we wish to append our new rule. If NULL is passed, then the new rule will become the head of the list
[out]errorThe integer error points to will be set non-zero if an error occurs
Returns
The head of the HA list

Definition at line 718 of file acl.c.

References append_ha_core().

Referenced by ip_identify_match_handler(), ip_identify_match_host_lookup(), and pjsip_enable_logger_host().

719 {
720  return append_ha_core(sense, stuff, path, error, 0);
721 }
static struct ast_ha * append_ha_core(const char *sense, const char *stuff, struct ast_ha *path, int *error, int port_flags)
Definition: acl.c:576
enum ast_acl_sense sense
Definition: acl.h:55
int error(const char *format,...)
Definition: utils/frame.c:999

◆ ast_apply_acl()

enum ast_acl_sense ast_apply_acl ( struct ast_acl_list acl_list,
const struct ast_sockaddr addr,
const char *  purpose 
)

Apply a set of rules to a given IP address.

Similar to the above, only uses an acl container, which is a whole slew of ast_ha lists. It runs ast_apply_ha on each of the ast_ha structs contained in the acl container. It will deny if any of the ast_ha lists fail, and it will pass only if all of the rules pass.

Parameters
acl_listThe head of the list of ACLs to evaluate
addrAn ast_sockaddr whose address is considered when matching rules
purposeContext for which the ACL is being applied - Establishes purpose of a notice when rejected
Return values
AST_SENSE_ALLOWThe IP address passes our ACLs
AST_SENSE_DENYThe IP address fails our ACLs

Definition at line 800 of file acl.c.

References ast_apply_acl_internal().

Referenced by apply_acl(), apply_contact_acl(), apply_endpoint_acl(), apply_endpoint_contact_acl(), auth_http_callback(), authenticate(), check_access(), check_peer_ok(), parse_register_contact(), register_verify(), and sip_allow_anyrtp_remote().

800  {
801  return ast_apply_acl_internal(acl_list, addr, purpose ?: "");
802 }
static enum ast_acl_sense ast_apply_acl_internal(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *log_prefix)
Definition: acl.c:758

◆ ast_apply_acl_nolog()

enum ast_acl_sense ast_apply_acl_nolog ( struct ast_acl_list acl_list,
const struct ast_sockaddr addr 
)

Apply a set of rules to a given IP address, don't log failure.

Exactly like ast_apply_acl, except that it will never log anything.

Parameters
acl_listThe head of the list of ACLs to evaluate
addrAn ast_sockaddr whose address is considered when matching rules
Return values
AST_SENSE_ALLOWThe IP address passes our ACLs
AST_SENSE_DENYThe IP address fails our ACLs

Definition at line 804 of file acl.c.

References ast_apply_acl_internal(), and NULL.

Referenced by rtp_learning_start().

804  {
805  return ast_apply_acl_internal(acl_list, addr, NULL);
806 }
#define NULL
Definition: resample.c:96
static enum ast_acl_sense ast_apply_acl_internal(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *log_prefix)
Definition: acl.c:758

◆ ast_apply_ha()

enum ast_acl_sense ast_apply_ha ( const struct ast_ha ha,
const struct ast_sockaddr addr 
)

Apply a set of rules to a given IP address.

The list of host access rules is traversed, beginning with the input rule. If the IP address given matches a rule, the "sense" of that rule is used as the return value. Note that if an IP address matches multiple rules that the last one matched will be the one whose sense will be returned.

Parameters
haThe head of the list of host access rules to follow
addrAn ast_sockaddr whose address is considered when matching rules
Return values
AST_SENSE_ALLOWThe IP address passes our ACL
AST_SENSE_DENYThe IP address fails our ACL

Definition at line 808 of file acl.c.

References ast_ha::addr, ast_copy_string(), ast_debug, ast_log, AST_SENSE_ALLOW, ast_sockaddr_apply_netmask(), ast_sockaddr_cmp_addr(), ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv4_mapped(), ast_sockaddr_is_ipv6(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), LOG_ERROR, ast_ha::netmask, ast_ha::next, and ast_ha::sense.

Referenced by ast_apply_acl_internal(), ast_sip_ouraddrfor(), AST_TEST_DEFINE(), ip_identify_match_check(), ip_identify_match_host_lookup(), pjsip_log_test_addr(), and skinny_register().

809 {
810  /* Start optimistic */
811  enum ast_acl_sense res = AST_SENSE_ALLOW;
812  const struct ast_ha *current_ha;
813 
814  for (current_ha = ha; current_ha; current_ha = current_ha->next) {
815  struct ast_sockaddr result;
816  struct ast_sockaddr mapped_addr;
817  const struct ast_sockaddr *addr_to_use;
818  uint16_t save_port;
819 #if 0 /* debugging code */
820  char iabuf[INET_ADDRSTRLEN];
821  char iabuf2[INET_ADDRSTRLEN];
822  /* DEBUG */
823  ast_copy_string(iabuf, ast_sockaddr_stringify(addr), sizeof(iabuf));
824  ast_copy_string(iabuf2, ast_sockaddr_stringify(&current_ha->addr), sizeof(iabuf2));
825  ast_debug(1, "##### Testing %s with %s\n", iabuf, iabuf2);
826 #endif
827  if (ast_sockaddr_is_ipv4(&current_ha->addr)) {
828  if (ast_sockaddr_is_ipv6(addr)) {
829  if (ast_sockaddr_is_ipv4_mapped(addr)) {
830  /* IPv4 ACLs apply to IPv4-mapped addresses */
831  if (!ast_sockaddr_ipv4_mapped(addr, &mapped_addr)) {
832  ast_log(LOG_ERROR, "%s provided to ast_sockaddr_ipv4_mapped could not be converted. That shouldn't be possible.\n",
833  ast_sockaddr_stringify(addr));
834  continue;
835  }
836  addr_to_use = &mapped_addr;
837  } else {
838  /* An IPv4 ACL does not apply to an IPv6 address */
839  continue;
840  }
841  } else {
842  /* Address is IPv4 and ACL is IPv4. No biggie */
843  addr_to_use = addr;
844  }
845  } else {
847  addr_to_use = addr;
848  } else {
849  /* Address is IPv4 or IPv4 mapped but ACL is IPv6. Skip */
850  continue;
851  }
852  }
853 
854  /* ast_sockaddr_apply_netmask() does not preserve the port, so we need to save and
855  * restore it */
856  save_port = ast_sockaddr_port(addr_to_use);
857 
858  /* For each rule, if this address and the netmask = the net address
859  apply the current rule */
860  if (ast_sockaddr_apply_netmask(addr_to_use, &current_ha->netmask, &result)) {
861  /* Unlikely to happen since we know the address to be IPv4 or IPv6 */
862  continue;
863  }
864 
865  ast_sockaddr_set_port(&result, save_port);
866 
867  if (!ast_sockaddr_cmp_addr(&result, &current_ha->addr)
868  && (!ast_sockaddr_port(&current_ha->addr)
869  || ast_sockaddr_port(&current_ha->addr) == ast_sockaddr_port(&result))) {
870  res = current_ha->sense;
871  }
872  }
873  return res;
874 }
struct ast_ha * next
Definition: acl.h:56
struct ast_sockaddr addr
Definition: acl.h:53
int ast_sockaddr_ipv4_mapped(const struct ast_sockaddr *addr, struct ast_sockaddr *ast_mapped)
Convert an IPv4-mapped IPv6 address into an IPv4 address.
Definition: netsock2.c:37
enum ast_acl_sense sense
Definition: acl.h:55
Socket address structure.
Definition: netsock2.h:97
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:413
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
struct ast_sockaddr netmask
Definition: acl.h:54
ast_acl_sense
Definition: acl.h:36
int ast_sockaddr_apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask, struct ast_sockaddr *result)
Apply a netmask to an address and store the result in a separate structure.
Definition: netsock2.c:357
#define LOG_ERROR
Definition: logger.h:285
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260
int ast_sockaddr_is_ipv4_mapped(const struct ast_sockaddr *addr)
Determine if this is an IPv4-mapped IPv6 address.
Definition: netsock2.c:507
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:401
static PGresult * result
Definition: cel_pgsql.c:88
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524

◆ ast_copy_ha()

void ast_copy_ha ( const struct ast_ha from,
struct ast_ha to 
)

Copy the contents of one HA to another.

This copies the internals of the 'from' HA to the 'to' HA. It is important that the 'to' HA has been allocated prior to calling this function

Parameters
fromSource HA to copy
toDestination HA to copy to
Return values
void

Definition at line 255 of file acl.c.

References ast_ha::addr, ast_sockaddr_copy(), ast_ha::netmask, and ast_ha::sense.

Referenced by add_calltoken_ignore(), ast_duplicate_ha(), and build_callno_limits().

256 {
257  ast_sockaddr_copy(&to->addr, &from->addr);
258  ast_sockaddr_copy(&to->netmask, &from->netmask);
259  to->sense = from->sense;
260 }
struct ast_sockaddr addr
Definition: acl.h:53
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
enum ast_acl_sense sense
Definition: acl.h:55
struct ast_sockaddr netmask
Definition: acl.h:54

◆ ast_duplicate_acl_list()

struct ast_acl_list* ast_duplicate_acl_list ( struct ast_acl_list original)

Duplicates the contests of a list of lists of host access rules.

A deep copy of an ast_acl list is made (which in turn means a deep copy of each of the ast_ha structs contained within). The returned value is allocated on the heap and must be freed independently of the input paramater when finished.

Parameters
originalThe ast_acl_list to copy
Return values
Thenew duplicated ast_acl_list

Definition at line 316 of file acl.c.

References ast_acl::acl, acl_new(), ast_calloc, ast_duplicate_ha_list(), ast_free_acl_list(), AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log, ast_acl::is_invalid, ast_acl::is_realtime, ast_acl::list, LOG_ERROR, ast_acl::name, and NULL.

Referenced by create_addr_from_peer(), and sip_allow_anyrtp_remote().

317 {
318  struct ast_acl_list *clone;
319  struct ast_acl *current_cursor;
320  struct ast_acl *current_clone;
321 
322  /* Early return if we receive a duplication request for a NULL original. */
323  if (!original) {
324  return NULL;
325  }
326 
327  if (!(clone = ast_calloc(1, sizeof(*clone)))) {
328  ast_log(LOG_ERROR, "Failed to allocate ast_acl_list struct while cloning an ACL\n");
329  return NULL;
330  }
331  AST_LIST_HEAD_INIT(clone);
332 
333  AST_LIST_LOCK(original);
334 
335  AST_LIST_TRAVERSE(original, current_cursor, list) {
336  if ((acl_new(&current_clone, current_cursor->name))) {
337  ast_log(LOG_ERROR, "Failed to allocate ast_acl struct while cloning an ACL.\n");
338  ast_free_acl_list(clone);
339  clone = NULL;
340  break;
341  }
342 
343  /* Copy data from original ACL to clone ACL */
344  current_clone->acl = ast_duplicate_ha_list(current_cursor->acl);
345 
346  current_clone->is_invalid = current_cursor->is_invalid;
347  current_clone->is_realtime = current_cursor->is_realtime;
348 
349  AST_LIST_INSERT_TAIL(clone, current_clone, list);
350 
351  if (current_cursor->acl && !current_clone->acl) {
352  /* Deal with failure after adding to clone so we don't have to free
353  * current_clone separately. */
354  ast_log(LOG_ERROR, "Failed to duplicate HA list while cloning ACL.\n");
355  ast_free_acl_list(clone);
356  clone = NULL;
357  break;
358  }
359  }
360 
361  AST_LIST_UNLOCK(original);
362 
363  return clone;
364 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
char name[ACL_NAME_LENGTH]
Definition: acl.h:71
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl_list)
Free a list of ACLs.
Definition: acl.c:233
Wrapper for an ast_acl linked list.
Definition: acl.h:76
#define NULL
Definition: resample.c:96
int is_realtime
Definition: acl.h:69
#define ast_log
Definition: astobj2.c:42
int is_invalid
Definition: acl.h:70
struct ast_ha * acl
Definition: acl.h:68
an ast_acl is a linked list node of ast_ha structs which may have names.
Definition: acl.h:67
struct ast_acl::@212 list
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
struct ast_ha * ast_duplicate_ha_list(struct ast_ha *original)
Duplicate the contents of a list of host access rules.
Definition: acl.c:277
static int acl_new(struct ast_acl **pointer, const char *name)
Definition: acl.c:305

◆ ast_duplicate_ha_list()

struct ast_ha* ast_duplicate_ha_list ( struct ast_ha original)

Duplicate the contents of a list of host access rules.

A deep copy of all ast_has in the list is made. The returned value is allocated on the heap and must be freed independently of the input parameter when finished.

Parameters
originalThe ast_ha to copy
Return values
Thehead of the list of duplicated ast_has

Definition at line 277 of file acl.c.

References ast_duplicate_ha(), ast_free_ha(), ast_ha::next, and NULL.

Referenced by ast_duplicate_acl_list(), and ast_named_acl_find().

278 {
279  struct ast_ha *start = original;
280  struct ast_ha *ret = NULL;
281  struct ast_ha *current, *prev = NULL;
282 
283  while (start) {
284  current = ast_duplicate_ha(start); /* Create copy of this object */
285  if (!current) {
286  ast_free_ha(ret);
287 
288  return NULL;
289  }
290 
291  if (prev) {
292  prev->next = current; /* Link previous to this object */
293  }
294 
295  if (!ret) {
296  ret = current; /* Save starting point */
297  }
298 
299  start = start->next; /* Go to next object */
300  prev = current; /* Save pointer to this object */
301  }
302  return ret; /* Return start of list */
303 }
struct ast_ha * next
Definition: acl.h:56
#define NULL
Definition: resample.c:96
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
static struct ast_ha * ast_duplicate_ha(struct ast_ha *original)
Definition: acl.c:263

◆ ast_find_ourip()

int ast_find_ourip ( struct ast_sockaddr ourip,
const struct ast_sockaddr bindaddr,
int  family 
)

Find our IP address.

This function goes through many iterations in an attempt to find our IP address. If any step along the way should fail, we move to the next item in the list. Here are the steps taken:

  • If bindaddr has a non-zero IP address, that is copied into ourip
  • We use a combination of gethostname and ast_gethostbyname to find our IP address.
  • We use ast_ouraddrfor with 198.41.0.4 as the destination IP address
  • We try some platform-specific socket operations to find the IP address
Parameters
[out]ouripOur IP address is written here when it is found
bindaddrA hint used for finding our IP. See the steps above for more details
familyOnly addresses of the given family will be returned. Use 0 or AST_SOCKADDR_UNSPEC to get addresses of all families.
Return values
0Success
-1Failure

Definition at line 1052 of file acl.c.

References ast_debug, ast_log, ast_ouraddrfor(), ast_sockaddr_copy(), ast_sockaddr_is_any(), ast_sockaddr_port, ast_sockaddr_set_port, get_local_address(), LOG_WARNING, MAXHOSTNAMELEN, ourhost, PARSE_PORT_FORBID, and resolve_first().

Referenced by ast_rtp_prop_set(), and reload_config().

1053 {
1054  char ourhost[MAXHOSTNAMELEN] = "";
1055  struct ast_sockaddr root;
1056  int res, port = ast_sockaddr_port(ourip);
1057 
1058  /* just use the bind address if it is nonzero */
1059  if (!ast_sockaddr_is_any(bindaddr)) {
1060  ast_sockaddr_copy(ourip, bindaddr);
1061  ast_debug(3, "Attached to given IP address\n");
1062  return 0;
1063  }
1064  /* try to use our hostname */
1065  if (gethostname(ourhost, sizeof(ourhost) - 1)) {
1066  ast_log(LOG_WARNING, "Unable to get hostname\n");
1067  } else {
1068  if (resolve_first(ourip, ourhost, PARSE_PORT_FORBID, family) == 0) {
1069  /* reset port since resolve_first wipes this out */
1070  ast_sockaddr_set_port(ourip, port);
1071  return 0;
1072  }
1073  }
1074  ast_debug(3, "Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\n");
1075  /* A.ROOT-SERVERS.NET. */
1076  if (!resolve_first(&root, "A.ROOT-SERVERS.NET", PARSE_PORT_FORBID, 0) &&
1077  !ast_ouraddrfor(&root, ourip)) {
1078  /* reset port since resolve_first wipes this out */
1079  ast_sockaddr_set_port(ourip, port);
1080  return 0;
1081  }
1082  res = get_local_address(ourip);
1083  ast_sockaddr_set_port(ourip, port);
1084  return res;
1085 }
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:171
#define LOG_WARNING
Definition: logger.h:274
static char ourhost[MAXHOSTNAMELEN]
Definition: chan_mgcp.c:238
#define MAXHOSTNAMELEN
Definition: network.h:69
Socket address structure.
Definition: netsock2.h:97
static int resolve_first(struct ast_sockaddr *addr, const char *name, int flag, int family)
Definition: acl.c:876
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
int ast_sockaddr_is_any(const struct ast_sockaddr *addr)
Determine if the address type is unspecified, or "any" address.
Definition: netsock2.c:534
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int ast_ouraddrfor(const struct ast_sockaddr *them, struct ast_sockaddr *us)
Get our local IP address when contacting a remote host.
Definition: acl.c:1005
static int get_local_address(struct ast_sockaddr *ourip)
Definition: acl.c:118

◆ ast_free_acl_list()

struct ast_acl_list* ast_free_acl_list ( struct ast_acl_list acl)

Free a list of ACLs.

Given the head of a list of ast_acl structs, it and all appended acl structs will be freed. This includes the ast_ha structs within the individual nodes.

Parameters
aclThe list of ACLs to free
Return values
NULL

Definition at line 233 of file acl.c.

References ast_acl::acl, ast_free, ast_free_ha(), AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_acl::list, and NULL.

Referenced by __init_manager(), acl_destroy(), ast_duplicate_acl_list(), build_peer(), build_user(), endpoint_destructor(), manager_free_user(), peer_destructor(), reload_config(), rtp_learning_start(), rtp_reload(), sip_allow_anyrtp_remote(), sip_destroy_peer(), sip_pvt_dtor(), unload_module(), and user_destructor().

234 {
235  struct ast_acl *current;
236 
237  if (!acl_list) {
238  return NULL;
239  }
240 
241  AST_LIST_LOCK(acl_list);
242  while ((current = AST_LIST_REMOVE_HEAD(acl_list, list))) {
243  ast_free_ha(current->acl);
244  ast_free(current);
245  }
246  AST_LIST_UNLOCK(acl_list);
247 
248  AST_LIST_HEAD_DESTROY(acl_list);
249  ast_free(acl_list);
250 
251  return NULL;
252 }
#define AST_LIST_LOCK(head)
Locks a list.
Definition: linkedlists.h:39
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
Definition: linkedlists.h:139
#define NULL
Definition: resample.c:96
void ast_free_ha(struct ast_ha *ha)
Free a list of HAs.
Definition: acl.c:222
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
struct ast_ha * acl
Definition: acl.h:68
an ast_acl is a linked list node of ast_ha structs which may have names.
Definition: acl.h:67
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
struct ast_acl::@212 list
#define ast_free(a)
Definition: astmm.h:182

◆ ast_free_ha()

void ast_free_ha ( struct ast_ha ha)

Free a list of HAs.

Given the head of a list of HAs, it and all appended HAs are freed

Parameters
haThe head of the list of HAs to free
Return values
void

Definition at line 222 of file acl.c.

References ast_free, and ast_ha::next.

Referenced by add_calltoken_ignore(), append_ha_core(), ast_duplicate_ha_list(), ast_free_acl_list(), AST_TEST_DEFINE(), build_callno_limits(), destroy_gateway(), destroy_named_acl(), destroy_sip_transport_state(), ip_identify_destroy(), named_acl_find_realtime(), pjsip_disable_logger(), pjsip_enable_logger_host(), pjsip_logger_session_destroy(), reload_config(), test_item_destructor(), transport_localnet_handler(), and unload_module().

223 {
224  struct ast_ha *hal;
225  while (ha) {
226  hal = ha;
227  ha = ha->next;
228  ast_free(hal);
229  }
230 }
struct ast_ha * next
Definition: acl.h:56
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
#define ast_free(a)
Definition: astmm.h:182

◆ ast_get_ip()

int ast_get_ip ( struct ast_sockaddr addr,
const char *  hostname 
)

Get the IP address given a hostname.

Similar in nature to ast_gethostbyname, except that instead of getting an entire hostent structure, you instead are given only the IP address inserted into a ast_sockaddr structure.

Parameters
addrThe IP address found. The address family is used as an input parameter to filter the returned addresses. If it is AST_AF_UNSPEC, both IPv4 and IPv6 addresses can be returned.
hostnameThe hostname to look up
Return values
0Success
-1Failure

Definition at line 1000 of file acl.c.

References ast_get_ip_or_srv(), and NULL.

Referenced by build_gateway(), build_peer(), config_parse_variables(), peer_set_srcaddr(), setup_stunaddr(), and stun_monitor_request().

1001 {
1002  return ast_get_ip_or_srv(addr, hostname, NULL);
1003 }
int ast_get_ip_or_srv(struct ast_sockaddr *addr, const char *hostname, const char *service)
Get the IP address given a hostname and optional service.
Definition: acl.c:897
#define NULL
Definition: resample.c:96
static struct ast_str * hostname
Definition: cdr_mysql.c:77

◆ ast_get_ip_or_srv()

int ast_get_ip_or_srv ( struct ast_sockaddr addr,
const char *  hostname,
const char *  service 
)

Get the IP address given a hostname and optional service.

If the service parameter is non-NULL, then an SRV lookup will be made by prepending the service to the hostname parameter, separated by a '.' For example, if hostname is "example.com" and service is "_sip._udp" then an SRV lookup will be done for "_sip._udp.example.com". If service is NULL, then this function acts exactly like a call to ast_get_ip.

Parameters
addrThe IP address found. The address family is used as an input parameter to filter the returned addresses. If it is 0, both IPv4 and IPv6 addresses can be returned.
hostnameThe hostname to look up
serviceA specific service provided by the host. A NULL service results in an A-record lookup instead of an SRV lookup
Return values
0Success
-1Failure

Definition at line 897 of file acl.c.

References ast_get_srv(), ast_sockaddr_set_port, host, NULL, PARSE_PORT_FORBID, resolve_first(), and ast_sockaddr::ss.

Referenced by ast_get_ip(), create_addr(), dnsmgr_refresh(), internal_dnsmgr_lookup(), and proxy_update().

898 {
899  char srv[256];
900  char host[256];
901  int srv_ret = 0;
902  int tportno;
903 
904  if (service) {
905  snprintf(srv, sizeof(srv), "%s.%s", service, hostname);
906  if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, srv)) > 0) {
907  hostname = host;
908  }
909  }
910 
911  if (resolve_first(addr, hostname, PARSE_PORT_FORBID, addr->ss.ss_family) != 0) {
912  return -1;
913  }
914 
915  if (srv_ret > 0) {
916  ast_sockaddr_set_port(addr, tportno);
917  }
918 
919  return 0;
920 }
struct sockaddr_storage ss
Definition: netsock2.h:98
enum ast_cc_service_type service
Definition: chan_sip.c:947
#define NULL
Definition: resample.c:96
static int resolve_first(struct ast_sockaddr *addr, const char *name, int flag, int family)
Definition: acl.c:876
int ast_get_srv(struct ast_channel *chan, char *host, int hostlen, int *port, const char *service)
Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup.
Definition: srv.c:260
static char host[256]
Definition: muted.c:77
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
static struct ast_str * hostname
Definition: cdr_mysql.c:77

◆ ast_ha_join()

void ast_ha_join ( const struct ast_ha ha,
struct ast_str **  buf 
)

Convert HAs to a comma separated string value.

Parameters
hathe starting ha head
bufstring buffer to convert data to

Definition at line 723 of file acl.c.

References ast_ha::addr, AST_SENSE_ALLOW, ast_sockaddr_port, ast_sockaddr_stringify(), ast_sockaddr_stringify_addr(), ast_str_append(), ast_ha::netmask, ast_ha::next, and ast_ha::sense.

Referenced by localnet_to_str(), and match_to_str().

724 {
725  for (; ha; ha = ha->next) {
726  const char *addr;
727 
728  if (ast_sockaddr_port(&ha->addr)) {
729  addr = ast_sockaddr_stringify(&ha->addr);
730  } else {
731  addr = ast_sockaddr_stringify_addr(&ha->addr);
732  }
733 
734  ast_str_append(buf, 0, "%s%s/",
735  ha->sense == AST_SENSE_ALLOW ? "!" : "",
736  addr);
737  /* Separated to avoid duplicating stringified addresses. */
739  if (ha->next) {
740  ast_str_append(buf, 0, ",");
741  }
742  }
743 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_ha * next
Definition: acl.h:56
struct ast_sockaddr addr
Definition: acl.h:53
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
enum ast_acl_sense sense
Definition: acl.h:55
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
struct ast_sockaddr netmask
Definition: acl.h:54
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:260

◆ ast_ha_join_cidr()

void ast_ha_join_cidr ( const struct ast_ha ha,
struct ast_str **  buf 
)

Convert HAs to a comma separated string value using CIDR notation.

Parameters
hathe starting ha head
bufstring buffer to convert data to

Definition at line 745 of file acl.c.

References ast_ha::addr, AST_SENSE_ALLOW, ast_sockaddr_cidr_bits(), ast_sockaddr_stringify_addr(), ast_str_append(), ast_ha::netmask, ast_ha::next, and ast_ha::sense.

746 {
747  for (; ha; ha = ha->next) {
748  const char *addr = ast_sockaddr_stringify_addr(&ha->addr);
749  ast_str_append(buf, 0, "%s%s/%d",
750  ha->sense == AST_SENSE_ALLOW ? "!" : "",
751  addr, ast_sockaddr_cidr_bits(&ha->netmask));
752  if (ha->next) {
753  ast_str_append(buf, 0, ",");
754  }
755  }
756 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_ha * next
Definition: acl.h:56
struct ast_sockaddr addr
Definition: acl.h:53
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
enum ast_acl_sense sense
Definition: acl.h:55
struct ast_sockaddr netmask
Definition: acl.h:54
int ast_sockaddr_cidr_bits(const struct ast_sockaddr *sa)
Count the 1 bits in a netmask.
Definition: netsock2.c:130

◆ ast_ha_output()

void ast_ha_output ( int  fd,
const struct ast_ha ha,
const char *  prefix 
)

output an HA to the provided fd

This function can be used centrally to output HAs as used in ACLs from other modules. It follows the format as originally used for named ACLs in named_acl.c.

Parameters
fdThe file-descriptor to which to output the HA.
haThe HA to output.
prefixIf you need a specific prefix output on each line, give it here, may be NULL.
Since
13.33.0, 16.10.0, 17.4.0

Definition at line 1087 of file acl.c.

References ast_ha::addr, ast_cli(), AST_SENSE_ALLOW, AST_SOCKADDR_BUFLEN, ast_sockaddr_stringify_addr(), ast_ha::netmask, ast_ha::next, and ast_ha::sense.

Referenced by ast_acl_output(), and cli_display_named_acl().

1088 {
1089  char addr[AST_SOCKADDR_BUFLEN];
1090  char *mask;
1091  int index = 0;
1092  for (; ha; ha = ha->next, ++index) {
1093  strcpy(addr, ast_sockaddr_stringify_addr(&ha->addr));
1094  mask = ast_sockaddr_stringify_addr(&ha->netmask);
1095  ast_cli(fd, "%s%3d: %s - %s/%s\n", prefix ?: "", index, ha->sense == AST_SENSE_ALLOW ? "allow" : " deny", addr, mask);
1096  }
1097 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
struct ast_ha * next
Definition: acl.h:56
#define AST_SOCKADDR_BUFLEN
Definition: netsock2.h:46
struct ast_sockaddr addr
Definition: acl.h:53
enum ast_acl_sense sense
Definition: acl.h:55
void ast_cli(int fd, const char *fmt,...)
Definition: clicompat.c:6
struct ast_sockaddr netmask
Definition: acl.h:54
static char prefix[MAX_PREFIX]
Definition: http.c:141

◆ ast_lookup_iface()

int ast_lookup_iface ( char *  iface,
struct ast_sockaddr address 
)

Find an IP address associated with a specific interface.

Given an interface such as "eth0" we find the primary IP address associated with it using the SIOCGIFADDR ioctl. If the ioctl call should fail, we populate address with 0s.

Note
This function is not actually used anywhere
Parameters
ifaceThe interface name whose IP address we wish to find
[out]addressThe interface's IP address is placed into this param
Return values
-1Failure. address is filled with 0s
0Success

◆ ast_named_acl_change_type()

struct stasis_message_type* ast_named_acl_change_type ( void  )

◆ ast_named_acl_find()

struct ast_ha* ast_named_acl_find ( const char *  name,
int *  is_realtime,
int *  is_undefined 
)

Retrieve a named ACL.

This function attempts to find a named ACL. If found, a copy of the requested ACL will be made which must be freed by the caller.

Parameters
nameName of the ACL sought
[out]is_realtimewill be true if the ACL being returned is from realtime
[out]is_undefinedwill be true if no ACL profile can be found for the requested name
Return values
Acopy of the named ACL as an ast_ha
NULLif no ACL could be found.

Definition at line 293 of file named_acl.c.

References ACL_FAMILY, ao2_cleanup, ao2_global_obj_ref, ast_check_realtime(), ast_duplicate_ha_list(), ast_log, ast_named_acl_change_type(), ast_realtime_is_mapping_defined(), globals, named_acl::ha, LOG_ERROR, LOG_NOTICE, LOG_WARNING, named_acl_find(), named_acl_find_realtime(), NULL, RAII_VAR, and STASIS_MESSAGE_TYPE_DEFN().

Referenced by ast_append_acl().

294 {
295  struct ast_ha *ha = NULL;
296 
299 
300  if (is_realtime) {
301  *is_realtime = 0;
302  }
303 
304  if (is_undefined) {
305  *is_undefined = 0;
306  }
307 
308  /* If the config or its named_acl_list hasn't been initialized, abort immediately. */
309  if ((!cfg) || (!(cfg->named_acl_list))) {
310  ast_log(LOG_ERROR, "Attempted to find named ACL '%s', but the ACL configuration isn't available.\n", name);
311  return NULL;
312  }
313 
314  named_acl = named_acl_find(cfg->named_acl_list, name);
315 
316  /* If a named ACL couldn't be retrieved locally, we need to try realtime storage. */
317  if (!named_acl) {
318  RAII_VAR(struct named_acl *, realtime_acl, NULL, ao2_cleanup);
319 
320  /* Attempt to create from realtime */
321  if ((realtime_acl = named_acl_find_realtime(name))) {
322  if (is_realtime) {
323  *is_realtime = 1;
324  }
325  ha = ast_duplicate_ha_list(realtime_acl->ha);
326  return ha;
327  }
328 
329  /* Couldn't create from realtime. Raise relevant flags and print relevant warnings. */
331  ast_log(LOG_WARNING, "ACL '%s' does not exist. The ACL will be marked as undefined and will automatically fail if applied.\n"
332  "This ACL may exist in the configured realtime backend, but that backend hasn't been registered yet. "
333  "Fix this establishing preload for the backend in 'modules.conf'.\n", name);
334  } else {
335  ast_log(LOG_WARNING, "ACL '%s' does not exist. The ACL will be marked as undefined and will automatically fail if applied.\n", name);
336  }
337 
338  if (is_undefined) {
339  *is_undefined = 1;
340  }
341 
342  return NULL;
343  }
344 
346 
347  if (!ha) {
348  ast_log(LOG_NOTICE, "ACL '%s' contains no rules. It is valid, but it will accept addresses unconditionally.\n", name);
349  }
350 
351  return ha;
352 }
struct ast_ha * ast_duplicate_ha_list(struct ast_ha *original)
Duplicate the contents of a list of host access rules.
Definition: acl.c:277
#define LOG_WARNING
Definition: logger.h:274
int ast_check_realtime(const char *family)
Check if realtime engine is configured for family.
Definition: main/config.c:3363
static struct named_acl * named_acl_find_realtime(const char *name)
Definition: named_acl.c:240
#define ao2_global_obj_ref(holder)
Definition: astobj2.h:925
#define NULL
Definition: resample.c:96
internal representation of ACL entries In principle user applications would have no need for this...
Definition: acl.h:51
#define ast_log
Definition: astobj2.c:42
struct ast_ha * ha
Definition: named_acl.c:109
#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:851
static struct console_pvt globals
#define LOG_ERROR
Definition: logger.h:285
#define LOG_NOTICE
Definition: logger.h:263
static const char name[]
Definition: cdr_mysql.c:74
int ast_realtime_is_mapping_defined(const char *family)
Determine if a mapping exists for a given family.
Definition: main/config.c:3026
static void * named_acl_find(struct ao2_container *container, const char *cat)
Find a named ACL in a container by its name.
Definition: named_acl.c:182
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
#define ACL_FAMILY
Definition: named_acl.c:50

◆ ast_ouraddrfor()

int ast_ouraddrfor ( const struct ast_sockaddr them,
struct ast_sockaddr us 
)

Get our local IP address when contacting a remote host.

This function will attempt to connect(2) to them over UDP using a source port of 5060. If the connect(2) call is successful, then we inspect the sockaddr_in output parameter of connect(2) to determine the IP address used to connect to them. This IP address is then copied into us.

Parameters
themThe IP address to which we wish to attempt to connect
[out]usThe source IP address used to connect to them
Return values
-1Failure
0Success

Definition at line 1005 of file acl.c.

References ast_connect(), ast_debug, ast_getsockname(), ast_log, ast_sockaddr_is_ipv6(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify_addr(), ast_strdupa, errno, LOG_ERROR, and LOG_WARNING.

Referenced by ast_find_ourip(), ast_rtp_remote_address_set(), ast_sip_ouraddrfor(), build_gateway(), find_subchannel_and_lock(), sip_acf_channel_read(), and unicast_rtp_request().

1006 {
1007  /*
1008  * We must create the errno string before creating the address
1009  * string because it could wipe out errno on the error return
1010  * paths.
1011  */
1012  const char *sock_err;
1013  int port;
1014  int s;
1015 
1016  /* Preserve our original address port */
1017  port = ast_sockaddr_port(us);
1018 
1019  s = socket(ast_sockaddr_is_ipv6(them) ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
1020  if (s < 0) {
1021  sock_err = ast_strdupa(strerror(errno));
1022  ast_log(LOG_ERROR, "Cannot create socket to %s: %s\n",
1023  ast_sockaddr_stringify_addr(them), sock_err);
1024  return -1;
1025  }
1026 
1027  if (ast_connect(s, them)) {
1028  sock_err = ast_strdupa(strerror(errno));
1029  ast_log(LOG_WARNING, "Cannot connect to %s: %s\n",
1030  ast_sockaddr_stringify_addr(them), sock_err);
1031  close(s);
1032  return -1;
1033  }
1034  if (ast_getsockname(s, us)) {
1035  sock_err = ast_strdupa(strerror(errno));
1036  ast_log(LOG_WARNING, "Cannot get socket name for connection to %s: %s\n",
1037  ast_sockaddr_stringify_addr(them), sock_err);
1038  close(s);
1039  return -1;
1040  }
1041  close(s);
1042 
1043  ast_sockaddr_set_port(us, port);
1044 
1045  ast_debug(3, "For destination '%s', our source address is '%s'.\n",
1048 
1049  return 0;
1050 }
static char * ast_sockaddr_stringify_addr(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only.
Definition: netsock2.h:290
#define LOG_WARNING
Definition: logger.h:274
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:521
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:444
#define ast_log
Definition: astobj2.c:42
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
#define LOG_ERROR
Definition: logger.h:285
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:537
int errno
int ast_getsockname(int sockfd, struct ast_sockaddr *addr)
Wrapper around getsockname(2) that uses struct ast_sockaddr.
Definition: netsock2.c:600
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
int ast_connect(int sockfd, const struct ast_sockaddr *addr)
Wrapper around connect(2) that uses struct ast_sockaddr.
Definition: netsock2.c:595

◆ ast_str2cos()

int ast_str2cos ( const char *  value,
unsigned int *  cos 
)

Convert a string to the appropriate COS value.

Parameters
valueThe COS string to convert
[out]cosThe integer representation of that COS value
Return values
-1Failure
0Success

Definition at line 953 of file acl.c.

Referenced by config_parse_variables(), reload_config(), and set_config().

954 {
955  int fval;
956 
957  if (sscanf(value, "%30d", &fval) == 1) {
958  if (fval < 8) {
959  *cos = fval;
960  return 0;
961  }
962  }
963 
964  return -1;
965 }
unsigned int cos
Definition: chan_iax2.c:352
int value
Definition: syslog.c:37

◆ ast_str2tos()

int ast_str2tos ( const char *  value,
unsigned int *  tos 
)

Convert a string to the appropriate TOS value.

Parameters
valueThe TOS string to convert
[out]tosThe integer representation of that TOS value
Return values
-1Failure
0Success

Definition at line 967 of file acl.c.

References ARRAY_LEN, dscp_codepoint::name, and dscp_codepoint::space.

Referenced by config_parse_variables(), iax_template_parse(), reload_config(), set_config(), tos_handler(), and transport_tos_handler().

968 {
969  int fval;
970  unsigned int x;
971 
972  if (sscanf(value, "%30i", &fval) == 1) {
973  *tos = fval & 0xFF;
974  return 0;
975  }
976 
977  for (x = 0; x < ARRAY_LEN(dscp_pool1); x++) {
978  if (!strcasecmp(value, dscp_pool1[x].name)) {
979  *tos = dscp_pool1[x].space << 2;
980  return 0;
981  }
982  }
983 
984  return -1;
985 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct dscp_codepoint dscp_pool1[]
Definition: acl.c:929
int value
Definition: syslog.c:37
unsigned int tos
Definition: chan_iax2.c:351
static const char name[]
Definition: cdr_mysql.c:74
unsigned int space
Definition: acl.c:924

◆ ast_tos2str()

const char* ast_tos2str ( unsigned int  tos)

Convert a TOS value into its string representation.

Parameters
tosThe TOS value to look up
Returns
The string equivalent of the TOS value

Definition at line 987 of file acl.c.

References ARRAY_LEN, dscp_codepoint::name, and dscp_codepoint::space.

Referenced by sip_show_settings().

988 {
989  unsigned int x;
990 
991  for (x = 0; x < ARRAY_LEN(dscp_pool1); x++) {
992  if (dscp_pool1[x].space == (tos >> 2)) {
993  return dscp_pool1[x].name;
994  }
995  }
996 
997  return "unknown";
998 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static const struct dscp_codepoint dscp_pool1[]
Definition: acl.c:929
char * name
Definition: acl.c:923
unsigned int tos
Definition: chan_iax2.c:351