|
|
@ -574,7 +574,7 @@ static void debug_ha_sense_appended(struct ast_ha *ha)
|
|
|
|
ha->sense);
|
|
|
|
ha->sense);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
|
|
|
|
static struct ast_ha *append_ha_core(const char *sense, const char *stuff, struct ast_ha *path, int *error, int port_flags)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct ast_ha *ha;
|
|
|
|
struct ast_ha *ha;
|
|
|
|
struct ast_ha *prev = NULL;
|
|
|
|
struct ast_ha *prev = NULL;
|
|
|
@ -591,6 +591,8 @@ struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while ((tmp = strsep(&list, ","))) {
|
|
|
|
while ((tmp = strsep(&list, ","))) {
|
|
|
|
|
|
|
|
uint16_t save_port;
|
|
|
|
|
|
|
|
|
|
|
|
if (!(ha = ast_calloc(1, sizeof(*ha)))) {
|
|
|
|
if (!(ha = ast_calloc(1, sizeof(*ha)))) {
|
|
|
|
if (error) {
|
|
|
|
if (error) {
|
|
|
|
*error = 1;
|
|
|
|
*error = 1;
|
|
|
@ -612,7 +614,7 @@ struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha
|
|
|
|
ha->sense = allowing;
|
|
|
|
ha->sense = allowing;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!ast_sockaddr_parse(&ha->addr, address, PARSE_PORT_FORBID)) {
|
|
|
|
if (!ast_sockaddr_parse(&ha->addr, address, port_flags)) {
|
|
|
|
ast_log(LOG_WARNING, "Invalid IP address: %s\n", address);
|
|
|
|
ast_log(LOG_WARNING, "Invalid IP address: %s\n", address);
|
|
|
|
ast_free_ha(ha);
|
|
|
|
ast_free_ha(ha);
|
|
|
|
if (error) {
|
|
|
|
if (error) {
|
|
|
@ -621,6 +623,11 @@ struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Be pedantic and zero out the port if we don't want it */
|
|
|
|
|
|
|
|
if ((port_flags & PARSE_PORT_MASK) == PARSE_PORT_FORBID) {
|
|
|
|
|
|
|
|
ast_sockaddr_set_port(&ha->addr, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* If someone specifies an IPv4-mapped IPv6 address,
|
|
|
|
/* If someone specifies an IPv4-mapped IPv6 address,
|
|
|
|
* we just convert this to an IPv4 ACL
|
|
|
|
* we just convert this to an IPv4 ACL
|
|
|
|
*/
|
|
|
|
*/
|
|
|
@ -669,6 +676,10 @@ struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ast_sockaddr_apply_netmask() does not preserve the port, so we need to save and
|
|
|
|
|
|
|
|
* restore it */
|
|
|
|
|
|
|
|
save_port = ast_sockaddr_port(&ha->addr);
|
|
|
|
|
|
|
|
|
|
|
|
if (ast_sockaddr_apply_netmask(&ha->addr, &ha->netmask, &ha->addr)) {
|
|
|
|
if (ast_sockaddr_apply_netmask(&ha->addr, &ha->netmask, &ha->addr)) {
|
|
|
|
/* This shouldn't happen because ast_sockaddr_parse would
|
|
|
|
/* This shouldn't happen because ast_sockaddr_parse would
|
|
|
|
* have failed much earlier on an unsupported address scheme
|
|
|
|
* have failed much earlier on an unsupported address scheme
|
|
|
@ -683,6 +694,8 @@ struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ast_sockaddr_set_port(&ha->addr, save_port);
|
|
|
|
|
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
if (prev) {
|
|
|
|
prev->next = ha;
|
|
|
|
prev->next = ha;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -698,12 +711,30 @@ struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return append_ha_core(sense, stuff, path, error, PARSE_PORT_FORBID);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct ast_ha *ast_append_ha_with_port(const char *sense, const char *stuff, struct ast_ha *path, int *error)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return append_ha_core(sense, stuff, path, error, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
|
|
|
|
void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
for (; ha; ha = ha->next) {
|
|
|
|
for (; ha; ha = ha->next) {
|
|
|
|
|
|
|
|
const char *addr;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (ast_sockaddr_port(&ha->addr)) {
|
|
|
|
|
|
|
|
addr = ast_sockaddr_stringify(&ha->addr);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
addr = ast_sockaddr_stringify_addr(&ha->addr);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ast_str_append(buf, 0, "%s%s/",
|
|
|
|
ast_str_append(buf, 0, "%s%s/",
|
|
|
|
ha->sense == AST_SENSE_ALLOW ? "!" : "",
|
|
|
|
ha->sense == AST_SENSE_ALLOW ? "!" : "",
|
|
|
|
ast_sockaddr_stringify_addr(&ha->addr));
|
|
|
|
addr);
|
|
|
|
/* Separated to avoid duplicating stringified addresses. */
|
|
|
|
/* Separated to avoid duplicating stringified addresses. */
|
|
|
|
ast_str_append(buf, 0, "%s", ast_sockaddr_stringify_addr(&ha->netmask));
|
|
|
|
ast_str_append(buf, 0, "%s", ast_sockaddr_stringify_addr(&ha->netmask));
|
|
|
|
if (ha->next) {
|
|
|
|
if (ha->next) {
|
|
|
@ -785,6 +816,7 @@ enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockad
|
|
|
|
struct ast_sockaddr result;
|
|
|
|
struct ast_sockaddr result;
|
|
|
|
struct ast_sockaddr mapped_addr;
|
|
|
|
struct ast_sockaddr mapped_addr;
|
|
|
|
const struct ast_sockaddr *addr_to_use;
|
|
|
|
const struct ast_sockaddr *addr_to_use;
|
|
|
|
|
|
|
|
uint16_t save_port;
|
|
|
|
#if 0 /* debugging code */
|
|
|
|
#if 0 /* debugging code */
|
|
|
|
char iabuf[INET_ADDRSTRLEN];
|
|
|
|
char iabuf[INET_ADDRSTRLEN];
|
|
|
|
char iabuf2[INET_ADDRSTRLEN];
|
|
|
|
char iabuf2[INET_ADDRSTRLEN];
|
|
|
@ -820,13 +852,22 @@ enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockad
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ast_sockaddr_apply_netmask() does not preserve the port, so we need to save and
|
|
|
|
|
|
|
|
* restore it */
|
|
|
|
|
|
|
|
save_port = ast_sockaddr_port(addr_to_use);
|
|
|
|
|
|
|
|
|
|
|
|
/* For each rule, if this address and the netmask = the net address
|
|
|
|
/* For each rule, if this address and the netmask = the net address
|
|
|
|
apply the current rule */
|
|
|
|
apply the current rule */
|
|
|
|
if (ast_sockaddr_apply_netmask(addr_to_use, ¤t_ha->netmask, &result)) {
|
|
|
|
if (ast_sockaddr_apply_netmask(addr_to_use, ¤t_ha->netmask, &result)) {
|
|
|
|
/* Unlikely to happen since we know the address to be IPv4 or IPv6 */
|
|
|
|
/* Unlikely to happen since we know the address to be IPv4 or IPv6 */
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!ast_sockaddr_cmp_addr(&result, ¤t_ha->addr)) {
|
|
|
|
|
|
|
|
|
|
|
|
ast_sockaddr_set_port(&result, save_port);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!ast_sockaddr_cmp_addr(&result, ¤t_ha->addr)
|
|
|
|
|
|
|
|
&& (!ast_sockaddr_port(¤t_ha->addr)
|
|
|
|
|
|
|
|
|| ast_sockaddr_port(¤t_ha->addr) == ast_sockaddr_port(&result))) {
|
|
|
|
res = current_ha->sense;
|
|
|
|
res = current_ha->sense;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|