]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Added authentication support. The tsig_key structure has been renamed
authorDamien Neil <source@isc.org>
Thu, 3 Aug 2000 21:00:41 +0000 (21:00 +0000)
committerDamien Neil <source@isc.org>
Thu, 3 Aug 2000 21:00:41 +0000 (21:00 +0000)
to auth_key and moved into libomapi.  libomapi now depends on libres,
which contains the data signing routines.

27 files changed:
Makefile.dist
client/clparse.c
common/alloc.c
common/dns.c
common/parse.c
dhcpctl/Makefile.dist
dhcpctl/cltest.c
dhcpctl/dhcpctl.c
dhcpctl/dhcpctl.h
dhcpctl/remote.c
includes/auth.h [deleted file]
includes/dhcpd.h
includes/omapip/omapip.h
includes/omapip/omapip_p.h
minires/dst_api.c
omapip/Makefile.dist
omapip/auth.c [new file with mode: 0644]
omapip/buffer.c
omapip/connection.c
omapip/dispatch.c
omapip/listener.c
omapip/message.c
omapip/protocol.c
omapip/support.c
relay/Makefile.dist
server/dhcpd.c
server/stables.c

index e51feb248709416656e62d94d7fdf2be850eec16..5780234934d139df5470fbfc9811bd9c133c46d0 100644 (file)
@@ -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 \
index 48ffa7d11a3bc554294c13cfe84fd021eb325c40..979152536f00e58368165f60056b93cb9761daff 100644 (file)
@@ -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;
index 7cb83e1984f38659ccbe700cde31a2753a2fef8d..040d826a415b0da7e9d2d40fcc3cd4d8efa13b9a 100644 (file)
@@ -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;
index 0d029da9d0d7c70a164c5e1afa91eaba593be1fa..31800bfc2349b57d05a72cbd25c04d4ad25b26c4 100644 (file)
@@ -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)
index fdbf659844f25ef706496dba4bf9016ecdc03a1e..30f7c641721ff848aac6265571c1c31a9f18a3e2 100644 (file)
@@ -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;
 }
 /*
index 24c875c5ec5bb3f43113e40fa6d43d4b3cb21560..03206b5de0441ce7b825cc51110c424a49499507 100644 (file)
@@ -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
index 904f037e6017f76fac8b2bf15f4fe4b349874737..cc4bba836bc78ea14a274b1bba42058f7730c928 100644 (file)
 
 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) {
index 2a8e7bfb35d066b87ab4755d84161df2c6abdae0..cf1a60148a1683a7683790cb06f81a20b4722087 100644 (file)
@@ -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) {
index 8eb9c81275cad434de7858c47587af717e4a7108..afe70a2c7b340efae01c67db0716a140d0f7eb57 100644 (file)
@@ -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 *);
index 07a6e1d1d87557da677e17afbeb2fc1120e244d9..546508746676c70d8337427c9087e4eaead4eda5 100644 (file)
 #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 (file)
index cc7dc06..0000000
+++ /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];
-};
-
index f42307ec77311ff675bbd6f2f7246a9bbe00a0e9..9a008affd9d2490160da10dcf16ffc9c52267db1 100644 (file)
@@ -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;
index c9c6b974cc68053c190d82acf7f104852da689bd..ecd80061ab932b1803f7831fcd6af421976f4007 100644 (file)
@@ -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 *,
index 74ef2e23a449321dfe50d0241961c4442a13cc49..0661d970306d08044c5078001b04491fe66f4737 100644 (file)
@@ -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);
index 15e3ab55aba2b4e4f40173e09eaa077d234d6ac5..69e6881541b2e76e9019672c2dbf2f797925685a 100644 (file)
@@ -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)
index 9dd2dfb1f1bd2b6ac53bab6047b28b56accc4375..e7bec5307c3cb3af4df60a6a6fdfbb3470d1c16b 100644 (file)
@@ -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 (file)
index 0000000..f5ce57b
--- /dev/null
@@ -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)
index 81fa07ce74ba0efe7e476cc3c1df47741801676b..e4bdc19a9e5fe07ce91b74a0961cb8144db6cb4a 100644 (file)
@@ -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;
index 2d85c39b853acf3e4e204368411f72abb46c0a45..a02fe29f0392b1571d5464074ddf60cce30af596 100644 (file)
@@ -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))
index ee402aeda8e53cbfa557f341cb77802d096244d3..2701d7b9519ec12cf51fee9f2c9d046efe6700ba 100644 (file)
@@ -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;
        }
 
index 23c6250f7ec096e7d5564f1f2938ac662dda8ab2..03ee6e5dd0a5b995ebe92f1654a16df073a4d0d0 100644 (file)
@@ -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,
index 60cd68576c37e212cecc7329daceb673acbf4273..7837f487dd2b6c08e7a8bbc837e8239682ac41a7 100644 (file)
@@ -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);
        }
index b254e2a08510ce5dacfa742ce6a491ee82a26c05..7eaeab896e194183a0f7273a1991c82c73ce2411 100644 (file)
@@ -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,
index 021fd405f16be047d5813c924dbe4497505e65a2..f9f148871cb1944ddc2e460daf854ac716e9ccda 100644 (file)
@@ -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,
index 39e64f25fb5061a662a568c6623b6e3b8fd7d768..d02f79facdf011e8885fdfff90ae040ff6ae6c78 100644 (file)
@@ -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)
index 4e7e57e499945e79a8cd5050ec8adae187f38cf0..d2f207c7fbbd90315199123a62e0ad83cfb2b63a 100644 (file)
@@ -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));
index 573812616fad8434033dd69bec1daa60a540a3d7..ccf7037f4cd475d1cfba3843bc7a8779bd736ce7 100644 (file)
@@ -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 },