Beispiel #1
0
static void
register_keys(const cfg_obj_t *control, const cfg_obj_t *keylist,
	      controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext)
{
	controlkey_t *keyid, *next;
	const cfg_obj_t *keydef;
	char secret[1024];
	isc_buffer_t b;
	isc_result_t result;

	/*
	 * Find the keys corresponding to the keyids used by this listener.
	 */
	for (keyid = ISC_LIST_HEAD(*keyids); keyid != NULL; keyid = next) {
		next = ISC_LIST_NEXT(keyid, link);

		result = cfgkeylist_find(keylist, keyid->keyname, &keydef);
		if (result != ISC_R_SUCCESS) {
			cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
				    "couldn't find key '%s' for use with "
				    "command channel %s",
				    keyid->keyname, socktext);
			ISC_LIST_UNLINK(*keyids, keyid, link);
			free_controlkey(keyid, mctx);
		} else {
			const cfg_obj_t *algobj = NULL;
			const cfg_obj_t *secretobj = NULL;
			const char *algstr = NULL;
			const char *secretstr = NULL;
			unsigned int algtype;

			(void)cfg_map_get(keydef, "algorithm", &algobj);
			(void)cfg_map_get(keydef, "secret", &secretobj);
			INSIST(algobj != NULL && secretobj != NULL);

			algstr = cfg_obj_asstring(algobj);
			secretstr = cfg_obj_asstring(secretobj);

			if (ns_config_getkeyalgorithm2(algstr, NULL,
					&algtype, NULL) != ISC_R_SUCCESS)
			{
				cfg_obj_log(control, ns_g_lctx,
					    ISC_LOG_WARNING,
					    "unsupported algorithm '%s' in "
					    "key '%s' for use with command "
					    "channel %s",
					    algstr, keyid->keyname, socktext);
				ISC_LIST_UNLINK(*keyids, keyid, link);
				free_controlkey(keyid, mctx);
				continue;
			}

			keyid->algorithm = algtype;
			isc_buffer_init(&b, secret, sizeof(secret));
			result = isc_base64_decodestring(secretstr, &b);

			if (result != ISC_R_SUCCESS) {
				cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING,
					    "secret for key '%s' on "
					    "command channel %s: %s",
					    keyid->keyname, socktext,
					    isc_result_totext(result));
				ISC_LIST_UNLINK(*keyids, keyid, link);
				free_controlkey(keyid, mctx);
				continue;
			}

			keyid->secret.length = isc_buffer_usedlength(&b);
			keyid->secret.base = isc_mem_get(mctx,
							 keyid->secret.length);
			if (keyid->secret.base == NULL) {
				cfg_obj_log(keydef, ns_g_lctx, ISC_LOG_WARNING,
					   "couldn't register key '%s': "
					   "out of memory", keyid->keyname);
				ISC_LIST_UNLINK(*keyids, keyid, link);
				free_controlkey(keyid, mctx);
				break;
			}
			memmove(keyid->secret.base, isc_buffer_base(&b),
				keyid->secret.length);
		}
	}
}
Beispiel #2
0
static isc_result_t ddns_update_ptr (struct data_string *ddns_fwd_name,
				     struct data_string *ddns_rev_name,
				     unsigned long ttl)
{
	ns_updque updqueue;
	ns_updrec *updrec;
	isc_result_t result = ISC_R_UNEXPECTED;

	/*
	 * The DHCP server submits a DNS query which deletes all of the PTR RRs
	 * associated with the lease IP address, and adds a PTR RR whose data
	 * is the client's (possibly disambiguated) host name. The server also
	 * adds a DHCID RR specified in Section 4.3.
	 *   -- "Interaction between DHCP and DNS"
	 */

	ISC_LIST_INIT (updqueue);

	/*
	 * Delete all PTR RRs.
	 */
	updrec = minires_mkupdrec (S_UPDATE,
				   (const char *)ddns_rev_name -> data,
				   C_IN, T_PTR, 0);
	if (!updrec) {
		result = ISC_R_NOMEMORY;
		goto error;
	}

	updrec -> r_data = (unsigned char *)0;
	updrec -> r_size = 0;
	updrec -> r_opcode = DELETE;

	ISC_LIST_APPEND (updqueue, updrec, r_link);

	/*
	 * Add PTR RR.
	 */
	updrec = minires_mkupdrec (S_UPDATE,
				   (const char *)ddns_rev_name -> data,
				   C_IN, T_PTR, ttl);
	if (!updrec) {
		result = ISC_R_NOMEMORY;
		goto error;
	}

	updrec -> r_data = ddns_fwd_name -> data;
	updrec -> r_size = ddns_fwd_name -> len;
	updrec -> r_opcode = ADD;

	ISC_LIST_APPEND (updqueue, updrec, r_link);

	/*
	 * Attempt to perform the update.
	 */
	result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
#if defined (DEBUG)
	print_dns_status ((int)result, &updqueue);
#endif
	if (result == ISC_R_SUCCESS) {
		log_info ("added reverse map from %.*s to %.*s",
			  (int)ddns_rev_name -> len,
			  (const char *)ddns_rev_name -> data,
			  (int)ddns_fwd_name -> len,
			  (const char *)ddns_fwd_name -> data);
	} else {
		log_error ("unable to add reverse map from %.*s to %.*s: %s",
			   (int)ddns_rev_name -> len,
			   (const char *)ddns_rev_name -> data,
			   (int)ddns_fwd_name -> len,
			   (const char *)ddns_fwd_name -> data,
			   isc_result_totext (result));
	}

	/* Fall through. */
      error:

	while (!ISC_LIST_EMPTY (updqueue)) {
		if((updqueue).head){
			updrec = ISC_LIST_HEAD (updqueue);
			ISC_LIST_UNLINK (updqueue, updrec, r_link);
			minires_freeupdrec (updrec);
		}
	}

	return result;
}
Beispiel #3
0
static isc_result_t
do_scan(ns_interfacemgr_t *mgr, ns_listenlist_t *ext_listen,
	isc_boolean_t verbose)
{
	isc_interfaceiter_t *iter = NULL;
	isc_boolean_t scan_ipv4 = ISC_FALSE;
	isc_boolean_t scan_ipv6 = ISC_FALSE;
	isc_boolean_t adjusting = ISC_FALSE;
	isc_boolean_t ipv6only = ISC_TRUE;
	isc_boolean_t ipv6pktinfo = ISC_TRUE;
	isc_result_t result;
	isc_netaddr_t zero_address, zero_address6;
	ns_listenelt_t *le;
	isc_sockaddr_t listen_addr;
	ns_interface_t *ifp;
	isc_boolean_t log_explicit = ISC_FALSE;
	isc_boolean_t dolistenon;

	if (ext_listen != NULL)
		adjusting = ISC_TRUE;

	if (isc_net_probeipv6() == ISC_R_SUCCESS)
		scan_ipv6 = ISC_TRUE;
#ifdef WANT_IPV6
	else
		isc_log_write(IFMGR_COMMON_LOGARGS,
			      verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
			      "no IPv6 interfaces found");
#endif

	if (isc_net_probeipv4() == ISC_R_SUCCESS)
		scan_ipv4 = ISC_TRUE;
	else
		isc_log_write(IFMGR_COMMON_LOGARGS,
			      verbose ? ISC_LOG_INFO : ISC_LOG_DEBUG(1),
			      "no IPv4 interfaces found");

	/*
	 * A special, but typical case; listen-on-v6 { any; }.
	 * When we can make the socket IPv6-only, open a single wildcard
	 * socket for IPv6 communication.  Otherwise, make separate socket
	 * for each IPv6 address in order to avoid accepting IPv4 packets
	 * as the form of mapped addresses unintentionally unless explicitly
	 * allowed.
	 */
#ifndef ISC_ALLOW_MAPPED
	if (scan_ipv6 == ISC_TRUE &&
	    isc_net_probe_ipv6only() != ISC_R_SUCCESS) {
		ipv6only = ISC_FALSE;
		log_explicit = ISC_TRUE;
	}
#endif
	if (scan_ipv6 == ISC_TRUE &&
	    isc_net_probe_ipv6pktinfo() != ISC_R_SUCCESS) {
		ipv6pktinfo = ISC_FALSE;
		log_explicit = ISC_TRUE;
	}
	if (scan_ipv6 == ISC_TRUE && ipv6only && ipv6pktinfo) {
		for (le = ISC_LIST_HEAD(mgr->listenon6->elts);
		     le != NULL;
		     le = ISC_LIST_NEXT(le, link)) {
			struct in6_addr in6a;

			if (!listenon_is_ip6_any(le))
				continue;

			in6a = in6addr_any;
			isc_sockaddr_fromin6(&listen_addr, &in6a, le->port);

			ifp = find_matching_interface(mgr, &listen_addr);
			if (ifp != NULL) {
				ifp->generation = mgr->generation;
			} else {
				isc_log_write(IFMGR_COMMON_LOGARGS,
					      ISC_LOG_INFO,
					      "listening on IPv6 "
					      "interfaces, port %u",
					      le->port);
				result = ns_interface_setup(mgr, &listen_addr,
							    "<any>", &ifp,
							    ISC_TRUE);
				if (result == ISC_R_SUCCESS)
					ifp->flags |= NS_INTERFACEFLAG_ANYADDR;
				else
					isc_log_write(IFMGR_COMMON_LOGARGS,
						      ISC_LOG_ERROR,
						      "listening on all IPv6 "
						      "interfaces failed");
				/* Continue. */
			}
		}
	}

	isc_netaddr_any(&zero_address);
	isc_netaddr_any6(&zero_address6);

	result = isc_interfaceiter_create(mgr->mctx, &iter);
	if (result != ISC_R_SUCCESS)
		return (result);

	if (adjusting == ISC_FALSE) {
		result = clearacl(mgr->mctx, &mgr->aclenv.localhost);
		if (result != ISC_R_SUCCESS)
			goto cleanup_iter;
		result = clearacl(mgr->mctx, &mgr->aclenv.localnets);
		if (result != ISC_R_SUCCESS)
			goto cleanup_iter;
		clearlistenon(mgr);
	}

	for (result = isc_interfaceiter_first(iter);
	     result == ISC_R_SUCCESS;
	     result = isc_interfaceiter_next(iter))
	{
		isc_interface_t interface;
		ns_listenlist_t *ll;
		unsigned int family; 

		result = isc_interfaceiter_current(iter, &interface);
		if (result != ISC_R_SUCCESS)
			break;

		family = interface.address.family;
		if (family != AF_INET && family != AF_INET6)
			continue;
		if (scan_ipv4 == ISC_FALSE && family == AF_INET)
			continue;
		if (scan_ipv6 == ISC_FALSE && family == AF_INET6)
			continue;

		/*
		 * Test for the address being nonzero rather than testing
		 * INTERFACE_F_UP, because on some systems the latter
		 * follows the media state and we could end up ignoring
		 * the interface for an entire rescan interval due to
		 * a temporary media glitch at rescan time.
		 */
		if (family == AF_INET &&
		    isc_netaddr_equal(&interface.address, &zero_address)) {
			continue;
		}
		if (family == AF_INET6 &&
		    isc_netaddr_equal(&interface.address, &zero_address6)) {
			continue;
		}

		if (adjusting == ISC_FALSE) {
			result = setup_locals(mgr, &interface);
			if (result != ISC_R_SUCCESS)
				goto ignore_interface;
		}

		ll = (family == AF_INET) ? mgr->listenon4 : mgr->listenon6;
		dolistenon = ISC_TRUE;
		for (le = ISC_LIST_HEAD(ll->elts);
		     le != NULL;
		     le = ISC_LIST_NEXT(le, link))
		{
			int match;
			isc_boolean_t ipv6_wildcard = ISC_FALSE;
			isc_netaddr_t listen_netaddr;
			isc_sockaddr_t listen_sockaddr;

			/*
			 * Construct a socket address for this IP/port
			 * combination.
			 */
			if (family == AF_INET) {
				isc_netaddr_fromin(&listen_netaddr,
						   &interface.address.type.in);
			} else {
				isc_netaddr_fromin6(&listen_netaddr,
						    &interface.address.type.in6);
				isc_netaddr_setzone(&listen_netaddr,
						    interface.address.zone);
			}
			isc_sockaddr_fromnetaddr(&listen_sockaddr,
						 &listen_netaddr,
						 le->port);

			/*
			 * See if the address matches the listen-on statement;
			 * if not, ignore the interface.
			 */
			(void)dns_acl_match(&listen_netaddr, NULL, le->acl,
					    &mgr->aclenv, &match, NULL);
			if (match <= 0)
				continue;

			if (adjusting == ISC_FALSE && dolistenon == ISC_TRUE) {
				setup_listenon(mgr, &interface, le->port);
				dolistenon = ISC_FALSE;
			}

			/*
			 * The case of "any" IPv6 address will require
			 * special considerations later, so remember it.
			 */
			if (family == AF_INET6 && ipv6only && ipv6pktinfo &&
			    listenon_is_ip6_any(le))
				ipv6_wildcard = ISC_TRUE;

			/*
			 * When adjusting interfaces with extra a listening
			 * list, see if the address matches the extra list.
			 * If it does, and is also covered by a wildcard
			 * interface, we need to listen on the address
			 * explicitly.
			 */
			if (adjusting == ISC_TRUE) {
				ns_listenelt_t *ele;

				match = 0;
				for (ele = ISC_LIST_HEAD(ext_listen->elts);
				     ele != NULL;
				     ele = ISC_LIST_NEXT(ele, link)) {
					(void)dns_acl_match(&listen_netaddr,
							    NULL, ele->acl,
							    NULL, &match, NULL);
					if (match > 0 &&
					    (ele->port == le->port ||
					    ele->port == 0))
						break;
					else
						match = 0;
				}
				if (ipv6_wildcard == ISC_TRUE && match == 0)
					continue;
			}

			ifp = find_matching_interface(mgr, &listen_sockaddr);
			if (ifp != NULL) {
				ifp->generation = mgr->generation;
			} else {
				char sabuf[ISC_SOCKADDR_FORMATSIZE];

				if (adjusting == ISC_FALSE &&
				    ipv6_wildcard == ISC_TRUE)
					continue;

				if (log_explicit && family == AF_INET6 &&
				    !adjusting && listenon_is_ip6_any(le)) {
					isc_log_write(IFMGR_COMMON_LOGARGS,
						      verbose ? ISC_LOG_INFO :
							      ISC_LOG_DEBUG(1),
						      "IPv6 socket API is "
						      "incomplete; explicitly "
						      "binding to each IPv6 "
						      "address separately");
					log_explicit = ISC_FALSE;
				}
				isc_sockaddr_format(&listen_sockaddr,
						    sabuf, sizeof(sabuf));
				isc_log_write(IFMGR_COMMON_LOGARGS,
					      ISC_LOG_INFO,
					      "%s"
					      "listening on %s interface "
					      "%s, %s",
					      (adjusting == ISC_TRUE) ?
					      "additionally " : "",
					      (family == AF_INET) ?
					      "IPv4" : "IPv6",
					      interface.name, sabuf);

				result = ns_interface_setup(mgr,
							    &listen_sockaddr,
							    interface.name,
							    &ifp,
							    (adjusting == ISC_TRUE) ?
							    ISC_FALSE :
							    ISC_TRUE);

				if (result != ISC_R_SUCCESS) {
					isc_log_write(IFMGR_COMMON_LOGARGS,
						      ISC_LOG_ERROR,
						      "creating %s interface "
						      "%s failed; interface "
						      "ignored",
						      (family == AF_INET) ?
						      "IPv4" : "IPv6",
						      interface.name);
				}
				/* Continue. */
			}

		}
		continue;

	ignore_interface:
		isc_log_write(IFMGR_COMMON_LOGARGS,
			      ISC_LOG_ERROR,
			      "ignoring %s interface %s: %s",
			      (family == AF_INET) ? "IPv4" : "IPv6",
			      interface.name, isc_result_totext(result));
		continue;
	}
	if (result != ISC_R_NOMORE)
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "interface iteration failed: %s",
				 isc_result_totext(result));
	else 
		result = ISC_R_SUCCESS;
 cleanup_iter:
	isc_interfaceiter_destroy(&iter);
	return (result);
}
int
main(int argc, char *argv[]) {
	char *origin = NULL, *file = NULL;
	char *inputformatstr = NULL;
	isc_result_t result;
	isc_log_t *log = NULL;
#ifdef USE_PKCS11
	const char *engine = "pkcs11";
#else
	const char *engine = NULL;
#endif
	char *classname = NULL;
	dns_rdataclass_t rdclass;
	char *endp;
	int ch;

#define CMDLINE_FLAGS \
	"hm:o:I:c:E:v:Vxz"

	/*
	 * Process memory debugging argument first.
	 */
	while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
		switch (ch) {
		case 'm':
			if (strcasecmp(isc_commandline_argument, "record") == 0)
				isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
			if (strcasecmp(isc_commandline_argument, "trace") == 0)
				isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
			if (strcasecmp(isc_commandline_argument, "usage") == 0)
				isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
			if (strcasecmp(isc_commandline_argument, "size") == 0)
				isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
			if (strcasecmp(isc_commandline_argument, "mctx") == 0)
				isc_mem_debugging |= ISC_MEM_DEBUGCTX;
			break;
		default:
			break;
		}
	}
	isc_commandline_reset = ISC_TRUE;
	check_result(isc_app_start(), "isc_app_start");

	result = isc_mem_create(0, 0, &mctx);
	if (result != ISC_R_SUCCESS)
		fatal("out of memory");

	dns_result_register();

	isc_commandline_errprint = ISC_FALSE;

	while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
		switch (ch) {
		case 'c':
			classname = isc_commandline_argument;
			break;

		case 'E':
			engine = isc_commandline_argument;
			break;

		case 'I':
			inputformatstr = isc_commandline_argument;
			break;

		case 'm':
			break;

		case 'o':
			origin = isc_commandline_argument;
			break;

		case 'v':
			endp = NULL;
			verbose = strtol(isc_commandline_argument, &endp, 0);
			if (*endp != '\0')
				fatal("verbose level must be numeric");
			break;

		case 'x':
			keyset_kskonly = ISC_TRUE;
			break;

		case 'z':
			ignore_kskflag = ISC_TRUE;
			break;

		case '?':
			if (isc_commandline_option != '?')
				fprintf(stderr, "%s: invalid argument -%c\n",
					program, isc_commandline_option);
			/* FALLTHROUGH */

		case 'h':
			/* Does not return. */
			usage();

		case 'V':
			/* Does not return. */
			version(program);

		default:
			fprintf(stderr, "%s: unhandled option -%c\n",
				program, isc_commandline_option);
			exit(1);
		}
	}

	if (ectx == NULL)
		setup_entropy(mctx, NULL, &ectx);

	result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (result != ISC_R_SUCCESS)
		fatal("could not create hash context");

	result = dst_lib_init2(mctx, ectx, engine, ISC_ENTROPY_BLOCKING);
	if (result != ISC_R_SUCCESS)
		fatal("could not initialize dst: %s",
		      isc_result_totext(result));

	isc_stdtime_get(&now);

	rdclass = strtoclass(classname);

	setup_logging(verbose, mctx, &log);

	argc -= isc_commandline_index;
	argv += isc_commandline_index;

	if (argc < 1)
		usage();

	file = argv[0];

	argc -= 1;
	argv += 1;

	POST(argc);
	POST(argv);

	if (origin == NULL)
		origin = file;

	if (inputformatstr != NULL) {
		if (strcasecmp(inputformatstr, "text") == 0)
			inputformat = dns_masterformat_text;
		else if (strcasecmp(inputformatstr, "raw") == 0)
			inputformat = dns_masterformat_raw;
		else
			fatal("unknown file format: %s\n", inputformatstr);
	}

	gdb = NULL;
	fprintf(stderr, "Loading zone '%s' from file '%s'\n", origin, file);
	loadzone(file, origin, rdclass, &gdb);
	gorigin = dns_db_origin(gdb);
	gclass = dns_db_class(gdb);

	gversion = NULL;
	result = dns_db_newversion(gdb, &gversion);
	check_result(result, "dns_db_newversion()");

	verifyzone(gdb, gversion, gorigin, mctx,
		   ignore_kskflag, keyset_kskonly);

	dns_db_closeversion(gdb, &gversion, ISC_FALSE);
	dns_db_detach(&gdb);

	cleanup_logging(&log);
	dst_lib_destroy();
	isc_hash_destroy();
	cleanup_entropy(&ectx);
	dns_name_destroy();
	if (verbose > 10)
		isc_mem_stats(mctx, stdout);
	isc_mem_destroy(&mctx);

	(void) isc_app_finish();

	return (0);
}
Beispiel #5
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_ULONG len;
	CK_ULONG slen;
	CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE;
	CK_OBJECT_CLASS kClass = CKO_PRIVATE_KEY;
	CK_KEY_TYPE kType = CKK_RSA;
	CK_ATTRIBUTE kTemplate[] =
	{
		{ CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) },
		{ CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) },
		{ CKA_PUBLIC_EXPONENT, pubexp, (CK_ULONG) sizeof(pubexp) },
		{ CKA_PRIVATE_EXPONENT, privexp, (CK_ULONG) sizeof(privexp) },
		{ CKA_PRIME_1, prime1, (CK_ULONG) sizeof(prime1) },
		{ CKA_PRIME_2, prime2, (CK_ULONG) sizeof(prime2) },
		{ CKA_EXPONENT_1, exp_1, (CK_ULONG) sizeof(exp_1) },
		{ CKA_EXPONENT_2, exp_2, (CK_ULONG) sizeof(exp_2) },
		{ CKA_COEFFICIENT, coeff, (CK_ULONG) sizeof(coeff) }
	};
	CK_MECHANISM mech = { CKM_SHA1_RSA_PKCS, NULL, 0 };
	pk11_context_t pctx;
	pk11_optype_t op_type = OP_RSA;
	char *lib_name = NULL;
	char *pin = NULL;
	int error = 0;
	int c, errflg = 0;
	int ontoken  = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			op_type = OP_ANY;
			break;
		case 'p':
			pin = isc_commandline_argument;
			break;
		case 't':
			ontoken = 1;
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\tsign [-m module] [-s slot] [-p pin] "
			"[-t] [-n count]\n");
		exit(1);
	}

	pk11_result_register();

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	if (pin == NULL)
		pin = getpassphrase("Enter Pin: ");

	result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_TRUE,
				  ISC_TRUE, (const char *) pin, slot);
	if ((result != ISC_R_SUCCESS) &&
	    (result != PK11_R_NORANDOMSERVICE) &&
	    (result != PK11_R_NODIGESTSERVICE) &&
	    (result != PK11_R_NOAESSERVICE)) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		exit(1);
	}

	if (pin != NULL)
		memset(pin, 0, strlen((char *)pin));

	hSession = pctx.session;

	/* Create the private RSA key */
	if (ontoken)
		kTemplate[2].pValue = &truevalue;

	rv = pkcs_C_CreateObject(hSession, kTemplate, 13, &hKey);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_CreateObject: Error = 0x%.8lX\n", rv);
		goto exit_key;
	}

	/* Randomize the buffer */
	len = (CK_ULONG) sizeof(buf);
	rv = pkcs_C_GenerateRandom(hSession, buf, len);
	if (rv != CKR_OK) {
		fprintf(stderr, "C_GenerateRandom: Error = 0x%.8lX\n", rv);
		goto exit_key;
	}

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_key;
	}

	for (i = 0; i < count; i++) {
		/* Initialize Sign */
		rv = pkcs_C_SignInit(hSession, &mech, hKey);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_SignInit[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}

		/* Perform Sign */
		slen = (CK_ULONG) sizeof(sig);
		rv = pkcs_C_Sign(hSession, buf, len, sig, &slen);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_Sign[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_key;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%u RSA signs in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g RSA signs/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_key:
	if (hKey != CK_INVALID_HANDLE) {
		rv = pkcs_C_DestroyObject(hSession, hKey);
		if (rv != CKR_OK)
			fprintf(stderr,
				"C_DestroyObject: Error = 0x%.8lX\n",
				rv);
	}

	pk11_return_session(&pctx);
	(void) pk11_finalize();

	exit(error);
}
Beispiel #6
0
isc_result_t
dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
		const char *name, dns_view_t **viewp)
{
	dns_view_t *view;
	isc_result_t result;

	/*
	 * Create a view.
	 */

	REQUIRE(name != NULL);
	REQUIRE(viewp != NULL && *viewp == NULL);

	view = isc_mem_get(mctx, sizeof(*view));
	if (view == NULL)
		return (ISC_R_NOMEMORY);

	view->mctx = NULL;
	isc_mem_attach(mctx, &view->mctx);
	view->name = isc_mem_strdup(mctx, name);
	if (view->name == NULL) {
		result = ISC_R_NOMEMORY;
		goto cleanup_view;
	}
	result = isc_mutex_init(&view->lock);
	if (result != ISC_R_SUCCESS)
		goto cleanup_name;

	view->zonetable = NULL;
#ifdef BIND9
	result = dns_zt_create(mctx, rdclass, &view->zonetable);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "dns_zt_create() failed: %s",
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto cleanup_mutex;
	}
#endif
	view->secroots_priv = NULL;
	view->fwdtable = NULL;
	result = dns_fwdtable_create(mctx, &view->fwdtable);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "dns_fwdtable_create() failed: %s",
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto cleanup_zt;
	}

	view->acache = NULL;
	view->cache = NULL;
	view->cachedb = NULL;
	view->dlzdatabase = NULL;
	view->hints = NULL;
	view->resolver = NULL;
	view->adb = NULL;
	view->requestmgr = NULL;
	view->rdclass = rdclass;
	view->frozen = ISC_FALSE;
	view->task = NULL;
	result = isc_refcount_init(&view->references, 1);
	if (result != ISC_R_SUCCESS)
		goto cleanup_fwdtable;
	view->weakrefs = 0;
	view->attributes = (DNS_VIEWATTR_RESSHUTDOWN|DNS_VIEWATTR_ADBSHUTDOWN|
			    DNS_VIEWATTR_REQSHUTDOWN);
	view->statickeys = NULL;
	view->dynamickeys = NULL;
	view->matchclients = NULL;
	view->matchdestinations = NULL;
	view->matchrecursiveonly = ISC_FALSE;
	result = dns_tsigkeyring_create(view->mctx, &view->dynamickeys);
	if (result != ISC_R_SUCCESS)
		goto cleanup_references;
	view->peers = NULL;
	view->order = NULL;
	view->delonly = NULL;
	view->rootdelonly = ISC_FALSE;
	view->rootexclude = NULL;
	view->resstats = NULL;
	view->resquerystats = NULL;
	view->cacheshared = ISC_FALSE;
	ISC_LIST_INIT(view->dns64);
	view->dns64cnt = 0;

	/*
	 * Initialize configuration data with default values.
	 */
	view->recursion = ISC_TRUE;
	view->auth_nxdomain = ISC_FALSE; /* Was true in BIND 8 */
	view->additionalfromcache = ISC_TRUE;
	view->additionalfromauth = ISC_TRUE;
	view->enablednssec = ISC_TRUE;
	view->enablevalidation = ISC_TRUE;
	view->acceptexpired = ISC_FALSE;
	view->minimalresponses = ISC_FALSE;
	view->transfer_format = dns_one_answer;
	view->cacheacl = NULL;
	view->cacheonacl = NULL;
	view->queryacl = NULL;
	view->queryonacl = NULL;
	view->recursionacl = NULL;
	view->recursiononacl = NULL;
	view->sortlist = NULL;
	view->transferacl = NULL;
	view->notifyacl = NULL;
	view->updateacl = NULL;
	view->upfwdacl = NULL;
	view->denyansweracl = NULL;
	view->answeracl_exclude = NULL;
	view->denyanswernames = NULL;
	view->answernames_exclude = NULL;
	view->provideixfr = ISC_TRUE;
	view->maxcachettl = 7 * 24 * 3600;
	view->maxncachettl = 3 * 3600;
	view->dstport = 53;
	view->preferred_glue = 0;
	view->flush = ISC_FALSE;
	view->dlv = NULL;
	view->maxudp = 0;
	view->maxbits = 0;
	view->v4_aaaa = dns_v4_aaaa_ok;
	view->v4_aaaa_acl = NULL;
	ISC_LIST_INIT(view->rpz_zones);
	view->rpz_recursive_only = ISC_TRUE;
	view->rpz_break_dnssec = ISC_FALSE;
	dns_fixedname_init(&view->dlv_fixed);
	view->managed_keys = NULL;
	view->redirect = NULL;
#ifdef BIND9
	view->new_zone_file = NULL;
	view->new_zone_config = NULL;
	view->cfg_destroy = NULL;

	result = dns_order_create(view->mctx, &view->order);
	if (result != ISC_R_SUCCESS)
		goto cleanup_dynkeys;
#endif

	result = dns_peerlist_new(view->mctx, &view->peers);
	if (result != ISC_R_SUCCESS)
		goto cleanup_order;

	result = dns_aclenv_init(view->mctx, &view->aclenv);
	if (result != ISC_R_SUCCESS)
		goto cleanup_peerlist;

	ISC_LINK_INIT(view, link);
	ISC_EVENT_INIT(&view->resevent, sizeof(view->resevent), 0, NULL,
		       DNS_EVENT_VIEWRESSHUTDOWN, resolver_shutdown,
		       view, NULL, NULL, NULL);
	ISC_EVENT_INIT(&view->adbevent, sizeof(view->adbevent), 0, NULL,
		       DNS_EVENT_VIEWADBSHUTDOWN, adb_shutdown,
		       view, NULL, NULL, NULL);
	ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
		       DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
		       view, NULL, NULL, NULL);
	view->viewlist = NULL;
	view->magic = DNS_VIEW_MAGIC;

	*viewp = view;

	return (ISC_R_SUCCESS);

 cleanup_peerlist:
	dns_peerlist_detach(&view->peers);

 cleanup_order:
#ifdef BIND9
	dns_order_detach(&view->order);

 cleanup_dynkeys:
#endif
	dns_tsigkeyring_detach(&view->dynamickeys);

 cleanup_references:
	isc_refcount_destroy(&view->references);

 cleanup_fwdtable:
	dns_fwdtable_destroy(&view->fwdtable);

 cleanup_zt:
#ifdef BIND9
	dns_zt_detach(&view->zonetable);

 cleanup_mutex:
#endif
	DESTROYLOCK(&view->lock);

 cleanup_name:
	isc_mem_free(mctx, view->name);

 cleanup_view:
	isc_mem_putanddetach(&view->mctx, view, sizeof(*view));

	return (result);
}
Beispiel #7
0
static inline void
check_result(isc_result_t result, const char *msg) {
	if (result != ISC_R_SUCCESS)
		fatal("%s: %s", msg, isc_result_totext(result));
}
Beispiel #8
0
/*%
 * Set up a logging channel according to the named.conf data
 * in 'cchan' and add it to 'lctx'.
 */
static isc_result_t
channel_fromconf(const cfg_obj_t *channel, isc_logconfig_t *lctx) {
	isc_result_t result;
	isc_logdestination_t dest;
	unsigned int type;
	unsigned int flags = 0;
	int level;
	const char *channelname;
	const cfg_obj_t *fileobj = NULL;
	const cfg_obj_t *syslogobj = NULL;
	const cfg_obj_t *nullobj = NULL;
	const cfg_obj_t *stderrobj = NULL;
	const cfg_obj_t *severity = NULL;
	int i;

	channelname = cfg_obj_asstring(cfg_map_getname(channel));

	(void)cfg_map_get(channel, "file", &fileobj);
	(void)cfg_map_get(channel, "syslog", &syslogobj);
	(void)cfg_map_get(channel, "null", &nullobj);
	(void)cfg_map_get(channel, "stderr", &stderrobj);

	i = 0;
	if (fileobj != NULL)
		i++;
	if (syslogobj != NULL)
		i++;
	if (nullobj != NULL)
		i++;
	if (stderrobj != NULL)
		i++;

	if (i != 1) {
		cfg_obj_log(channel, ns_g_lctx, ISC_LOG_ERROR,
			      "channel '%s': exactly one of file, syslog, "
			      "null, and stderr must be present", channelname);
		return (ISC_R_FAILURE);
	}

	type = ISC_LOG_TONULL;

	if (fileobj != NULL) {
		const cfg_obj_t *pathobj = cfg_tuple_get(fileobj, "file");
		const cfg_obj_t *sizeobj = cfg_tuple_get(fileobj, "size");
		const cfg_obj_t *versionsobj =
				 cfg_tuple_get(fileobj, "versions");
		isc_int32_t versions = ISC_LOG_ROLLNEVER;
		isc_offset_t size = 0;

		type = ISC_LOG_TOFILE;

		if (versionsobj != NULL && cfg_obj_isuint32(versionsobj))
			versions = cfg_obj_asuint32(versionsobj);
		if (versionsobj != NULL && cfg_obj_isstring(versionsobj) &&
		    strcasecmp(cfg_obj_asstring(versionsobj), "unlimited") == 0)
			versions = ISC_LOG_ROLLINFINITE;
		if (sizeobj != NULL &&
		    cfg_obj_isuint64(sizeobj) &&
		    cfg_obj_asuint64(sizeobj) < ISC_OFFSET_MAXIMUM)
			size = (isc_offset_t)cfg_obj_asuint64(sizeobj);
		dest.file.stream = NULL;
		dest.file.name = cfg_obj_asstring(pathobj);
		dest.file.versions = versions;
		dest.file.maximum_size = size;
	} else if (syslogobj != NULL) {
		int facility = LOG_DAEMON;

		type = ISC_LOG_TOSYSLOG;

		if (cfg_obj_isstring(syslogobj)) {
			const char *facilitystr = cfg_obj_asstring(syslogobj);
			(void)isc_syslog_facilityfromstring(facilitystr,
							    &facility);
		}
		dest.facility = facility;
	} else if (stderrobj != NULL) {
		type = ISC_LOG_TOFILEDESC;
		dest.file.stream = stderr;
		dest.file.name = NULL;
		dest.file.versions = ISC_LOG_ROLLNEVER;
		dest.file.maximum_size = 0;
	}

	/*
	 * Munge flags.
	 */
	{
		const cfg_obj_t *printcat = NULL;
		const cfg_obj_t *printsev = NULL;
		const cfg_obj_t *printtime = NULL;

		(void)cfg_map_get(channel, "print-category", &printcat);
		(void)cfg_map_get(channel, "print-severity", &printsev);
		(void)cfg_map_get(channel, "print-time", &printtime);

		if (printcat != NULL && cfg_obj_asboolean(printcat))
			flags |= ISC_LOG_PRINTCATEGORY;
		if (printtime != NULL && cfg_obj_asboolean(printtime))
			flags |= ISC_LOG_PRINTTIME;
		if (printsev != NULL && cfg_obj_asboolean(printsev))
			flags |= ISC_LOG_PRINTLEVEL;
	}

	level = ISC_LOG_INFO;
	if (cfg_map_get(channel, "severity", &severity) == ISC_R_SUCCESS) {
		if (cfg_obj_isstring(severity)) {
			const char *str = cfg_obj_asstring(severity);
			if (strcasecmp(str, "critical") == 0)
				level = ISC_LOG_CRITICAL;
			else if (strcasecmp(str, "error") == 0)
				level = ISC_LOG_ERROR;
			else if (strcasecmp(str, "warning") == 0)
				level = ISC_LOG_WARNING;
			else if (strcasecmp(str, "notice") == 0)
				level = ISC_LOG_NOTICE;
			else if (strcasecmp(str, "info") == 0)
				level = ISC_LOG_INFO;
			else if (strcasecmp(str, "dynamic") == 0)
				level = ISC_LOG_DYNAMIC;
		} else
			/* debug */
			level = cfg_obj_asuint32(severity);
	}

	result = isc_log_createchannel(lctx, channelname,
				       type, level, &dest, flags);

	if (result == ISC_R_SUCCESS && type == ISC_LOG_TOFILE) {
		FILE *fp;

		/*
		 * Test to make sure that file is a plain file.
		 * Fix defect #22771
		*/
		result = isc_file_isplainfile(dest.file.name);
		if (result == ISC_R_SUCCESS ||
		    result == ISC_R_FILENOTFOUND) {
			/*
			 * Test that the file can be opened, since
			 * isc_log_open() can't effectively report
			 * failures when called in
			 * isc_log_doit().
			 */
			result = isc_stdio_open(dest.file.name, "a", &fp);
			if (result != ISC_R_SUCCESS) {
				syslog(LOG_ERR,
					"isc_stdio_open '%s' failed: %s",
					dest.file.name,
					isc_result_totext(result));
				fprintf(stderr,
					"isc_stdio_open '%s' failed: %s",
					dest.file.name,
					isc_result_totext(result));
			} else
				(void)isc_stdio_close(fp);
		} else {
			syslog(LOG_ERR, "isc_file_isplainfile '%s' failed: %s",
				dest.file.name, isc_result_totext(result));
			fprintf(stderr, "isc_file_isplainfile '%s' failed: %s",
				dest.file.name, isc_result_totext(result));
		}
	}

	return (result);
}
Beispiel #9
0
static isc_result_t
process_dhtkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name,
	       dns_rdata_tkey_t *tkeyin, dns_tkeyctx_t *tctx,
	       dns_rdata_tkey_t *tkeyout,
	       dns_tsig_keyring_t *ring, dns_namelist_t *namelist)
{
	isc_result_t result = ISC_R_SUCCESS;
	dns_name_t *keyname, ourname;
	dns_rdataset_t *keyset = NULL;
	dns_rdata_t keyrdata = DNS_RDATA_INIT, ourkeyrdata = DNS_RDATA_INIT;
	isc_boolean_t found_key = ISC_FALSE, found_incompatible = ISC_FALSE;
	dst_key_t *pubkey = NULL;
	isc_buffer_t ourkeybuf, *shared = NULL;
	isc_region_t r, r2, ourkeyr;
	unsigned char keydata[DST_KEY_MAXSIZE];
	unsigned int sharedsize;
	isc_buffer_t secret;
	unsigned char *randomdata = NULL, secretdata[256];
	dns_ttl_t ttl = 0;

	if (tctx->dhkey == NULL) {
		tkey_log("process_dhtkey: tkey-dhkey not defined");
		tkeyout->error = dns_tsigerror_badalg;
		return (DNS_R_REFUSED);
	}

	if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_HMACMD5_NAME)) {
		tkey_log("process_dhtkey: algorithms other than "
			 "hmac-md5 are not supported");
		tkeyout->error = dns_tsigerror_badalg;
		return (ISC_R_SUCCESS);
	}

	/*
	 * Look for a DH KEY record that will work with ours.
	 */
	for (result = dns_message_firstname(msg, DNS_SECTION_ADDITIONAL);
	     result == ISC_R_SUCCESS && !found_key;
	     result = dns_message_nextname(msg, DNS_SECTION_ADDITIONAL)) {
		keyname = NULL;
		dns_message_currentname(msg, DNS_SECTION_ADDITIONAL, &keyname);
		keyset = NULL;
		result = dns_message_findtype(keyname, dns_rdatatype_key, 0,
					      &keyset);
		if (result != ISC_R_SUCCESS)
			continue;

		for (result = dns_rdataset_first(keyset);
		     result == ISC_R_SUCCESS && !found_key;
		     result = dns_rdataset_next(keyset)) {
			dns_rdataset_current(keyset, &keyrdata);
			pubkey = NULL;
			result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
							 msg->mctx, &pubkey);
			if (result != ISC_R_SUCCESS) {
				dns_rdata_reset(&keyrdata);
				continue;
			}
			if (dst_key_alg(pubkey) == DNS_KEYALG_DH) {
				if (dst_key_paramcompare(pubkey, tctx->dhkey))
				{
					found_key = ISC_TRUE;
					ttl = keyset->ttl;
					break;
				} else
					found_incompatible = ISC_TRUE;
			}
			dst_key_free(&pubkey);
			dns_rdata_reset(&keyrdata);
		}
	}

	if (!found_key) {
		if (found_incompatible) {
			tkey_log("process_dhtkey: found an incompatible key");
			tkeyout->error = dns_tsigerror_badkey;
			return (ISC_R_SUCCESS);
		} else {
			tkey_log("process_dhtkey: failed to find a key");
			return (DNS_R_FORMERR);
		}
	}

	RETERR(add_rdata_to_list(msg, keyname, &keyrdata, ttl, namelist));

	isc_buffer_init(&ourkeybuf, keydata, sizeof(keydata));
	RETERR(dst_key_todns(tctx->dhkey, &ourkeybuf));
	isc_buffer_usedregion(&ourkeybuf, &ourkeyr);
	dns_rdata_fromregion(&ourkeyrdata, dns_rdataclass_any,
			     dns_rdatatype_key, &ourkeyr);

	dns_name_init(&ourname, NULL);
	dns_name_clone(dst_key_name(tctx->dhkey), &ourname);

	/*
	 * XXXBEW The TTL should be obtained from the database, if it exists.
	 */
	RETERR(add_rdata_to_list(msg, &ourname, &ourkeyrdata, 0, namelist));

	RETERR(dst_key_secretsize(tctx->dhkey, &sharedsize));
	RETERR(isc_buffer_allocate(msg->mctx, &shared, sharedsize));

	result = dst_key_computesecret(pubkey, tctx->dhkey, shared);
	if (result != ISC_R_SUCCESS) {
		tkey_log("process_dhtkey: failed to compute shared secret: %s",
			 isc_result_totext(result));
		goto failure;
	}
	dst_key_free(&pubkey);

	isc_buffer_init(&secret, secretdata, sizeof(secretdata));

	randomdata = isc_mem_get(tkeyout->mctx, TKEY_RANDOM_AMOUNT);
	if (randomdata == NULL)
		goto failure;

	result = dst__entropy_getdata(randomdata, TKEY_RANDOM_AMOUNT,
				      ISC_FALSE);
	if (result != ISC_R_SUCCESS) {
		tkey_log("process_dhtkey: failed to obtain entropy: %s",
			 isc_result_totext(result));
		goto failure;
	}

	r.base = randomdata;
	r.length = TKEY_RANDOM_AMOUNT;
	r2.base = tkeyin->key;
	r2.length = tkeyin->keylen;
	RETERR(compute_secret(shared, &r2, &r, &secret));
	isc_buffer_free(&shared);

	RETERR(dns_tsigkey_create(name, &tkeyin->algorithm,
				  isc_buffer_base(&secret),
				  isc_buffer_usedlength(&secret),
				  ISC_TRUE, signer, tkeyin->inception,
				  tkeyin->expire, ring->mctx, ring, NULL));

	/* This key is good for a long time */
	tkeyout->inception = tkeyin->inception;
	tkeyout->expire = tkeyin->expire;

	tkeyout->key = randomdata;
	tkeyout->keylen = TKEY_RANDOM_AMOUNT;

	return (ISC_R_SUCCESS);

 failure:
	if (!ISC_LIST_EMPTY(*namelist))
		free_namelist(msg, namelist);
	if (shared != NULL)
		isc_buffer_free(&shared);
	if (pubkey != NULL)
		dst_key_free(&pubkey);
	if (randomdata != NULL)
		isc_mem_put(tkeyout->mctx, randomdata, TKEY_RANDOM_AMOUNT);
	return (result);
}
Beispiel #10
0
ATF_TC_BODY(dumpraw, tc) {
	isc_result_t result;
	dns_db_t *db = NULL;
	dns_dbversion_t *version = NULL;
	char origin[sizeof(TEST_ORIGIN)];
	dns_name_t dns_origin;
	isc_buffer_t source, target;
	unsigned char name_buf[BUFLEN];
	int len;

	UNUSED(tc);

	strcpy(origin, TEST_ORIGIN);
	len = strlen(origin);
	isc_buffer_init(&source, origin, len);
	isc_buffer_add(&source, len);
	isc_buffer_setactive(&source, len);
	isc_buffer_init(&target, name_buf, BUFLEN);
	dns_name_init(&dns_origin, NULL);
	result = dns_name_fromtext(&dns_origin, &source, dns_rootname,
				   0, &target);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_test_begin(NULL, ISC_FALSE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_db_create(mctx, "rbt", &dns_origin, dns_dbtype_zone,
			       dns_rdataclass_in, 0, NULL, &db);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = dns_db_load(db, "testdata/master/master1.data");
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	dns_db_currentversion(db, &version);

	result = dns_master_dump2(mctx, db, version,
				  &dns_master_style_default, "test.dump",
				  dns_masterformat_raw);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = test_master("test.dump", dns_masterformat_raw, NULL, NULL);
	ATF_CHECK_STREQ(isc_result_totext(result), "success");
	ATF_CHECK(headerset);
	ATF_CHECK_EQ(header.flags, 0);

	dns_master_initrawheader(&header);
	header.sourceserial = 12345;
	header.flags |= DNS_MASTERRAW_SOURCESERIALSET;

	unlink("test.dump");
	result = dns_master_dump3(mctx, db, version,
				  &dns_master_style_default, "test.dump",
				  dns_masterformat_raw, &header);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	result = test_master("test.dump", dns_masterformat_raw, NULL, NULL);
	ATF_CHECK_STREQ(isc_result_totext(result), "success");
	ATF_CHECK(headerset);
	ATF_CHECK((header.flags & DNS_MASTERRAW_SOURCESERIALSET) != 0);
	ATF_CHECK_EQ(header.sourceserial, 12345);

	unlink("test.dump");
	dns_db_closeversion(db, &version, ISC_FALSE);
	dns_db_detach(&db);
	dns_test_end();
}
Beispiel #11
0
int
main(int argc, char **argv) {
	isc_result_t result;
	isc_mem_t *mctx = NULL;
	isc_log_t *lctx = NULL;
	isc_logconfig_t *lcfg = NULL;
	isc_logdestination_t destination;
	cfg_parser_t *pctx = NULL;
	cfg_obj_t *cfg = NULL;
	cfg_type_t *type = NULL;
	isc_boolean_t grammar = ISC_FALSE;
	isc_boolean_t memstats = ISC_FALSE;
	char *filename = NULL;

	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);

	result = isc_log_create(mctx, &lctx, &lcfg);
	check_result(result, "isc_log_create()");
	isc_log_setcontext(lctx);

	/*
	 * Create and install the default channel.
	 */
	destination.file.stream = stderr;
	destination.file.name = NULL;
	destination.file.versions = ISC_LOG_ROLLNEVER;
	destination.file.maximum_size = 0;
	result = isc_log_createchannel(lcfg, "_default",
				       ISC_LOG_TOFILEDESC,
				       ISC_LOG_DYNAMIC,
				       &destination, ISC_LOG_PRINTTIME);
	check_result(result, "isc_log_createchannel()");
	result = isc_log_usechannel(lcfg, "_default", NULL, NULL);
	check_result(result, "isc_log_usechannel()");

	/*
	 * Set the initial debug level.
	 */
	isc_log_setdebuglevel(lctx, 2);

	if (argc < 3)
		usage();

	while (argc > 1) {
		if (strcmp(argv[1], "--grammar") == 0) {
			grammar = ISC_TRUE;
		} else if (strcmp(argv[1], "--memstats") == 0) {
			memstats = ISC_TRUE;
		} else if (strcmp(argv[1], "--named") == 0) {
			type = &cfg_type_namedconf;
		} else if (strcmp(argv[1], "--rndc") == 0) {
			type = &cfg_type_rndcconf;
		} else if (argv[1][0] == '-') {
			usage();
		} else {
			filename = argv[1];
		}
		argv++, argc--;
	}

	if (grammar) {
		if (type == NULL)
			usage();
		cfg_print_grammar(type, output, NULL);
	} else {
		if (type == NULL || filename == NULL)
			usage();
		RUNTIME_CHECK(cfg_parser_create(mctx, lctx, &pctx) == ISC_R_SUCCESS);

		result = cfg_parse_file(pctx, filename, type, &cfg);

		fprintf(stderr, "read config: %s\n", isc_result_totext(result));

		if (result != ISC_R_SUCCESS)
			exit(1);

		cfg_print(cfg, output, NULL);

		cfg_obj_destroy(pctx, &cfg);

		cfg_parser_destroy(&pctx);
	}

	isc_log_destroy(&lctx);
	if (memstats)
		isc_mem_stats(mctx, stderr);
	isc_mem_destroy(&mctx);

	fflush(stdout);
	if (ferror(stdout)) {
		fprintf(stderr, "write error\n");
		return (1);
	} else
		return (0);
}
Beispiel #12
0
static void
lookup_done(isc_task_t *task, isc_event_t *event) {
	ns_lwdclient_t *client;
	ns_lwdclientmgr_t *cm;
	dns_lookupevent_t *levent;
	lwres_buffer_t lwb;
	dns_name_t *name;
	dns_rdataset_t *rdataset;
	dns_rdataset_t *sigrdataset;
	isc_result_t result;
	lwres_result_t lwresult;
	isc_region_t r;
	isc_buffer_t b;
	lwres_grbnresponse_t *grbn;
	int i;

	REQUIRE(event != NULL);

	UNUSED(task);

	lwb.base = NULL;
	client = event->ev_arg;
	cm = client->clientmgr;
	INSIST(client->lookup == (dns_lookup_t *)event->ev_sender);

	levent = (dns_lookupevent_t *)event;
	grbn = &client->grbn;

	ns_lwdclient_log(50, "lookup event result = %s",
			 isc_result_totext(levent->result));

	result = levent->result;
	if (result != ISC_R_SUCCESS) {
		dns_lookup_destroy(&client->lookup);
		isc_event_free(&event);
		levent = NULL;

		switch (result) {
		case DNS_R_NXDOMAIN:
		case DNS_R_NCACHENXDOMAIN:
			result = ns_lwsearchctx_next(&client->searchctx);
			if (result != ISC_R_SUCCESS)
				lwresult = LWRES_R_NOTFOUND;
			else {
				start_lookup(client);
				return;
			}
			break;
		case DNS_R_NXRRSET:
		case DNS_R_NCACHENXRRSET:
			lwresult = LWRES_R_TYPENOTFOUND;
			break;
		default:
			lwresult = LWRES_R_FAILURE;
		}
		ns_lwdclient_errorpktsend(client, lwresult);
		return;
	}

	name = levent->name;
	b = client->recv_buffer;

	grbn->flags = 0;

	grbn->nrdatas = 0;
	grbn->rdatas = NULL;
	grbn->rdatalen = NULL;

	grbn->nsigs = 0;
	grbn->sigs = NULL;
	grbn->siglen = NULL;

	result = dns_name_totext(name, ISC_TRUE, &client->recv_buffer);
	if (result != ISC_R_SUCCESS)
		goto out;
	grbn->realname = (char *)isc_buffer_used(&b);
	grbn->realnamelen = isc_buffer_usedlength(&client->recv_buffer) -
			    isc_buffer_usedlength(&b);
	ns_lwdclient_log(50, "found name '%.*s'", grbn->realnamelen,
			 grbn->realname);

	grbn->rdclass = cm->view->rdclass;
	grbn->rdtype = client->rdtype;

	rdataset = levent->rdataset;
	if (rdataset != NULL) {
		/* The normal case */
		grbn->nrdatas = dns_rdataset_count(rdataset);
		grbn->rdatas = isc_mem_get(cm->mctx, grbn->nrdatas *
					   sizeof(unsigned char *));
		if (grbn->rdatas == NULL)
			goto out;
		grbn->rdatalen = isc_mem_get(cm->mctx, grbn->nrdatas *
					     sizeof(lwres_uint16_t));
		if (grbn->rdatalen == NULL)
			goto out;

		i = 0;
		result = fill_array(&i, rdataset, grbn->nrdatas, grbn->rdatas,
				    grbn->rdatalen);
		if (result != ISC_R_SUCCESS)
			goto out;
		INSIST(i == grbn->nrdatas);
		grbn->ttl = rdataset->ttl;
		if (rdataset->trust == dns_trust_secure)
			grbn->flags |= LWRDATA_VALIDATED;
	} else {
		/* The SIG query case */
		result = iterate_node(grbn, levent->db, levent->node,
				      cm->mctx);
		if (result != ISC_R_SUCCESS)
			goto out;
	}
	ns_lwdclient_log(50, "filled in %d rdata%s", grbn->nrdatas,
			 (grbn->nrdatas == 1) ? "" : "s");

	sigrdataset = levent->sigrdataset;
	if (sigrdataset != NULL) {
		grbn->nsigs = dns_rdataset_count(sigrdataset);
		grbn->sigs = isc_mem_get(cm->mctx, grbn->nsigs *
					 sizeof(unsigned char *));
		if (grbn->sigs == NULL)
			goto out;
		grbn->siglen = isc_mem_get(cm->mctx, grbn->nsigs *
					   sizeof(lwres_uint16_t));
		if (grbn->siglen == NULL)
			goto out;

		i = 0;
		result = fill_array(&i, sigrdataset, grbn->nsigs, grbn->sigs,
				    grbn->siglen);
		if (result != ISC_R_SUCCESS)
			goto out;
		INSIST(i == grbn->nsigs);
		ns_lwdclient_log(50, "filled in %d signature%s", grbn->nsigs,
				 (grbn->nsigs == 1) ? "" : "s");
	}

	/*
	 * Render the packet.
	 */
	client->pkt.recvlength = LWRES_RECVLENGTH;
	client->pkt.authtype = 0; /* XXXMLG */
	client->pkt.authlength = 0;
	client->pkt.result = LWRES_R_SUCCESS;

	lwresult = lwres_grbnresponse_render(cm->lwctx,
					     grbn, &client->pkt, &lwb);
	if (lwresult != LWRES_R_SUCCESS)
		goto out;

	isc_mem_put(cm->mctx, grbn->rdatas,
		    grbn->nrdatas * sizeof(unsigned char *));
	isc_mem_put(cm->mctx, grbn->rdatalen,
		    grbn->nrdatas * sizeof(lwres_uint16_t));

	if (grbn->sigs != NULL)
		isc_mem_put(cm->mctx, grbn->sigs,
			    grbn->nsigs * sizeof(unsigned char *));
	if (grbn->siglen != NULL)
		isc_mem_put(cm->mctx, grbn->siglen,
			    grbn->nsigs * sizeof(lwres_uint16_t));

	r.base = lwb.base;
	r.length = lwb.used;
	client->sendbuf = r.base;
	client->sendlength = r.length;
	result = ns_lwdclient_sendreply(client, &r);
	if (result != ISC_R_SUCCESS)
		goto out2;

	NS_LWDCLIENT_SETSEND(client);

	dns_lookup_destroy(&client->lookup);
	isc_event_free(&event);

	return;

 out:
	if (grbn->rdatas != NULL)
		isc_mem_put(cm->mctx, grbn->rdatas,
			    grbn->nrdatas * sizeof(unsigned char *));
	if (grbn->rdatalen != NULL)
		isc_mem_put(cm->mctx, grbn->rdatalen,
			    grbn->nrdatas * sizeof(lwres_uint16_t));

	if (grbn->sigs != NULL)
		isc_mem_put(cm->mctx, grbn->sigs,
			    grbn->nsigs * sizeof(unsigned char *));
	if (grbn->siglen != NULL)
		isc_mem_put(cm->mctx, grbn->siglen,
			    grbn->nsigs * sizeof(lwres_uint16_t));
 out2:
	if (client->lookup != NULL)
		dns_lookup_destroy(&client->lookup);
	if (lwb.base != NULL)
		lwres_context_freemem(cm->lwctx, lwb.base, lwb.length);

		isc_event_free(&event);

	ns_lwdclient_log(50, "error constructing getrrsetbyname response");
	ns_lwdclient_errorpktsend(client, LWRES_R_FAILURE);
}
Beispiel #13
0
static void
update_listener(ns_controls_t *cp, controllistener_t **listenerp,
		const cfg_obj_t *control, const cfg_obj_t *config,
		isc_sockaddr_t *addr, cfg_aclconfctx_t *aclconfctx,
		const char *socktext, isc_sockettype_t type)
{
	controllistener_t *listener;
	const cfg_obj_t *allow;
	const cfg_obj_t *global_keylist = NULL;
	const cfg_obj_t *control_keylist = NULL;
	dns_acl_t *new_acl = NULL;
	controlkeylist_t keys;
	isc_result_t result = ISC_R_SUCCESS;

	for (listener = ISC_LIST_HEAD(cp->listeners);
	     listener != NULL;
	     listener = ISC_LIST_NEXT(listener, link))
		if (isc_sockaddr_equal(addr, &listener->address))
			break;

	if (listener == NULL) {
		*listenerp = NULL;
		return;
	}

	/*
	 * There is already a listener for this sockaddr.
	 * Update the access list and key information.
	 *
	 * First try to deal with the key situation.  There are a few
	 * possibilities:
	 *  (a)	It had an explicit keylist and still has an explicit keylist.
	 *  (b)	It had an automagic key and now has an explicit keylist.
	 *  (c)	It had an explicit keylist and now needs an automagic key.
	 *  (d) It has an automagic key and still needs the automagic key.
	 *
	 * (c) and (d) are the annoying ones.  The caller needs to know
	 * that it should use the automagic configuration for key information
	 * in place of the named.conf configuration.
	 *
	 * XXXDCL There is one other hazard that has not been dealt with,
	 * the problem that if a key change is being caused by a control
	 * channel reload, then the response will be with the new key
	 * and not able to be decrypted by the client.
	 */
	if (control != NULL)
		get_key_info(config, control, &global_keylist,
			     &control_keylist);

	if (control_keylist != NULL) {
		INSIST(global_keylist != NULL);

		ISC_LIST_INIT(keys);
		result = controlkeylist_fromcfg(control_keylist,
						listener->mctx, &keys);
		if (result == ISC_R_SUCCESS) {
			free_controlkeylist(&listener->keys, listener->mctx);
			listener->keys = keys;
			register_keys(control, global_keylist, &listener->keys,
				      listener->mctx, socktext);
		}
	} else {
		free_controlkeylist(&listener->keys, listener->mctx);
		result = get_rndckey(listener->mctx, &listener->keys);
	}

	if (result != ISC_R_SUCCESS && global_keylist != NULL) {
		/*
		 * This message might be a little misleading since the
		 * "new keys" might in fact be identical to the old ones,
		 * but tracking whether they are identical just for the
		 * sake of avoiding this message would be too much trouble.
		 */
		if (control != NULL)
			cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
				    "couldn't install new keys for "
				    "command channel %s: %s",
				    socktext, isc_result_totext(result));
		else
			isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
				      NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
				      "couldn't install new keys for "
				      "command channel %s: %s",
				      socktext, isc_result_totext(result));
	}

	/*
	 * Now, keep the old access list unless a new one can be made.
	 */
	if (control != NULL && type == isc_sockettype_tcp) {
		allow = cfg_tuple_get(control, "allow");
		result = cfg_acl_fromconfig(allow, config, ns_g_lctx,
					    aclconfctx, listener->mctx, 0,
					    &new_acl);
	} else {
		result = dns_acl_any(listener->mctx, &new_acl);
	}

	if (result == ISC_R_SUCCESS) {
		dns_acl_detach(&listener->acl);
		dns_acl_attach(new_acl, &listener->acl);
		dns_acl_detach(&new_acl);
		/* XXXDCL say the old acl is still used? */
	} else if (control != NULL)
		cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
			    "couldn't install new acl for "
			    "command channel %s: %s",
			    socktext, isc_result_totext(result));
	else
		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
			      NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,
			      "couldn't install new acl for "
			      "command channel %s: %s",
			      socktext, isc_result_totext(result));

	if (result == ISC_R_SUCCESS && type == isc_sockettype_unix) {
		isc_uint32_t perm, owner, group;
		perm  = cfg_obj_asuint32(cfg_tuple_get(control, "perm"));
		owner = cfg_obj_asuint32(cfg_tuple_get(control, "owner"));
		group = cfg_obj_asuint32(cfg_tuple_get(control, "group"));
		result = ISC_R_SUCCESS;
		if (listener->perm != perm || listener->owner != owner ||
		    listener->group != group)
			result = isc_socket_permunix(&listener->address, perm,
						     owner, group);
		if (result == ISC_R_SUCCESS) {
			listener->perm = perm;
			listener->owner = owner;
			listener->group = group;
		} else if (control != NULL)
			cfg_obj_log(control, ns_g_lctx, ISC_LOG_WARNING,
				    "couldn't update ownership/permission for "
				    "command channel %s", socktext);
	}

	*listenerp = listener;
}
Beispiel #14
0
static isc_result_t
get_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {
	isc_result_t result;
	cfg_parser_t *pctx = NULL;
	cfg_obj_t *config = NULL;
	const cfg_obj_t *key = NULL;
	const cfg_obj_t *algobj = NULL;
	const cfg_obj_t *secretobj = NULL;
	const char *algstr = NULL;
	const char *secretstr = NULL;
	controlkey_t *keyid = NULL;
	char secret[1024];
	unsigned int algtype;
	isc_buffer_t b;

	isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,
		      NS_LOGMODULE_CONTROL, ISC_LOG_INFO,
		      "configuring command channel from '%s'",
		      ns_g_keyfile);
	if (! isc_file_exists(ns_g_keyfile))
		return (ISC_R_FILENOTFOUND);

	CHECK(cfg_parser_create(mctx, ns_g_lctx, &pctx));
	CHECK(cfg_parse_file(pctx, ns_g_keyfile, &cfg_type_rndckey, &config));
	CHECK(cfg_map_get(config, "key", &key));

	keyid = isc_mem_get(mctx, sizeof(*keyid));
	if (keyid == NULL)
		CHECK(ISC_R_NOMEMORY);
	keyid->keyname = isc_mem_strdup(mctx,
					cfg_obj_asstring(cfg_map_getname(key)));
	keyid->secret.base = NULL;
	keyid->secret.length = 0;
	keyid->algorithm = DST_ALG_UNKNOWN;
	ISC_LINK_INIT(keyid, link);
	if (keyid->keyname == NULL)
		CHECK(ISC_R_NOMEMORY);

	CHECK(bind9_check_key(key, ns_g_lctx));

	(void)cfg_map_get(key, "algorithm", &algobj);
	(void)cfg_map_get(key, "secret", &secretobj);
	INSIST(algobj != NULL && secretobj != NULL);

	algstr = cfg_obj_asstring(algobj);
	secretstr = cfg_obj_asstring(secretobj);

	if (ns_config_getkeyalgorithm2(algstr, NULL,
				       &algtype, NULL) != ISC_R_SUCCESS) {
		cfg_obj_log(key, ns_g_lctx,
			    ISC_LOG_WARNING,
			    "unsupported algorithm '%s' in "
			    "key '%s' for use with command "
			    "channel",
			    algstr, keyid->keyname);
		goto cleanup;
	}

	keyid->algorithm = algtype;
	isc_buffer_init(&b, secret, sizeof(secret));
	result = isc_base64_decodestring(secretstr, &b);

	if (result != ISC_R_SUCCESS) {
		cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
			    "secret for key '%s' on command channel: %s",
			    keyid->keyname, isc_result_totext(result));
		goto cleanup;
	}

	keyid->secret.length = isc_buffer_usedlength(&b);
	keyid->secret.base = isc_mem_get(mctx,
					 keyid->secret.length);
	if (keyid->secret.base == NULL) {
		cfg_obj_log(key, ns_g_lctx, ISC_LOG_WARNING,
			   "couldn't register key '%s': "
			   "out of memory", keyid->keyname);
		CHECK(ISC_R_NOMEMORY);
	}
	memmove(keyid->secret.base, isc_buffer_base(&b),
		keyid->secret.length);
	ISC_LIST_APPEND(*keyids, keyid, link);
	keyid = NULL;
	result = ISC_R_SUCCESS;

  cleanup:
	if (keyid != NULL)
		free_controlkey(keyid, mctx);
	if (config != NULL)
		cfg_obj_destroy(pctx, &config);
	if (pctx != NULL)
		cfg_parser_destroy(&pctx);
	return (result);
}
Beispiel #15
0
int
main(int argc, char *argv[]) {
	isc_boolean_t verbose = ISC_FALSE;
	unsigned int workers = 2;
	isc_timermgr_t *timermgr;
	int ch;
	isc_socketmgr_t *socketmgr;
	dns_dispatchmgr_t *dispatchmgr;
	dns_cache_t *cache;
	isc_buffer_t b;

	RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS);

	dns_result_register();

	mctx = NULL;
	RUNTIME_CHECK(isc_mem_create(0, 0, &mctx) == ISC_R_SUCCESS);

	RUNTIME_CHECK(isc_entropy_create(mctx, &ectx) == ISC_R_SUCCESS);
	RUNTIME_CHECK(isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE)
		      == ISC_R_SUCCESS);

	while ((ch = isc_commandline_parse(argc, argv, "d:vw:")) != -1) {
		switch (ch) {
		case 'd':
			level = (unsigned int)atoi(isc_commandline_argument);
			break;
		case 'v':
			verbose = ISC_TRUE;
			break;
		case 'w':
			workers = (unsigned int)atoi(isc_commandline_argument);
			break;
		}
	}

	log_init();

	if (verbose) {
		printf("%u workers\n", workers);
		printf("IPv4: %s\n", isc_result_totext(isc_net_probeipv4()));
		printf("IPv6: %s\n", isc_result_totext(isc_net_probeipv6()));
	}

	taskmgr = NULL;
	RUNTIME_CHECK(isc_taskmgr_create(mctx, workers, 0, &taskmgr) ==
		      ISC_R_SUCCESS);
	task = NULL;
	RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task) ==
		      ISC_R_SUCCESS);
	isc_task_setname(task, "byname", NULL);

	dispatchmgr = NULL;
	RUNTIME_CHECK(dns_dispatchmgr_create(mctx, NULL, &dispatchmgr)
		      == ISC_R_SUCCESS);

	timermgr = NULL;
	RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS);
	socketmgr = NULL;
	RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);

	cache = NULL;
	RUNTIME_CHECK(dns_cache_create(mctx, taskmgr, timermgr,
				       dns_rdataclass_in, "rbt", 0, NULL,
				       &cache) == ISC_R_SUCCESS);

	view = NULL;
	RUNTIME_CHECK(dns_view_create(mctx, dns_rdataclass_in, "default",
				      &view) == ISC_R_SUCCESS);

	{
		unsigned int attrs;
		dns_dispatch_t *disp4 = NULL;
		dns_dispatch_t *disp6 = NULL;

		if (isc_net_probeipv4() == ISC_R_SUCCESS) {
			isc_sockaddr_t any4;
			isc_sockaddr_any(&any4);

			attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
			RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr,
							  socketmgr,
							  taskmgr, &any4,
							  512, 6, 1024,
							  17, 19, attrs,
							  attrs, &disp4)
				      == ISC_R_SUCCESS);
			INSIST(disp4 != NULL);
		}

		if (isc_net_probeipv6() == ISC_R_SUCCESS) {
			isc_sockaddr_t any6;

			isc_sockaddr_any6(&any6);

			attrs = DNS_DISPATCHATTR_IPV6 | DNS_DISPATCHATTR_UDP;
			RUNTIME_CHECK(dns_dispatch_getudp(dispatchmgr,
							  socketmgr,
							  taskmgr, &any6,
							  512, 6, 1024,
							  17, 19, attrs,
							  attrs, &disp6)
				      == ISC_R_SUCCESS);
			INSIST(disp6 != NULL);
		}

		RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, 1,
						      socketmgr,
						      timermgr, 0,
						      dispatchmgr,
						      disp4, disp6) ==
		      ISC_R_SUCCESS);

		if (disp4 != NULL)
			dns_dispatch_detach(&disp4);
		if (disp6 != NULL)
			dns_dispatch_detach(&disp6);
	}

	{
		struct in_addr ina;
		isc_sockaddr_t sa;
		isc_sockaddrlist_t sal;

		ISC_LIST_INIT(sal);
		ina.s_addr = inet_addr("127.0.0.1");
		isc_sockaddr_fromin(&sa, &ina, 53);
		ISC_LIST_APPEND(sal, &sa, link);

		RUNTIME_CHECK(dns_fwdtable_add(view->fwdtable, dns_rootname,
					       &sal, dns_fwdpolicy_only)
			      == ISC_R_SUCCESS);
	}

	dns_view_setcache(view, cache);
	dns_view_freeze(view);

	dns_cache_detach(&cache);

	printf("name = %s\n", argv[isc_commandline_index]);
	isc_buffer_init(&b, argv[isc_commandline_index],
			strlen(argv[isc_commandline_index]));
	isc_buffer_add(&b, strlen(argv[isc_commandline_index]));
	dns_fixedname_init(&name);
	dns_fixedname_init(&target);
	RUNTIME_CHECK(dns_name_fromtext(dns_fixedname_name(&name), &b,
					dns_rootname, 0, NULL) ==
		      ISC_R_SUCCESS);

	RUNTIME_CHECK(isc_app_onrun(mctx, task, run, NULL) == ISC_R_SUCCESS);

	(void)isc_app_run();

	dns_view_detach(&view);
	isc_task_shutdown(task);
	isc_task_detach(&task);

	dns_dispatchmgr_destroy(&dispatchmgr);

	isc_taskmgr_destroy(&taskmgr);

	isc_socketmgr_destroy(&socketmgr);
	isc_timermgr_destroy(&timermgr);

	isc_log_destroy(&lctx);

	isc_hash_destroy();
	isc_entropy_detach(&ectx);

	if (verbose)
		isc_mem_stats(mctx, stdout);
	isc_mem_destroy(&mctx);

	isc_app_finish();

	return (0);
}
Beispiel #16
0
static isc_result_t
process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin,
		dns_tkeyctx_t *tctx, dns_rdata_tkey_t *tkeyout,
		dns_tsig_keyring_t *ring)
{
	isc_result_t result = ISC_R_SUCCESS;
	dst_key_t *dstkey = NULL;
	dns_tsigkey_t *tsigkey = NULL;
	dns_fixedname_t principal;
	isc_stdtime_t now;
	isc_region_t intoken;
	isc_buffer_t *outtoken = NULL;
	gss_ctx_id_t gss_ctx = NULL;

	/*
	 * You have to define either a gss credential (principal) to
	 * accept with tkey-gssapi-credential, or you have to
	 * configure a specific keytab (with tkey-gssapi-keytab) in
	 * order to use gsstkey
	 */
	if (tctx->gsscred == NULL && tctx->gssapi_keytab == NULL) {
		tkey_log("process_gsstkey(): no tkey-gssapi-credential "
			 "or tkey-gssapi-keytab configured");
		return (ISC_R_NOPERM);
	}

	if (!dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPI_NAME) &&
	    !dns_name_equal(&tkeyin->algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
		tkeyout->error = dns_tsigerror_badalg;
		tkey_log("process_gsstkey(): dns_tsigerror_badalg");	/* XXXSRA */
		return (ISC_R_SUCCESS);
	}

	/*
	 * XXXDCL need to check for key expiry per 4.1.1
	 * XXXDCL need a way to check fully established, perhaps w/key_flags
	 */

	intoken.base = tkeyin->key;
	intoken.length = tkeyin->keylen;

	result = dns_tsigkey_find(&tsigkey, name, &tkeyin->algorithm, ring);
	if (result == ISC_R_SUCCESS)
		gss_ctx = dst_key_getgssctx(tsigkey->key);

	dns_fixedname_init(&principal);

	/*
	 * Note that tctx->gsscred may be NULL if tctx->gssapi_keytab is set
	 */
	result = dst_gssapi_acceptctx(tctx->gsscred, tctx->gssapi_keytab,
				      &intoken,
				      &outtoken, &gss_ctx,
				      dns_fixedname_name(&principal),
				      tctx->mctx);
	if (result == DNS_R_INVALIDTKEY) {
		if (tsigkey != NULL)
			dns_tsigkey_detach(&tsigkey);
		tkeyout->error = dns_tsigerror_badkey;
		tkey_log("process_gsstkey(): dns_tsigerror_badkey");    /* XXXSRA */
		return (ISC_R_SUCCESS);
	}
	if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS)
		goto failure;
	/*
	 * XXXDCL Section 4.1.3: Limit GSS_S_CONTINUE_NEEDED to 10 times.
	 */

	isc_stdtime_get(&now);

	if (tsigkey == NULL) {
#ifdef GSSAPI
		OM_uint32 gret, minor, lifetime;
#endif
		isc_uint32_t expire;

		RETERR(dst_key_fromgssapi(name, gss_ctx, ring->mctx,
					  &dstkey, &intoken));
		/*
		 * Limit keys to 1 hour or the context's lifetime whichever
		 * is smaller.
		 */
		expire = now + 3600;
#ifdef GSSAPI
		gret = gss_context_time(&minor, gss_ctx, &lifetime);
		if (gret == GSS_S_COMPLETE && now + lifetime < expire)
			expire = now + lifetime;
#endif
		RETERR(dns_tsigkey_createfromkey(name, &tkeyin->algorithm,
						 dstkey, ISC_TRUE,
						 dns_fixedname_name(&principal),
						 now, expire, ring->mctx, ring,
						 NULL));
		dst_key_free(&dstkey);
		tkeyout->inception = now;
		tkeyout->expire = expire;
	} else {
		tkeyout->inception = tsigkey->inception;
		tkeyout->expire = tsigkey->expire;
		dns_tsigkey_detach(&tsigkey);
	}

	if (outtoken) {
		tkeyout->key = isc_mem_get(tkeyout->mctx,
					   isc_buffer_usedlength(outtoken));
		if (tkeyout->key == NULL) {
			result = ISC_R_NOMEMORY;
			goto failure;
		}
		tkeyout->keylen = isc_buffer_usedlength(outtoken);
		memmove(tkeyout->key, isc_buffer_base(outtoken),
		       isc_buffer_usedlength(outtoken));
		isc_buffer_free(&outtoken);
	} else {
		tkeyout->key = isc_mem_get(tkeyout->mctx, tkeyin->keylen);
		if (tkeyout->key == NULL) {
			result = ISC_R_NOMEMORY;
			goto failure;
		}
		tkeyout->keylen = tkeyin->keylen;
		memmove(tkeyout->key, tkeyin->key, tkeyin->keylen);
	}

	tkeyout->error = dns_rcode_noerror;

	tkey_log("process_gsstkey(): dns_tsigerror_noerror");   /* XXXSRA */

	return (ISC_R_SUCCESS);

failure:
	if (tsigkey != NULL)
		dns_tsigkey_detach(&tsigkey);

	if (dstkey != NULL)
		dst_key_free(&dstkey);

	if (outtoken != NULL)
		isc_buffer_free(&outtoken);

	tkey_log("process_gsstkey(): %s",
		isc_result_totext(result));	/* XXXSRA */

	return (result);
}
Beispiel #17
0
int 
main(int argc, char **argv) {
	int fd;
	int i;
	struct servent *ent;
	struct server_list *sp = NULL;
	int no_daemon = 0;
	int quiet = 0;
	isc_result_t status;
	char *s;

        /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
           2 (stderr) are open. To do this, we assume that when we
           open a file the lowest available file descriptor is used. */
        fd = open("/dev/null", O_RDWR);
        if (fd == 0)
                fd = open("/dev/null", O_RDWR);
        if (fd == 1)
                fd = open("/dev/null", O_RDWR);
        if (fd == 2)
                log_perror = 0; /* No sense logging to /dev/null. */
        else if (fd != -1)
                close(fd);

	openlog ("dhcrelay", LOG_NDELAY|LOG_PID, LOG_DAEMON);

#if !defined(DEBUG)
	setlogmask (LOG_UPTO (LOG_INFO));
#endif	

	/* Set up the OMAPI. */
	status = omapi_init ();
	if (status != ISC_R_SUCCESS)
		log_fatal ("Can't initialize OMAPI: %s",
			   isc_result_totext (status));

	/* Set up the OMAPI wrappers for the interface object. */
	interface_setup ();

	for (i = 1; i < argc; i++) {
		if (!strcmp (argv [i], "-p")) {
			if (++i == argc)
				usage ();
			local_port = htons (atoi (argv [i]));
			log_debug ("binding to user-specified port %d",
			       ntohs (local_port));
		} else if (!strcmp (argv [i], "-d")) {
			no_daemon = 1;
 		} else if (!strcmp (argv [i], "-i")) {
			struct interface_info *tmp =
				(struct interface_info *)0;
			status = interface_allocate (&tmp, MDL);
			if (status != ISC_R_SUCCESS)
				log_fatal ("%s: interface_allocate: %s",
					   argv [i],
					   isc_result_totext (status));
			if (++i == argc) {
				usage ();
			}
			strcpy (tmp -> name, argv [i]);
			interface_snorf (tmp, INTERFACE_REQUESTED);
			interface_dereference (&tmp, MDL);
		} else if (!strcmp (argv [i], "-q")) {
			quiet = 1;
			quiet_interface_discovery = 1;
		} else if (!strcmp (argv [i], "-a")) {
			add_agent_options = 1;
		} else if (!strcmp (argv [i], "-c")) {
			int hcount;
			if (++i == argc)
				usage ();
			hcount = atoi(argv[i]);
			if (hcount <= 255)
				max_hop_count= hcount;
			else
				usage ();
		} else if (!strcmp (argv [i], "-A")) {
			if (++i == argc)
				usage ();
			dhcp_max_agent_option_packet_length = atoi (argv [i]);
		} else if (!strcmp (argv [i], "-m")) {
			if (++i == argc)
				usage ();
			if (!strcasecmp (argv [i], "append")) {
				agent_relay_mode = forward_and_append;
			} else if (!strcasecmp (argv [i], "replace")) {
				agent_relay_mode = forward_and_replace;
			} else if (!strcasecmp (argv [i], "forward")) {
				agent_relay_mode = forward_untouched;
			} else if (!strcasecmp (argv [i], "discard")) {
				agent_relay_mode = discard;
			} else
				usage ();
		} else if (!strcmp (argv [i], "-D")) {
			drop_agent_mismatches = 1;
 		} else if (argv [i][0] == '-') {
 		    usage ();
		} else if (!strcmp (argv [i], "--version")) {
			log_info ("isc-dhcrelay-%s", PACKAGE_VERSION);
			exit (0);
 		} else {
			struct hostent *he;
			struct in_addr ia, *iap = (struct in_addr *)0;
			if (inet_aton (argv [i], &ia)) {
				iap = &ia;
			} else {
				he = gethostbyname (argv [i]);
				if (!he) {
					log_error ("%s: host unknown",
						   argv [i]);
				} else {
					iap = ((struct in_addr *)
					       he -> h_addr_list [0]);
				}
			}
			if (iap) {
				sp = ((struct server_list *)
				      dmalloc (sizeof *sp, MDL));
				if (!sp)
					log_fatal ("no memory for server.\n");
				sp -> next = servers;
				servers = sp;
				memcpy (&sp -> to.sin_addr,
					iap, sizeof *iap);
			}
 		}
	}

	if ((s = getenv ("PATH_DHCRELAY_PID"))) {
		path_dhcrelay_pid = s;
	}

	if (!quiet) {
		log_info ("%s %s", message, PACKAGE_VERSION);
		log_info (copyright);
		log_info (arr);
		log_info (url);
	} else {
		quiet = 0;
		log_perror = 0;
	}

	/* Default to the DHCP/BOOTP port. */
	if (!local_port) {
		ent = getservbyname ("dhcps", "udp");
		if (!ent)
			local_port = htons (67);
		else
			local_port = ent -> s_port;
		endservent ();
	}
	remote_port = htons (ntohs (local_port) + 1);
  
	/* We need at least one server. */
	if (!sp) {
		usage ();
	}

	/* Set up the server sockaddrs. */
	for (sp = servers; sp; sp = sp -> next) {
		sp -> to.sin_port = local_port;
		sp -> to.sin_family = AF_INET;
#ifdef HAVE_SA_LEN
		sp -> to.sin_len = sizeof sp -> to;
#endif
	}

	/* Get the current time... */
	time(&cur_time);

	/* Discover all the network interfaces. */
	discover_interfaces (DISCOVER_RELAY);

	/* Set up the bootp packet handler... */
	bootp_packet_handler = relay;

	/* Become a daemon... */
	if (!no_daemon) {
		int pid;
		FILE *pf;
		int pfdesc;

		log_perror = 0;

#ifdef __uClinux__
		if ((pid = vfork()) < 0)
#else
		if ((pid = fork()) < 0)
#endif
			log_fatal ("can't fork daemon: %m");
		else if (pid)
			exit (0);

		pfdesc = open (path_dhcrelay_pid,
			       O_CREAT | O_TRUNC | O_WRONLY, 0644);

		if (pfdesc < 0) {
			log_error ("Can't create %s: %m", path_dhcrelay_pid);
		} else {
			pf = fdopen (pfdesc, "w");
			if (!pf)
				log_error ("Can't fdopen %s: %m",
				      path_dhcrelay_pid);
			else {
				fprintf (pf, "%ld\n", (long)getpid ());
				fclose (pf);
			}	
		}

		close (0);
		close (1);
		close (2);
		pid = setsid ();

                chdir("/");
	}

	/* Start dispatching packets and timeouts... */
	dispatch ();

	/*NOTREACHED*/
	return 0;
}
Beispiel #18
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_OBJECT_HANDLE *hKey;
	CK_OBJECT_CLASS kClass = CKO_PUBLIC_KEY;
	CK_KEY_TYPE kType = CKK_RSA;
	CK_ATTRIBUTE kTemplate[] =
	{
		{ CKA_CLASS, &kClass, (CK_ULONG) sizeof(kClass) },
		{ CKA_KEY_TYPE, &kType, (CK_ULONG) sizeof(kType) },
		{ CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
		{ CKA_LABEL, (CK_BYTE_PTR) label, (CK_ULONG) sizeof(label) },
		{ CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
		{ CKA_MODULUS, modulus, (CK_ULONG) sizeof(modulus) },
		{ CKA_PUBLIC_EXPONENT, exponent, (CK_ULONG) sizeof(exponent) }
	};
	pk11_context_t pctx;
	char *lib_name = NULL;
	char *pin = NULL;
	int error = 0;
	int c, errflg = 0;
	int ontoken  = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:p:tn:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			break;
		case 'p':
			pin = isc_commandline_argument;
			break;
		case 't':
			ontoken = 1;
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\tpubrsa [-m module] [-s slot] [-p pin] "
			"[-t] [-n count]\n");
		exit(1);
	}

	/* Allocate hanles */
	hKey = (CK_SESSION_HANDLE *)
		malloc(count * sizeof(CK_SESSION_HANDLE));
	if (hKey == NULL) {
		perror("malloc");
		exit(1);
	}
	for (i = 0; i < count; i++)
		hKey[i] = CK_INVALID_HANDLE;

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	if (pin == NULL)
		pin = getpassphrase("Enter Pin: ");

	result = pk11_get_session(&pctx, OP_ANY, ISC_TRUE, ISC_TRUE,
				  (const char *) pin, slot);
	if (result != ISC_R_SUCCESS) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		free(hKey);
		exit(1);
	}

	if (pin != NULL)
		memset(pin, 0, strlen((char *)pin));

	hSession = pctx.session;

	if (ontoken)
		kTemplate[2].pValue = &truevalue;

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_objects;
	}

	for (i = 0; i < count; i++) {
		(void) snprintf(label, sizeof(label), "obj%u", i);
		kTemplate[4].ulValueLen = strlen(label);
		rv = pkcs_C_CreateObject(hSession, kTemplate, 8, &hKey[i]);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_CreateObject[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			if (i == 0)
				goto exit_objects;
			break;
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_objects;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%u public RSA keys in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g public RSA keys/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_objects:
	for (i = 0; i < count; i++) {
		/* Destroy objects */
		if (hKey[i] == CK_INVALID_HANDLE)
			continue;
		rv = pkcs_C_DestroyObject(hSession, hKey[i]);
		if ((rv != CKR_OK) && !errflg) {
			fprintf(stderr,
				"C_DestroyObject[%u]: Error = 0x%.8lX\n",
				i, rv);
			errflg = 1;
		}
	}

	free(hKey);

	pk11_return_session(&pctx);
	pk11_shutdown();

	exit(error);
}
Beispiel #19
0
isc_result_t
isc_httpdmgr_create(isc_mem_t *mctx, isc_socket_t *sock, isc_task_t *task,
		    isc_httpdclientok_t *client_ok,
		    isc_httpdondestroy_t *ondestroy, void *cb_arg,
		    isc_timermgr_t *tmgr, isc_httpdmgr_t **httpdp)
{
	isc_result_t result;
	isc_httpdmgr_t *httpd;

	REQUIRE(mctx != NULL);
	REQUIRE(sock != NULL);
	REQUIRE(task != NULL);
	REQUIRE(tmgr != NULL);
	REQUIRE(httpdp != NULL && *httpdp == NULL);

	httpd = isc_mem_get(mctx, sizeof(isc_httpdmgr_t));
	if (httpd == NULL)
		return (ISC_R_NOMEMORY);

	result = isc_mutex_init(&httpd->lock);
	if (result != ISC_R_SUCCESS) {
		isc_mem_put(mctx, httpd, sizeof(isc_httpdmgr_t));
		return (result);
	}
	httpd->mctx = NULL;
	isc_mem_attach(mctx, &httpd->mctx);
	httpd->sock = NULL;
	isc_socket_attach(sock, &httpd->sock);
	httpd->task = NULL;
	isc_task_attach(task, &httpd->task);
	httpd->timermgr = tmgr; /* XXXMLG no attach function? */
	httpd->client_ok = client_ok;
	httpd->ondestroy = ondestroy;
	httpd->cb_arg = cb_arg;

	ISC_LIST_INIT(httpd->running);
	ISC_LIST_INIT(httpd->urls);

	/* XXXMLG ignore errors on isc_socket_listen() */
	result = isc_socket_listen(sock, SOMAXCONN);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_socket_listen() failed: %s",
				 isc_result_totext(result));
		goto cleanup;
	}

	(void)isc_socket_filter(sock, "httpready");

	result = isc_socket_accept(sock, task, isc_httpd_accept, httpd);
	if (result != ISC_R_SUCCESS)
		goto cleanup;

	httpd->render_404 = render_404;
	httpd->render_500 = render_500;

	*httpdp = httpd;
	return (ISC_R_SUCCESS);

  cleanup:
	isc_task_detach(&httpd->task);
	isc_socket_detach(&httpd->sock);
	isc_mem_detach(&httpd->mctx);
	isc_mutex_destroy(&httpd->lock);
	isc_mem_put(mctx, httpd, sizeof(isc_httpdmgr_t));
	return (result);
}
Beispiel #20
0
int
main(int argc, char *argv[]) {
	isc_result_t result;
	CK_RV rv;
	CK_SLOT_ID slot = 0;
	CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE;
	CK_ULONG len = sizeof(buf);
	pk11_context_t pctx;
	pk11_optype_t op_type = OP_RAND;
	char *lib_name = NULL;
	int error = 0;
	int c, errflg = 0;
	unsigned int count = 1000;
	unsigned int i;
	struct timespec starttime;
	struct timespec endtime;

	while ((c = isc_commandline_parse(argc, argv, ":m:s:n:")) != -1) {
		switch (c) {
		case 'm':
			lib_name = isc_commandline_argument;
			break;
		case 's':
			slot = atoi(isc_commandline_argument);
			op_type = OP_ANY;
			break;
		case 'n':
			count = atoi(isc_commandline_argument);
			break;
		case ':':
			fprintf(stderr,
				"Option -%c requires an operand\n",
				isc_commandline_option);
			errflg++;
			break;
		case '?':
		default:
			fprintf(stderr, "Unrecognised option: -%c\n",
				isc_commandline_option);
			errflg++;
		}
	}

	if (errflg) {
		fprintf(stderr, "Usage:\n");
		fprintf(stderr,
			"\trandom [-m module] [-s slot] [-n count]\n");
		exit(1);
	}

	pk11_result_register();

	/* Initialize the CRYPTOKI library */
	if (lib_name != NULL)
		pk11_set_lib_name(lib_name);

	result = pk11_get_session(&pctx, op_type, ISC_FALSE, ISC_FALSE,
				  ISC_FALSE, NULL, slot);
	if ((result != ISC_R_SUCCESS) &&
	    (result != PK11_R_NODIGESTSERVICE) &&
	    (result != PK11_R_NOAESSERVICE)) {
		fprintf(stderr, "Error initializing PKCS#11: %s\n",
			isc_result_totext(result));
		exit(1);
	}

	hSession = pctx.session;

	if (clock_gettime(CLOCK_REALTIME, &starttime) < 0) {
		perror("clock_gettime(start)");
		goto exit_session;
	}

	for (i = 0; i < count; i++) {
		/* Get random bytes */
		rv = pkcs_C_GenerateRandom(hSession, buf, len);
		if (rv != CKR_OK) {
			fprintf(stderr,
				"C_GenerateRandom[%u]: Error = 0x%.8lX\n",
				i, rv);
			error = 1;
			break;
		}
	}

	if (clock_gettime(CLOCK_REALTIME, &endtime) < 0) {
		perror("clock_gettime(end)");
		goto exit_session;
	}

	endtime.tv_sec -= starttime.tv_sec;
	endtime.tv_nsec -= starttime.tv_nsec;
	while (endtime.tv_nsec < 0) {
		endtime.tv_sec -= 1;
		endtime.tv_nsec += 1000000000;
	}
	printf("%uK random bytes in %ld.%09lds\n", i,
	       endtime.tv_sec, endtime.tv_nsec);
	if (i > 0)
		printf("%g random bytes/s\n",
		       1024 * i / ((double) endtime.tv_sec +
				   (double) endtime.tv_nsec / 1000000000.));

    exit_session:
	pk11_return_session(&pctx);
	(void) pk11_finalize();

	exit(error);
}
Beispiel #21
0
static void
update_addordelete(isc_mem_t *mctx, char *cmdline, isc_boolean_t isdelete,
		   dns_name_t *name)
{
	isc_result_t result;
	isc_uint32_t ttl;
	char *word;
	dns_rdataclass_t rdataclass;
	dns_rdatatype_t rdatatype;
	dns_rdata_t *rdata = NULL;
	dns_rdatalist_t *rdatalist = NULL;
	dns_rdataset_t *rdataset = NULL;
	isc_textregion_t region;

	/*
	 * Read the owner name.
	 */
	parse_name(&cmdline, name);

	rdata = isc_mem_get(mctx, sizeof(*rdata));
	if (rdata == NULL) {
		fprintf(stderr, "memory allocation for rdata failed\n");
		exit(1);
	}
	dns_rdata_init(rdata);

	/*
	 * If this is an add, read the TTL and verify that it's in range.
	 * If it's a delete, ignore a TTL if present (for compatibility).
	 */
	word = nsu_strsep(&cmdline, " \t\r\n");
	if (word == NULL || *word == 0) {
		if (!isdelete) {
			fprintf(stderr, "could not read owner ttl\n");
			exit(1);
		}
		else {
			ttl = 0;
			rdataclass = dns_rdataclass_any;
			rdatatype = dns_rdatatype_any;
			rdata->flags = DNS_RDATA_UPDATE;
			goto doneparsing;
		}
	}
	result = isc_parse_uint32(&ttl, word, 10);
	if (result != ISC_R_SUCCESS) {
		if (isdelete) {
			ttl = 0;
			goto parseclass;
		} else {
			fprintf(stderr, "ttl '%s': %s\n", word,
				isc_result_totext(result));
			exit(1);
		}
	}

	if (isdelete)
		ttl = 0;
	else if (ttl > TTL_MAX) {
		fprintf(stderr, "ttl '%s' is out of range (0 to %u)\n",
			word, TTL_MAX);
		exit(1);
	}

	/*
	 * Read the class or type.
	 */
	word = nsu_strsep(&cmdline, " \t\r\n");
 parseclass:
	if (word == NULL || *word == 0) {
		if (isdelete) {
			rdataclass = dns_rdataclass_any;
			rdatatype = dns_rdatatype_any;
			rdata->flags = DNS_RDATA_UPDATE;
		goto doneparsing;
		} else {
			fprintf(stderr, "could not read class or type\n");
			exit(1);
		}
	}
	region.base = word;
	region.length = strlen(word);
	result = dns_rdataclass_fromtext(&rdataclass, &region);
	if (result == ISC_R_SUCCESS) {
		/*
		 * Now read the type.
		 */
		word = nsu_strsep(&cmdline, " \t\r\n");
		if (word == NULL || *word == 0) {
			if (isdelete) {
				rdataclass = dns_rdataclass_any;
				rdatatype = dns_rdatatype_any;
				rdata->flags = DNS_RDATA_UPDATE;
				goto doneparsing;
			} else {
				fprintf(stderr, "could not read type\n");
				exit(1);
			}
		}
		region.base = word;
		region.length = strlen(word);
		result = dns_rdatatype_fromtext(&rdatatype, &region);
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "'%s' is not a valid type: %s\n",
				word, isc_result_totext(result));
			exit(1);
		}
	} else {
		rdataclass = default_rdataclass;
		result = dns_rdatatype_fromtext(&rdatatype, &region);
		if (result != ISC_R_SUCCESS) {
			fprintf(stderr, "'%s' is not a valid class or type: "
				"%s\n", word, isc_result_totext(result));
			exit(1);
		}
	}

	parse_rdata(mctx, &cmdline, rdataclass, rdatatype, rdata);

	if (isdelete) {
		if ((rdata->flags & DNS_RDATA_UPDATE) != 0)
			rdataclass = dns_rdataclass_any;
		else
			rdataclass = dns_rdataclass_none;
	} else {
		if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
			fprintf(stderr, "could not read rdata\n");
			exit(1);
		}
	}

 doneparsing:

	rdatalist = isc_mem_get(mctx, sizeof(*rdatalist));
	if (rdatalist == NULL) {
		fprintf(stderr, "memory allocation for rdatalist failed\n");
		exit(1);
	}
	dns_rdatalist_init(rdatalist);
	rdatalist->type = rdatatype;
	rdatalist->rdclass = rdataclass;
	rdatalist->covers = rdatatype;
	rdatalist->ttl = (dns_ttl_t)ttl;
	ISC_LIST_INIT(rdatalist->rdata);
	ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
	ISC_LIST_APPEND(usedrdatalists, rdatalist, link);

	rdataset = isc_mem_get(mctx, sizeof(*rdataset));
	if (rdataset == NULL) {
		fprintf(stderr, "memory allocation for rdataset failed\n");
		exit(1);
	}
	dns_rdataset_init(rdataset);
	dns_rdatalist_tordataset(rdatalist, rdataset);
	ISC_LIST_INIT(name->list);
	ISC_LIST_APPEND(name->list, rdataset, link);
}
Beispiel #22
0
ATF_TC_BODY(deserialize_corrupt, tc) {
	dns_rbt_t *rbt = NULL;
	isc_result_t result;
	FILE *rbtfile = NULL;
	off_t offset;
	int fd;
	off_t filesize = 0;
	char *base, *p, *q;
	isc_uint32_t r;
	int i;

	UNUSED(tc);

	isc_mem_debugging = ISC_MEM_DEBUGRECORD;

	result = dns_test_begin(NULL, ISC_TRUE);
	ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);

	/* Set up map file */
	result = dns_rbt_create(mctx, delete_data, NULL, &rbt);
	ATF_CHECK_EQ(result, ISC_R_SUCCESS);

	add_test_data(mctx, rbt);
	rbtfile = fopen("./zone.bin", "w+b");
	ATF_REQUIRE(rbtfile != NULL);
	result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
					&offset);
	ATF_REQUIRE(result == ISC_R_SUCCESS);
	dns_rbt_destroy(&rbt);

	/* Read back with random fuzzing */
	for (i = 0; i < 256; i++) {
		dns_rbt_t *rbt_deserialized = NULL;

		fd = open("zone.bin", O_RDWR);
		isc_file_getsizefd(fd, &filesize);
		base = mmap(NULL, filesize,
			    PROT_READ|PROT_WRITE,
			    MAP_FILE|MAP_PRIVATE, fd, 0);
		ATF_REQUIRE(base != NULL && base != MAP_FAILED);
		close(fd);

		/* Randomly fuzz a portion of the memory */
		isc_random_get(&r);
		p = base + (r % filesize);
		q = base + filesize;
		isc_random_get(&r);
		q -= (r % (q - p));
		while (p++ < q) {
			isc_random_get(&r);
			*p = r & 0xff;
		}

		result = dns_rbt_deserialize_tree(base, filesize, 0, mctx,
						  delete_data, NULL,
						  fix_data, NULL,
						  NULL, &rbt_deserialized);
		printf("%d: %s\n", i, isc_result_totext(result));

		/* Test to make sure we have a valid tree */
		ATF_REQUIRE(result == ISC_R_SUCCESS ||
			    result == ISC_R_INVALIDFILE);
		if (result != ISC_R_SUCCESS)
			ATF_REQUIRE(rbt_deserialized == NULL);

		if (rbt_deserialized != NULL)
			dns_rbt_destroy(&rbt_deserialized);

		munmap(base, filesize);
	}

	unlink("zone.bin");
	dns_test_end();
}
Beispiel #23
0
isc_result_t
isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
		unsigned int write_quota)
{
	isc_result_t result;

	REQUIRE(rwl != NULL);

	/*
	 * In case there's trouble initializing, we zero magic now.  If all
	 * goes well, we'll set it to RWLOCK_MAGIC.
	 */
	rwl->magic = 0;

	rwl->spins = 0;
#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
	rwl->write_requests = 0;
	rwl->write_completions = 0;
	rwl->cnt_and_flag = 0;
	rwl->readers_waiting = 0;
	rwl->write_granted = 0;
	if (read_quota != 0) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "read quota is not supported");
	}
	if (write_quota == 0)
		write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
	rwl->write_quota = write_quota;
#else
	rwl->type = isc_rwlocktype_read;
	rwl->original = isc_rwlocktype_none;
	rwl->active = 0;
	rwl->granted = 0;
	rwl->readers_waiting = 0;
	rwl->writers_waiting = 0;
	if (read_quota == 0)
		read_quota = RWLOCK_DEFAULT_READ_QUOTA;
	rwl->read_quota = read_quota;
	if (write_quota == 0)
		write_quota = RWLOCK_DEFAULT_WRITE_QUOTA;
	rwl->write_quota = write_quota;
#endif

	result = isc_mutex_init(&rwl->lock);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = isc_condition_init(&rwl->readable);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init(readable) %s: %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"),
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto destroy_lock;
	}
	result = isc_condition_init(&rwl->writeable);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_condition_init(writeable) %s: %s",
				 isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
						ISC_MSG_FAILED, "failed"),
				 isc_result_totext(result));
		result = ISC_R_UNEXPECTED;
		goto destroy_rcond;
	}

	rwl->magic = RWLOCK_MAGIC;

	return (ISC_R_SUCCESS);

  destroy_rcond:
	(void)isc_condition_destroy(&rwl->readable);
  destroy_lock:
	DESTROYLOCK(&rwl->lock);

	return (result);
}
Beispiel #24
0
/*% constructs a sql dbinstance (DBI) */
isc_result_t
sdlzh_build_sqldbinstance(isc_mem_t *mctx, const char *allnodes_str,
			 const char *allowxfr_str, const char *authority_str,
			 const char *findzone_str, const char *lookup_str,
			 const char *countzone_str, dbinstance_t **dbi)
{

	isc_result_t result;
	dbinstance_t *db = NULL;

	REQUIRE(dbi != NULL && *dbi == NULL);
	REQUIRE(mctx != NULL);

	/* allocate and zero memory for driver structure */
	db = isc_mem_get(mctx, sizeof(dbinstance_t));
	if (db == NULL) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not allocate memory for "
			      "database instance object.");
		return (ISC_R_NOMEMORY);
	}
	memset(db, 0, sizeof(dbinstance_t));
	db->dbconn = NULL;
	db->client = NULL;
	db->record = NULL;
	db->zone = NULL;
	db->mctx = NULL;
	db->query_buf = NULL;
	db->allnodes_q = NULL;
	db->allowxfr_q = NULL;
	db->authority_q = NULL;
	db->findzone_q = NULL;
	db->countzone_q = NULL;
	db->lookup_q = NULL;

	/* attach to the memory context */
	isc_mem_attach(mctx, &db->mctx);

	/* initialize the reference count mutex */
	result = isc_mutex_init(&db->instance_lock);
	if (result != ISC_R_SUCCESS) {
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 "isc_mutex_init() failed: %s",
				 isc_result_totext(result));
		goto cleanup;
	}

	/* build the all nodes query list */
	result = build_querylist(mctx, allnodes_str, &db->zone,
				 &db->record, &db->client,
				 &db->allnodes_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build all nodes query list");
		goto cleanup;
	}

	/* build the allow zone transfer query list */
	result = build_querylist(mctx, allowxfr_str, &db->zone,
				 &db->record, &db->client,
				 &db->allowxfr_q,
				 SDLZH_REQUIRE_ZONE | SDLZH_REQUIRE_CLIENT);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build allow xfr query list");
		goto cleanup;
	}

	/* build the authority query, query list */
	result = build_querylist(mctx, authority_str, &db->zone,
				 &db->record, &db->client,
				 &db->authority_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build authority query list");
		goto cleanup;
	}

	/* build findzone query, query list */
	result = build_querylist(mctx, findzone_str, &db->zone,
				 &db->record, &db->client,
				 &db->findzone_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build find zone query list");
		goto cleanup;
	}

	/* build countzone query, query list */
	result = build_querylist(mctx, countzone_str, &db->zone,
				 &db->record, &db->client,
				 &db->countzone_q, SDLZH_REQUIRE_ZONE);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build count zone query list");
		goto cleanup;
	}

	/* build lookup query, query list */
	result = build_querylist(mctx, lookup_str, &db->zone,
				 &db->record, &db->client,
				 &db->lookup_q, SDLZH_REQUIRE_RECORD);
	/* if unsuccessful, log err msg and cleanup */
	if (result != ISC_R_SUCCESS) {
		isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
			      DNS_LOGMODULE_DLZ, ISC_LOG_ERROR,
			      "Could not build lookup query list");
		goto cleanup;
	}

	/* pass back the db instance */
	*dbi = (dbinstance_t *) db;

	/* return success */
	return (ISC_R_SUCCESS);

 cleanup:
	/* destroy whatever was build of the db instance */
	destroy_sqldbinstance(db);
	/* return failure */
	return (ISC_R_FAILURE);
}
Beispiel #25
0
static isc_result_t ddns_remove_ptr (struct data_string *ddns_rev_name)
{
	ns_updque updqueue;
	ns_updrec *updrec;
	isc_result_t result;

	/*
	 * When a lease expires or a DHCP client issues a DHCPRELEASE request,
	 * the DHCP server SHOULD delete the PTR RR that matches the DHCP
	 * binding, if one was successfully added. The server's update query
	 * SHOULD assert that the name in the PTR record matches the name of
	 * the client whose lease has expired or been released.
	 *   -- "Interaction between DHCP and DNS"
	 */

	ISC_LIST_INIT (updqueue);

	/*
	 * Delete the PTR RRset for the leased address.
	 */
	updrec = minires_mkupdrec (S_UPDATE,
				   (const char *)ddns_rev_name -> data,
				   C_IN, T_PTR, 0);
	if (!updrec) {
		result = ISC_R_NOMEMORY;
		goto error;
	}

	updrec -> r_data = (unsigned char *)0;
	updrec -> r_size = 0;
	updrec -> r_opcode = DELETE;

	ISC_LIST_APPEND (updqueue, updrec, r_link);

	/*
	 * Attempt to perform the update.
	 */
	result = minires_nupdate (&resolver_state, ISC_LIST_HEAD (updqueue));
#if defined (DEBUG)
	print_dns_status ((int)result, &updqueue);
#endif
	if (result == ISC_R_SUCCESS) {
		log_info ("removed reverse map on %.*s",
			  (int)ddns_rev_name -> len,
			  (const char *)ddns_rev_name -> data);
	} else {
		if (result != ISC_R_NXRRSET && result != ISC_R_NXDOMAIN)
			log_error ("can't remove reverse map on %.*s: %s",
				   (int)ddns_rev_name -> len,
				   (const char *)ddns_rev_name -> data,
				   isc_result_totext (result));
	}

	/* Not there is success. */
	if (result == ISC_R_NXRRSET || result == ISC_R_NXDOMAIN)
		result = ISC_R_SUCCESS;

	/* Fall through. */
      error:

	while (!ISC_LIST_EMPTY (updqueue)) {
		if((updqueue).head){
			updrec = ISC_LIST_HEAD (updqueue);
			ISC_LIST_UNLINK (updqueue, updrec, r_link);
			minires_freeupdrec (updrec);
		}
	}

	return result;
}
int
main(int argc, char **argv) {
	char		*algname = NULL, *classname = NULL;
	char		*filename = NULL, *dir = NULL, *namestr;
	char		*lookaside = NULL;
	char		*endp;
	int		ch;
	unsigned int	dtype = DNS_DSDIGEST_SHA1;
	isc_boolean_t	both = ISC_TRUE;
	isc_boolean_t	usekeyset = ISC_FALSE;
	isc_boolean_t	showall = ISC_FALSE;
	isc_result_t	result;
	isc_log_t	*log = NULL;
	isc_entropy_t	*ectx = NULL;
	dns_rdataset_t	rdataset;
	dns_rdata_t	rdata;

	dns_rdata_init(&rdata);

	if (argc == 1)
		usage();

	result = isc_mem_create(0, 0, &mctx);
	if (result != ISC_R_SUCCESS)
		fatal("out of memory");

#ifdef PKCS11CRYPTO
	pk11_result_register();
#endif
	dns_result_register();

	isc_commandline_errprint = ISC_FALSE;

	while ((ch = isc_commandline_parse(argc, argv,
					   "12Aa:c:d:Ff:K:l:sT:v:hV")) != -1) {
		switch (ch) {
		case '1':
			dtype = DNS_DSDIGEST_SHA1;
			both = ISC_FALSE;
			break;
		case '2':
			dtype = DNS_DSDIGEST_SHA256;
			both = ISC_FALSE;
			break;
		case 'A':
			showall = ISC_TRUE;
			break;
		case 'a':
			algname = isc_commandline_argument;
			both = ISC_FALSE;
			break;
		case 'c':
			classname = isc_commandline_argument;
			break;
		case 'd':
			fprintf(stderr, "%s: the -d option is deprecated; "
					"use -K\n", program);
			/* fall through */
		case 'K':
			dir = isc_commandline_argument;
			if (strlen(dir) == 0U)
				fatal("directory must be non-empty string");
			break;
		case 'f':
			filename = isc_commandline_argument;
			break;
		case 'l':
			lookaside = isc_commandline_argument;
			if (strlen(lookaside) == 0U)
				fatal("lookaside must be a non-empty string");
			break;
		case 's':
			usekeyset = ISC_TRUE;
			break;
		case 'T':
			emitttl = ISC_TRUE;
			ttl = atol(isc_commandline_argument);
			break;
		case 'v':
			verbose = strtol(isc_commandline_argument, &endp, 0);
			if (*endp != '\0')
				fatal("-v must be followed by a number");
			break;
		case 'F':
			/* Reserved for FIPS mode */
			/* FALLTHROUGH */
		case '?':
			if (isc_commandline_option != '?')
				fprintf(stderr, "%s: invalid argument -%c\n",
					program, isc_commandline_option);
			/* FALLTHROUGH */
		case 'h':
			/* Does not return. */
			usage();

		case 'V':
			/* Does not return. */
			version(program);

		default:
			fprintf(stderr, "%s: unhandled option -%c\n",
				program, isc_commandline_option);
			exit(1);
		}
	}

	if (algname != NULL) {
		if (strcasecmp(algname, "SHA1") == 0 ||
		    strcasecmp(algname, "SHA-1") == 0)
			dtype = DNS_DSDIGEST_SHA1;
		else if (strcasecmp(algname, "SHA256") == 0 ||
			 strcasecmp(algname, "SHA-256") == 0)
			dtype = DNS_DSDIGEST_SHA256;
#if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
		else if (strcasecmp(algname, "GOST") == 0)
			dtype = DNS_DSDIGEST_GOST;
#endif
		else if (strcasecmp(algname, "SHA384") == 0 ||
			 strcasecmp(algname, "SHA-384") == 0)
			dtype = DNS_DSDIGEST_SHA384;
		else
			fatal("unknown algorithm %s", algname);
	}

	rdclass = strtoclass(classname);

	if (usekeyset && filename != NULL)
		fatal("cannot use both -s and -f");

	/* When not using -f, -A is implicit */
	if (filename == NULL)
		showall = ISC_TRUE;

	if (argc < isc_commandline_index + 1 && filename == NULL)
		fatal("the key file name was not specified");
	if (argc > isc_commandline_index + 1)
		fatal("extraneous arguments");

	if (ectx == NULL)
		setup_entropy(mctx, NULL, &ectx);
	result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
	if (result != ISC_R_SUCCESS)
		fatal("could not initialize hash");
	result = dst_lib_init(mctx, ectx,
			      ISC_ENTROPY_BLOCKING | ISC_ENTROPY_GOODONLY);
	if (result != ISC_R_SUCCESS)
		fatal("could not initialize dst: %s",
		      isc_result_totext(result));
	isc_entropy_stopcallbacksources(ectx);

	setup_logging(mctx, &log);

	dns_rdataset_init(&rdataset);

	if (usekeyset || filename != NULL) {
		if (argc < isc_commandline_index + 1 && filename != NULL) {
			/* using zone name as the zone file name */
			namestr = filename;
		} else
			namestr = argv[isc_commandline_index];

		result = initname(namestr);
		if (result != ISC_R_SUCCESS)
			fatal("could not initialize name %s", namestr);

		if (usekeyset)
			result = loadkeyset(dir, &rdataset);
		else
			result = loadset(filename, &rdataset);

		if (result != ISC_R_SUCCESS)
			fatal("could not load DNSKEY set: %s\n",
			      isc_result_totext(result));

		for (result = dns_rdataset_first(&rdataset);
		     result == ISC_R_SUCCESS;
		     result = dns_rdataset_next(&rdataset)) {
			dns_rdata_init(&rdata);
			dns_rdataset_current(&rdataset, &rdata);

			if (verbose > 2)
				logkey(&rdata);

			if (both) {
				emit(DNS_DSDIGEST_SHA1, showall, lookaside,
				     &rdata);
				emit(DNS_DSDIGEST_SHA256, showall, lookaside,
				     &rdata);
			} else
				emit(dtype, showall, lookaside, &rdata);
		}
	} else {
		unsigned char key_buf[DST_KEY_MAXSIZE];

		loadkey(argv[isc_commandline_index], key_buf,
			DST_KEY_MAXSIZE, &rdata);

		if (both) {
			emit(DNS_DSDIGEST_SHA1, showall, lookaside, &rdata);
			emit(DNS_DSDIGEST_SHA256, showall, lookaside, &rdata);
		} else
			emit(dtype, showall, lookaside, &rdata);
	}

	if (dns_rdataset_isassociated(&rdataset))
		dns_rdataset_disassociate(&rdataset);
	cleanup_logging(&log);
	dst_lib_destroy();
	isc_hash_destroy();
	cleanup_entropy(&ectx);
	dns_name_destroy();
	if (verbose > 10)
		isc_mem_stats(mctx, stdout);
	isc_mem_destroy(&mctx);

	fflush(stdout);
	if (ferror(stdout)) {
		fprintf(stderr, "write error\n");
		return (1);
	} else
		return (0);
}
Beispiel #27
0
static isc_result_t
ns_interface_create(ns_interfacemgr_t *mgr, isc_sockaddr_t *addr,
		    const char *name, ns_interface_t **ifpret)
{
	ns_interface_t *ifp;
	isc_result_t result;

	REQUIRE(NS_INTERFACEMGR_VALID(mgr));
	ifp = isc_mem_get(mgr->mctx, sizeof(*ifp));
	if (ifp == NULL)
		return (ISC_R_NOMEMORY);
	ifp->mgr = NULL;
	ifp->generation = mgr->generation;
	ifp->addr = *addr;
	ifp->flags = 0;
	strncpy(ifp->name, name, sizeof(ifp->name));
	ifp->name[sizeof(ifp->name)-1] = '\0';
	ifp->clientmgr = NULL;

	result = isc_mutex_init(&ifp->lock);
	if (result != ISC_R_SUCCESS)
		goto lock_create_failure;

	result = ns_clientmgr_create(mgr->mctx, mgr->taskmgr,
				     ns_g_timermgr,
				     &ifp->clientmgr);
	if (result != ISC_R_SUCCESS) {
		isc_log_write(IFMGR_COMMON_LOGARGS, ISC_LOG_ERROR,
			      "ns_clientmgr_create() failed: %s",
			      isc_result_totext(result));
		goto clientmgr_create_failure;
	}

	ifp->udpdispatch = NULL;

	ifp->tcpsocket = NULL;
	/*
	 * Create a single TCP client object.  It will replace itself
	 * with a new one as soon as it gets a connection, so the actual
	 * connections will be handled in parallel even though there is
	 * only one client initially.
	 */
	ifp->ntcptarget = 1;
	ifp->ntcpcurrent = 0;

	ISC_LINK_INIT(ifp, link);

	ns_interfacemgr_attach(mgr, &ifp->mgr);
	ISC_LIST_APPEND(mgr->interfaces, ifp, link);

	ifp->references = 1;
	ifp->magic = IFACE_MAGIC;
	*ifpret = ifp;

	return (ISC_R_SUCCESS);

 clientmgr_create_failure:
	DESTROYLOCK(&ifp->lock);
 lock_create_failure:
	ifp->magic = 0;
	isc_mem_put(mgr->mctx, ifp, sizeof(*ifp));

	return (ISC_R_UNEXPECTED);
}
Beispiel #28
0
void trace_interface_input (trace_type_t *ttype, unsigned len, char *buf)
{
	trace_interface_packet_t *tipkt;
	struct interface_info *ip;
	struct sockaddr_in *sin;
	struct iaddr addr;
	isc_result_t status;

	if (len != sizeof *tipkt) {
		log_error ("trace interface packet size mismatch: %ld != %d",
			   (long)(sizeof *tipkt), len);
		return;
	}
	tipkt = (trace_interface_packet_t *)buf;
	
	ip = (struct interface_info *)0;
	status = interface_allocate (&ip, MDL);
	if (status != ISC_R_SUCCESS) {
	      foo:
		log_error ("trace_interface_input: %s.",
			   isc_result_totext (status));
		return;
	}
	ip -> ifp = dmalloc (sizeof *(ip -> ifp), MDL);
	if (!ip -> ifp) {
		interface_dereference (&ip, MDL);
		status = ISC_R_NOMEMORY;
		goto foo;
	}

	memcpy (&ip -> hw_address, &tipkt -> hw_address,
		sizeof ip -> hw_address);
	/* XXX: Without the full addresses state it's not quite a full
	 * trace.
	 */
	ip->address_count = ip->address_max = 1;
	ip->addresses = dmalloc(sizeof(*ip->addresses), MDL);
	memcpy(ip->addresses, &tipkt->primary_address, sizeof(*ip->addresses));
	memcpy (ip -> name, tipkt -> name, sizeof ip -> name);
	ip -> index = ntohl (tipkt -> index);

	interface_snorf (ip, 0);
	if (dhcp_interface_discovery_hook)
		(*dhcp_interface_discovery_hook) (ip);

	/* Fake up an ifp. */
	memcpy (ip -> ifp -> ifr_name, ip -> name, sizeof ip -> name);
#ifdef HAVE_SA_LEN
	ip -> ifp -> ifr_addr.sa_len = sizeof (struct sockaddr_in);
#endif
	sin = (struct sockaddr_in *)&ip -> ifp -> ifr_addr;
	sin->sin_addr = ip->addresses[0];

	addr.len = 4;
	memcpy (addr.iabuf, &sin -> sin_addr.s_addr, addr.len);
	if (dhcp_interface_setup_hook)
		(*dhcp_interface_setup_hook) (ip, &addr);
	interface_stash (ip);

	if (!quiet_interface_discovery) {
		log_info ("Listening on Trace/%s/%s%s%s",
			  ip -> name,
			  print_hw_addr (ip -> hw_address.hbuf [0],
					 ip -> hw_address.hlen - 1,
					 &ip -> hw_address.hbuf [1]),
			  (ip -> shared_network ? "/" : ""),
			  (ip -> shared_network ?
			   ip -> shared_network -> name : ""));
		if (strcmp (ip -> name, "fallback")) {
			log_info ("Sending   on Trace/%s/%s%s%s",
				  ip -> name,
				  print_hw_addr (ip -> hw_address.hbuf [0],
						 ip -> hw_address.hlen - 1,
						 &ip -> hw_address.hbuf [1]),
				  (ip -> shared_network ? "/" : ""),
				  (ip -> shared_network ?
				   ip -> shared_network -> name : ""));
		}
	}
	interface_dereference (&ip, MDL);
}
Beispiel #29
0
static void
t_timers_x(isc_timertype_t timertype, isc_time_t *expires,
	   isc_interval_t *interval,
	   void (*action)(isc_task_t *, isc_event_t *))
{
	char		*p;
	isc_mem_t	*mctx;
	isc_taskmgr_t	*tmgr;
	isc_task_t	*task;
	unsigned int	workers;
	isc_result_t	isc_result;
	isc_timermgr_t	*timermgr;

	Tx_eventcnt = 0;
	isc_time_settoepoch(&Tx_endtime);

	workers = 2;
	p = t_getenv("ISC_TASK_WORKERS");
	if (p != NULL)
		workers = atoi(p);

	mctx = NULL;
	isc_result = isc_mem_create(0, 0, &mctx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mem_create failed %s\n",
		       isc_result_totext(isc_result));
		++Tx_nprobs;
		return;
	}

	isc_result = isc_mutex_init(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_init failed %s\n",
		       isc_result_totext(isc_result));
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_condition_init(&Tx_cv);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_condition_init failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&Tx_mx);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	tmgr = NULL;
	isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_taskmgr_create failed %s\n",
		       isc_result_totext(isc_result));
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	timermgr = NULL;
	isc_result = isc_timermgr_create(mctx, &timermgr);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_timermgr_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_mutex_lock(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_lock failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	task = NULL;
	isc_result = isc_task_create(tmgr, 0, &task);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_create failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_task_onshutdown(task, tx_sde, NULL);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_task_onshutdown failed %s\n",
		       isc_result_totext(isc_result));
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	isc_result = isc_time_now(&Tx_lasttime);
	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	Tx_timer = NULL;
	isc_result = isc_timer_create(timermgr, timertype, expires, interval,
				      task, action, (void *)timertype,
				      &Tx_timer);

	if (isc_result != ISC_R_SUCCESS) {
		isc_timermgr_destroy(&timermgr);
		isc_task_destroy(&task);
		isc_taskmgr_destroy(&tmgr);
		DESTROYLOCK(&Tx_mx);
		(void) isc_condition_destroy(&Tx_cv);
		isc_mem_destroy(&mctx);
		++Tx_nprobs;
		return;
	}

	/*
	 * Wait for shutdown processing to complete.
	 */
	while (Tx_eventcnt != Tx_nevents) {
		isc_result = isc_condition_wait(&Tx_cv, &Tx_mx);
		if (isc_result != ISC_R_SUCCESS) {
			t_info("isc_condition_waituntil failed %s\n",
			       isc_result_totext(isc_result));
			++Tx_nprobs;
		}
	}

	isc_result = isc_mutex_unlock(&Tx_mx);
	if (isc_result != ISC_R_SUCCESS) {
		t_info("isc_mutex_unlock failed %s\n",
		       isc_result_totext(isc_result));
		++Tx_nprobs;
	}

	isc_task_detach(&task);
	isc_taskmgr_destroy(&tmgr);
	isc_timermgr_destroy(&timermgr);
	DESTROYLOCK(&Tx_mx);
	(void) isc_condition_destroy(&Tx_cv);
	isc_mem_destroy(&mctx);

}
Beispiel #30
0
static void
control_recvmessage(isc_task_t *task, isc_event_t *event) {
	controlconnection_t *conn;
	controllistener_t *listener;
	controlkey_t *key;
	isccc_sexpr_t *request = NULL;
	isccc_sexpr_t *response = NULL;
	isccc_region_t ccregion;
	isc_uint32_t algorithm;
	isccc_region_t secret;
	isc_stdtime_t now;
	isc_buffer_t b;
	isc_region_t r;
	isc_uint32_t len;
	isc_buffer_t text;
	char textarray[2*1024];
	isc_result_t result;
	isc_result_t eresult;
	isccc_sexpr_t *_ctrl;
	isccc_time_t sent;
	isccc_time_t exp;
	isc_uint32_t nonce;

	REQUIRE(event->ev_type == ISCCC_EVENT_CCMSG);

	conn = event->ev_arg;
	listener = conn->listener;
	algorithm = DST_ALG_UNKNOWN;
	secret.rstart = NULL;

	/* Is the server shutting down? */
	if (listener->controls->shuttingdown)
		goto cleanup;

	if (conn->ccmsg.result != ISC_R_SUCCESS) {
		if (conn->ccmsg.result != ISC_R_CANCELED &&
		    conn->ccmsg.result != ISC_R_EOF)
			log_invalid(&conn->ccmsg, conn->ccmsg.result);
		goto cleanup;
	}

	request = NULL;

	for (key = ISC_LIST_HEAD(listener->keys);
	     key != NULL;
	     key = ISC_LIST_NEXT(key, link))
	{
		ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer);
		ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer);
		secret.rstart = isc_mem_get(listener->mctx, key->secret.length);
		if (secret.rstart == NULL)
			goto cleanup;
		memmove(secret.rstart, key->secret.base, key->secret.length);
		secret.rend = secret.rstart + key->secret.length;
		algorithm = key->algorithm;
		result = isccc_cc_fromwire(&ccregion, &request,
					   algorithm, &secret);
		if (result == ISC_R_SUCCESS)
			break;
		isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret));
		if (result != ISCCC_R_BADAUTH) {
			log_invalid(&conn->ccmsg, result);
			goto cleanup;
		}
	}

	if (key == NULL) {
		log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH);
		goto cleanup;
	}

	/* We shouldn't be getting a reply. */
	if (isccc_cc_isreply(request)) {
		log_invalid(&conn->ccmsg, ISC_R_FAILURE);
		goto cleanup_request;
	}

	isc_stdtime_get(&now);

	/*
	 * Limit exposure to replay attacks.
	 */
	_ctrl = isccc_alist_lookup(request, "_ctrl");
	if (!isccc_alist_alistp(_ctrl)) {
		log_invalid(&conn->ccmsg, ISC_R_FAILURE);
		goto cleanup_request;
	}

	if (isccc_cc_lookupuint32(_ctrl, "_tim", &sent) == ISC_R_SUCCESS) {
		if ((sent + CLOCKSKEW) < now || (sent - CLOCKSKEW) > now) {
			log_invalid(&conn->ccmsg, ISCCC_R_CLOCKSKEW);
			goto cleanup_request;
		}
	} else {
		log_invalid(&conn->ccmsg, ISC_R_FAILURE);
		goto cleanup_request;
	}

	/*
	 * Expire messages that are too old.
	 */
	if (isccc_cc_lookupuint32(_ctrl, "_exp", &exp) == ISC_R_SUCCESS &&
	    now > exp) {
		log_invalid(&conn->ccmsg, ISCCC_R_EXPIRED);
		goto cleanup_request;
	}

	/*
	 * Duplicate suppression (required for UDP).
	 */
	isccc_cc_cleansymtab(listener->controls->symtab, now);
	result = isccc_cc_checkdup(listener->controls->symtab, request, now);
	if (result != ISC_R_SUCCESS) {
		if (result == ISC_R_EXISTS)
			result = ISCCC_R_DUPLICATE;
		log_invalid(&conn->ccmsg, result);
		goto cleanup_request;
	}

	if (conn->nonce != 0 &&
	    (isccc_cc_lookupuint32(_ctrl, "_nonce", &nonce) != ISC_R_SUCCESS ||
	     conn->nonce != nonce)) {
		log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH);
		goto cleanup_request;
	}

	isc_buffer_init(&text, textarray, sizeof(textarray));

	/*
	 * Establish nonce.
	 */
	if (conn->nonce == 0) {
		while (conn->nonce == 0)
			isc_random_get(&conn->nonce);
		eresult = ISC_R_SUCCESS;
	} else
		eresult = ns_control_docommand(request, &text);

	result = isccc_cc_createresponse(request, now, now + 60, &response);
	if (result != ISC_R_SUCCESS)
		goto cleanup_request;
	if (eresult != ISC_R_SUCCESS) {
		isccc_sexpr_t *data;

		data = isccc_alist_lookup(response, "_data");
		if (data != NULL) {
			const char *estr = isc_result_totext(eresult);
			if (isccc_cc_definestring(data, "err", estr) == NULL)
				goto cleanup_response;
		}
	}

	if (isc_buffer_usedlength(&text) > 0) {
		isccc_sexpr_t *data;

		data = isccc_alist_lookup(response, "_data");
		if (data != NULL) {
			char *str = (char *)isc_buffer_base(&text);
			if (isccc_cc_definestring(data, "text", str) == NULL)
				goto cleanup_response;
		}
	}

	_ctrl = isccc_alist_lookup(response, "_ctrl");
	if (_ctrl == NULL ||
	    isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL)
		goto cleanup_response;

	ccregion.rstart = conn->buffer + 4;
	ccregion.rend = conn->buffer + sizeof(conn->buffer);
	result = isccc_cc_towire(response, &ccregion, algorithm, &secret);
	if (result != ISC_R_SUCCESS)
		goto cleanup_response;
	isc_buffer_init(&b, conn->buffer, 4);
	len = sizeof(conn->buffer) - REGION_SIZE(ccregion);
	isc_buffer_putuint32(&b, len - 4);
	r.base = conn->buffer;
	r.length = len;

	result = isc_socket_send(conn->sock, &r, task, control_senddone, conn);
	if (result != ISC_R_SUCCESS)
		goto cleanup_response;
	conn->sending = ISC_TRUE;

	isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret));
	isccc_sexpr_free(&request);
	isccc_sexpr_free(&response);
	return;

 cleanup_response:
	isccc_sexpr_free(&response);

 cleanup_request:
	isccc_sexpr_free(&request);
	isc_mem_put(listener->mctx, secret.rstart, REGION_SIZE(secret));

 cleanup:
	isc_socket_detach(&conn->sock);
	isccc_ccmsg_invalidate(&conn->ccmsg);
	conn->ccmsg_valid = ISC_FALSE;
	maybe_free_connection(conn);
	maybe_free_listener(listener);
}