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); } } }
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; }
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); }
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); }
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); }
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)); }
/*% * 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); }
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); }
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(); }
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); }
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); }
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; }
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); }
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); }
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); }
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; }
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); }
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); }
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); }
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, ®ion); 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, ®ion); 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, ®ion); 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); }
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(); }
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); }
/*% 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); }
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); }
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); }
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); }
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); }
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); }