Let access list stanzas be defined in IPv6

This commit is contained in:
Pierre Pronchery 2018-06-26 03:20:44 +02:00
parent 8ecd10b4c0
commit 89c7d6f8b9
4 changed files with 78 additions and 23 deletions

View File

@ -373,8 +373,9 @@ add_int_ent(acc_int_list_t **ilist, const char *ip)
*/
if(strcasecmp(ip, "ANY") == 0)
{
new_sle->maddr = 0x0;
new_sle->mask = 0x0;
new_sle->family = AF_INET;
new_sle->acc_int.inet.maddr = 0x0;
new_sle->acc_int.inet.mask = 0x0;
}
else
{
@ -473,17 +474,18 @@ add_int_ent(acc_int_list_t **ilist, const char *ip)
/* Store our mask converted from CIDR to a 32-bit value.
*/
new_sle->family = AF_INET;
if(mask == 32)
new_sle->mask = 0xFFFFFFFF;
new_sle->acc_int.inet.mask = 0xFFFFFFFF;
else if(need_shift && (mask > 0 && mask < 32))
new_sle->mask = (0xFFFFFFFF << (32 - mask));
new_sle->acc_int.inet.mask = (0xFFFFFFFF << (32 - mask));
else
new_sle->mask = mask;
new_sle->acc_int.inet.mask = mask;
/* Store our masked address for comparisons with future incoming
* packets.
*/
new_sle->maddr = ntohl(in.s_addr) & new_sle->mask;
new_sle->acc_int.inet.maddr = ntohl(in.s_addr) & new_sle->acc_int.inet.mask;
}
/* If this is not the first entry, we walk our pointer to the
@ -2070,22 +2072,49 @@ int valid_access_stanzas(acc_stanza_t *acc)
}
int
compare_addr_list(acc_int_list_t *ip_list, const uint32_t ip)
compare_addr_list(acc_int_list_t *ip_list, int family, ...)
{
int match = 0;
va_list ap;
uint32_t ip;
struct in6_addr * ip6;
va_start(ap, family);
switch(family)
{
case AF_INET:
ip = va_arg(ap, uint32_t);
break;
case AF_INET6:
ip6 = va_arg(ap, struct in6_addr *);
break;
default:
va_end(ap);
return 0;
}
va_end(ap);
while(ip_list)
{
if((ip & ip_list->mask) == (ip_list->maddr & ip_list->mask))
if(ip_list->family != family)
{
match = 1;
break;
ip_list = ip_list->next;
continue;
}
switch(family)
{
case AF_INET:
if((ip & ip_list->acc_int.inet.mask) == (ip_list->acc_int.inet.maddr & ip_list->acc_int.inet.mask))
return 1;
break;
case AF_INET6:
if(memcmp(&ip_list->acc_int.inet6.maddr, ip6, sizeof(*ip6)) == 0)
return 1;
break;
}
ip_list = ip_list->next;
}
return(match);
return 0;
}
/**

View File

@ -114,7 +114,7 @@ int valid_access_stanzas(acc_stanza_t *acc);
* \return Returns true on a match
*
*/
int compare_addr_list(acc_int_list_t *source_list, const uint32_t ip);
int compare_addr_list(acc_int_list_t *source_list, int family, ...);
/**
* \brief Check for a proto-port string

View File

@ -361,8 +361,20 @@ enum {
*/
typedef struct acc_int_list
{
unsigned int maddr;
unsigned int mask;
int family;
union
{
struct
{
unsigned int maddr;
unsigned int mask;
} inet;
struct
{
struct in6_addr maddr;
unsigned int prefix;
} inet6;
} acc_int;
struct acc_int_list *next;
} acc_int_list_t;

View File

@ -347,14 +347,28 @@ check_stanza_expiration(acc_stanza_t *acc, spa_data_t *spadat,
* source IP
*/
static int
is_src_match(acc_stanza_t *acc, const uint32_t ip)
is_src_match(acc_stanza_t *acc, const spa_pkt_info_t *spa_pkt)
{
while (acc)
switch (spa_pkt->packet_family)
{
if(compare_addr_list(acc->source_list, ip))
return 1;
case AF_INET:
while (acc)
{
if(compare_addr_list(acc->source_list, AF_INET, ntohl(spa_pkt->packet_addr.inet.src_ip)))
return 1;
acc = acc->next;
acc = acc->next;
}
break;
case AF_INET6:
while (acc)
{
if(compare_addr_list(acc->source_list, AF_INET6, &spa_pkt->packet_addr.inet6.src_ip))
return 1;
acc = acc->next;
}
break;
}
return 0;
}
@ -363,7 +377,7 @@ static int
src_check(fko_srv_options_t *opts, spa_pkt_info_t *spa_pkt,
spa_data_t *spadat, char **raw_digest)
{
if (is_src_match(opts->acc_stanzas, ntohl(spa_pkt->packet_src_ip)))
if (is_src_match(opts->acc_stanzas, spa_pkt))
{
if(strncasecmp(opts->config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
{
@ -427,9 +441,9 @@ static int
src_dst_check(acc_stanza_t *acc, spa_pkt_info_t *spa_pkt,
spa_data_t *spadat, const int stanza_num)
{
if(! compare_addr_list(acc->source_list, ntohl(spa_pkt->packet_src_ip)) ||
if(! compare_addr_list(acc->source_list, AF_INET, ntohl(spa_pkt->packet_src_ip)) ||
(acc->destination_list != NULL
&& ! compare_addr_list(acc->destination_list, ntohl(spa_pkt->packet_dst_ip))))
&& ! compare_addr_list(acc->destination_list, AF_INET, ntohl(spa_pkt->packet_dst_ip))))
{
log_msg(LOG_DEBUG,
"(stanza #%d) SPA packet (%s -> %s) filtered by SOURCE and/or DESTINATION criteria",