summaryrefslogtreecommitdiffstats
path: root/lib/libutil
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2004-02-26 22:41:47 +0000
committerkientzle <kientzle@FreeBSD.org>2004-02-26 22:41:47 +0000
commit8b8fb9aae5628c7005a6ddca3f43524536e45a67 (patch)
tree5e278436635ecd11128c037e5897c960d101598c /lib/libutil
parent58a98b5bd1671c30f49bae2eadb70fb996c4ac0b (diff)
downloadFreeBSD-src-8b8fb9aae5628c7005a6ddca3f43524536e45a67.zip
FreeBSD-src-8b8fb9aae5628c7005a6ddca3f43524536e45a67.tar.gz
Add a clean_environment call to libutil.
This function removes all environment variables except the ones listed on a "whitelist." The function accepts two whitelist arguments. If the first is NULL, a built-in default list will be used. This allows callers to get a variety of behaviors: * Default screening: provide NULL for both lists * Custom screening: provide a custom list for the first argument * Modified default screening: provide NULL for first arg, list of additional variables to preserve in the second arg Idea from: Jacques Vidrine MFC after: 2 weeks
Diffstat (limited to 'lib/libutil')
-rw-r--r--lib/libutil/Makefile8
-rw-r--r--lib/libutil/clean_environment.386
-rw-r--r--lib/libutil/clean_environment.c121
3 files changed, 211 insertions, 4 deletions
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index e13663c..de6aa63 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -6,9 +6,9 @@ SHLIB_MAJOR= 4
SHLIBDIR?= /lib
CFLAGS+=-DLIBC_SCCS -I${.CURDIR} -I${.CURDIR}/../libc/gen/
CFLAGS+=-DINET6
-SRCS= _secure_path.c auth.c fparseln.c login.c login_auth.c \
- login_cap.c login_class.c login_crypt.c login_ok.c login_times.c \
- login_tty.c logout.c logwtmp.c property.c pty.c \
+SRCS= _secure_path.c auth.c clean_environment.c fparseln.c login.c \
+ login_auth.c login_cap.c login_class.c login_crypt.c login_ok.c \
+ login_times.c login_tty.c logout.c logwtmp.c property.c pty.c \
pw_util.c realhostname.c stub.c \
trimdomain.c uucplock.c
INCS= libutil.h login_cap.h
@@ -16,7 +16,7 @@ INCS= libutil.h login_cap.h
MAN+= login.3 login_auth.3 login_tty.3 logout.3 logwtmp.3 pty.3 \
login_cap.3 login_class.3 login_times.3 login_ok.3 \
_secure_path.3 uucplock.3 property.3 auth.3 realhostname.3 \
- realhostname_sa.3 trimdomain.3 fparseln.3
+ realhostname_sa.3 trimdomain.3 fparseln.3 clean_environment.3
MAN+= login.conf.5 auth.conf.5
MLINKS+= property.3 properties_read.3 property.3 properties_free.3
MLINKS+= property.3 property_find.3
diff --git a/lib/libutil/clean_environment.3 b/lib/libutil/clean_environment.3
new file mode 100644
index 0000000..b99ebf3
--- /dev/null
+++ b/lib/libutil/clean_environment.3
@@ -0,0 +1,86 @@
+.\" Copyright (c) 2003 Tim Kientzle
+.\" 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd March 1, 2004
+.Os
+.Dt CLEAN_ENVIRONMENT 3
+.Sh NAME
+.Nm clean_environment
+.Nd sanitize environment variables
+.Sh LIBRARY
+.Lb libutil
+.Sh SYNOPSIS
+.In libutil.h
+.Ft void
+.Fn clean_environment "const char * const *whitelist" "const char * const *extra_whitelist"
+.Sh DESCRIPTION
+The
+.Fn clean_environment
+function removes unsafe environment variables from the current
+process environment.
+It scans the current environment and discards any environment variable
+that does not occur in one of the two NULL-terminated lists.
+.Pp
+If the first argument is
+.Dv NULL ,
+a built-in default whitelist will be used.
+Most callers will use
+.Dv NULL
+for both arguments to obtain the default environment screening.
+Callers who need to make minor adjustments to the built-in
+whitelist can set the first argument to
+.Dv NULL
+and use the second argument to, in effect,
+add elements to the built-in whitelist.
+.Sh EXAMPLES
+The first example illustrates the typical usage.
+In this case, the default built-in environment screen
+will be used, which removes all environment variables
+that are not on the built-in whitelist.
+.Bd -literal -offset indent
+ clean_environment(NULL, NULL);
+.Ed
+.Pp
+The following example applies the default environment screens
+except that the environment variables
+.Cm MYCUSTOM
+and
+.Cm MYCUSTOM2
+will also be kept and the
+.Cm TERM
+and
+.Cm TERMCAP
+environment variables will be removed.
+.Bd -literal -offset indent
+ const char *keep[] = { "MYCUSTOM", "MYCUSTOM2", NULL };
+ const char *remove[] = { "TERM", "TERMCAP", NULL };
+
+ clean_environment(NULL, keep);
+ for (p = remove; *p != NULL; p++)
+ unsetenv(*p);
+.Ed
+.Sh SEE ALSO
+.Xr unsetenv 3
diff --git a/lib/libutil/clean_environment.c b/lib/libutil/clean_environment.c
new file mode 100644
index 0000000..068e412
--- /dev/null
+++ b/lib/libutil/clean_environment.c
@@ -0,0 +1,121 @@
+/*-
+ * Copyright (c) 2004 Tim Kientzle
+ * 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
+ * in this position and unchanged.
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <string.h>
+#include "libutil.h"
+
+static int env_var_in_list(const char * const *list, char *var, size_t len);
+
+
+/*
+ * Default whitelist of "known safe" environment variables.
+ */
+static const char *default_whitelist[] = {
+ /* List from SUS "Environment Variables" Appendix */
+ "ARFLAGS", "CC", "CDPATH", "CFLAGS", "CHARSET", "COLUMNS",
+ "DATEMSK", "DEAD", "EDITOR", "ENV", "EXINIT", "FC", "FCEDIT",
+ "FFLAGS", "GET", "GFLAGS", "HISTFILE", "HISTORY", "HISTSIZE",
+ "HOME", "IFS", "LANG", "LC_ALL", "LC_COLLATE", "LC_CTYPE",
+ "LC_MESSAGES", "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LDFLAGS",
+ "LEX", "LFLAGS", "LINENO", "LINES", "LISTER", "LOGNAME", "LPDEST",
+ "MAIL", "MAILCHECK", "MAILER", "MAILPATH", "MAILRC", "MAKEFLAGS",
+ "MAKESHELL", "MANPATH", "MBOX", "MORE", "MSGVERB", "NLSPATH",
+ "NPROC", "OLDPWD", "OPTARG", "OPTERR", "OPTIND", "PAGER", "PATH",
+ "PPID", "PRINTER", "PROCLANG", "PROJECTDIR", "PS1", "PS2", "PS3",
+ "PS4", "PWD", "RANDOM", "SECONDS", "SHELL", "TERM", "TERMCAP",
+ "TERMINFO", "TMPDIR", "TZ", "USER", "VISUAL", "YACC", "YFLAGS",
+
+ /* Additional Environment Variables */
+ "KRB5CCNAME", "LOGIN", "MAILDIR", "SSH_AGENT_PID", "SSH_AUTH_SOCK",
+
+ /* Terminating NULL */
+ NULL
+};
+
+static int
+env_var_in_list(const char * const *list, char *var, size_t len)
+{
+ if (list == NULL)
+ return (0);
+
+ while (*list != NULL) {
+ if (strncmp(var, *list, len) == 0 &&
+ len == strlen(*list))
+ return (1);
+ list++;
+ }
+ return (0);
+}
+
+
+/*
+ * Scrub the environment by applying a "whitelist" of safe variables
+ * and a "blacklist" of known dangerous variables. Each environment
+ * variable is examined and is retained only if it appears in a whitelist
+ * and does not appear in the blacklist.
+ *
+ * If the first argument is NULL, a built-in whitelist will be used.
+ * The second and third arguments allow clients to adjust the built-in
+ * whitelist without having to replicate it.
+ *
+ */
+void
+clean_environment(const char * const *whitelist,
+ const char * const *extra_whitelist)
+{
+ extern char **environ;
+ char *p, **new, **old;
+ int len;
+ int safe;
+
+ old = environ;
+ new = environ;
+
+ if (whitelist == NULL)
+ whitelist = default_whitelist;
+
+ while (*old != NULL) {
+ safe = 0;
+ p = strchr(*old, '=');
+ if (p != NULL)
+ len = p - *old;
+ else
+ len = strlen(*old);
+
+ if (env_var_in_list(whitelist, *old, len) ||
+ env_var_in_list(extra_whitelist, *old, len))
+ *new++ = *old;
+
+ old++;
+ }
+ while (*new != NULL)
+ *new++ = NULL;
+
+}
OpenPOWER on IntegriCloud