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 ? ".. %.*s .." : "%.*s .."; 116 len = LOGLINELEN; // remainder printed next iteration 117 stream->cut = 1; 118 } else { 119 fmt = stream->cut ? ".. %.*s" : "%.*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 (void)write(nsd->verifier_pipe[1], buf, sizeof(buf)); 278 } 279 280 /* 281 * Reap process and update status of respective zone based on the exit code 282 * of a verifier. Everything from STDOUT and STDERR still available is read and 283 * written to the log as it might contain valuable information. 284 * 285 * NOTE: A timeout might have caused the verifier to be terminated. 286 */ 287 void verify_handle_exit(int fd, short event, void *arg) 288 { 289 int wstatus; 290 pid_t pid; 291 struct nsd *nsd; 292 char buf[1]; 293 294 assert(event & EV_READ); 295 assert(arg != NULL); 296 297 nsd = (struct nsd *)arg; 298 299 if(read(fd, buf, sizeof(buf)) == -1) { 300 if(errno != EAGAIN && errno != EINTR && errno != EWOULDBLOCK) 301 log_msg(LOG_ERR, "verify_handle_exit: read failed: %s", 302 strerror(errno)); 303 } 304 305 while(((pid = waitpid(-1, &wstatus, WNOHANG)) == -1 && errno == EINTR) 306 || (pid > 0)) 307 { 308 struct verifier *verifier = NULL; 309 310 for(size_t i = 0; !verifier && i < nsd->verifier_limit; i++) { 311 if(nsd->verifiers[i].zone != NULL && 312 nsd->verifiers[i].pid == pid) 313 { 314 verifier = &nsd->verifiers[i]; 315 } 316 } 317 318 if(verifier == NULL) { 319 continue; 320 } 321 322 if(!WIFEXITED(wstatus)) { 323 log_msg(LOG_ERR, "verify: verifier for zone %s " 324 "(pid %d) exited abnormally", 325 verifier->zone->opts->name, pid); 326 } else { 327 int priority = LOG_INFO; 328 int status = WEXITSTATUS(wstatus); 329 if(status != 0) { 330 priority = LOG_ERR; 331 verifier->zone->is_bad = 1; 332 } 333 log_msg(priority, "verify: verifier for zone %s " 334 "(pid %d) exited with %d", 335 verifier->zone->opts->name, pid, status); 336 } 337 338 close_verifier(verifier); 339 nsd->verifier_count--; 340 } 341 342 while(nsd->mode == NSD_RUN && 343 nsd->verifier_count < nsd->verifier_limit && 344 nsd->next_zone_to_verify != NULL) 345 { 346 verify_zone(nsd, nsd->next_zone_to_verify); 347 nsd->next_zone_to_verify 348 = verify_next_zone(nsd, nsd->next_zone_to_verify); 349 } 350 351 if(nsd->next_zone_to_verify == NULL && nsd->verifier_count == 0) { 352 event_base_loopexit(nsd->event_base, NULL); 353 return; 354 } 355 } 356 357 /* 358 * A parent may be terminated (by the NSD_QUIT signal (nsdc stop command)). 359 * When a reload server process is running, the parent will then send a 360 * NSD_QUIT command to that server. This handler makes sure that this command 361 * is not neglected and that the reload server process will exit (gracefully). 362 */ 363 void 364 verify_handle_command(int fd, short event, void *arg) 365 { 366 struct nsd *nsd = (struct nsd *)arg; 367 int len; 368 sig_atomic_t mode; 369 370 assert(nsd != NULL); 371 assert(event & (EV_READ 372 #ifdef EV_CLOSED 373 | EV_CLOSED 374 #endif 375 )); 376 377 if((len = read(fd, &mode, sizeof(mode))) == -1) { 378 log_msg(LOG_ERR, "verify: verify_handle_command: read: %s", 379 strerror(errno)); 380 return; 381 } else if(len == 0) { 382 log_msg(LOG_INFO, "verify: command channel closed"); 383 mode = NSD_QUIT; 384 } else if(mode != NSD_QUIT) { 385 log_msg(LOG_ERR, "verify: bad command: %d", (int)mode); 386 return; 387 } 388 389 nsd->mode = mode; 390 391 if(nsd->verifier_count == 0) { 392 event_base_loopexit(nsd->event_base, NULL); 393 return; /* exit early if no verifiers are executing */ 394 } 395 396 /* kill verifiers, processes reaped elsewhere */ 397 for(size_t i = 0; i < nsd->verifier_limit; i++) { 398 if(nsd->verifiers[i].zone != NULL) { 399 kill_verifier(&nsd->verifiers[i]); 400 } 401 } 402 } 403 404 /* 405 * A verifier is executed for the specified zone (if a verifier is configured 406 * and the zone has not been verified before). If one of the verifiers exits 407 * with non-zero, the zone is marked bad and nsd drops the zone update and 408 * reloads again. 409 */ 410 void verify_zone(struct nsd *nsd, struct zone *zone) 411 { 412 struct verifier *verifier = NULL; 413 int32_t timeout; 414 char **command; 415 FILE *fin; 416 int fdin, fderr, fdout, flags; 417 418 assert(nsd != NULL); 419 assert(nsd->verifier_count < nsd->verifier_limit); 420 assert(zone != NULL); 421 422 fin = NULL; 423 fdin = fdout = fderr = -1; 424 425 /* search for available verifier slot */ 426 for(size_t i = 0; i < nsd->verifier_limit && !verifier; i++) { 427 if(nsd->verifiers[i].zone == NULL) { 428 verifier = &nsd->verifiers[i]; 429 } 430 } 431 432 assert(verifier != NULL); 433 434 if(zone->opts->pattern->verifier != NULL) { 435 command = zone->opts->pattern->verifier; 436 } else if (nsd->options->verifier != NULL) { 437 command = nsd->options->verifier; 438 } else { 439 log_msg(LOG_ERR, "verify: no verifier for zone %s", 440 zone->opts->name); 441 return; 442 } 443 444 if(zone->opts->pattern->verifier_timeout 445 != VERIFIER_TIMEOUT_INHERIT) 446 { 447 timeout = zone->opts->pattern->verifier_timeout; 448 } else { 449 timeout = nsd->options->verifier_timeout; 450 } 451 452 if(zone->opts->pattern->verifier_feed_zone 453 != VERIFIER_FEED_ZONE_INHERIT) 454 { 455 fdin = zone->opts->pattern->verifier_feed_zone ? -2 : -1; 456 } else { 457 fdin = nsd->options->verifier_feed_zone ? -2 : -1; 458 } 459 460 assert(timeout >= 0); 461 462 setenv("VERIFY_ZONE", zone->opts->name, 1); 463 setenv("VERIFY_ZONE_ON_STDIN", fdin == -2 ? "yes" : "no", 1); 464 465 verifier->pid = popen3( 466 command, fdin == -2 ? &fdin : NULL, &fdout, &fderr); 467 if(verifier->pid == -1) { 468 log_msg(LOG_ERR, "verify: could not start verifier for zone " 469 "%s: %s", zone->opts->name, strerror(errno)); 470 goto fail_popen3; 471 } 472 flags = fcntl(fderr, F_GETFL, 0); 473 if (fcntl(fderr, F_SETFL, flags | O_NONBLOCK) == -1) { 474 log_msg(LOG_ERR, "verify: fcntl(stderr, ..., O_NONBLOCK) for " 475 "zone %s: %s", 476 zone->opts->name, strerror(errno)); 477 goto fail_fcntl; 478 } 479 flags = fcntl(fdout, F_GETFL, 0); 480 if(fcntl(fdout, F_SETFL, flags | O_NONBLOCK) == -1) { 481 log_msg(LOG_ERR, "verify: fcntl(stdout, ..., O_NONBLOCK) for " 482 "zone %s: %s", 483 zone->opts->name, strerror(errno)); 484 goto fail_fcntl; 485 } 486 if (fdin >= 0) { 487 if ((fin = fdopen(fdin, "w")) == NULL) { 488 log_msg(LOG_ERR, "verify: fdopen(stdin, ...) for " 489 "zone %s: %s", 490 zone->opts->name, strerror(errno)); 491 goto fail_fcntl; 492 } 493 /* write unbuffered */ 494 setbuf(fin, NULL); 495 } 496 497 verifier->zone = zone; 498 verifier->was_ok = zone->is_ok; 499 500 unsetenv("VERIFY_ZONE"); 501 unsetenv("VERIFY_ZONE_ON_STDIN"); 502 503 verifier->error_stream.fd = fderr; 504 verifier->error_stream.cnt = 0; 505 verifier->error_stream.off = 0; 506 verifier->error_stream.buf[0] = '\0'; 507 event_set(&verifier->error_stream.event, 508 verifier->error_stream.fd, 509 EV_READ|EV_PERSIST, 510 verify_handle_stream, 511 verifier); 512 event_base_set(nsd->event_base, &verifier->error_stream.event); 513 if(event_add(&verifier->error_stream.event, NULL) != 0) { 514 log_msg(LOG_ERR, "verify: could not add error event for " 515 "zone %s", zone->opts->name); 516 goto fail_stderr; 517 } 518 519 verifier->output_stream.fd = fdout; 520 verifier->output_stream.cnt = 0; 521 verifier->output_stream.off = 0; 522 verifier->output_stream.buf[0] = '\0'; 523 event_set(&verifier->output_stream.event, 524 verifier->output_stream.fd, 525 EV_READ|EV_PERSIST, 526 verify_handle_stream, 527 verifier); 528 event_base_set(nsd->event_base, &verifier->output_stream.event); 529 if(event_add(&verifier->output_stream.event, NULL) != 0) { 530 log_msg(LOG_ERR, "verify: could not add output event for " 531 "zone %s", zone->opts->name); 532 goto fail_stdout; 533 } 534 535 if(fin != NULL) { 536 verifier->zone_feed.fh = fin; 537 538 zone_rr_iter_init(&verifier->zone_feed.rriter, zone); 539 540 verifier->zone_feed.rrprinter 541 = create_pretty_rr(nsd->server_region); 542 verifier->zone_feed.region 543 = region_create(xalloc, free); 544 verifier->zone_feed.buffer 545 = buffer_create(nsd->server_region, MAX_RDLENGTH); 546 547 event_set(&verifier->zone_feed.event, 548 fileno(verifier->zone_feed.fh), 549 EV_WRITE|EV_PERSIST, 550 &verify_handle_feed, 551 verifier); 552 event_base_set(nsd->event_base, &verifier->zone_feed.event); 553 if(event_add(&verifier->zone_feed.event, NULL) != 0) { 554 log_msg(LOG_ERR, "verify: could not add input event " 555 "for zone %s", zone->opts->name); 556 goto fail_stdin; 557 } 558 } 559 560 if(timeout > 0) { 561 verifier->timeout.tv_sec = timeout; 562 verifier->timeout.tv_usec = 0; 563 event_set(&verifier->timeout_event, 564 -1, 565 EV_TIMEOUT, 566 verify_handle_timeout, 567 verifier); 568 event_base_set(nsd->event_base, &verifier->timeout_event); 569 if(event_add(&verifier->timeout_event, &verifier->timeout) != 0) { 570 log_msg(LOG_ERR, "verify: could not add timeout event " 571 "for zone %s", zone->opts->name); 572 goto fail_timeout; 573 } 574 575 log_msg(LOG_INFO, "verify: started verifier for zone %s " 576 "(pid %d), timeout is %d seconds", 577 zone->opts->name, verifier->pid, timeout); 578 } else { 579 log_msg(LOG_INFO, "verify: started verifier for zone %s " 580 "(pid %d)", zone->opts->name, verifier->pid); 581 } 582 583 zone->is_ok = 1; 584 nsd->verifier_count++; 585 return; 586 587 fail_timeout: 588 verifier->timeout.tv_sec = 0; 589 verifier->timeout.tv_usec = 0; 590 if(fin != NULL) { 591 event_del(&verifier->zone_feed.event); 592 } 593 fail_stdin: 594 verifier->zone_feed.fh = NULL; 595 event_del(&verifier->output_stream.event); 596 fail_stdout: 597 verifier->output_stream.fd = -1; 598 event_del(&verifier->error_stream.event); 599 fail_stderr: 600 verifier->error_stream.fd = -1; 601 fail_fcntl: 602 kill_verifier(verifier); 603 if(fin != NULL) { 604 fclose(fin); 605 } else if (fdin >= 0) { 606 close(fdin); 607 } 608 close(fdout); 609 close(fderr); 610 fail_popen3: 611 zone->is_bad = 1; 612 verifier->pid = -1; 613 verifier->zone = NULL; 614 } 615