317. [func] Use callbacks from libomapi to determine if a
new connection is valid, and if a key requested to be used with that connection is valid.
This commit is contained in:
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: omapi.h,v 1.13 2000/06/23 21:05:21 tale Exp $ */
|
||||
/* $Id: omapi.h,v 1.14 2000/07/10 11:22:59 tale Exp $ */
|
||||
|
||||
/*
|
||||
* Definitions for the object management API and protocol.
|
||||
@@ -114,10 +114,20 @@ omapi_protocol_connect(omapi_object_t *object, const char *server,
|
||||
void
|
||||
omapi_protocol_disconnect(omapi_object_t *handle, isc_boolean_t force);
|
||||
|
||||
/*
|
||||
* XXXDCL The use of one void *arg for all three callbacks/taskactions is
|
||||
* questionable.
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_protocol_listen(omapi_object_t *mgr, isc_sockaddr_t *addr,
|
||||
dns_acl_t *acl, int backlog,
|
||||
isc_taskaction_t destroy_action, void *destroy_arg);
|
||||
isc_boolean_t ((*verify_connection)
|
||||
(isc_sockaddr_t *incoming,
|
||||
void *connect_arg)),
|
||||
isc_boolean_t ((*verify_key)
|
||||
(const char *name,
|
||||
unsigned int algorithm,
|
||||
void *key_arg)),
|
||||
isc_taskaction_t destroy_action, void *arg);
|
||||
|
||||
/*
|
||||
* Public functions defined in connection.c.
|
||||
@@ -152,8 +162,14 @@ omapi_connection_puthandle(omapi_object_t *connection, omapi_object_t *object);
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_listener_listen(omapi_object_t *mgr, isc_sockaddr_t *addr,
|
||||
dns_acl_t *acl, unsigned int backlog,
|
||||
isc_taskaction_t destroy_action, void *destroy_arg);
|
||||
isc_boolean_t ((*verify_connection)
|
||||
(isc_sockaddr_t *incoming,
|
||||
void *connect_arg)),
|
||||
isc_boolean_t ((*verify_key)
|
||||
(const char *name,
|
||||
unsigned int algorithm,
|
||||
void *key_arg)),
|
||||
isc_taskaction_t destroy_action, void *arg);
|
||||
|
||||
void
|
||||
omapi_listener_shutdown(omapi_object_t *mgr);
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: private.h,v 1.21 2000/06/23 21:28:31 tale Exp $ */
|
||||
/* $Id: private.h,v 1.22 2000/07/10 11:23:00 tale Exp $ */
|
||||
|
||||
/*****
|
||||
***** Private master include file for the OMAPI library.
|
||||
@@ -242,6 +242,15 @@ struct omapi_protocol {
|
||||
isc_region_t signature_in;
|
||||
isc_buffer_t *signature_out;
|
||||
isc_result_t verify_result;
|
||||
/*
|
||||
* A callback to find out whether a requested key is valid on
|
||||
* the connection, and the arg the caller wants to help it decide.
|
||||
* Only gets set on the server side.
|
||||
*/
|
||||
isc_boolean_t ((*verify_key)(const char *name,
|
||||
unsigned int algorithm,
|
||||
void *key_arg));
|
||||
void * verify_key_arg;
|
||||
};
|
||||
|
||||
/*****
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: listener.c,v 1.26 2000/06/23 22:28:22 tale Exp $ */
|
||||
/* $Id: listener.c,v 1.27 2000/07/10 11:22:56 tale Exp $ */
|
||||
|
||||
/*
|
||||
* Subroutines that support the generic listener object.
|
||||
@@ -39,7 +39,11 @@ typedef struct omapi_listener_object {
|
||||
isc_mutex_t mutex;
|
||||
isc_task_t *task;
|
||||
isc_socket_t *socket; /* Listening socket. */
|
||||
dns_acl_t *acl;
|
||||
isc_boolean_t (*verify_connection)(isc_sockaddr_t *sockaddr,
|
||||
void *connect_arg);
|
||||
isc_boolean_t (*verify_key)(const char *name, unsigned int algorithm,
|
||||
void *key_arg);
|
||||
void *callback_arg;
|
||||
/*
|
||||
* Locked by mutex.
|
||||
*/
|
||||
@@ -73,20 +77,18 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
isc_buffer_t *ibuffer = NULL;
|
||||
isc_buffer_t *obuffer = NULL;
|
||||
isc_task_t *connection_task = NULL;
|
||||
isc_socket_t *socket;
|
||||
isc_socket_t *sock;
|
||||
isc_sockaddr_t sockaddr;
|
||||
isc_netaddr_t netaddr;
|
||||
omapi_connection_t *connection = NULL;
|
||||
omapi_object_t *protocol = NULL;
|
||||
omapi_protocol_t *protocol = NULL;
|
||||
omapi_listener_t *listener;
|
||||
int match;
|
||||
|
||||
/*
|
||||
* XXXDCL audit error handling
|
||||
*/
|
||||
|
||||
result = ((isc_socket_newconnev_t *)event)->result;
|
||||
socket = ((isc_socket_newconnev_t *)event)->newsocket;
|
||||
sock = ((isc_socket_newconnev_t *)event)->newsocket;
|
||||
listener = (omapi_listener_t *)event->ev_arg;
|
||||
|
||||
/*
|
||||
@@ -151,21 +153,14 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
/*
|
||||
* Is the connection from a valid host?
|
||||
*/
|
||||
result = isc_socket_getpeername(socket, &sockaddr);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
isc_netaddr_fromsockaddr(&netaddr, &sockaddr);
|
||||
|
||||
result = dns_acl_match(&netaddr, NULL, listener->acl,
|
||||
NULL, &match, NULL);
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS || match <= 0) {
|
||||
result = isc_socket_getpeername(sock, &sockaddr);
|
||||
if (result != ISC_R_SUCCESS ||
|
||||
!listener->verify_connection(&sockaddr, listener->callback_arg)) {
|
||||
/*
|
||||
* Permission denied. Close the connection.
|
||||
* XXXDCL isc_log_write an error.
|
||||
*/
|
||||
isc_socket_detach(&socket);
|
||||
isc_socket_detach(&sock);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -198,7 +193,7 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
|
||||
connection->task = connection_task;
|
||||
connection->state = omapi_connection_connected;
|
||||
connection->socket = socket;
|
||||
connection->socket = sock;
|
||||
connection->is_client = ISC_FALSE;
|
||||
|
||||
ISC_LIST_INIT(connection->input_buffers);
|
||||
@@ -211,11 +206,19 @@ listener_accept(isc_task_t *task, isc_event_t *event) {
|
||||
* connection.
|
||||
*/
|
||||
protocol = NULL;
|
||||
result = omapi_object_create(&protocol, omapi_type_protocol,
|
||||
result = omapi_object_create((omapi_object_t **)&protocol,
|
||||
omapi_type_protocol,
|
||||
sizeof(omapi_protocol_t));
|
||||
if (result != ISC_R_SUCCESS)
|
||||
goto free_connection_object;
|
||||
|
||||
|
||||
/*
|
||||
* Hand off the key verification information to the protocol object.
|
||||
*/
|
||||
protocol->verify_key = listener->verify_key;
|
||||
protocol->verify_key_arg = listener->callback_arg;
|
||||
|
||||
/*
|
||||
* Tie the protocol object bidirectionally to the connection
|
||||
* object, with the connection as the outer object.
|
||||
@@ -274,15 +277,21 @@ free_task:
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
omapi_listener_listen(omapi_object_t *caller, isc_sockaddr_t *addr,
|
||||
dns_acl_t *acl, unsigned int backlog,
|
||||
isc_taskaction_t destroy_action, void *destroy_arg)
|
||||
omapi_listener_listen(omapi_object_t *manager, isc_sockaddr_t *addr,
|
||||
isc_boolean_t ((*verify_connection)
|
||||
(isc_sockaddr_t *incoming,
|
||||
void *connect_arg)),
|
||||
isc_boolean_t ((*verify_key)
|
||||
(const char *name,
|
||||
unsigned int algorithm,
|
||||
void *key_arg)),
|
||||
isc_taskaction_t destroy_action, void *arg)
|
||||
{
|
||||
isc_result_t result;
|
||||
isc_task_t *task;
|
||||
omapi_listener_t *listener;
|
||||
|
||||
REQUIRE(caller != NULL);
|
||||
REQUIRE(manager != NULL);
|
||||
REQUIRE(addr != NULL && isc_sockaddr_getport(addr) != 0);
|
||||
|
||||
task = NULL;
|
||||
@@ -321,14 +330,13 @@ omapi_listener_listen(omapi_object_t *caller, isc_sockaddr_t *addr,
|
||||
/*
|
||||
* Now tell the kernel to listen for connections.
|
||||
*/
|
||||
result = isc_socket_listen(listener->socket, backlog);
|
||||
result = isc_socket_listen(listener->socket, 0);
|
||||
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* Queue up the first accept event. The listener object
|
||||
* will be passed to listener_accept() when it is called.
|
||||
*/
|
||||
dns_acl_attach(acl, &listener->acl);
|
||||
listener->listening = ISC_TRUE;
|
||||
result = isc_socket_accept(listener->socket, task,
|
||||
listener_accept, listener);
|
||||
@@ -338,16 +346,18 @@ omapi_listener_listen(omapi_object_t *caller, isc_sockaddr_t *addr,
|
||||
/*
|
||||
* Tie the listener object to the calling object.
|
||||
*/
|
||||
OBJECT_REF(&caller->outer, listener);
|
||||
OBJECT_REF(&listener->inner, caller);
|
||||
OBJECT_REF(&manager->outer, listener);
|
||||
OBJECT_REF(&listener->inner, manager);
|
||||
|
||||
/*
|
||||
* The callback is not set until here because it should
|
||||
* The destroy action is not set until here because it should
|
||||
* only be called if the listener was successfully set up.
|
||||
*/
|
||||
listener->destroy_action = destroy_action;
|
||||
listener->destroy_arg = destroy_arg;
|
||||
|
||||
listener->destroy_arg = arg;
|
||||
listener->verify_connection = verify_connection;
|
||||
listener->verify_key = verify_key;
|
||||
listener->callback_arg = arg;
|
||||
|
||||
} else {
|
||||
/*
|
||||
@@ -430,9 +440,6 @@ listener_destroy(omapi_object_t *listener) {
|
||||
|
||||
if (l->socket != NULL)
|
||||
isc_socket_detach(&l->socket);
|
||||
|
||||
if (l->acl != NULL)
|
||||
dns_acl_detach(&l->acl);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: protocol.c,v 1.28 2000/06/23 21:36:57 tale Exp $ */
|
||||
/* $Id: protocol.c,v 1.29 2000/07/10 11:22:58 tale Exp $ */
|
||||
|
||||
/*
|
||||
* Functions supporting the object management protocol.
|
||||
@@ -197,11 +197,17 @@ send_intro(omapi_object_t *h, unsigned int ver) {
|
||||
*/
|
||||
isc_result_t
|
||||
omapi_protocol_listen(omapi_object_t *manager, isc_sockaddr_t *addr,
|
||||
dns_acl_t *acl, int max,
|
||||
isc_taskaction_t destroy_action, void *destroy_arg)
|
||||
isc_boolean_t ((*verify_connection)
|
||||
(isc_sockaddr_t *incoming,
|
||||
void *connect_arg)),
|
||||
isc_boolean_t ((*verify_key)
|
||||
(const char *name,
|
||||
unsigned int algorithm,
|
||||
void *key_arg)),
|
||||
isc_taskaction_t destroy_action, void *arg)
|
||||
{
|
||||
return (omapi_listener_listen((omapi_object_t *)manager, addr,
|
||||
acl, max, destroy_action, destroy_arg));
|
||||
return (omapi_listener_listen(manager, addr, verify_connection,
|
||||
verify_key, destroy_action, arg));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
@@ -713,6 +719,20 @@ protocol_setvalue(omapi_object_t *h, omapi_string_t *name, omapi_data_t *value)
|
||||
if (p->authname != NULL && p->algorithm != 0) {
|
||||
unsigned int sigsize;
|
||||
|
||||
/*
|
||||
* Verifying the key through a callback is (currently) only
|
||||
* done by the server.
|
||||
* XXXDCL the client should have some way of checking whether
|
||||
* what is being set is what it asked for.
|
||||
*/
|
||||
if (p->verify_key != NULL &&
|
||||
!p->verify_key(p->authname, p->algorithm,
|
||||
p->verify_key_arg))
|
||||
return (ISC_R_NOPERM);
|
||||
|
||||
if (p->key != NULL)
|
||||
dst_key_free(&p->key);
|
||||
|
||||
result = auth_makekey(p->authname, p->algorithm, &p->key);
|
||||
|
||||
if (result == ISC_R_SUCCESS)
|
||||
|
||||
Reference in New Issue
Block a user