From: Jelte Jansen Date: Thu, 24 Mar 2005 15:29:56 +0000 (+0000) Subject: tsig answer verification works! X-Git-Tag: release-0.50~188 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33f63c636a85feaf6ef3ac824ed3f0f2bd18bbd9;p=thirdparty%2Fldns.git tsig answer verification works! code a bit of a mess now, cleanup on the TODO --- diff --git a/dnssec.c b/dnssec.c index 2e87fb29..77b624a2 100644 --- a/dnssec.c +++ b/dnssec.c @@ -396,9 +396,114 @@ ldns_key_buf2rsa(ldns_buffer *key) return rsa; } +/** + * Makes an exact copy of the wire, but with the tsig rr removed + */ +uint8_t * +ldns_tsig_prepare_pkt_wire(uint8_t *wire, size_t wire_len, size_t *result_len) +{ + uint8_t *wire2 = NULL; + uint16_t qd_count; + uint16_t an_count; + uint16_t ns_count; + uint16_t ar_count; + ldns_rr *rr; + + size_t pos; + uint16_t i; + + ldns_status status; + + /* fake parse the wire */ + qd_count = QDCOUNT(wire); + an_count = ANCOUNT(wire); + ns_count = NSCOUNT(wire); + ar_count = ARCOUNT(wire); + + if (ar_count > 0) { + ar_count--; + } else { + return NULL; + } + +printf("\n\n\n\n\n"); +printf("WIRE:\n"); +for(i=0; i #include #include +#include #include @@ -24,12 +25,12 @@ /* prototypes */ -ldns_pkt * ldns_send_udp(ldns_buffer *, const struct sockaddr_storage *, socklen_t, struct timeval timeout); -ldns_pkt * ldns_send_tcp(ldns_buffer *, const struct sockaddr_storage *, socklen_t, struct timeval timeout); +uint8_t * ldns_send_udp(ldns_buffer *, const struct sockaddr_storage *, socklen_t, struct timeval timeout, size_t *); +uint8_t * ldns_send_tcp(ldns_buffer *, const struct sockaddr_storage *, socklen_t, struct timeval timeout, size_t *); ldns_pkt * ldns_send(ldns_resolver *, ldns_pkt *); int ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout); ssize_t ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, socklen_t tolen); -ldns_pkt *ldns_tcp_read_packet(int sockfd); +uint8_t *ldns_tcp_read_wire(int sockfd, size_t *size); #endif /* !_LDNS_NET_H */ diff --git a/ldns/wire2host.h b/ldns/wire2host.h index fe827f1a..54e751ab 100644 --- a/ldns/wire2host.h +++ b/ldns/wire2host.h @@ -8,6 +8,94 @@ #include #include +/* The length of the header */ +#define HEADER_SIZE 12 + +/* First octet of flags */ +#define RD_MASK 0x01U +#define RD_SHIFT 0 +#define RD(wirebuf) (*(wirebuf+2) & RD_MASK) +#define RD_SET(wirebuf) (*(wirebuf+2) |= RD_MASK) +#define RD_CLR(wirebuf) (*(wirebuf+2) &= ~RD_MASK) + +#define TC_MASK 0x02U +#define TC_SHIFT 1 +#define TC(wirebuf) (*(wirebuf+2) & TC_MASK) +#define TC_SET(wirebuf) (*(wirebuf+2) |= TC_MASK) +#define TC_CLR(wirebuf) (*(wirebuf+2) &= ~TC_MASK) + +#define AA_MASK 0x04U +#define AA_SHIFT 2 +#define AA(wirebuf) (*(wirebuf+2) & AA_MASK) +#define AA_SET(wirebuf) (*(wirebuf+2) |= AA_MASK) +#define AA_CLR(wirebuf) (*(wirebuf+2) &= ~AA_MASK) + +#define OPCODE_MASK 0x78U +#define OPCODE_SHIFT 3 +#define OPCODE(wirebuf) ((*(wirebuf+2) & OPCODE_MASK) >> OPCODE_SHIFT) +#define OPCODE_SET(wirebuf, opcode) \ + (*(wirebuf+2) = ((*(wirebuf+2)) & ~OPCODE_MASK) | ((opcode) << OPCODE_SHIFT)) + +#define QR_MASK 0x80U +#define QR_SHIFT 7 +#define QR(wirebuf) (*(wirebuf+2) & QR_MASK) +#define QR_SET(wirebuf) (*(wirebuf+2) |= QR_MASK) +#define QR_CLR(wirebuf) (*(wirebuf+2) &= ~QR_MASK) + +/* Second octet of flags */ +#define RCODE_MASK 0x0fU +#define RCODE_SHIFT 0 +#define RCODE(wirebuf) (*(wirebuf+3) & RCODE_MASK) +#define RCODE_SET(wirebuf, rcode) \ + (*(wirebuf+3) = ((*(wirebuf+3)) & ~RCODE_MASK) | (rcode)) + +#define CD_MASK 0x10U +#define CD_SHIFT 4 +#define CD(wirebuf) (*(wirebuf+3) & CD_MASK) +#define CD_SET(wirebuf) (*(wirebuf+3) |= CD_MASK) +#define CD_CLR(wirebuf) (*(wirebuf+3) &= ~CD_MASK) + +#define AD_MASK 0x20U +#define AD_SHIFT 5 +#define AD(wirebuf) (*(wirebuf+3) & AD_MASK) +#define AD_SET(wirebuf) (*(wirebuf+3) |= AD_MASK) +#define AD_CLR(wirebuf) (*(wirebuf+3) &= ~AD_MASK) + +#define Z_MASK 0x40U +#define Z_SHIFT 6 +#define Z(wirebuf) (*(wirebuf+3) & Z_MASK) +#define Z_SET(wirebuf) (*(wirebuf+3) |= Z_MASK) +#define Z_CLR(wirebuf) (*(wirebuf+3) &= ~Z_MASK) + +#define RA_MASK 0x80U +#define RA_SHIFT 7 +#define RA(wirebuf) (*(wirebuf+3) & RA_MASK) +#define RA_SET(wirebuf) (*(wirebuf+3) |= RA_MASK) +#define RA_CLR(wirebuf) (*(wirebuf+3) &= ~RA_MASK) + +/* Query ID */ +#define ID(wirebuf) (read_uint16(wirebuf)) + +/* Counter of the question section */ +#define QDCOUNT_OFF 4 +/* +#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF))) +*/ +#define QDCOUNT(wirebuf) (read_uint16(wirebuf+QDCOUNT_OFF)) + +/* Counter of the answer section */ +#define ANCOUNT_OFF 6 +#define ANCOUNT(wirebuf) (read_uint16(wirebuf+ANCOUNT_OFF)) + +/* Counter of the authority section */ +#define NSCOUNT_OFF 8 +#define NSCOUNT(wirebuf) (read_uint16(wirebuf+NSCOUNT_OFF)) + +/* Counter of the additional section */ +#define ARCOUNT_OFF 10 +#define ARCOUNT(wirebuf) (read_uint16(wirebuf+ARCOUNT_OFF)) + + /** * Converts the data on the uint8_t bytearray (in wire format) to a DNS packet diff --git a/net.c b/net.c index 39d2cd4f..53aa0370 100644 --- a/net.c +++ b/net.c @@ -22,7 +22,6 @@ #include #include #include - #include #include #include @@ -55,17 +54,27 @@ ldns_send(ldns_resolver *r, ldns_pkt *query_pkt) ldns_rdf **ns_array; ldns_pkt *reply; ldns_buffer *qb; + + uint8_t *reply_bytes = NULL; + size_t reply_size = 0; + + ldns_rdf *tsig_mac = NULL; ns_array = ldns_resolver_nameservers(r); reply = NULL; ns_len = 0; qb = ldns_buffer_new(MAX_PACKETLEN); + if (ldns_pkt_tsig(query_pkt)) { + tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3); + } + if (ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) { printf("could not convert to wire fmt\n"); return NULL; } + /* loop through all defined nameservers */ for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { @@ -97,11 +106,18 @@ ldns_send(ldns_resolver *r, ldns_pkt *query_pkt) gettimeofday(&tv_s, NULL); /* query */ if (1 == ldns_resolver_usevc(r)) { - reply = ldns_send_tcp(qb, ns, ns_len, ldns_resolver_timeout(r)); + reply_bytes = ldns_send_tcp(qb, ns, ns_len, ldns_resolver_timeout(r), &reply_size); } else { /* udp here, please */ - reply = ldns_send_udp(qb, ns, ns_len, ldns_resolver_timeout(r)); + reply_bytes = ldns_send_udp(qb, ns, ns_len, ldns_resolver_timeout(r), &reply_size); } + + if (ldns_wire2pkt(&reply, reply_bytes, reply_size) != + LDNS_STATUS_OK) { + printf("malformed answer\n"); + return NULL; + } + FREE(ns); gettimeofday(&tv_e, NULL); @@ -110,7 +126,7 @@ ldns_send(ldns_resolver *r, ldns_pkt *query_pkt) ((tv_e.tv_sec - tv_s.tv_sec) * 1000) + (tv_e.tv_usec - tv_s.tv_usec) / 1000); ldns_pkt_set_answerfrom(reply, ns_array[i]); - ldns_pkt_set_when(reply, ctime((time_t*)&tv_s.tv_sec)); + ldns_pkt_set_when(reply, ctime((time_t*)&tv_s.tv_sec)); break; } else { if (ldns_resolver_fail(r)) { @@ -122,6 +138,19 @@ ldns_send(ldns_resolver *r, ldns_pkt *query_pkt) /* wait retrans seconds... */ } + + if (tsig_mac && reply_bytes) { + if (!ldns_pkt_tsig_verify(reply, + reply_bytes, + reply_size, + ldns_resolver_tsig_keyname(r), + ldns_resolver_tsig_keydata(r), + tsig_mac)) { + /* TODO: no print, feedback */ + printf(";; WARNING: TSIG VERIFICATION OF ANSWER FAILED!\n"); + } + } + ldns_buffer_free(qb); return reply; } @@ -134,15 +163,15 @@ ldns_send(ldns_resolver *r, ldns_pkt *query_pkt) * \param[in] timeout the timeout value for the network * \return a packet with the answer */ -ldns_pkt * -ldns_send_udp(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout) +uint8_t * +ldns_send_udp(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answer_size) { int sockfd; ssize_t bytes; uint8_t *answer; - ldns_pkt *answer_pkt; - /* + + ldns_pkt *answer_pkt; struct timeval timeout; timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC; @@ -199,16 +228,9 @@ ldns_send_udp(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t to /* resize accordingly */ answer = (uint8_t*)XREALLOC(answer, uint8_t *, (size_t) bytes); + *answer_size = (size_t) bytes; - if (ldns_wire2pkt(&answer_pkt, answer, (size_t) bytes) != - LDNS_STATUS_OK) { - FREE(answer); - return NULL; - } else { - ldns_pkt_set_size(answer_pkt, (size_t) bytes); - FREE(answer); - return answer_pkt; - } + return answer; } /** @@ -275,10 +297,9 @@ ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage * Creates a new ldns_pkt structure and reads the header data from the given * socket */ -ldns_pkt * -ldns_tcp_read_packet(int sockfd) +uint8_t * +ldns_tcp_read_wire(int sockfd, size_t *size) { - ldns_pkt *pkt; uint8_t *wire; uint16_t wire_size; ssize_t bytes = 0; @@ -291,7 +312,6 @@ ldns_tcp_read_packet(int sockfd) fprintf(stderr, "socket timeout\n"); } perror("error receiving tcp packet"); - FREE(pkt); return NULL; } } @@ -313,17 +333,10 @@ ldns_tcp_read_packet(int sockfd) return NULL; } } + + *size = (size_t) bytes; - if (ldns_wire2pkt(&pkt, wire, (size_t) wire_size) != - LDNS_STATUS_OK) { - printf("could not create packet\n"); - FREE(wire); - return NULL; - } else { - ldns_pkt_set_size(pkt, (size_t) bytes); - FREE(wire); - return pkt; - } + return wire; } /** @@ -337,11 +350,11 @@ ldns_tcp_read_packet(int sockfd) /* keep in mind that in DNS tcp messages the first 2 bytes signal the * amount data to expect */ -ldns_pkt * -ldns_send_tcp(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout) +uint8_t * +ldns_send_tcp(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, struct timeval timeout, size_t *answer_size) { int sockfd; - ldns_pkt *answer; + uint8_t *answer; sockfd = ldns_tcp_connect(to, tolen, timeout); @@ -353,7 +366,7 @@ ldns_send_tcp(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t to return NULL; } - answer = ldns_tcp_read_packet(sockfd); + answer = ldns_tcp_read_wire(sockfd, answer_size); close(sockfd); diff --git a/resolver.c b/resolver.c index aedefcbb..8049544d 100644 --- a/resolver.c +++ b/resolver.c @@ -667,7 +667,6 @@ ldns_resolver_send(ldns_resolver *r, ldns_rdf *name, ldns_rr_type type, ldns_rr_ uint8_t retries; ldns_status status; - ldns_rdf *tsig_mac = NULL; assert(r != NULL); assert(name != NULL); @@ -733,8 +732,6 @@ ldns_resolver_send(ldns_resolver *r, ldns_rdf *name, ldns_rr_type type, ldns_rr_ 300, "hmac-md5.sig-alg.reg.int", NULL); - tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3); - /* TODO: no print and feedback to caller */ if (status != LDNS_STATUS_OK) { fprintf(stderr, "error creating tsig: %u\n", status); @@ -752,16 +749,6 @@ ldns_resolver_send(ldns_resolver *r, ldns_rdf *name, ldns_rr_type type, ldns_rr_ ldns_pkt_free(query_pkt); - if (tsig_mac) { - if (!ldns_pkt_tsig_verify(answer_pkt, - ldns_resolver_tsig_keyname(r), - ldns_resolver_tsig_keydata(r), - tsig_mac)) { - /* TODO: no print, feedback */ - printf(";; WARNING: TSIG VERIFICATION OF ANSWER FAILED!\n"); - } - } - return answer_pkt; } @@ -864,6 +851,8 @@ ldns_rr * ldns_axfr_next(ldns_resolver *resolver) { ldns_rr *cur_rr; + uint8_t *packet_wire; + size_t packet_wire_size; /* check if start() has been called */ if (!resolver || resolver->_socket == 0) { @@ -888,7 +877,11 @@ ldns_axfr_next(ldns_resolver *resolver) } return cur_rr; } else { - resolver->_cur_axfr_pkt = ldns_tcp_read_packet(resolver->_socket); + packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size); + + ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, packet_wire_size); + free(packet_wire); +/* resolver->_cur_axfr_pkt = ldns_tcp_read_packet(resolver->_socket);*/ resolver->_axfr_i = 0; return ldns_axfr_next(resolver); diff --git a/wire2host.c b/wire2host.c index 30801021..919b0c7f 100644 --- a/wire2host.c +++ b/wire2host.c @@ -47,93 +47,6 @@ * */ -/* The length of the header */ -#define HEADER_SIZE 12 - -/* First octet of flags */ -#define RD_MASK 0x01U -#define RD_SHIFT 0 -#define RD(wirebuf) (*(wirebuf+2) & RD_MASK) -#define RD_SET(wirebuf) (*(wirebuf+2) |= RD_MASK) -#define RD_CLR(wirebuf) (*(wirebuf+2) &= ~RD_MASK) - -#define TC_MASK 0x02U -#define TC_SHIFT 1 -#define TC(wirebuf) (*(wirebuf+2) & TC_MASK) -#define TC_SET(wirebuf) (*(wirebuf+2) |= TC_MASK) -#define TC_CLR(wirebuf) (*(wirebuf+2) &= ~TC_MASK) - -#define AA_MASK 0x04U -#define AA_SHIFT 2 -#define AA(wirebuf) (*(wirebuf+2) & AA_MASK) -#define AA_SET(wirebuf) (*(wirebuf+2) |= AA_MASK) -#define AA_CLR(wirebuf) (*(wirebuf+2) &= ~AA_MASK) - -#define OPCODE_MASK 0x78U -#define OPCODE_SHIFT 3 -#define OPCODE(wirebuf) ((*(wirebuf+2) & OPCODE_MASK) >> OPCODE_SHIFT) -#define OPCODE_SET(wirebuf, opcode) \ - (*(wirebuf+2) = ((*(wirebuf+2)) & ~OPCODE_MASK) | ((opcode) << OPCODE_SHIFT)) - -#define QR_MASK 0x80U -#define QR_SHIFT 7 -#define QR(wirebuf) (*(wirebuf+2) & QR_MASK) -#define QR_SET(wirebuf) (*(wirebuf+2) |= QR_MASK) -#define QR_CLR(wirebuf) (*(wirebuf+2) &= ~QR_MASK) - -/* Second octet of flags */ -#define RCODE_MASK 0x0fU -#define RCODE_SHIFT 0 -#define RCODE(wirebuf) (*(wirebuf+3) & RCODE_MASK) -#define RCODE_SET(wirebuf, rcode) \ - (*(wirebuf+3) = ((*(wirebuf+3)) & ~RCODE_MASK) | (rcode)) - -#define CD_MASK 0x10U -#define CD_SHIFT 4 -#define CD(wirebuf) (*(wirebuf+3) & CD_MASK) -#define CD_SET(wirebuf) (*(wirebuf+3) |= CD_MASK) -#define CD_CLR(wirebuf) (*(wirebuf+3) &= ~CD_MASK) - -#define AD_MASK 0x20U -#define AD_SHIFT 5 -#define AD(wirebuf) (*(wirebuf+3) & AD_MASK) -#define AD_SET(wirebuf) (*(wirebuf+3) |= AD_MASK) -#define AD_CLR(wirebuf) (*(wirebuf+3) &= ~AD_MASK) - -#define Z_MASK 0x40U -#define Z_SHIFT 6 -#define Z(wirebuf) (*(wirebuf+3) & Z_MASK) -#define Z_SET(wirebuf) (*(wirebuf+3) |= Z_MASK) -#define Z_CLR(wirebuf) (*(wirebuf+3) &= ~Z_MASK) - -#define RA_MASK 0x80U -#define RA_SHIFT 7 -#define RA(wirebuf) (*(wirebuf+3) & RA_MASK) -#define RA_SET(wirebuf) (*(wirebuf+3) |= RA_MASK) -#define RA_CLR(wirebuf) (*(wirebuf+3) &= ~RA_MASK) - -/* Query ID */ -#define ID(wirebuf) (read_uint16(wirebuf)) - -/* Counter of the question section */ -#define QDCOUNT_OFF 4 -/* -#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF))) -*/ -#define QDCOUNT(wirebuf) (read_uint16(wirebuf+QDCOUNT_OFF)) - -/* Counter of the answer section */ -#define ANCOUNT_OFF 6 -#define ANCOUNT(wirebuf) (read_uint16(wirebuf+ANCOUNT_OFF)) - -/* Counter of the authority section */ -#define NSCOUNT_OFF 8 -#define NSCOUNT(wirebuf) (read_uint16(wirebuf+NSCOUNT_OFF)) - -/* Counter of the additional section */ -#define ARCOUNT_OFF 10 -#define ARCOUNT(wirebuf) (read_uint16(wirebuf+ARCOUNT_OFF)) - /* allocates memory to *dname! */ ldns_status @@ -512,6 +425,9 @@ printf("\n"); ldns_rr_free(rr); ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) - 1); } else if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_TSIG) { +printf("PACKET HAD TSIG: "); +ldns_rr_print(stdout, rr); +printf("\n"); ldns_pkt_set_tsig(packet, rr); ldns_pkt_set_arcount(packet, ldns_pkt_arcount(packet) - 1); } else if (!ldns_rr_list_push_rr(ldns_pkt_additional(packet), rr)) {