]>
git.siccegge.de Git - dane-monitoring-plugins.git/blob - check_dane/resolve.py
5 from datetime
import datetime
7 from unbound
import ub_ctx
, ub_strerror
8 from unbound
import RR_TYPE_A
, RR_TYPE_AAAA
, RR_TYPE_RRSIG
, RR_TYPE_SRV
10 from ldns
import ldns_wire2pkt
11 from ldns
import LDNS_SECTION_ANSWER
14 def _parse_rrsig_date(expirestring
):
15 expires
= datetime(int(expirestring
[:4]),
16 int(expirestring
[4:6]),
17 int(expirestring
[6:8]),
18 int(expirestring
[8:10]),
19 int(expirestring
[10:12]),
20 int(expirestring
[12:14]))
24 def format_address(data
, datatype
):
25 """Given a answer packet for an A or AAAA query, return the string
26 representation of the address
28 if datatype
== RR_TYPE_A
:
29 return '.'.join([str(a
) for a
in data
])
30 elif datatype
== RR_TYPE_AAAA
:
31 data
= list(struct
.iter_unpack("!H", data
))
32 return ":".join(["%x" % a
for a
in data
])
37 def dnssec_verify_rrsig_validity(data
, warn
=-1, critical
=0):
38 """Given a answer packet confirm validity of rrsigs (with safety) """
39 now
= datetime
.utcnow()
41 s
, packet
= ldns_wire2pkt(data
)
43 logging
.error("Parsing packet failed with errorcode %d", s
)
46 rrsigs
= packet
.rr_list_by_type(RR_TYPE_RRSIG
, LDNS_SECTION_ANSWER
).rrs()
49 expire
= _parse_rrsig_date(str(rrsig
.rrsig_expiration()))
50 incept
= _parse_rrsig_date(str(rrsig
.rrsig_inception()))
53 logging
.error("Signature not yet valid, only from %s", incept
)
56 stillvalid
= expire
- now
57 deltastr
= str(stillvalid
).split(",")
59 if stillvalid
.days
< max(0, critical
):
60 logging
.error("expires in %8s,%16s", deltastr
[0], deltastr
[1])
62 elif stillvalid
.days
< warn
:
63 logging
.warning("expires in %8s,%16s", deltastr
[0], deltastr
[1])
67 def srv_lookup(name
, resolver
):
69 result
= resolver
.resolve(name
, rrtype
=RR_TYPE_SRV
)
70 for bytevalue
in result
.data
.raw
:
71 priority
, weight
, port
= struct
.unpack("!HHH", bytevalue
[:6])
72 hostname
= '.'.join(result
.data
.dname2str(bytevalue
[6:]))
73 retval
.append(((hostname
, port
), {'priority': priority
, 'weight': weight
}))
77 class ResolverException(BaseException
):
78 def __init__(self
, message
):
79 BaseException
.__init
__(self
)
80 self
.message
= message
84 def __init__(self
, ancor
, fwd
=None):
85 self
._resolver
= ub_ctx()
86 status
= self
._resolver
.add_ta_file(ancor
)
88 raise ResolverException(ub_strerror(status
))
91 status
= self
._resolver
.set_fwd(fwd
)
93 raise ResolverException(ub_strerror(status
))
96 def resolve(self
, name
, rrtype
, secure
=False):
97 status
, result
= self
._resolver
.resolve(name
, rrtype
)
99 raise ResolverException(ub_strerror(status
))
101 if secure
and not result
.secure
:
102 raise ResolverException("Response was not signed")