--- embedaddon/dnsmasq/src/auth.c 2021/03/17 00:56:46 1.1.1.4 +++ embedaddon/dnsmasq/src/auth.c 2023/09/27 11:02:07 1.1.1.5 @@ -1,4 +1,4 @@ -/* dnsmasq is Copyright (c) 2000-2021 Simon Kelley +/* dnsmasq is Copyright (c) 2000-2022 Simon Kelley This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -105,7 +105,7 @@ size_t answer_auth(struct dns_header *header, char *li int nameoffset, axfroffset = 0; int q, anscount = 0, authcount = 0; struct crec *crecp; - int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0; + int auth = !local_query, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0, out_of_zone = 0; struct auth_zone *zone = NULL; struct addrlist *subnet = NULL; char *cut; @@ -146,6 +146,7 @@ size_t answer_auth(struct dns_header *header, char *li if (qclass != C_IN) { auth = 0; + out_of_zone = 1; continue; } @@ -159,6 +160,7 @@ size_t answer_auth(struct dns_header *header, char *li if (!zone) { + out_of_zone = 1; auth = 0; continue; } @@ -208,7 +210,7 @@ size_t answer_auth(struct dns_header *header, char *li if (local_query || in_zone(zone, intr->name, NULL)) { found = 1; - log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL); + log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL, 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_PTR, C_IN, "d", intr->name)) @@ -232,7 +234,7 @@ size_t answer_auth(struct dns_header *header, char *li strcat(name, "."); strcat(name, zone->domain); } - log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid)); + log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid), 0); found = 1; if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, @@ -241,7 +243,7 @@ size_t answer_auth(struct dns_header *header, char *li } else if (crecp->flags & (F_DHCP | F_HOSTS) && (local_query || in_zone(zone, name, NULL))) { - log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid)); + log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid), 0); found = 1; if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, @@ -253,10 +255,21 @@ size_t answer_auth(struct dns_header *header, char *li } while ((crecp = cache_find_by_addr(crecp, &addr, now, flag))); + if (!found && is_rev_synth(flag, &addr, name) && (local_query || in_zone(zone, name, NULL))) + { + log_query(F_CONFIG | F_REVERSE | flag, name, &addr, NULL, 0); + found = 1; + + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, + daemon->auth_ttl, NULL, + T_PTR, C_IN, "d", name)) + anscount++; + } + if (found) nxdomain = 0; else - log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL); + log_query(flag | F_NEG | F_NXDOMAIN | F_REVERSE | (auth ? F_AUTH : 0), NULL, &addr, NULL, 0); continue; } @@ -273,6 +286,7 @@ size_t answer_auth(struct dns_header *header, char *li if (!zone) { + out_of_zone = 1; auth = 0; continue; } @@ -286,7 +300,7 @@ size_t answer_auth(struct dns_header *header, char *li if (rc == 2 && qtype == T_MX) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, ""); + log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_MX, C_IN, "sd", rec->weight, rec->target)) anscount++; @@ -301,7 +315,7 @@ size_t answer_auth(struct dns_header *header, char *li if (rc == 2 && qtype == T_SRV) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, ""); + log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_SRV, C_IN, "sssd", rec->priority, rec->weight, rec->srvport, rec->target)) @@ -335,7 +349,7 @@ size_t answer_auth(struct dns_header *header, char *li if (rc == 2 && txt->class == qtype) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, querystr(NULL, txt->class)); + log_query(F_CONFIG | F_RRNAME, name, NULL, NULL, txt->class); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, txt->class, C_IN, "t", txt->len, txt->txt)) anscount++; @@ -349,7 +363,7 @@ size_t answer_auth(struct dns_header *header, char *li if (rc == 2 && qtype == T_TXT) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, ""); + log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_TXT, C_IN, "t", txt->len, txt->txt)) anscount++; @@ -363,7 +377,7 @@ size_t answer_auth(struct dns_header *header, char *li if (rc == 2 && qtype == T_NAPTR) { found = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, ""); + log_query(F_CONFIG | F_RRNAME, name, NULL, "", 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, T_NAPTR, C_IN, "sszzzd", na->order, na->pref, na->flags, na->services, na->regexp, na->replace)) @@ -393,13 +407,23 @@ size_t answer_auth(struct dns_header *header, char *li continue; found = 1; - log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL); + log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL, 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addrlist->addr)) anscount++; } } + + if (!found && is_name_synthetic(flag, name, &addr) ) + { + nxdomain = 0; + + log_query(F_FORWARD | F_CONFIG | flag, name, &addr, NULL, 0); + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, + daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &addr)) + anscount++; + } if (!cut) { @@ -408,8 +432,7 @@ size_t answer_auth(struct dns_header *header, char *li if (qtype == T_SOA) { auth = soa = 1; /* inhibits auth section */ - found = 1; - log_query(F_RRNAME | F_AUTH, zone->domain, NULL, ""); + log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); } else if (qtype == T_AXFR) { @@ -444,16 +467,14 @@ size_t answer_auth(struct dns_header *header, char *li soa = 1; /* inhibits auth section */ ns = 1; /* ensure we include NS records! */ axfr = 1; - found = 1; axfroffset = nameoffset; - log_query(F_RRNAME | F_AUTH, zone->domain, NULL, ""); + log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); } else if (qtype == T_NS) { auth = 1; ns = 1; /* inhibits auth section */ - found = 1; - log_query(F_RRNAME | F_AUTH, zone->domain, NULL, ""); + log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "", 0); } } @@ -471,9 +492,8 @@ size_t answer_auth(struct dns_header *header, char *li (local_query || filter_zone(zone, flag, &(crecp->addr)))) { *cut = '.'; /* restore domain part */ - log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid)); + log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0); *cut = 0; /* remove domain part */ - found = 1; if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &crecp->addr)) @@ -493,8 +513,7 @@ size_t answer_auth(struct dns_header *header, char *li nxdomain = 0; if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr)))) { - log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid)); - found = 1; + log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid), 0); if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl, NULL, qtype, C_IN, qtype == T_A ? "4" : "6", &crecp->addr)) @@ -541,7 +560,7 @@ size_t answer_auth(struct dns_header *header, char *li if (candidate) { - log_query(F_CONFIG | F_CNAME, name, NULL, NULL); + log_query(F_CONFIG | F_CNAME, name, NULL, NULL, 0); strcpy(name, candidate->target); if (!strchr(name, '.')) { @@ -559,7 +578,7 @@ size_t answer_auth(struct dns_header *header, char *li else if (cache_find_non_terminal(name, now)) nxdomain = 0; - log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL); + log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL, 0); } } @@ -589,7 +608,7 @@ size_t answer_auth(struct dns_header *header, char *li if (subnet->prefixlen >= 16 ) p += sprintf(p, "%u.", a & 0xff); a = a >> 8; - p += sprintf(p, "%u.in-addr.arpa", a & 0xff); + sprintf(p, "%u.in-addr.arpa", a & 0xff); } else @@ -602,7 +621,7 @@ size_t answer_auth(struct dns_header *header, char *li int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3]; p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4); } - p += sprintf(p, "ip6.arpa"); + sprintf(p, "ip6.arpa"); } } @@ -855,10 +874,22 @@ size_t answer_auth(struct dns_header *header, char *li SET_RCODE(header, NXDOMAIN); else SET_RCODE(header, NOERROR); /* no error */ + header->ancount = htons(anscount); header->nscount = htons(authcount); header->arcount = htons(0); + if (!local_query && out_of_zone) + { + SET_RCODE(header, REFUSED); + header->ancount = htons(0); + header->nscount = htons(0); + addr.log.rcode = REFUSED; + addr.log.ede = EDE_NOT_AUTH; + log_query(F_UPSTREAM | F_RCODE, "error", &addr, NULL, 0); + return resize_packet(header, ansp - (unsigned char *)header, NULL, 0); + } + /* Advertise our packet size limit in our reply */ if (have_pseudoheader) return add_pseudoheader(header, ansp - (unsigned char *)header, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0); @@ -867,6 +898,3 @@ size_t answer_auth(struct dns_header *header, char *li } #endif - - -