Commit 49146f3c authored by Damien Neil's avatar Damien Neil

Added authentication support. The tsig_key structure has been renamed

to auth_key and moved into libomapi.  libomapi now depends on libres,
which contains the data signing routines.
parent c62871ba
......@@ -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 \
......
......@@ -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;
......
......@@ -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;
......
......@@ -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)
......@@ -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;
}
/*
......
......@@ -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
......
......@@ -46,30 +46,61 @@
int main (int, char **);
enum modes { up, down };
enum modes { up, down, undefined };
static void usage (char *s) {
fprintf (stderr,
"Usage: %s [-n <username>] [-p <password>] [-a <algorithm>]"
"(-u | -d) <if>\n", s);
exit (1);
}
int main (argc, argv)
int argc;
char **argv;
{
isc_result_t status, waitstatus;
dhcpctl_handle authenticator;
dhcpctl_handle connection;
dhcpctl_handle host_handle, group_handle, interface_handle;
dhcpctl_data_string cid;
dhcpctl_data_string result, groupname, identifier;
int i;
int mode;
int mode = undefined;
char *name = 0, *pass = 0, *algorithm = "hmac-md5", *interface = 0;
const char *action;
if (!strcmp (argv [1], "-u")) {
mode = up;
} else if (!strcmp (argv [1], "-d")) {
mode = down;
} else {
fprintf (stderr, "Unknown switch \"%s\"\n", argv [1]);
exit (1);
for (i = 1; i < argc; i++) {
if (!strcmp (argv[i], "-u")) {
mode = up;
} else if (!strcmp (argv [1], "-d")) {
mode = down;
} else if (!strcmp (argv[i], "-n")) {
if (++i == argc)
usage(argv[0]);
name = argv[i];
} else if (!strcmp (argv[i], "-p")) {
if (++i == argc)
usage(argv[0]);
pass = argv[i];
} else if (!strcmp (argv[i], "-a")) {
if (++i == argc)
usage(argv[0]);
algorithm = argv[i];
} else if (argv[i][0] == '-') {
usage(argv[0]);
} else {
interface = argv[i];
}
}
if (!interface)
usage(argv[0]);
if (mode == undefined)
usage(argv[0]);
if ((name || pass) && !(name && pass))
usage(argv[0]);
status = dhcpctl_initialize ();
if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_initialize: %s\n",
......@@ -77,16 +108,29 @@ int main (argc, argv)
exit (1);
}
memset (&connection, 0, sizeof connection);
authenticator = dhcpctl_null_handle;
if (name) {
status = dhcpctl_new_authenticator (&authenticator,
name, algorithm, pass,
strlen (pass) + 1);
if (status != ISC_R_SUCCESS) {
fprintf (stderr, "Cannot create authenticator: %s\n",
isc_result_totext (status));
exit (1);
}
}
connection = dhcpctl_null_handle;
status = dhcpctl_connect (&connection, "127.0.0.1", 7911,
(dhcpctl_handle)0);
authenticator);
if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_connect: %s\n",
isc_result_totext (status));
exit (1);
}
memset (&interface_handle, 0, sizeof interface_handle);
interface_handle = dhcpctl_null_handle;
status = dhcpctl_new_object (&interface_handle,
connection, "interface");
if (status != ISC_R_SUCCESS) {
......@@ -95,7 +139,8 @@ int main (argc, argv)
exit (1);
}
status = dhcpctl_set_string_value (interface_handle, argv [2], "name");
status = dhcpctl_set_string_value (interface_handle,
interface, "name");
if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_set_value: %s\n",
isc_result_totext (status));
......@@ -104,7 +149,7 @@ int main (argc, argv)
if (mode == up) {
/* "up" the interface */
printf ("upping interface %s\n", argv [2]);
printf ("upping interface %s\n", interface);
action = "create";
status = dhcpctl_open_object (interface_handle, connection,
DHCPCTL_CREATE | DHCPCTL_EXCL);
......@@ -115,7 +160,7 @@ int main (argc, argv)
}
} else {
/* down the interface */
printf ("downing interface %s\n", argv [2]);
printf ("downing interface %s\n", interface);
action = "remove";
status = dhcpctl_open_object (interface_handle, connection, 0);
if (status != ISC_R_SUCCESS) {
......
......@@ -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) {
......
......@@ -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 *);
......
......@@ -44,6 +44,56 @@
#include <omapip/omapip_p.h>
#include "dhcpctl.h"
/* dhcpctl_new_authenticator
synchronous - creates an authenticator object.
returns nonzero status code if the object couldn't be created
stores handle to authenticator through h if successful, and returns zero.
name is the authenticator name (NUL-terminated string).
algorithm is the NUL-terminated string name of the algorithm to use
(currently, only "hmac-md5" is supported).
secret and secret_len is the key secret. */
dhcpctl_status dhcpctl_new_authenticator (dhcpctl_handle *h,
const char *name,
const char *algorithm,
const char *secret,
unsigned secret_len)
{
struct auth_key *key = (struct auth_key *)0;
isc_result_t status;
status = omapi_auth_key_new (&key, MDL);
if (status != ISC_R_SUCCESS)
return status;
key -> name = dmalloc (strlen (name) + 1, MDL);
if (!key -> name) {
omapi_auth_key_dereference (&key, MDL);
return ISC_R_NOMEMORY;
}
strcpy (key -> name, name);
key -> algorithm = dmalloc (strlen (algorithm) + 1, MDL);
if (!key -> algorithm) {
omapi_auth_key_dereference (&key, MDL);
return ISC_R_NOMEMORY;
}
strcpy (key -> algorithm, algorithm);
status = omapi_data_string_new (&key -> key, secret_len, MDL);
if (status != ISC_R_SUCCESS) {
omapi_auth_key_dereference (&key, MDL);
return status;
}
memcpy (key -> key -> value, secret, secret_len);
key -> key -> len = secret_len;
*h = (dhcpctl_handle) key;
return ISC_R_SUCCESS;
}
/* dhcpctl_new_object
synchronous - creates a local handle for a host entry.
......
/* 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. */