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