Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  * verify.c -- running verifiers and serving the zone to be verified.
      3  *
      4  * Copyright (c) 2012-2020, NLnet Labs. All rights reserved.
      5  *
      6  * See LICENSE for the license.
      7  *
      8  */
      9 
     10 #include "config.h"
     11 
     12 #include <assert.h>
     13 #include <ctype.h>
     14 #include <errno.h>
     15 #include <stdarg.h>
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 #ifdef HAVE_SYSLOG_H
     20 #include <syslog.h>
     21 #endif /* HAVE_SYSLOG_H */
     22 #include <unistd.h>
     23 #include <fcntl.h>
     24 #include <sys/wait.h>
     25 
     26 #include "region-allocator.h"
     27 #include "namedb.h"
     28 #include "nsd.h"
     29 #include "options.h"
     30 #include "difffile.h"
     31 #include "verify.h"
     32 #include "popen3.h"
     33 
     34 struct zone *verify_next_zone(struct nsd *nsd, struct zone *zone)
     35 {
     36 	int verify;
     37 	struct radnode *node;
     38 
     39 	if(zone != NULL) {
     40 		node = radix_next(zone->node);
     41 	} else {
     42 		node = radix_first(nsd->db->zonetree);
     43 	}
     44 
     45 	while(node != NULL) {
     46 		zone = (struct zone *)node->elem;
     47 		verify = zone->opts->pattern->verify_zone;
     48 		if(verify == VERIFY_ZONE_INHERIT) {
     49 			verify = nsd->options->verify_zones;
     50 		}
     51 		if(verify && zone->is_updated && !zone->is_checked) {
     52 			return zone;
     53 		}
     54 		node = radix_next(node);
     55 	}
     56 
     57 	return NULL;
     58 }
     59 
     60 static inline ssize_t fill_buffer(struct verifier_stream *stream)
     61 {
     62 	ssize_t cnt = 0;
     63 
     64 	assert(stream);
     65 	assert(stream->fd != -1);
     66 	assert(stream->cnt <= LOGBUFSIZE);
     67 	assert(stream->off <= stream->cnt);
     68 
     69 	// move data to start of buffer assuming all complete lines are printed
     70 	if (stream->off) {
     71 		size_t len = stream->cnt - stream->off;
     72 		memmove(stream->buf, stream->buf + stream->off, len);
     73 		stream->off = 0;
     74 		stream->cnt = len;
     75 		stream->buf[stream->cnt] = '\0'; // always null-terminate
     76 	}
     77 
     78 	// read data if space is available
     79 	cnt = read(stream->fd, stream->buf + stream->cnt, LOGBUFSIZE - stream->cnt);
     80 	if (cnt > 0)
     81 		stream->cnt += (size_t)cnt;
     82 	assert(stream->cnt <= LOGBUFSIZE);
     83 	assert(stream->off <= stream->cnt);
     84 	stream->buf[stream->cnt] = '\0'; // always null-terminate
     85 
     86 	return cnt;
     87 }
     88 
     89 static inline size_t print_line(struct verifier_stream *stream, int eof)
     90 {
     91 	char *eol = NULL;
     92 	size_t len;
     93 	const char *fmt;
     94 
     95 	if (stream->cnt == 0)
     96 		return 0;
     97 	assert(stream->off <= stream->cnt);
     98 	if (stream->off == stream->cnt)
     99 		return 0;
    100 
    101 	// try to locate natural line break
    102 	assert(stream->buf[stream->cnt] == '\0');
    103 	if ((eol = strchr(stream->buf + stream->off, '\n'))) {
    104 		len = eol - (stream->buf + stream->off);
    105 	} else {
    106 		len = stream->cnt - stream->off;
    107 	}
    108 
    109 	assert(len <= (stream->cnt - stream->off));
    110 	// wait for buffer to contain a full line except on eof
    111 	if (len < LOGLINELEN && !eol && !eof)
    112 		return 0;
    113 
    114 	if (len > LOGLINELEN) {
    115 		fmt = stream->cut ? "verifier: .. %.*s .." : "verifier: %.*s ..";
    116 		len = LOGLINELEN; // remainder printed next iteration
    117 		stream->cut = 1;
    118 	} else {
    119 		fmt = stream->cut ? "verifier: .. %.*s" : "verifier: %.*s";
    120 		stream->cut = 0;
    121 	}
    122 	log_msg(stream->priority, fmt, len, stream->buf + stream->off);
    123 
    124 	stream->off += len + (eol != NULL);
    125 	assert(stream->off <= stream->cnt);
    126 	return len;
    127 }
    128 
    129 /*
    130  * Log verifier output on STDOUT and STDERR. Lines longer than LOGLINELEN are
    131  * split over multiple lines. Line-breaks are indicated in the log with "...".
    132  */
    133 static void verify_handle_stream(int fd, short event, void *arg)
    134 {
    135 	int eof = 0;
    136 	ssize_t cnt;
    137 	struct verifier *verifier;
    138 	struct verifier_stream *stream;
    139 
    140 	assert((event & EV_READ));
    141 	assert(arg != NULL);
    142 
    143 	verifier = (struct verifier *)arg;
    144 	if (fd == verifier->output_stream.fd) {
    145 		stream = &verifier->output_stream;
    146 	} else {
    147 		assert(fd == verifier->error_stream.fd);
    148 		stream = &verifier->error_stream;
    149 	}
    150 
    151 	assert(stream);
    152 	assert(stream->fd != -1);
    153 
    154 	do {
    155 		cnt = fill_buffer(stream);
    156 		eof = !cnt || (cnt < 0 && errno != EAGAIN && errno != EINTR);
    157 		while (print_line(stream, eof)) ;
    158 	} while (cnt > 0);
    159 
    160 	if(eof) {
    161 		event_del(&stream->event);
    162 		close(stream->fd);
    163 		stream->fd = -1;
    164 	}
    165 }
    166 
    167 static void kill_verifier(struct verifier *verifier)
    168 {
    169 	assert(verifier != NULL);
    170 	assert(verifier->zone != NULL);
    171 
    172 	if(kill(verifier->pid, SIGTERM) == -1) {
    173 		log_msg(LOG_ERR, "verify: cannot kill verifier for "
    174 		                 "zone %s (pid %d): %s",
    175 		                 verifier->zone->opts->name,
    176 		                 verifier->pid,
    177 		                 strerror(errno));
    178 	}
    179 }
    180 
    181 static void close_stream(struct verifier *verifier, struct verifier_stream *stream)
    182 {
    183 	if (stream->fd == -1)
    184 		return;
    185 	verify_handle_stream(stream->fd, EV_READ, verifier);
    186 	if (stream->fd == -1)
    187 		return;
    188 	event_del(&stream->event);
    189 	close(stream->fd);
    190 	stream->fd = -1;
    191 }
    192 
    193 static void close_verifier(struct verifier *verifier)
    194 {
    195 	/* unregister events and close streams (in that order) */
    196 	if(verifier->timeout.tv_sec > 0) {
    197 		event_del(&verifier->timeout_event);
    198 		verifier->timeout.tv_sec = 0;
    199 		verifier->timeout.tv_usec = 0;
    200 	}
    201 
    202 	if(verifier->zone_feed.fh != NULL) {
    203 		event_del(&verifier->zone_feed.event);
    204 		fclose(verifier->zone_feed.fh);
    205 		verifier->zone_feed.fh = NULL;
    206 		region_destroy(verifier->zone_feed.region);
    207 	}
    208 
    209 	close_stream(verifier, &verifier->error_stream);
    210 	close_stream(verifier, &verifier->output_stream);
    211 
    212 	verifier->zone->is_ok = verifier->was_ok;
    213 	verifier->pid = -1;
    214 	verifier->zone = NULL;
    215 }
    216 
    217 /*
    218  * Feed zone to verifier over STDIN as it becomes available.
    219  */
    220 static void verify_handle_feed(int fd, short event, void *arg)
    221 {
    222 	struct verifier *verifier;
    223 	struct rr *rr;
    224 
    225 	(void)fd;
    226 	assert(event == EV_WRITE);
    227 	assert(arg != NULL);
    228 
    229 	verifier = (struct verifier *)arg;
    230 	if((rr = zone_rr_iter_next(&verifier->zone_feed.rriter)) != NULL) {
    231 		print_rr(verifier->zone_feed.fh,
    232 		         verifier->zone_feed.rrprinter,
    233 		         rr,
    234 		         verifier->zone_feed.region,
    235 		         verifier->zone_feed.buffer);
    236 	} else {
    237 		event_del(&verifier->zone_feed.event);
    238 		fclose(verifier->zone_feed.fh);
    239 		verifier->zone_feed.fh = NULL;
    240 		region_destroy(verifier->zone_feed.region);
    241 	}
    242 }
    243 
    244 /*
    245  * This handler will be called when a verifier-timeout alarm goes off. It just
    246  * kills the verifier. server_verify_zones will make sure the zone will be
    247  * considered bad.
    248  */
    249 void verify_handle_timeout(int fd, short event, void *arg)
    250 {
    251 	struct verifier *verifier;
    252 
    253 	(void)fd;
    254 	assert((event & EV_TIMEOUT));
    255 	assert(arg != NULL);
    256 
    257 	verifier = (struct verifier *)arg;
    258 	verifier->zone->is_bad = 1;
    259 
    260 	log_msg(LOG_ERR, "verify: verifier for zone %s (pid %d) timed out",
    261 	                 verifier->zone->opts->name, verifier->pid);
    262 
    263 	/* kill verifier, process reaped by exit handler */
    264 	kill_verifier(verifier);
    265 }
    266 
    267 void verify_handle_signal(int sig, short event, void *arg)
    268 {
    269 	char buf[1] = { '\0' };
    270 	struct nsd *nsd;
    271 
    272 	assert(sig == SIGCHLD);
    273 	assert((event & EV_SIGNAL));
    274 	assert(arg != NULL);
    275 
    276 	nsd = (struct nsd *)arg;
    277 	if(write(nsd->verifier_pipe[1], buf, sizeof(buf)) == -1) {
    278 		log_msg(LOG_ERR, "verify_handle_signal: write failed: %s",
    279 				strerror(errno));
    280 	}
    281 }
    282 
    283 /*
    284  * Reap process and update status of respective zone based on the exit code
    285  * of a verifier. Everything from STDOUT and STDERR still available is read and
    286  * written to the log as it might contain valuable information.
    287  *
    288  * NOTE: A timeout might have caused the verifier to be terminated.
    289  */
    290 void verify_handle_exit(int fd, short event, void *arg)
    291 {
    292 	int wstatus;
    293 	pid_t pid;
    294 	struct nsd *nsd;
    295 	char buf[1];
    296 
    297 	assert((event & EV_READ));
    298 	assert(arg != NULL);
    299 
    300 	nsd = (struct nsd *)arg;
    301 
    302 	if(read(fd, buf, sizeof(buf)) == -1) {
    303 		if(errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK)
    304 			log_msg(LOG_ERR, "verify_handle_exit: read failed: %s",
    305 				strerror(errno));
    306 	}
    307 
    308 	while(((pid = waitpid(-1, &wstatus, WNOHANG)) == -1 && errno == EINTR)
    309 	    || (pid > 0))
    310 	{
    311 		struct verifier *verifier = NULL;
    312 
    313 		for(size_t i = 0; !verifier && i < nsd->verifier_limit; i++) {
    314 			if(nsd->verifiers[i].zone != NULL &&
    315 			   nsd->verifiers[i].pid == pid)
    316 			{
    317 				verifier = &nsd->verifiers[i];
    318 			}
    319 		}
    320 
    321 		if(verifier == NULL) {
    322 			continue;
    323 		}
    324 
    325 		if(!WIFEXITED(wstatus)) {
    326 			log_msg(LOG_ERR, "verify: verifier for zone %s "
    327 			                 "(pid %d) exited abnormally",
    328 			                 verifier->zone->opts->name, pid);
    329 		} else {
    330 			int priority = LOG_INFO;
    331 			int status = WEXITSTATUS(wstatus);
    332 			if(status != 0) {
    333 				priority = LOG_ERR;
    334 				verifier->zone->is_bad = 1;
    335 			}
    336 			log_msg(priority, "verify: verifier for zone %s "
    337 			                  "(pid %d) exited with %d",
    338 			                  verifier->zone->opts->name, pid, status);
    339 		}
    340 
    341 		close_verifier(verifier);
    342 		nsd->verifier_count--;
    343 	}
    344 
    345 	while(nsd->mode == NSD_RUN &&
    346 	      nsd->verifier_count < nsd->verifier_limit &&
    347 	      nsd->next_zone_to_verify != NULL)
    348 	{
    349 		verify_zone(nsd, nsd->next_zone_to_verify);
    350 		nsd->next_zone_to_verify
    351 			= verify_next_zone(nsd, nsd->next_zone_to_verify);
    352 	}
    353 
    354 	if(nsd->next_zone_to_verify == NULL && nsd->verifier_count == 0) {
    355 		event_base_loopexit(nsd->event_base, NULL);
    356 		return;
    357 	}
    358 }
    359 
    360 /*
    361  * A parent may be terminated (by the NSD_QUIT signal (nsdc stop command)).
    362  * When a reload server process is running, the parent will then send a
    363  * NSD_QUIT command to that server. This handler makes sure that this command
    364  * is not neglected and that the reload server process will exit (gracefully).
    365  */
    366 void
    367 verify_handle_command(int fd, short event, void *arg)
    368 {
    369 	struct nsd *nsd = (struct nsd *)arg;
    370 	int len;
    371 	sig_atomic_t mode;
    372 
    373 	assert(nsd != NULL);
    374 	assert((event & (EV_READ
    375 #ifdef EV_CLOSED
    376 	| EV_CLOSED
    377 #endif
    378 	)));
    379 
    380 	if((len = read(fd, &mode, sizeof(mode))) == -1) {
    381 		log_msg(LOG_ERR, "verify: verify_handle_command: read: %s",
    382 		                 strerror(errno));
    383 		return;
    384 	} else if(len == 0) {
    385 		log_msg(LOG_INFO, "verify: command channel closed");
    386 		mode = NSD_QUIT;
    387 	} else if(mode != NSD_QUIT) {
    388 		log_msg(LOG_ERR, "verify: bad command: %d", (int)mode);
    389 		return;
    390 	}
    391 
    392 	nsd->mode = mode;
    393 
    394 	if(nsd->verifier_count == 0) {
    395 		event_base_loopexit(nsd->event_base, NULL);
    396 		return; /* exit early if no verifiers are executing */
    397 	}
    398 
    399 	/* kill verifiers, processes reaped elsewhere */
    400 	for(size_t i = 0; i < nsd->verifier_limit; i++) {
    401 		if(nsd->verifiers[i].zone != NULL) {
    402 			kill_verifier(&nsd->verifiers[i]);
    403 		}
    404 	}
    405 }
    406 
    407 /*
    408  * A verifier is executed for the specified zone (if a verifier is configured
    409  * and the zone has not been verified before). If one of the verifiers exits
    410  * with non-zero, the zone is marked bad and nsd drops the zone update and
    411  * reloads again.
    412  */
    413 void verify_zone(struct nsd *nsd, struct zone *zone)
    414 {
    415 	struct verifier *verifier = NULL;
    416 	int32_t timeout;
    417 	char **command;
    418 	FILE *fin;
    419 	int fdin, fderr, fdout, flags;
    420 
    421 	assert(nsd != NULL);
    422 	assert(nsd->verifier_count < nsd->verifier_limit);
    423 	assert(zone != NULL);
    424 
    425 	fin = NULL;
    426 	fdin = fdout = fderr = -1;
    427 
    428 	/* search for available verifier slot */
    429 	for(size_t i = 0; i < nsd->verifier_limit && !verifier; i++) {
    430 		if(nsd->verifiers[i].zone == NULL) {
    431 			verifier = &nsd->verifiers[i];
    432 		}
    433 	}
    434 
    435 	assert(verifier != NULL);
    436 
    437 	if(zone->opts->pattern->verifier != NULL) {
    438 		command = zone->opts->pattern->verifier;
    439 	} else if (nsd->options->verifier != NULL) {
    440 		command = nsd->options->verifier;
    441 	} else {
    442 		log_msg(LOG_ERR, "verify: no verifier for zone %s",
    443 		                 zone->opts->name);
    444 		return;
    445 	}
    446 
    447 	if(zone->opts->pattern->verifier_timeout
    448 		!= VERIFIER_TIMEOUT_INHERIT)
    449 	{
    450 		timeout = zone->opts->pattern->verifier_timeout;
    451 	} else {
    452 		timeout = nsd->options->verifier_timeout;
    453 	}
    454 
    455 	if(zone->opts->pattern->verifier_feed_zone
    456 		!= VERIFIER_FEED_ZONE_INHERIT)
    457 	{
    458 		fdin = zone->opts->pattern->verifier_feed_zone ? -2 : -1;
    459 	} else {
    460 		fdin = nsd->options->verifier_feed_zone ? -2 : -1;
    461 	}
    462 
    463 	assert(timeout >= 0);
    464 
    465 	setenv("VERIFY_ZONE", zone->opts->name, 1);
    466 	setenv("VERIFY_ZONE_ON_STDIN", fdin == -2 ? "yes" : "no", 1);
    467 
    468 	verifier->pid = popen3(
    469 		command, fdin == -2 ? &fdin : NULL, &fdout, &fderr);
    470 	if(verifier->pid == -1) {
    471 		log_msg(LOG_ERR, "verify: could not start verifier for zone "
    472 				 "%s: %s", zone->opts->name, strerror(errno));
    473 		goto fail_popen3;
    474 	}
    475 	flags = fcntl(fderr, F_GETFL, 0);
    476 	if (fcntl(fderr, F_SETFL, flags | O_NONBLOCK) == -1) {
    477 		log_msg(LOG_ERR, "verify: fcntl(stderr, ..., O_NONBLOCK) for "
    478 		                 "zone %s: %s",
    479 		                 zone->opts->name, strerror(errno));
    480 		goto fail_fcntl;
    481 	}
    482 	flags = fcntl(fdout, F_GETFL, 0);
    483 	if(fcntl(fdout, F_SETFL, flags | O_NONBLOCK) == -1) {
    484 		log_msg(LOG_ERR, "verify: fcntl(stdout, ..., O_NONBLOCK) for "
    485 		                 "zone %s: %s",
    486 		                 zone->opts->name, strerror(errno));
    487 		goto fail_fcntl;
    488 	}
    489 	if (fdin >= 0) {
    490 		if ((fin = fdopen(fdin, "w")) == NULL) {
    491 			log_msg(LOG_ERR, "verify: fdopen(stdin, ...) for "
    492 			                 "zone %s: %s",
    493 		                         zone->opts->name, strerror(errno));
    494 			goto fail_fcntl;
    495 		}
    496 		/* write unbuffered */
    497 		setbuf(fin, NULL);
    498 	}
    499 
    500 	verifier->zone = zone;
    501 	verifier->was_ok = zone->is_ok;
    502 
    503 	unsetenv("VERIFY_ZONE");
    504 	unsetenv("VERIFY_ZONE_ON_STDIN");
    505 
    506 	verifier->error_stream.fd = fderr;
    507 	verifier->error_stream.cnt = 0;
    508 	verifier->error_stream.off = 0;
    509 	verifier->error_stream.buf[0] = '\0';
    510 	event_set(&verifier->error_stream.event,
    511 	          verifier->error_stream.fd,
    512 	          EV_READ|EV_PERSIST,
    513 	          verify_handle_stream,
    514 		  verifier);
    515 	event_base_set(nsd->event_base, &verifier->error_stream.event);
    516 	if(event_add(&verifier->error_stream.event, NULL) != 0) {
    517 		log_msg(LOG_ERR, "verify: could not add error event for "
    518 		                 "zone %s", zone->opts->name);
    519 		goto fail_stderr;
    520 	}
    521 
    522 	verifier->output_stream.fd = fdout;
    523 	verifier->output_stream.cnt = 0;
    524 	verifier->output_stream.off = 0;
    525 	verifier->output_stream.buf[0] = '\0';
    526 	event_set(&verifier->output_stream.event,
    527 	          verifier->output_stream.fd,
    528 	          EV_READ|EV_PERSIST,
    529 	          verify_handle_stream,
    530 	          verifier);
    531 	event_base_set(nsd->event_base, &verifier->output_stream.event);
    532 	if(event_add(&verifier->output_stream.event, NULL) != 0) {
    533 		log_msg(LOG_ERR, "verify: could not add output event for "
    534 		                 "zone %s", zone->opts->name);
    535 		goto fail_stdout;
    536 	}
    537 
    538 	if(fin != NULL) {
    539 		verifier->zone_feed.fh = fin;
    540 
    541 		zone_rr_iter_init(&verifier->zone_feed.rriter, zone);
    542 
    543 		verifier->zone_feed.rrprinter
    544 			= create_pretty_rr(nsd->server_region);
    545 		verifier->zone_feed.region
    546 			= region_create(xalloc, free);
    547 		verifier->zone_feed.buffer
    548 			= buffer_create(nsd->server_region, MAX_RDLENGTH);
    549 
    550 		event_set(&verifier->zone_feed.event,
    551 		          fileno(verifier->zone_feed.fh),
    552 			  EV_WRITE|EV_PERSIST,
    553 			  &verify_handle_feed,
    554 			  verifier);
    555 		event_base_set(nsd->event_base, &verifier->zone_feed.event);
    556 		if(event_add(&verifier->zone_feed.event, NULL) != 0) {
    557 			log_msg(LOG_ERR, "verify: could not add input event "
    558 			                 "for zone %s", zone->opts->name);
    559 			goto fail_stdin;
    560 		}
    561 	}
    562 
    563 	if(timeout > 0) {
    564 		verifier->timeout.tv_sec = timeout;
    565 		verifier->timeout.tv_usec = 0;
    566 		event_set(&verifier->timeout_event,
    567 		          -1,
    568 		          EV_TIMEOUT,
    569 		          verify_handle_timeout,
    570 		          verifier);
    571 		event_base_set(nsd->event_base, &verifier->timeout_event);
    572 		if(event_add(&verifier->timeout_event, &verifier->timeout) != 0) {
    573 			log_msg(LOG_ERR, "verify: could not add timeout event "
    574 			                 "for zone %s", zone->opts->name);
    575 			goto fail_timeout;
    576 		}
    577 
    578 		log_msg(LOG_INFO, "verify: started verifier for zone %s "
    579 		                  "(pid %d), timeout is %d seconds",
    580 		                  zone->opts->name, verifier->pid, timeout);
    581 	} else {
    582 		log_msg(LOG_INFO, "verify: started verifier for zone %s "
    583 		                  "(pid %d)", zone->opts->name, verifier->pid);
    584 	}
    585 
    586 	zone->is_ok = 1;
    587 	nsd->verifier_count++;
    588 	return;
    589 
    590 fail_timeout:
    591 	verifier->timeout.tv_sec = 0;
    592 	verifier->timeout.tv_usec = 0;
    593 	if(fin != NULL) {
    594 		event_del(&verifier->zone_feed.event);
    595 	}
    596 fail_stdin:
    597 	verifier->zone_feed.fh = NULL;
    598 	event_del(&verifier->output_stream.event);
    599 fail_stdout:
    600 	verifier->output_stream.fd = -1;
    601 	event_del(&verifier->error_stream.event);
    602 fail_stderr:
    603 	verifier->error_stream.fd = -1;
    604 fail_fcntl:
    605 	kill_verifier(verifier);
    606 	if(fin != NULL) {
    607 		fclose(fin);
    608 	} else if (fdin >= 0) {
    609 		close(fdin);
    610 	}
    611 	close(fdout);
    612 	close(fderr);
    613 fail_popen3:
    614 	zone->is_bad = 1;
    615 	verifier->pid = -1;
    616 	verifier->zone = NULL;
    617 }
    618