summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.dist2
-rw-r--r--client/clparse.c5
-rw-r--r--common/alloc.c133
-rw-r--r--common/dns.c51
-rw-r--r--common/parse.c30
-rw-r--r--dhcpctl/Makefile.dist8
-rw-r--r--dhcpctl/cltest.c77
-rw-r--r--dhcpctl/dhcpctl.c1
-rw-r--r--dhcpctl/dhcpctl.h12
-rw-r--r--dhcpctl/remote.c50
-rw-r--r--includes/auth.h59
-rw-r--r--includes/dhcpd.h26
-rw-r--r--includes/omapip/omapip.h52
-rw-r--r--includes/omapip/omapip_p.h37
-rw-r--r--minires/dst_api.c8
-rw-r--r--omapip/Makefile.dist8
-rw-r--r--omapip/auth.c271
-rw-r--r--omapip/buffer.c28
-rw-r--r--omapip/connection.c225
-rw-r--r--omapip/dispatch.c11
-rw-r--r--omapip/listener.c43
-rw-r--r--omapip/message.c165
-rw-r--r--omapip/protocol.c447
-rw-r--r--omapip/support.c49
-rw-r--r--relay/Makefile.dist2
-rw-r--r--server/dhcpd.c38
-rw-r--r--server/stables.c4
27 files changed, 1467 insertions, 375 deletions
diff --git a/Makefile.dist b/Makefile.dist
index e51feb24..57802349 100644
--- a/Makefile.dist
+++ b/Makefile.dist
@@ -17,7 +17,7 @@
# http://www.isc.org for more information.
#
-SUBDIRS= common omapip $(MINIRES) server client relay dhcpctl
+SUBDIRS= common $(MINIRES) omapip server client relay dhcpctl
all:
@for dir in ${SUBDIRS}; do \
diff --git a/client/clparse.c b/client/clparse.c
index 48ffa7d1..97915253 100644
--- a/client/clparse.c
+++ b/client/clparse.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: clparse.c,v 1.48 2000/07/20 00:53:17 mellon Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: clparse.c,v 1.49 2000/08/03 20:59:31 neild Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -948,7 +948,8 @@ void parse_client_lease_declaration (cfile, lease, ipp, clientp)
skip_to_semi (cfile);
break;
}
- if (tsig_key_lookup (&lease -> key, val) != ISC_R_SUCCESS)
+ if (omapi_auth_key_lookup_name (&lease -> key, val) !=
+ ISC_R_SUCCESS)
parse_warn (cfile, "unknown key %s", val);
parse_semi (cfile);
break;
diff --git a/common/alloc.c b/common/alloc.c
index 7cb83e19..040d826a 100644
--- a/common/alloc.c
+++ b/common/alloc.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: alloc.c,v 1.51 2000/08/01 22:54:47 neild Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: alloc.c,v 1.52 2000/08/03 20:59:33 neild Exp $ Copyright (c) 1996-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -292,29 +292,6 @@ void free_client_lease (lease, file, line)
dfree (lease, file, line);
}
-struct auth_key *new_auth_key (len, file, line)
- unsigned len;
- const char *file;
- int line;
-{
- struct auth_key *peer;
- unsigned size = len - 1 + sizeof (struct auth_key);
-
- peer = (struct auth_key *)dmalloc (size, file, line);
- if (!peer)
- return peer;
- memset (peer, 0, size);
- return peer;
-}
-
-void free_auth_key (peer, file, line)
- struct auth_key *peer;
- const char *file;
- int line;
-{
- dfree (peer, file, line);
-}
-
pair free_pairs;
pair new_pair (file, line)
@@ -1002,114 +979,6 @@ int packet_dereference (ptr, file, line)
return 1;
}
-int tsig_key_allocate (ptr, file, line)
- struct tsig_key **ptr;
- const char *file;
- int line;
-{
- int size;
-
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct tsig_key *)0;
-#endif
- }
-
- *ptr = dmalloc (sizeof **ptr, file, line);
- if (*ptr) {
- memset (*ptr, 0, sizeof **ptr);
- (*ptr) -> refcnt = 1;
- return 1;
- }
- return 0;
-}
-
-int tsig_key_reference (ptr, bp, file, line)
- struct tsig_key **ptr;
- struct tsig_key *bp;
- const char *file;
- int line;
-{
- if (!ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
- if (*ptr) {
- log_error ("%s(%d): non-null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- *ptr = (struct tsig_key *)0;
-#endif
- }
- *ptr = bp;
- bp -> refcnt++;
- rc_register (file, line, ptr, bp, bp -> refcnt);
- dmalloc_reuse (bp, file, line, 1);
- return 1;
-}
-
-int tsig_key_dereference (ptr, file, line)
- struct tsig_key **ptr;
- const char *file;
- int line;
-{
- int i;
- struct tsig_key *tsig_key;
-
- if (!ptr || !*ptr) {
- log_error ("%s(%d): null pointer", file, line);
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- tsig_key = *ptr;
- *ptr = (struct tsig_key *)0;
- --tsig_key -> refcnt;
- rc_register (file, line, ptr, tsig_key, tsig_key -> refcnt);
- if (tsig_key -> refcnt > 0)
- return 1;
-
- if (tsig_key -> refcnt < 0) {
- log_error ("%s(%d): negative refcnt!", file, line);
-#if defined (DEBUG_RC_HISTORY)
- dump_rc_history ();
-#endif
-#if defined (POINTER_DEBUG)
- abort ();
-#else
- return 0;
-#endif
- }
-
- if (tsig_key -> name)
- dfree (tsig_key -> name, file, line);
- if (tsig_key -> algorithm)
- dfree (tsig_key -> algorithm, file, line);
- if (tsig_key -> key.buffer)
- data_string_forget (&tsig_key -> key, file, line);
- dfree (tsig_key, file, line);
- return 1;
-}
-
int dns_zone_allocate (ptr, file, line)
struct dns_zone **ptr;
const char *file;
diff --git a/common/dns.c b/common/dns.c
index 0d029da9..31800bfc 100644
--- a/common/dns.c
+++ b/common/dns.c
@@ -42,7 +42,7 @@
#ifndef lint
static char copyright[] =
-"$Id: dns.c,v 1.26 2000/07/05 07:14:26 mellon Exp $ Copyright (c) 2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: dns.c,v 1.27 2000/08/03 20:59:34 neild Exp $ Copyright (c) 2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -158,7 +158,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
strlen (zone -> key -> name) > NS_MAXDNAME) ||
(!zone -> key -> algorithm ||
strlen (zone -> key -> algorithm) > NS_MAXDNAME) ||
- (!zone -> key -> key.len)) {
+ (!zone -> key)) {
dns_zone_dereference (&zone, MDL);
return ISC_R_INVALIDKEY;
}
@@ -169,7 +169,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
return ISC_R_NOMEMORY;
}
memset (tkey, 0, sizeof *tkey);
- tkey -> data = dmalloc (zone -> key -> key.len, MDL);
+ tkey -> data = dmalloc (zone -> key -> key -> len, MDL);
if (!tkey -> data) {
dfree (tkey, MDL);
goto nomem;
@@ -177,8 +177,8 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
strcpy (tkey -> name, zone -> key -> name);
strcpy (tkey -> alg, zone -> key -> algorithm);
memcpy (tkey -> data,
- zone -> key -> key.data, zone -> key -> key.len);
- tkey -> len = zone -> key -> key.len;
+ zone -> key -> key -> value, zone -> key -> key -> len);
+ tkey -> len = zone -> key -> key -> len;
*key = tkey;
return ISC_R_SUCCESS;
}
@@ -249,44 +249,6 @@ isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name)
return status;
}
-isc_result_t enter_tsig_key (struct tsig_key *tkey)
-{
- struct tsig_key *tk = (struct tsig_key *)0;
-
- if (tsig_key_hash) {
- tsig_key_hash_lookup (&tk, tsig_key_hash,
- tkey -> name, 0, MDL);
- if (tk == tkey) {
- tsig_key_dereference (&tk, MDL);
- return ISC_R_SUCCESS;
- }
- if (tk) {
- tsig_key_hash_delete (tsig_key_hash,
- tkey -> name, 0, MDL);
- tsig_key_dereference (&tk, MDL);
- }
- } else {
- tsig_key_hash =
- new_hash ((hash_reference)tsig_key_reference,
- (hash_dereference)tsig_key_dereference, 1);
- if (!tsig_key_hash)
- return ISC_R_NOMEMORY;
- }
- tsig_key_hash_add (tsig_key_hash, tkey -> name, 0, tkey, MDL);
- return ISC_R_SUCCESS;
-
-}
-
-isc_result_t tsig_key_lookup (struct tsig_key **tkey, const char *name) {
- struct tsig_key *tk;
-
- if (!tsig_key_hash)
- return ISC_R_NOTFOUND;
- if (!tsig_key_hash_lookup (tkey, tsig_key_hash, name, 0, MDL))
- return ISC_R_NOTFOUND;
- return ISC_R_SUCCESS;
-}
-
int dns_zone_dereference (ptr, file, line)
struct dns_zone **ptr;
const char *file;
@@ -326,7 +288,7 @@ int dns_zone_dereference (ptr, file, line)
if (dns_zone -> name)
dfree (dns_zone -> name, file, line);
if (dns_zone -> key)
- tsig_key_dereference (&dns_zone -> key, file, line);
+ omapi_auth_key_dereference (&dns_zone -> key, file, line);
if (dns_zone -> primary)
option_cache_dereference (&dns_zone -> primary, file, line);
if (dns_zone -> secondary)
@@ -447,4 +409,3 @@ void repudiate_zone (struct dns_zone **zone)
#endif /* NSUPDATE */
HASH_FUNCTIONS (dns_zone, const char *, struct dns_zone)
-HASH_FUNCTIONS (tsig_key, const char *, struct tsig_key)
diff --git a/common/parse.c b/common/parse.c
index fdbf6598..30f7c641 100644
--- a/common/parse.c
+++ b/common/parse.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: parse.c,v 1.77 2000/07/06 09:57:23 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: parse.c,v 1.78 2000/08/03 20:59:36 neild Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -1806,7 +1806,8 @@ int parse_zone (struct dns_zone *zone, struct parse *cfile)
skip_to_semi (cfile);
return 0;
}
- if (tsig_key_lookup (&zone -> key, val) != ISC_R_SUCCESS)
+ if (omapi_auth_key_lookup_name (&zone -> key, val) !=
+ ISC_R_SUCCESS)
parse_warn (cfile, "unknown key %s", val);
if (!parse_semi (cfile))
return 0;
@@ -1839,7 +1840,8 @@ int parse_key (struct parse *cfile)
int token;
const char *val;
int done = 0;
- struct tsig_key *key;
+ struct auth_key *key;
+ struct data_string ds;
isc_result_t status;
token = next_token (&val, cfile);
@@ -1848,8 +1850,8 @@ int parse_key (struct parse *cfile)
skip_to_semi (cfile);
return 0;
}
- key = (struct tsig_key *)0;
- if (!tsig_key_allocate (&key, MDL))
+ key = (struct auth_key *)0;
+ if (omapi_auth_key_new (&key, MDL) != ISC_R_SUCCESS)
log_fatal ("no memory for tsig key");
key -> name = dmalloc (strlen (val) + 1, MDL);
if (!key -> name)
@@ -1883,13 +1885,23 @@ int parse_key (struct parse *cfile)
break;
case SECRET:
- if (key -> key.buffer) {
+ if (key -> key) {
parse_warn (cfile, "key %s: too many secrets",
key -> name);
goto rbad;
}
- if (!parse_base64 (&key -> key, cfile))
+
+ memset (&ds, 0, sizeof(ds));
+ if (!parse_base64 (&ds, cfile))
+ goto rbad;
+ status = omapi_data_string_new (&key -> key, ds.len,
+ MDL);
+ if (status != ISC_R_SUCCESS)
goto rbad;
+ memcpy (key -> key -> value,
+ ds.buffer -> data, ds.len);
+ data_string_forget (&ds, MDL);
+
if (!parse_semi (cfile))
goto rbad;
break;
@@ -1910,7 +1922,7 @@ int parse_key (struct parse *cfile)
token = next_token (&val, cfile);
/* Remember the key. */
- status = enter_tsig_key (key);
+ status = omapi_auth_key_enter (key);
if (status != ISC_R_SUCCESS) {
parse_warn (cfile, "tsig key %s: %s",
key -> name, isc_result_totext (status));
@@ -1921,7 +1933,7 @@ int parse_key (struct parse *cfile)
rbad:
skip_to_rbrace (cfile, 1);
bad:
- tsig_key_dereference (&key, MDL);
+ omapi_auth_key_dereference (&key, MDL);
return 0;
}
/*
diff --git a/dhcpctl/Makefile.dist b/dhcpctl/Makefile.dist
index 24c875c5..03206b5d 100644
--- a/dhcpctl/Makefile.dist
+++ b/dhcpctl/Makefile.dist
@@ -30,13 +30,13 @@ CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
all: libdhcpctl.a svtest cltest $(CATMANPAGES)
-svtest: test.o libdhcpctl.a ../omapip/libomapi.a
+svtest: test.o libdhcpctl.a ../omapip/libomapi.a $(BINDLIB)
$(CC) $(DEBUG) $(LFLAGS) -o svtest test.o libdhcpctl.a \
- ../omapip/libomapi.a $(LIBS)
+ ../omapip/libomapi.a $(BINDLIB) $(LIBS)
-cltest: cltest.o libdhcpctl.a ../omapip/libomapi.a
+cltest: cltest.o libdhcpctl.a ../omapip/libomapi.a $(BINDLIB)
$(CC) $(DEBUG) $(LFLAGS) -o cltest cltest.o libdhcpctl.a \
- ../omapip/libomapi.a $(LIBS)
+ ../omapip/libomapi.a $(BINDLIB) $(LIBS)
libdhcpctl.a: $(OBJ)
rm -f libdhcpctl.a
diff --git a/dhcpctl/cltest.c b/dhcpctl/cltest.c
index 904f037e..cc4bba83 100644
--- a/dhcpctl/cltest.c
+++ b/dhcpctl/cltest.c
@@ -46,30 +46,61 @@
int main (int, char **);
-enum modes { up, down };
+enum modes { up, down, undefined };
+
+static void usage (char *s) {
+ fprintf (stderr,
+ "Usage: %s [-n <username>] [-p <password>] [-a <algorithm>]"
+ "(-u | -d) <if>\n", s);
+ exit (1);
+}
int main (argc, argv)
int argc;
char **argv;
{
isc_result_t status, waitstatus;
+ dhcpctl_handle authenticator;
dhcpctl_handle connection;
dhcpctl_handle host_handle, group_handle, interface_handle;
dhcpctl_data_string cid;
dhcpctl_data_string result, groupname, identifier;
int i;
- int mode;
+ int mode = undefined;
+ char *name = 0, *pass = 0, *algorithm = "hmac-md5", *interface = 0;
const char *action;
-
- if (!strcmp (argv [1], "-u")) {
- mode = up;
- } else if (!strcmp (argv [1], "-d")) {
- mode = down;
- } else {
- fprintf (stderr, "Unknown switch \"%s\"\n", argv [1]);
- exit (1);
+
+ for (i = 1; i < argc; i++) {
+ if (!strcmp (argv[i], "-u")) {
+ mode = up;
+ } else if (!strcmp (argv [1], "-d")) {
+ mode = down;
+ } else if (!strcmp (argv[i], "-n")) {
+ if (++i == argc)
+ usage(argv[0]);
+ name = argv[i];
+ } else if (!strcmp (argv[i], "-p")) {
+ if (++i == argc)
+ usage(argv[0]);
+ pass = argv[i];
+ } else if (!strcmp (argv[i], "-a")) {
+ if (++i == argc)
+ usage(argv[0]);
+ algorithm = argv[i];
+ } else if (argv[i][0] == '-') {
+ usage(argv[0]);
+ } else {
+ interface = argv[i];
+ }
}
+ if (!interface)
+ usage(argv[0]);
+ if (mode == undefined)
+ usage(argv[0]);
+ if ((name || pass) && !(name && pass))
+ usage(argv[0]);
+
status = dhcpctl_initialize ();
if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_initialize: %s\n",
@@ -77,16 +108,29 @@ int main (argc, argv)
exit (1);
}
- memset (&connection, 0, sizeof connection);
+ authenticator = dhcpctl_null_handle;
+
+ if (name) {
+ status = dhcpctl_new_authenticator (&authenticator,
+ name, algorithm, pass,
+ strlen (pass) + 1);
+ if (status != ISC_R_SUCCESS) {
+ fprintf (stderr, "Cannot create authenticator: %s\n",
+ isc_result_totext (status));
+ exit (1);
+ }
+ }
+
+ connection = dhcpctl_null_handle;
status = dhcpctl_connect (&connection, "127.0.0.1", 7911,
- (dhcpctl_handle)0);
+ authenticator);
if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_connect: %s\n",
isc_result_totext (status));
exit (1);
}
- memset (&interface_handle, 0, sizeof interface_handle);
+ interface_handle = dhcpctl_null_handle;
status = dhcpctl_new_object (&interface_handle,
connection, "interface");
if (status != ISC_R_SUCCESS) {
@@ -95,7 +139,8 @@ int main (argc, argv)
exit (1);
}
- status = dhcpctl_set_string_value (interface_handle, argv [2], "name");
+ status = dhcpctl_set_string_value (interface_handle,
+ interface, "name");
if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_set_value: %s\n",
isc_result_totext (status));
@@ -104,7 +149,7 @@ int main (argc, argv)
if (mode == up) {
/* "up" the interface */
- printf ("upping interface %s\n", argv [2]);
+ printf ("upping interface %s\n", interface);
action = "create";
status = dhcpctl_open_object (interface_handle, connection,
DHCPCTL_CREATE | DHCPCTL_EXCL);
@@ -115,7 +160,7 @@ int main (argc, argv)
}
} else {
/* down the interface */
- printf ("downing interface %s\n", argv [2]);
+ printf ("downing interface %s\n", interface);
action = "remove";
status = dhcpctl_open_object (interface_handle, connection, 0);
if (status != ISC_R_SUCCESS) {
diff --git a/dhcpctl/dhcpctl.c b/dhcpctl/dhcpctl.c
index 2a8e7bfb..cf1a6014 100644
--- a/dhcpctl/dhcpctl.c
+++ b/dhcpctl/dhcpctl.c
@@ -91,6 +91,7 @@ dhcpctl_status dhcpctl_connect (dhcpctl_handle *connection,
dhcpctl_handle authinfo)
{
isc_result_t status;
+ dhcpctl_status waitstatus;
status = omapi_generic_new (connection, MDL);
if (status != ISC_R_SUCCESS) {
diff --git a/dhcpctl/dhcpctl.h b/dhcpctl/dhcpctl.h
index 8eb9c812..afe70a2c 100644
--- a/dhcpctl/dhcpctl.h
+++ b/dhcpctl/dhcpctl.h
@@ -50,9 +50,11 @@ typedef isc_result_t dhcpctl_status;
typedef omapi_object_t *dhcpctl_handle;
typedef omapi_data_string_t *dhcpctl_data_string;
-#define DHCPCTL_CREATE 1
-#define DHCPCTL_UPDATE 2
-#define DHCPCTL_EXCL 4
+#define dhcpctl_null_handle ((dhcpctl_handle) 0)
+
+#define DHCPCTL_CREATE OMAPI_CREATE
+#define DHCPCTL_UPDATE OMAPI_UPDATE
+#define DHCPCTL_EXCL OMAPI_EXCL
typedef struct {
OMAPI_OBJECT_PREAMBLE;
@@ -105,6 +107,10 @@ isc_result_t dhcpctl_callback_stuff_values (omapi_object_t *,
omapi_object_t *,
omapi_object_t *);
+dhcpctl_status dhcpctl_new_authenticator (dhcpctl_handle *,
+ const char *, const char *,
+ const char *, unsigned);
+
dhcpctl_status dhcpctl_open_object (dhcpctl_handle, dhcpctl_handle, int);
dhcpctl_status dhcpctl_new_object (dhcpctl_handle *,
dhcpctl_handle, const char *);
diff --git a/dhcpctl/remote.c b/dhcpctl/remote.c
index 07a6e1d1..54650874 100644
--- a/dhcpctl/remote.c
+++ b/dhcpctl/remote.c
@@ -44,6 +44,56 @@
#include <omapip/omapip_p.h>
#include "dhcpctl.h"
+/* dhcpctl_new_authenticator
+
+ synchronous - creates an authenticator object.
+ returns nonzero status code if the object couldn't be created
+ stores handle to authenticator through h if successful, and returns zero.
+ name is the authenticator name (NUL-terminated string).
+ algorithm is the NUL-terminated string name of the algorithm to use
+ (currently, only "hmac-md5" is supported).
+ secret and secret_len is the key secret. */
+
+dhcpctl_status dhcpctl_new_authenticator (dhcpctl_handle *h,
+ const char *name,
+ const char *algorithm,
+ const char *secret,
+ unsigned secret_len)
+{
+ struct auth_key *key = (struct auth_key *)0;
+ isc_result_t status;
+
+ status = omapi_auth_key_new (&key, MDL);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ key -> name = dmalloc (strlen (name) + 1, MDL);
+ if (!key -> name) {
+ omapi_auth_key_dereference (&key, MDL);
+ return ISC_R_NOMEMORY;
+ }
+ strcpy (key -> name, name);
+
+ key -> algorithm = dmalloc (strlen (algorithm) + 1, MDL);
+ if (!key -> algorithm) {
+ omapi_auth_key_dereference (&key, MDL);
+ return ISC_R_NOMEMORY;
+ }
+ strcpy (key -> algorithm, algorithm);
+
+ status = omapi_data_string_new (&key -> key, secret_len, MDL);
+ if (status != ISC_R_SUCCESS) {
+ omapi_auth_key_dereference (&key, MDL);
+ return status;
+ }
+ memcpy (key -> key -> value, secret, secret_len);
+ key -> key -> len = secret_len;
+
+ *h = (dhcpctl_handle) key;
+ return ISC_R_SUCCESS;
+}
+
+
/* dhcpctl_new_object
synchronous - creates a local handle for a host entry.
diff --git a/includes/auth.h b/includes/auth.h
deleted file mode 100644
index cc7dc065..00000000
--- a/includes/auth.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* auth.h
-
- Definitions to do with the DHCP authentication protocol... */
-
-/*
- * Copyright (c) 1996-1999 Internet Software Consortium.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of The Internet Software Consortium nor the names
- * of its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
- * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * This software has been written for the Internet Software Consortium
- * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
- * To learn more about the Internet Software Consortium, see
- * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
- * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
- * ``http://www.nominum.com''.
- */
-
-
-/* State structure for ongoing computation of a packet signature. */
-
-struct signature_state {
- u_int8_t *algorithm_state;
- u_int8_t *output;
- int output_len;
- void (*update) PROTO ((u_int8_t *, u_int8_t *, u_int8_t *));
- void (*final) PROTO ((u_int8_t *, u_int8_t *));
-};
-
-struct auth_key {
- unsigned length;
- u_int8_t data [1];
-};
-
diff --git a/includes/dhcpd.h b/includes/dhcpd.h
index f42307ec..9a008aff 100644
--- a/includes/dhcpd.h
+++ b/includes/dhcpd.h
@@ -74,7 +74,6 @@
#include "statement.h"
#include "tree.h"
#include "inet.h"
-#include "auth.h"
#include "dhctoken.h"
#include <isc/result.h>
@@ -373,6 +372,7 @@ struct lease_state {
#define SV_LIMITED_BROADCAST_ADDRESS 33
#define SV_REMOTE_PORT 34
#define SV_LOCAL_ADDRESS 35
+#define SV_OMAPI_KEY 36
#if !defined (DEFAULT_DEFAULT_LEASE_TIME)
# define DEFAULT_DEFAULT_LEASE_TIME 43200
@@ -589,13 +589,6 @@ struct class {
struct executable_statement *statements;
};
-struct tsig_key {
- int refcnt;
- char *name;
- char *algorithm;
- struct data_string key;
-};
-
/* DHCP client lease structure... */
struct client_lease {
struct client_lease *next; /* Next lease in list. */
@@ -604,7 +597,7 @@ struct client_lease {
char *server_name; /* Name of boot server. */
char *filename; /* Name of file we're supposed to boot. */
struct string_list *medium; /* Network medium. */
- struct tsig_key *key; /* Key used in basic DHCP authentication. */
+ struct auth_key *key; /* Key used in basic DHCP authentication. */
unsigned int is_static : 1; /* If set, lease is from config file. */
unsigned int is_bootp: 1; /* If set, lease was aquired with BOOTP. */
@@ -819,7 +812,7 @@ struct dns_zone {
char *name;
struct option_cache *primary;
struct option_cache *secondary;
- struct tsig_key *key;
+ struct auth_key *key;
};
/* Bitmask of dhcp option codes. */
@@ -1229,8 +1222,6 @@ void free_protocol PROTO ((struct protocol *, const char *, int));
void free_dhcp_packet PROTO ((struct dhcp_packet *, const char *, int));
struct client_lease *new_client_lease PROTO ((const char *, int));
void free_client_lease PROTO ((struct client_lease *, const char *, int));
-struct auth_key *new_auth_key PROTO ((unsigned, const char *, int));
-void free_auth_key PROTO ((struct auth_key *, const char *, int));
struct permit *new_permit PROTO ((const char *, int));
void free_permit PROTO ((struct permit *, const char *, int));
pair new_pair PROTO ((const char *, int));
@@ -1288,10 +1279,6 @@ int binding_scope_reference PROTO ((struct binding_scope **,
int dns_zone_allocate PROTO ((struct dns_zone **, const char *, int));
int dns_zone_reference PROTO ((struct dns_zone **,
struct dns_zone *, const char *, int));
-int tsig_key_allocate PROTO ((struct tsig_key **, const char *, int));
-int tsig_key_reference PROTO ((struct tsig_key **,
- struct tsig_key *, const char *, int));
-int tsig_key_dereference PROTO ((struct tsig_key **, const char *, int));
/* print.c */
char *print_hw_addr PROTO ((int, int, unsigned char *));
@@ -1760,8 +1747,6 @@ void tkey_free (ns_tsig_key **);
#endif
isc_result_t enter_dns_zone (struct dns_zone *);
isc_result_t dns_zone_lookup (struct dns_zone **, const char *);
-isc_result_t enter_tsig_key (struct tsig_key *);
-isc_result_t tsig_key_lookup (struct tsig_key **, const char *);
int dns_zone_dereference PROTO ((struct dns_zone **, const char *, int));
#if defined (NSUPDATE)
ns_rcode find_cached_zone (const char *, ns_class, char *,
@@ -1771,7 +1756,6 @@ void forget_zone (struct dns_zone **);
void repudiate_zone (struct dns_zone **);
#endif /* NSUPDATE */
HASH_FUNCTIONS_DECL (dns_zone, const char *, struct dns_zone)
-HASH_FUNCTIONS_DECL (tsig_key, const char *, struct tsig_key)
/* resolv.c */
extern char path_resolv_conf [];
@@ -1825,10 +1809,6 @@ int find_matching_case (struct executable_statement **,
struct binding_scope **,
struct expression *, struct executable_statement *);
-/* auth.c */
-void enter_auth_key PROTO ((struct data_string *, struct auth_key *));
-const struct auth_key *auth_key_lookup PROTO ((struct data_string *));
-
/* comapi.c */
extern omapi_object_type_t *dhcp_type_interface;
extern omapi_object_type_t *dhcp_type_group;
diff --git a/includes/omapip/omapip.h b/includes/omapip/omapip.h
index c9c6b974..ecd80061 100644
--- a/includes/omapip/omapip.h
+++ b/includes/omapip/omapip.h
@@ -154,6 +154,18 @@ typedef struct {
omapi_addr_t *addresses;
} omapi_addr_list_t;
+typedef struct auth_key {
+ OMAPI_OBJECT_PREAMBLE;
+ char *name;
+ char *algorithm;
+ omapi_data_string_t *key;
+} omapi_auth_key_t;
+
+#define OMAPI_CREATE 1
+#define OMAPI_UPDATE 2
+#define OMAPI_EXCL 4
+#define OMAPI_NOTIFY_PROTOCOL 8
+
#define OMAPI_OBJECT_ALLOC(name, stype, type) \
isc_result_t name##_allocate (stype **p, const char *file, int line) \
{ \
@@ -184,9 +196,21 @@ isc_result_t omapi_protocol_connect (omapi_object_t *,
isc_result_t omapi_connect_list (omapi_object_t *, omapi_addr_list_t *,
omapi_addr_t *);
isc_result_t omapi_protocol_listen (omapi_object_t *, unsigned, int);
+isc_boolean_t omapi_protocol_authenticated (omapi_object_t *);
+isc_result_t omapi_protocol_configure_security (omapi_object_t *,
+ isc_result_t (*)
+ (omapi_object_t *,
+ omapi_addr_t *),
+ isc_result_t (*)
+ (omapi_object_t *,
+ omapi_auth_key_t *));
isc_result_t omapi_protocol_accept (omapi_object_t *);
isc_result_t omapi_protocol_send_intro (omapi_object_t *, unsigned, unsigned);
isc_result_t omapi_protocol_ready (omapi_object_t *);
+isc_result_t omapi_protocol_add_auth (omapi_object_t *, omapi_object_t *,
+ omapi_handle_t);
+isc_result_t omapi_protocol_lookup_auth (omapi_object_t **, omapi_object_t *,
+ omapi_handle_t);
isc_result_t omapi_protocol_set_value (omapi_object_t *, omapi_object_t *,
omapi_data_string_t *,
omapi_typed_data_t *);
@@ -221,6 +245,9 @@ isc_result_t omapi_protocol_listener_stuff (omapi_object_t *,
omapi_object_t *);
isc_result_t omapi_protocol_send_status (omapi_object_t *, omapi_object_t *,
isc_result_t, unsigned, const char *);
+isc_result_t omapi_protocol_send_open (omapi_object_t *, omapi_object_t *,
+ const char *, omapi_object_t *,
+ unsigned);
isc_result_t omapi_protocol_send_update (omapi_object_t *, omapi_object_t *,
unsigned, omapi_object_t *);
@@ -232,6 +259,8 @@ isc_result_t omapi_connection_connect (omapi_object_t *);
isc_result_t omapi_connection_reader (omapi_object_t *);
isc_result_t omapi_connection_writer (omapi_object_t *);
isc_result_t omapi_connection_reaper (omapi_object_t *);
+isc_result_t omapi_connection_output_auth_length (omapi_object_t *,
+ unsigned *);
isc_result_t omapi_connection_set_value (omapi_object_t *, omapi_object_t *,
omapi_data_string_t *,
omapi_typed_data_t *);
@@ -257,6 +286,10 @@ isc_result_t omapi_listen_addr (omapi_object_t *,
isc_result_t omapi_listener_accept (omapi_object_t *);
int omapi_listener_readfd (omapi_object_t *);
isc_result_t omapi_accept (omapi_object_t *);
+isc_result_t omapi_listener_configure_security (omapi_object_t *,
+ isc_result_t (*)
+ (omapi_object_t *,
+ omapi_addr_t *));
isc_result_t omapi_listener_set_value (omapi_object_t *, omapi_object_t *,
omapi_data_string_t *,
omapi_typed_data_t *);
@@ -324,6 +357,22 @@ isc_result_t omapi_message_register (omapi_object_t *);
isc_result_t omapi_message_unregister (omapi_object_t *);
isc_result_t omapi_message_process (omapi_object_t *, omapi_object_t *);
+OMAPI_OBJECT_ALLOC_DECL (omapi_auth_key,
+ omapi_auth_key_t, omapi_type_auth_key)
+isc_result_t omapi_auth_key_new (omapi_auth_key_t **, const char *, int);
+isc_result_t omapi_auth_key_destroy (omapi_object_t *, const char *, int);
+isc_result_t omapi_auth_key_enter (omapi_auth_key_t *);
+isc_result_t omapi_auth_key_lookup_name (omapi_auth_key_t **, const char *);
+isc_result_t omapi_auth_key_lookup (omapi_object_t **,
+ omapi_object_t *,
+ omapi_object_t *);
+isc_result_t omapi_auth_key_get_value (omapi_object_t *, omapi_object_t *,
+ omapi_data_string_t *,
+ omapi_value_t **);
+isc_result_t omapi_auth_key_stuff_values (omapi_object_t *,
+ omapi_object_t *,
+ omapi_object_t *);
+
extern omapi_object_type_t *omapi_type_connection;
extern omapi_object_type_t *omapi_type_listener;
extern omapi_object_type_t *omapi_type_io_object;
@@ -333,6 +382,7 @@ extern omapi_object_type_t *omapi_type_protocol_listener;
extern omapi_object_type_t *omapi_type_waiter;
extern omapi_object_type_t *omapi_type_remote;
extern omapi_object_type_t *omapi_type_message;
+extern omapi_object_type_t *omapi_type_auth_key;
extern omapi_object_type_t *omapi_object_types;
@@ -408,6 +458,8 @@ isc_result_t omapi_make_int_value (omapi_value_t **, omapi_data_string_t *,
int, const char *, int);
isc_result_t omapi_make_uint_value (omapi_value_t **, omapi_data_string_t *,
unsigned int, const char *, int);
+isc_result_t omapi_make_object_value (omapi_value_t **, omapi_data_string_t *,
+ omapi_object_t *, const char *, int);
isc_result_t omapi_make_handle_value (omapi_value_t **, omapi_data_string_t *,
omapi_object_t *, const char *, int);
isc_result_t omapi_make_string_value (omapi_value_t **, omapi_data_string_t *,
diff --git a/includes/omapip/omapip_p.h b/includes/omapip/omapip_p.h
index 74ef2e23..0661d970 100644
--- a/includes/omapip/omapip_p.h
+++ b/includes/omapip/omapip_p.h
@@ -68,6 +68,7 @@
#include "cdefs.h"
#include "osdep.h"
+#include <isc/dst.h>
#include <isc/result.h>
#include <omapip/convert.h>
@@ -127,12 +128,17 @@ typedef struct __omapi_message_object {
u_int32_t rid;
} omapi_message_object_t;
+typedef struct __omapi_remote_auth {
+ struct __omapi_remote_auth *next;
+ omapi_handle_t remote_handle;
+ omapi_object_t *a;
+} omapi_remote_auth_t;
+
typedef struct {
OMAPI_OBJECT_PREAMBLE;
u_int32_t header_size;
u_int32_t protocol_version;
u_int32_t next_xid;
- omapi_object_t *authinfo; /* Default authinfo to use. */
omapi_protocol_state_t state; /* Input state. */
int reading_message_values; /* True if reading message-specific
@@ -140,10 +146,24 @@ typedef struct {
omapi_message_object_t *message; /* Incoming message. */
omapi_data_string_t *name; /* Incoming name. */
omapi_typed_data_t *value; /* Incoming value. */
+ isc_result_t verify_result;
+ omapi_remote_auth_t *default_auth; /* Default authinfo to use. */
+ omapi_remote_auth_t *remote_auth_list; /* Authenticators active on
+ this connection. */
+
+ isc_boolean_t insecure; /* Set to allow unauthenticated
+ messages. */
+
+ isc_result_t (*verify_auth) (omapi_object_t *, omapi_auth_key_t *);
} omapi_protocol_object_t;
typedef struct {
OMAPI_OBJECT_PREAMBLE;
+
+ isc_boolean_t insecure; /* Set to allow unauthenticated
+ messages. */
+
+ isc_result_t (*verify_auth) (omapi_object_t *, omapi_auth_key_t *);
} omapi_protocol_listener_object_t;
#include <omapip/buffer.h>
@@ -152,6 +172,7 @@ typedef struct __omapi_listener_object {
OMAPI_OBJECT_PREAMBLE;
int socket; /* Connection socket. */
struct sockaddr_in address;
+ isc_result_t (*verify_addr) (omapi_object_t *, omapi_addr_t *);
} omapi_listener_object_t;
typedef struct __omapi_connection_object {
@@ -170,6 +191,12 @@ typedef struct __omapi_connection_object {
omapi_buffer_t *outbufs;
omapi_listener_object_t *listener; /* Listener that accepted this
connection, if any. */
+ DST_KEY *in_key; /* Authenticator signing incoming
+ data. */
+ void *in_context; /* Input hash context. */
+ DST_KEY *out_key; /* Authenticator signing outgoing
+ data. */
+ void *out_context; /* Output hash context. */
} omapi_connection_object_t;
typedef struct __omapi_io_object {
@@ -191,6 +218,7 @@ typedef struct __omapi_generic_object {
typedef struct __omapi_waiter_object {
OMAPI_OBJECT_PREAMBLE;
int ready;
+ isc_result_t waitstatus;
struct __omapi_waiter_object *next;
} omapi_waiter_object_t;
@@ -226,6 +254,13 @@ OMAPI_OBJECT_ALLOC_DECL (omapi_generic,
OMAPI_OBJECT_ALLOC_DECL (omapi_message,
omapi_message_object_t, omapi_type_message)
+isc_result_t omapi_connection_sign_data (int mode,
+ DST_KEY *key,
+ void **context,
+ const u_char *data,
+ const unsigned len,
+ omapi_typed_data_t **result);
+
extern int log_priority;
extern int log_perror;
extern void (*log_cleanup) (void);
diff --git a/minires/dst_api.c b/minires/dst_api.c
index 15e3ab55..69e68815 100644
--- a/minires/dst_api.c
+++ b/minires/dst_api.c
@@ -1,5 +1,5 @@
#ifndef LINT
-static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/minires/Attic/dst_api.c,v 1.2 2000/02/02 19:59:15 mellon Exp $";
+static const char rcsid[] = "$Header: /tmp/cvstest/DHCP/minires/Attic/dst_api.c,v 1.3 2000/08/03 21:00:05 neild Exp $";
#endif
/*
@@ -722,7 +722,8 @@ dst_key_to_dnskey(const DST_KEY *key, u_char *out_storage,
}
memset(out_storage, 0, out_len);
val = (u_int16_t)(key->dk_flags & 0xffff);
- putUShort(out_storage, val);
+ out_storage[0] = (val >> 8) & 0xff;
+ out_storage[1] = val & 0xff;
loc += 2;
out_storage[loc++] = (u_char) key->dk_proto;
@@ -730,7 +731,8 @@ dst_key_to_dnskey(const DST_KEY *key, u_char *out_storage,
if (key->dk_flags > 0xffff) { /* Extended flags */
val = (u_int16_t)((key->dk_flags >> 16) & 0xffff);
- putUShort(&out_storage[loc], val);
+ out_storage[loc] = (val >> 8) & 0xff;
+ out_storage[loc+1] = val & 0xff;
loc += 2;
}
if (key->dk_KEY_struct == NULL)
diff --git a/omapip/Makefile.dist b/omapip/Makefile.dist
index 9dd2dfb1..e7bec530 100644
--- a/omapip/Makefile.dist
+++ b/omapip/Makefile.dist
@@ -21,10 +21,10 @@ CATMANPAGES = omapi.cat3
SEDMANPAGES = omapi.man3
SRC = protocol.c buffer.c alloc.c result.c connection.c errwarn.c \
listener.c dispatch.c generic.c support.c handle.c message.c \
- convert.c hash.c
+ convert.c hash.c auth.c
OBJ = protocol.o buffer.o alloc.o result.o connection.o errwarn.o \
listener.o dispatch.o generic.o support.o handle.o message.o \
- convert.o hash.o
+ convert.o hash.o auth.o
MAN = omapi.3
DEBUG = -g
@@ -33,8 +33,8 @@ CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
all: libomapi.a svtest $(CATMANPAGES)
-svtest: test.o libomapi.a
- $(CC) $(DEBUG) $(LFLAGS) -o svtest test.o libomapi.a $(LIBS)
+svtest: test.o libomapi.a $(BINDLIB)
+ $(CC) $(DEBUG) $(LFLAGS) -o svtest test.o libomapi.a $(BINDLIB) $(LIBS)
libomapi.a: $(OBJ)
rm -f libomapi.a
diff --git a/omapip/auth.c b/omapip/auth.c
new file mode 100644
index 00000000..f5ce57bc
--- /dev/null
+++ b/omapip/auth.c
@@ -0,0 +1,271 @@
+/* auth.c
+
+ Subroutines having to do with authentication. */
+
+/*
+ * Copyright (c) 1998-2000 Internet Software Consortium.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of The Internet Software Consortium nor the names
+ * of its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INTERNET SOFTWARE CONSORTIUM AND
+ * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE INTERNET SOFTWARE CONSORTIUM OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This software has been written for the Internet Software Consortium
+ * by Ted Lemon in cooperation with Vixie Enterprises and Nominum, Inc.
+ * To learn more about the Internet Software Consortium, see
+ * ``http://www.isc.org/''. To learn more about Vixie Enterprises,
+ * see ``http://www.vix.com''. To learn more about Nominum, Inc., see
+ * ``http://www.nominum.com''.
+ */
+
+#ifndef lint
+static char ocopyright[] =
+"$Id: auth.c,v 1.1 2000/08/03 21:00:11 neild Exp $ Copyright 1998-2000 The Internet Software Consortium.";
+#endif
+
+#include <omapip/omapip_p.h>
+
+OMAPI_OBJECT_ALLOC (omapi_auth_key, omapi_auth_key_t, omapi_type_auth_key);
+
+static struct hash_table *auth_key_hash = (struct hash_table *)0;
+HASH_FUNCTIONS_DECL (omapi_auth_key, const char *, omapi_auth_key_t)
+
+isc_result_t omapi_auth_key_new (omapi_auth_key_t **o, const char *file,
+ int line)
+{
+ return omapi_auth_key_allocate (o, MDL);
+}
+
+isc_result_t omapi_auth_key_destroy (omapi_object_t *h,
+ const char *file, int line)
+{
+ omapi_auth_key_t *a;
+
+ if (h -> type != omapi_type_auth_key)
+ return ISC_R_INVALIDARG;
+ a = (omapi_auth_key_t *)h;
+
+ if (auth_key_hash)
+ omapi_auth_key_hash_delete (auth_key_hash, a -> name, 0, MDL);
+
+ if (a -> name)
+ dfree (a -> name, MDL);
+ if (a -> algorithm)
+ dfree (a -> algorithm, MDL);
+ if (a -> key)
+ omapi_data_string_dereference (&a -> key, MDL);
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_auth_key_enter (omapi_auth_key_t *a)
+{
+ omapi_auth_key_t *tk;
+
+ if (a -> type != omapi_type_auth_key)
+ return ISC_R_INVALIDARG;
+
+ tk = (omapi_auth_key_t *)0;
+ if (auth_key_hash) {
+ omapi_auth_key_hash_lookup (&tk, auth_key_hash,
+ a -> name, 0, MDL);
+ if (tk == a) {
+ omapi_auth_key_dereference (&tk, MDL);
+ return ISC_R_SUCCESS;
+ }
+ if (tk) {
+ omapi_auth_key_hash_delete (auth_key_hash,
+ tk -> name, 0, MDL);
+ omapi_auth_key_dereference (&tk, MDL);
+ }
+ } else {
+ auth_key_hash =
+ new_hash ((hash_reference)omapi_auth_key_reference,
+ (hash_dereference)omapi_auth_key_dereference,
+ 1);
+ if (!auth_key_hash)
+ return ISC_R_NOMEMORY;
+ }
+ omapi_auth_key_hash_add (auth_key_hash, a -> name, 0, a, MDL);
+ return ISC_R_SUCCESS;
+
+}
+
+isc_result_t omapi_auth_key_lookup_name (omapi_auth_key_t **a,
+ const char *name)
+{
+ if (!auth_key_hash)
+ return ISC_R_NOTFOUND;
+ if (!omapi_auth_key_hash_lookup (a, auth_key_hash, name, 0, MDL))
+ return ISC_R_NOTFOUND;
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_auth_key_lookup (omapi_object_t **h,
+ omapi_object_t *id,
+ omapi_object_t *ref)
+{
+ isc_result_t status;
+ omapi_value_t *name = (omapi_value_t *)0;
+ omapi_value_t *algorithm = (omapi_value_t *)0;
+
+ if (!auth_key_hash)
+ return ISC_R_NOTFOUND;
+
+ status = omapi_get_value_str (ref, id, "name", &name);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ if ((name -> value -> type != omapi_datatype_string) &&
+ (name -> value -> type != omapi_datatype_data)) {
+ omapi_value_dereference (&name, MDL);
+ return ISC_R_NOTFOUND;
+ }
+
+ status = omapi_get_value_str (ref, id, "algorithm", &algorithm);
+ if (status != ISC_R_SUCCESS) {
+ omapi_value_dereference (&name, MDL);
+ return status;
+ }
+
+ if ((algorithm -> value -> type != omapi_datatype_string) &&
+ (algorithm -> value -> type != omapi_datatype_data)) {
+ omapi_value_dereference (&name, MDL);
+ omapi_value_dereference (&algorithm, MDL);
+ return ISC_R_NOTFOUND;
+ }
+
+
+ if (!omapi_auth_key_hash_lookup ((omapi_auth_key_t **)h, auth_key_hash,
+ name -> value -> u.buffer.value,
+ name -> value -> u.buffer.len, MDL)) {
+ omapi_value_dereference (&name, MDL);
+ omapi_value_dereference (&algorithm, MDL);
+ return ISC_R_NOTFOUND;
+ }
+
+ if (omapi_td_strcmp (algorithm -> value,
+ ((omapi_auth_key_t *)*h) -> algorithm) != 0) {
+ omapi_value_dereference (&name, MDL);
+ omapi_value_dereference (&algorithm, MDL);
+ omapi_object_dereference (h, MDL);
+ return ISC_R_NOTFOUND;
+ }
+
+ omapi_value_dereference (&name, MDL);
+ omapi_value_dereference (&algorithm, MDL);
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_auth_key_stuff_values (omapi_object_t *c,
+ omapi_object_t *id,
+ omapi_object_t *h)
+{
+ omapi_auth_key_t *a;
+ isc_result_t status;
+
+ if (h -> type != omapi_type_auth_key)
+ return ISC_R_INVALIDARG;
+ a = (omapi_auth_key_t *)h;
+
+ /* Write only the name and algorithm -- not the secret! */
+ if (a -> name) {
+ status = omapi_connection_put_name (c, "name");
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_connection_put_string (c, a -> name);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+ if (a -> algorithm) {
+ status = omapi_connection_put_name (c, "algorithm");
+ if (status != ISC_R_SUCCESS)
+ return status;
+ status = omapi_connection_put_string (c, a -> algorithm);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_auth_key_get_value (omapi_object_t *h,
+ omapi_object_t *id,
+ omapi_data_string_t *name,
+ omapi_value_t **value)
+{
+ omapi_auth_key_t *a;
+ isc_result_t status;
+
+ if (h -> type != omapi_type_auth_key)
+ return ISC_R_UNEXPECTED;
+ a = (omapi_auth_key_t *)h;
+
+ if (omapi_ds_strcmp (name, "name") == 0) {
+ if (a -> name)
+ return omapi_make_string_value
+ (value, name, a -> name, MDL);
+ else
+ return ISC_R_NOTFOUND;
+ } else if (omapi_ds_strcmp (name, "key") == 0) {
+ if (a -> key) {
+ status = omapi_value_new (value, MDL);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ status = omapi_data_string_reference
+ (&(*value) -> name, name, MDL);
+ if (status != ISC_R_SUCCESS) {
+ omapi_value_dereference (value, MDL);
+ return status;
+ }
+
+ status = omapi_typed_data_new (MDL, &(*value) -> value,
+ omapi_datatype_data,
+ a -> key -> len);
+ if (status != ISC_R_SUCCESS) {
+ omapi_value_dereference (value, MDL);
+ return status;
+ }
+
+ memcpy ((*value) -> value -> u.buffer.value,
+ a -> key -> value, a -> key -> len);
+ return ISC_R_SUCCESS;
+ } else
+ return ISC_R_NOTFOUND;
+ } else if (omapi_ds_strcmp (name, "algorithm") == 0) {
+ if (a -> algorithm)
+ return omapi_make_string_value
+ (value, name, a -> algorithm, MDL);
+ else
+ return ISC_R_NOTFOUND;
+ }
+
+ return ISC_R_SUCCESS;
+}
+
+HASH_FUNCTIONS (omapi_auth_key, const char *, omapi_auth_key_t)
diff --git a/omapip/buffer.c b/omapip/buffer.c
index 81fa07ce..e4bdc19a 100644
--- a/omapip/buffer.c
+++ b/omapip/buffer.c
@@ -139,6 +139,7 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h,
isc_result_t status;
int bytes_copied = 0;
unsigned copy_len;
+ int sig_flags = SIG_MODE_UPDATE;
omapi_connection_object_t *c;
/* Make sure len is valid. */
@@ -177,6 +178,17 @@ isc_result_t omapi_connection_copyin (omapi_object_t *h,
if (copy_len > (len - bytes_copied))
copy_len = len - bytes_copied;
+ if (c -> out_key) {
+ if (!c -> out_context)
+ sig_flags |= SIG_MODE_INIT;
+ status = omapi_connection_sign_data
+ (sig_flags, c -> out_key, &c -> out_context,
+ &bufp [bytes_copied], copy_len,
+ (omapi_typed_data_t **)0);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
memcpy (&buffer -> buf [buffer -> tail],
&bufp [bytes_copied], copy_len);
buffer -> tail += copy_len;
@@ -200,7 +212,9 @@ isc_result_t omapi_connection_copyout (unsigned char *buf,
unsigned first_byte;
omapi_buffer_t *buffer;
unsigned char *bufp;
+ int sig_flags = SIG_MODE_UPDATE;
omapi_connection_object_t *c;
+ isc_result_t status;
if (!h || h -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
@@ -231,6 +245,20 @@ isc_result_t omapi_connection_copyout (unsigned char *buf,
if (bytes_this_copy > bytes_remaining)
bytes_this_copy = bytes_remaining;
if (bufp) {
+ if (c -> in_key) {
+ if (!c -> in_context)
+ sig_flags |= SIG_MODE_INIT;
+ status = omapi_connection_sign_data
+ (sig_flags,
+ c -> in_key,
+ &c -> in_context,
+ &buffer -> buf [first_byte],
+ bytes_this_copy,
+ (omapi_typed_data_t **)0);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
memcpy (bufp, &buffer -> buf [first_byte],
bytes_this_copy);
bufp += bytes_this_copy;
diff --git a/omapip/connection.c b/omapip/connection.c
index 2d85c39b..a02fe29f 100644
--- a/omapip/connection.c
+++ b/omapip/connection.c
@@ -406,13 +406,188 @@ isc_result_t omapi_connection_reaper (omapi_object_t *h)
return ISC_R_SUCCESS;
}
+static isc_result_t make_dst_key (DST_KEY **dst_key, omapi_object_t *a) {
+ omapi_value_t *name = (omapi_value_t *)0;
+ omapi_value_t *algorithm = (omapi_value_t *)0;
+ omapi_value_t *key = (omapi_value_t *)0;
+ int algorithm_id;
+ char *name_str;
+ isc_result_t status = ISC_R_SUCCESS;
+
+ if (status == ISC_R_SUCCESS)
+ status = omapi_get_value_str
+ (a, (omapi_object_t *)0, "name", &name);
+
+ if (status == ISC_R_SUCCESS)
+ status = omapi_get_value_str
+ (a, (omapi_object_t *)0, "algorithm", &algorithm);
+
+ if (status == ISC_R_SUCCESS)
+ status = omapi_get_value_str
+ (a, (omapi_object_t *)0, "key", &key);
+
+ if (status == ISC_R_SUCCESS) {
+ if (omapi_td_strcmp (algorithm -> value, "hmac-md5") == 0) {
+ algorithm_id = KEY_HMAC_MD5;
+ } else {
+ status = ISC_R_INVALIDARG;
+ }
+ }
+
+ if (status == ISC_R_SUCCESS) {
+ name_str = dmalloc (name -> value -> u.buffer.len + 1, MDL);
+ if (!name_str)
+ status = ISC_R_NOMEMORY;
+ }
+
+ if (status == ISC_R_SUCCESS) {
+ memcpy (name_str,
+ name -> value -> u.buffer.value,
+ name -> value -> u.buffer.len);
+ name_str [name -> value -> u.buffer.len] = 0;
+
+ *dst_key = dst_buffer_to_key (name_str, algorithm_id, 0, 0,
+ key -> value -> u.buffer.value,
+ key -> value -> u.buffer.len);
+ if (!*dst_key)
+ status = ISC_R_NOMEMORY;
+ }
+
+ if (name_str)
+ dfree (name_str, MDL);
+ if (key)
+ omapi_value_dereference (&key, MDL);
+ if (algorithm)
+ omapi_value_dereference (&algorithm, MDL);
+ if (name)
+ omapi_value_dereference (&name, MDL);
+
+ return status;
+}
+
+isc_result_t omapi_connection_sign_data (int mode,
+ DST_KEY *key,
+ void **context,
+ const u_char *data,
+ const unsigned len,
+ omapi_typed_data_t **result)
+{
+ omapi_typed_data_t *td = (omapi_typed_data_t *)0;
+ isc_result_t status;
+ int r;
+
+ if (mode & SIG_MODE_FINAL) {
+ status = omapi_typed_data_new (MDL, &td,
+ omapi_datatype_data,
+ dst_sig_size (key));
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
+ r = dst_sign_data (mode, key, context, data, len,
+ td ? td -> u.buffer.value : (u_char *)0,
+ td ? td -> u.buffer.len : 0);
+
+ /* dst_sign_data() really should do this for us, shouldn't it? */
+ if (mode & SIG_MODE_FINAL)
+ *context = (void *)0;
+
+ if (r < 0) {
+ if (td)
+ omapi_typed_data_dereference (&td, MDL);
+ return ISC_R_INVALIDKEY;
+ }
+
+ if (result && td) {
+ omapi_typed_data_reference (result, td, MDL);
+ }
+
+ if (td)
+ omapi_typed_data_dereference (&td, MDL);
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_connection_output_auth_length (omapi_object_t *h,
+ unsigned *l)
+{
+ omapi_connection_object_t *c;
+
+ if (h -> type != omapi_type_connection)
+ return ISC_R_INVALIDARG;
+ c = (omapi_connection_object_t *)h;
+
+ if (!c -> out_key)
+ return ISC_R_NOTFOUND;
+
+ *l = dst_sig_size (c -> out_key);
+ return ISC_R_SUCCESS;
+}
+
isc_result_t omapi_connection_set_value (omapi_object_t *h,
omapi_object_t *id,
omapi_data_string_t *name,
omapi_typed_data_t *value)
{
+ omapi_connection_object_t *c;
+ isc_result_t status;
+
if (h -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
+ c = (omapi_connection_object_t *)h;
+
+ if (omapi_ds_strcmp (name, "input-authenticator") == 0) {
+ if (value && value -> type != omapi_datatype_object)
+ return ISC_R_INVALIDARG;
+
+ if (c -> in_context) {
+ omapi_connection_sign_data (SIG_MODE_FINAL,
+ c -> in_key,
+ &c -> in_context,
+ 0, 0,
+ (omapi_typed_data_t **) 0);
+ }
+
+ if (c -> in_key) {
+ dst_free_key (c -> in_key);
+ c -> in_key = (DST_KEY *)0;
+ }
+
+ if (value) {
+ status = make_dst_key (&c -> in_key,
+ value -> u.object);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
+ return ISC_R_SUCCESS;
+ }
+ else if (omapi_ds_strcmp (name, "output-authenticator") == 0) {
+ if (value && value -> type != omapi_datatype_object)
+ return ISC_R_INVALIDARG;
+
+ if (c -> out_context) {
+ omapi_connection_sign_data (SIG_MODE_FINAL,
+ c -> out_key,
+ &c -> out_context,
+ 0, 0,
+ (omapi_typed_data_t **) 0);
+ }
+
+ if (c -> out_key) {
+ dst_free_key (c -> out_key);
+ c -> out_key = (DST_KEY *)0;
+ }
+
+ if (value) {
+ status = make_dst_key (&c -> out_key,
+ value -> u.object);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
+ return ISC_R_SUCCESS;
+ }
if (h -> inner && h -> inner -> type -> set_value)
return (*(h -> inner -> type -> set_value))
@@ -425,8 +600,58 @@ isc_result_t omapi_connection_get_value (omapi_object_t *h,
omapi_data_string_t *name,
omapi_value_t **value)
{
+ omapi_connection_object_t *c;
+ omapi_typed_data_t *td = (omapi_typed_data_t *)0;
+ isc_result_t status;
+
if (h -> type != omapi_type_connection)
return ISC_R_INVALIDARG;
+ c = (omapi_connection_object_t *)h;
+
+ if (omapi_ds_strcmp (name, "input-signature") == 0) {
+ if (!c -> in_key || !c -> in_context)
+ return ISC_R_NOTFOUND;
+
+ status = omapi_connection_sign_data (SIG_MODE_FINAL,
+ c -> in_key,
+ &c -> in_context,
+ 0, 0, &td);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ status = omapi_make_value (value, name, td, MDL);
+ omapi_typed_data_dereference (&td, MDL);
+ return status;
+
+ } else if (omapi_ds_strcmp (name, "input-signature-size") == 0) {
+ if (!c -> in_key)
+ return ISC_R_NOTFOUND;
+
+ return omapi_make_int_value (value, name,
+ dst_sig_size (c -> in_key), MDL);
+
+ } else if (omapi_ds_strcmp (name, "output-signature") == 0) {
+ if (!c -> out_key || !c -> out_context)
+ return ISC_R_NOTFOUND;
+
+ status = omapi_connection_sign_data (SIG_MODE_FINAL,
+ c -> out_key,
+ &c -> out_context,
+ 0, 0, &td);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ status = omapi_make_value (value, name, td, MDL);
+ omapi_typed_data_dereference (&td, MDL);
+ return status;
+
+ } else if (omapi_ds_strcmp (name, "output-signature-size") == 0) {
+ if (!c -> out_key)
+ return ISC_R_NOTFOUND;
+
+ return omapi_make_int_value (value, name,
+ dst_sig_size (c -> out_key), MDL);
+ }
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
diff --git a/omapip/dispatch.c b/omapip/dispatch.c
index ee402aed..2701d7b9 100644
--- a/omapip/dispatch.c
+++ b/omapip/dispatch.c
@@ -206,8 +206,9 @@ isc_result_t omapi_wait_for_completion (omapi_object_t *object,
if (waiter -> inner)
omapi_object_dereference (&waiter -> inner, MDL);
+ status = waiter -> waitstatus;
omapi_waiter_dereference (&waiter, MDL);
- return ISC_R_SUCCESS;
+ return status;;
}
isc_result_t omapi_one_dispatch (omapi_object_t *wo,
@@ -510,6 +511,14 @@ isc_result_t omapi_waiter_signal_handler (omapi_object_t *h,
if (!strcmp (name, "ready")) {
waiter = (omapi_waiter_object_t *)h;
waiter -> ready = 1;
+ waiter -> waitstatus = ISC_R_SUCCESS;
+ return ISC_R_SUCCESS;
+ }
+
+ if (!strcmp (name, "status")) {
+ waiter = (omapi_waiter_object_t *)h;
+ waiter -> ready = 1;
+ waiter -> waitstatus = va_arg (ap, isc_result_t);
return ISC_R_SUCCESS;
}
diff --git a/omapip/listener.c b/omapip/listener.c
index 23c6250f..03ee6e5d 100644
--- a/omapip/listener.c
+++ b/omapip/listener.c
@@ -122,6 +122,17 @@ isc_result_t omapi_listen_addr (omapi_object_t *h,
}
#endif
+ /* Set the REUSEADDR option so that we don't fail to start if
+ we're being restarted. */
+ i = 1;
+ if (setsockopt (obj -> socket, SOL_SOCKET, SO_REUSEADDR,
+ (char *)&i, sizeof i) < 0) {
+ close (obj -> socket);
+ omapi_listener_dereference (&obj, MDL);
+ return ISC_R_UNEXPECTED;
+ }
+
+
/* Try to bind to the wildcard address using the port number
we were given. */
i = bind (obj -> socket,
@@ -173,6 +184,7 @@ isc_result_t omapi_accept (omapi_object_t *h)
SOCKLEN_T len;
omapi_connection_object_t *obj;
omapi_listener_object_t *listener;
+ omapi_addr_t addr;
int i;
if (h -> type != omapi_type_listener)
@@ -200,6 +212,21 @@ isc_result_t omapi_accept (omapi_object_t *h)
obj -> state = omapi_connection_connected;
+ /* Verify that this host is allowed to connect. */
+ if (listener -> verify_addr) {
+ addr.addrtype = AF_INET;
+ addr.addrlen = sizeof (obj -> remote_addr.sin_addr);
+ memcpy (addr.address, &obj -> remote_addr.sin_addr,
+ sizeof (obj -> remote_addr.sin_addr));
+ addr.port = ntohs(obj -> remote_addr.sin_port);
+
+ status = (listener -> verify_addr) (h, &addr);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect ((omapi_object_t *)obj, 1);
+ return status;
+ }
+ }
+
status = omapi_register_io_object ((omapi_object_t *)obj,
omapi_connection_readfd,
omapi_connection_writefd,
@@ -221,6 +248,22 @@ isc_result_t omapi_accept (omapi_object_t *h)
return status;
}
+isc_result_t omapi_listener_configure_security (omapi_object_t *h,
+ isc_result_t (*verify_addr)
+ (omapi_object_t *,
+ omapi_addr_t *))
+{
+ omapi_listener_object_t *l;
+
+ if (h -> type != omapi_type_listener)
+ return ISC_R_INVALIDARG;
+ l = (omapi_listener_object_t *)h;
+
+ l -> verify_addr = verify_addr;
+
+ return ISC_R_SUCCESS;
+}
+
isc_result_t omapi_listener_set_value (omapi_object_t *h,
omapi_object_t *id,
omapi_data_string_t *name,
diff --git a/omapip/message.c b/omapip/message.c
index 60cd6857..7837f487 100644
--- a/omapip/message.c
+++ b/omapip/message.c
@@ -249,14 +249,14 @@ isc_result_t omapi_message_signal_handler (omapi_object_t *h,
return ISC_R_INVALIDARG;
m = (omapi_message_object_t *)h;
- if (!strcmp (name, "status") &&
- (m -> object || m -> notify_object)) {
- if (m -> object)
- return ((m -> object -> type -> signal_handler))
- (m -> object, name, ap);
- else
+ if (!strcmp (name, "status")) {
+ if (m -> notify_object &&
+ m -> notify_object -> type -> signal_handler)
return ((m -> notify_object -> type -> signal_handler))
(m -> notify_object, name, ap);
+ else if (m -> object && m -> object -> type -> signal_handler)
+ return ((m -> object -> type -> signal_handler))
+ (m -> object, name, ap);
}
if (h -> inner && h -> inner -> type -> signal_handler)
return (*(h -> inner -> type -> signal_handler)) (h -> inner,
@@ -378,20 +378,35 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
response, something's fishy. */
if (!m)
return ISC_R_NOTFOUND;
- } else
+ /* The authenticator on responses must match the initial
+ message. */
+ if (message -> authid != m -> authid)
+ return ISC_R_NOTFOUND;
+ } else {
m = (omapi_message_object_t *)0;
+ /* All messages must have an authenticator, with the exception
+ of messages that are opening a new authenticator. */
+ if (omapi_protocol_authenticated (po) &&
+ !message -> id_object &&
+ message -> op != OMAPI_OP_OPEN) {
+ return omapi_protocol_send_status
+ (po, message -> id_object, ISC_R_NOKEYS,
+ message -> id, "No authenticator on message");
+ }
+ }
+
switch (message -> op) {
case OMAPI_OP_OPEN:
if (m) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0, ISC_R_INVALIDARG,
+ (po, message -> id_object, ISC_R_INVALIDARG,
message -> id, "OPEN can't be a response");
}
/* Get the type of the requested object, if one was
specified. */
- status = omapi_get_value_str (mo, (omapi_object_t *)0,
+ status = omapi_get_value_str (mo, message -> id_object,
"type", &tv);
if (status == ISC_R_SUCCESS &&
(tv -> value -> type == omapi_datatype_data ||
@@ -406,16 +421,25 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
if (tv)
omapi_value_dereference (&tv, MDL);
+ /* If this object had no authenticator, the requested object
+ must be an authenticator object. */
+ if (omapi_protocol_authenticated (po) &&
+ !message -> id_object &&
+ type != omapi_type_auth_key) {
+ return omapi_protocol_send_status
+ (po, message -> id_object, ISC_R_NOKEYS,
+ message -> id, "No authenticator on message");
+ }
+
/* Get the create flag. */
- status = omapi_get_value_str (mo,
- (omapi_object_t *)0,
+ status = omapi_get_value_str (mo, message -> id_object,
"create", &tv);
if (status == ISC_R_SUCCESS) {
status = omapi_get_int_value (&create, tv -> value);
omapi_value_dereference (&tv, MDL);
if (status != ISC_R_SUCCESS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"invalid create flag value");
}
@@ -423,15 +447,14 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
create = 0;
/* Get the update flag. */
- status = omapi_get_value_str (mo,
- (omapi_object_t *)0,
+ status = omapi_get_value_str (mo, message -> id_object,
"update", &tv);
if (status == ISC_R_SUCCESS) {
status = omapi_get_int_value (&update, tv -> value);
omapi_value_dereference (&tv, MDL);
if (status != ISC_R_SUCCESS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"invalid update flag value");
}
@@ -439,15 +462,14 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
update = 0;
/* Get the exclusive flag. */
- status = omapi_get_value_str (mo,
- (omapi_object_t *)0,
+ status = omapi_get_value_str (mo, message -> id_object,
"exclusive", &tv);
if (status == ISC_R_SUCCESS) {
status = omapi_get_int_value (&exclusive, tv -> value);
omapi_value_dereference (&tv, MDL);
if (status != ISC_R_SUCCESS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"invalid exclusive flag value");
}
@@ -459,8 +481,9 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
if (!type) {
if (create) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
- ISC_R_INVALIDARG, message -> id,
+ (po, message -> id_object,
+ ISC_R_INVALIDARG,
+ message -> id,
"type required on create");
}
goto refresh;
@@ -470,25 +493,25 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
look up the object. */
if (!type -> lookup) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
ISC_R_NOTIMPLEMENTED, message -> id,
"unsearchable object type");
}
if (!message -> object) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
ISC_R_NOTFOUND, message -> id,
"no lookup key specified");
}
- status = (*(type -> lookup)) (&object, (omapi_object_t *)0,
+ status = (*(type -> lookup)) (&object, message -> id_object,
message -> object);
if (status != ISC_R_SUCCESS &&
status != ISC_R_NOTFOUND &&
status != ISC_R_NOKEYS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"object lookup failed");
}
@@ -497,7 +520,7 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
create it, return an error. */
if (status == ISC_R_NOTFOUND && !create) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
ISC_R_NOTFOUND, message -> id,
"no object matches specification");
}
@@ -508,7 +531,7 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
if (status == ISC_R_SUCCESS && create && exclusive) {
omapi_object_dereference (&object, MDL);
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
ISC_R_EXISTS, message -> id,
"specified object already exists");
}
@@ -516,11 +539,11 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
/* If we're creating the object, do it now. */
if (!object) {
status = omapi_object_create (&object,
- (omapi_object_t *)0,
+ message -> id_object,
type);
if (status != ISC_R_SUCCESS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"can't create new object");
}
@@ -528,18 +551,50 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
/* If we're updating it, do so now. */
if (create || update) {
+ /* This check does not belong here. */
+ if (object -> type == omapi_type_auth_key) {
+ omapi_object_dereference (&object, MDL);
+ return omapi_protocol_send_status
+ (po, message -> id_object,
+ status, message -> id,
+ "can't update object");
+ }
+
status = omapi_object_update (object,
- (omapi_object_t *)0,
+ message -> id_object,
message -> object,
message -> h);
if (status != ISC_R_SUCCESS) {
omapi_object_dereference (&object, MDL);
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"can't update object");
}
}
+
+ /* If this is an authenticator object, add it to the active
+ set for the connection. */
+ if (object -> type == omapi_type_auth_key) {
+ omapi_handle_t handle;
+ status = omapi_object_handle (&handle, object);
+ if (status != ISC_R_SUCCESS) {
+ omapi_object_dereference (&object, MDL);
+ return omapi_protocol_send_status
+ (po, message -> id_object,
+ status, message -> id,
+ "can't select authenticator");
+ }
+
+ status = omapi_protocol_add_auth (po, object, handle);
+ if (status != ISC_R_SUCCESS) {
+ omapi_object_dereference (&object, MDL);
+ return omapi_protocol_send_status
+ (po, message -> id_object,
+ status, message -> id,
+ "can't select authenticator");
+ }
+ }
/* Now send the new contents of the object back in
response. */
@@ -550,37 +605,53 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
status = omapi_handle_lookup (&object, message -> h);
if (status != ISC_R_SUCCESS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"no matching handle");
}
send:
- status = omapi_protocol_send_update (po, (omapi_object_t *)0,
+ status = omapi_protocol_send_update (po, message -> id_object,
message -> id, object);
omapi_object_dereference (&object, MDL);
return status;
case OMAPI_OP_UPDATE:
- if (m -> object) {
+ if (m && m -> object) {
omapi_object_reference (&object, m -> object, MDL);
} else {
status = omapi_handle_lookup (&object, message -> h);
if (status != ISC_R_SUCCESS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"no matching handle");
}
}
- status = omapi_object_update (object, (omapi_object_t *)0,
- message -> object,
- message -> h);
+ if (object -> type == omapi_type_auth_key ||
+ (object -> inner &&
+ object -> inner -> type == omapi_type_auth_key)) {
+ if (!m) {
+ omapi_object_dereference (&object, MDL);
+ return omapi_protocol_send_status
+ (po, message -> id_object,
+ status, message -> id,
+ "cannot update authenticator");
+ }
+
+ status = omapi_protocol_add_auth (po, object,
+ message -> h);
+ } else {
+ status = omapi_object_update (object,
+ message -> id_object,
+ message -> object,
+ message -> h);
+ }
if (status != ISC_R_SUCCESS) {
omapi_object_dereference (&object, MDL);
if (!message -> rid)
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"can't update object");
if (m)
@@ -591,7 +662,7 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
}
if (!message -> rid)
status = omapi_protocol_send_status
- (po, (omapi_object_t *)0, ISC_R_SUCCESS,
+ (po, message -> id_object, ISC_R_SUCCESS,
message -> id, (char *)0);
if (m)
omapi_signal ((omapi_object_t *)m,
@@ -601,7 +672,7 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
case OMAPI_OP_NOTIFY:
return omapi_protocol_send_status
- (po, (omapi_object_t *)0, ISC_R_NOTIMPLEMENTED,
+ (po, message -> id_object, ISC_R_NOTIMPLEMENTED,
message -> id, "notify not implemented yet");
case OMAPI_OP_STATUS:
@@ -610,8 +681,7 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
return ISC_R_UNEXPECTED;
/* Get the wait status. */
- status = omapi_get_value_str (mo,
- (omapi_object_t *)0,
+ status = omapi_get_value_str (mo, message -> id_object,
"result", &tv);
if (status == ISC_R_SUCCESS) {
status = omapi_get_int_value (&wsi, tv -> value);
@@ -622,8 +692,7 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
} else
waitstatus = ISC_R_UNEXPECTED;
- status = omapi_get_value_str (mo,
- (omapi_object_t *)0,
+ status = omapi_get_value_str (mo, message -> id_object,
"message", &tv);
omapi_signal ((omapi_object_t *)m, "status", waitstatus, tv);
if (status == ISC_R_SUCCESS)
@@ -634,22 +703,22 @@ isc_result_t omapi_message_process (omapi_object_t *mo, omapi_object_t *po)
status = omapi_handle_lookup (&object, message -> h);
if (status != ISC_R_SUCCESS) {
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
status, message -> id,
"no matching handle");
}
if (!object -> type -> remove)
return omapi_protocol_send_status
- (po, (omapi_object_t *)0,
+ (po, message -> id_object,
ISC_R_NOTIMPLEMENTED, message -> id,
"no remove method for object");
status = (*(object -> type -> remove)) (object,
- (omapi_object_t *)0);
+ message -> id_object);
omapi_object_dereference (&object, MDL);
- return omapi_protocol_send_status (po, (omapi_object_t *)0,
+ return omapi_protocol_send_status (po, message -> id_object,
status, message -> id,
(char *)0);
}
diff --git a/omapip/protocol.c b/omapip/protocol.c
index b254e2a0..7eaeab89 100644
--- a/omapip/protocol.c
+++ b/omapip/protocol.c
@@ -51,7 +51,7 @@ OMAPI_OBJECT_ALLOC (omapi_protocol_listener, omapi_protocol_listener_object_t,
isc_result_t omapi_protocol_connect (omapi_object_t *h,
const char *server_name,
unsigned port,
- omapi_object_t *authinfo)
+ omapi_object_t *a)
{
isc_result_t status;
omapi_protocol_object_t *obj;
@@ -78,8 +78,30 @@ isc_result_t omapi_protocol_connect (omapi_object_t *h,
return status;
}
- if (authinfo)
- omapi_object_reference (&obj -> authinfo, authinfo, MDL);
+ /* If we were passed a default authenticator, store it now. We'll
+ open it once we're connected. */
+ if (a) {
+ obj -> default_auth =
+ dmalloc (sizeof(omapi_remote_auth_t), MDL);
+ if (!obj -> default_auth) {
+ omapi_protocol_dereference (&obj, MDL);
+ return ISC_R_NOMEMORY;
+ }
+
+ obj -> default_auth -> next = (omapi_remote_auth_t *)0;
+ status = omapi_object_reference (&obj -> default_auth -> a,
+ a, MDL);
+ if (status != ISC_R_SUCCESS) {
+ dfree (obj -> default_auth, MDL);
+ omapi_protocol_dereference (&obj, MDL);
+ return status;
+ }
+
+ obj -> insecure = 0;
+ } else {
+ obj -> insecure = 1;
+ }
+
omapi_protocol_dereference (&obj, MDL);
return ISC_R_SUCCESS;
}
@@ -128,8 +150,11 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po,
omapi_protocol_object_t *p;
omapi_object_t *c;
omapi_message_object_t *m, *om;
+ omapi_remote_auth_t *ra;
+ omapi_value_t *signature;
isc_result_t status;
u_int32_t foo;
+ unsigned auth_len;
if (po -> type != omapi_type_protocol ||
!po -> outer || po -> outer -> type != omapi_type_connection ||
@@ -142,12 +167,57 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po,
m = (omapi_message_object_t *)mo;
om = (omapi_message_object_t *)omo;
- /* XXX Write the authenticator length */
- status = omapi_connection_put_uint32 (c, 0);
- if (status != ISC_R_SUCCESS)
+ /* Find the authid to use for this message. */
+ if (id) {
+ for (ra = p -> remote_auth_list; ra; ra = ra -> next) {
+ if (ra -> a == id) {
+ break;
+ }
+ }
+
+ if (!ra)
+ return ISC_R_KEY_UNKNOWN;
+ } else if (p -> remote_auth_list) {
+ ra = p -> default_auth;
+ } else {
+ ra = (omapi_remote_auth_t *)0;
+ }
+
+ if (ra) {
+ m -> authid = ra -> remote_handle;
+ status = omapi_object_reference (&m -> id_object,
+ ra -> a, MDL);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
+ /* Write the ID of the authentication key we're using. */
+ status = omapi_connection_put_uint32 (c, ra ? ra -> remote_handle : 0);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
return status;
- /* XXX Write the ID of the authentication key we're using. */
- status = omapi_connection_put_uint32 (c, 0);
+ }
+
+ /* Activate the authentication key on the connection. */
+ auth_len = 0;
+ if (ra) {
+ status = omapi_set_object_value (c, (omapi_object_t *)0,
+ "output-authenticator",
+ ra -> a);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+
+ status = omapi_connection_output_auth_length (c, &auth_len);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+ }
+
+ /* Write the authenticator length */
+ status = omapi_connection_put_uint32 (c, auth_len);
if (status != ISC_R_SUCCESS) {
omapi_disconnect (c, 1);
return status;
@@ -223,7 +293,35 @@ isc_result_t omapi_protocol_send_message (omapi_object_t *po,
return status;
}
- /* XXX Write the authenticator... */
+ if (ra) {
+ /* Calculate the message signature. */
+ signature = (omapi_value_t *)0;
+ status = omapi_get_value_str (c, (omapi_object_t *)0,
+ "output-signature", &signature);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+
+ /* Write the authenticator... */
+ status = (omapi_connection_copyin
+ (c, signature -> value -> u.buffer.value,
+ signature -> value -> u.buffer.len));
+ omapi_value_dereference (&signature, MDL);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+
+ /* Dectivate the authentication key on the connection. */
+ status = omapi_set_value_str (c, (omapi_object_t *)0,
+ "output-authenticator",
+ (omapi_typed_data_t *)0);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+ }
return ISC_R_SUCCESS;
}
@@ -235,6 +333,7 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
isc_result_t status;
omapi_protocol_object_t *p;
omapi_object_t *c;
+ omapi_value_t *signature;
u_int16_t nlen;
u_int32_t vlen;
u_int32_t th;
@@ -257,6 +356,19 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
return ISC_R_SUCCESS;
}
+ /* Should only receive these when opening the initial authenticator. */
+ if (!strcmp (name, "status")) {
+ status = va_arg (ap, isc_result_t);
+ if (status != ISC_R_SUCCESS) {
+ omapi_signal_in (h -> inner, "status", status,
+ (omapi_object_t *)0);
+ omapi_disconnect (p -> outer, 1);
+ return status;
+ } else {
+ return omapi_signal_in (h -> inner, "ready");
+ }
+ }
+
/* Not a signal we recognize? */
if (strcmp (name, "ready")) {
if (p -> inner && p -> inner -> type -> signal_handler)
@@ -291,7 +403,18 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
return ISC_R_PROTOCOLERROR;
}
- status = omapi_signal_in (h -> inner, "ready");
+ if (p -> default_auth) {
+ status = omapi_protocol_send_open
+ (h, (omapi_object_t *)0, "authenticator",
+ p -> default_auth -> a,
+ OMAPI_NOTIFY_PROTOCOL);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+ } else {
+ status = omapi_signal_in (h -> inner, "ready");
+ }
to_header_wait:
/* The next thing we're expecting is a message header. */
@@ -313,10 +436,29 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
return status;
}
+ p -> verify_result = ISC_R_SUCCESS;
+
/* Swap in the header... */
omapi_connection_get_uint32 (c, &p -> message -> authid);
- /* XXX bind the authenticator here! */
+ /* Bind the authenticator to the message object. */
+ if (p -> message -> authid) {
+ status = (omapi_protocol_lookup_auth
+ (&p -> message -> id_object, h,
+ p -> message -> authid));
+ if (status != ISC_R_SUCCESS)
+ p -> verify_result = status;
+
+ /* Activate the authentication key. */
+ status = omapi_set_object_value
+ (c, (omapi_object_t *)0, "input-authenticator",
+ p -> message -> id_object);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+ }
+
omapi_connection_get_uint32 (c, &p -> message -> authlen);
omapi_connection_get_uint32 (c, &p -> message -> op);
omapi_connection_get_uint32 (c, &th);
@@ -462,31 +604,71 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
signature_wait:
case omapi_protocol_signature_wait:
+ if (p -> message -> id_object) {
+ /* Compute the signature of the message. */
+ signature = (omapi_value_t *)0;
+ status = omapi_get_value_str (c, (omapi_object_t *)0,
+ "input-signature",
+ &signature);
+ if (status != ISC_R_SUCCESS) {
+ omapi_disconnect (c, 1);
+ return status;
+ }
+
+ /* Disable the authentication key on the connection. */
+ status = omapi_set_value_str (c, (omapi_object_t *)0,
+ "input-authenticator",
+ (omapi_typed_data_t *)0);
+ if (status != ISC_R_SUCCESS) {
+ omapi_value_dereference (&signature, MDL);
+ omapi_disconnect (c, 1);
+ return status;
+ }
+ }
+
+ /* Read the authenticator. */
status = omapi_typed_data_new (MDL,
&p -> message -> authenticator,
omapi_datatype_data,
p -> message -> authlen);
if (status != ISC_R_SUCCESS) {
+ omapi_value_dereference (&signature, MDL);
omapi_disconnect (c, 1);
return ISC_R_NOMEMORY;
}
omapi_connection_copyout
(p -> message -> authenticator -> u.buffer.value, c,
p -> message -> authlen);
- /* XXX now do something to verify the signature. */
+
+ /* Verify the signature. */
+ if (p -> message -> id_object &&
+ ((signature -> value -> u.buffer.len !=
+ p -> message -> authlen) ||
+ (memcmp (signature -> value -> u.buffer.value,
+ p -> message -> authenticator -> u.buffer.value,
+ p -> message -> authlen) != 0))) {
+ /* Invalid signature. */
+ p -> verify_result = ISC_R_INVALIDKEY;
+ }
+
+ omapi_value_dereference (&signature, MDL);
/* Process the message. */
message_done:
- status = omapi_message_process ((omapi_object_t *)p -> message,
- h);
+ if (p -> verify_result != ISC_R_SUCCESS) {
+ status = omapi_protocol_send_status
+ (h, (omapi_object_t *)0, p -> verify_result,
+ p -> message -> id, (char *)0);
+ } else {
+ status = omapi_message_process
+ ((omapi_object_t *)p -> message, h);
+ }
if (status != ISC_R_SUCCESS) {
omapi_disconnect (c, 1);
return ISC_R_NOMEMORY;
}
- /* XXX unbind the authenticator. */
- auth_unbind:
omapi_message_dereference (&p -> message, MDL);
/* Now wait for the next message. */
@@ -499,13 +681,110 @@ isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
return ISC_R_SUCCESS;
}
+isc_result_t omapi_protocol_add_auth (omapi_object_t *po,
+ omapi_object_t *ao,
+ omapi_handle_t handle)
+{
+ omapi_protocol_object_t *p;
+ omapi_remote_auth_t *r;
+ isc_result_t status;
+
+ if (ao -> type != omapi_type_auth_key &&
+ (!ao -> inner || ao -> inner -> type != omapi_type_auth_key))
+ return ISC_R_INVALIDARG;
+
+ if (po -> type != omapi_type_protocol)
+ return ISC_R_INVALIDARG;
+ p = (omapi_protocol_object_t *)po;
+
+ if (p -> verify_auth) {
+ status = (p -> verify_auth) (po, (omapi_auth_key_t *)ao);
+ if (status != ISC_R_SUCCESS)
+ return status;
+ }
+
+ /* If omapi_protocol_connect() was called with a default
+ authenticator, p -> default_auth will already be set,
+ but p -> remote_auth_list will not yet be initialized. */
+ if (p -> default_auth && !p -> remote_auth_list) {
+ if (p -> default_auth -> a != ao) {
+ /* Something just went horribly wrong. */
+ omapi_disconnect (p -> outer, 1);
+ return ISC_R_UNEXPECTED;
+ }
+
+ p -> remote_auth_list = p -> default_auth;
+ p -> default_auth -> remote_handle = handle;
+
+ return omapi_signal_in (p -> inner, "ready");
+ }
+
+ r = dmalloc (sizeof(*r), MDL);
+ if (!r)
+ return ISC_R_NOMEMORY;
+
+ status = omapi_object_reference (&r -> a, ao, MDL);
+ if (status != ISC_R_SUCCESS) {
+ dfree (r, MDL);
+ return status;
+ }
+
+ r -> remote_handle = handle;
+ r -> next = p -> remote_auth_list;
+ p -> remote_auth_list = r;
+
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t omapi_protocol_lookup_auth (omapi_object_t **a,
+ omapi_object_t *po,
+ omapi_handle_t handle)
+{
+ omapi_protocol_object_t *p;
+ omapi_remote_auth_t *r;
+
+ if (po -> type != omapi_type_protocol)
+ return ISC_R_INVALIDARG;
+ p = (omapi_protocol_object_t *)po;
+
+ for (r = p -> remote_auth_list; r; r = r -> next)
+ if (r -> remote_handle == handle)
+ return omapi_object_reference (a, r -> a, MDL);
+
+ return ISC_R_NOTFOUND;
+}
+
isc_result_t omapi_protocol_set_value (omapi_object_t *h,
omapi_object_t *id,
omapi_data_string_t *name,
omapi_typed_data_t *value)
{
+ omapi_protocol_object_t *p;
+ omapi_remote_auth_t *r;
+
if (h -> type != omapi_type_protocol)
return ISC_R_INVALIDARG;
+ p = (omapi_protocol_object_t *)h;
+
+ if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
+ if (value -> type != omapi_datatype_object)
+ return ISC_R_INVALIDARG;
+
+ if (!value || !value -> u.object) {
+ p -> default_auth = (omapi_remote_auth_t *)0;
+ } else {
+ for (r = p -> remote_auth_list; r; r = r -> next)
+ if (r -> a == value -> u.object)
+ break;
+
+ if (!r)
+ return ISC_R_KEY_UNKNOWN;
+
+ p -> default_auth = r;
+ }
+
+ return ISC_R_SUCCESS;
+ }
if (h -> inner && h -> inner -> type -> set_value)
return (*(h -> inner -> type -> set_value))
@@ -518,8 +797,19 @@ isc_result_t omapi_protocol_get_value (omapi_object_t *h,
omapi_data_string_t *name,
omapi_value_t **value)
{
+ omapi_protocol_object_t *p;
+
if (h -> type != omapi_type_protocol)
return ISC_R_INVALIDARG;
+ p = (omapi_protocol_object_t *)h;
+
+ if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
+ if (!p -> default_auth)
+ return ISC_R_NOTFOUND;
+
+ return omapi_make_object_value (value, name,
+ p -> default_auth -> a, MDL);
+ }
if (h -> inner && h -> inner -> type -> get_value)
return (*(h -> inner -> type -> get_value))
@@ -536,8 +826,19 @@ isc_result_t omapi_protocol_destroy (omapi_object_t *h,
p = (omapi_protocol_object_t *)h;
if (p -> message)
omapi_message_dereference (&p -> message, file, line);
- if (p -> authinfo)
- return omapi_object_dereference (&p -> authinfo, file, line);
+
+ /* This will happen if: 1) A default authenticator is supplied to
+ omapi_protocol_connect(), and 2) something goes wrong before
+ the authenticator can be opened. */
+ if (p -> default_auth && !p -> remote_auth_list)
+ dfree (p -> default_auth, file, line);
+
+ while (p -> remote_auth_list) {
+ omapi_remote_auth_t *r = p -> remote_auth_list -> next;
+ omapi_object_dereference (&r -> a, file, line);
+ dfree (r, file, line);
+ p -> remote_auth_list = r;
+ }
return ISC_R_SUCCESS;
}
@@ -559,6 +860,46 @@ isc_result_t omapi_protocol_stuff_values (omapi_object_t *c,
return ISC_R_SUCCESS;
}
+/* Returns a boolean indicating whether this protocol requires that
+ messages be authenticated or not. */
+
+isc_boolean_t omapi_protocol_authenticated (omapi_object_t *h)
+{
+ if (h -> type != omapi_type_protocol)
+ return isc_boolean_false;
+ if (((omapi_protocol_object_t *)h) -> insecure)
+ return isc_boolean_false;
+ else
+ return isc_boolean_true;
+}
+
+/* Sets the address and authenticator verification callbacks. The handle
+ is to a listener object, not a protocol object. */
+
+isc_result_t omapi_protocol_configure_security (omapi_object_t *h,
+ isc_result_t (*verify_addr)
+ (omapi_object_t *,
+ omapi_addr_t *),
+ isc_result_t (*verify_auth)
+ (omapi_object_t *,
+ omapi_auth_key_t *))
+{
+ omapi_protocol_listener_object_t *l;
+
+ if (h -> outer && h -> outer -> type == omapi_type_protocol_listener)
+ h = h -> outer;
+
+ if (h -> type != omapi_type_protocol_listener)
+ return ISC_R_INVALIDARG;
+ l = (omapi_protocol_listener_object_t *)h;
+
+ l -> verify_auth = verify_auth;
+ l -> insecure = 0;
+
+ return omapi_listener_configure_security (h -> outer, verify_addr);
+}
+
+
/* Set up a listener for the omapi protocol. The handle stored points to
a listener object, not a protocol object. */
@@ -586,6 +927,9 @@ isc_result_t omapi_protocol_listen (omapi_object_t *h,
return status;
}
+ /* What a terrible default. */
+ obj -> insecure = 1;
+
status = omapi_listen ((omapi_object_t *)obj, port, max);
omapi_protocol_listener_dereference (&obj, MDL);
return status;
@@ -623,6 +967,9 @@ isc_result_t omapi_protocol_listener_signal (omapi_object_t *o,
if (status != ISC_R_SUCCESS)
return status;
+ obj -> verify_auth = p -> verify_auth;
+ obj -> insecure = p -> insecure;
+
status = omapi_object_reference (&obj -> outer, c, MDL);
if (status != ISC_R_SUCCESS) {
lose:
@@ -754,6 +1101,70 @@ isc_result_t omapi_protocol_send_status (omapi_object_t *po,
return status;
}
+/* The OMAPI_NOTIFY_PROTOCOL flag will cause the notify-object for the
+ message to be set to the protocol object. This is used when opening
+ the default authenticator. */
+
+isc_result_t omapi_protocol_send_open (omapi_object_t *po,
+ omapi_object_t *id,
+ const char *type,
+ omapi_object_t *object,
+ unsigned flags)
+{
+ isc_result_t status;
+ omapi_message_object_t *message = (omapi_message_object_t *)0;
+ omapi_object_t *mo;
+
+ if (po -> type != omapi_type_protocol)
+ return ISC_R_INVALIDARG;
+
+ status = omapi_message_new ((omapi_object_t **)&message, MDL);
+ mo = (omapi_object_t *)message;
+
+ if (status == ISC_R_SUCCESS)
+ status = omapi_set_int_value (mo, (omapi_object_t *)0,
+ "op", OMAPI_OP_OPEN);
+
+ if (status == ISC_R_SUCCESS)
+ status = omapi_set_object_value (mo, (omapi_object_t *)0,
+ "object", object);
+
+ if ((flags & OMAPI_CREATE) && (status == ISC_R_SUCCESS))
+ status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
+ "create", 1);
+
+ if ((flags & OMAPI_UPDATE) && (status == ISC_R_SUCCESS))
+ status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
+ "update", 1);
+
+ if ((flags & OMAPI_EXCL) && (status == ISC_R_SUCCESS))
+ status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
+ "exclusive", 1);
+
+ if ((flags & OMAPI_NOTIFY_PROTOCOL) && (status == ISC_R_SUCCESS))
+ status = omapi_set_object_value (mo, (omapi_object_t *)0,
+ "notify-object", po);
+
+ if (type && (status == ISC_R_SUCCESS))
+ status = omapi_set_string_value (mo, (omapi_object_t *)0,
+ "type", type);
+
+ if (status == ISC_R_SUCCESS)
+ status = omapi_message_register (mo);
+
+ if (status == ISC_R_SUCCESS) {
+ status = omapi_protocol_send_message (po, id, mo,
+ (omapi_object_t *)0);
+ if (status != ISC_R_SUCCESS)
+ omapi_message_unregister (mo);
+ }
+
+ if (message)
+ omapi_message_dereference (&message, MDL);
+
+ return status;
+}
+
isc_result_t omapi_protocol_send_update (omapi_object_t *po,
omapi_object_t *id,
unsigned rid,
diff --git a/omapip/support.c b/omapip/support.c
index 021fd405..f9f14887 100644
--- a/omapip/support.c
+++ b/omapip/support.c
@@ -53,6 +53,7 @@ omapi_object_type_t *omapi_type_protocol_listener;
omapi_object_type_t *omapi_type_waiter;
omapi_object_type_t *omapi_type_remote;
omapi_object_type_t *omapi_type_message;
+omapi_object_type_t *omapi_type_auth_key;
omapi_object_type_t *omapi_object_types;
int omapi_object_type_count;
@@ -62,6 +63,8 @@ isc_result_t omapi_init (void)
{
isc_result_t status;
+ dst_init();
+
/* Register all the standard object types... */
status = omapi_object_type_register (&omapi_type_connection,
"connection",
@@ -159,6 +162,19 @@ isc_result_t omapi_init (void)
if (status != ISC_R_SUCCESS)
return status;
+ status = omapi_object_type_register (&omapi_type_auth_key,
+ "authenticator",
+ 0,
+ omapi_auth_key_get_value,
+ omapi_auth_key_destroy,
+ 0,
+ omapi_auth_key_stuff_values,
+ omapi_auth_key_lookup,
+ 0, 0, 0, 0, 0,
+ sizeof (omapi_auth_key_t));
+ if (status != ISC_R_SUCCESS)
+ return status;
+
/* This seems silly, but leave it. */
return ISC_R_SUCCESS;
}
@@ -630,12 +646,11 @@ isc_result_t omapi_make_int_value (omapi_value_t **vp,
return status;
}
status = omapi_typed_data_new (file, line, &(*vp) -> value,
- omapi_datatype_int);
+ omapi_datatype_int, value);
if (status != ISC_R_SUCCESS) {
omapi_value_dereference (vp, file, line);
return status;
}
- (*vp) -> value -> u.integer = value;
return ISC_R_SUCCESS;
}
@@ -647,6 +662,36 @@ isc_result_t omapi_make_uint_value (omapi_value_t **vp,
return omapi_make_int_value (vp, name, (int)value, file, line);
}
+isc_result_t omapi_make_object_value (omapi_value_t **vp,
+ omapi_data_string_t *name,
+ omapi_object_t *value,
+ const char *file, int line)
+{
+ isc_result_t status;
+
+ status = omapi_value_new (vp, file, line);
+ if (status != ISC_R_SUCCESS)
+ return status;
+
+ status = omapi_data_string_reference (&(*vp) -> name,
+ name, file, line);
+ if (status != ISC_R_SUCCESS) {
+ omapi_value_dereference (vp, file, line);
+ return status;
+ }
+
+ if (value) {
+ status = omapi_typed_data_new (file, line, &(*vp) -> value,
+ omapi_datatype_object, value);
+ if (status != ISC_R_SUCCESS) {
+ omapi_value_dereference (vp, file, line);
+ return status;
+ }
+ }
+
+ return ISC_R_SUCCESS;
+}
+
isc_result_t omapi_make_handle_value (omapi_value_t **vp,
omapi_data_string_t *name,
omapi_object_t *value,
diff --git a/relay/Makefile.dist b/relay/Makefile.dist
index 39e64f25..d02f79fa 100644
--- a/relay/Makefile.dist
+++ b/relay/Makefile.dist
@@ -26,7 +26,7 @@ MAN = dhcrelay.8
DEBUG = -g
INCLUDES = -I$(TOP) $(BINDINC) -I$(TOP)/includes
-DHCPLIB = ../common/libdhcp.a ../omapip/libomapi.a
+DHCPLIB = ../common/libdhcp.a ../omapip/libomapi.a $(BINDLIB)
CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
all: $(PROG) $(CATMANPAGES)
diff --git a/server/dhcpd.c b/server/dhcpd.c
index 4e7e57e4..d2f207c7 100644
--- a/server/dhcpd.c
+++ b/server/dhcpd.c
@@ -43,7 +43,7 @@
#ifndef lint
static char ocopyright[] =
-"$Id: dhcpd.c,v 1.97 2000/07/27 09:03:05 mellon Exp $ Copyright 1995-2000 Internet Software Consortium.";
+"$Id: dhcpd.c,v 1.98 2000/08/03 21:00:39 neild Exp $ Copyright 1995-2000 Internet Software Consortium.";
#endif
static char copyright[] =
@@ -137,6 +137,18 @@ const char *path_dhcpd_pid = _PATH_DHCPD_PID;
int dhcp_max_agent_option_packet_length = DHCP_MTU_MAX;
+static omapi_auth_key_t *omapi_key = (omapi_auth_key_t *)0;
+
+static isc_result_t verify_addr (omapi_object_t *l, omapi_addr_t *addr) {
+ return ISC_R_SUCCESS;
+}
+
+static isc_result_t verify_auth (omapi_object_t *p, omapi_auth_key_t *a) {
+ if (a != omapi_key)
+ return ISC_R_INVALIDKEY;
+ return ISC_R_SUCCESS;
+}
+
int main (argc, argv, envp)
int argc;
char **argv, **envp;
@@ -164,6 +176,9 @@ int main (argc, argv, envp)
struct parse *parse;
int lose;
int omapi_port;
+ omapi_object_t *auth;
+ struct tsig_key *key;
+ omapi_typed_data_t *td;
int no_dhcpd_conf = 0;
int no_dhcpd_db = 0;
int no_dhcpd_pid = 0;
@@ -413,6 +428,24 @@ int main (argc, argv, envp)
data_string_forget (&db, MDL);
}
+ oc = lookup_option (&server_universe, options, SV_OMAPI_KEY);
+ if (oc &&
+ evaluate_option_cache (&db, (struct packet *)0,
+ (struct lease *)0, options,
+ (struct option_state *)0,
+ &global_scope, oc, MDL)) {
+ s = dmalloc (db.len + 1, MDL);
+ if (!s)
+ log_fatal ("no memory for OMAPI key filename.");
+ memcpy (s, db.data, db.len);
+ s [db.len] = 0;
+ data_string_forget (&db, MDL);
+ result = omapi_auth_key_lookup_name (&omapi_key, s);
+ dfree (s, MDL);
+ if (result != ISC_R_SUCCESS)
+ log_fatal ("Invalid OMAPI key: %s", s);
+ }
+
oc = lookup_option (&server_universe, options, SV_LOCAL_PORT);
if (oc &&
evaluate_option_cache (&db, (struct packet *)0,
@@ -510,6 +543,9 @@ int main (argc, argv, envp)
isc_result_totext (result));
result = omapi_protocol_listen (listener,
(unsigned)omapi_port, 1);
+ if (result == ISC_R_SUCCESS)
+ result = omapi_protocol_configure_security
+ (listener, verify_addr, verify_auth);
if (result != ISC_R_SUCCESS)
log_fatal ("Can't start OMAPI protocol: %s",
isc_result_totext (result));
diff --git a/server/stables.c b/server/stables.c
index 57381261..ccf7037f 100644
--- a/server/stables.c
+++ b/server/stables.c
@@ -43,7 +43,7 @@
#ifndef lint
static char copyright[] =
-"$Id: stables.c,v 1.15 2000/06/28 23:35:45 mellon Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
+"$Id: stables.c,v 1.16 2000/08/03 21:00:41 neild Exp $ Copyright (c) 1995-2000 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
@@ -481,7 +481,7 @@ struct option server_options [256] = {
{ "limited-broadcast-address", "I", &server_universe, 33 },
{ "remote-port", "S", &server_universe, 34 },
{ "local-address", "I", &server_universe, 35 },
- { "option-36", "X", &server_universe, 36 },
+ { "omapi-key", "t", &server_universe, 36 },
{ "option-37", "X", &server_universe, 37 },
{ "option-38", "X", &server_universe, 38 },
{ "option-39", "X", &server_universe, 39 },