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

📄 controlconf.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 3 页
字号:
		goto cleanup;	}	/*	 * Establish nonce.	 */	while (conn->nonce == 0)		isc_random_get(&conn->nonce);	isc_buffer_init(&text, textarray, sizeof(textarray));	eresult = ns_control_docommand(request, &text);	result = isccc_cc_createresponse(request, now, now + 60, &response);	if (result != ISC_R_SUCCESS)		goto cleanup;	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;		}	}	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;		}	}	_ctrl = isccc_alist_lookup(response, "_ctrl");	if (_ctrl == NULL ||	    isccc_cc_defineuint32(_ctrl, "_nonce", conn->nonce) == NULL)		goto cleanup;	ccregion.rstart = conn->buffer + 4;	ccregion.rend = conn->buffer + sizeof(conn->buffer);	result = isccc_cc_towire(response, &ccregion, &secret);	if (result != ISC_R_SUCCESS)		goto cleanup;	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;	conn->sending = ISC_TRUE;	if (secret.rstart != NULL)		isc_mem_put(listener->mctx, secret.rstart,			    REGION_SIZE(secret));	if (request != NULL)		isccc_sexpr_free(&request);	if (response != NULL)		isccc_sexpr_free(&response);	return; cleanup:	if (secret.rstart != NULL)		isc_mem_put(listener->mctx, secret.rstart,			    REGION_SIZE(secret));	isc_socket_detach(&conn->sock);	isccc_ccmsg_invalidate(&conn->ccmsg);	conn->ccmsg_valid = ISC_FALSE;	maybe_free_connection(conn);	maybe_free_listener(listener);	if (request != NULL)		isccc_sexpr_free(&request);	if (response != NULL)		isccc_sexpr_free(&response);}static voidcontrol_timeout(isc_task_t *task, isc_event_t *event) {	controlconnection_t *conn = event->ev_arg;	UNUSED(task);	isc_timer_detach(&conn->timer);	maybe_free_connection(conn);	isc_event_free(&event);}static isc_result_tnewconnection(controllistener_t *listener, isc_socket_t *sock) {	controlconnection_t *conn;	isc_interval_t interval;	isc_result_t result;	conn = isc_mem_get(listener->mctx, sizeof(*conn));	if (conn == NULL)		return (ISC_R_NOMEMORY);		conn->sock = sock;	isccc_ccmsg_init(listener->mctx, sock, &conn->ccmsg);	conn->ccmsg_valid = ISC_TRUE;	conn->sending = ISC_FALSE;	conn->timer = NULL;	isc_interval_set(&interval, 60, 0);	result = isc_timer_create(ns_g_timermgr, isc_timertype_once,				  NULL, &interval, listener->task,				  control_timeout, conn, &conn->timer);	if (result != ISC_R_SUCCESS)		goto cleanup;	conn->listener = listener;	conn->nonce = 0;	ISC_LINK_INIT(conn, link);	result = isccc_ccmsg_readmessage(&conn->ccmsg, listener->task,					 control_recvmessage, conn);	if (result != ISC_R_SUCCESS)		goto cleanup;	isccc_ccmsg_setmaxsize(&conn->ccmsg, 2048);	ISC_LIST_APPEND(listener->connections, conn, link);	return (ISC_R_SUCCESS); cleanup:	isccc_ccmsg_invalidate(&conn->ccmsg);	if (conn->timer != NULL)		isc_timer_detach(&conn->timer);	isc_mem_put(listener->mctx, conn, sizeof(*conn));	return (result);}static voidcontrol_newconn(isc_task_t *task, isc_event_t *event) {	isc_socket_newconnev_t *nevent = (isc_socket_newconnev_t *)event;	controllistener_t *listener = event->ev_arg;	isc_socket_t *sock;	isc_sockaddr_t peeraddr;	isc_result_t result;	UNUSED(task);	listener->listening = ISC_FALSE;	if (nevent->result != ISC_R_SUCCESS) {		if (nevent->result == ISC_R_CANCELED) {			shutdown_listener(listener);			goto cleanup;		}		goto restart;	}	sock = nevent->newsocket;	(void)isc_socket_getpeername(sock, &peeraddr);	if (!address_ok(&peeraddr, listener->acl)) {		char socktext[ISC_SOCKADDR_FORMATSIZE];		isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,			      NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,			      "rejected command channel message from %s",			      socktext);		isc_socket_detach(&sock);		goto restart;	}	result = newconnection(listener, sock);	if (result != ISC_R_SUCCESS) {		char socktext[ISC_SOCKADDR_FORMATSIZE];		isc_sockaddr_format(&peeraddr, socktext, sizeof(socktext));		isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL,			      NS_LOGMODULE_CONTROL, ISC_LOG_WARNING,			      "dropped command channel from %s: %s",			      socktext, isc_result_totext(result));		isc_socket_detach(&sock);		goto restart;	} restart:	control_next(listener); cleanup:	isc_event_free(&event);}static voidcontrols_shutdown(ns_controls_t *controls) {	controllistener_t *listener;	controllistener_t *next;	for (listener = ISC_LIST_HEAD(controls->listeners);	     listener != NULL;	     listener = next)	{		/*		 * This is asynchronous.  As listeners shut down, they will		 * call their callbacks.		 */		next = ISC_LIST_NEXT(listener, link);		shutdown_listener(listener);	}}voidns_controls_shutdown(ns_controls_t *controls) {	controls_shutdown(controls);	controls->shuttingdown = ISC_TRUE;}static isc_result_tcfgkeylist_find(cfg_obj_t *keylist, const char *keyname, cfg_obj_t **objp) {	cfg_listelt_t *element;	const char *str;	cfg_obj_t *obj;	for (element = cfg_list_first(keylist);	     element != NULL;	     element = cfg_list_next(element))	{		obj = cfg_listelt_value(element);		str = cfg_obj_asstring(cfg_map_getname(obj));		if (strcasecmp(str, keyname) == 0)			break;	}	if (element == NULL)		return (ISC_R_NOTFOUND);	obj = cfg_listelt_value(element);	*objp = obj;	return (ISC_R_SUCCESS);}static isc_result_tcontrolkeylist_fromcfg(cfg_obj_t *keylist, isc_mem_t *mctx,		       controlkeylist_t *keyids){	cfg_listelt_t *element;	char *newstr = NULL;	const char *str;	cfg_obj_t *obj;	controlkey_t *key = NULL;	for (element = cfg_list_first(keylist);	     element != NULL;	     element = cfg_list_next(element))	{		obj = cfg_listelt_value(element);		str = cfg_obj_asstring(obj);		newstr = isc_mem_strdup(mctx, str);		if (newstr == NULL)			goto cleanup;		key = isc_mem_get(mctx, sizeof(*key));		if (key == NULL)			goto cleanup;		key->keyname = newstr;		key->secret.base = NULL;		key->secret.length = 0;		ISC_LINK_INIT(key, link);		ISC_LIST_APPEND(*keyids, key, link);		key = NULL;		newstr = NULL;	}	return (ISC_R_SUCCESS); cleanup:	if (newstr != NULL)		isc_mem_free(mctx, newstr);	if (key != NULL)		isc_mem_put(mctx, key, sizeof(*key));	free_controlkeylist(keyids, mctx);	return (ISC_R_NOMEMORY);}static voidregister_keys(cfg_obj_t *control, cfg_obj_t *keylist,	      controlkeylist_t *keyids, isc_mem_t *mctx, const char *socktext){	controlkey_t *keyid, *next;	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 {			cfg_obj_t *algobj = NULL;			cfg_obj_t *secretobj = NULL;			char *algstr = NULL;			char *secretstr = NULL;			(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_getkeyalgorithm(algstr, 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;			}			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;			}			memcpy(keyid->secret.base, isc_buffer_base(&b),			       keyid->secret.length);		}	}}#define CHECK(x) \	do { \		 result = (x); \		 if (result != ISC_R_SUCCESS) \			goto cleanup; \	} while (0)		static isc_result_tget_rndckey(isc_mem_t *mctx, controlkeylist_t *keyids) {	isc_result_t result;	cfg_parser_t *pctx = NULL;	cfg_obj_t *config = NULL;	cfg_obj_t *key = NULL;	cfg_obj_t *algobj = NULL;	cfg_obj_t *secretobj = NULL;	char *algstr = NULL;	char *secretstr = NULL;	controlkey_t *keyid = NULL;	char secret[1024];	isc_buffer_t b;	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;	ISC_LINK_INIT(keyid, link);	if (keyid->keyname == NULL) 		CHECK(ISC_R_NOMEMORY);	CHECK(cfg_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_getkeyalgorithm(algstr, 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;	}	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));		CHECK(result);	}	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);	}	memcpy(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);

⌨️ 快捷键说明

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