diff options
author | obrien <obrien@FreeBSD.org> | 2000-07-20 08:36:42 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-07-20 08:36:42 +0000 |
commit | 6c5ad021325798ac0714185ddc1df496452dfa44 (patch) | |
tree | 74fa317603829de6b9ba9165393c99dd06763841 /contrib | |
parent | 5d4d7eb572e000c3cc53cfa2975257bfdd959b00 (diff) | |
download | FreeBSD-src-6c5ad021325798ac0714185ddc1df496452dfa44.zip FreeBSD-src-6c5ad021325798ac0714185ddc1df496452dfa44.tar.gz |
Import Patchlevel 3 of the ISC 2.0 dhcp client.
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/isc-dhcp/Makefile.conf | 1 | ||||
-rw-r--r-- | contrib/isc-dhcp/README | 6 | ||||
-rw-r--r-- | contrib/isc-dhcp/RELNOTES | 11 | ||||
-rw-r--r-- | contrib/isc-dhcp/client/Makefile.dist | 3 | ||||
-rw-r--r-- | contrib/isc-dhcp/client/clparse.c | 6 | ||||
-rw-r--r-- | contrib/isc-dhcp/client/dhclient.c | 231 | ||||
-rw-r--r-- | contrib/isc-dhcp/includes/dhcpd.h | 7 | ||||
-rw-r--r-- | contrib/isc-dhcp/includes/version.h | 2 |
8 files changed, 173 insertions, 94 deletions
diff --git a/contrib/isc-dhcp/Makefile.conf b/contrib/isc-dhcp/Makefile.conf index d2fb534..509e32f 100644 --- a/contrib/isc-dhcp/Makefile.conf +++ b/contrib/isc-dhcp/Makefile.conf @@ -46,6 +46,7 @@ MANCAT = cat ETC = /etc VARRUN = /var/run VARDB = /var/db +CLIENT_PATH = '"PATH=/usr/ucb:/usr/bin:/usr/sbin:/bin:/sbin"' # Major version number (if applicable) ##--majver-- diff --git a/contrib/isc-dhcp/README b/contrib/isc-dhcp/README index 03f308f..cf1fa60 100644 --- a/contrib/isc-dhcp/README +++ b/contrib/isc-dhcp/README @@ -1,6 +1,6 @@ <C><H4>Internet Software Consortium</H4></C> <C><H4>Dynamic Host Configuration Protocol Distribution</H4></C> -<C><H4>Version 2 Patchlevel 2</H4></C> +<C><H4>Version 2 Patchlevel 3</H4></C> <C><H4>June 30, 2000</H4></C> <C><H4>README FILE</H4></C> @@ -135,13 +135,13 @@ information. On Digital Unix, type ``man pfilt''.</P> the tar utility and the gzip command - type something like:</P> <BLOCKQUOTE> - zcat dhcp-2.0pl2.tar.gz |tar xvf - + zcat dhcp-2.0pl3.tar.gz |tar xvf - </BLOCKQUOTE> <P>On BSD/OS, you have to type gzcat, not zcat, and you may run into similar problems on other operating systems.</P> -<P>Now, cd to the dhcp-2.0pl2 subdirectory that you've just created and +<P>Now, cd to the dhcp-2.0pl3 subdirectory that you've just created and configure the source tree by typing:</P> <BLOCKQUOTE> diff --git a/contrib/isc-dhcp/RELNOTES b/contrib/isc-dhcp/RELNOTES index 7e7a5c3..60d2958 100644 --- a/contrib/isc-dhcp/RELNOTES +++ b/contrib/isc-dhcp/RELNOTES @@ -1,7 +1,7 @@ Internet Software Consortium Dynamic Host Configuration Protocol Distribution - Version 2 Patchlevel 2 - June 30, 2000 + Version 2 Patchlevel 3 + July 19, 2000 Release Notes @@ -22,6 +22,13 @@ the README file. This log describes the changes that have been made in version 2.0 since June of 1997. + CHANGES FROM VERSION 2.0 PATCHLEVEL 2 + +- Rather than calling a client environment setup script, set the + environment up directly, so as to avoid any possible exploit making + use of clever shell metacharacter hacks. This is a security fix + that applies to the DHCP client *only*. + CHANGES FROM VERSION 2.0 PATCHLEVEL 1 - Fix a case where an unitialized pointer could result from an exceptional diff --git a/contrib/isc-dhcp/client/Makefile.dist b/contrib/isc-dhcp/client/Makefile.dist index 2109d39..2b261a7 100644 --- a/contrib/isc-dhcp/client/Makefile.dist +++ b/contrib/isc-dhcp/client/Makefile.dist @@ -42,7 +42,8 @@ MAN = dhclient.8 dhclient.conf.5 dhclient-script.8 dhclient.leases.5 DEBUG = -g INCLUDES = -I.. -I../includes DHCPLIB = ../common/libdhcp.a -CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS) +CFLAGS = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS) \ + -DCLIENT_PATH=${CLIENT_PATH} all: $(PROG) $(CATMANPAGES) diff --git a/contrib/isc-dhcp/client/clparse.c b/contrib/isc-dhcp/client/clparse.c index 65acbc8..9af7744 100644 --- a/contrib/isc-dhcp/client/clparse.c +++ b/contrib/isc-dhcp/client/clparse.c @@ -42,7 +42,7 @@ #ifndef lint static char copyright[] = -"$Id: clparse.c,v 1.13.2.4 1999/03/29 21:21:37 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n"; +"$Id: clparse.c,v 1.13.2.5 2000/07/20 05:06:40 mellon Exp $ Copyright (c) 1997 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -50,6 +50,8 @@ static char copyright[] = struct client_config top_level_config; +char client_script_name [] = "/etc/dhclient-script"; + /* client-conf-file :== client-declarations EOF client-declarations :== <nil> | client-declaration @@ -79,7 +81,7 @@ int read_client_conf () top_level_config.backoff_cutoff = 15; top_level_config.initial_interval = 3; top_level_config.bootp_policy = ACCEPT; - top_level_config.script_name = "/etc/dhclient-script"; + top_level_config.script_name = client_script_name; top_level_config.requested_options [top_level_config.requested_option_count++] = DHO_SUBNET_MASK; diff --git a/contrib/isc-dhcp/client/dhclient.c b/contrib/isc-dhcp/client/dhclient.c index 30424f6..4110ad5 100644 --- a/contrib/isc-dhcp/client/dhclient.c +++ b/contrib/isc-dhcp/client/dhclient.c @@ -56,7 +56,7 @@ #ifndef lint static char ocopyright[] = -"$Id: dhclient.c,v 1.44.2.44 2000/01/26 12:51:11 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; +"$Id: dhclient.c,v 1.44.2.45 2000/07/20 05:06:41 mellon Exp $ Copyright (c) 1995, 1996, 1997, 1998, 1999 The Internet Software Consortium. All rights reserved.\n"; #endif /* not lint */ #include "dhcpd.h" @@ -139,6 +139,10 @@ int main (argc, argv, envp) no_daemon = 1; } else if (!strcmp (argv [i], "-D")) { save_scripts = 1; + } else if (!strcmp (argv [i], "-cf")) { + if (++i == argc) + usage (s); + path_dhclient_conf = argv [i]; } else if (!strcmp (argv [i], "-pf")) { if (++i == argc) usage (s); @@ -1899,38 +1903,24 @@ void script_init (ip, reason, medium) char *reason; struct string_list *medium; { - int fd; -#ifndef HAVE_MKSTEMP - - do { -#endif - strcpy (scriptName, "/tmp/dcsXXXXXX"); -#ifdef HAVE_MKSTEMP - fd = mkstemp (scriptName); -#else - if (!mktemp (scriptName)) - error ("can't create temporary client script %s: %m", - scriptName); - fd = open (scriptName, O_EXCL | O_CREAT | O_WRONLY, 0600); - } while (fd < 0 && errno == EEXIST); -#endif - if (fd < 0) - error ("can't create temporary script %s: %m", scriptName); + struct string_list *sl, *next; - scriptFile = fdopen (fd, "w"); - if (!scriptFile) - error ("can't write script file: %m"); - fprintf (scriptFile, "#!/bin/sh\n\n"); if (ip) { - fprintf (scriptFile, "interface=\"%s\"\n", ip -> name); - fprintf (scriptFile, "export interface\n"); - } - if (medium) { - fprintf (scriptFile, "medium=\"%s\"\n", medium -> string); - fprintf (scriptFile, "export medium\n"); + for (sl = ip -> client -> env; sl; sl = next) { + next = sl -> next; + dfree (sl, "script_init"); + } + ip -> client -> env = (struct string_list *)0; + ip -> client -> envc = 0; + + client_envadd (ip -> client, "", "interface", "%s", + ip -> name); + if (medium) + client_envadd (ip -> client, + "", "medium", "%s", medium -> string); + + client_envadd (ip -> client, "", "reason", "%s", reason); } - fprintf (scriptFile, "reason=\"%s\"\n", reason); - fprintf (scriptFile, "export reason\n"); } void script_write_params (ip, prefix, lease) @@ -1942,9 +1932,8 @@ void script_write_params (ip, prefix, lease) u_int8_t dbuf [1500]; int len; - fprintf (scriptFile, "%sip_address=\"%s\"\n", - prefix, piaddr (lease -> address)); - fprintf (scriptFile, "export %sip_address\n", prefix); + client_envadd (ip -> client, + prefix, "ip_address", "%s", piaddr (lease -> address)); /* For the benefit of Linux (and operating systems which may have similar needs), compute the network address based on @@ -1965,36 +1954,26 @@ void script_write_params (ip, prefix, lease) subnet = subnet_number (lease -> address, netmask); if (subnet.len) { - fprintf (scriptFile, "%snetwork_number=\"%s\";\n", - prefix, piaddr (subnet)); - fprintf (scriptFile, "export %snetwork_number\n", - prefix); + client_envadd (ip -> client, prefix, "network_number", + "%s", piaddr (subnet)); if (!lease -> options [DHO_BROADCAST_ADDRESS].len) { broadcast = broadcast_addr (subnet, netmask); if (broadcast.len) { - fprintf (scriptFile, - "%s%s=\"%s\";\n", prefix, - "broadcast_address", - piaddr (broadcast)); - fprintf (scriptFile, - "export %s%s\n", prefix, - "broadcast_address"); + client_envadd (ip -> client, + prefix, "broadcast_address", + "%s", piaddr (subnet)); } } } } - if (lease -> filename) { - fprintf (scriptFile, "%sfilename=\"%s\";\n", - prefix, lease -> filename); - fprintf (scriptFile, "export %sfilename\n", prefix); - } - if (lease -> server_name) { - fprintf (scriptFile, "%sserver_name=\"%s\";\n", - prefix, lease -> server_name); - fprintf (scriptFile, "export %sserver_name\n", prefix); - } + if (lease -> filename) + client_envadd (ip -> client, + prefix, "filename", "%s", lease -> filename); + if (lease -> server_name) + client_envadd (ip -> client, prefix, "server_name", + "%s", lease -> server_name); for (i = 0; i < 256; i++) { u_int8_t *dp; @@ -2067,57 +2046,141 @@ void script_write_params (ip, prefix, lease) len = 0; } if (len) { - char *s = dhcp_option_ev_name (&dhcp_options [i]); - - fprintf (scriptFile, "%s%s=\"%s\"\n", prefix, s, - pretty_print_option (i, dp, len, 0, 0)); - fprintf (scriptFile, "export %s%s\n", prefix, s); + char name [256]; + if (dhcp_option_ev_name (name, sizeof name, + &dhcp_options [i])) { + client_envadd (ip -> client, prefix, name, "%s", + (pretty_print_option (i, dp, + len, 0, 0))); + } } } - fprintf (scriptFile, "%sexpiry=\"%d\"\n", - prefix, (int)lease -> expiry); /* XXX */ - fprintf (scriptFile, "export %sexpiry\n", prefix); + client_envadd (ip -> client, + prefix, "expiry", "%d", (int)(lease -> expiry)); } int script_go (ip) struct interface_info *ip; { int rval; + char *scriptName; + char *argv [2]; + char **envp; + char *epp [3]; + char reason [] = "REASON=NBI"; + static char client_path [] = CLIENT_PATH; + int i; + struct string_list *sp, *next; + int pid, wpid, wstatus; - if (ip) - fprintf (scriptFile, "%s\n", - ip -> client -> config -> script_name); - else - fprintf (scriptFile, "%s\n", - top_level_config.script_name); - fprintf (scriptFile, "exit $?\n"); - fclose (scriptFile); - chmod (scriptName, 0700); - rval = system (scriptName); - if (!save_scripts) - unlink (scriptName); - return rval; + if (ip) { + scriptName = ip -> client -> config -> script_name; + envp = dmalloc ((ip -> client -> envc + 2) * sizeof (char *), + "script_go"); + if (!envp) { + error ("No memory for client script environment."); + return 0; + } + i = 0; + for (sp = ip -> client -> env; sp; sp = sp -> next) { + envp [i++] = sp -> string; + } + envp [i++] = client_path; + envp [i] = (char *)0; + } else { + scriptName = top_level_config.script_name; + epp [0] = reason; + epp [1] = client_path; + epp [2] = (char *)0; + envp = epp; + } + + argv [0] = scriptName; + argv [1] = (char *)0; + + pid = fork (); + if (pid < 0) { + error ("fork: %m"); + wstatus = 0; + } else if (pid) { + do { + wpid = wait (&wstatus); + } while (wpid != pid && wpid > 0); + if (wpid < 0) { + error ("wait: %m"); + wstatus = 0; + } + } else { + execve (scriptName, argv, envp); + error ("execve (%s, ...): %m", scriptName); + exit (0); + } + + if (ip) { + for (sp = ip -> client -> env; sp; sp = next) { + next = sp -> next; + dfree (sp, "script_go"); + } + ip -> client -> env = (struct string_list *)0; + ip -> client -> envc = 0; + dfree (envp, "script_go"); + } + return wstatus & 0xff; } -char *dhcp_option_ev_name (option) +void client_envadd (struct client_state *client, + const char *prefix, const char *name, const char *fmt, ...) +{ + char spbuf [1024]; + char *s; + unsigned len, i; + struct string_list *val; + va_list list; + + va_start (list, fmt); + len = vsnprintf (spbuf, sizeof spbuf, fmt, list); + va_end (list); + + val = dmalloc (strlen (prefix) + strlen (name) + 1 /* = */ + + len + sizeof *val, "client_envadd"); + if (!val) + return; + s = val -> string; + strcpy (s, prefix); + strcat (s, name); + s += strlen (s); + *s++ = '='; + if (len >= sizeof spbuf) { + va_start (list, fmt); + vsnprintf (s, len + 1, fmt, list); + va_end (list); + } else + strcpy (s, spbuf); + val -> next = client -> env; + client -> env = val; + client -> envc++; +} + +int dhcp_option_ev_name (buf, buflen, option) + char *buf; + unsigned buflen; struct option *option; { - static char evbuf [256]; int i; - if (strlen (option -> name) + 1 > sizeof evbuf) - error ("option %s name is larger than static buffer."); for (i = 0; option -> name [i]; i++) { + if (i + 1 == buflen) + return 0; if (option -> name [i] == '-') - evbuf [i] = '_'; + buf [i] = '_'; else - evbuf [i] = option -> name [i]; + buf [i] = option -> name [i]; } - evbuf [i] = 0; - return evbuf; + buf [i] = 0; + return 1; } - + void go_daemon () { static int state = 0; diff --git a/contrib/isc-dhcp/includes/dhcpd.h b/contrib/isc-dhcp/includes/dhcpd.h index ddf34f0..d46ddf1 100644 --- a/contrib/isc-dhcp/includes/dhcpd.h +++ b/contrib/isc-dhcp/includes/dhcpd.h @@ -356,6 +356,9 @@ struct client_state { struct iaddr requested_address; /* Address we would like to get. */ struct client_config *config; /* Information from config file. */ + + struct string_list *env; /* Client script environment. */ + int envc; /* Number of entries in environment. */ }; /* Information about each network interface. */ @@ -895,13 +898,15 @@ void free_client_lease PROTO ((struct client_lease *)); void rewrite_client_leases PROTO ((void)); void write_client_lease PROTO ((struct interface_info *, struct client_lease *, int)); -char *dhcp_option_ev_name PROTO ((struct option *)); void script_init PROTO ((struct interface_info *, char *, struct string_list *)); void script_write_params PROTO ((struct interface_info *, char *, struct client_lease *)); int script_go PROTO ((struct interface_info *)); +void client_envadd PROTO ((struct client_state *, + const char *, const char *, const char *, ...)); +int dhcp_option_ev_name (char *, size_t, struct option *); struct client_lease *packet_to_lease PROTO ((struct packet *)); void go_daemon PROTO ((void)); diff --git a/contrib/isc-dhcp/includes/version.h b/contrib/isc-dhcp/includes/version.h index ccda68f..70d3d067 100644 --- a/contrib/isc-dhcp/includes/version.h +++ b/contrib/isc-dhcp/includes/version.h @@ -1,3 +1,3 @@ /* Current version of ISC DHCP Distribution. */ -#define DHCP_VERSION "2.0pl2" +#define DHCP_VERSION "2.0pl3" |