DNSResolver::DNSResolver() : m_data(new DNSResolverData()) { int use_dns_public = 0; const char* dns_public_addr = "8.8.4.4"; if (auto res = getenv("DNS_PUBLIC")) { std::string dns_public(res); // TODO: could allow parsing of IP and protocol: e.g. DNS_PUBLIC=tcp:8.8.8.8 if (dns_public == "tcp") { LOG_PRINT_L0("Using public DNS server: " << dns_public_addr << " (TCP)"); use_dns_public = 1; } } // init libunbound context m_data->m_ub_context = ub_ctx_create(); if (use_dns_public) { ub_ctx_set_fwd(m_data->m_ub_context, dns_public_addr); ub_ctx_set_option(m_data->m_ub_context, "do-udp:", "no"); ub_ctx_set_option(m_data->m_ub_context, "do-tcp:", "yes"); } else { // look for "/etc/resolv.conf" and "/etc/hosts" or platform equivalent ub_ctx_resolvconf(m_data->m_ub_context, NULL); ub_ctx_hosts(m_data->m_ub_context, NULL); } #ifdef DEVELOPER_LIBUNBOUND_OLD #pragma message "Using the work around for old libunbound" { // work around for bug https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=515 needed for it to compile on e.g. Debian 7 char * ds_copy = NULL; // this will be the writable copy of string that bugged version of libunbound requires try { char * ds_copy = strdup( ::get_builtin_ds() ); ub_ctx_add_ta(m_data->m_ub_context, ds_copy); } catch(...) { // probably not needed but to work correctly in every case... if (ds_copy) { free(ds_copy); ds_copy=NULL; } // for the strdup throw ; } if (ds_copy) { free(ds_copy); ds_copy=NULL; } // for the strdup } #else // normal version for fixed libunbound ub_ctx_add_ta(m_data->m_ub_context, ::get_builtin_ds() ); #endif }
int unbound_init(struct ub_ctx *dnsctx) { int ugh; /* create unbound resolver context */ dnsctx = ub_ctx_create(); if(!dnsctx) { libreswan_log("error: could not create unbound context\n"); return 0; } DBG(DBG_DNS, ub_ctx_debuglevel(dnsctx,5); DBG_log("unbound context created - setting debug level to 5\n")); /* lookup from /etc/hosts before DNS lookups as people expect that */ if( (ugh=ub_ctx_hosts(dnsctx, "/etc/hosts")) != 0) { libreswan_log("error reading hosts: %s: %s\n", ub_strerror(ugh), strerror(errno)); return 0; } DBG(DBG_DNS, DBG_log("/etc/hosts lookups activated\n")); /* * Use /etc/resolv.conf as forwarding cache - we expect people to reconfigure this * file if they need to work around DHCP DNS obtained servers */ if( (ugh=ub_ctx_resolvconf(dnsctx, "/etc/resolv.conf")) != 0) { libreswan_log("error reading resolv.conf: %s: %s\n", ub_strerror(ugh), strerror(errno)); return 0; } DBG(DBG_DNS, DBG_log("/etc/resolv.conf usage activated\n")); /* add trust anchors to libunbound context - make this configurable later */ DBG(DBG_DNS, DBG_log("Loading root key:%s\n",rootanchor)); ugh = ub_ctx_add_ta(dnsctx, rootanchor); if(ugh != 0) { libreswan_log("error adding the DNSSEC root key: %s: %s\n", ub_strerror(ugh), strerror(errno)); return 0; } /* Enable DLV */ DBG(DBG_DNS, DBG_log("Loading dlv key:%s\n",dlvanchor)); ugh = ub_ctx_set_option(dnsctx, "dlv-anchor:",dlvanchor); if(ugh != 0) { libreswan_log("error adding the DLV key: %s: %s\n", ub_strerror(ugh), strerror(errno)); return 0; } return 1; }
DNSResolver::DNSResolver() : m_data(new DNSResolverData()) { int use_dns_public = 0; std::vector<std::string> dns_public_addr; if (auto res = getenv("DNS_PUBLIC")) { dns_public_addr = tools::dns_utils::parse_dns_public(res); if (!dns_public_addr.empty()) { MGINFO("Using public DNS server(s): " << boost::join(dns_public_addr, ", ") << " (TCP)"); use_dns_public = 1; } else { MERROR("Failed to parse DNS_PUBLIC"); } } // init libunbound context m_data->m_ub_context = ub_ctx_create(); if (use_dns_public) { for (const auto &ip: dns_public_addr) ub_ctx_set_fwd(m_data->m_ub_context, string_copy(ip.c_str())); ub_ctx_set_option(m_data->m_ub_context, string_copy("do-udp:"), string_copy("no")); ub_ctx_set_option(m_data->m_ub_context, string_copy("do-tcp:"), string_copy("yes")); } else { // look for "/etc/resolv.conf" and "/etc/hosts" or platform equivalent ub_ctx_resolvconf(m_data->m_ub_context, NULL); ub_ctx_hosts(m_data->m_ub_context, NULL); } const char * const *ds = ::get_builtin_ds(); while (*ds) { MINFO("adding trust anchor: " << *ds); ub_ctx_add_ta(m_data->m_ub_context, string_copy(*ds++)); } }
/** Main routine for checkconf */ int main(int argc, char* argv[]) { int c; char* qclass = NULL; char* qtype = NULL; struct ub_ctx* ctx = NULL; int debuglevel = 0; ctx = ub_ctx_create(); if(!ctx) { fprintf(stderr, "error: out of memory\n"); exit(1); } /* parse the options */ while( (c=getopt(argc, argv, "46F:c:df:hrt:vy:C:")) != -1) { switch(c) { case '4': check_ub_res(ub_ctx_set_option(ctx, "do-ip6:", "no")); break; case '6': check_ub_res(ub_ctx_set_option(ctx, "do-ip4:", "no")); break; case 'c': qclass = optarg; break; case 'C': check_ub_res(ub_ctx_config(ctx, optarg)); break; case 'd': debuglevel++; if(debuglevel < 2) debuglevel = 2; /* at least VERB_DETAIL */ break; case 'r': check_ub_res(ub_ctx_resolvconf(ctx, "/etc/resolv.conf")); break; case 't': qtype = optarg; break; case 'v': verb++; break; case 'y': check_ub_res(ub_ctx_add_ta(ctx, optarg)); break; case 'f': check_ub_res(ub_ctx_add_ta_file(ctx, optarg)); break; case 'F': check_ub_res(ub_ctx_trustedkeys(ctx, optarg)); break; case '?': case 'h': default: usage(); } } if(debuglevel != 0) /* set after possible -C options */ check_ub_res(ub_ctx_debuglevel(ctx, debuglevel)); if(ub_ctx_get_option(ctx, "use-syslog", &optarg) == 0) { if(strcmp(optarg, "yes") == 0) /* disable use-syslog */ check_ub_res(ub_ctx_set_option(ctx, "use-syslog:", "no")); free(optarg); } argc -= optind; argv += optind; if(argc != 1) usage(); #ifdef HAVE_NSS if(NSS_NoDB_Init(".") != SECSuccess) { fprintf(stderr, "could not init NSS\n"); return 1; } #endif lookup(ctx, argv[0], qtype, qclass); return 0; }
static void nss_ubdns_load_keys(void) { DIR *dirp; int dir_fd; struct dirent de; struct dirent *res; dirp = opendir(NSS_UBDNS_KEYDIR); if (dirp == NULL) return; dir_fd = dirfd(dirp); if (dir_fd == -1) return; while (readdir_r(dirp, &de, &res) == 0 && res != NULL) { FILE *fp; int fd; char *line = NULL; char *fn; size_t len = 0; size_t fnlen; ssize_t bytes_read; fn = de.d_name; fnlen = strlen(fn); if (fnlen < 5 || !(fn[fnlen - 4] == '.' && fn[fnlen - 3] == 'k' && fn[fnlen - 2] == 'e' && fn[fnlen - 1] == 'y')) { continue; } if (!isalnum(fn[0])) continue; fd = openat(dir_fd, de.d_name, O_RDONLY); if (fd == -1) continue; fp = fdopen(fd, "r"); if (fp == NULL) { close(fd); continue; } while ((bytes_read = getline(&line, &len, fp)) != -1) { char *p = line; while (isspace(*p)) p++; if (*p == '\0' || *p == ';') continue; ub_ctx_add_ta(ctx, p); } free(line); close(fd); } closedir(dirp); }