mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Zone-transfer peer restriction option.
This commit is contained in:
31
src/auth.c
31
src/auth.c
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
20
src/option.c
20
src/option.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user