Example #1
0
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

}
Example #2
0
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;
}
Example #3
0
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++));
  }
}
Example #4
0
/** 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;
}
Example #5
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);
}