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 @@ ...@@ -17,7 +17,7 @@
# http://www.isc.org for more information. # http://www.isc.org for more information.
# #
SUBDIRS= common omapip $(MINIRES) server client relay dhcpctl SUBDIRS= common $(MINIRES) omapip server client relay dhcpctl
all: all:
@for dir in ${SUBDIRS}; do \ @for dir in ${SUBDIRS}; do \
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
...@@ -948,7 +948,8 @@ void parse_client_lease_declaration (cfile, lease, ipp, clientp) ...@@ -948,7 +948,8 @@ void parse_client_lease_declaration (cfile, lease, ipp, clientp)
skip_to_semi (cfile); skip_to_semi (cfile);
break; 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_warn (cfile, "unknown key %s", val);
parse_semi (cfile); parse_semi (cfile);
break; break;
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
...@@ -292,29 +292,6 @@ void free_client_lease (lease, file, line) ...@@ -292,29 +292,6 @@ void free_client_lease (lease, file, line)
dfree (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 free_pairs;
pair new_pair (file, line) pair new_pair (file, line)
...@@ -1002,114 +979,6 @@ int packet_dereference (ptr, file, line) ...@@ -1002,114 +979,6 @@ int packet_dereference (ptr, file, line)
return 1; 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) int dns_zone_allocate (ptr, file, line)
struct dns_zone **ptr; struct dns_zone **ptr;
const char *file; const char *file;
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
...@@ -158,7 +158,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname, ...@@ -158,7 +158,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
strlen (zone -> key -> name) > NS_MAXDNAME) || strlen (zone -> key -> name) > NS_MAXDNAME) ||
(!zone -> key -> algorithm || (!zone -> key -> algorithm ||
strlen (zone -> key -> algorithm) > NS_MAXDNAME) || strlen (zone -> key -> algorithm) > NS_MAXDNAME) ||
(!zone -> key -> key.len)) { (!zone -> key)) {
dns_zone_dereference (&zone, MDL); dns_zone_dereference (&zone, MDL);
return ISC_R_INVALIDKEY; return ISC_R_INVALIDKEY;
} }
...@@ -169,7 +169,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname, ...@@ -169,7 +169,7 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname,
return ISC_R_NOMEMORY; return ISC_R_NOMEMORY;
} }
memset (tkey, 0, sizeof *tkey); memset (tkey, 0, sizeof *tkey);
tkey -> data = dmalloc (zone -> key -> key.len, MDL); tkey -> data = dmalloc (zone -> key -> key -> len, MDL);
if (!tkey -> data) { if (!tkey -> data) {
dfree (tkey, MDL); dfree (tkey, MDL);
goto nomem; goto nomem;
...@@ -177,8 +177,8 @@ isc_result_t find_tsig_key (ns_tsig_key **key, const char *zname, ...@@ -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 -> name, zone -> key -> name);
strcpy (tkey -> alg, zone -> key -> algorithm); strcpy (tkey -> alg, zone -> key -> algorithm);
memcpy (tkey -> data, memcpy (tkey -> data,
zone -> key -> key.data, zone -> key -> key.len); zone -> key -> key -> value, zone -> key -> key -> len);
tkey -> len = zone -> key -> key.len; tkey -> len = zone -> key -> key -> len;
*key = tkey; *key = tkey;
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }
...@@ -249,44 +249,6 @@ isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name) ...@@ -249,44 +249,6 @@ isc_result_t dns_zone_lookup (struct dns_zone **zone, const char *name)
return status; 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) int dns_zone_dereference (ptr, file, line)
struct dns_zone **ptr; struct dns_zone **ptr;
const char *file; const char *file;
...@@ -326,7 +288,7 @@ int dns_zone_dereference (ptr, file, line) ...@@ -326,7 +288,7 @@ int dns_zone_dereference (ptr, file, line)
if (dns_zone -> name) if (dns_zone -> name)
dfree (dns_zone -> name, file, line); dfree (dns_zone -> name, file, line);
if (dns_zone -> key) 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) if (dns_zone -> primary)
option_cache_dereference (&dns_zone -> primary, file, line); option_cache_dereference (&dns_zone -> primary, file, line);
if (dns_zone -> secondary) if (dns_zone -> secondary)
...@@ -447,4 +409,3 @@ void repudiate_zone (struct dns_zone **zone) ...@@ -447,4 +409,3 @@ void repudiate_zone (struct dns_zone **zone)
#endif /* NSUPDATE */ #endif /* NSUPDATE */
HASH_FUNCTIONS (dns_zone, const char *, struct dns_zone) HASH_FUNCTIONS (dns_zone, const char *, struct dns_zone)
HASH_FUNCTIONS (tsig_key, const char *, struct tsig_key)
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
#ifndef lint #ifndef lint
static char copyright[] = 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 */ #endif /* not lint */
#include "dhcpd.h" #include "dhcpd.h"
...@@ -1806,7 +1806,8 @@ int parse_zone (struct dns_zone *zone, struct parse *cfile) ...@@ -1806,7 +1806,8 @@ int parse_zone (struct dns_zone *zone, struct parse *cfile)
skip_to_semi (cfile); skip_to_semi (cfile);
return 0; 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); parse_warn (cfile, "unknown key %s", val);
if (!parse_semi (cfile)) if (!parse_semi (cfile))
return 0; return 0;
...@@ -1839,7 +1840,8 @@ int parse_key (struct parse *cfile) ...@@ -1839,7 +1840,8 @@ int parse_key (struct parse *cfile)
int token; int token;
const char *val; const char *val;
int done = 0; int done = 0;
struct tsig_key *key; struct auth_key *key;
struct data_string ds;
isc_result_t status; isc_result_t status;
token = next_token (&val, cfile); token = next_token (&val, cfile);
...@@ -1848,8 +1850,8 @@ int parse_key (struct parse *cfile) ...@@ -1848,8 +1850,8 @@ int parse_key (struct parse *cfile)
skip_to_semi (cfile); skip_to_semi (cfile);
return 0; return 0;
} }
key = (struct tsig_key *)0; key = (struct auth_key *)0;
if (!tsig_key_allocate (&key, MDL)) if (omapi_auth_key_new (&key, MDL) != ISC_R_SUCCESS)
log_fatal ("no memory for tsig key"); log_fatal ("no memory for tsig key");
key -> name = dmalloc (strlen (val) + 1, MDL); key -> name = dmalloc (strlen (val) + 1, MDL);
if (!key -> name) if (!key -> name)
...@@ -1883,13 +1885,23 @@ int parse_key (struct parse *cfile) ...@@ -1883,13 +1885,23 @@ int parse_key (struct parse *cfile)
break; break;
case SECRET: case SECRET:
if (key -> key.buffer) { if (key -> key) {
parse_warn (cfile, "key %s: too many secrets", parse_warn (cfile, "key %s: too many secrets",
key -> name); key -> name);
goto rbad; 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; goto rbad;
memcpy (key -> key -> value,
ds.buffer -> data, ds.len);
data_string_forget (&ds, MDL);
if (!parse_semi (cfile)) if (!parse_semi (cfile))
goto rbad; goto rbad;
break; break;
...@@ -1910,7 +1922,7 @@ int parse_key (struct parse *cfile) ...@@ -1910,7 +1922,7 @@ int parse_key (struct parse *cfile)
token = next_token (&val, cfile); token = next_token (&val, cfile);
/* Remember the key. */ /* Remember the key. */
status = enter_tsig_key (key); status = omapi_auth_key_enter (key);
if (status != ISC_R_SUCCESS) { if (status != ISC_R_SUCCESS) {
parse_warn (cfile, "tsig key %s: %s", parse_warn (cfile, "tsig key %s: %s",
key -> name, isc_result_totext (status)); key -> name, isc_result_totext (status));
...@@ -1921,7 +1933,7 @@ int parse_key (struct parse *cfile) ...@@ -1921,7 +1933,7 @@ int parse_key (struct parse *cfile)
rbad: rbad:
skip_to_rbrace (cfile, 1); skip_to_rbrace (cfile, 1);
bad: bad:
tsig_key_dereference (&key, MDL); omapi_auth_key_dereference (&key, MDL);
return 0; return 0;
} }
/* /*
......
...@@ -30,13 +30,13 @@ CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS) ...@@ -30,13 +30,13 @@ CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS)
all: libdhcpctl.a svtest cltest $(CATMANPAGES) 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 \ $(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 \ $(CC) $(DEBUG) $(LFLAGS) -o cltest cltest.o libdhcpctl.a \
../omapip/libomapi.a $(LIBS) ../omapip/libomapi.a $(BINDLIB) $(LIBS)
libdhcpctl.a: $(OBJ) libdhcpctl.a: $(OBJ)
rm -f libdhcpctl.a rm -f libdhcpctl.a
......
...@@ -46,30 +46,61 @@ ...@@ -46,30 +46,61 @@
int main (int, char **); 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 main (argc, argv)
int argc; int argc;
char **argv; char **argv;
{ {
isc_result_t status, waitstatus; isc_result_t status, waitstatus;
dhcpctl_handle authenticator;
dhcpctl_handle connection; dhcpctl_handle connection;
dhcpctl_handle host_handle, group_handle, interface_handle; dhcpctl_handle host_handle, group_handle, interface_handle;
dhcpctl_data_string cid; dhcpctl_data_string cid;
dhcpctl_data_string result, groupname, identifier; dhcpctl_data_string result, groupname, identifier;
int i; int i;
int mode; int mode = undefined;
char *name = 0, *pass = 0, *algorithm = "hmac-md5", *interface = 0;
const char *action; const char *action;
if (!strcmp (argv [1], "-u")) { for (i = 1; i < argc; i++) {
mode = up; if (!strcmp (argv[i], "-u")) {
} else if (!strcmp (argv [1], "-d")) { mode = up;
mode = down; } else if (!strcmp (argv [1], "-d")) {
} else { mode = down;
fprintf (stderr, "Unknown switch \"%s\"\n", argv [1]); } else if (!strcmp (argv[i], "-n")) {
exit (1); 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 (); status = dhcpctl_initialize ();
if (status != ISC_R_SUCCESS) { if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_initialize: %s\n", fprintf (stderr, "dhcpctl_initialize: %s\n",
...@@ -77,16 +108,29 @@ int main (argc, argv) ...@@ -77,16 +108,29 @@ int main (argc, argv)
exit (1); 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, status = dhcpctl_connect (&connection, "127.0.0.1", 7911,
(dhcpctl_handle)0); authenticator);
if (status != ISC_R_SUCCESS) { if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_connect: %s\n", fprintf (stderr, "dhcpctl_connect: %s\n",
isc_result_totext (status)); isc_result_totext (status));
exit (1); exit (1);
} }
memset (&interface_handle, 0, sizeof interface_handle); interface_handle = dhcpctl_null_handle;
status = dhcpctl_new_object (&interface_handle, status = dhcpctl_new_object (&interface_handle,
connection, "interface"); connection, "interface");
if (status != ISC_R_SUCCESS) { if (status != ISC_R_SUCCESS) {
...@@ -95,7 +139,8 @@ int main (argc, argv) ...@@ -95,7 +139,8 @@ int main (argc, argv)
exit (1); 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) { if (status != ISC_R_SUCCESS) {
fprintf (stderr, "dhcpctl_set_value: %s\n",