Wed Aug 18 22:33:57 2010

Asterisk developer's documentation


acl.h File Reference

Access Control of various sorts. More...

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

Go to the source code of this file.

Data Structures

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...

Defines

#define AST_SENSE_ALLOW   1
#define AST_SENSE_DENY   0

Functions

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.
int ast_apply_ha (struct ast_ha *ha, struct sockaddr_in *sin)
 Apply a set of rules to a given IP address.
void ast_copy_ha (const struct ast_ha *from, struct ast_ha *to)
 Copy the contents of one HA to another.
ast_haast_duplicate_ha_list (struct ast_ha *original)
 Duplicate the contents of a list of host access rules.
int ast_find_ourip (struct in_addr *ourip, struct sockaddr_in bindaddr)
 Find our IP address.
void ast_free_ha (struct ast_ha *ha)
 Free a list of HAs.
int ast_get_ip (struct sockaddr_in *sin, const char *value)
 Get the IP address given a hostname.
int ast_get_ip_or_srv (struct sockaddr_in *sin, const char *value, const char *service)
 Get the IP address given a hostname and optional service.
int ast_lookup_iface (char *iface, struct in_addr *address)
 Find an IP address associated with a specific interface.
int ast_ouraddrfor (struct in_addr *them, struct in_addr *us)
 Get our local IP address when contacting a remote host.
int ast_str2cos (const char *value, unsigned int *cos)
 Convert a string to the appropriate COS value.
int ast_str2tos (const char *value, unsigned int *tos)
 Convert a string to the appropriate TOS value.
const char * ast_tos2str (unsigned int tos)
 Convert a TOS value into its string representation.


Detailed Description

Access Control of various sorts.

Definition in file acl.h.


Define Documentation

#define AST_SENSE_ALLOW   1

Definition at line 35 of file acl.h.

Referenced by ast_append_ha(), ast_apply_ha(), ast_sip_ouraddrfor(), and parse_register_contact().

#define AST_SENSE_DENY   0

Definition at line 34 of file acl.h.

Referenced by ast_append_ha().


Function Documentation

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:
sense Either "permit" or "deny" (Actually any 'p' word will result in permission, and any other word will result in denial)
stuff The 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).
path The 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] error The integer error points to will be set non-zero if an error occurs
Returns:
The head of the HA list

Definition at line 265 of file acl.c.

References ast_debug, ast_free, ast_inet_ntoa(), ast_log(), ast_malloc, AST_SENSE_ALLOW, AST_SENSE_DENY, ast_strdupa, inet_aton(), LOG_WARNING, ast_ha::netaddr, and ast_ha::next.

Referenced by add_calltoken_ignore(), build_callno_limits(), build_device(), build_gateway(), build_peer(), and build_user().

00266 {
00267    struct ast_ha *ha;
00268    char *nm;
00269    struct ast_ha *prev = NULL;
00270    struct ast_ha *ret;
00271    int x;
00272    char *tmp = ast_strdupa(stuff);
00273 
00274    ret = path;
00275    while (path) {
00276       prev = path;
00277       path = path->next;
00278    }
00279 
00280    ha = ast_malloc(sizeof(*ha));
00281    if (!ha)
00282       return ret;
00283 
00284    nm = strchr(tmp, '/');
00285    if (!nm) {
00286       /* assume /32. Yes, htonl does not do anything for this particular mask
00287          but we better use it to show we remember about byte order */
00288       ha->netmask.s_addr = htonl(0xFFFFFFFF);
00289    } else {
00290       *nm = '\0';
00291       nm++;
00292 
00293       if (!strchr(nm, '.')) {
00294          if ((sscanf(nm, "%30d", &x) == 1) && (x >= 0) && (x <= 32))
00295             if (x == 0) {
00296                /* This is special-cased to prevent unpredictable
00297                 * behavior of shifting left 32 bits
00298                 */
00299                ha->netmask.s_addr = 0;
00300             } else {
00301                ha->netmask.s_addr = htonl(0xFFFFFFFF << (32 - x));
00302             }
00303          else {
00304             ast_log(LOG_WARNING, "Invalid CIDR in %s\n", stuff);
00305             ast_free(ha);
00306             if (error)
00307                *error = 1;
00308             return ret;
00309          }
00310       } else if (!inet_aton(nm, &ha->netmask)) {
00311          ast_log(LOG_WARNING, "Invalid mask in %s\n", stuff);
00312          ast_free(ha);
00313          if (error)
00314             *error = 1;
00315          return ret;
00316       }
00317    }
00318 
00319    if (!inet_aton(tmp, &ha->netaddr)) {
00320       ast_log(LOG_WARNING, "Invalid IP address in %s\n", stuff);
00321       ast_free(ha);
00322       if (error)
00323          *error = 1;
00324       return ret;
00325    }
00326 
00327    ha->netaddr.s_addr &= ha->netmask.s_addr;
00328 
00329    ha->sense = strncasecmp(sense, "p", 1) ? AST_SENSE_DENY : AST_SENSE_ALLOW;
00330 
00331    ha->next = NULL;
00332    if (prev) {
00333       prev->next = ha;
00334    } else {
00335       ret = ha;
00336    }
00337 
00338    ast_debug(1, "%s/%s sense %d appended to acl for peer\n", ast_strdupa(ast_inet_ntoa(ha->netaddr)), ast_strdupa(ast_inet_ntoa(ha->netmask)), ha->sense);
00339 
00340    return ret;
00341 }

int ast_apply_ha ( struct ast_ha ha,
struct sockaddr_in *  sin 
)

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:
ha The head of the list of host access rules to follow
sin A sockaddr_in whose address is considered when matching rules
Return values:
AST_SENSE_ALLOW The IP address passes our ACL
AST_SENSE_DENY The IP address fails our ACL

Definition at line 343 of file acl.c.

References ast_copy_string(), ast_debug, ast_inet_ntoa(), AST_SENSE_ALLOW, ast_ha::netaddr, ast_ha::netmask, ast_ha::next, and ast_ha::sense.

Referenced by ast_sip_ouraddrfor(), authenticate(), check_access(), check_peer_ok(), parse_register_contact(), register_verify(), and skinny_register().

00344 {
00345    /* Start optimistic */
00346    int res = AST_SENSE_ALLOW;
00347    while (ha) {
00348 #if 0 /* debugging code */
00349       char iabuf[INET_ADDRSTRLEN];
00350       char iabuf2[INET_ADDRSTRLEN];
00351       /* DEBUG */
00352       ast_copy_string(iabuf, ast_inet_ntoa(sin->sin_addr), sizeof(iabuf));
00353       ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2));
00354       ast_debug(1, "##### Testing %s with %s\n", iabuf, iabuf2);
00355 #endif
00356       /* For each rule, if this address and the netmask = the net address
00357          apply the current rule */
00358       if ((sin->sin_addr.s_addr & ha->netmask.s_addr) == ha->netaddr.s_addr)
00359          res = ha->sense;
00360       ha = ha->next;
00361    }
00362    return res;
00363 }

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:
from Source HA to copy
to Destination HA to copy to
Return values:
void 

Definition at line 223 of file acl.c.

References ast_ha::netaddr, ast_ha::netmask, and ast_ha::sense.

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

00224 {
00225    memcpy(&to->netaddr, &from->netaddr, sizeof(from->netaddr));
00226    memcpy(&to->netmask, &from->netmask, sizeof(from->netmask));
00227    to->sense = from->sense;
00228 }

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.

Note:
This function is not actually used anywhere.
Parameters:
original The ast_ha to copy
Return values:
The head of the list of duplicated ast_has

Definition at line 245 of file acl.c.

References ast_duplicate_ha(), and ast_ha::next.

00246 {
00247    struct ast_ha *start = original;
00248    struct ast_ha *ret = NULL;
00249    struct ast_ha *current, *prev = NULL;
00250 
00251    while (start) {
00252       current = ast_duplicate_ha(start);  /* Create copy of this object */
00253       if (prev)
00254          prev->next = current;      /* Link previous to this object */
00255 
00256       if (!ret)
00257          ret = current;    /* Save starting point */
00258 
00259       start = start->next;    /* Go to next object */
00260       prev = current;         /* Save pointer to this object */
00261    }
00262    return ret;             /* Return start of list */
00263 }

int ast_find_ourip ( struct in_addr *  ourip,
struct sockaddr_in  bindaddr 
)

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:

Parameters:
[out] ourip Our IP address is written here when it is found
bindaddr A hint used for finding our IP. See the steps above for more details
Return values:
0 Success
-1 Failure

Definition at line 502 of file acl.c.

References ahp, ast_debug, ast_gethostbyname(), ast_log(), ast_ouraddrfor(), get_local_address(), hp, inet_aton(), LOG_WARNING, MAXHOSTNAMELEN, and ourhost.

Referenced by __oh323_rtp_create(), gtalk_create_candidates(), jingle_create_candidates(), and load_module().

00503 {
00504    char ourhost[MAXHOSTNAMELEN] = "";
00505    struct ast_hostent ahp;
00506    struct hostent *hp;
00507    struct in_addr saddr;
00508 
00509    /* just use the bind address if it is nonzero */
00510    if (ntohl(bindaddr.sin_addr.s_addr)) {
00511       memcpy(ourip, &bindaddr.sin_addr, sizeof(*ourip));
00512       ast_debug(3, "Attached to given IP address\n");
00513       return 0;
00514    }
00515    /* try to use our hostname */
00516    if (gethostname(ourhost, sizeof(ourhost) - 1)) {
00517       ast_log(LOG_WARNING, "Unable to get hostname\n");
00518    } else {
00519       hp = ast_gethostbyname(ourhost, &ahp);
00520       if (hp) {
00521          memcpy(ourip, hp->h_addr, sizeof(*ourip));
00522          ast_debug(3, "Found one IP address based on local hostname %s.\n", ourhost);
00523          return 0;
00524       }
00525    }
00526    ast_debug(3, "Trying to check A.ROOT-SERVERS.NET and get our IP address for that connection\n");
00527    /* A.ROOT-SERVERS.NET. */
00528    if (inet_aton("198.41.0.4", &saddr) && !ast_ouraddrfor(&saddr, ourip))
00529       return 0;
00530    return get_local_address(ourip);
00531 }

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:
ha The head of the list of HAs to free
Return values:
void 

Definition at line 212 of file acl.c.

References ast_free, and ast_ha::next.

Referenced by add_calltoken_ignore(), build_callno_limits(), build_peer(), build_user(), destroy_gateway(), oh323_destroy_peer(), oh323_destroy_user(), peer_destructor(), reload_config(), sip_destroy_peer(), unload_module(), and user_destructor().

00213 {
00214    struct ast_ha *hal;
00215    while (ha) {
00216       hal = ha;
00217       ha = ha->next;
00218       ast_free(hal);
00219    }
00220 }

int ast_get_ip ( struct sockaddr_in *  sin,
const char *  value 
)

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 sockaddr_in structure.

Parameters:
[out] sin The IP address is written into sin->sin_addr
value The hostname to look up
Return values:
0 Success
-1 Failure

Definition at line 466 of file acl.c.

References ast_get_ip_or_srv().

Referenced by build_device(), build_gateway(), build_peer(), build_user(), and peer_set_srcaddr().

00467 {
00468    return ast_get_ip_or_srv(sin, value, NULL);
00469 }

int ast_get_ip_or_srv ( struct sockaddr_in *  sin,
const char *  value,
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 value parameter, separated by a '.' For example, if value 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:
[out] sin The IP address is written into sin->sin_addr
value The hostname to look up
service A specific service provided by the host. A NULL service results in an A-record lookup instead of an SRV lookup
Return values:
0 Success
-1 Failure

Definition at line 365 of file acl.c.

References ahp, ast_get_srv(), ast_gethostbyname(), ast_log(), hp, and LOG_WARNING.

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

00366 {
00367    struct hostent *hp;
00368    struct ast_hostent ahp;
00369    char srv[256];
00370    char host[256];
00371    int tportno = ntohs(sin->sin_port);
00372    if (service) {
00373       snprintf(srv, sizeof(srv), "%s.%s", service, value);
00374       if (ast_get_srv(NULL, host, sizeof(host), &tportno, srv) > 0) {
00375          sin->sin_port = htons(tportno);
00376          value = host;
00377       }
00378    }
00379    hp = ast_gethostbyname(value, &ahp);
00380    if (hp) {
00381       memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
00382    } else {
00383       ast_log(LOG_WARNING, "Unable to lookup '%s'\n", value);
00384       return -1;
00385    }
00386    return 0;
00387 }

int ast_lookup_iface ( char *  iface,
struct in_addr *  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:
iface The interface name whose IP address we wish to find
[out] address The interface's IP address is placed into this param
Return values:
-1 Failure. address is filled with 0s
0 Success

int ast_ouraddrfor ( struct in_addr *  them,
struct in_addr *  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:
them The IP address to which we wish to attempt to connect
[out] us The source IP address used to connect to them
Return values:
-1 Failure
0 Success

Definition at line 471 of file acl.c.

References ast_debug, ast_log(), LOG_ERROR, LOG_WARNING, and s.

Referenced by ast_find_ourip(), ast_sip_ouraddrfor(), build_gateway(), and find_subchannel_and_lock().

00472 {
00473    int s;
00474    struct sockaddr_in sin;
00475    socklen_t slen;
00476 
00477    s = socket(PF_INET, SOCK_DGRAM, 0);
00478    if (s < 0) {
00479       ast_log(LOG_ERROR, "Cannot create socket\n");
00480       return -1;
00481    }
00482    sin.sin_family = AF_INET;
00483    sin.sin_port = htons(5060);
00484    sin.sin_addr = *them;
00485    if (connect(s, (struct sockaddr *)&sin, sizeof(sin))) {
00486       ast_log(LOG_WARNING, "Cannot connect\n");
00487       close(s);
00488       return -1;
00489    }
00490    slen = sizeof(sin);
00491    if (getsockname(s, (struct sockaddr *)&sin, &slen)) {
00492       ast_log(LOG_WARNING, "Cannot get socket name\n");
00493       close(s);
00494       return -1;
00495    }
00496    close(s);
00497    ast_debug(3, "Found IP address for this socket\n");
00498    *us = sin.sin_addr;
00499    return 0;
00500 }

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

Convert a string to the appropriate COS value.

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

Definition at line 420 of file acl.c.

Referenced by reload_config(), and set_config().

00421 {
00422    int fval;
00423 
00424    if (sscanf(value, "%30d", &fval) == 1) {
00425       if (fval < 8) {
00426           *cos = fval;
00427           return 0;
00428       }
00429    }
00430 
00431    return -1;
00432 }

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

Convert a string to the appropriate TOS value.

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

Definition at line 434 of file acl.c.

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

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

00435 {
00436    int fval;
00437    unsigned int x;
00438 
00439    if (sscanf(value, "%30i", &fval) == 1) {
00440       *tos = fval & 0xFF;
00441       return 0;
00442    }
00443 
00444    for (x = 0; x < ARRAY_LEN(dscp_pool1); x++) {
00445       if (!strcasecmp(value, dscp_pool1[x].name)) {
00446          *tos = dscp_pool1[x].space << 2;
00447          return 0;
00448       }
00449    }
00450 
00451    return -1;
00452 }

const char* ast_tos2str ( unsigned int  tos  ) 

Convert a TOS value into its string representation.

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

Definition at line 454 of file acl.c.

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

Referenced by sip_show_settings().

00455 {
00456    unsigned int x;
00457 
00458    for (x = 0; x < ARRAY_LEN(dscp_pool1); x++) {
00459       if (dscp_pool1[x].space == (tos >> 2))
00460          return dscp_pool1[x].name;
00461    }
00462 
00463    return "unknown";
00464 }


Generated on Wed Aug 18 22:33:57 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7