⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 controlconf.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2001-2003  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: controlconf.c,v 1.28.2.9.2.6 2004/03/08 09:04:14 marka Exp $ */#include <config.h>#include <isc/base64.h>#include <isc/buffer.h>#include <isc/event.h>#include <isc/mem.h>#include <isc/net.h>#include <isc/netaddr.h>#include <isc/random.h>#include <isc/result.h>#include <isc/stdtime.h>#include <isc/string.h>#include <isc/timer.h>#include <isc/util.h>#include <isccfg/namedconf.h>#include <bind9/check.h>#include <isccc/alist.h>#include <isccc/cc.h>#include <isccc/ccmsg.h>#include <isccc/events.h>#include <isccc/result.h>#include <isccc/sexpr.h>#include <isccc/symtab.h>#include <isccc/util.h>#include <dns/result.h>#include <named/config.h>#include <named/control.h>#include <named/log.h>#include <named/server.h>/* * Note: Listeners and connections are not locked.  All event handlers are * executed by the server task, and all callers of exported routines must * be running under the server task. */typedef struct controlkey controlkey_t;typedef ISC_LIST(controlkey_t) controlkeylist_t;typedef struct controlconnection controlconnection_t;typedef ISC_LIST(controlconnection_t) controlconnectionlist_t;typedef struct controllistener controllistener_t;typedef ISC_LIST(controllistener_t) controllistenerlist_t;struct controlkey {	char *				keyname;	isc_region_t			secret;	ISC_LINK(controlkey_t)		link;};struct controlconnection {	isc_socket_t *			sock;	isccc_ccmsg_t			ccmsg;	isc_boolean_t			ccmsg_valid;	isc_boolean_t			sending;	isc_timer_t *			timer;	unsigned char			buffer[2048];	controllistener_t *		listener;	isc_uint32_t			nonce;	ISC_LINK(controlconnection_t)	link;};struct controllistener {	ns_controls_t *			controls;	isc_mem_t *			mctx;	isc_task_t *			task;	isc_sockaddr_t			address;	isc_socket_t *			sock;	dns_acl_t *			acl;	isc_boolean_t			listening;	isc_boolean_t			exiting;	controlkeylist_t		keys;	controlconnectionlist_t		connections;	ISC_LINK(controllistener_t)	link;};struct ns_controls {	ns_server_t			*server;	controllistenerlist_t 		listeners;	isc_boolean_t			shuttingdown;	isccc_symtab_t			*symtab;};static void control_newconn(isc_task_t *task, isc_event_t *event);static void control_recvmessage(isc_task_t *task, isc_event_t *event);#define CLOCKSKEW 300static voidfree_controlkey(controlkey_t *key, isc_mem_t *mctx) {	if (key->keyname != NULL)		isc_mem_free(mctx, key->keyname);	if (key->secret.base != NULL)		isc_mem_put(mctx, key->secret.base, key->secret.length);	isc_mem_put(mctx, key, sizeof(*key));}static voidfree_controlkeylist(controlkeylist_t *keylist, isc_mem_t *mctx) {	while (!ISC_LIST_EMPTY(*keylist)) {		controlkey_t *key = ISC_LIST_HEAD(*keylist);		ISC_LIST_UNLINK(*keylist, key, link);		free_controlkey(key, mctx);	}}static voidfree_listener(controllistener_t *listener) {	INSIST(listener->exiting);	INSIST(!listener->listening);	INSIST(ISC_LIST_EMPTY(listener->connections));	if (listener->sock != NULL)		isc_socket_detach(&listener->sock);	free_controlkeylist(&listener->keys, listener->mctx);	if (listener->acl != NULL)		dns_acl_detach(&listener->acl);	isc_mem_put(listener->mctx, listener, sizeof(*listener));}static voidmaybe_free_listener(controllistener_t *listener) {	if (listener->exiting &&	    !listener->listening &&	    ISC_LIST_EMPTY(listener->connections))		free_listener(listener);}static voidmaybe_free_connection(controlconnection_t *conn) {	controllistener_t *listener = conn->listener;	if (conn->timer != NULL)		isc_timer_detach(&conn->timer);	if (conn->ccmsg_valid) {		isccc_ccmsg_cancelread(&conn->ccmsg);		return;	}	if (conn->sending) {		isc_socket_cancel(conn->sock, listener->task,				  ISC_SOCKCANCEL_SEND);		return;	}	ISC_LIST_UNLINK(listener->connections, conn, link);	isc_mem_put(listener->mctx, conn, sizeof(*conn));}static voidshutdown_listener(controllistener_t *listener) {	controlconnection_t *conn;	controlconnection_t *next;	if (!listener->exiting) {		char socktext[ISC_SOCKADDR_FORMATSIZE];		ISC_LIST_UNLINK(listener->controls->listeners, listener, link);		isc_sockaddr_format(&listener->address, socktext,				    sizeof(socktext));		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,			      NS_LOGMODULE_CONTROL, ISC_LOG_NOTICE,			      "stopping command channel on %s", socktext);		listener->exiting = ISC_TRUE;	}	for (conn = ISC_LIST_HEAD(listener->connections);	     conn != NULL;	     conn = next)	{		next = ISC_LIST_NEXT(conn, link);		maybe_free_connection(conn);	}	if (listener->listening)		isc_socket_cancel(listener->sock, listener->task,				  ISC_SOCKCANCEL_ACCEPT);	maybe_free_listener(listener);}static isc_boolean_taddress_ok(isc_sockaddr_t *sockaddr, dns_acl_t *acl) {	isc_netaddr_t netaddr;	isc_result_t result;	int match;	isc_netaddr_fromsockaddr(&netaddr, sockaddr);	result = dns_acl_match(&netaddr, NULL, acl,			       &ns_g_server->aclenv, &match, NULL);	if (result != ISC_R_SUCCESS || match <= 0)		return (ISC_FALSE);	else		return (ISC_TRUE);}static isc_result_tcontrol_accept(controllistener_t *listener) {	isc_result_t result;	result = isc_socket_accept(listener->sock,				   listener->task,				   control_newconn, listener);	if (result != ISC_R_SUCCESS)		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_socket_accept() failed: %s",				 isc_result_totext(result));	else		listener->listening = ISC_TRUE;	return (result);}static isc_result_tcontrol_listen(controllistener_t *listener) {	isc_result_t result;	result = isc_socket_listen(listener->sock, 0);	if (result != ISC_R_SUCCESS)		UNEXPECTED_ERROR(__FILE__, __LINE__,				 "isc_socket_listen() failed: %s",				 isc_result_totext(result));	return (result);}static voidcontrol_next(controllistener_t *listener) {	(void)control_accept(listener);}static voidcontrol_senddone(isc_task_t *task, isc_event_t *event) {	isc_socketevent_t *sevent = (isc_socketevent_t *) event;	controlconnection_t *conn = event->ev_arg;	controllistener_t *listener = conn->listener;	isc_socket_t *sock = (isc_socket_t *)sevent->ev_sender;	isc_result_t result;	REQUIRE(conn->sending);	UNUSED(task);	conn->sending = ISC_FALSE;	if (sevent->result != ISC_R_SUCCESS &&	    sevent->result != ISC_R_CANCELED)	{		char socktext[ISC_SOCKADDR_FORMATSIZE];		isc_sockaddr_t peeraddr;		(void)isc_socket_getpeername(sock, &peeraddr);		isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,			      NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,			      "error sending command response to %s: %s",			      socktext, isc_result_totext(sevent->result));	}	isc_event_free(&event);	result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task,					 control_recvmessage, conn);	if (result != ISC_R_SUCCESS) {		isc_socket_detach(&conn->sock);		maybe_free_connection(conn);		maybe_free_listener(listener);	}}static inline voidlog_invalid(isccc_ccmsg_t *ccmsg, isc_result_t result) {	char socktext[ISC_SOCKADDR_FORMATSIZE];	isc_sockaddr_t peeraddr;	(void)isc_socket_getpeername(ccmsg->sock, &peeraddr);	isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));	isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,		      NS_LOGMODULE_CONTROL, ISC_LOG_ERROR,		      "invalid command from %s: %s",		      socktext, isc_result_totext(result));}static voidcontrol_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;	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[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;	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;		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;	}	/* We shouldn't be getting a reply. */	if (isccc_cc_isreply(request)) {		log_invalid(&conn->ccmsg, ISC_R_FAILURE);		goto cleanup;	}	isc_stdtime_get(&now);	/*	 * Limit exposure to replay attacks.	 */	_ctrl = isccc_alist_lookup(request, "_ctrl");	if (_ctrl == NULL) {		log_invalid(&conn->ccmsg, ISC_R_FAILURE);		goto cleanup;	}	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;		}	} else {		log_invalid(&conn->ccmsg, ISC_R_FAILURE);		goto cleanup;	}	/*	 * 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;	}	/*	 * 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;	}	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;	}	/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -