diff --git a/bin/named/controlconf.c b/bin/named/controlconf.c index 9ceabec6cf..38133fb038 100644 --- a/bin/named/controlconf.c +++ b/bin/named/controlconf.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: controlconf.c,v 1.13 2001/06/29 23:34:40 gson Exp $ */ +/* $Id: controlconf.c,v 1.14 2001/07/04 03:54:55 bwelling Exp $ */ #include @@ -336,13 +336,7 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) { conn = event->ev_arg; listener = conn->listener; - key = ISC_LIST_HEAD(listener->keys); - INSIST(key != NULL); - secret.rstart = isc_mem_get(listener->mctx, key->secret.length); - if (secret.rstart == NULL) - goto cleanup; - memcpy(secret.rstart, key->secret.base, key->secret.length); - secret.rend = secret.rstart + key->secret.length; + secret.rstart = NULL; if (conn->ccmsg.result != ISC_R_SUCCESS) { if (conn->ccmsg.result != ISC_R_CANCELED && @@ -351,12 +345,41 @@ control_recvmessage(isc_task_t *task, isc_event_t *event) { goto cleanup; } - ccregion.rstart = isc_buffer_base(&conn->ccmsg.buffer); - ccregion.rend = isc_buffer_used(&conn->ccmsg.buffer); request = NULL; - result = isccc_cc_fromwire(&ccregion, &request, &secret); - if (result != ISC_R_SUCCESS) { - log_invalid(&conn->ccmsg, result); + INSIST(!ISC_LIST_EMPTY(listener->keys)); + + 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; + memcpy(secret.rstart, key->secret.base, key->secret.length); + secret.rend = secret.rstart + key->secret.length; + result = isccc_cc_fromwire(&ccregion, &request, &secret); + if (result == ISC_R_SUCCESS) + break; + else if (result == ISCCC_R_BADAUTH) { + /* + * For some reason, request is non-NULL when + * isccc_cc_fromwire returns ISCCC_R_BADAUTH. + */ + if (request != NULL) + isccc_sexpr_free(&request); + isc_mem_put(listener->mctx, secret.rstart, + REGION_SIZE(secret)); + } + else { + log_invalid(&conn->ccmsg, result); + goto cleanup; + } + } + + if (key == NULL) { + log_invalid(&conn->ccmsg, ISCCC_R_BADAUTH); goto cleanup; }