1238106Sdes/* 2238106Sdes * checkconf/unbound-host.c - replacement for host that supports validation. 3238106Sdes * 4238106Sdes * Copyright (c) 2007, NLnet Labs. All rights reserved. 5238106Sdes * 6238106Sdes * This software is open source. 7238106Sdes * 8238106Sdes * Redistribution and use in source and binary forms, with or without 9238106Sdes * modification, are permitted provided that the following conditions 10238106Sdes * are met: 11238106Sdes * 12238106Sdes * Redistributions of source code must retain the above copyright notice, 13238106Sdes * this list of conditions and the following disclaimer. 14238106Sdes * 15238106Sdes * Redistributions in binary form must reproduce the above copyright notice, 16238106Sdes * this list of conditions and the following disclaimer in the documentation 17238106Sdes * and/or other materials provided with the distribution. 18238106Sdes * 19238106Sdes * Neither the name of the NLNET LABS nor the names of its contributors may 20238106Sdes * be used to endorse or promote products derived from this software without 21238106Sdes * specific prior written permission. 22238106Sdes * 23238106Sdes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24266114Sdes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25266114Sdes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26266114Sdes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27266114Sdes * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28266114Sdes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29266114Sdes * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30266114Sdes * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31266114Sdes * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32266114Sdes * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33266114Sdes * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34238106Sdes */ 35238106Sdes 36238106Sdes/** 37238106Sdes * \file 38238106Sdes * 39238106Sdes * This file performs functionality like 'host', and also supports validation. 40238106Sdes * It uses the libunbound library. 41238106Sdes */ 42238106Sdes 43238106Sdes#include "config.h" 44238106Sdes#ifdef HAVE_GETOPT_H 45238106Sdes#include <getopt.h> 46238106Sdes#endif 47238106Sdes/* remove alloc checks, not in this part of the code */ 48238106Sdes#ifdef UNBOUND_ALLOC_STATS 49238106Sdes#undef malloc 50238106Sdes#undef calloc 51238106Sdes#undef free 52238106Sdes#undef realloc 53238106Sdes#endif 54238106Sdes#ifdef UNBOUND_ALLOC_LITE 55238106Sdes#undef malloc 56238106Sdes#undef calloc 57238106Sdes#undef free 58238106Sdes#undef realloc 59238106Sdes#undef strdup 60238106Sdes#define unbound_lite_wrapstr(s) s 61238106Sdes#endif 62238106Sdes#include "libunbound/unbound.h" 63287917Sdes#include "sldns/rrdef.h" 64287917Sdes#include "sldns/wire2str.h" 65249141Sdes#ifdef HAVE_NSS 66249141Sdes/* nss3 */ 67249141Sdes#include "nss.h" 68249141Sdes#endif 69356345Scy#ifdef HAVE_SSL 70356345Scy#ifdef HAVE_OPENSSL_SSL_H 71356345Scy#include <openssl/ssl.h> 72356345Scy#endif 73356345Scy#ifdef HAVE_OPENSSL_ERR_H 74356345Scy#include <openssl/err.h> 75356345Scy#endif 76356345Scy#endif /* HAVE_SSL */ 77238106Sdes 78238106Sdes/** verbosity for unbound-host app */ 79238106Sdesstatic int verb = 0; 80238106Sdes 81238106Sdes/** Give unbound-host usage, and exit (1). */ 82238106Sdesstatic void 83307729Sdesusage(void) 84238106Sdes{ 85356345Scy printf("Usage: unbound-host [-C configfile] [-vdhr46] [-c class] [-t type]\n"); 86356345Scy printf(" [-y key] [-f keyfile] [-F namedkeyfile] hostname\n"); 87238106Sdes printf(" Queries the DNS for information.\n"); 88238106Sdes printf(" The hostname is looked up for IP4, IP6 and mail.\n"); 89238106Sdes printf(" If an ip-address is given a reverse lookup is done.\n"); 90238106Sdes printf(" Use the -v option to see DNSSEC security information.\n"); 91238106Sdes printf(" -t type what type to look for.\n"); 92238106Sdes printf(" -c class what class to look for, if not class IN.\n"); 93238106Sdes printf(" -y 'keystring' specify trust anchor, DS or DNSKEY, like\n"); 94238106Sdes printf(" -y 'example.com DS 31560 5 1 1CFED8478...'\n"); 95276605Sdes printf(" -D DNSSEC enable with default root anchor\n"); 96276605Sdes printf(" from %s\n", ROOT_ANCHOR_FILE); 97238106Sdes printf(" -f keyfile read trust anchors from file, with lines as -y.\n"); 98238106Sdes printf(" -F keyfile read named.conf-style trust anchors.\n"); 99238106Sdes printf(" -C config use the specified unbound.conf (none read by default)\n"); 100356345Scy printf(" pass as first argument if you want to override some\n"); 101356345Scy printf(" options with further arguments\n"); 102238106Sdes printf(" -r read forwarder information from /etc/resolv.conf\n"); 103307729Sdes printf(" breaks validation if the forwarder does not do DNSSEC.\n"); 104238106Sdes printf(" -v be more verbose, shows nodata and security.\n"); 105238106Sdes printf(" -d debug, traces the action, -d -d shows more.\n"); 106238106Sdes printf(" -4 use ipv4 network, avoid ipv6.\n"); 107238106Sdes printf(" -6 use ipv6 network, avoid ipv4.\n"); 108238106Sdes printf(" -h show this usage help.\n"); 109238106Sdes printf("Version %s\n", PACKAGE_VERSION); 110238106Sdes printf("BSD licensed, see LICENSE in source package for details.\n"); 111238106Sdes printf("Report bugs to %s\n", PACKAGE_BUGREPORT); 112238106Sdes exit(1); 113238106Sdes} 114238106Sdes 115238106Sdes/** determine if str is ip4 and put into reverse lookup format */ 116238106Sdesstatic int 117238106Sdesisip4(const char* nm, char** res) 118238106Sdes{ 119238106Sdes struct in_addr addr; 120238106Sdes /* ddd.ddd.ddd.ddd.in-addr.arpa. is less than 32 */ 121238106Sdes char buf[32]; 122238106Sdes if(inet_pton(AF_INET, nm, &addr) <= 0) { 123238106Sdes return 0; 124238106Sdes } 125238106Sdes snprintf(buf, sizeof(buf), "%u.%u.%u.%u.in-addr.arpa", 126238106Sdes (unsigned)((uint8_t*)&addr)[3], (unsigned)((uint8_t*)&addr)[2], 127238106Sdes (unsigned)((uint8_t*)&addr)[1], (unsigned)((uint8_t*)&addr)[0]); 128238106Sdes *res = strdup(buf); 129238106Sdes return 1; 130238106Sdes} 131238106Sdes 132238106Sdes/** determine if str is ip6 and put into reverse lookup format */ 133238106Sdesstatic int 134238106Sdesisip6(const char* nm, char** res) 135238106Sdes{ 136238106Sdes struct in6_addr addr; 137238106Sdes /* [nibble.]{32}.ip6.arpa. is less than 128 */ 138238106Sdes const char* hex = "0123456789abcdef"; 139238106Sdes char buf[128]; 140238106Sdes char *p; 141238106Sdes int i; 142238106Sdes if(inet_pton(AF_INET6, nm, &addr) <= 0) { 143238106Sdes return 0; 144238106Sdes } 145238106Sdes p = buf; 146238106Sdes for(i=15; i>=0; i--) { 147238106Sdes uint8_t b = ((uint8_t*)&addr)[i]; 148238106Sdes *p++ = hex[ (b&0x0f) ]; 149238106Sdes *p++ = '.'; 150238106Sdes *p++ = hex[ (b&0xf0) >> 4 ]; 151238106Sdes *p++ = '.'; 152238106Sdes } 153238106Sdes snprintf(buf+16*4, sizeof(buf)-16*4, "ip6.arpa"); 154238106Sdes *res = strdup(buf); 155238106Sdes if(!*res) { 156238106Sdes fprintf(stderr, "error: out of memory\n"); 157238106Sdes exit(1); 158238106Sdes } 159238106Sdes return 1; 160238106Sdes} 161238106Sdes 162238106Sdes/** massage input name */ 163238106Sdesstatic char* 164238106Sdesmassage_qname(const char* nm, int* reverse) 165238106Sdes{ 166238106Sdes /* recognise IP4 and IP6, create reverse addresses if needed */ 167238106Sdes char* res; 168238106Sdes if(isip4(nm, &res)) { 169238106Sdes *reverse = 1; 170238106Sdes } else if(isip6(nm, &res)) { 171238106Sdes *reverse = 1; 172238106Sdes } else { 173238106Sdes res = strdup(nm); 174238106Sdes } 175238106Sdes if(!res) { 176238106Sdes fprintf(stderr, "error: out of memory\n"); 177238106Sdes exit(1); 178238106Sdes } 179238106Sdes return res; 180238106Sdes} 181238106Sdes 182238106Sdes/** massage input type */ 183238106Sdesstatic int 184238106Sdesmassage_type(const char* t, int reverse, int* multi) 185238106Sdes{ 186238106Sdes if(t) { 187266114Sdes int r = sldns_get_rr_type_by_name(t); 188238106Sdes if(r == 0 && strcasecmp(t, "TYPE0") != 0 && 189238106Sdes strcmp(t, "") != 0) { 190238106Sdes fprintf(stderr, "error unknown type %s\n", t); 191238106Sdes exit(1); 192238106Sdes } 193238106Sdes return r; 194238106Sdes } 195238106Sdes if(!t && reverse) 196238106Sdes return LDNS_RR_TYPE_PTR; 197238106Sdes *multi = 1; 198238106Sdes return LDNS_RR_TYPE_A; 199238106Sdes} 200238106Sdes 201238106Sdes/** massage input class */ 202238106Sdesstatic int 203238106Sdesmassage_class(const char* c) 204238106Sdes{ 205238106Sdes if(c) { 206266114Sdes int r = sldns_get_rr_class_by_name(c); 207238106Sdes if(r == 0 && strcasecmp(c, "CLASS0") != 0 && 208238106Sdes strcmp(c, "") != 0) { 209238106Sdes fprintf(stderr, "error unknown class %s\n", c); 210238106Sdes exit(1); 211238106Sdes } 212238106Sdes return r; 213238106Sdes } 214238106Sdes return LDNS_RR_CLASS_IN; 215238106Sdes} 216238106Sdes 217238106Sdes/** nice security status string */ 218238106Sdesstatic const char* 219238106Sdessecure_str(struct ub_result* result) 220238106Sdes{ 221356345Scy if(result->rcode != 0 && result->rcode != 3) return "(error)"; 222238106Sdes if(result->secure) return "(secure)"; 223238106Sdes if(result->bogus) return "(BOGUS (security failure))"; 224238106Sdes return "(insecure)"; 225238106Sdes} 226238106Sdes 227238106Sdes/** nice string for type */ 228238106Sdesstatic void 229238106Sdespretty_type(char* s, size_t len, int t) 230238106Sdes{ 231266114Sdes char d[16]; 232266114Sdes sldns_wire2str_type_buf((uint16_t)t, d, sizeof(d)); 233238106Sdes snprintf(s, len, "%s", d); 234238106Sdes} 235238106Sdes 236238106Sdes/** nice string for class */ 237238106Sdesstatic void 238238106Sdespretty_class(char* s, size_t len, int c) 239238106Sdes{ 240266114Sdes char d[16]; 241266114Sdes sldns_wire2str_class_buf((uint16_t)c, d, sizeof(d)); 242238106Sdes snprintf(s, len, "%s", d); 243238106Sdes} 244238106Sdes 245238106Sdes/** nice string for rcode */ 246238106Sdesstatic void 247238106Sdespretty_rcode(char* s, size_t len, int r) 248238106Sdes{ 249266114Sdes char d[16]; 250266114Sdes sldns_wire2str_rcode_buf(r, d, sizeof(d)); 251266114Sdes snprintf(s, len, "%s", d); 252238106Sdes} 253238106Sdes 254238106Sdes/** convert and print rdata */ 255238106Sdesstatic void 256238106Sdesprint_rd(int t, char* data, size_t len) 257238106Sdes{ 258266114Sdes char s[65535]; 259266114Sdes sldns_wire2str_rdata_buf((uint8_t*)data, len, s, sizeof(s), (uint16_t)t); 260266114Sdes printf(" %s", s); 261238106Sdes} 262238106Sdes 263238106Sdes/** pretty line of RR data for results */ 264238106Sdesstatic void 265238106Sdespretty_rdata(char* q, char* cstr, char* tstr, int t, const char* sec, 266238106Sdes char* data, size_t len) 267238106Sdes{ 268238106Sdes printf("%s", q); 269238106Sdes if(strcmp(cstr, "IN") != 0) 270238106Sdes printf(" in class %s", cstr); 271238106Sdes if(t == LDNS_RR_TYPE_A) 272238106Sdes printf(" has address"); 273238106Sdes else if(t == LDNS_RR_TYPE_AAAA) 274238106Sdes printf(" has IPv6 address"); 275238106Sdes else if(t == LDNS_RR_TYPE_MX) 276238106Sdes printf(" mail is handled by"); 277238106Sdes else if(t == LDNS_RR_TYPE_PTR) 278238106Sdes printf(" domain name pointer"); 279238106Sdes else printf(" has %s record", tstr); 280238106Sdes print_rd(t, data, len); 281238106Sdes if(verb > 0) 282238106Sdes printf(" %s", sec); 283238106Sdes printf("\n"); 284238106Sdes} 285238106Sdes 286238106Sdes/** pretty line of output for results */ 287238106Sdesstatic void 288238106Sdespretty_output(char* q, int t, int c, struct ub_result* result, int docname) 289238106Sdes{ 290238106Sdes int i; 291238106Sdes const char *secstatus = secure_str(result); 292238106Sdes char tstr[16]; 293238106Sdes char cstr[16]; 294238106Sdes char rcodestr[16]; 295238106Sdes pretty_type(tstr, 16, t); 296238106Sdes pretty_class(cstr, 16, c); 297238106Sdes pretty_rcode(rcodestr, 16, result->rcode); 298238106Sdes 299238106Sdes if(!result->havedata && result->rcode) { 300238106Sdes printf("Host %s not found: %d(%s).", 301238106Sdes q, result->rcode, rcodestr); 302238106Sdes if(verb > 0) 303238106Sdes printf(" %s", secstatus); 304238106Sdes printf("\n"); 305238106Sdes if(result->bogus && result->why_bogus) 306238106Sdes printf("%s\n", result->why_bogus); 307238106Sdes return; 308238106Sdes } 309238106Sdes if(docname && result->canonname && 310238106Sdes result->canonname != result->qname) { 311238106Sdes printf("%s is an alias for %s", result->qname, 312238106Sdes result->canonname); 313238106Sdes if(verb > 0) 314238106Sdes printf(" %s", secstatus); 315238106Sdes printf("\n"); 316238106Sdes } 317238106Sdes /* remove trailing . from long canonnames for nicer output */ 318238106Sdes if(result->canonname && strlen(result->canonname) > 1 && 319238106Sdes result->canonname[strlen(result->canonname)-1] == '.') 320238106Sdes result->canonname[strlen(result->canonname)-1] = 0; 321238106Sdes if(!result->havedata) { 322238106Sdes if(verb > 0) { 323238106Sdes printf("%s", result->canonname?result->canonname:q); 324238106Sdes if(strcmp(cstr, "IN") != 0) 325238106Sdes printf(" in class %s", cstr); 326238106Sdes if(t == LDNS_RR_TYPE_A) 327238106Sdes printf(" has no address"); 328238106Sdes else if(t == LDNS_RR_TYPE_AAAA) 329238106Sdes printf(" has no IPv6 address"); 330238106Sdes else if(t == LDNS_RR_TYPE_PTR) 331238106Sdes printf(" has no domain name ptr"); 332238106Sdes else if(t == LDNS_RR_TYPE_MX) 333238106Sdes printf(" has no mail handler record"); 334238106Sdes else if(t == LDNS_RR_TYPE_ANY) { 335266114Sdes char* s = sldns_wire2str_pkt( 336266114Sdes result->answer_packet, 337266114Sdes (size_t)result->answer_len); 338266114Sdes if(!s) { 339266114Sdes fprintf(stderr, "alloc failure\n"); 340238106Sdes exit(1); 341238106Sdes } 342266114Sdes printf("%s\n", s); 343356345Scy free(s); 344238106Sdes } else printf(" has no %s record", tstr); 345238106Sdes printf(" %s\n", secstatus); 346238106Sdes } 347238106Sdes /* else: emptiness to indicate no data */ 348238106Sdes if(result->bogus && result->why_bogus) 349238106Sdes printf("%s\n", result->why_bogus); 350238106Sdes return; 351238106Sdes } 352238106Sdes i=0; 353238106Sdes while(result->data[i]) 354238106Sdes { 355238106Sdes pretty_rdata( 356238106Sdes result->canonname?result->canonname:q, 357238106Sdes cstr, tstr, t, secstatus, result->data[i], 358238106Sdes (size_t)result->len[i]); 359238106Sdes i++; 360238106Sdes } 361238106Sdes if(result->bogus && result->why_bogus) 362238106Sdes printf("%s\n", result->why_bogus); 363238106Sdes} 364238106Sdes 365238106Sdes/** perform a lookup and printout return if domain existed */ 366238106Sdesstatic int 367238106Sdesdnslook(struct ub_ctx* ctx, char* q, int t, int c, int docname) 368238106Sdes{ 369238106Sdes int ret; 370238106Sdes struct ub_result* result; 371238106Sdes 372238106Sdes ret = ub_resolve(ctx, q, t, c, &result); 373238106Sdes if(ret != 0) { 374238106Sdes fprintf(stderr, "resolve error: %s\n", ub_strerror(ret)); 375238106Sdes exit(1); 376238106Sdes } 377238106Sdes pretty_output(q, t, c, result, docname); 378238106Sdes ret = result->nxdomain; 379238106Sdes ub_resolve_free(result); 380238106Sdes return ret; 381238106Sdes} 382238106Sdes 383238106Sdes/** perform host lookup */ 384238106Sdesstatic void 385238106Sdeslookup(struct ub_ctx* ctx, const char* nm, const char* qt, const char* qc) 386238106Sdes{ 387238106Sdes /* massage input into a query name, type and class */ 388238106Sdes int multi = 0; /* no type, so do A, AAAA, MX */ 389238106Sdes int reverse = 0; /* we are doing a reverse lookup */ 390238106Sdes char* realq = massage_qname(nm, &reverse); 391238106Sdes int t = massage_type(qt, reverse, &multi); 392238106Sdes int c = massage_class(qc); 393238106Sdes 394238106Sdes /* perform the query */ 395238106Sdes if(multi) { 396238106Sdes if(!dnslook(ctx, realq, LDNS_RR_TYPE_A, c, 1)) { 397238106Sdes /* domain exists, lookup more */ 398238106Sdes (void)dnslook(ctx, realq, LDNS_RR_TYPE_AAAA, c, 0); 399238106Sdes (void)dnslook(ctx, realq, LDNS_RR_TYPE_MX, c, 0); 400238106Sdes } 401238106Sdes } else { 402238106Sdes (void)dnslook(ctx, realq, t, c, 1); 403238106Sdes } 404238106Sdes ub_ctx_delete(ctx); 405238106Sdes free(realq); 406238106Sdes} 407238106Sdes 408238106Sdes/** print error if any */ 409238106Sdesstatic void 410238106Sdescheck_ub_res(int r) 411238106Sdes{ 412238106Sdes if(r != 0) { 413238106Sdes fprintf(stderr, "error: %s\n", ub_strerror(r)); 414238106Sdes exit(1); 415238106Sdes } 416238106Sdes} 417238106Sdes 418238106Sdes/** getopt global, in case header files fail to declare it. */ 419238106Sdesextern int optind; 420238106Sdes/** getopt global, in case header files fail to declare it. */ 421238106Sdesextern char* optarg; 422238106Sdes 423276605Sdes/** Main routine for unbound-host */ 424238106Sdesint main(int argc, char* argv[]) 425238106Sdes{ 426238106Sdes int c; 427238106Sdes char* qclass = NULL; 428238106Sdes char* qtype = NULL; 429356345Scy char* use_syslog = NULL; 430238106Sdes struct ub_ctx* ctx = NULL; 431238106Sdes int debuglevel = 0; 432238106Sdes 433238106Sdes ctx = ub_ctx_create(); 434238106Sdes if(!ctx) { 435238106Sdes fprintf(stderr, "error: out of memory\n"); 436238106Sdes exit(1); 437238106Sdes } 438276605Sdes /* no need to fetch additional targets, we only do few lookups */ 439276605Sdes check_ub_res(ub_ctx_set_option(ctx, "target-fetch-policy:", "0 0 0 0 0")); 440238106Sdes 441238106Sdes /* parse the options */ 442276605Sdes while( (c=getopt(argc, argv, "46DF:c:df:hrt:vy:C:")) != -1) { 443238106Sdes switch(c) { 444238106Sdes case '4': 445238106Sdes check_ub_res(ub_ctx_set_option(ctx, "do-ip6:", "no")); 446238106Sdes break; 447238106Sdes case '6': 448238106Sdes check_ub_res(ub_ctx_set_option(ctx, "do-ip4:", "no")); 449238106Sdes break; 450238106Sdes case 'c': 451238106Sdes qclass = optarg; 452238106Sdes break; 453238106Sdes case 'C': 454238106Sdes check_ub_res(ub_ctx_config(ctx, optarg)); 455238106Sdes break; 456276605Sdes case 'D': 457276605Sdes check_ub_res(ub_ctx_add_ta_file(ctx, ROOT_ANCHOR_FILE)); 458276605Sdes break; 459238106Sdes case 'd': 460238106Sdes debuglevel++; 461238106Sdes if(debuglevel < 2) 462238106Sdes debuglevel = 2; /* at least VERB_DETAIL */ 463238106Sdes break; 464238106Sdes case 'r': 465238106Sdes check_ub_res(ub_ctx_resolvconf(ctx, "/etc/resolv.conf")); 466238106Sdes break; 467238106Sdes case 't': 468238106Sdes qtype = optarg; 469238106Sdes break; 470238106Sdes case 'v': 471238106Sdes verb++; 472238106Sdes break; 473238106Sdes case 'y': 474238106Sdes check_ub_res(ub_ctx_add_ta(ctx, optarg)); 475238106Sdes break; 476238106Sdes case 'f': 477238106Sdes check_ub_res(ub_ctx_add_ta_file(ctx, optarg)); 478238106Sdes break; 479238106Sdes case 'F': 480238106Sdes check_ub_res(ub_ctx_trustedkeys(ctx, optarg)); 481238106Sdes break; 482238106Sdes case '?': 483238106Sdes case 'h': 484238106Sdes default: 485238106Sdes usage(); 486238106Sdes } 487238106Sdes } 488238106Sdes if(debuglevel != 0) /* set after possible -C options */ 489238106Sdes check_ub_res(ub_ctx_debuglevel(ctx, debuglevel)); 490356345Scy if(ub_ctx_get_option(ctx, "use-syslog", &use_syslog) == 0) { 491356345Scy if(strcmp(use_syslog, "yes") == 0) /* disable use-syslog */ 492238106Sdes check_ub_res(ub_ctx_set_option(ctx, 493238106Sdes "use-syslog:", "no")); 494356345Scy free(use_syslog); 495238106Sdes } 496238106Sdes argc -= optind; 497238106Sdes argv += optind; 498238106Sdes if(argc != 1) 499238106Sdes usage(); 500238106Sdes 501356345Scy#ifdef HAVE_SSL 502356345Scy#ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS 503356345Scy ERR_load_crypto_strings(); 504356345Scy#endif 505356345Scy#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) 506356345Scy ERR_load_SSL_strings(); 507356345Scy#endif 508356345Scy#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO) 509356345Scy# ifndef S_SPLINT_S 510356345Scy OpenSSL_add_all_algorithms(); 511356345Scy# endif 512356345Scy#else 513356345Scy OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS 514356345Scy | OPENSSL_INIT_ADD_ALL_DIGESTS 515356345Scy | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); 516356345Scy#endif 517356345Scy#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL) 518356345Scy (void)SSL_library_init(); 519356345Scy#else 520356345Scy (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); 521356345Scy#endif 522356345Scy#endif /* HAVE_SSL */ 523249141Sdes#ifdef HAVE_NSS 524249141Sdes if(NSS_NoDB_Init(".") != SECSuccess) { 525249141Sdes fprintf(stderr, "could not init NSS\n"); 526249141Sdes return 1; 527249141Sdes } 528249141Sdes#endif 529238106Sdes lookup(ctx, argv[0], qtype, qclass); 530238106Sdes return 0; 531238106Sdes} 532