X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Ftypes.c;h=59e9502e2f60f7072d4281479f8c69a14df1c576;hb=fc440c64836370db9d8cb1a25f09c9df0786f865;hp=196a0874514f44b9481c0ead2b12ea27863ebab0;hpb=7f8bbe29436e29cc2683955d642f79a10d62f67d;p=adns.git diff --git a/src/types.c b/src/types.c index 196a087..59e9502 100644 --- a/src/types.c +++ b/src/types.c @@ -4,7 +4,8 @@ */ /* * This file is part of adns, which is - * Copyright (C) 1997-2000,2003,2006 Ian Jackson + * Copyright (C) 1997-2000,2003,2006,2014-2016,2020 Ian Jackson + * Copyright (C) 2014 Mark Wooding * Copyright (C) 1999-2000,2003,2006 Tony Finch * Copyright (C) 1991 Massachusetts Institute of Technology * (See the file INSTALL for full details.) @@ -20,8 +21,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program; if not, write to the Free Software Foundation. */ #include @@ -221,7 +221,7 @@ static adns_status pa_txt(const parseinfo *pai, int cbyte, return adns_s_ok; } -static adns_status cs_txt(vbuf *vb, const void *datap) { +static adns_status cs_txt(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_intstr *const *rrp= datap; const adns_rr_intstr *current; adns_status st; @@ -238,7 +238,7 @@ static adns_status cs_txt(vbuf *vb, const void *datap) { * _hinfo (cs) */ -static adns_status cs_hinfo(vbuf *vb, const void *datap) { +static adns_status cs_hinfo(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_intstrpair *rrp= datap; adns_status st; @@ -316,7 +316,7 @@ static adns_status csp_genaddr(vbuf *vb, int af, const void *p) { return adns_s_ok; } -static adns_status cs_inaddr(vbuf *vb, const void *datap) { +static adns_status cs_inaddr(vbuf *vb, adns_rrtype rrt, const void *datap) { return csp_genaddr(vb, AF_INET,datap); } @@ -338,7 +338,7 @@ static int di_in6addr(adns_state ads, return dip_genaddr(ads,AF_INET6,datap_a,datap_b); } -static adns_status cs_in6addr(vbuf *vb, const void *datap) { +static adns_status cs_in6addr(vbuf *vb, adns_rrtype rrt, const void *datap) { return csp_genaddr(vb,AF_INET6,datap); } @@ -499,7 +499,7 @@ static adns_status csp_addr(vbuf *vb, const adns_rr_addr *rrp) { return adns_s_ok; } -static adns_status cs_addr(vbuf *vb, const void *datap) { +static adns_status cs_addr(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_addr *rrp= datap; return csp_addr(vb,rrp); @@ -785,7 +785,7 @@ static adns_status csp_domain(vbuf *vb, const char *domain) { return adns_s_ok; } -static adns_status cs_domain(vbuf *vb, const void *datap) { +static adns_status cs_domain(vbuf *vb, adns_rrtype rrt, const void *datap) { const char *const *domainp= datap; return csp_domain(vb,*domainp); } @@ -838,6 +838,7 @@ static adns_status pap_findaddrs(const parseinfo *pai, adns_rr_hostaddr *ha, &type, &class, &ttl, &rdlen, &rdstart, pai->dgram, pai->dglen, dmstart, &ownermatched); if (st) return st; + if (type==-1) continue; if (!ownermatched || class != DNS_CLASS_IN) continue; typef= addr_rrtypeflag(type); if (!(want & typef)) continue; @@ -892,6 +893,7 @@ static void icb_hostaddr(adns_query parent, adns_query child) { done: if (st) { adns__free_interim(parent, rrp->addrs); + rrp->addrs = 0; rrp->naddrs= (st>0 && st<=adns_s_max_tempfail) ? -1 : 0; } @@ -999,11 +1001,13 @@ static void mf_hostaddr(adns_query qu, void *datap) { mfp_hostaddr(qu,rrp); } -static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) { +static adns_status csp_hostaddr(vbuf *vb, adns_rrtype rrt, + const adns_rr_hostaddr *rrp) { const char *errstr; adns_status st; char buf[20]; int i; + size_t addrsz= gsz_addr(0, rrt); st= csp_domain(vb,rrp->host); if (st) return st; @@ -1023,7 +1027,7 @@ static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) { CSP_ADDSTR(" ("); for (i=0; inaddrs; i++) { CSP_ADDSTR(" "); - st= csp_addr(vb,&rrp->addrs[i]); + st= csp_addr(vb, (const void*)((const char*)rrp->addrs + addrsz*i)); } CSP_ADDSTR(" )"); } else { @@ -1032,10 +1036,10 @@ static adns_status csp_hostaddr(vbuf *vb, const adns_rr_hostaddr *rrp) { return adns_s_ok; } -static adns_status cs_hostaddr(vbuf *vb, const void *datap) { +static adns_status cs_hostaddr(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_hostaddr *rrp= datap; - return csp_hostaddr(vb,rrp); + return csp_hostaddr(vb,rrt,rrp); } /* @@ -1107,26 +1111,35 @@ static void mf_inthostaddr(adns_query qu, void *datap) { mfp_hostaddr(qu,&rrp->ha); } -static adns_status cs_inthostaddr(vbuf *vb, const void *datap) { - const adns_rr_inthostaddr *rrp= datap; +static adns_status csp_intofinthost(vbuf *vb, int i) { char buf[10]; - sprintf(buf,"%u ",rrp->i); + if (i < 0 || i > 0xffff) + /* currently only used for MX whose priorities are 16-bit */ + return adns_s_invaliddata; + + sprintf(buf,"%u ",i); CSP_ADDSTR(buf); + return adns_s_ok; +} + +static adns_status cs_inthostaddr(vbuf *vb, adns_rrtype rrt, const void *datap) { + const adns_rr_inthostaddr *rrp= datap; + adns_status st; - return csp_hostaddr(vb,&rrp->ha); + st = csp_intofinthost(vb,rrp->i); if (st) return st; + return csp_hostaddr(vb,rrt,&rrp->ha); } /* * _inthost (cs) */ -static adns_status cs_inthost(vbuf *vb, const void *datap) { +static adns_status cs_inthost(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_intstr *rrp= datap; - char buf[10]; + adns_status st; - sprintf(buf,"%u ",rrp->i); - CSP_ADDSTR(buf); + st = csp_intofinthost(vb,rrp->i); if (st) return st; return csp_domain(vb,rrp->str); } @@ -1277,6 +1290,7 @@ static adns_status pap_mailbox822(const parseinfo *pai, pai->dgram, pai->dglen, max, *cbyte_io, cbyte_io); st= adns__findlabel_next(&fls,&lablen,&labstart); + if (st) return st; if (!lablen) { adns__vbuf_appendstr(vb,"."); goto x_ok; @@ -1349,7 +1363,7 @@ static adns_status pa_rp(const parseinfo *pai, int cbyte, return adns_s_ok; } -static adns_status cs_rp(vbuf *vb, const void *datap) { +static adns_status cs_rp(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_strpair *rrp= datap; adns_status st; @@ -1369,7 +1383,7 @@ static adns_status pa_soa(const parseinfo *pai, int cbyte, adns_rr_soa *rrp= datap; const byte *dgram= pai->dgram; adns_status st; - int msw, lsw, i; + int i; st= pap_domain(pai, &cbyte, max, &rrp->mname, pai->qu->flags & adns_qf_quoteok_anshost ? pdf_quoteok : 0); @@ -1381,9 +1395,8 @@ static adns_status pa_soa(const parseinfo *pai, int cbyte, if (cbyte+20 != max) return adns_s_invaliddata; for (i=0; i<5; i++) { - GET_W(cbyte,msw); - GET_W(cbyte,lsw); - (&rrp->serial)[i]= (msw<<16) | lsw; + unsigned long v; + (&rrp->serial)[i]= GET_L(cbyte, v); } return adns_s_ok; @@ -1396,7 +1409,7 @@ static void mf_soa(adns_query qu, void *datap) { adns__makefinal_str(qu,&rrp->rname); } -static adns_status cs_soa(vbuf *vb, const void *datap) { +static adns_status cs_soa(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_soa *rrp= datap; char buf[20]; int i; @@ -1407,6 +1420,8 @@ static adns_status cs_soa(vbuf *vb, const void *datap) { st= csp_mailbox(vb,rrp->rname); if (st) return st; for (i=0; i<5; i++) { + if (rrp->serial > 0xffffffffUL) + return adns_s_invaliddata; sprintf(buf," %lu",(&rrp->serial)[i]); CSP_ADDSTR(buf); } @@ -1495,12 +1510,16 @@ static int di_srv(adns_state ads, const void *datap_a, const void *datap_b) { static adns_status csp_srv_begin(vbuf *vb, const adns_rr_srvha *rrp /* might be adns_rr_srvraw* */) { char buf[30]; + if (rrp->priority < 0 || rrp->priority > 0xffff || + rrp->weight < 0 || rrp->weight > 0xffff || + rrp->port < 0 || rrp->port > 0xffff) + return adns_s_invaliddata; sprintf(buf,"%u %u %u ", rrp->priority, rrp->weight, rrp->port); CSP_ADDSTR(buf); return adns_s_ok; } -static adns_status cs_srvraw(vbuf *vb, const void *datap) { +static adns_status cs_srvraw(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_srvraw *rrp= datap; adns_status st; @@ -1508,12 +1527,12 @@ static adns_status cs_srvraw(vbuf *vb, const void *datap) { return csp_domain(vb,rrp->host); } -static adns_status cs_srvha(vbuf *vb, const void *datap) { +static adns_status cs_srvha(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_srvha *rrp= datap; adns_status st; st= csp_srv_begin(vb,(const void*)datap); if (st) return st; - return csp_hostaddr(vb,&rrp->ha); + return csp_hostaddr(vb,rrt,&rrp->ha); } static void postsort_srv(adns_state ads, void *array, int nrrs,int rrsz, @@ -1604,12 +1623,15 @@ static adns_status pa_opaque(const parseinfo *pai, int cbyte, return adns_s_ok; } -static adns_status cs_opaque(vbuf *vb, const void *datap) { +static adns_status cs_opaque(vbuf *vb, adns_rrtype rrt, const void *datap) { const adns_rr_byteblock *rrp= datap; char buf[10]; int l; unsigned char *p; + if (rrp->len < 0 || rrp->len > 0xffff) + return adns_s_invaliddata; + sprintf(buf,"\\# %d",rrp->len); CSP_ADDSTR(buf); @@ -1693,6 +1715,10 @@ DEEP_TYPE(unknown,0, "unknown",byteblock,opaque, 0, opaque ); const typeinfo *adns__findtype(adns_rrtype type) { const typeinfo *begin, *end, *mid; + if (type & ~(adns_rrtype)0x63ffffff) + /* 0x60000000 is reserved for `harmless' future expansion */ + return 0; + if (type & adns_r_unknown) return &typeinfo_unknown; type &= adns_rrt_reprmask;