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 68struct dt_msg { 69 void *buf; 70 size_t len_buf; 71 Dnstap__Dnstap d; 72 Dnstap__Message m; 73}; 74 75static int 76dt_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 97static void 98dt_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 109static void 110dt_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. */ 134struct 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 149void log_crypto_err(const char* str); /* in server.c */ 150 151/* Create TLS writer object for fstrm. */ 152static struct dt_tls_writer* 153tls_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 */ 257static void 258tls_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 */ 277static fstrm_res 278dt_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 */ 286static fstrm_res 287dt_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 x = SSL_get_peer_certificate(dtw->ssl); 408 if(!x) { 409 log_crypto_err("Server presented no peer certificate"); 410 return fstrm_res_failure; 411 } 412 X509_free(x); 413 414 return fstrm_res_success; 415} 416 417/* The fstrm writer close callback for TLS */ 418static fstrm_res 419dt_tls_writer_close(void* obj) 420{ 421 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 422 if(dtw->connected) { 423 dtw->connected = 0; 424 if(dtw->ssl) 425 SSL_shutdown(dtw->ssl); 426 SSL_free(dtw->ssl); 427 dtw->ssl = NULL; 428 if(dtw->fd != -1) { 429 close(dtw->fd); 430 dtw->fd = -1; 431 } 432 return fstrm_res_success; 433 } 434 return fstrm_res_failure; 435} 436 437/* The fstrm writer read callback for TLS */ 438static fstrm_res 439dt_tls_writer_read(void* obj, void* buf, size_t nbytes) 440{ 441 /* want to read nbytes of data */ 442 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 443 size_t nread = 0; 444 if(!dtw->connected) 445 return fstrm_res_failure; 446 while(nread < nbytes) { 447 int r; 448 ERR_clear_error(); 449 if((r = SSL_read(dtw->ssl, ((char*)buf)+nread, nbytes-nread)) <= 0) { 450 r = SSL_get_error(dtw->ssl, r); 451 if(r == SSL_ERROR_ZERO_RETURN) { 452 log_msg(LOG_ERR, "dnstap: EOF from %s", 453 dtw->ip); 454 return fstrm_res_failure; 455 } 456 if(r == SSL_ERROR_SYSCALL) { 457 log_msg(LOG_ERR, "dnstap: read %s: %s", 458 dtw->ip, strerror(errno)); 459 return fstrm_res_failure; 460 } 461 if(r == SSL_ERROR_SSL) { 462 log_crypto_err("dnstap: could not SSL_read"); 463 return fstrm_res_failure; 464 } 465 log_msg(LOG_ERR, "dnstap: SSL_read failed with err %d", 466 r); 467 return fstrm_res_failure; 468 } 469 nread += r; 470 } 471 return fstrm_res_success; 472} 473 474/* The fstrm writer write callback for TLS */ 475static fstrm_res 476dt_tls_writer_write(void* obj, const struct iovec* iov, int iovcnt) 477{ 478 struct dt_tls_writer* dtw = (struct dt_tls_writer*)obj; 479 int i; 480 if(!dtw->connected) 481 return fstrm_res_failure; 482 for(i=0; i<iovcnt; i++) { 483 if(SSL_write(dtw->ssl, iov[i].iov_base, (int)(iov[i].iov_len)) <= 0) { 484 log_crypto_err("dnstap: could not SSL_write"); 485 return fstrm_res_failure; 486 } 487 } 488 return fstrm_res_success; 489} 490 491/* Create the fstrm writer object for TLS */ 492static struct fstrm_writer* 493dt_tls_make_writer(struct fstrm_writer_options* fwopt, 494 struct dt_tls_writer* dtw) 495{ 496 struct fstrm_rdwr* rdwr = fstrm_rdwr_init(dtw); 497 fstrm_rdwr_set_destroy(rdwr, dt_tls_writer_destroy); 498 fstrm_rdwr_set_open(rdwr, dt_tls_writer_open); 499 fstrm_rdwr_set_close(rdwr, dt_tls_writer_close); 500 fstrm_rdwr_set_read(rdwr, dt_tls_writer_read); 501 fstrm_rdwr_set_write(rdwr, dt_tls_writer_write); 502 return fstrm_writer_init(fwopt, &rdwr); 503} 504#endif /* HAVE_SSL */ 505 506/* check that the socket file can be opened and exists, print error if not */ 507static void 508check_socket_file(const char* socket_path) 509{ 510 struct stat statbuf; 511 memset(&statbuf, 0, sizeof(statbuf)); 512 if(stat(socket_path, &statbuf) < 0) { 513 log_msg(LOG_WARNING, "could not open dnstap-socket-path: %s, %s", 514 socket_path, strerror(errno)); 515 } 516} 517 518struct dt_env * 519dt_create(const char *socket_path, char* ip, unsigned num_workers, 520 int tls, char* tls_server_name, char* tls_cert_bundle, 521 char* tls_client_key_file, char* tls_client_cert_file) 522{ 523#ifndef NDEBUG 524 fstrm_res res; 525#endif 526 struct dt_env *env; 527 struct fstrm_iothr_options *fopt; 528 struct fstrm_unix_writer_options *fuwopt = NULL; 529 struct fstrm_tcp_writer_options *ftwopt = NULL; 530 struct fstrm_writer *fw; 531 struct fstrm_writer_options *fwopt; 532 533 assert(num_workers > 0); 534 if(ip == NULL || ip[0] == 0) { 535 VERBOSITY(1, (LOG_INFO, "attempting to connect to dnstap socket %s", 536 socket_path)); 537 assert(socket_path != NULL); 538 check_socket_file(socket_path); 539 } else { 540 VERBOSITY(1, (LOG_INFO, "attempting to connect to dnstap %ssocket %s", 541 (tls?"tls ":""), ip)); 542 } 543 544 env = (struct dt_env *) calloc(1, sizeof(struct dt_env)); 545 if (!env) 546 return NULL; 547 548 fwopt = fstrm_writer_options_init(); 549#ifndef NDEBUG 550 res = 551#else 552 (void) 553#endif 554 fstrm_writer_options_add_content_type(fwopt, 555 DNSTAP_CONTENT_TYPE, sizeof(DNSTAP_CONTENT_TYPE) - 1); 556 assert(res == fstrm_res_success); 557 558 if(ip == NULL || ip[0] == 0) { 559 fuwopt = fstrm_unix_writer_options_init(); 560 fstrm_unix_writer_options_set_socket_path(fuwopt, socket_path); 561 } else { 562 char* at = strchr(ip, '@'); 563 if(!tls) { 564 ftwopt = fstrm_tcp_writer_options_init(); 565 if(at == NULL) { 566 fstrm_tcp_writer_options_set_socket_address(ftwopt, ip); 567 fstrm_tcp_writer_options_set_socket_port(ftwopt, "3333"); 568 } else { 569 *at = 0; 570 fstrm_tcp_writer_options_set_socket_address(ftwopt, ip); 571 fstrm_tcp_writer_options_set_socket_port(ftwopt, at+1); 572 *at = '@'; 573 } 574 } else { 575#ifdef HAVE_SSL 576 env->tls_writer = tls_writer_init(ip, tls_server_name, 577 tls_cert_bundle, tls_client_key_file, 578 tls_client_cert_file); 579#else 580 (void)tls_server_name; 581 (void)tls_cert_bundle; 582 (void)tls_client_key_file; 583 (void)tls_client_cert_file; 584 log_msg(LOG_ERR, "dnstap: tls enabled but compiled without ssl."); 585#endif 586 if(!env->tls_writer) { 587 log_msg(LOG_ERR, "dt_create: tls_writer_init() failed"); 588 fstrm_writer_options_destroy(&fwopt); 589 free(env); 590 return NULL; 591 } 592 } 593 } 594 if(ip == NULL || ip[0] == 0) 595 fw = fstrm_unix_writer_init(fuwopt, fwopt); 596 else if(!tls) 597 fw = fstrm_tcp_writer_init(ftwopt, fwopt); 598#ifdef HAVE_SSL 599 else 600 fw = dt_tls_make_writer(fwopt, env->tls_writer); 601#endif 602 assert(fw != NULL); 603 604 fopt = fstrm_iothr_options_init(); 605 fstrm_iothr_options_set_num_input_queues(fopt, num_workers); 606 env->iothr = fstrm_iothr_init(fopt, &fw); 607 if (env->iothr == NULL) { 608 log_msg(LOG_ERR, "dt_create: fstrm_iothr_init() failed"); 609 fstrm_writer_destroy(&fw); 610 free(env); 611 env = NULL; 612 } 613 fstrm_iothr_options_destroy(&fopt); 614 615 if(ip == NULL || ip[0] == 0) 616 fstrm_unix_writer_options_destroy(&fuwopt); 617 else if(!tls) 618 fstrm_tcp_writer_options_destroy(&ftwopt); 619 fstrm_writer_options_destroy(&fwopt); 620 621 return env; 622} 623 624static void 625dt_apply_identity(struct dt_env *env, struct nsd_options *cfg) 626{ 627 char buf[MAXHOSTNAMELEN+1]; 628 if (!cfg->dnstap_send_identity) 629 return; 630 free(env->identity); 631 if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) { 632 if (gethostname(buf, MAXHOSTNAMELEN) == 0) { 633 buf[MAXHOSTNAMELEN] = 0; 634 env->identity = strdup(buf); 635 } else { 636 error("dt_apply_identity: gethostname() failed"); 637 } 638 } else { 639 env->identity = strdup(cfg->dnstap_identity); 640 } 641 if (env->identity == NULL) 642 error("dt_apply_identity: strdup() failed"); 643 env->len_identity = (unsigned int)strlen(env->identity); 644 VERBOSITY(1, (LOG_INFO, "dnstap identity field set to \"%s\"", 645 env->identity)); 646} 647 648static void 649dt_apply_version(struct dt_env *env, struct nsd_options *cfg) 650{ 651 if (!cfg->dnstap_send_version) 652 return; 653 free(env->version); 654 if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0) 655 env->version = strdup(PACKAGE_STRING); 656 else 657 env->version = strdup(cfg->dnstap_version); 658 if (env->version == NULL) 659 error("dt_apply_version: strdup() failed"); 660 env->len_version = (unsigned int)strlen(env->version); 661 VERBOSITY(1, (LOG_INFO, "dnstap version field set to \"%s\"", 662 env->version)); 663} 664 665void 666dt_apply_cfg(struct dt_env *env, struct nsd_options *cfg) 667{ 668 if (!cfg->dnstap_enable) 669 return; 670 671 dt_apply_identity(env, cfg); 672 dt_apply_version(env, cfg); 673 if ((env->log_auth_query_messages = (unsigned int) 674 cfg->dnstap_log_auth_query_messages)) 675 { 676 VERBOSITY(1, (LOG_INFO, "dnstap Message/AUTH_QUERY enabled")); 677 } 678 if ((env->log_auth_response_messages = (unsigned int) 679 cfg->dnstap_log_auth_response_messages)) 680 { 681 VERBOSITY(1, (LOG_INFO, "dnstap Message/AUTH_RESPONSE enabled")); 682 } 683} 684 685int 686dt_init(struct dt_env *env) 687{ 688 env->ioq = fstrm_iothr_get_input_queue(env->iothr); 689 if (env->ioq == NULL) 690 return 0; 691 return 1; 692} 693 694void 695dt_delete(struct dt_env *env) 696{ 697 if (!env) 698 return; 699 VERBOSITY(1, (LOG_INFO, "closing dnstap socket")); 700 fstrm_iothr_destroy(&env->iothr); 701 free(env->identity); 702 free(env->version); 703 free(env); 704} 705 706static void 707dt_fill_timeval(const struct timeval *tv, 708 uint64_t *time_sec, protobuf_c_boolean *has_time_sec, 709 uint32_t *time_nsec, protobuf_c_boolean *has_time_nsec) 710{ 711#ifndef S_SPLINT_S 712 *time_sec = tv->tv_sec; 713 *time_nsec = tv->tv_usec * 1000; 714#endif 715 *has_time_sec = 1; 716 *has_time_nsec = 1; 717} 718 719static void 720dt_fill_buffer(uint8_t* pkt, size_t pktlen, ProtobufCBinaryData *p, protobuf_c_boolean *has) 721{ 722 p->len = pktlen; 723 p->data = pkt; 724 *has = 1; 725} 726 727static void 728dt_msg_fill_net(struct dt_msg *dm, 729#ifdef INET6 730 struct sockaddr_storage *rs, 731 struct sockaddr_storage *qs, 732#else 733 struct sockaddr_in *rs, 734 struct sockaddr_in *qs, 735#endif 736 int is_tcp, 737 ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr, 738 uint32_t *rport, protobuf_c_boolean *has_rport, 739 ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr, 740 uint32_t *qport, protobuf_c_boolean *has_qport) 741 742{ 743#ifdef INET6 744 assert(qs->ss_family == AF_INET6 || qs->ss_family == AF_INET); 745 if (qs->ss_family == AF_INET6) { 746 struct sockaddr_in6 *s = (struct sockaddr_in6 *) qs; 747 748 /* socket_family */ 749 dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET6; 750 dm->m.has_socket_family = 1; 751 752 /* addr: query_address or response_address */ 753 qaddr->data = s->sin6_addr.s6_addr; 754 qaddr->len = 16; /* IPv6 */ 755 *has_qaddr = 1; 756 757 /* port: query_port or response_port */ 758 *qport = ntohs(s->sin6_port); 759 *has_qport = 1; 760 } else if (qs->ss_family == AF_INET) { 761#else 762 if (qs->sin_family == AF_INET) { 763#endif /* INET6 */ 764 struct sockaddr_in *s = (struct sockaddr_in *) qs; 765 766 /* socket_family */ 767 dm->m.socket_family = DNSTAP__SOCKET_FAMILY__INET; 768 dm->m.has_socket_family = 1; 769 770 /* addr: query_address or response_address */ 771 qaddr->data = (uint8_t *) &s->sin_addr.s_addr; 772 qaddr->len = 4; /* IPv4 */ 773 *has_qaddr = 1; 774 775 /* port: query_port or response_port */ 776 *qport = ntohs(s->sin_port); 777 *has_qport = 1; 778 } 779 780#ifdef INET6 781 assert(rs->ss_family == AF_INET6 || rs->ss_family == AF_INET); 782 if (rs->ss_family == AF_INET6) { 783 struct sockaddr_in6 *s = (struct sockaddr_in6 *) rs; 784 785 /* addr: query_address or response_address */ 786 raddr->data = s->sin6_addr.s6_addr; 787 raddr->len = 16; /* IPv6 */ 788 *has_raddr = 1; 789 790 /* port: query_port or response_port */ 791 *rport = ntohs(s->sin6_port); 792 *has_rport = 1; 793 } else if (rs->ss_family == AF_INET) { 794#else 795 if (rs->sin_family == AF_INET) { 796#endif /* INET6 */ 797 struct sockaddr_in *s = (struct sockaddr_in *) rs; 798 799 /* addr: query_address or response_address */ 800 raddr->data = (uint8_t *) &s->sin_addr.s_addr; 801 raddr->len = 4; /* IPv4 */ 802 *has_raddr = 1; 803 804 /* port: query_port or response_port */ 805 *rport = ntohs(s->sin_port); 806 *has_rport = 1; 807 } 808 809 810 if (!is_tcp) { 811 /* socket_protocol */ 812 dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP; 813 dm->m.has_socket_protocol = 1; 814 } else { 815 /* socket_protocol */ 816 dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP; 817 dm->m.has_socket_protocol = 1; 818 } 819} 820 821void 822dt_msg_send_auth_query(struct dt_env *env, 823#ifdef INET6 824 struct sockaddr_storage* local_addr, 825 struct sockaddr_storage* addr, 826#else 827 struct sockaddr_in* local_addr, 828 struct sockaddr_in* addr, 829#endif 830 int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen) 831{ 832 struct dt_msg dm; 833 struct timeval qtime; 834 835 gettimeofday(&qtime, NULL); 836 837 /* type */ 838 dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__AUTH_QUERY); 839 840 if(zone) { 841 /* query_zone */ 842 dm.m.query_zone.data = zone; 843 dm.m.query_zone.len = zonelen; 844 dm.m.has_query_zone = 1; 845 } 846 847 /* query_time */ 848 dt_fill_timeval(&qtime, 849 &dm.m.query_time_sec, &dm.m.has_query_time_sec, 850 &dm.m.query_time_nsec, &dm.m.has_query_time_nsec); 851 852 /* query_message */ 853 dt_fill_buffer(pkt, pktlen, &dm.m.query_message, &dm.m.has_query_message); 854 855 /* socket_family, socket_protocol, query_address, query_port, reponse_address (local_address), response_port (local_port) */ 856 dt_msg_fill_net(&dm, local_addr, addr, is_tcp, 857 &dm.m.response_address, &dm.m.has_response_address, 858 &dm.m.response_port, &dm.m.has_response_port, 859 &dm.m.query_address, &dm.m.has_query_address, 860 &dm.m.query_port, &dm.m.has_query_port); 861 862 863 if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) 864 dt_send(env, dm.buf, dm.len_buf); 865} 866 867void 868dt_msg_send_auth_response(struct dt_env *env, 869#ifdef INET6 870 struct sockaddr_storage* local_addr, 871 struct sockaddr_storage* addr, 872#else 873 struct sockaddr_in* local_addr, 874 struct sockaddr_in* addr, 875#endif 876 int is_tcp, uint8_t* zone, size_t zonelen, uint8_t* pkt, size_t pktlen) 877{ 878 struct dt_msg dm; 879 struct timeval rtime; 880 881 gettimeofday(&rtime, NULL); 882 883 /* type */ 884 dt_msg_init(env, &dm, DNSTAP__MESSAGE__TYPE__AUTH_RESPONSE); 885 886 if(zone) { 887 /* query_zone */ 888 dm.m.query_zone.data = zone; 889 dm.m.query_zone.len = zonelen; 890 dm.m.has_query_zone = 1; 891 } 892 893 /* response_time */ 894 dt_fill_timeval(&rtime, 895 &dm.m.response_time_sec, &dm.m.has_response_time_sec, 896 &dm.m.response_time_nsec, &dm.m.has_response_time_nsec); 897 898 /* response_message */ 899 dt_fill_buffer(pkt, pktlen, &dm.m.response_message, &dm.m.has_response_message); 900 901 /* socket_family, socket_protocol, query_address, query_port, response_address (local_address), response_port (local_port) */ 902 dt_msg_fill_net(&dm, local_addr, addr, is_tcp, 903 &dm.m.response_address, &dm.m.has_response_address, 904 &dm.m.response_port, &dm.m.has_response_port, 905 &dm.m.query_address, &dm.m.has_query_address, 906 &dm.m.query_port, &dm.m.has_query_port); 907 908 if (dt_pack(&dm.d, &dm.buf, &dm.len_buf)) 909 dt_send(env, dm.buf, dm.len_buf); 910} 911 912#endif /* USE_DNSTAP */ 913