Пример #1
0
/** update domain to file */
static int
do_update(char* domain, char* file)
{
	struct ub_ctx* ctx;
	struct ub_result* result;
	int r;
	printf("updating %s to %s\n", domain, file);
	ctx = ub_ctx_create();
	if(!ctx) fatal("ub_ctx_create failed");

	if((r=ub_ctx_add_ta_file(ctx, file))) {
		printf("%s\n", ub_strerror(r));
		fatal("ub_ctx_add_ta_file failed");
	}

	if(!(result=do_lookup(ctx, domain))) {
		ub_ctx_delete(ctx);
		return 1;
	}
	ub_ctx_delete(ctx);
	do_print(result, file);
	ub_resolve_free(result);
	return 0;
}
Пример #2
0
static void unbound_ctx_config(bool do_dnssec, const char *rootfile, const char *trusted)
{
	int ugh;

	if (DBGP(DBG_DNS)) {
		ub_ctx_debuglevel(dns_ctx, 5);
		DBG_log("unbound context created - setting debug level to 5");
	};

	/* lookup from /etc/hosts before DNS lookups as people expect that */
	ugh = ub_ctx_hosts(dns_ctx, "/etc/hosts");
	if (ugh != 0) {
		loglog(RC_LOG_SERIOUS, "error reading hosts: %s: %s",
			ub_strerror(ugh), strerror(errno));
	} else {
		DBG(DBG_DNS, DBG_log("/etc/hosts lookups activated"));
	}

	/*
	 * Use /etc/resolv.conf as forwarding cache - we expect people
	 * to reconfigure this file if they need to work around DHCP DNS
	 * obtained servers.
	 */
	/*
	 * ??? ub_ctx_resolvconf is not currently documented to set errno.
	 * Private communications with W.C.A. Wijngaards 2017 October:
	 * "Is errno is meaningful after a failed call to libunbound?"
	 * "Yes it is.  Specifically for the error-to-read-file case.
	 *  Not other cases (eg. socket errors happen too far away in the code)."
	 */
	errno = 0;
	ugh = ub_ctx_resolvconf(dns_ctx, "/etc/resolv.conf");
	if (ugh != 0) {
		int e = errno;	/* protect value from ub_strerror */

		loglog(RC_LOG_SERIOUS, "error reading /etc/resolv.conf: %s: [errno: %s]",
			ub_strerror(ugh), strerror(e));
	} else {
		DBG(DBG_DNS, DBG_log("/etc/resolv.conf usage activated"));
	}

	if (!do_dnssec) {
		/* No DNSSEC - nothing more to configure */
		DBG(DBG_DNS, DBG_log("dnssec validation disabled by configuration"));
	}

	if (rootfile == NULL) {
		if (trusted != NULL) {
			loglog(RC_LOG_SERIOUS, "dnssec-enable=yes but no dnssec-rootkey-file or trust anchors specified.");
			loglog(RC_LOG_SERIOUS, "WARNING: DNSSEC validation disabled");
		}
	} else {
		DBG(DBG_DNS, DBG_log("Loading dnssec root key from:%s", rootfile));
		/* the cast is there for unbound < 1.4.12 */
		/* ??? ub_ctx_add_ta_autr is not documented to set errno */
		errno = 0;
		ugh = ub_ctx_add_ta_autr(dns_ctx, (char *) rootfile);
		if (ugh != 0) {
			int e = errno;	/* protect value from ub_strerror */

			loglog(RC_LOG_SERIOUS, "error adding dnssec root key: %s [errno: %s]",
				ub_strerror(ugh), strerror(e));
			loglog(RC_LOG_SERIOUS, "WARNING: DNSSEC validation likely broken!");
		}
	}

	if (trusted == NULL) {
		DBG(DBG_DNS,DBG_log("No additional dnssec trust anchors defined via dnssec-trusted= option"));
	} else {
		glob_t globbuf;
		char **fnp;
		int r = glob(trusted, GLOB_ERR, globugh_ta, &globbuf);

		switch (r) {
		case 0:	/* success */
			for (fnp = globbuf.gl_pathv; fnp != NULL && *fnp != NULL; fnp++) {
				ugh = ub_ctx_add_ta_file(dns_ctx, *fnp);
				if (ugh != 0) {
					loglog(RC_LOG_SERIOUS, "Ignored trusted key file %s: %s",
						*fnp,  ub_strerror(ugh));
				} else {
					DBG(DBG_DNS, DBG_log("Added contents of trusted key file %s to unbound resolver context",
						*fnp));
				}
			}
			break;

		case GLOB_NOSPACE:
			loglog(RC_LOG_SERIOUS, "out of space processing dnssec-trusted= argument: %s",
				trusted);
			break;

		case GLOB_ABORTED:
			/* already logged by globugh_ta */
			break;

		case GLOB_NOMATCH:
			loglog(RC_LOG_SERIOUS, "no trust anchor files matched '%s'", trusted);
			break;

		default:
			loglog(RC_LOG_SERIOUS, "trusted key file '%s': unknown glob error %d",
				trusted, r);
			break;
		}
		globfree(&globbuf);
	}
}
Пример #3
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;
}
Пример #4
0
int main(int argc, char **argv)
{
	struct ub_ctx* ctx;
	struct ub_result* result;
	int retval;
        int i;
        struct timeval starttime, endtime;

        int number = 100000;
        if (argc > 1) {
            number = atoi(argv[1]);
        }

	/* create context */
	ctx = ub_ctx_create();
	if(!ctx) {
		printf("error: could not create unbound context\n");
		return 1;
	}

	/* read /etc/resolv.conf for DNS proxy settings (from DHCP) */
	if( (retval=ub_ctx_resolvconf(ctx, "resolv.conf")) != 0) {
		printf("error reading resolv.conf: %s. errno says: %s\n", 
			ub_strerror(retval), strerror(errno));
		return 1;
	}

	/* read /etc/hosts for locally supplied host addresses */
	if( (retval=ub_ctx_hosts(ctx, "hosts")) != 0) {
		printf("error reading hosts: %s. errno says: %s\n", 
			ub_strerror(retval), strerror(errno));
		return 1;
	}

	/* read public keys for DNSSEC verification */
	if( (retval=ub_ctx_add_ta_file(ctx, "keys")) != 0) {
		printf("error adding keys: %s\n", ub_strerror(retval));
		return 1;
	}

	/* query for webserver */
	retval = ub_resolve(ctx, LOOKUP_NAME, 1, 1, &result);
	if(retval != 0) {
		printf("resolve error: %s\n", ub_strerror(retval));
		return 1;
	}

	/* show first result */
	if(result->havedata)
		printf("The address is %s\n", 
			inet_ntoa(*(struct in_addr*)result->data[0]));
	/* show security status */
	if(!result->secure) {
            fprintf(stderr, "something very wrong; not validated response returned\n");
            exit(1);
        }
        fprintf(stderr, "validated response returned\n");

        // Note: this is without proper memory freeing
        fprintf(stderr, "starting %d queries without context....\n", number);
        gettimeofday(&starttime, NULL);
        for (i = 0; i < number; i++) {
            retval = ub_resolve(ctx, LOOKUP_NAME, 1, 1, &result);
        }
        gettimeofday(&endtime, NULL);
        fprintf(stderr, "time elapsed (ms) for %d queries: %d\n", number, timeofday_diff(&starttime, &endtime));

	ub_resolve_free(result);
	ub_ctx_delete(ctx);

	return 0;
}