Zone-transfer peer restriction option.

This commit is contained in:
Simon Kelley
2012-12-09 18:24:58 +00:00
parent e1ff419cf9
commit 496787677e
4 changed files with 53 additions and 9 deletions

View File

@@ -72,7 +72,7 @@ static int in_zone(struct auth_zone *zone, char *name, char **cut)
}
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now)
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr)
{
char *name = daemon->namebuff;
unsigned char *p, *ansp;
@@ -357,6 +357,35 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
}
else if (qtype == T_AXFR)
{
if (daemon->auth_peers)
{
struct iname *peers;
if (peer_addr->sa.sa_family == AF_INET)
peer_addr->in.sin_port = 0;
#ifdef HAVE_IPV6
else
peer_addr->in6.sin6_port = 0;
#endif
for (peers = daemon->auth_peers; peers; peers = peers->next)
if (sockaddr_isequal(peer_addr, &peers->addr))
break;
if (!peers)
{
if (peer_addr->sa.sa_family == AF_INET)
inet_ntop(AF_INET, &peer_addr->in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
#ifdef HAVE_IPV6
else
inet_ntop(AF_INET6, &peer_addr->in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN);
#endif
my_syslog(LOG_WARNING, _("ignoring zone transfer request from %s"), daemon->addrbuff);
return 0;
}
}
soa = 1; /* inhibits auth section */
ns = 1; /* ensure we include NS records! */
axfr = 1;

View File

@@ -762,7 +762,7 @@ extern struct daemon {
struct cond_domain *cond_domain;
char *runfile;
char *lease_change_command;
struct iname *if_names, *if_addrs, *if_except, *dhcp_except;
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers;
struct bogus_addr *bogus_addr;
struct server *servers;
int log_fac; /* log facility */
@@ -909,7 +909,7 @@ int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
/* auth.c */
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now);
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr);
/* util.c */
void rand_init(void);

View File

@@ -814,7 +814,7 @@ void receive_query(struct listener *listen, time_t now)
if (auth_dns)
{
m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now);
m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr);
if (m >= 1)
send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
(char *)header, m, &source_addr, &dst_addr, if_index);
@@ -904,7 +904,7 @@ unsigned char *tcp_request(int confd, time_t now,
dst_addr_4.s_addr = 0;
if (auth_dns)
m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now);
m = answer_auth(header, ((char *) header) + 65536, (size_t)size, now, &peer_addr);
else
{
/* m > 0 if answered from cache */
@@ -1043,7 +1043,8 @@ unsigned char *tcp_request(int confd, time_t now,
c1 = m>>8;
c2 = m;
if (!read_write(confd, &c1, 1, 0) ||
if (m == 0 ||
!read_write(confd, &c1, 1, 0) ||
!read_write(confd, &c2, 1, 0) ||
!read_write(confd, packet, m, 0))
return packet;

View File

@@ -126,6 +126,7 @@ struct myoption {
#define LOPT_AUTHTTL 315
#define LOPT_AUTHSOA 316
#define LOPT_AUTHSFS 317
#define LOPT_AUTHPEER 318
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -257,6 +258,7 @@ static const struct myoption opts[] =
{ "auth-ttl", 1, 0, LOPT_AUTHTTL },
{ "auth-soa", 1, 0, LOPT_AUTHSOA },
{ "auth-sec-servers", 1, 0, LOPT_AUTHSFS },
{ "auth-peer", 1, 0, LOPT_AUTHPEER },
{ NULL, 0, 0, 0 }
};
@@ -393,7 +395,8 @@ static struct {
{ LOPT_AUTHZONE, ARG_DUP, "<domain>,<subnet>[,<subnet>]", gettext_noop("Domain to export to global DNS"), NULL },
{ LOPT_AUTHTTL, ARG_ONE, "<integer>", gettext_noop("Set TTL for authoritative replies"), NULL },
{ LOPT_AUTHSOA, ARG_ONE, "<serial>[,...]", gettext_noop("Set authoritive zone information"), NULL },
{ LOPT_AUTHSFS, ARG_ONE, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
{ LOPT_AUTHSFS, ARG_DUP, "<NS>[,<NS>...]", gettext_noop("Secondary authoritative nameservers for forward domains"), NULL },
{ LOPT_AUTHPEER, ARG_DUP, "<ipaddr>[,<ipaddr>...]", gettext_noop("Peers which are allowed to do zone transfer"), NULL },
{ 0, 0, NULL, NULL, NULL }
};
@@ -1871,14 +1874,15 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
}
case 'a': /* --listen-address */
case LOPT_AUTHPEER: /* --auth-peer */
do {
struct iname *new = opt_malloc(sizeof(struct iname));
comma = split(arg);
unhide_metas(arg);
new->next = daemon->if_addrs;
if (arg && (new->addr.in.sin_addr.s_addr = inet_addr(arg)) != (in_addr_t)-1)
{
new->addr.sa.sa_family = AF_INET;
new->addr.in.sin_port = 0;
#ifdef HAVE_SOCKADDR_SA_LEN
new->addr.in.sin_len = sizeof(new->addr.in);
#endif
@@ -1889,6 +1893,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
new->addr.sa.sa_family = AF_INET6;
new->addr.in6.sin6_flowinfo = 0;
new->addr.in6.sin6_scope_id = 0;
new->addr.in6.sin6_port = 0;
#ifdef HAVE_SOCKADDR_SA_LEN
new->addr.in6.sin6_len = sizeof(new->addr.in6);
#endif
@@ -1898,7 +1903,16 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
ret_err(gen_err);
new->used = 0;
daemon->if_addrs = new;
if (option == 'a')
{
new->next = daemon->if_addrs;
daemon->if_addrs = new;
}
else
{
new->next = daemon->auth_peers;
daemon->auth_peers = new;
}
arg = comma;
} while (arg);
break;