static void ratelimiter_free(isc_ratelimiter_t *rl) { DESTROYLOCK(&rl->lock); isc_mem_put(rl->mctx, rl, sizeof(*rl)); }
isc_result_t dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm, dst_key_t *dstkey, isc_boolean_t generated, dns_name_t *creator, isc_stdtime_t inception, isc_stdtime_t expire, isc_mem_t *mctx, dns_tsig_keyring_t *ring, dns_tsigkey_t **key) { dns_tsigkey_t *tkey; isc_result_t ret; unsigned int refs = 0; REQUIRE(key == NULL || *key == NULL); REQUIRE(name != NULL); REQUIRE(algorithm != NULL); REQUIRE(mctx != NULL); REQUIRE(key != NULL || ring != NULL); tkey = (dns_tsigkey_t *) isc_mem_get(mctx, sizeof(dns_tsigkey_t)); if (tkey == NULL) return (ISC_R_NOMEMORY); dns_name_init(&tkey->name, NULL); ret = dns_name_dup(name, mctx, &tkey->name); if (ret != ISC_R_SUCCESS) goto cleanup_key; (void)dns_name_downcase(&tkey->name, &tkey->name, NULL); if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { tkey->algorithm = DNS_TSIG_HMACMD5_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA1_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA1) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA224_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA224) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA256_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA256) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA384_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA384) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) { tkey->algorithm = DNS_TSIG_HMACSHA512_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA512) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPI_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME; if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) { ret = DNS_R_BADALG; goto cleanup_name; } } else { if (dstkey != NULL) { ret = DNS_R_BADALG; goto cleanup_name; } tkey->algorithm = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->algorithm == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_name; } dns_name_init(tkey->algorithm, NULL); ret = dns_name_dup(algorithm, mctx, tkey->algorithm); if (ret != ISC_R_SUCCESS) goto cleanup_algorithm; (void)dns_name_downcase(tkey->algorithm, tkey->algorithm, NULL); } if (creator != NULL) { tkey->creator = isc_mem_get(mctx, sizeof(dns_name_t)); if (tkey->creator == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_algorithm; } dns_name_init(tkey->creator, NULL); ret = dns_name_dup(creator, mctx, tkey->creator); if (ret != ISC_R_SUCCESS) { isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); goto cleanup_algorithm; } } else tkey->creator = NULL; tkey->key = NULL; if (dstkey != NULL) dst_key_attach(dstkey, &tkey->key); tkey->ring = ring; if (key != NULL) refs = 1; if (ring != NULL) refs++; ret = isc_refcount_init(&tkey->refs, refs); if (ret != ISC_R_SUCCESS) goto cleanup_creator; tkey->generated = generated; tkey->inception = inception; tkey->expire = expire; tkey->mctx = NULL; isc_mem_attach(mctx, &tkey->mctx); ISC_LINK_INIT(tkey, link); tkey->magic = TSIG_MAGIC; if (ring != NULL) { ret = keyring_add(ring, name, tkey); if (ret != ISC_R_SUCCESS) goto cleanup_refs; } /* * Ignore this if it's a GSS key, since the key size is meaningless. */ if (dstkey != NULL && dst_key_size(dstkey) < 64 && !dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME) && !dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_TSIG, ISC_LOG_INFO, "the key '%s' is too short to be secure", namestr); } if (key != NULL) *key = tkey; return (ISC_R_SUCCESS); cleanup_refs: tkey->magic = 0; while (refs-- > 0) isc_refcount_decrement(&tkey->refs, NULL); isc_refcount_destroy(&tkey->refs); cleanup_creator: if (tkey->key != NULL) dst_key_free(&tkey->key); if (tkey->creator != NULL) { dns_name_free(tkey->creator, mctx); isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); } cleanup_algorithm: if (algname_is_allocated(tkey->algorithm)) { if (dns_name_dynamic(tkey->algorithm)) dns_name_free(tkey->algorithm, mctx); isc_mem_put(mctx, tkey->algorithm, sizeof(dns_name_t)); } cleanup_name: dns_name_free(&tkey->name, mctx); cleanup_key: isc_mem_put(mctx, tkey, sizeof(dns_tsigkey_t)); return (ret); }
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); (void)isc_mutex_destroy(&httpd->lock); isc_mem_put(mctx, httpd, sizeof(isc_httpdmgr_t)); return (result); }
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->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; #ifdef BIND9 view->zonetable = NULL; 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->dampening = NULL; view->dlzdatabase = NULL; view->hints = NULL; view->resolver = NULL; view->adb = NULL; view->requestmgr = NULL; view->mctx = mctx; 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->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_put(mctx, view, sizeof(*view)); return (result); }
void dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp) { isc_mem_put(mctx, *ctrp, DNS_STATS_NCOUNTERS * sizeof(isc_uint64_t)); *ctrp = NULL; }
void isc_timermgr_destroy(isc_timermgr_t **managerp) { isc_timermgr_t *manager; isc_mem_t *mctx; /* * Destroy a timer manager. */ REQUIRE(managerp != NULL); manager = *managerp; REQUIRE(VALID_MANAGER(manager)); LOCK(&manager->lock); #ifndef ISC_PLATFORM_USETHREADS if (manager->refs > 1) { manager->refs--; UNLOCK(&manager->lock); *managerp = NULL; return; } isc__timermgr_dispatch(); #endif /* ISC_PLATFORM_USETHREADS */ REQUIRE(EMPTY(manager->timers)); manager->done = ISC_TRUE; #ifdef ISC_PLATFORM_USETHREADS XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TIMER, ISC_MSG_SIGNALDESTROY, "signal (destroy)")); SIGNAL(&manager->wakeup); #endif /* ISC_PLATFORM_USETHREADS */ UNLOCK(&manager->lock); #ifdef ISC_PLATFORM_USETHREADS /* * Wait for thread to exit. */ if (isc_thread_join(manager->thread, NULL) != ISC_R_SUCCESS) UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_join() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); #endif /* ISC_PLATFORM_USETHREADS */ /* * Clean up. */ #ifdef ISC_PLATFORM_USETHREADS (void)isc_condition_destroy(&manager->wakeup); #endif /* ISC_PLATFORM_USETHREADS */ DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); manager->magic = 0; mctx = manager->mctx; isc_mem_put(mctx, manager, sizeof(*manager)); isc_mem_detach(&mctx); *managerp = NULL; }
isc_result_t ns_lwdclientmgr_create(ns_lwreslistener_t *listener, unsigned int nclients, isc_taskmgr_t *taskmgr) { ns_lwresd_t *lwresd = listener->manager; ns_lwdclientmgr_t *cm; ns_lwdclient_t *client; unsigned int i; isc_result_t result = ISC_R_FAILURE; cm = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclientmgr_t)); if (cm == NULL) return (ISC_R_NOMEMORY); cm->listener = NULL; ns_lwreslistener_attach(listener, &cm->listener); cm->mctx = lwresd->mctx; cm->sock = NULL; isc_socket_attach(listener->sock, &cm->sock); cm->view = lwresd->view; cm->lwctx = NULL; cm->task = NULL; cm->flags = 0; ISC_LINK_INIT(cm, link); ISC_LIST_INIT(cm->idle); ISC_LIST_INIT(cm->running); if (lwres_context_create(&cm->lwctx, cm->mctx, ns__lwresd_memalloc, ns__lwresd_memfree, LWRES_CONTEXT_SERVERMODE) != ISC_R_SUCCESS) goto errout; for (i = 0; i < nclients; i++) { client = isc_mem_get(lwresd->mctx, sizeof(ns_lwdclient_t)); if (client != NULL) { ns_lwdclient_log(50, "created client %p, manager %p", client, cm); ns_lwdclient_initialize(client, cm); } } /* * If we could create no clients, clean up and return. */ if (ISC_LIST_EMPTY(cm->idle)) goto errout; result = isc_task_create(taskmgr, 0, &cm->task); if (result != ISC_R_SUCCESS) goto errout; /* * This MUST be last, since there is no way to cancel an onshutdown... */ result = isc_task_onshutdown(cm->task, lwdclientmgr_shutdown_callback, cm); if (result != ISC_R_SUCCESS) goto errout; ns_lwreslistener_linkcm(listener, cm); return (ISC_R_SUCCESS); errout: client = ISC_LIST_HEAD(cm->idle); while (client != NULL) { ISC_LIST_UNLINK(cm->idle, client, link); isc_mem_put(lwresd->mctx, client, sizeof(*client)); client = ISC_LIST_HEAD(cm->idle); } if (cm->task != NULL) isc_task_detach(&cm->task); if (cm->lwctx != NULL) lwres_context_destroy(&cm->lwctx); isc_mem_put(lwresd->mctx, cm, sizeof(*cm)); return (result); }
static isc_result_t getbuf6(isc_interfaceiter_t *iter) { char strbuf[ISC_STRERRORSIZE]; isc_result_t result; iter->bufsize6 = IFCONF_BUFSIZE_INITIAL; for (;;) { iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6); if (iter->buf6 == NULL) return (ISC_R_NOMEMORY); memset(&iter->lifc, 0, sizeof(iter->lifc)); #ifdef ISC_HAVE_LIFC_FAMILY iter->lifc.lifc_family = AF_INET6; #endif #ifdef ISC_HAVE_LIFC_FLAGS iter->lifc.lifc_flags = 0; #endif iter->lifc.lifc_len = iter->bufsize6; iter->lifc.lifc_buf = iter->buf6; /* * Ignore the HP/UX warning about "integer overflow during * conversion". It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc) == -1) { #ifdef __hpux /* * IPv6 interface scanning is not available on all * kernels w/ IPv6 sockets. */ if (errno == ENOENT) { isc__strerror(errno, strbuf, sizeof(strbuf)); isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL, ISC_LOGMODULE_INTERFACE, ISC_LOG_DEBUG(1), isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "get interface " "configuration: %s"), strbuf); result = ISC_R_FAILURE; goto cleanup; } #endif if (errno != EINVAL) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "get interface " "configuration: %s"), strbuf); result = ISC_R_UNEXPECTED; goto cleanup; } /* * EINVAL. Retry with a bigger buffer. */ } else { /* * The ioctl succeeded. * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If * ifc.ifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ) < iter->bufsize6) break; } if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) { UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_BUFFERMAX, "get interface " "configuration: " "maximum buffer " "size exceeded")); result = ISC_R_UNEXPECTED; goto cleanup; } isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); iter->bufsize6 *= 2; } if (iter->lifc.lifc_len != 0) iter->mode = 6; return (ISC_R_SUCCESS); cleanup: isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6); iter->buf6 = NULL; return (result); }
isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; isc_result_t result; char strbuf[ISC_STRERRORSIZE]; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->mode = 4; iter->buf = NULL; iter->pos = (unsigned int) -1; #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) iter->buf6 = NULL; iter->pos6 = (unsigned int) -1; iter->result6 = ISC_R_NOMORE; iter->socket6 = -1; iter->first6 = ISC_FALSE; #endif /* * Get the interface configuration, allocating more memory if * necessary. */ #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) result = isc_net_probeipv6(); if (result == ISC_R_SUCCESS) { /* * Create an unbound datagram socket to do the SIOCGLIFCONF * ioctl on. HP/UX requires an AF_INET6 socket for * SIOCGLIFCONF to get IPv6 addresses. */ if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_MAKESCANSOCKET, "making interface " "scan socket: %s"), strbuf); result = ISC_R_UNEXPECTED; goto socket6_failure; } result = iter->result6 = getbuf6(iter); if (result != ISC_R_NOTIMPLEMENTED && result != ISC_R_SUCCESS) goto ioctl6_failure; } #endif if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_MAKESCANSOCKET, "making interface " "scan socket: %s"), strbuf); result = ISC_R_UNEXPECTED; goto socket_failure; } result = getbuf4(iter); if (result != ISC_R_SUCCESS) goto ioctl_failure; /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ #ifdef HAVE_TRUCLUSTER iter->clua_context = -1; iter->clua_done = ISC_TRUE; #endif #ifdef __linux iter->proc = fopen("/proc/net/if_inet6", "r"); iter->valid = ISC_R_FAILURE; #endif iter->result = ISC_R_FAILURE; iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); ioctl_failure: if (iter->buf != NULL) isc_mem_put(mctx, iter->buf, iter->bufsize); (void) close(iter->socket); socket_failure: #if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR) if (iter->buf6 != NULL) isc_mem_put(mctx, iter->buf6, iter->bufsize6); ioctl6_failure: if (iter->socket6 != -1) (void) close(iter->socket6); socket6_failure: #endif isc_mem_put(mctx, iter, sizeof(*iter)); return (result); }
ISC_TASKFUNC_SCOPE isc_result_t isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers, unsigned int default_quantum, isc_taskmgr_t **managerp) { isc_result_t result; unsigned int i, started = 0; isc__taskmgr_t *manager; /* * Create a new task manager. */ REQUIRE(workers > 0); REQUIRE(managerp != NULL && *managerp == NULL); #ifndef USE_WORKER_THREADS UNUSED(i); UNUSED(started); #endif #ifdef USE_SHARED_MANAGER if (taskmgr != NULL) { if (taskmgr->refs == 0) return (ISC_R_SHUTTINGDOWN); taskmgr->refs++; *managerp = (isc_taskmgr_t *)taskmgr; return (ISC_R_SUCCESS); } #endif /* USE_SHARED_MANAGER */ manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); manager->common.methods = &taskmgrmethods; manager->common.impmagic = TASK_MANAGER_MAGIC; manager->common.magic = ISCAPI_TASKMGR_MAGIC; manager->mode = isc_taskmgrmode_normal; manager->mctx = NULL; result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) goto cleanup_mgr; #ifdef USE_WORKER_THREADS manager->workers = 0; manager->threads = isc_mem_allocate(mctx, workers * sizeof(isc_thread_t)); if (manager->threads == NULL) { result = ISC_R_NOMEMORY; goto cleanup_lock; } if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_threads; } if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_workavailable; } if (isc_condition_init(&manager->paused) != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); result = ISC_R_UNEXPECTED; goto cleanup_exclusivegranted; } #endif /* USE_WORKER_THREADS */ if (default_quantum == 0) default_quantum = DEFAULT_DEFAULT_QUANTUM; manager->default_quantum = default_quantum; INIT_LIST(manager->tasks); INIT_LIST(manager->ready_tasks); INIT_LIST(manager->ready_priority_tasks); manager->tasks_running = 0; manager->exclusive_requested = ISC_FALSE; manager->pause_requested = ISC_FALSE; manager->exiting = ISC_FALSE; manager->excl = NULL; isc_mem_attach(mctx, &manager->mctx); #ifdef USE_WORKER_THREADS LOCK(&manager->lock); /* * Start workers. */ for (i = 0; i < workers; i++) { if (isc_thread_create(run, manager, &manager->threads[manager->workers]) == ISC_R_SUCCESS) { manager->workers++; started++; } } UNLOCK(&manager->lock); if (started == 0) { manager_free(manager); return (ISC_R_NOTHREADS); } isc_thread_setconcurrency(workers); #endif /* USE_WORKER_THREADS */ #ifdef USE_SHARED_MANAGER manager->refs = 1; taskmgr = manager; #endif /* USE_SHARED_MANAGER */ *managerp = (isc_taskmgr_t *)manager; return (ISC_R_SUCCESS); #ifdef USE_WORKER_THREADS cleanup_exclusivegranted: (void)isc_condition_destroy(&manager->exclusive_granted); cleanup_workavailable: (void)isc_condition_destroy(&manager->work_available); cleanup_threads: isc_mem_free(mctx, manager->threads); cleanup_lock: DESTROYLOCK(&manager->lock); #endif cleanup_mgr: isc_mem_put(mctx, manager, sizeof(*manager)); return (result); }
static isc_result_t getbuf4(isc_interfaceiter_t *iter) { char strbuf[ISC_STRERRORSIZE]; iter->bufsize = IFCONF_BUFSIZE_INITIAL; for (;;) { iter->buf = isc_mem_get(iter->mctx, iter->bufsize); if (iter->buf == NULL) return (ISC_R_NOMEMORY); memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len)); iter->ifc.ifc_len = iter->bufsize; iter->ifc.ifc_buf = iter->buf; /* * Ignore the HP/UX warning about "integer overflow during * conversion". It comes from its own macro definition, * and is really hard to shut up. */ if (ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc) == -1) { if (errno != EINVAL) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_GETIFCONFIG, "get interface " "configuration: %s"), strbuf); goto unexpected; } /* * EINVAL. Retry with a bigger buffer. */ } else { /* * The ioctl succeeded. * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If * ifc.lifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq) < iter->bufsize) break; } if (iter->bufsize >= IFCONF_BUFSIZE_MAX) { UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERIOCTL, ISC_MSG_BUFFERMAX, "get interface " "configuration: " "maximum buffer " "size exceeded")); goto unexpected; } isc_mem_put(iter->mctx, iter->buf, iter->bufsize); iter->bufsize *= 2; } return (ISC_R_SUCCESS); unexpected: isc_mem_put(iter->mctx, iter->buf, iter->bufsize); iter->buf = NULL; return (ISC_R_UNEXPECTED); }
static isc_result_t opensslrsa_tofile(const dst_key_t *key, const char *directory) { int i; RSA *rsa; dst_private_t priv; unsigned char *bufs[8]; isc_result_t result; #if USE_EVP if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); rsa = EVP_PKEY_get1_RSA(key->keydata.pkey); if (rsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); #else if (key->keydata.rsa == NULL) return (DST_R_NULLKEY); rsa = key->keydata.rsa; #endif for (i = 0; i < 8; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n)); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } } i = 0; priv.elements[i].tag = TAG_RSA_MODULUS; priv.elements[i].length = BN_num_bytes(rsa->n); BN_bn2bin(rsa->n, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; priv.elements[i].length = BN_num_bytes(rsa->e); BN_bn2bin(rsa->e, bufs[i]); priv.elements[i].data = bufs[i]; i++; if (rsa->d != NULL) { priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; priv.elements[i].length = BN_num_bytes(rsa->d); BN_bn2bin(rsa->d, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->p != NULL) { priv.elements[i].tag = TAG_RSA_PRIME1; priv.elements[i].length = BN_num_bytes(rsa->p); BN_bn2bin(rsa->p, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->q != NULL) { priv.elements[i].tag = TAG_RSA_PRIME2; priv.elements[i].length = BN_num_bytes(rsa->q); BN_bn2bin(rsa->q, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->dmp1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT1; priv.elements[i].length = BN_num_bytes(rsa->dmp1); BN_bn2bin(rsa->dmp1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->dmq1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT2; priv.elements[i].length = BN_num_bytes(rsa->dmq1); BN_bn2bin(rsa->dmq1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (rsa->iqmp != NULL) { priv.elements[i].tag = TAG_RSA_COEFFICIENT; priv.elements[i].length = BN_num_bytes(rsa->iqmp); BN_bn2bin(rsa->iqmp, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_RSA_ENGINE; priv.elements[i].length = strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_RSA_LABEL; priv.elements[i].length = strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: #if USE_EVP RSA_free(rsa); #endif for (i = 0; i < 8; i++) { if (bufs[i] == NULL) break; isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n)); } return (result); }
static void opensslrsa_destroyctx(dst_context_t *dctx) { #if USE_EVP EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx; #endif REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 || dctx->key->key_alg == DST_ALG_RSASHA1 || dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 || dctx->key->key_alg == DST_ALG_RSASHA256 || dctx->key->key_alg == DST_ALG_RSASHA512); #if USE_EVP if (evp_md_ctx != NULL) { EVP_MD_CTX_destroy(evp_md_ctx); dctx->ctxdata.evp_md_ctx = NULL; } #else switch (dctx->key->key_alg) { case DST_ALG_RSAMD5: { isc_md5_t *md5ctx = dctx->ctxdata.md5ctx; if (md5ctx != NULL) { isc_md5_invalidate(md5ctx); isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t)); dctx->ctxdata.md5ctx = NULL; } } break; case DST_ALG_RSASHA1: case DST_ALG_NSEC3RSASHA1: { isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx; if (sha1ctx != NULL) { isc_sha1_invalidate(sha1ctx); isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t)); dctx->ctxdata.sha1ctx = NULL; } } break; case DST_ALG_RSASHA256: { isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx; if (sha256ctx != NULL) { isc_sha256_invalidate(sha256ctx); isc_mem_put(dctx->mctx, sha256ctx, sizeof(isc_sha256_t)); dctx->ctxdata.sha256ctx = NULL; } } break; case DST_ALG_RSASHA512: { isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx; if (sha512ctx != NULL) { isc_sha512_invalidate(sha512ctx); isc_mem_put(dctx->mctx, sha512ctx, sizeof(isc_sha512_t)); dctx->ctxdata.sha512ctx = NULL; } } break; default: INSIST(0); } #endif }
int main(int argc, char **argv) { isc_boolean_t show_final_mem = ISC_FALSE; isc_result_t result = ISC_R_SUCCESS; isc_taskmgr_t *taskmgr = NULL; isc_task_t *task = NULL; isc_log_t *log = NULL; isc_logconfig_t *logconfig = NULL; isc_logdestination_t logdest; cfg_parser_t *pctx = NULL; cfg_obj_t *config = NULL; const char *keyname = NULL; struct in_addr in; struct in6_addr in6; char *p; size_t argslen; int ch; int i; result = isc_file_progname(*argv, program, sizeof(program)); if (result != ISC_R_SUCCESS) memcpy(program, "rndc", 5); progname = program; admin_conffile = RNDC_CONFFILE; admin_keyfile = RNDC_KEYFILE; isc_sockaddr_any(&local4); isc_sockaddr_any6(&local6); result = isc_app_start(); if (result != ISC_R_SUCCESS) fatal("isc_app_start() failed: %s", isc_result_totext(result)); isc_commandline_errprint = ISC_FALSE; while ((ch = isc_commandline_parse(argc, argv, "b:c:hk:Mmp:s:Vy:")) != -1) { switch (ch) { case 'b': if (inet_pton(AF_INET, isc_commandline_argument, &in) == 1) { isc_sockaddr_fromin(&local4, &in, 0); local4set = ISC_TRUE; } else if (inet_pton(AF_INET6, isc_commandline_argument, &in6) == 1) { isc_sockaddr_fromin6(&local6, &in6, 0); local6set = ISC_TRUE; } break; case 'c': admin_conffile = isc_commandline_argument; break; case 'k': admin_keyfile = isc_commandline_argument; break; case 'M': isc_mem_debugging = ISC_MEM_DEBUGTRACE; break; case 'm': show_final_mem = ISC_TRUE; break; case 'p': remoteport = atoi(isc_commandline_argument); if (remoteport > 65535 || remoteport == 0) fatal("port '%s' out of range", isc_commandline_argument); break; case 's': servername = isc_commandline_argument; break; case 'V': verbose = ISC_TRUE; break; case 'y': keyname = isc_commandline_argument; break; case '?': if (isc_commandline_option != '?') { fprintf(stderr, "%s: invalid argument -%c\n", program, isc_commandline_option); usage(1); } case 'h': usage(0); break; default: fprintf(stderr, "%s: unhandled option -%c\n", program, isc_commandline_option); exit(1); } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(1); isc_random_get(&serial); DO("create memory context", isc_mem_create(0, 0, &mctx)); DO("create socket manager", isc_socketmgr_create(mctx, &socketmgr)); DO("create task manager", isc_taskmgr_create(mctx, 1, 0, &taskmgr)); DO("create task", isc_task_create(taskmgr, 0, &task)); DO("create logging context", isc_log_create(mctx, &log, &logconfig)); isc_log_setcontext(log); DO("setting log tag", isc_log_settag(logconfig, progname)); logdest.file.stream = stderr; logdest.file.name = NULL; logdest.file.versions = ISC_LOG_ROLLNEVER; logdest.file.maximum_size = 0; DO("creating log channel", isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_INFO, &logdest, ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL)); DO("enabling log channel", isc_log_usechannel(logconfig, "stderr", NULL, NULL)); parse_config(mctx, log, keyname, &pctx, &config); isccc_result_register(); command = *argv; /* * Convert argc/argv into a space-delimited command string * similar to what the user might enter in interactive mode * (if that were implemented). */ argslen = 0; for (i = 0; i < argc; i++) argslen += strlen(argv[i]) + 1; args = isc_mem_get(mctx, argslen); if (args == NULL) DO("isc_mem_get", ISC_R_NOMEMORY); p = args; for (i = 0; i < argc; i++) { size_t len = strlen(argv[i]); memcpy(p, argv[i], len); p += len; *p++ = ' '; } p--; *p++ = '\0'; INSIST(p == args + argslen); notify("%s", command); if (strcmp(command, "restart") == 0) fatal("'%s' is not implemented", command); if (nserveraddrs == 0) get_addresses(servername, (in_port_t) remoteport); DO("post event", isc_app_onrun(mctx, task, rndc_start, NULL)); result = isc_app_run(); if (result != ISC_R_SUCCESS) fatal("isc_app_run() failed: %s", isc_result_totext(result)); if (connects > 0 || sends > 0 || recvs > 0) isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socketmgr_destroy(&socketmgr); isc_log_destroy(&log); isc_log_setcontext(NULL); cfg_obj_destroy(pctx, &config); cfg_parser_destroy(&pctx); isc_mem_put(mctx, args, argslen); isccc_ccmsg_invalidate(&ccmsg); dns_name_destroy(); if (show_final_mem) isc_mem_stats(mctx, stderr); isc_mem_destroy(&mctx); if (failed) return (1); return (0); }
isc_result_t isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type, isc_time_t *expires, isc_interval_t *interval, isc_task_t *task, isc_taskaction_t action, const void *arg, isc_timer_t **timerp) { isc_timer_t *timer; isc_result_t result; isc_time_t now; /* * Create a new 'type' timer managed by 'manager'. The timers * parameters are specified by 'expires' and 'interval'. Events * will be posted to 'task' and when dispatched 'action' will be * called with 'arg' as the arg value. The new timer is returned * in 'timerp'. */ REQUIRE(VALID_MANAGER(manager)); REQUIRE(task != NULL); REQUIRE(action != NULL); if (expires == NULL) expires = isc_time_epoch; if (interval == NULL) interval = isc_interval_zero; REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE(timerp != NULL && *timerp == NULL); REQUIRE(type != isc_timertype_limited || !(isc_time_isepoch(expires) || isc_interval_iszero(interval))); /* * Get current time. */ if (type != isc_timertype_inactive) { TIME_NOW(&now); } else { /* * We don't have to do this, but it keeps the compiler from * complaining about "now" possibly being used without being * set, even though it will never actually happen. */ isc_time_settoepoch(&now); } timer = isc_mem_get(manager->mctx, sizeof(*timer)); if (timer == NULL) return (ISC_R_NOMEMORY); timer->manager = manager; timer->references = 1; if (type == isc_timertype_once && !isc_interval_iszero(interval)) { result = isc_time_add(&now, interval, &timer->idle); if (result != ISC_R_SUCCESS) { isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } } else isc_time_settoepoch(&timer->idle); timer->type = type; timer->expires = *expires; timer->interval = *interval; timer->task = NULL; isc_task_attach(task, &timer->task); timer->action = action; /* * Removing the const attribute from "arg" is the best of two * evils here. If the timer->arg member is made const, then * it affects a great many recipients of the timer event * which did not pass in an "arg" that was truly const. * Changing isc_timer_create() to not have "arg" prototyped as const, * though, can cause compilers warnings for calls that *do* * have a truly const arg. The caller will have to carefully * keep track of whether arg started as a true const. */ DE_CONST(arg, timer->arg); timer->index = 0; result = isc_mutex_init(&timer->lock); if (result != ISC_R_SUCCESS) { isc_task_detach(&timer->task); isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } ISC_LINK_INIT(timer, link); timer->magic = TIMER_MAGIC; LOCK(&manager->lock); /* * Note we don't have to lock the timer like we normally would because * there are no external references to it yet. */ if (type != isc_timertype_inactive) result = schedule(timer, &now, ISC_TRUE); else result = ISC_R_SUCCESS; if (result == ISC_R_SUCCESS) APPEND(manager->timers, timer, link); UNLOCK(&manager->lock); if (result != ISC_R_SUCCESS) { timer->magic = 0; DESTROYLOCK(&timer->lock); isc_task_detach(&timer->task); isc_mem_put(manager->mctx, timer, sizeof(*timer)); return (result); } *timerp = timer; return (ISC_R_SUCCESS); }
isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; isc_result_t result; size_t bufsize; size_t bufused; char strbuf[ISC_STRERRORSIZE]; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->buf = 0; /* * Determine the amount of memory needed. */ bufsize = 0; if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, ISC_MSG_GETIFLISTSIZE, "getting interface " "list size: sysctl: %s"), strbuf); result = ISC_R_UNEXPECTED; goto failure; } iter->bufsize = bufsize; iter->buf = isc_mem_get(iter->mctx, iter->bufsize); if (iter->buf == NULL) { result = ISC_R_NOMEMORY; goto failure; } bufused = bufsize; if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, ISC_MSG_GETIFLIST, "getting interface list: " "sysctl: %s"), strbuf); result = ISC_R_UNEXPECTED; goto failure; } iter->bufused = bufused; INSIST(iter->bufused <= iter->bufsize); /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ iter->pos = (unsigned int) -1; iter->result = ISC_R_FAILURE; iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); failure: if (iter->buf != NULL) isc_mem_put(mctx, iter->buf, iter->bufsize); isc_mem_put(mctx, iter, sizeof(*iter)); return (result); }
isc_result_t isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp) { isc_timermgr_t *manager; isc_result_t result; /* * Create a timer manager. */ REQUIRE(managerp != NULL && *managerp == NULL); #ifndef ISC_PLATFORM_USETHREADS if (timermgr != NULL) { timermgr->refs++; *managerp = timermgr; return (ISC_R_SUCCESS); } #endif /* ISC_PLATFORM_USETHREADS */ manager = isc_mem_get(mctx, sizeof(*manager)); if (manager == NULL) return (ISC_R_NOMEMORY); manager->magic = TIMER_MANAGER_MAGIC; manager->mctx = NULL; manager->done = ISC_FALSE; INIT_LIST(manager->timers); manager->nscheduled = 0; isc_time_settoepoch(&manager->due); manager->heap = NULL; result = isc_heap_create(mctx, sooner, set_index, 0, &manager->heap); if (result != ISC_R_SUCCESS) { INSIST(result == ISC_R_NOMEMORY); isc_mem_put(mctx, manager, sizeof(*manager)); return (ISC_R_NOMEMORY); } result = isc_mutex_init(&manager->lock); if (result != ISC_R_SUCCESS) { isc_heap_destroy(&manager->heap); isc_mem_put(mctx, manager, sizeof(*manager)); return (result); } isc_mem_attach(mctx, &manager->mctx); #ifdef ISC_PLATFORM_USETHREADS if (isc_condition_init(&manager->wakeup) != ISC_R_SUCCESS) { isc_mem_detach(&manager->mctx); DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_condition_init() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); return (ISC_R_UNEXPECTED); } if (isc_thread_create(run, manager, &manager->thread) != ISC_R_SUCCESS) { isc_mem_detach(&manager->mctx); (void)isc_condition_destroy(&manager->wakeup); DESTROYLOCK(&manager->lock); isc_heap_destroy(&manager->heap); isc_mem_put(mctx, manager, sizeof(*manager)); UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_thread_create() %s", isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL, ISC_MSG_FAILED, "failed")); return (ISC_R_UNEXPECTED); } #else /* ISC_PLATFORM_USETHREADS */ manager->refs = 1; timermgr = manager; #endif /* ISC_PLATFORM_USETHREADS */ *managerp = manager; return (ISC_R_SUCCESS); }
static isc_result_t create_stats(isc_mem_t *mctx, int ncounters, isc_stats_t **statsp) { isc_stats_t *stats; isc_result_t result = ISC_R_SUCCESS; REQUIRE(statsp != NULL && *statsp == NULL); stats = isc_mem_get(mctx, sizeof(*stats)); if (stats == NULL) return (ISC_R_NOMEMORY); result = isc_mutex_init(&stats->lock); if (result != ISC_R_SUCCESS) goto clean_stats; stats->counters = isc_mem_get(mctx, sizeof(isc_stat_t) * ncounters); if (stats->counters == NULL) { result = ISC_R_NOMEMORY; goto clean_mutex; } stats->copiedcounters = isc_mem_get(mctx, sizeof(isc_uint64_t) * ncounters); if (stats->copiedcounters == NULL) { result = ISC_R_NOMEMORY; goto clean_counters; } #ifdef ISC_RWLOCK_USEATOMIC result = isc_rwlock_init(&stats->counterlock, 0, 0); if (result != ISC_R_SUCCESS) goto clean_copiedcounters; #endif stats->references = 1; memset(stats->counters, 0, sizeof(isc_stat_t) * ncounters); stats->mctx = NULL; isc_mem_attach(mctx, &stats->mctx); stats->ncounters = ncounters; stats->magic = ISC_STATS_MAGIC; *statsp = stats; return (result); clean_counters: isc_mem_put(mctx, stats->counters, sizeof(isc_stat_t) * ncounters); #ifdef ISC_RWLOCK_USEATOMIC clean_copiedcounters: isc_mem_put(mctx, stats->copiedcounters, sizeof(isc_stat_t) * ncounters); #endif clean_mutex: DESTROYLOCK(&stats->lock); clean_stats: isc_mem_put(mctx, stats, sizeof(*stats)); return (result); }
isc_result_t dns_tsec_create(isc_mem_t *mctx, dns_tsectype_t type, dst_key_t *key, dns_tsec_t **tsecp) { isc_result_t result; dns_tsec_t *tsec; dns_tsigkey_t *tsigkey = NULL; dns_name_t *algname; REQUIRE(mctx != NULL); REQUIRE(tsecp != NULL && *tsecp == NULL); tsec = isc_mem_get(mctx, sizeof(*tsec)); if (tsec == NULL) return (ISC_R_NOMEMORY); tsec->type = type; tsec->mctx = mctx; switch (type) { case dns_tsectype_tsig: switch (dst_key_alg(key)) { case DST_ALG_HMACMD5: algname = dns_tsig_hmacmd5_name; break; case DST_ALG_HMACSHA1: algname = dns_tsig_hmacsha1_name; break; case DST_ALG_HMACSHA224: algname = dns_tsig_hmacsha224_name; break; case DST_ALG_HMACSHA256: algname = dns_tsig_hmacsha256_name; break; case DST_ALG_HMACSHA384: algname = dns_tsig_hmacsha384_name; break; case DST_ALG_HMACSHA512: algname = dns_tsig_hmacsha512_name; break; default: isc_mem_put(mctx, tsec, sizeof(*tsec)); return (DNS_R_BADALG); } result = dns_tsigkey_createfromkey(dst_key_name(key), algname, key, ISC_FALSE, NULL, 0, 0, mctx, NULL, &tsigkey); if (result != ISC_R_SUCCESS) { isc_mem_put(mctx, tsec, sizeof(*tsec)); return (result); } tsec->ukey.tsigkey = tsigkey; break; case dns_tsectype_sig0: tsec->ukey.key = key; break; default: INSIST(0); } tsec->magic = DNS_TSEC_MAGIC; *tsecp = tsec; return (ISC_R_SUCCESS); }
isc_result_t dst_key_fromnamedfile(const char *filename, const char *dirname, int type, isc_mem_t *mctx, dst_key_t **keyp) { isc_result_t result; dst_key_t *pubkey = NULL, *key = NULL; char *newfilename = NULL; int newfilenamelen = 0; isc_lex_t *lex = NULL; REQUIRE(dst_initialized == ISC_TRUE); REQUIRE(filename != NULL); REQUIRE((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) != 0); REQUIRE(mctx != NULL); REQUIRE(keyp != NULL && *keyp == NULL); /* If an absolute path is specified, don't use the key directory */ #ifndef WIN32 if (filename[0] == '/') dirname = NULL; #else /* WIN32 */ if (filename[0] == '/' || filename[0] == '\\') dirname = NULL; #endif newfilenamelen = strlen(filename) + 5; if (dirname != NULL) newfilenamelen += strlen(dirname) + 1; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) return (ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, dirname, filename, ".key"); INSIST(result == ISC_R_SUCCESS); result = dst_key_read_public(newfilename, type, mctx, &pubkey); isc_mem_put(mctx, newfilename, newfilenamelen); newfilename = NULL; RETERR(result); if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC || (pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) { result = computeid(pubkey); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } *keyp = pubkey; return (ISC_R_SUCCESS); } result = algorithm_status(pubkey->key_alg); if (result != ISC_R_SUCCESS) { dst_key_free(&pubkey); return (result); } key = get_key_struct(pubkey->key_name, pubkey->key_alg, pubkey->key_flags, pubkey->key_proto, 0, pubkey->key_class, pubkey->key_ttl, mctx); if (key == NULL) { dst_key_free(&pubkey); return (ISC_R_NOMEMORY); } if (key->func->parse == NULL) RETERR(DST_R_UNSUPPORTEDALG); newfilenamelen = strlen(filename) + 9; if (dirname != NULL) newfilenamelen += strlen(dirname) + 1; newfilename = isc_mem_get(mctx, newfilenamelen); if (newfilename == NULL) RETERR(ISC_R_NOMEMORY); result = addsuffix(newfilename, newfilenamelen, dirname, filename, ".private"); INSIST(result == ISC_R_SUCCESS); RETERR(isc_lex_create(mctx, 1500, &lex)); RETERR(isc_lex_openfile(lex, newfilename)); isc_mem_put(mctx, newfilename, newfilenamelen); RETERR(key->func->parse(key, lex, pubkey)); isc_lex_destroy(&lex); RETERR(computeid(key)); if (pubkey->key_id != key->key_id) RETERR(DST_R_INVALIDPRIVATEKEY); dst_key_free(&pubkey); *keyp = key; return (ISC_R_SUCCESS); out: if (pubkey != NULL) dst_key_free(&pubkey); if (newfilename != NULL) isc_mem_put(mctx, newfilename, newfilenamelen); if (lex != NULL) isc_lex_destroy(&lex); if (key != NULL) dst_key_free(&key); return (result); }
isc_result_t dns_diff_print(dns_diff_t *diff, FILE *file) { isc_result_t result; dns_difftuple_t *t; char *mem = NULL; unsigned int size = 2048; REQUIRE(DNS_DIFF_VALID(diff)); mem = isc_mem_get(diff->mctx, size); if (mem == NULL) return (ISC_R_NOMEMORY); for (t = ISC_LIST_HEAD(diff->tuples); t != NULL; t = ISC_LIST_NEXT(t, link)) { isc_buffer_t buf; isc_region_t r; dns_rdatalist_t rdl; dns_rdataset_t rds; dns_rdata_t rd = DNS_RDATA_INIT; result = diff_tuple_tordataset(t, &rd, &rdl, &rds); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "diff_tuple_tordataset failed: %s", dns_result_totext(result)); result = ISC_R_UNEXPECTED; goto cleanup; } again: isc_buffer_init(&buf, mem, size); result = dns_rdataset_totext(&rds, &t->name, ISC_FALSE, ISC_FALSE, &buf); if (result == ISC_R_NOSPACE) { isc_mem_put(diff->mctx, mem, size); size += 1024; mem = isc_mem_get(diff->mctx, size); if (mem == NULL) { result = ISC_R_NOMEMORY; goto cleanup; } goto again; } if (result != ISC_R_SUCCESS) goto cleanup; /* * Get rid of final newline. */ INSIST(buf.used >= 1 && ((char *) buf.base)[buf.used-1] == '\n'); buf.used--; isc_buffer_usedregion(&buf, &r); if (file != NULL) fprintf(file, "%s %.*s\n", t->op == DNS_DIFFOP_ADD ? "add" : "del", (int) r.length, (char *) r.base); else isc_log_write(DIFF_COMMON_LOGARGS, ISC_LOG_DEBUG(7), "%s %.*s", t->op == DNS_DIFFOP_ADD ? "add" : "del", (int) r.length, (char *) r.base); } result = ISC_R_SUCCESS; cleanup: if (mem != NULL) isc_mem_put(diff->mctx, mem, size); return (result); }
static void destroy(isc_event_t *event) { isc_mem_t *mctx = event->ev_destroy_arg; isc_mem_put(mctx, event, event->ev_size); }
int main(void) { isc_mem_t *mctx = NULL; isc_entropy_t *ectx = NULL; isc_buffer_t b; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; result = isc_mem_create(0, 0, &mctx); if (result != ISC_R_SUCCESS) return (1); current = isc_mem_get(mctx, 256); if (current == NULL) return (1); if (getcwd(current, 256) == NULL) { perror("getcwd"); return (1); } dns_result_register(); result = isc_entropy_create(mctx, &ectx); if (result != ISC_R_SUCCESS) return (1); result = isc_entropy_createfilesource(ectx, "randomfile"); if (result != ISC_R_SUCCESS) return (1); dst_lib_init(mctx, ectx, ISC_ENTROPY_BLOCKING|ISC_ENTROPY_GOODONLY); dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); isc_buffer_init(&b, "test.", 5); isc_buffer_add(&b, 5); result = dns_name_fromtext(name, &b, NULL, 0, NULL); if (result != ISC_R_SUCCESS) return (1); io(name, 23616, DST_ALG_DSA, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx); io(name, 54622, DST_ALG_RSAMD5, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx); io(name, 49667, DST_ALG_DSA, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx); io(name, 2, DST_ALG_RSAMD5, DST_TYPE_PRIVATE|DST_TYPE_PUBLIC, mctx); isc_buffer_init(&b, "dh.", 3); isc_buffer_add(&b, 3); result = dns_name_fromtext(name, &b, NULL, 0, NULL); if (result != ISC_R_SUCCESS) return (1); dh(name, 18602, name, 48957, mctx); generate(DST_ALG_RSAMD5, mctx); generate(DST_ALG_DH, mctx); generate(DST_ALG_DSA, mctx); generate(DST_ALG_HMACMD5, mctx); dst_lib_destroy(); isc_entropy_detach(&ectx); isc_mem_put(mctx, current, 256); /* isc_mem_stats(mctx, stdout);*/ isc_mem_destroy(&mctx); return (0); }
isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { char strbuf[ISC_STRERRORSIZE]; isc_interfaceiter_t *iter; isc_result_t result; int error; unsigned long bytesReturned = 0; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); InitSockets(); iter->mctx = mctx; iter->buf4 = NULL; iter->buf6 = NULL; iter->pos4 = NULL; iter->pos6 = 0; iter->buf6size = 0; iter->buf4size = 0; iter->result = ISC_R_FAILURE; iter->numIF = 0; iter->v4IF = 0; /* * Create an unbound datagram socket to do the * SIO_GET_INTERFACE_LIST WSAIoctl on. */ iter->socket = socket(AF_INET, SOCK_DGRAM, 0); if (iter->socket == INVALID_SOCKET) { error = WSAGetLastError(); if (error == WSAEAFNOSUPPORT) goto inet6_only; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "making interface scan socket: %s", strbuf); result = ISC_R_UNEXPECTED; goto socket_failure; } /* * Get the interface configuration, allocating more memory if * necessary. */ iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO); for (;;) { iter->buf4 = isc_mem_get(mctx, iter->buf4size); if (iter->buf4 == NULL) { result = ISC_R_NOMEMORY; goto alloc_failure; } if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST, 0, 0, iter->buf4, iter->buf4size, &bytesReturned, 0, 0) == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEFAULT && error != WSAENOBUFS) { errno = error; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl_failure; } /* * EINVAL. Retry with a bigger buffer. */ } else { /* * The WSAIoctl succeeded. * If the number of the returned bytes is the same * as the buffer size, we will grow it just in * case and retry. */ if (bytesReturned > 0 && (bytesReturned < iter->buf4size)) break; } if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) { UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: " "maximum buffer size exceeded"); result = ISC_R_UNEXPECTED; goto ioctl_failure; } isc_mem_put(mctx, iter->buf4, iter->buf4size); iter->buf4size += IFCONF_SIZE_INCREMENT * sizeof(INTERFACE_INFO); } /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO); /* We don't need the socket any more, so close it */ closesocket(iter->socket); inet6_only: /* * Create an unbound datagram socket to do the * SIO_ADDRESS_LIST_QUERY WSAIoctl on. */ iter->socket = socket(AF_INET6, SOCK_DGRAM, 0); if (iter->socket == INVALID_SOCKET) { error = WSAGetLastError(); if (error == WSAEAFNOSUPPORT) goto inet_only; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "making interface scan socket: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl_failure; } /* * Get the interface configuration, allocating more memory if * necessary. */ iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) + IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS); for (;;) { iter->buf6 = isc_mem_get(mctx, iter->buf6size); if (iter->buf6 == NULL) { result = ISC_R_NOMEMORY; goto ioctl_failure; } if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY, 0, 0, iter->buf6, iter->buf6size, &bytesReturned, 0, 0) == SOCKET_ERROR) { error = WSAGetLastError(); if (error != WSAEFAULT && error != WSAENOBUFS) { errno = error; isc__strerror(error, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, "sio address list query: %s", strbuf); result = ISC_R_UNEXPECTED; goto ioctl6_failure; } /* * EINVAL. Retry with a bigger buffer. */ } else break; if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) { UNEXPECTED_ERROR(__FILE__, __LINE__, "get interface configuration: " "maximum buffer size exceeded"); result = ISC_R_UNEXPECTED; goto ioctl6_failure; } isc_mem_put(mctx, iter->buf6, iter->buf6size); iter->buf6size += IFCONF_SIZE_INCREMENT * sizeof(SOCKET_ADDRESS); } closesocket(iter->socket); inet_only: iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); ioctl6_failure: isc_mem_put(mctx, iter->buf6, iter->buf6size); ioctl_failure: if (iter->buf4 != NULL) isc_mem_put(mctx, iter->buf4, iter->buf4size); alloc_failure: if (iter->socket != INVALID_SOCKET) (void) closesocket(iter->socket); socket_failure: isc_mem_put(mctx, iter, sizeof(*iter)); return (result); }
isc_result_t dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername, unsigned int argc, char *argv[], dns_dlzdb_t **dbp) { dns_dlzimplementation_t *impinfo; isc_result_t result; dns_dlzdb_t *db = NULL; /* * initialize the dlz_implementations list, this is guaranteed * to only really happen once. */ RUNTIME_CHECK(isc_once_do(&once, dlz_initialize) == ISC_R_SUCCESS); /* * Performs checks to make sure data is as we expect it to be. */ REQUIRE(dbp != NULL && *dbp == NULL); REQUIRE(dlzname != NULL); REQUIRE(drivername != NULL); REQUIRE(mctx != NULL); /* write log message */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_INFO, "Loading '%s' using driver %s", dlzname, drivername); /* lock the dlz_implementations list so we can search it. */ RWLOCK(&dlz_implock, isc_rwlocktype_read); /* search for the driver implementation */ impinfo = dlz_impfind(drivername); if (impinfo == NULL) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "unsupported DLZ database driver '%s'." " %s not loaded.", drivername, dlzname); return (ISC_R_NOTFOUND); } /* Allocate memory to hold the DLZ database driver */ db = isc_mem_get(mctx, sizeof(dns_dlzdb_t)); if (db == NULL) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); return (ISC_R_NOMEMORY); } /* Make sure memory region is set to all 0's */ memset(db, 0, sizeof(dns_dlzdb_t)); ISC_LINK_INIT(db, link); db->implementation = impinfo; if (dlzname != NULL) db->dlzname = isc_mem_strdup(mctx, dlzname); /* Create a new database using implementation 'drivername'. */ result = ((impinfo->methods->create)(mctx, dlzname, argc, argv, impinfo->driverarg, &db->dbdata)); /* mark the DLZ driver as valid */ if (result == ISC_R_SUCCESS) { RWUNLOCK(&dlz_implock, isc_rwlocktype_read); db->magic = DNS_DLZ_MAGIC; isc_mem_attach(mctx, &db->mctx); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2), "DLZ driver loaded successfully."); *dbp = db; return (ISC_R_SUCCESS); } else { isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_DLZ, ISC_LOG_ERROR, "DLZ driver failed to load."); } /* impinfo->methods->create failed. */ RWUNLOCK(&dlz_implock, isc_rwlocktype_read); isc_mem_put(mctx, db, sizeof(dns_dlzdb_t)); return (result); }
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 = isc_entropy_getdata(tctx->ectx, randomdata, TKEY_RANDOM_AMOUNT, NULL, 0); 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, msg->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); }
isc_result_t dns_tsig_sign(dns_message_t *msg) { dns_tsigkey_t *key; dns_rdata_any_tsig_t tsig, querytsig; unsigned char data[128]; isc_buffer_t databuf, sigbuf; isc_buffer_t *dynbuf; dns_name_t *owner; dns_rdata_t *rdata = NULL; dns_rdatalist_t *datalist; dns_rdataset_t *dataset; isc_region_t r; isc_stdtime_t now; isc_mem_t *mctx; dst_context_t *ctx = NULL; isc_result_t ret; unsigned char badtimedata[BADTIMELEN]; unsigned int sigsize = 0; isc_boolean_t response = is_response(msg); REQUIRE(msg != NULL); REQUIRE(VALID_TSIG_KEY(dns_message_gettsigkey(msg))); /* * If this is a response, there should be a query tsig. */ if (response && msg->querytsig == NULL) return (DNS_R_EXPECTEDTSIG); dynbuf = NULL; mctx = msg->mctx; key = dns_message_gettsigkey(msg); tsig.mctx = mctx; tsig.common.rdclass = dns_rdataclass_any; tsig.common.rdtype = dns_rdatatype_tsig; ISC_LINK_INIT(&tsig.common, link); dns_name_init(&tsig.algorithm, NULL); dns_name_clone(key->algorithm, &tsig.algorithm); isc_stdtime_get(&now); tsig.timesigned = now + msg->timeadjust; tsig.fudge = DNS_TSIG_FUDGE; tsig.originalid = msg->id; isc_buffer_init(&databuf, data, sizeof(data)); if (response) tsig.error = msg->querytsigstatus; else tsig.error = dns_rcode_noerror; if (tsig.error != dns_tsigerror_badtime) { tsig.otherlen = 0; tsig.other = NULL; } else { isc_buffer_t otherbuf; tsig.otherlen = BADTIMELEN; tsig.other = badtimedata; isc_buffer_init(&otherbuf, tsig.other, tsig.otherlen); isc_buffer_putuint48(&otherbuf, tsig.timesigned); } if (key->key != NULL && tsig.error != dns_tsigerror_badsig) { unsigned char header[DNS_MESSAGE_HEADERLEN]; isc_buffer_t headerbuf; isc_uint16_t digestbits; ret = dst_context_create3(key->key, mctx, DNS_LOGCATEGORY_DNSSEC, ISC_TRUE, &ctx); if (ret != ISC_R_SUCCESS) return (ret); /* * If this is a response, digest the query signature. */ if (response) { dns_rdata_t querytsigrdata = DNS_RDATA_INIT; ret = dns_rdataset_first(msg->querytsig); if (ret != ISC_R_SUCCESS) goto cleanup_context; dns_rdataset_current(msg->querytsig, &querytsigrdata); ret = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_putuint16(&databuf, querytsig.siglen); if (isc_buffer_availablelength(&databuf) < querytsig.siglen) { ret = ISC_R_NOSPACE; goto cleanup_context; } isc_buffer_putmem(&databuf, querytsig.signature, querytsig.siglen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } #if defined(__clang__) && \ ( __clang_major__ < 3 || \ (__clang_major__ == 3 && __clang_minor__ < 2) || \ (__clang_major__ == 4 && __clang_minor__ < 2)) /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */ else memset(&querytsig, 0, sizeof(querytsig)); #endif /* * Digest the header. */ isc_buffer_init(&headerbuf, header, sizeof(header)); dns_message_renderheader(msg, &headerbuf); isc_buffer_usedregion(&headerbuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest the remainder of the message. */ isc_buffer_usedregion(msg->buffer, &r); isc_region_consume(&r, DNS_MESSAGE_HEADERLEN); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (msg->tcp_continuation == 0) { /* * Digest the name, class, ttl, alg. */ dns_name_toregion(&key->name, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; isc_buffer_clear(&databuf); isc_buffer_putuint16(&databuf, dns_rdataclass_any); isc_buffer_putuint32(&databuf, 0); /* ttl */ isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; dns_name_toregion(&tsig.algorithm, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } /* Digest the timesigned and fudge */ isc_buffer_clear(&databuf); if (tsig.error == dns_tsigerror_badtime) { INSIST(response); tsig.timesigned = querytsig.timesigned; } isc_buffer_putuint48(&databuf, tsig.timesigned); isc_buffer_putuint16(&databuf, tsig.fudge); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; if (msg->tcp_continuation == 0) { /* * Digest the error and other data length. */ isc_buffer_clear(&databuf); isc_buffer_putuint16(&databuf, tsig.error); isc_buffer_putuint16(&databuf, tsig.otherlen); isc_buffer_usedregion(&databuf, &r); ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; /* * Digest other data. */ if (tsig.otherlen > 0) { r.length = tsig.otherlen; r.base = tsig.other; ret = dst_context_adddata(ctx, &r); if (ret != ISC_R_SUCCESS) goto cleanup_context; } } ret = dst_key_sigsize(key->key, &sigsize); if (ret != ISC_R_SUCCESS) goto cleanup_context; tsig.signature = (unsigned char *) isc_mem_get(mctx, sigsize); if (tsig.signature == NULL) { ret = ISC_R_NOMEMORY; goto cleanup_context; } isc_buffer_init(&sigbuf, tsig.signature, sigsize); ret = dst_context_sign(ctx, &sigbuf); if (ret != ISC_R_SUCCESS) goto cleanup_signature; dst_context_destroy(&ctx); digestbits = dst_key_getbits(key->key); if (digestbits != 0) { unsigned int bytes = (digestbits + 1) / 8; if (response && bytes < querytsig.siglen) bytes = querytsig.siglen; if (bytes > isc_buffer_usedlength(&sigbuf)) bytes = isc_buffer_usedlength(&sigbuf); tsig.siglen = bytes; } else tsig.siglen = isc_buffer_usedlength(&sigbuf); } else { tsig.siglen = 0; tsig.signature = NULL; } ret = dns_message_gettemprdata(msg, &rdata); if (ret != ISC_R_SUCCESS) goto cleanup_signature; ret = isc_buffer_allocate(msg->mctx, &dynbuf, 512); if (ret != ISC_R_SUCCESS) goto cleanup_rdata; ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &tsig, dynbuf); if (ret != ISC_R_SUCCESS) goto cleanup_dynbuf; dns_message_takebuffer(msg, &dynbuf); if (tsig.signature != NULL) { isc_mem_put(mctx, tsig.signature, sigsize); tsig.signature = NULL; } owner = NULL; ret = dns_message_gettempname(msg, &owner); if (ret != ISC_R_SUCCESS) goto cleanup_rdata; dns_name_init(owner, NULL); ret = dns_name_dup(&key->name, msg->mctx, owner); if (ret != ISC_R_SUCCESS) goto cleanup_owner; datalist = NULL; ret = dns_message_gettemprdatalist(msg, &datalist); if (ret != ISC_R_SUCCESS) goto cleanup_owner; dataset = NULL; ret = dns_message_gettemprdataset(msg, &dataset); if (ret != ISC_R_SUCCESS) goto cleanup_rdatalist; datalist->rdclass = dns_rdataclass_any; datalist->type = dns_rdatatype_tsig; datalist->covers = 0; datalist->ttl = 0; ISC_LIST_INIT(datalist->rdata); ISC_LIST_APPEND(datalist->rdata, rdata, link); dns_rdataset_init(dataset); RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == ISC_R_SUCCESS); msg->tsig = dataset; msg->tsigname = owner; /* Windows does not like the tsig name being compressed. */ msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS; return (ISC_R_SUCCESS); cleanup_rdatalist: dns_message_puttemprdatalist(msg, &datalist); cleanup_owner: dns_message_puttempname(msg, &owner); goto cleanup_rdata; cleanup_dynbuf: isc_buffer_free(&dynbuf); cleanup_rdata: dns_message_puttemprdata(msg, &rdata); cleanup_signature: if (tsig.signature != NULL) isc_mem_put(mctx, tsig.signature, sigsize); cleanup_context: if (ctx != NULL) dst_context_destroy(&ctx); return (ret); }
/* * Called at startup for each dlopen zone in named.conf */ static isc_result_t dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[], void *driverarg, void **dbdata) { dlopen_data_t *cd; isc_mem_t *mctx = NULL; isc_result_t result = ISC_R_FAILURE; isc_boolean_t triedload = ISC_FALSE; UNUSED(driverarg); if (argc < 2) { dlopen_log(ISC_LOG_ERROR, "dlz_dlopen driver for '%s' needs a path to " "the shared library", dlzname); return (ISC_R_FAILURE); } isc_mem_create(0, 0, &mctx); cd = isc_mem_get(mctx, sizeof(*cd)); if (cd == NULL) { isc_mem_destroy(&mctx); return (ISC_R_NOMEMORY); } memset(cd, 0, sizeof(*cd)); cd->mctx = mctx; cd->dl_path = isc_mem_strdup(cd->mctx, argv[1]); if (cd->dl_path == NULL) { result = ISC_R_NOMEMORY; goto failed; } cd->dlzname = isc_mem_strdup(cd->mctx, dlzname); if (cd->dlzname == NULL) { result = ISC_R_NOMEMORY; goto failed; } triedload = ISC_TRUE; /* Initialize the lock */ result = isc_mutex_init(&cd->lock); if (result != ISC_R_SUCCESS) goto failed; /* Open the library */ cd->dl_handle = LoadLibraryA(cd->dl_path); if (cd->dl_handle == NULL) { unsigned int error = GetLastError(); dlopen_log(ISC_LOG_ERROR, "dlz_dlopen failed to open library '%s' - %u", cd->dl_path, error); result = ISC_R_FAILURE; goto cleanup_lock; } /* Find the symbols */ cd->dlz_version = (dlz_dlopen_version_t *) dl_load_symbol(cd, "dlz_version", ISC_TRUE); cd->dlz_create = (dlz_dlopen_create_t *) dl_load_symbol(cd, "dlz_create", ISC_TRUE); cd->dlz_lookup = (dlz_dlopen_lookup_t *) dl_load_symbol(cd, "dlz_lookup", ISC_TRUE); cd->dlz_findzonedb = (dlz_dlopen_findzonedb_t *) dl_load_symbol(cd, "dlz_findzonedb", ISC_TRUE); if (cd->dlz_create == NULL || cd->dlz_version == NULL || cd->dlz_lookup == NULL || cd->dlz_findzonedb == NULL) { /* We're missing a required symbol */ result = ISC_R_FAILURE; goto cleanup_lock; } cd->dlz_allowzonexfr = (dlz_dlopen_allowzonexfr_t *) dl_load_symbol(cd, "dlz_allowzonexfr", ISC_FALSE); cd->dlz_allnodes = (dlz_dlopen_allnodes_t *) dl_load_symbol(cd, "dlz_allnodes", ISC_TF(cd->dlz_allowzonexfr != NULL)); cd->dlz_authority = (dlz_dlopen_authority_t *) dl_load_symbol(cd, "dlz_authority", ISC_FALSE); cd->dlz_newversion = (dlz_dlopen_newversion_t *) dl_load_symbol(cd, "dlz_newversion", ISC_FALSE); cd->dlz_closeversion = (dlz_dlopen_closeversion_t *) dl_load_symbol(cd, "dlz_closeversion", ISC_TF(cd->dlz_newversion != NULL)); cd->dlz_configure = (dlz_dlopen_configure_t *) dl_load_symbol(cd, "dlz_configure", ISC_FALSE); cd->dlz_ssumatch = (dlz_dlopen_ssumatch_t *) dl_load_symbol(cd, "dlz_ssumatch", ISC_FALSE); cd->dlz_addrdataset = (dlz_dlopen_addrdataset_t *) dl_load_symbol(cd, "dlz_addrdataset", ISC_FALSE); cd->dlz_subrdataset = (dlz_dlopen_subrdataset_t *) dl_load_symbol(cd, "dlz_subrdataset", ISC_FALSE); cd->dlz_delrdataset = (dlz_dlopen_delrdataset_t *) dl_load_symbol(cd, "dlz_delrdataset", ISC_FALSE); /* Check the version of the API is the same */ cd->version = cd->dlz_version(&cd->flags); if (cd->version < (DLZ_DLOPEN_VERSION - DLZ_DLOPEN_AGE) || cd->version > DLZ_DLOPEN_VERSION) { dlopen_log(ISC_LOG_ERROR, "dlz_dlopen: %s: incorrect driver API version %d, " "requires %d", cd->dl_path, cd->version, DLZ_DLOPEN_VERSION); result = ISC_R_FAILURE; goto cleanup_lock; } /* * Call the library's create function. Note that this is an * extended version of dlz create, with the addition of * named function pointers for helper functions that the * driver will need. This avoids the need for the backend to * link the BIND9 libraries */ MAYBE_LOCK(cd); result = cd->dlz_create(dlzname, argc-1, argv+1, &cd->dbdata, "log", dlopen_log, "putrr", dns_sdlz_putrr, "putnamedrr", dns_sdlz_putnamedrr, "writeable_zone", dns_dlz_writeablezone, NULL); MAYBE_UNLOCK(cd); if (result != ISC_R_SUCCESS) goto cleanup_lock; *dbdata = cd; return (ISC_R_SUCCESS); cleanup_lock: DESTROYLOCK(&cd->lock); failed: dlopen_log(ISC_LOG_ERROR, "dlz_dlopen of '%s' failed", dlzname); if (cd->dl_path) isc_mem_free(mctx, cd->dl_path); if (cd->dlzname) isc_mem_free(mctx, cd->dlzname); if (triedload) (void) isc_mutex_destroy(&cd->lock); if (cd->dl_handle) FreeLibrary(cd->dl_handle); isc_mem_put(mctx, cd, sizeof(*cd)); isc_mem_destroy(&mctx); return (result); }
static void isc_httpd_accept(isc_task_t *task, isc_event_t *ev) { isc_result_t result; isc_httpdmgr_t *httpdmgr = ev->ev_arg; isc_httpd_t *httpd; isc_region_t r; isc_socket_newconnev_t *nev = (isc_socket_newconnev_t *)ev; isc_sockaddr_t peeraddr; ENTER("accept"); LOCK(&httpdmgr->lock); if (MSHUTTINGDOWN(httpdmgr)) { NOTICE("accept shutting down, goto out"); goto out; } if (nev->result == ISC_R_CANCELED) { NOTICE("accept canceled, goto out"); goto out; } if (nev->result != ISC_R_SUCCESS) { /* XXXMLG log failure */ NOTICE("accept returned failure, goto requeue"); goto requeue; } (void)isc_socket_getpeername(nev->newsocket, &peeraddr); if (httpdmgr->client_ok != NULL && !(httpdmgr->client_ok)(&peeraddr, httpdmgr->cb_arg)) { isc_socket_detach(&nev->newsocket); goto requeue; } httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t)); if (httpd == NULL) { /* XXXMLG log failure */ NOTICE("accept failed to allocate memory, goto requeue"); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->mgr = httpdmgr; ISC_LINK_INIT(httpd, link); ISC_LIST_APPEND(httpdmgr->running, httpd, link); ISC_HTTPD_SETRECV(httpd); httpd->sock = nev->newsocket; isc_socket_setname(httpd->sock, "httpd", NULL); httpd->flags = 0; /* * Initialize the buffer for our headers. */ httpd->headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW); if (httpd->headerdata == NULL) { isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->headerlen = HTTP_SENDGROW; isc_buffer_init(&httpd->headerbuffer, httpd->headerdata, httpd->headerlen); ISC_LIST_INIT(httpd->bufflist); isc_buffer_initnull(&httpd->bodybuffer); reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; result = isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); /* FIXME!!! */ POST(result); NOTICE("accept queued recv on socket"); requeue: result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept, httpdmgr); if (result != ISC_R_SUCCESS) { /* XXXMLG what to do? Log failure... */ NOTICE("accept could not reaccept due to failure"); } out: UNLOCK(&httpdmgr->lock); httpdmgr_destroy(httpdmgr); isc_event_free(&ev); EXIT("accept"); }
static isc_result_t pkcs11rsa_tofile(const dst_key_t *key, const char *directory) { int i; pk11_object_t *rsa; CK_ATTRIBUTE *attr; CK_ATTRIBUTE *modulus = NULL, *exponent = NULL; CK_ATTRIBUTE *d = NULL, *p = NULL, *q = NULL; CK_ATTRIBUTE *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; dst_private_t priv; unsigned char *bufs[10]; isc_result_t result; if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); if (key->external) { priv.nelements = 0; return (dst__privstruct_writefile(key, &priv, directory)); } rsa = key->keydata.pkey; for (attr = pk11_attribute_first(rsa); attr != NULL; attr = pk11_attribute_next(rsa, attr)) switch (attr->type) { case CKA_MODULUS: modulus = attr; break; case CKA_PUBLIC_EXPONENT: exponent = attr; break; case CKA_PRIVATE_EXPONENT: d = attr; break; case CKA_PRIME_1: p = attr; break; case CKA_PRIME_2: q = attr; break; case CKA_EXPONENT_1: dmp1 = attr; break; case CKA_EXPONENT_2: dmq1 = attr; break; case CKA_COEFFICIENT: iqmp = attr; break; } if ((modulus == NULL) || (exponent == NULL)) return (DST_R_NULLKEY); memset(bufs, 0, sizeof(bufs)); for (i = 0; i < 10; i++) { bufs[i] = isc_mem_get(key->mctx, modulus->ulValueLen); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } memset(bufs[i], 0, modulus->ulValueLen); } i = 0; priv.elements[i].tag = TAG_RSA_MODULUS; priv.elements[i].length = (unsigned short) modulus->ulValueLen; memmove(bufs[i], modulus->pValue, modulus->ulValueLen); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; priv.elements[i].length = (unsigned short) exponent->ulValueLen; memmove(bufs[i], exponent->pValue, exponent->ulValueLen); priv.elements[i].data = bufs[i]; i++; if (d != NULL) { priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; priv.elements[i].length = (unsigned short) d->ulValueLen; memmove(bufs[i], d->pValue, d->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (p != NULL) { priv.elements[i].tag = TAG_RSA_PRIME1; priv.elements[i].length = (unsigned short) p->ulValueLen; memmove(bufs[i], p->pValue, p->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (q != NULL) { priv.elements[i].tag = TAG_RSA_PRIME2; priv.elements[i].length = (unsigned short) q->ulValueLen; memmove(bufs[i], q->pValue, q->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (dmp1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT1; priv.elements[i].length = (unsigned short) dmp1->ulValueLen; memmove(bufs[i], dmp1->pValue, dmp1->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (dmq1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT2; priv.elements[i].length = (unsigned short) dmq1->ulValueLen; memmove(bufs[i], dmq1->pValue, dmq1->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (iqmp != NULL) { priv.elements[i].tag = TAG_RSA_COEFFICIENT; priv.elements[i].length = (unsigned short) iqmp->ulValueLen; memmove(bufs[i], iqmp->pValue, iqmp->ulValueLen); priv.elements[i].data = bufs[i]; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_RSA_ENGINE; priv.elements[i].length = strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_RSA_LABEL; priv.elements[i].length = strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: for (i = 0; i < 10; i++) { if (bufs[i] == NULL) break; memset(bufs[i], 0, modulus->ulValueLen); isc_mem_put(key->mctx, bufs[i], modulus->ulValueLen); } return (result); }