]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
auth zone http work.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 8 Feb 2018 15:14:51 +0000 (15:14 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 8 Feb 2018 15:14:51 +0000 (15:14 +0000)
git-svn-id: file:///svn/unbound/trunk@4524 be551aaa-1e26-0410-a405-d3ace91eadb9

services/authzone.c
util/netevent.c

index 108bfa9b10ef88f4cb76d4c79563bf30803fb1f5..4761c0a95ebaa8ecb12c1dd22711ab5badde720e 100644 (file)
@@ -3735,23 +3735,53 @@ chunkline_get_line_collated(struct auth_chunk** chunk, size_t* chunk_pos,
        return 1;
 }
 
+/** process $ORIGIN for http */
+static int
+http_parse_origin(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
+{
+       char* line = (char*)sldns_buffer_begin(buf);
+       if(strncmp(line, "$ORIGIN", 7) == 0 &&
+               isspace((unsigned char)line[7])) {
+               int s;
+               pstate->origin_len = sizeof(pstate->origin);
+               s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8),
+                       pstate->origin, &pstate->origin_len);
+               if(s) pstate->origin_len = 0;
+               return 1;
+       }
+       return 0;
+}
+
+/** process $TTL for http */
+static int
+http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
+{
+       char* line = (char*)sldns_buffer_begin(buf);
+       if(strncmp(line, "$TTL", 4) == 0 &&
+               isspace((unsigned char)line[4])) {
+               const char* end = NULL;
+               pstate->default_ttl = sldns_str2period(
+                       sldns_strip_ws(line+5), &end);
+               return 1;
+       }
+       return 0;
+}
+
 /** find noncomment RR line in chunks, collates lines if ( ) format */
 static int
 chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
-       sldns_buffer* buf)
+       sldns_buffer* buf, struct sldns_file_parse_state* pstate)
 {
        while(chunkline_get_line_collated(chunk, chunk_pos, buf)) {
                if(chunkline_is_comment_line_or_empty(buf)) {
                        /* a comment, go to next line */
                        continue;
                }
-               if(strncmp((char*)sldns_buffer_begin(buf), "$ORIGIN", 7)==0) {
-                       /* skip $ORIGIN to find RR */
-                       continue;
+               if(http_parse_origin(buf, pstate)) {
+                       continue; /* $ORIGIN has been handled */
                }
-               if(strncmp((char*)sldns_buffer_begin(buf), "$TTL", 4)==0) {
-                       /* skip $TTL to find RR */
-                       continue;
+               if(http_parse_ttl(buf, pstate)) {
+                       continue; /* $TTL has been handled */
                }
                return 1;
        }
@@ -3767,26 +3797,68 @@ http_zonefile_syntax_check(struct auth_xfer* xfr, sldns_buffer* buf)
 {
        uint8_t rr[LDNS_RR_BUF_SIZE];
        size_t rr_len, dname_len = 0;
+       struct sldns_file_parse_state pstate;
        struct auth_chunk* chunk;
        size_t chunk_pos;
        int e;
+       memset(&pstate, 0, sizeof(pstate));
+       pstate.default_ttl = 3600;
+       if(xfr->namelen < sizeof(pstate.origin)) {
+               pstate.origin_len = xfr->namelen;
+               memmove(pstate.origin, xfr->name, xfr->namelen);
+       }
        chunk = xfr->task_transfer->chunks_first;
        chunk_pos = 0;
-       if(!chunkline_non_comment_RR(&chunk, &chunk_pos, buf)) {
+       if(!chunkline_non_comment_RR(&chunk, &chunk_pos, buf, &pstate)) {
                return 0;
        }
        rr_len = sizeof(rr);
        e=sldns_str2wire_rr_buf((char*)sldns_buffer_begin(buf), rr, &rr_len,
-               &dname_len, 3600, NULL, 0, NULL, 0);
+               &dname_len, pstate.default_ttl,
+               pstate.origin_len?pstate.origin:NULL, pstate.origin_len,
+               pstate.prev_rr_len?pstate.prev_rr:NULL, pstate.prev_rr_len);
        if(e != 0) {
                log_err("parse failure on SOA RR[%d]: %s",
                        LDNS_WIREPARSE_OFFSET(e),
                        sldns_get_errorstr_parse(LDNS_WIREPARSE_ERROR(e)));
                return 0;
        }
+       /* check that name is correct */
+       if(query_dname_compare(rr, xfr->name) != 0) {
+               char nm[255+1], zname[255+1];
+               dname_str(rr, nm);
+               dname_str(xfr->name, zname);
+               log_err("parse failure for %s, SOA RR for %s found instead",
+                       zname, nm);
+               return 0;
+       }
+       /* check that type is SOA */
+       if(sldns_wirerr_get_type(rr, rr_len, dname_len) != LDNS_RR_TYPE_SOA) {
+               log_err("parse failure: first record in downloaded zonefile "
+                       "not of type SOA");
+               return 0;
+       }
+       /* check that class is correct */
+       if(sldns_wirerr_get_class(rr, rr_len, dname_len) != xfr->dclass) {
+               log_err("parse failure: first record in downloaded zonefile "
+                       "from wrong RR class");
+               return 0;
+       }
        return 1;
 }
 
+/** sum sizes of chunklist */
+static size_t
+chunklist_sum(struct auth_chunk* list)
+{
+       struct auth_chunk* p;
+       size_t s = 0;
+       for(p=list; p; p=p->next) {
+               s += p->len;
+       }
+       return s;
+}
+
 /** remove newlines from collated line */
 static void
 chunkline_newline_removal(sldns_buffer* buf)
@@ -3799,38 +3871,6 @@ chunkline_newline_removal(sldns_buffer* buf)
        }
 }
 
-/** process $ORIGIN for http */
-static int
-http_parse_origin(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
-{
-       char* line = (char*)sldns_buffer_begin(buf);
-       if(strncmp(line, "$ORIGIN", 7) == 0 &&
-               isspace((unsigned char)line[7])) {
-               int s;
-               pstate->origin_len = sizeof(pstate->origin);
-               s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8),
-                       pstate->origin, &pstate->origin_len);
-               if(s) pstate->origin_len = 0;
-               return 1;
-       }
-       return 0;
-}
-
-/** process $TTL for http */
-static int
-http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
-{
-       char* line = (char*)sldns_buffer_begin(buf);
-       if(strncmp(line, "$TTL", 4) == 0 &&
-               isspace((unsigned char)line[4])) {
-               const char* end = NULL;
-               pstate->default_ttl = sldns_str2period(
-                       sldns_strip_ws(line+5), &end);
-               return 1;
-       }
-       return 0;
-}
-
 /** for http download, parse and add RR to zone */
 static int
 http_parse_add_rr(struct auth_xfer* xfr, struct auth_zone* z,
@@ -4202,6 +4242,10 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
                memmove(pstate.origin, xfr->name, xfr->namelen);
        }
 
+       if(verbosity >= VERB_ALGO)
+               verbose(VERB_ALGO, "http download %s of size %d",
+               xfr->task_transfer->master->file,
+               (int)chunklist_sum(xfr->task_transfer->chunks_first));
        if(xfr->task_transfer->chunks_first && verbosity >= VERB_ALGO) {
                char preview[1024];
                if(xfr->task_transfer->chunks_first->len+1 > sizeof(preview)) {
@@ -4220,8 +4264,7 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
        /* perhaps a little syntax check before we try to apply the data? */
        if(!http_zonefile_syntax_check(xfr, scratch_buffer)) {
                log_err("http download %s/%s does not contain a zonefile, "
-                       " no SOA but got '%s'",
-                       xfr->task_transfer->master->host,
+                       "but got '%s'", xfr->task_transfer->master->host,
                        xfr->task_transfer->master->file,
                        sldns_buffer_begin(scratch_buffer));
                return 0;
index 90bba04dff0f47c679c403a46a9df2fb0fb57bd0..8723b4740fbd08a199b8219fd9945e22104afdbd 100644 (file)
@@ -2916,7 +2916,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
                c->timeout->tv_usec = (msec%1000)*1000;
 #endif /* S_SPLINT_S */
        }
-       if(c->type == comm_tcp) {
+       if(c->type == comm_tcp || c->type == comm_http) {
                ub_event_del_bits(c->ev->ev, UB_EV_READ|UB_EV_WRITE);
                if(c->tcp_is_reading)
                        ub_event_add_bits(c->ev->ev, UB_EV_READ);