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
34struct 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
60static 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
89static 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 */
133static 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
167static 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
181static 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
193static 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 */
220static 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 */
249void 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
267void 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 */
290void 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 */
366void
367verify_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 */
413void 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
590fail_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	}
596fail_stdin:
597	verifier->zone_feed.fh = NULL;
598	event_del(&verifier->output_stream.event);
599fail_stdout:
600	verifier->output_stream.fd = -1;
601	event_del(&verifier->error_stream.event);
602fail_stderr:
603	verifier->error_stream.fd = -1;
604fail_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);
613fail_popen3:
614	zone->is_bad = 1;
615	verifier->pid = -1;
616	verifier->zone = NULL;
617}
618