1 /* dnstap support for NSD */ 2 3 /* 4 * Copyright (c) 2013-2014, Farsight Security, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * 3. Neither the name of the copyright holder nor the names of its 19 * contributors may be used to endorse or promote products derived from 20 * this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 26 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include "dnstap/dnstap_config.h" 36 37 #ifdef USE_DNSTAP 38 39 #include "config.h" 40 #include <string.h> 41 #include <sys/time.h> 42 #ifdef HAVE_SYS_STAT_H 43 #include <sys/stat.h> 44 #endif 45 #include <errno.h> 46 #include <unistd.h> 47 #include "util.h" 48 #include "options.h" 49 50 #include <fstrm.h> 51 #include <protobuf-c/protobuf-c.h> 52 53 #include "dnstap/dnstap.h" 54 #include "dnstap/dnstap.pb-c.h" 55 56 #ifdef HAVE_SSL 57 #ifdef HAVE_OPENSSL_SSL_H 58 #include <openssl/ssl.h> 59 #endif 60 #ifdef HAVE_OPENSSL_ERR_H 61 #include <openssl/err.h> 62 #endif 63 #endif 64 65 #define DNSTAP_CONTENT_TYPE "protobuf:dnstap.Dnstap" 66 #define DNSTAP_INITIAL_BUF_SIZE 256 67 68 struct dt_msg { 69 void *buf; 70 size_t len_buf; 71 Dnstap__Dnstap d; 72 Dnstap__Message m; 73 }; 74 75 static int 76 dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz) 77 { 78 ProtobufCBufferSimple sbuf; 79 80 memset(&sbuf, 0, sizeof(sbuf)); 81 sbuf.base.append = protobuf_c_buffer_simple_append; 82 sbuf.len = 0; 83 sbuf.alloced = DNSTAP_INITIAL_BUF_SIZE; 84 sbuf.data = malloc(sbuf.alloced); 85 if (sbuf.data == NULL) 86 return 0; 87 sbuf.must_free_data = 1; 88 89 *sz = dnstap__dnstap__pack_to_buffer(d, (ProtobufCBuffer *) &sbuf); 90 if (sbuf.data == NULL) 91 return 0; 92 *buf = sbuf.data; 93 94 return 1; 95 } 96 97 static void 98 dt_send(const struct dt_env *env, void *buf, size_t len_buf) 99 { 100 fstrm_res res; 101 if (!buf) 102 return; 103 res = fstrm_iothr_submit(env->iothr, env->ioq, buf, len_buf, 104 fstrm_free_wrapper, NULL); 105 if (res != fstrm_res_success) 106 free(buf); 107 } 108 109 static void 110 dt_msg_init(const struct dt_env *env, 111 struct dt_msg *dm, 112 Dnstap__Message__Type mtype) 113 { 114 memset(dm, 0, sizeof(*dm)); 115 dm->d.base.descriptor = &dnstap__dnstap__descriptor; 116 dm->m.base.descriptor = &dnstap__message__descriptor; 117 dm->d.type = DNSTAP__DNSTAP__TYPE__MESSAGE; 118 dm->d.message = &dm->m; 119 dm->m.type = mtype; 120 if (env->identity != NULL) { 121 dm->d.identity.data = (uint8_t *) env->identity; 122 dm->d.identity.len = (size_t) env->len_identity; 123 dm->d.has_identity = 1; 124 } 125 if (env->version != NULL) { 126 dm->d.version.data = (uint8_t *) env->version; 127 dm->d.version.len = (size_t) env->len_version; 128 dm->d.has_version = 1; 129 } 130 } 131 132 #ifdef HAVE_SSL 133 /** TLS writer object for fstrm. */ 134 struct dt_tls_writer { 135 /* ip address */ 136 char* ip; 137 /* if connected already */ 138 int connected; 139 /* file descriptor */ 140 int fd; 141 /* TLS context */ 142 SSL_CTX* ctx; 143 /* SSL transport */ 144 SSL* ssl; 145 /* the server name to authenticate */ 146 char* tls_server_name; 147 }; 148 149 void log_crypto_err(const char* str); /* in server.c */ 150 151 /* Create TLS writer object for fstrm. */ 152 static struct dt_tls_writer* 153 tls_writer_init(char* ip, char* tls_server_name, char* tls_cert_bundle, 154 char* tls_client_key_file, char* tls_client_cert_file) 155 { 156 struct dt_tls_writer* dtw = (struct dt_tls_writer*)calloc(1, 157 sizeof(*dtw)); 158 if(!dtw) return NULL; 159 dtw->fd = -1; 160 dtw->ip = strdup(ip); 161 if(!dtw->ip) { 162 free(dtw); 163 return NULL; 164 } 165 dtw->ctx = SSL_CTX_new(SSLv23_client_method()); 166 if(!dtw->ctx) { 167 log_msg(LOG_ERR, "dnstap: SSL_CTX_new failed"); 168 free(dtw->ip); 169 free(dtw); 170 return NULL; 171 } 172 #if SSL_OP_NO_SSLv2 != 0 173 if((SSL_CTX_set_options(dtw->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) 174 != SSL_OP_NO_SSLv2) { 175 log_msg(LOG_ERR, "dnstap: could not set SSL_OP_NO_SSLv2"); 176 SSL_CTX_free(dtw->ctx); 177 free(dtw->ip); 178 free(dtw); 179 return NULL; 180 } 181 #endif 182 if((SSL_CTX_set_options(dtw->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3) 183 != SSL_OP_NO_SSLv3) { 184 log_msg(LOG_ERR, "dnstap: could not set SSL_OP_NO_SSLv3"); 185 SSL_CTX_free(dtw->ctx); 186 free(dtw->ip); 187 free(dtw); 188 return NULL; 189 } 190 #if defined(SSL_OP_NO_RENEGOTIATION) 191 /* disable client renegotiation */ 192 if((SSL_CTX_set_options(dtw->ctx, SSL_OP_NO_RENEGOTIATION) & 193 SSL_OP_NO_RENEGOTIATION) != SSL_OP_NO_RENEGOTIATION) { 194 log_msg(LOG_ERR, "dnstap: could not set SSL_OP_NO_RENEGOTIATION"); 195 SSL_CTX_free(dtw->ctx); 196 free(dtw->ip); 197 free(dtw); 198 return NULL; 199 } 200 #endif 201 if(tls_client_key_file && tls_client_key_file[0]) { 202 if(!SSL_CTX_use_certificate_chain_file(dtw->ctx, 203 tls_client_cert_file)) { 204 log_msg(LOG_ERR, "dnstap: SSL_CTX_use_certificate_chain_file failed for %s", tls_client_cert_file); 205 SSL_CTX_free(dtw->ctx); 206 free(dtw->ip); 207 free(dtw); 208 return NULL; 209 } 210 if(!SSL_CTX_use_PrivateKey_file(dtw->ctx, tls_client_key_file, 211 SSL_FILETYPE_PEM)) { 212 log_msg(LOG_ERR, "dnstap: SSL_CTX_use_PrivateKey_file failed for %s", tls_client_key_file); 213 SSL_CTX_free(dtw->ctx); 214 free(dtw->ip); 215 free(dtw); 216 return NULL; 217 } 218 if(!SSL_CTX_check_private_key(dtw->ctx)) { 219 log_msg(LOG_ERR, "dnstap: SSL_CTX_check_private_key failed for %s", tls_client_key_file); 220 SSL_CTX_free(dtw->ctx); 221 free(dtw->ip); 222 free(dtw); 223 return NULL; 224 } 225 } 226 if(tls_cert_bundle && tls_cert_bundle[0]) { 227 if(!SSL_CTX_load_verify_locations(dtw->ctx, tls_cert_bundle, NULL)) { 228 log_msg(LOG_ERR, "dnstap: SSL_CTX_load_verify_locations failed for %s", tls_cert_bundle); 229 SSL_CTX_free(dtw->ctx); 230 free(dtw->ip); 231 free(dtw); 232 return NULL; 233 } 234 if(SSL_CTX_set_default_verify_paths(dtw->ctx) != 1) { 235 log_msg(LOG_ERR, "dnstap: SSL_CTX_set_default_verify_paths failed"); 236 SSL_CTX_free(dtw->ctx); 237 free(dtw->ip); 238 free(dtw); 239 return NULL; 240 } 241 SSL_CTX_set_verify(dtw->ctx, SSL_VERIFY_PEER, NULL); 242 } 243 if(tls_server_name) { 244 dtw->tls_server_name = strdup(tls_server_name); 245 if(!dtw->tls_server_name) { 246 log_msg(LOG_ERR, "dnstap: strdup failed"); 247 SSL_CTX_free(dtw->ctx); 248 free(dtw->ip); 249 free(dtw); 250 return NULL; 251 } 252 } 253 return dtw; 254 } 255 256 /* Delete TLS writer object */ 257 static void 258 tls_writer_delete(struct dt_tls_writer* dtw) 259 { 260 if(!dtw) 261 return; 262 if(dtw->ssl) 263 SSL_shutdown(dtw->ssl); 264 SSL_free(dtw->ssl); 265 dtw->ssl = NULL; 266 SSL_CTX_free(dtw->ctx); 267 if(dtw->fd != -1) { 268 close(dtw->fd); 269 dtw->fd = -1; 270 } 271 free(dtw->ip); 272 free(dtw->tls_server_name); 273 free(dtw); 274 } 275 276 /* The fstrm writer destroy callback for TLS */ 277 static fstrm_res 278 dt_tls_writer_destroy(void* obj) 279 { 280 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 281 tls_writer_delete(dtw); 282 return fstrm_res_success; 283 } 284 285 /* The fstrm writer open callback for TLS */ 286 static fstrm_res 287 dt_tls_writer_open(void* obj) 288 { 289 struct sockaddr_storage addr; 290 socklen_t addrlen; 291 char* svr, *at = NULL; 292 int port = 3333; 293 int addrfamily; 294 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 295 X509* x; 296 297 /* skip action if already connected */ 298 if(dtw->connected) 299 return fstrm_res_success; 300 301 /* figure out port number */ 302 svr = dtw->ip; 303 at = strchr(svr, '@'); 304 if(at != NULL) { 305 *at = 0; 306 port = atoi(at+1); 307 } 308 309 /* parse addr */ 310 memset(&addr, 0, sizeof(addr)); 311 #ifdef INET6 312 if(strchr(svr, ':')) { 313 struct sockaddr_in6 sa; 314 addrlen = (socklen_t)sizeof(struct sockaddr_in6); 315 memset(&sa, 0, addrlen); 316 sa.sin6_family = AF_INET6; 317 sa.sin6_port = (in_port_t)htons((uint16_t)port); 318 if(inet_pton((int)sa.sin6_family, svr, &sa.sin6_addr) <= 0) { 319 log_msg(LOG_ERR, "dnstap: could not parse IP: %s", svr); 320 if(at != NULL) 321 *at = '@'; 322 return fstrm_res_failure; 323 } 324 memcpy(&addr, &sa, addrlen); 325 addrfamily = AF_INET6; 326 } else 327 #else 328 if(1) 329 #endif 330 { 331 struct sockaddr_in sa; 332 addrlen = (socklen_t)sizeof(struct sockaddr_in); 333 memset(&sa, 0, addrlen); 334 sa.sin_family = AF_INET; 335 sa.sin_port = (in_port_t)htons((uint16_t)port); 336 if(inet_pton((int)sa.sin_family, svr, &sa.sin_addr) <= 0) { 337 log_msg(LOG_ERR, "dnstap: could not parse IP: %s", svr); 338 if(at != NULL) 339 *at = '@'; 340 return fstrm_res_failure; 341 } 342 memcpy(&addr, &sa, addrlen); 343 addrfamily = AF_INET; 344 } 345 if(at != NULL) 346 *at = '@'; 347 348 /* open socket */ 349 dtw->fd = socket(addrfamily, SOCK_STREAM, 0); 350 if(dtw->fd == -1) { 351 log_msg(LOG_ERR, "dnstap: socket failed: %s", strerror(errno)); 352 return fstrm_res_failure; 353 } 354 if(connect(dtw->fd, (struct sockaddr*)&addr, addrlen) < 0) { 355 log_msg(LOG_ERR, "dnstap: connect failed: %s", strerror(errno)); 356 return fstrm_res_failure; 357 } 358 dtw->connected = 1; 359 360 /* setup SSL */ 361 dtw->ssl = SSL_new(dtw->ctx); 362 if(!dtw->ssl) { 363 log_msg(LOG_ERR, "dnstap: SSL_new failed"); 364 return fstrm_res_failure; 365 } 366 SSL_set_connect_state(dtw->ssl); 367 (void)SSL_set_mode(dtw->ssl, SSL_MODE_AUTO_RETRY); 368 if(!SSL_set_fd(dtw->ssl, dtw->fd)) { 369 log_msg(LOG_ERR, "dnstap: SSL_set_fd failed"); 370 return fstrm_res_failure; 371 } 372 if(dtw->tls_server_name && dtw->tls_server_name[0]) { 373 if(!SSL_set1_host(dtw->ssl, dtw->tls_server_name)) { 374 log_msg(LOG_ERR, "dnstap: TLS setting of hostname %s failed to %s", 375 dtw->tls_server_name, dtw->ip); 376 return fstrm_res_failure; 377 } 378 } 379 380 /* handshake */ 381 while(1) { 382 int r; 383 ERR_clear_error(); 384 if( (r=SSL_do_handshake(dtw->ssl)) == 1) 385 break; 386 r = SSL_get_error(dtw->ssl, r); 387 if(r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE) { 388 if(r == SSL_ERROR_ZERO_RETURN) { 389 log_msg(LOG_ERR, "dnstap: EOF on SSL_do_handshake"); 390 return fstrm_res_failure; 391 } 392 if(r == SSL_ERROR_SYSCALL) { 393 log_msg(LOG_ERR, "dnstap: SSL_do_handshake failed: %s", strerror(errno)); 394 return fstrm_res_failure; 395 } 396 log_crypto_err("dnstap: SSL_do_handshake failed"); 397 return fstrm_res_failure; 398 } 399 /* wants to be called again */ 400 } 401 402 /* check authenticity of server */ 403 if(SSL_get_verify_result(dtw->ssl) != X509_V_OK) { 404 log_crypto_err("SSL verification failed"); 405 return fstrm_res_failure; 406 } 407 #ifdef HAVE_SSL_GET1_PEER_CERTIFICATE 408 x = SSL_get1_peer_certificate(dtw->ssl); 409 #else 410 x = SSL_get_peer_certificate(dtw->ssl); 411 #endif 412 if(!x) { 413 log_crypto_err("Server presented no peer certificate"); 414 return fstrm_res_failure; 415 } 416 X509_free(x); 417 418 return fstrm_res_success; 419 } 420 421 /* The fstrm writer close callback for TLS */ 422 static fstrm_res 423 dt_tls_writer_close(void* obj) 424 { 425 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 426 if(dtw->connected) { 427 dtw->connected = 0; 428 if(dtw->ssl) 429 SSL_shutdown(dtw->ssl); 430 SSL_free(dtw->ssl); 431 dtw->ssl = NULL; 432 if(dtw->fd != -1) { 433 close(dtw->fd); 434 dtw->fd = -1; 435 } 436 return fstrm_res_success; 437 } 438 return fstrm_res_failure; 439 } 440 441 /* The fstrm writer read callback for TLS */ 442 static fstrm_res 443 dt_tls_writer_read(void* obj, void* buf, size_t nbytes) 444 { 445 /* want to read nbytes of data */ 446 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 447 size_t nread = 0; 448 if(!dtw->connected) 449 return fstrm_res_failure; 450 while(nread < nbytes) { 451 int r; 452 ERR_clear_error(); 453 if((r = SSL_read(dtw->ssl, ((char*)buf)+nread, nbytes-nread)) <= 0) { 454 r = SSL_get_error(dtw->ssl, r); 455 if(r == SSL_ERROR_ZERO_RETURN) { 456 log_msg(LOG_ERR, "dnstap: EOF from %s", 457 dtw->ip); 458 return fstrm_res_failure; 459 } 460 if(r == SSL_ERROR_SYSCALL) { 461 log_msg(LOG_ERR, "dnstap: read %s: %s", 462 dtw->ip, strerror(errno)); 463 return fstrm_res_failure; 464 } 465 if(r == SSL_ERROR_SSL) { 466 log_crypto_err("dnstap: could not SSL_read"); 467 return fstrm_res_failure; 468 } 469 log_msg(LOG_ERR, "dnstap: SSL_read failed with err %d", 470 r); 471 return fstrm_res_failure; 472 } 473 nread += r; 474 } 475 return fstrm_res_success; 476 } 477 478 /* The fstrm writer write callback for TLS */ 479 static fstrm_res 480 dt_tls_writer_write(void* obj, const struct iovec* iov, int iovcnt) 481 { 482 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 483 int i; 484 if(!dtw->connected) 485 return fstrm_res_failure; 486 for(i=0; i<iovcnt; i++) { 487 if(SSL_write(dtw->ssl, iov[i].iov_base, (int)(iov[i].iov_len)) <= 0) { 488 log_crypto_err("dnstap: could not SSL_write"); 489 return fstrm_res_failure; 490 } 491 } 492 return fstrm_res_success; 493 } 494 495 /* Create the fstrm writer object for TLS */ 496 static struct fstrm_writer* 497 dt_tls_make_writer(struct fstrm_writer_options* fwopt, 498 struct dt_tls_writer* dtw) 499 { 500 struct fstrm_rdwr* rdwr = fstrm_rdwr_init(dtw); 501 fstrm_rdwr_set_destroy(rdwr, dt_tls_writer_destroy); 502 fstrm_rdwr_set_open(rdwr, dt_tls_writer_open); 503 fstrm_rdwr_set_close(rdwr, dt_tls_writer_close); 504 fstrm_rdwr_set_read(rdwr, dt_tls_writer_read); 505 fstrm_rdwr_set_write(rdwr, dt_tls_writer_write); 506 return fstrm_writer_init(fwopt, &rdwr); 507 } 508 #endif /* HAVE_SSL */ 509 510 /* check that the socket file can be opened and exists, print error if not */ 511 static void 512 check_socket_file(const char* socket_path) 513 { 514 struct stat statbuf; 515 memset(&statbuf, 0, sizeof(statbuf)); 516 if(stat(socket_path, &statbuf) < 0) { 517 log_msg(LOG_WARNING, "could not open dnstap-socket-path: %s, %s", 518 socket_path, strerror(errno)); 519 } 520 } 521 522 struct dt_env * 523 dt_create(const char *socket_path, char* ip, unsigned num_workers, 524 int tls, char* tls_server_name, char* tls_cert_bundle, 525 char* tls_client_key_file, char* tls_client_cert_file) 526 { 527 #ifndef NDEBUG 528 fstrm_res res; 529 #endif 530 struct dt_env *env; 531 struct fstrm_iothr_options *fopt; 532 struct fstrm_unix_writer_options *fuwopt = NULL; 533 struct fstrm_tcp_writer_options *ftwopt = NULL; 534 struct fstrm_writer *fw; 535 struct fstrm_writer_options *fwopt; 536 537 assert(num_workers > 0); 538 if(ip == NULL || ip[0] == 0) { 539 VERBOSITY(1, (LOG_INFO, "attempting to connect to dnstap socket %s", 540 socket_path)); 541 assert(socket_path != NULL); 542 check_socket_file(socket_path); 543 } else { 544 VERBOSITY(1, (LOG_INFO, "attempting to connect to dnstap %ssocket %s", 545 (tls?"tls ":""), ip)); 546 } 547 548 env = (struct dt_env *) calloc(1, sizeof(struct dt_env)); 549 if (!env) 550 return NULL; 551 552 fwopt = fstrm_writer_options_init(); 553 #ifndef NDEBUG 554 res = 555 #else 556 (void) 557 #endif 558 fstrm_writer_options_add_content_type(fwopt, 559 DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1); 560 assert(res == fstrm_res_success); 561 562 if(ip == NULL || ip[0] == 0) { 563 fuwopt = fstrm_unix_writer_options_init(); 564 fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path); 565 } else { 566 char* at = strchr(ip, '@'); 567 if(!tls) { 568 ftwopt = fstrm_tcp_writer_options_init(); 569 if(at == NULL) { 570 fstrm_tcp_writer_options_set_socket_address(ftwopt, ip); 571 fstrm_tcp_writer_options_set_socket_port(ftwopt, "3333"); 572 } else { 573 *at = 0; 574 fstrm_tcp_writer_options_set_socket_address(ftwopt, ip); 575 fstrm_tcp_writer_options_set_socket_port(ftwopt, at+1); 576 *at = '@'; 577 } 578 } else { 579 #ifdef HAVE_SSL 580 env->tls_writer = tls_writer_init(ip, tls_server_name, 581 tls_cert_bundle, tls_client_key_file, 582 tls_client_cert_file); 583 #else 584 (void)tls_server_name; 585 (void)tls_cert_bundle; 586 (void)tls_client_key_file; 587 (void)tls_client_cert_file; 588 log_msg(LOG_ERR, "dnstap: tls enabled but compiled without ssl."); 589 #endif 590 if(!env->tls_writer) { 591 log_msg(LOG_ERR, "dt_create: tls_writer_init() failed"); 592 fstrm_writer_options_destroy(&fwopt); 593 free(env); 594 return NULL; 595 } 596 } 597 } 598 if(ip == NULL || ip[0] == 0) 599 fw = fstrm_unix_writer_init(fuwopt, fwopt); 600 else if(!tls) 601 fw = fstrm_tcp_writer_init(ftwopt, fwopt); 602 #ifdef HAVE_SSL 603 else 604 fw = dt_tls_make_writer(fwopt, env->tls_writer); 605 #endif 606 assert(fw != NULL); 607 608 fopt = fstrm_iothr_options_init(); 609 fstrm_iothr_options_set_num_input_queues(fopt, num_workers); 610 env->iothr = fstrm_iothr_init(fopt, &fw); 611 if (env->iothr == NULL) { 612 log_msg(LOG_ERR, "dt_create: fstrm_iothr_init() failed"); 613 fstrm_writer_destroy(&fw); 614 free(env); 615 env = NULL; 616 } 617 fstrm_iothr_options_destroy(&fopt); 618 619 if(ip == NULL || ip[0] == 0) 620 fstrm_unix_writer_options_destroy(&fuwopt); 621 else if(!tls) 622 fstrm_tcp_writer_options_destroy(&ftwopt); 623 fstrm_writer_options_destroy(&fwopt); 624 625 return env; 626 } 627 628 static void 629 dt_apply_identity(struct dt_env *env, struct nsd_options *cfg) 630 { 631 char buf[MAXHOSTNAMELEN+1]; 632 if (!cfg->dnstap_send_identity) 633 return; 634 free(env->identity); 635 if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) { 636 if (gethostname(buf, MAXHOSTNAMELEN) == 0) { 637 buf[MAXHOSTNAMELEN] = 0; 638 env->identity = strdup(buf); 639 } else { 640 error("dt_apply_identity: gethostname() failed"); 641 } 642 } else { 643 env->identity = strdup(cfg->dnstap_identity); 644 } 645 if (env->identity == NULL) 646 error("dt_apply_identity: strdup() failed"); 647 env->len_identity = (unsigned int)strlen(env->identity); 648 VERBOSITY(1, (LOG_INFO, "dnstap identity field set to \"%s\"", 649 env->identity)); 650 } 651 652 static void 653 dt_apply_version(struct dt_env *env, struct nsd_options *cfg) 654 { 655 if (!cfg->dnstap_send_version) 656 return; 657 free(env->version); 658 if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0) 659 env->version = strdup(PACKAGE_STRING); 660 else 661 env->version = strdup(cfg->dnstap_version); 662 if (env->version == NULL) 663 error("dt_apply_version: strdup() failed"); 664 env->len_version = (unsigned int)strlen(env->version); 665 VERBOSITY(1, (LOG_INFO, "dnstap version field set to \"%s\"", 666 env->version)); 667 } 668 669 void 670 dt_apply_cfg(struct dt_env *env, struct nsd_options *cfg) 671 { 672 if (!cfg->dnstap_enable) 673 return; 674 675 dt_apply_identity(env, cfg); 676 dt_apply_version(env, cfg); 677 if ((env->log_auth_query_messages = (unsigned int) 678 cfg->dnstap_log_auth_query_messages)) 679 { 680 VERBOSITY(1, (LOG_INFO, "dnstap Message/AUTH_QUERY enabled")); 681 } 682 if ((env->log_auth_response_messages = (unsigned int) 683 cfg->dnstap_log_auth_response_messages)) 684 { 685 VERBOSITY(1, (LOG_INFO, "dnstap Message/AUTH_RESPONSE enabled")); 686 } 687 } 688 689 int 690 dt_init(struct dt_env *env) 691 { 692 env->ioq = fstrm_iothr_get_input_queue(env->iothr); 693 if (env->ioq == NULL) 694 return 0; 695 return 1; 696 } 697 698 void 699 dt_delete(struct dt_env *env) 700 { 701 if (!env) 702 return; 703 VERBOSITY(1, (LOG_INFO, "closing dnstap socket")); 704 fstrm_iothr_destroy(&env->iothr); 705 free(env->identity); 706 free(env->version); 707 free(env); 708 } 709 710 static void 711 dt_fill_timeval(const struct timeval *tv, 712 uint64_t *time_sec, protobuf_c_boolean *has_time_sec, 713 uint32_t *time_nsec, protobuf_c_boolean *has_time_nsec) 714 { 715 #ifndef S_SPLINT_S 716 *time_sec = tv->tv_sec; 717 *time_nsec = tv->tv_usec * 1000; 718 #endif 719 *has_time_sec = 1; 720 *has_time_nsec = 1; 721 } 722 723 static void 724 dt_fill_buffer(uint8_t* pkt, size_t pktlen, ProtobufCBinaryData *p, protobuf_c_boolean *has) 725 { 726 p->len = pktlen; 727 p->data = pkt; 728 *has = 1; 729 } 730 731 static void 732 dt_msg_fill_net(struct dt_msg *dm, 733 #ifdef INET6 734 struct sockaddr_storage *rs, 735 struct sockaddr_storage *qs, 736 #else 737 struct sockaddr_in *rs, 738 struct sockaddr_in *qs, 739 #endif 740 int is_tcp, 741 ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr, 742 uint32_t *rport, protobuf_c_boolean *has_rport, 743 ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr, 744 uint32_t *qport, protobuf_c_boolean *has_qport) 745 746 { 747 #ifdef INET6 748 assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET); 749 if (qs->ss_family == AF_INET6) { 750 struct sockaddr_in6 *s = (struct sockaddr_in6 *) qs; 751 752 /* socket_family */ 753 dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6; 754 dm->m.has_socket_family = 1; 755 756 /* addr: query_address or response_address */ 757 qaddr->data = s->sin6_addr.s6_addr; 758 qaddr->len = 16; /* IPv6 */ 759 *has_qaddr = 1; 760 761 /* port: query_port or response_port */ 762 *qport = ntohs(s->sin6_port); 763 *has_qport = 1; 764 } else if (qs->ss_family == AF_INET) { 765 #else 766 if (qs->sin_family == AF_INET) { 767 #endif /* INET6 */ 768 struct sockaddr_in *s = (struct sockaddr_in *) qs; 769 770 /* socket_family */ 771 dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET; 772 dm->m.has_socket_family = 1; 773 774 /* addr: query_address or response_address */ 775 qaddr->data = (uint8_t *) &s->sin_addr.s_addr; 776 qaddr->len = 4; /* IPv4 */ 777 *has_qaddr = 1; 778 779 /* port: query_port or response_port */ 780 *qport = ntohs(s->sin_port); 781 *has_qport = 1; 782 } 783 784 #ifdef INET6 785 assert(rs->ss_family == AF_INET6 || rs->ss_family == AF_INET); 786 if (rs->ss_family == AF_INET6) { 787 struct sockaddr_in6 *s = (struct sockaddr_in6 *) rs; 788 789 /* addr: query_address or response_address */ 790 raddr->data = s->sin6_addr.s6_addr; 791 raddr->len = 16; /* IPv6 */ 792 *has_raddr = 1; 793 794 /* port: query_port or response_port */ 795 *rport = ntohs(s->sin6_port); 796 *has_rport = 1; 797 } else if (rs->ss_family == AF_INET) { 798 #else 799 if (rs->sin_family == AF_INET) { 800 #endif /* INET6 */ 801 struct sockaddr_in *s = (struct sockaddr_in *) rs; 802 803 /* addr: query_address or response_address */ 804 raddr->data = (uint8_t *) &s->sin_addr.s_addr; 805 raddr->len = 4; /* IPv4 */ 806 *has_raddr = 1; 807 808 /* port: query_port or response_port */ 809 *rport = ntohs(s->sin_port); 810 *has_rport = 1; 811 } 812 813 814 if (!is_tcp) { 815 /* socket_protocol */ 816 dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP; 817 dm->m.has_socket_protocol = 1; 818 } else { 819 /* socket_protocol */ 820 dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP; 821 dm->m.has_socket_protocol = 1; 822 } 823 } 824 825 void 826 dt_msg_send_auth_query(struct dt_env *env, 827 #ifdef INET6 828 struct sockaddr_storage* local_addr, 829 struct sockaddr_storage* addr, 830 #else 831 struct sockaddr_in* local_addr, 832 struct sockaddr_in* addr, 833 #endif 834 int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen) 835 { 836 struct dt_msg dm; 837 struct timeval qtime; 838 839 gettimeofday(&qtime, NULL); 840 841 /* type */ 842 dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__AUTH_QUERY); 843 844 if(zone) { 845 /* query_zone */ 846 dm.m.query_zone.data = zone; 847 dm.m.query_zone.len = zonelen; 848 dm.m.has_query_zone = 1; 849 } 850 851 /* query_time */ 852 dt_fill_timeval(&qtime, 853 &dm.m.query_time_sec, &dm.m.has_query_time_sec, 854 &dm.m.query_time_nsec, &dm.m.has_query_time_nsec); 855 856 /* query_message */ 857 dt_fill_buffer(pkt, pktlen, &dm.m.query_message, &dm.m.has_query_message); 858 859 /* socket_family, socket_protocol, query_address, query_port, reponse_address (local_address), response_port (local_port) */ 860 dt_msg_fill_net(&dm, local_addr, addr, is_tcp, 861 &dm.m.response_address, &dm.m.has_response_address, 862 &dm.m.response_port, &dm.m.has_response_port, 863 &dm.m.query_address, &dm.m.has_query_address, 864 &dm.m.query_port, &dm.m.has_query_port); 865 866 867 if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) 868 dt_send(env, dm.buf, dm.len_buf); 869 } 870 871 void 872 dt_msg_send_auth_response(struct dt_env *env, 873 #ifdef INET6 874 struct sockaddr_storage* local_addr, 875 struct sockaddr_storage* addr, 876 #else 877 struct sockaddr_in* local_addr, 878 struct sockaddr_in* addr, 879 #endif 880 int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen) 881 { 882 struct dt_msg dm; 883 struct timeval rtime; 884 885 gettimeofday(&rtime, NULL); 886 887 /* type */ 888 dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE); 889 890 if(zone) { 891 /* query_zone */ 892 dm.m.query_zone.data = zone; 893 dm.m.query_zone.len = zonelen; 894 dm.m.has_query_zone = 1; 895 } 896 897 /* response_time */ 898 dt_fill_timeval(&rtime, 899 &dm.m.response_time_sec, &dm.m.has_response_time_sec, 900 &dm.m.response_time_nsec, &dm.m.has_response_time_nsec); 901 902 /* response_message */ 903 dt_fill_buffer(pkt, pktlen, &dm.m.response_message, &dm.m.has_response_message); 904 905 /* socket_family, socket_protocol, query_address, query_port, response_address (local_address), response_port (local_port) */ 906 dt_msg_fill_net(&dm, local_addr, addr, is_tcp, 907 &dm.m.response_address, &dm.m.has_response_address, 908 &dm.m.response_port, &dm.m.has_response_port, 909 &dm.m.query_address, &dm.m.has_query_address, 910 &dm.m.query_port, &dm.m.has_query_port); 911 912 if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) 913 dt_send(env, dm.buf, dm.len_buf); 914 } 915 916 #endif /* USE_DNSTAP */ 917