Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
D
Dnsmasq
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
Dnsmasq
Commits
373e9173
Commit
373e9173
authored
Dec 01, 2017
by
Simon Kelley
1
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix
a6004d7f
to cope with >256 RRs in answer section.
parent
74f0f9a0
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
36 additions
and
28 deletions
+36
-28
src/dnsmasq.c
src/dnsmasq.c
+3
-2
src/dnsmasq.h
src/dnsmasq.h
+4
-3
src/dnssec.c
src/dnssec.c
+21
-9
src/forward.c
src/forward.c
+3
-9
src/rfc1035.c
src/rfc1035.c
+5
-5
No files found.
src/dnsmasq.c
View file @
373e9173
...
@@ -118,8 +118,9 @@ int main (int argc, char **argv)
...
@@ -118,8 +118,9 @@ int main (int argc, char **argv)
daemon
->
namebuff
=
safe_malloc
(
MAXDNAME
*
2
);
daemon
->
namebuff
=
safe_malloc
(
MAXDNAME
*
2
);
daemon
->
keyname
=
safe_malloc
(
MAXDNAME
*
2
);
daemon
->
keyname
=
safe_malloc
(
MAXDNAME
*
2
);
daemon
->
workspacename
=
safe_malloc
(
MAXDNAME
*
2
);
daemon
->
workspacename
=
safe_malloc
(
MAXDNAME
*
2
);
/* one char flag per possible RR in answer section. */
/* one char flag per possible RR in answer section (may get extended). */
daemon
->
rr_status
=
safe_malloc
(
256
);
daemon
->
rr_status_sz
=
64
;
daemon
->
rr_status
=
safe_malloc
(
daemon
->
rr_status_sz
);
}
}
#endif
#endif
...
...
src/dnsmasq.h
View file @
373e9173
...
@@ -1030,7 +1030,8 @@ extern struct daemon {
...
@@ -1030,7 +1030,8 @@ extern struct daemon {
#ifdef HAVE_DNSSEC
#ifdef HAVE_DNSSEC
char
*
keyname
;
/* MAXDNAME size buffer */
char
*
keyname
;
/* MAXDNAME size buffer */
char
*
workspacename
;
/* ditto */
char
*
workspacename
;
/* ditto */
char
*
rr_status
;
/* 256 bytes as flags for individual RRs */
char
*
rr_status
;
/* flags for individual RRs */
int
rr_status_sz
;
#endif
#endif
unsigned
int
local_answer
,
queries_forwarded
,
auth_answer
;
unsigned
int
local_answer
,
queries_forwarded
,
auth_answer
;
struct
frec
*
frec_list
;
struct
frec
*
frec_list
;
...
@@ -1145,7 +1146,7 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
...
@@ -1145,7 +1146,7 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
unsigned
long
ttl
);
unsigned
long
ttl
);
int
extract_addresses
(
struct
dns_header
*
header
,
size_t
qlen
,
char
*
name
,
int
extract_addresses
(
struct
dns_header
*
header
,
size_t
qlen
,
char
*
name
,
time_t
now
,
char
**
ipsets
,
int
is_sign
,
int
check_rebind
,
time_t
now
,
char
**
ipsets
,
int
is_sign
,
int
check_rebind
,
int
no_cache_dnssec
,
int
secure
,
int
*
doctored
,
char
*
rr_status
);
int
no_cache_dnssec
,
int
secure
,
int
*
doctored
);
size_t
answer_request
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
size_t
answer_request
(
struct
dns_header
*
header
,
char
*
limit
,
size_t
qlen
,
struct
in_addr
local_addr
,
struct
in_addr
local_netmask
,
struct
in_addr
local_addr
,
struct
in_addr
local_netmask
,
time_t
now
,
int
ad_reqd
,
int
do_bit
,
int
have_pseudoheader
);
time_t
now
,
int
ad_reqd
,
int
do_bit
,
int
have_pseudoheader
);
...
@@ -1178,7 +1179,7 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char
...
@@ -1178,7 +1179,7 @@ size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char
int
dnssec_validate_by_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_by_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_ds
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
class
);
int
dnssec_validate_reply
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
*
class
,
int
dnssec_validate_reply
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
*
class
,
int
check_unsigned
,
int
*
neganswer
,
int
*
nons
,
char
*
rr_status
);
int
check_unsigned
,
int
*
neganswer
,
int
*
nons
);
int
dnskey_keytag
(
int
alg
,
int
flags
,
unsigned
char
*
key
,
int
keylen
);
int
dnskey_keytag
(
int
alg
,
int
flags
,
unsigned
char
*
key
,
int
keylen
);
size_t
filter_rrsigs
(
struct
dns_header
*
header
,
size_t
plen
);
size_t
filter_rrsigs
(
struct
dns_header
*
header
,
size_t
plen
);
unsigned
char
*
hash_questions
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
);
unsigned
char
*
hash_questions
(
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
);
...
...
src/dnssec.c
View file @
373e9173
...
@@ -859,7 +859,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
...
@@ -859,7 +859,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
if
(
qtype
!=
T_DS
||
qclass
!=
class
)
if
(
qtype
!=
T_DS
||
qclass
!=
class
)
rc
=
STAT_BOGUS
;
rc
=
STAT_BOGUS
;
else
else
rc
=
dnssec_validate_reply
(
now
,
header
,
plen
,
name
,
keyname
,
NULL
,
0
,
&
neganswer
,
&
nons
,
NULL
);
rc
=
dnssec_validate_reply
(
now
,
header
,
plen
,
name
,
keyname
,
NULL
,
0
,
&
neganswer
,
&
nons
);
if
(
rc
==
STAT_INSECURE
)
if
(
rc
==
STAT_INSECURE
)
rc
=
STAT_BOGUS
;
rc
=
STAT_BOGUS
;
...
@@ -1645,11 +1645,11 @@ static int zone_status(char *name, int class, char *keyname, time_t now)
...
@@ -1645,11 +1645,11 @@ static int zone_status(char *name, int class, char *keyname, time_t now)
STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname, class in *class)
STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname, class in *class)
STAT_NEED_DS need DS to complete validation (name is returned in keyname)
STAT_NEED_DS need DS to complete validation (name is returned in keyname)
If non-NULL,
rr_status points to a char array which corressponds to the RRs in the
daemon->
rr_status points to a char array which corressponds to the RRs in the
answer section (only). This is set to 1 for each RR which is validated, and 0 for any which aren't.
answer section (only). This is set to 1 for each RR which is validated, and 0 for any which aren't.
*/
*/
int
dnssec_validate_reply
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
dnssec_validate_reply
(
time_t
now
,
struct
dns_header
*
header
,
size_t
plen
,
char
*
name
,
char
*
keyname
,
int
*
class
,
int
check_unsigned
,
int
*
neganswer
,
int
*
nons
,
char
*
rr_status
)
int
*
class
,
int
check_unsigned
,
int
*
neganswer
,
int
*
nons
)
{
{
static
unsigned
char
**
targets
=
NULL
;
static
unsigned
char
**
targets
=
NULL
;
static
int
target_sz
=
0
;
static
int
target_sz
=
0
;
...
@@ -1659,8 +1659,20 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
...
@@ -1659,8 +1659,20 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
int
i
,
j
,
rc
;
int
i
,
j
,
rc
;
int
secure
=
STAT_SECURE
;
int
secure
=
STAT_SECURE
;
if
(
rr_status
)
/* extend rr_status if necessary */
memset
(
rr_status
,
0
,
ntohs
(
header
->
ancount
));
if
(
daemon
->
rr_status_sz
<
ntohs
(
header
->
ancount
))
{
char
*
new
=
whine_malloc
(
ntohs
(
header
->
ancount
)
+
64
);
if
(
!
new
)
return
STAT_BOGUS
;
free
(
daemon
->
rr_status
);
daemon
->
rr_status
=
new
;
daemon
->
rr_status_sz
=
ntohs
(
header
->
ancount
)
+
64
;
}
memset
(
daemon
->
rr_status
,
0
,
ntohs
(
header
->
ancount
));
if
(
neganswer
)
if
(
neganswer
)
*
neganswer
=
0
;
*
neganswer
=
0
;
...
@@ -1754,8 +1766,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
...
@@ -1754,8 +1766,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
if
(
j
!=
i
)
if
(
j
!=
i
)
{
{
/* Done already: copy the validation status */
/* Done already: copy the validation status */
if
(
rr_status
&&
(
i
<
ntohs
(
header
->
ancount
)
))
if
(
i
<
ntohs
(
header
->
ancount
))
rr_status
[
i
]
=
rr_status
[
j
];
daemon
->
rr_status
[
i
]
=
daemon
->
rr_status
[
j
];
}
}
else
else
{
{
...
@@ -1814,8 +1826,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
...
@@ -1814,8 +1826,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
/* rc is now STAT_SECURE or STAT_SECURE_WILDCARD */
/* rc is now STAT_SECURE or STAT_SECURE_WILDCARD */
/* Note that RR is validated */
/* Note that RR is validated */
if
(
rr_status
&&
(
i
<
ntohs
(
header
->
ancount
)
))
if
(
i
<
ntohs
(
header
->
ancount
))
rr_status
[
i
]
=
1
;
daemon
->
rr_status
[
i
]
=
1
;
/* Note if we've validated either the answer to the question
/* Note if we've validated either the answer to the question
or the target of a CNAME. Any not noted will need NSEC or
or the target of a CNAME. Any not noted will need NSEC or
...
...
src/forward.c
View file @
373e9173
...
@@ -560,7 +560,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
...
@@ -560,7 +560,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
char
**
sets
=
0
;
char
**
sets
=
0
;
int
munged
=
0
,
is_sign
;
int
munged
=
0
,
is_sign
;
size_t
plen
;
size_t
plen
;
char
*
rr_status
=
NULL
;
(
void
)
ad_reqd
;
(
void
)
ad_reqd
;
(
void
)
do_bit
;
(
void
)
do_bit
;
...
@@ -651,11 +650,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
...
@@ -651,11 +650,6 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
server
->
flags
|=
SERV_WARNED_RECURSIVE
;
server
->
flags
|=
SERV_WARNED_RECURSIVE
;
}
}
#ifdef HAVE_DNSSEC
if
(
option_bool
(
OPT_DNSSEC_VALID
))
rr_status
=
daemon
->
rr_status
;
#endif
if
(
daemon
->
bogus_addr
&&
RCODE
(
header
)
!=
NXDOMAIN
&&
if
(
daemon
->
bogus_addr
&&
RCODE
(
header
)
!=
NXDOMAIN
&&
check_for_bogus_wildcard
(
header
,
n
,
daemon
->
namebuff
,
daemon
->
bogus_addr
,
now
))
check_for_bogus_wildcard
(
header
,
n
,
daemon
->
namebuff
,
daemon
->
bogus_addr
,
now
))
{
{
...
@@ -681,7 +675,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
...
@@ -681,7 +675,7 @@ static size_t process_reply(struct dns_header *header, time_t now, struct server
cache_secure
=
0
;
cache_secure
=
0
;
}
}
if
(
extract_addresses
(
header
,
n
,
daemon
->
namebuff
,
now
,
sets
,
is_sign
,
check_rebind
,
no_cache
,
cache_secure
,
&
doctored
,
rr_status
))
if
(
extract_addresses
(
header
,
n
,
daemon
->
namebuff
,
now
,
sets
,
is_sign
,
check_rebind
,
no_cache
,
cache_secure
,
&
doctored
))
{
{
my_syslog
(
LOG_WARNING
,
_
(
"possible DNS-rebind attack detected: %s"
),
daemon
->
namebuff
);
my_syslog
(
LOG_WARNING
,
_
(
"possible DNS-rebind attack detected: %s"
),
daemon
->
namebuff
);
munged
=
1
;
munged
=
1
;
...
@@ -906,7 +900,7 @@ void reply_query(int fd, int family, time_t now)
...
@@ -906,7 +900,7 @@ void reply_query(int fd, int family, time_t now)
else
else
status
=
dnssec_validate_reply
(
now
,
header
,
n
,
daemon
->
namebuff
,
daemon
->
keyname
,
&
forward
->
class
,
status
=
dnssec_validate_reply
(
now
,
header
,
n
,
daemon
->
namebuff
,
daemon
->
keyname
,
&
forward
->
class
,
option_bool
(
OPT_DNSSEC_NO_SIGN
)
&&
(
server
->
flags
&
SERV_DO_DNSSEC
),
option_bool
(
OPT_DNSSEC_NO_SIGN
)
&&
(
server
->
flags
&
SERV_DO_DNSSEC
),
NULL
,
NULL
,
daemon
->
rr_status
);
NULL
,
NULL
);
}
}
/* Can't validate, as we're missing key data. Put this
/* Can't validate, as we're missing key data. Put this
...
@@ -1491,7 +1485,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
...
@@ -1491,7 +1485,7 @@ static int tcp_key_recurse(time_t now, int status, struct dns_header *header, si
else
else
new_status
=
dnssec_validate_reply
(
now
,
header
,
n
,
name
,
keyname
,
&
class
,
new_status
=
dnssec_validate_reply
(
now
,
header
,
n
,
name
,
keyname
,
&
class
,
option_bool
(
OPT_DNSSEC_NO_SIGN
)
&&
(
server
->
flags
&
SERV_DO_DNSSEC
),
option_bool
(
OPT_DNSSEC_NO_SIGN
)
&&
(
server
->
flags
&
SERV_DO_DNSSEC
),
NULL
,
NULL
,
daemon
->
rr_status
);
NULL
,
NULL
);
if
(
new_status
!=
STAT_NEED_DS
&&
new_status
!=
STAT_NEED_KEY
)
if
(
new_status
!=
STAT_NEED_DS
&&
new_status
!=
STAT_NEED_KEY
)
break
;
break
;
...
...
src/rfc1035.c
View file @
373e9173
...
@@ -585,7 +585,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doc
...
@@ -585,7 +585,7 @@ static int find_soa(struct dns_header *header, size_t qlen, char *name, int *doc
Return 1 if we reject an address because it look like part of dns-rebinding attack. */
Return 1 if we reject an address because it look like part of dns-rebinding attack. */
int
extract_addresses
(
struct
dns_header
*
header
,
size_t
qlen
,
char
*
name
,
time_t
now
,
int
extract_addresses
(
struct
dns_header
*
header
,
size_t
qlen
,
char
*
name
,
time_t
now
,
char
**
ipsets
,
int
is_sign
,
int
check_rebind
,
int
no_cache_dnssec
,
char
**
ipsets
,
int
is_sign
,
int
check_rebind
,
int
no_cache_dnssec
,
int
secure
,
int
*
doctored
,
char
*
rr_status
)
int
secure
,
int
*
doctored
)
{
{
unsigned
char
*
p
,
*
p1
,
*
endrr
,
*
namep
;
unsigned
char
*
p
,
*
p1
,
*
endrr
,
*
namep
;
int
i
,
j
,
qtype
,
qclass
,
aqtype
,
aqclass
,
ardlen
,
res
,
searched_soa
=
0
;
int
i
,
j
,
qtype
,
qclass
,
aqtype
,
aqclass
,
ardlen
,
res
,
searched_soa
=
0
;
...
@@ -610,9 +610,9 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
...
@@ -610,9 +610,9 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
{
{
if
(
secure
)
if
(
secure
)
return
0
;
return
0
;
if
(
rr_status
)
if
(
option_bool
(
OPT_DNSSEC_VALID
)
)
for
(
i
=
0
;
i
<
ntohs
(
header
->
ancount
);
i
++
)
for
(
i
=
0
;
i
<
ntohs
(
header
->
ancount
);
i
++
)
if
(
rr_status
[
i
])
if
(
daemon
->
rr_status
[
i
])
return
0
;
return
0
;
}
}
}
}
...
@@ -682,7 +682,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
...
@@ -682,7 +682,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
if
(
!
extract_name
(
header
,
qlen
,
&
p1
,
name
,
1
,
0
))
if
(
!
extract_name
(
header
,
qlen
,
&
p1
,
name
,
1
,
0
))
return
0
;
return
0
;
if
(
rr_status
&&
rr_status
[
j
])
if
(
option_bool
(
OPT_DNSSEC_VALID
)
&&
daemon
->
rr_status
[
j
])
{
{
/* validated RR anywhere in CNAME chain, don't cache. */
/* validated RR anywhere in CNAME chain, don't cache. */
if
(
cname_short
||
aqtype
==
T_CNAME
)
if
(
cname_short
||
aqtype
==
T_CNAME
)
...
@@ -766,7 +766,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
...
@@ -766,7 +766,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
if
(
aqclass
==
C_IN
&&
res
!=
2
&&
(
aqtype
==
T_CNAME
||
aqtype
==
qtype
))
if
(
aqclass
==
C_IN
&&
res
!=
2
&&
(
aqtype
==
T_CNAME
||
aqtype
==
qtype
))
{
{
#ifdef HAVE_DNSSEC
#ifdef HAVE_DNSSEC
if
(
rr_status
&&
rr_status
[
j
])
if
(
option_bool
(
OPT_DNSSEC_VALID
)
&&
daemon
->
rr_status
[
j
])
secflag
=
F_DNSSECOK
;
secflag
=
F_DNSSECOK
;
#endif
#endif
if
(
aqtype
==
T_CNAME
)
if
(
aqtype
==
T_CNAME
)
...
...
神楽坂玲奈
@zh99998
mentioned in commit
8c707e1e
·
Dec 13, 2020
mentioned in commit
8c707e1e
mentioned in commit 8c707e1e377eb2eb88a94518757750b6f1e261bf
Toggle commit list
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment