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