diff options
author | Werner Koch <[email protected]> | 2019-03-18 18:41:07 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2019-03-18 18:41:07 +0000 |
commit | a52d883fdbe6e0de8cb26f9c6aedf01a7f66cbe7 (patch) | |
tree | e59dfb41b24a12c314dbd1137637366315ac1453 /dirmngr/dns.c | |
parent | kbx: Add framework for a public key daemon. (diff) | |
parent | speedo: Fix installer build with NSIS-3 (diff) | |
download | gnupg-a52d883fdbe6e0de8cb26f9c6aedf01a7f66cbe7.tar.gz gnupg-a52d883fdbe6e0de8cb26f9c6aedf01a7f66cbe7.zip |
Merge branch 'master' into switch-to-gpgk
--
Diffstat (limited to 'dirmngr/dns.c')
-rw-r--r-- | dirmngr/dns.c | 175 |
1 files changed, 115 insertions, 60 deletions
diff --git a/dirmngr/dns.c b/dirmngr/dns.c index 77f83f437..fa5e5283d 100644 --- a/dirmngr/dns.c +++ b/dirmngr/dns.c @@ -77,6 +77,7 @@ typedef int socket_fd_t; #include <netdb.h> /* struct addrinfo */ #endif +#include "gpgrt.h" /* For GGPRT_GCC_VERSION */ #include "dns.h" @@ -943,10 +944,11 @@ static int dns_sa_cmp(void *a, void *b) { #if _WIN32 static int dns_inet_pton(int af, const void *src, void *dst) { union { struct sockaddr_in sin; struct sockaddr_in6 sin6; } u; + int size_of_u = (int)sizeof u; u.sin.sin_family = af; - if (0 != WSAStringToAddressA((void *)src, af, (void *)0, (struct sockaddr *)&u, &(int){ sizeof u })) + if (0 != WSAStringToAddressA((void *)src, af, (void *)0, (struct sockaddr *)&u, &size_of_u)) return -1; switch (af) { @@ -1124,6 +1126,7 @@ static inline _Bool dns_isgraph(unsigned char c) { static int dns_poll(int fd, short events, int timeout) { fd_set rset, wset; + struct timeval tv = { timeout, 0 }; if (!events) return 0; @@ -1140,7 +1143,7 @@ static int dns_poll(int fd, short events, int timeout) { if (events & DNS_POLLOUT) FD_SET(fd, &wset); - select(fd + 1, &rset, &wset, 0, (timeout >= 0)? &(struct timeval){ timeout, 0 } : NULL); + select(fd + 1, &rset, &wset, 0, (timeout >= 0)? &tv : NULL); return 0; } /* dns_poll() */ @@ -1214,9 +1217,10 @@ static size_t dns_send_nopipe(int fd, const void *src, size_t len, int flags, dn if (!sigismember(&pending, SIGPIPE)) { int saved = error; + const struct timespec ts = { 0, 0 }; if (!count && error == EPIPE) { - while (-1 == sigtimedwait(&piped, NULL, &(struct timespec){ 0, 0 }) && errno == EINTR) + while (-1 == sigtimedwait(&piped, NULL, &ts) && errno == EINTR) ;; } @@ -1832,7 +1836,7 @@ static void dns_p_free(struct dns_packet *P) { } /* dns_p_free() */ -/* convience routine to free any existing packet before storing new packet */ +/* convenience routine to free any existing packet before storing new packet */ static struct dns_packet *dns_p_setptr(struct dns_packet **dst, struct dns_packet *src) { dns_p_free(*dst); @@ -2213,7 +2217,8 @@ static void dns_p_dump3(struct dns_packet *P, struct dns_rr_i *I, FILE *fp) { void dns_p_dump(struct dns_packet *P, FILE *fp) { - dns_p_dump3(P, dns_rr_i_new(P, .section = 0), fp); + struct dns_rr_i _I = { 0 }; + dns_p_dump3(P, &_I, fp); } /* dns_p_dump() */ @@ -2792,8 +2797,7 @@ size_t dns_d_cname(void *dst, size_t lim, const void *dn, size_t len, struct dns { error = ENAMETOOLONG; goto error; } for (depth = 0; depth < 7; depth++) { - dns_rr_i_init(memset(&i, 0, sizeof i), P); - + memset(&i, 0, sizeof i); i.section = DNS_S_ALL & ~DNS_S_QD; i.name = host; i.type = DNS_T_CNAME; @@ -3218,15 +3222,11 @@ int dns_rr_i_shuffle(struct dns_rr *a, struct dns_rr *b, struct dns_rr_i *i, str } /* dns_rr_i_shuffle() */ -struct dns_rr_i *dns_rr_i_init(struct dns_rr_i *i, struct dns_packet *P) { +void dns_rr_i_init(struct dns_rr_i *i) { static const struct dns_rr_i i_initializer; - (void)P; - i->state = i_initializer.state; i->saved = i->state; - - return i; } /* dns_rr_i_init() */ @@ -3262,7 +3262,8 @@ unsigned dns_rr_grep(struct dns_rr *rr, unsigned lim, struct dns_rr_i *i, struct return count; error: - *error_ = error; + if (error_) + *error_ = error; return count; } /* dns_rr_grep() */ @@ -5274,7 +5275,8 @@ error: struct dns_packet *dns_hosts_query(struct dns_hosts *hosts, struct dns_packet *Q, int *error_) { - struct dns_packet *P = dns_p_new(512); + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _P = { 0 }; + struct dns_packet *P = dns_p_init(&_P.p, 512); struct dns_packet *A = 0; struct dns_rr rr; struct dns_hosts_entry *ent; @@ -6835,6 +6837,7 @@ unsigned dns_hints_grep(struct sockaddr **sa, socklen_t *sa_len, unsigned lim, s struct dns_packet *dns_hints_query(struct dns_hints *hints, struct dns_packet *Q, int *error_) { + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _P = { 0 }; struct dns_packet *A, *P; struct dns_rr rr; char zone[DNS_D_MAXNAME + 1]; @@ -6843,8 +6846,11 @@ struct dns_packet *dns_hints_query(struct dns_hints *hints, struct dns_packet *Q struct sockaddr *sa; socklen_t slen; int error; + struct dns_rr_i _I = { 0 }; + + _I.section = DNS_S_QUESTION; - if (!dns_rr_grep(&rr, 1, dns_rr_i_new(Q, .section = DNS_S_QUESTION), Q, &error)) + if (!dns_rr_grep(&rr, 1, &_I, Q, &error)) goto error; if (!(zlen = dns_d_expand(zone, sizeof zone, rr.dn.p, Q, &error))) @@ -6852,7 +6858,7 @@ struct dns_packet *dns_hints_query(struct dns_hints *hints, struct dns_packet *Q else if (zlen >= sizeof zone) goto toolong; - P = dns_p_new(512); + P = dns_p_init(&_P.p, 512); dns_header(P)->qr = 1; if ((error = dns_rr_copy(P, &rr, Q))) @@ -7110,7 +7116,8 @@ static int dns_socket(struct sockaddr *local, int type, int *error_) { #if defined SO_NOSIGPIPE if (type != SOCK_DGRAM) { - if (0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &(int){ 1 }, sizeof (int))) + const int v = 1; + if (0 != setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &v, sizeof (int))) goto soerr; } #endif @@ -7486,11 +7493,12 @@ error: static _Bool dns_so_tcp_keep(struct dns_socket *so) { struct sockaddr_storage remote; + socklen_t l = sizeof remote; if (so->tcp == -1) return 0; - if (0 != getpeername(so->tcp, (struct sockaddr *)&remote, &(socklen_t){ sizeof remote })) + if (0 != getpeername(so->tcp, (struct sockaddr *)&remote, &l)) return 0; return 0 == dns_sa_cmp(&remote, &so->remote); @@ -7521,9 +7529,13 @@ static unsigned char *dns_so_tcp_recv_buffer(struct dns_socket *so) { } -#if defined __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warray-bounds" + +#if GPGRT_GCC_VERSION >= 80000 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Warray-bounds" +#elif defined __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Warray-bounds" #endif static int dns_so_tcp_send(struct dns_socket *so) { @@ -7589,8 +7601,10 @@ static int dns_so_tcp_recv(struct dns_socket *so) { return 0; } /* dns_so_tcp_recv() */ -#if __clang__ -#pragma clang diagnostic pop +#if GPGRT_GCC_VERSION >= 80000 +# pragma GCC diagnostic pop +#elif __clang__ +# pragma clang diagnostic pop #endif @@ -7634,7 +7648,7 @@ retry: goto udp_connect_retry; } else if (error == ECONNREFUSED) /* Error for previous socket operation may - be reserverd asynchronously. */ + be reserverd(?) asynchronously. */ goto udp_connect_retry; if (error) @@ -8449,7 +8463,8 @@ error: static struct dns_packet *dns_res_glue(struct dns_resolver *R, struct dns_packet *Q) { - struct dns_packet *P = dns_p_new(512); + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _P = { 0 }; + struct dns_packet *P = dns_p_init(&_P.p, 512); char qname[DNS_D_MAXNAME + 1]; size_t qlen; enum dns_type qtype; @@ -8521,12 +8536,22 @@ static int dns_res_nameserv_cmp(struct dns_rr *a, struct dns_rr *b, struct dns_r struct dns_ns ns; int cmp, error; - if (!(error = dns_ns_parse(&ns, a, P))) - glued[0] = !!dns_rr_grep(&x, 1, dns_rr_i_new(P, .section = (DNS_S_ALL & ~DNS_S_QD), .name = ns.host, .type = DNS_T_A), P, &error); + if (!(error = dns_ns_parse(&ns, a, P))) { + struct dns_rr_i _I = { 0 }; - if (!(error = dns_ns_parse(&ns, b, P))) - glued[1] = !!dns_rr_grep(&y, 1, dns_rr_i_new(P, .section = (DNS_S_ALL & ~DNS_S_QD), .name = ns.host, .type = DNS_T_A), P, &error); + _I.section = (DNS_S_ALL & ~DNS_S_QD); + _I.name = ns.host; + _I.type = DNS_T_A; + glued[0] = !!dns_rr_grep(&x, 1, &_I, P, &error); + } + if (!(error = dns_ns_parse(&ns, b, P))) { + struct dns_rr_i _I = { 0 }; + _I.section = (DNS_S_ALL & ~DNS_S_QD); + _I.name = ns.host; + _I.type = DNS_T_A; + glued[1] = !!dns_rr_grep(&y, 1, &_I, P, &error); + } if ((cmp = glued[1] - glued[0])) { return cmp; } else if ((cmp = (dns_rr_offset(&y) < i->args[0]) - (dns_rr_offset(&x) < i->args[0]))) { @@ -8727,7 +8752,7 @@ exec: F->state++; /* FALL THROUGH */ case DNS_R_ITERATE: - dns_rr_i_init(&F->hints_i, F->hints); + dns_rr_i_init(&F->hints_i); F->hints_i.section = DNS_S_AUTHORITY; F->hints_i.type = DNS_T_NS; @@ -8746,7 +8771,7 @@ exec: dgoto(R->sp, DNS_R_SWITCH); } - dns_rr_i_init(&F->hints_j, F->hints); + dns_rr_i_init(&F->hints_j); /* Assume there are glue records */ dgoto(R->sp, DNS_R_FOREACH_A); @@ -8799,14 +8824,14 @@ exec: if (!dns_rr_i_count(&F->hints_j)) { /* Check if we have in fact servers with an IPv6 address. */ - dns_rr_i_init(&F->hints_j, F->hints); + dns_rr_i_init(&F->hints_j); F->hints_j.name = u.ns.host; F->hints_j.type = DNS_T_AAAA; F->hints_j.section = DNS_S_ALL & ~DNS_S_QD; if (dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) { /* We do. Reinitialize iterator and handle it. */ - dns_rr_i_init(&F->hints_j, F->hints); + dns_rr_i_init(&F->hints_j); dgoto(R->sp, DNS_R_FOREACH_AAAA); } @@ -8935,14 +8960,14 @@ exec: if (!dns_rr_i_count(&F->hints_j)) { /* Check if we have in fact servers with an IPv4 address. */ - dns_rr_i_init(&F->hints_j, F->hints); + dns_rr_i_init(&F->hints_j); F->hints_j.name = u.ns.host; F->hints_j.type = DNS_T_A; F->hints_j.section = DNS_S_ALL & ~DNS_S_QD; if (dns_rr_grep(&rr, 1, &F->hints_j, F->hints, &error)) { /* We do. Reinitialize iterator and handle it. */ - dns_rr_i_init(&F->hints_j, F->hints); + dns_rr_i_init(&F->hints_j); dgoto(R->sp, DNS_R_FOREACH_A); } @@ -9080,7 +9105,7 @@ exec: R->smart.section = DNS_S_AN; R->smart.type = R->qtype; - dns_rr_i_init(&R->smart, F->answer); + dns_rr_i_init(&R->smart); F->state++; /* FALL THROUGH */ case DNS_R_SMART0_A: @@ -9824,7 +9849,7 @@ exec: return error; dns_strlcpy(ai->i_cname, ai->cname, sizeof ai->i_cname); - dns_rr_i_init(&ai->i, ai->answer); + dns_rr_i_init(&ai->i); ai->i.section = DNS_S_AN; ai->i.name = ai->i_cname; ai->i.type = dns_ai_qtype(ai); @@ -9871,7 +9896,7 @@ exec: ai->state++; /* FALL THROUGH */ case DNS_AI_S_ITERATE_G: dns_strlcpy(ai->g_cname, ai->cname, sizeof ai->g_cname); - dns_rr_i_init(&ai->g, ai->glue); + dns_rr_i_init(&ai->g); ai->g.section = DNS_S_ALL & ~DNS_S_QD; ai->g.name = ai->g_cname; ai->g.type = ai->af.qtype; @@ -9890,8 +9915,14 @@ exec: return dns_ai_setent(ent, &any, rr.type, ai); case DNS_AI_S_SUBMIT_G: + { + struct dns_rr_i _I = { 0 }; + + _I.section = DNS_S_QD; + _I.name = ai->g.name; + _I.type = ai->g.type; /* skip if already queried */ - if (dns_rr_grep(&rr, 1, dns_rr_i_new(ai->glue, .section = DNS_S_QD, .name = ai->g.name, .type = ai->g.type), ai->glue, &error)) + if (dns_rr_grep(&rr, 1, &_I, ai->glue, &error)) dns_ai_goto(DNS_AI_S_FOREACH_I); /* skip if we recursed (CNAME chains should have been handled in the resolver) */ if (++ai->g_depth > 1) @@ -9900,7 +9931,8 @@ exec: if ((error = dns_res_submit(ai->res, ai->g.name, ai->g.type, DNS_C_IN))) return error; - ai->state++; /* FALL THROUGH */ + ai->state++; + } /* FALL THROUGH */ case DNS_AI_S_CHECK_G: if ((error = dns_res_check(ai->res))) return error; @@ -10074,8 +10106,9 @@ static const struct { { "AR", DNS_S_ADDITIONAL }, }; -const char *(dns_strsection)(enum dns_section section, void *_dst, size_t lim) { - struct dns_buf dst = DNS_B_INTO(_dst, lim); +const char *(dns_strsection)(enum dns_section section) { + char _dst[DNS_STRMAXLEN + 1] = { 0 }; + struct dns_buf dst = DNS_B_INTO(_dst, sizeof _dst); unsigned i; for (i = 0; i < lengthof(dns_sections); i++) { @@ -10123,8 +10156,9 @@ static const struct { { "IN", DNS_C_IN }, }; -const char *(dns_strclass)(enum dns_class type, void *_dst, size_t lim) { - struct dns_buf dst = DNS_B_INTO(_dst, lim); +const char *(dns_strclass)(enum dns_class type) { + char _dst[DNS_STRMAXLEN + 1] = { 0 }; + struct dns_buf dst = DNS_B_INTO(_dst, sizeof _dst); unsigned i; for (i = 0; i < lengthof(dns_classes); i++) { @@ -10159,8 +10193,9 @@ enum dns_class dns_iclass(const char *name) { } /* dns_iclass() */ -const char *(dns_strtype)(enum dns_type type, void *_dst, size_t lim) { - struct dns_buf dst = DNS_B_INTO(_dst, lim); +const char *(dns_strtype)(enum dns_type type) { + char _dst[DNS_STRMAXLEN + 1] = { 0 }; + struct dns_buf dst = DNS_B_INTO(_dst, sizeof _dst); unsigned i; for (i = 0; i < lengthof(dns_rrtypes); i++) { @@ -10563,7 +10598,9 @@ static struct dns_trace *trace(const char *mode) { static void print_packet(struct dns_packet *P, FILE *fp) { - dns_p_dump3(P, dns_rr_i_new(P, .sort = MAIN.sort), fp); + struct dns_rr_i _I = { 0 }; + I.sort = MAIN.sort; + dns_p_dump3(P, &I, fp); if (MAIN.verbose > 2) hexdump(P->data, P->end, fp); @@ -10571,8 +10608,10 @@ static void print_packet(struct dns_packet *P, FILE *fp) { static int parse_packet(int argc DNS_NOTUSED, char *argv[] DNS_NOTUSED) { - struct dns_packet *P = dns_p_new(512); - struct dns_packet *Q = dns_p_new(512); + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _P = { 0 }; + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _Q = { 0 }; + struct dns_packet *P = dns_p_init(&_P.p, 512); + struct dns_packet *Q = dns_p_init(&_Q.p, 512); enum dns_section section; struct dns_rr rr; int error; @@ -10612,10 +10651,16 @@ static int parse_packet(int argc DNS_NOTUSED, char *argv[] DNS_NOTUSED) { #if 0 dns_rr_foreach(&rr, Q, .name = "ns8.yahoo.com.") { #else + char _p[DNS_D_MAXNAME + 1] = { 0 }; + const char *dn = "ns8.yahoo.com"; + char *_name = dns_d_init(_p, sizeof _p, dn, strlen (dn), DNS_D_ANCHOR); struct dns_rr rrset[32]; - struct dns_rr_i *rri = dns_rr_i_new(Q, .name = dns_d_new("ns8.yahoo.com", DNS_D_ANCHOR), .sort = MAIN.sort); + struct dns_rr_i _I = { 0 }; + struct dns_rr_i *rri = &I; unsigned rrcount = dns_rr_grep(rrset, lengthof(rrset), rri, Q, &error); + I.name = _name; + I.sort = MAIN.sort; for (unsigned i = 0; i < rrcount; i++) { rr = rrset[i]; #endif @@ -10641,13 +10686,14 @@ static int parse_packet(int argc DNS_NOTUSED, char *argv[] DNS_NOTUSED) { static int parse_domain(int argc, char *argv[]) { + char _p[DNS_D_MAXNAME + 1] = { 0 }; char *dn; dn = (argc > 1)? argv[1] : "f.l.google.com"; printf("[%s]\n", dn); - dn = dns_d_new(dn); + dn = dns_d_init(_p, sizeof _p, dn, strlen (dn), DNS_D_ANCHOR); do { puts(dn); @@ -10772,7 +10818,8 @@ static int show_hosts(int argc DNS_NOTUSED, char *argv[] DNS_NOTUSED) { static int query_hosts(int argc, char *argv[]) { - struct dns_packet *Q = dns_p_new(512); + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _Q = { 0 }; + struct dns_packet *Q = dns_p_init(&_Q.p, 512); struct dns_packet *A; char qname[DNS_D_MAXNAME + 1]; size_t qlen; @@ -10890,11 +10937,13 @@ static int dump_random(int argc, char *argv[]) { static int send_query(int argc, char *argv[]) { - struct dns_packet *A, *Q = dns_p_new(512); + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _Q = { 0 }; + struct dns_packet *A, *Q = dns_p_init(&_Q.p, 512); char host[INET6_ADDRSTRLEN + 1]; struct sockaddr_storage ss; struct dns_socket *so; int error, type; + struct dns_options opts = { 0 }; memset(&ss, 0, sizeof ss); if (argc > 1) { @@ -10929,7 +10978,7 @@ static int send_query(int argc, char *argv[]) { fprintf(stderr, "querying %s for %s IN %s\n", host, MAIN.qname, dns_strtype(MAIN.qtype)); - if (!(so = dns_so_open((struct sockaddr *)&resconf()->iface, type, dns_opts(), &error))) + if (!(so = dns_so_open((struct sockaddr *)&resconf()->iface, type, &opts, &error))) panic("dns_so_open: %s", dns_strerror(error)); while (!(A = dns_so_query(so, Q, (struct sockaddr *)&ss, &error))) { @@ -10984,9 +11033,10 @@ static int show_hints(int argc, char *argv[]) { if (0 == strcmp(how, "plain")) { dns_hints_dump(hints, stdout); } else { + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _P = { 0 }; struct dns_packet *query, *answer; - query = dns_p_new(512); + query = dns_p_init(&_P.p, 512); if ((error = dns_p_push(query, DNS_S_QUESTION, who, strlen(who), DNS_T_A, DNS_C_IN, 0, 0))) panic("%s: %s", who, dns_strerror(error)); @@ -11012,6 +11062,11 @@ static int resolve_query(int argc DNS_NOTUSED, char *argv[]) { struct dns_packet *ans; const struct dns_stat *st; int error; + struct dns_options opts = { 0 }; + + opts.socks_host = &MAIN.socks_host; + opts.socks_user = MAIN.socks_user; + opts.socks_password = MAIN.socks_password; if (!MAIN.qname) MAIN.qname = "www.google.com"; @@ -11021,9 +11076,7 @@ static int resolve_query(int argc DNS_NOTUSED, char *argv[]) { resconf()->options.recurse = recurse; if (!(R = dns_res_open(resconf(), hosts(), dns_hints_mortal(hints(resconf(), &error)), cache(), - dns_opts(.socks_host=&MAIN.socks_host, - .socks_user=MAIN.socks_user, - .socks_password=MAIN.socks_password), &error))) + &opts, &error))) panic("%s: %s", MAIN.qname, dns_strerror(error)); dns_res_settrace(R, trace("w+b")); @@ -11067,6 +11120,7 @@ static int resolve_addrinfo(int argc DNS_NOTUSED, char *argv[]) { struct addrinfo *ent; char pretty[512]; int error; + struct dns_options opts = { 0 }; if (!MAIN.qname) MAIN.qname = "www.google.com"; @@ -11074,7 +11128,7 @@ static int resolve_addrinfo(int argc DNS_NOTUSED, char *argv[]) { resconf()->options.recurse = recurse; - if (!(res = dns_res_open(resconf(), hosts(), dns_hints_mortal(hints(resconf(), &error)), cache(), dns_opts(), &error))) + if (!(res = dns_res_open(resconf(), hosts(), dns_hints_mortal(hints(resconf(), &error)), cache(), &opts, &error))) panic("%s: %s", MAIN.qname, dns_strerror(error)); if (!(ai = dns_ai_open(MAIN.qname, "80", MAIN.qtype, &ai_hints, res, &error))) @@ -11145,7 +11199,8 @@ static int echo_port(int argc DNS_NOTUSED, char *argv[] DNS_NOTUSED) { panic("127.0.0.1:5353: %s", dns_strerror(errno)); for (;;) { - struct dns_packet *pkt = dns_p_new(512); + union { unsigned char b[dns_p_calcsize((512))]; struct dns_packet p; } _P = { 0 }; + struct dns_packet *pkt = dns_p_init(&_P.p, 512); struct sockaddr_storage ss; socklen_t slen = sizeof ss; ssize_t count; |