diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
commit | 008d0be72b2f160382c6e880765e96b64a050c65 (patch) | |
tree | 36f48a98a3815a408e2ce1693dd182af90f80305 /release/src/router/busybox/applets | |
parent | 611becfb8726c60cb060368541ad98191d4532f5 (diff) | |
download | tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.gz tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.bz2 |
imported original firmware WRT54GL_v4.30.11_11_US
Diffstat (limited to 'release/src/router/busybox/applets')
-rw-r--r-- | release/src/router/busybox/applets/Makefile | 30 | ||||
-rwxr-xr-x | release/src/router/busybox/applets/Makefile.in | 36 | ||||
-rw-r--r-- | release/src/router/busybox/applets/applets.c | 454 | ||||
-rw-r--r-- | release/src/router/busybox/applets/busybox.c | 184 | ||||
-rwxr-xr-x | release/src/router/busybox/applets/busybox.mkll | 24 | ||||
-rwxr-xr-x | release/src/router/busybox/applets/install.sh | 52 | ||||
-rw-r--r-- | release/src/router/busybox/applets/usage.c | 10 |
7 files changed, 790 insertions, 0 deletions
diff --git a/release/src/router/busybox/applets/Makefile b/release/src/router/busybox/applets/Makefile new file mode 100644 index 00000000..f4ebb149 --- /dev/null +++ b/release/src/router/busybox/applets/Makefile @@ -0,0 +1,30 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +TOPDIR:= ../ +APPLETS_DIR:=./ +include $(TOPDIR).config +include $(TOPDIR)Rules.mak +include Makefile.in +all: $(libraries-y) +-include $(TOPDIR).depend + +clean: + rm -f *.o *.a $(AR_TARGET) + diff --git a/release/src/router/busybox/applets/Makefile.in b/release/src/router/busybox/applets/Makefile.in new file mode 100755 index 00000000..cb6c647d --- /dev/null +++ b/release/src/router/busybox/applets/Makefile.in @@ -0,0 +1,36 @@ +# Makefile for busybox +# +# Copyright (C) 1999-2003 by Erik Andersen <andersen@codepoet.org> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +APPLETS_AR:=applets.a +ifndef $(APPLETS_DIR) +APPLETS_DIR:=$(TOPDIR)applets/ +endif + +APPLET_SRC:=applets.c busybox.c usage.c +APPLET_OBJ:= $(patsubst %.c,$(APPLETS_DIR)%.o, $(APPLET_SRC)) + + + +libraries-y+=$(APPLETS_DIR)$(APPLETS_AR) + +$(APPLET_OBJ): $(TOPDIR).config + +$(APPLETS_DIR)$(APPLETS_AR): $(APPLET_OBJ) + $(AR) -ro $@ $(APPLET_OBJ) + diff --git a/release/src/router/busybox/applets/applets.c b/release/src/router/busybox/applets/applets.c new file mode 100644 index 00000000..4af569de --- /dev/null +++ b/release/src/router/busybox/applets/applets.c @@ -0,0 +1,454 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) tons of folks. Tracking down who wrote what + * isn't something I'm going to worry about... If you wrote something + * here, please feel free to acknowledge your work. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Based in part on code from sash, Copyright (c) 1999 by David I. Bell + * Permission has been granted to redistribute this code under the GPL. + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "busybox.h" + +#undef APPLET +#undef APPLET_NOUSAGE +#undef PROTOTYPES +#include "applets.h" + +struct BB_applet *applet_using; + +/* The -1 arises because of the {0,NULL,0,-1} entry above. */ +const size_t NUM_APPLETS = (sizeof (applets) / sizeof (struct BB_applet) - 1); + + +#ifdef CONFIG_FEATURE_SUID + +static void check_suid (struct BB_applet *app); + +#ifdef CONFIG_FEATURE_SUID_CONFIG + +#include <sys/stat.h> +#include <ctype.h> +#include "pwd_.h" +#include "grp_.h" + +static int parse_config_file (void); + +static int config_ok; + +#define CONFIG_FILE "/etc/busybox.conf" + +/* applets [] is const, so we have to define this "override" structure */ +struct BB_suid_config +{ + struct BB_applet *m_applet; + + uid_t m_uid; + gid_t m_gid; + mode_t m_mode; + + struct BB_suid_config *m_next; +}; + +static struct BB_suid_config *suid_config; + +#endif /* CONFIG_FEATURE_SUID_CONFIG */ + +#endif /* CONFIG_FEATURE_SUID */ + + + +extern void +bb_show_usage (void) +{ + const char *format_string; + const char *usage_string = usage_messages; + int i; + + for (i = applet_using - applets; i > 0;) { + if (!*usage_string++) { + --i; + } + } + + format_string = "%s\n\nUsage: %s %s\n\n"; + if (*usage_string == '\b') + format_string = "%s\n\nNo help available.\n\n"; + fprintf (stderr, format_string, bb_msg_full_version, applet_using->name, + usage_string); + + exit (EXIT_FAILURE); +} + +static int +applet_name_compare (const void *x, const void *y) +{ + const char *name = x; + const struct BB_applet *applet = y; + + return strcmp (name, applet->name); +} + +extern const size_t NUM_APPLETS; + +struct BB_applet * +find_applet_by_name (const char *name) +{ + return bsearch (name, applets, NUM_APPLETS, sizeof (struct BB_applet), + applet_name_compare); +} + +void +run_applet_by_name (const char *name, int argc, char **argv) +{ + static int recurse_level = 0; + extern int been_there_done_that; /* From busybox.c */ + +#ifdef CONFIG_FEATURE_SUID_CONFIG + if (recurse_level == 0) + config_ok = parse_config_file (); +#endif + + recurse_level++; + /* Do a binary search to find the applet entry given the name. */ + if ((applet_using = find_applet_by_name (name)) != NULL) { + bb_applet_name = applet_using->name; + if (argv[1] && strcmp (argv[1], "--help") == 0) { + if (strcmp (applet_using->name, "busybox") == 0) { + if (argv[2]) + applet_using = find_applet_by_name (argv[2]); + else + applet_using = NULL; + } + if (applet_using) + bb_show_usage (); + been_there_done_that = 1; + busybox_main (0, NULL); + } +#ifdef CONFIG_FEATURE_SUID + check_suid (applet_using); +#endif + + exit ((*(applet_using->main)) (argc, argv)); + } + /* Just in case they have renamed busybox - Check argv[1] */ + if (recurse_level == 1) { + run_applet_by_name ("busybox", argc, argv); + } + recurse_level--; +} + + +#ifdef CONFIG_FEATURE_SUID + +#ifdef CONFIG_FEATURE_SUID_CONFIG + +/* check if u is member of group g */ +static int +ingroup (uid_t u, gid_t g) +{ + struct group *grp = getgrgid (g); + + if (grp) { + char **mem; + + for (mem = grp->gr_mem; *mem; mem++) { + struct passwd *pwd = getpwnam (*mem); + + if (pwd && (pwd->pw_uid == u)) + return 1; + } + } + return 0; +} + +#endif + + +void +check_suid (struct BB_applet *applet) +{ + uid_t ruid = getuid (); /* real [ug]id */ + uid_t rgid = getgid (); + +#ifdef CONFIG_FEATURE_SUID_CONFIG + if (config_ok) { + struct BB_suid_config *sct; + + for (sct = suid_config; sct; sct = sct->m_next) { + if (sct->m_applet == applet) + break; + } + if (sct) { + mode_t m = sct->m_mode; + + if (sct->m_uid == ruid) /* same uid */ + m >>= 6; + else if ((sct->m_gid == rgid) || ingroup (ruid, sct->m_gid)) /* same group / in group */ + m >>= 3; + + if (!(m & S_IXOTH)) /* is x bit not set ? */ + bb_error_msg_and_die ("You have no permission to run this applet!"); + + if ((sct->m_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { /* *both* have to be set for sgid */ + if (setegid (sct->m_gid)) + bb_error_msg_and_die + ("BusyBox binary has insufficient rights to set proper GID for applet!"); + } else + setgid (rgid); /* no sgid -> drop */ + + if (sct->m_mode & S_ISUID) { + if (seteuid (sct->m_uid)) + bb_error_msg_and_die + ("BusyBox binary has insufficient rights to set proper UID for applet!"); + } else + setuid (ruid); /* no suid -> drop */ + } else { + /* default: drop all priviledges */ + setgid (rgid); + setuid (ruid); + } + return; + } else { +#ifndef CONFIG_FEATURE_SUID_CONFIG_QUIET + static int onetime = 0; + + if (!onetime) { + onetime = 1; + fprintf (stderr, "Using fallback suid method\n"); + } +#endif + } +#endif + + if (applet->need_suid == _BB_SUID_ALWAYS) { + if (geteuid () != 0) + bb_error_msg_and_die ("This applet requires root priviledges!"); + } else if (applet->need_suid == _BB_SUID_NEVER) { + setgid (rgid); /* drop all priviledges */ + setuid (ruid); + } +} + +#ifdef CONFIG_FEATURE_SUID_CONFIG + + +#define parse_error(x) { err=x; goto pe_label; } + + +int +parse_config_file (void) +{ + struct stat st; + char *err = 0; + FILE *f = 0; + int lc = 0; + + suid_config = 0; + + /* is there a config file ? */ + if (stat (CONFIG_FILE, &st) == 0) { + /* is it owned by root with no write perm. for group and others ? */ + if (S_ISREG (st.st_mode) && (st.st_uid == 0) + && (!(st.st_mode & (S_IWGRP | S_IWOTH)))) { + /* that's ok .. then try to open it */ + f = fopen (CONFIG_FILE, "r"); + + if (f) { + char buffer[256]; + int section = 0; + + while (fgets (buffer, sizeof (buffer) - 1, f)) { + char c = buffer[0]; + char *p; + + lc++; + + p = strchr (buffer, '#'); + if (p) + *p = 0; + p = buffer + bb_strlen (buffer); + while ((p > buffer) && isspace (*--p)) + *p = 0; + + if (p == buffer) + continue; + + if (c == '[') { + p = strchr (buffer, ']'); + + if (!p || (p == (buffer + 1))) /* no matching ] or empty [] */ + parse_error ("malformed section header"); + + *p = 0; + + if (strcasecmp (buffer + 1, "SUID") == 0) + section = 1; + else + section = -1; /* unknown section - just skip */ + } else if (section) { + switch (section) { + case 1:{ /* SUID */ + int l; + struct BB_applet *applet; + + p = strchr (buffer, '='); /* <key>[::space::]*=[::space::]*<value> */ + + if (!p || (p == (buffer + 1))) /* no = or key is empty */ + parse_error ("malformed keyword"); + + l = p - buffer; + while (isspace (buffer[--l])) { + /* skip whitespace */ + } + + buffer[l + 1] = 0; + + if ((applet = find_applet_by_name (buffer))) { + struct BB_suid_config *sct = + xmalloc (sizeof (struct BB_suid_config)); + + sct->m_applet = applet; + sct->m_next = suid_config; + suid_config = sct; + + while (isspace (*++p)) { + /* skip whitespace */ + } + + sct->m_mode = 0; + + switch (*p++) { + case 'S': + sct->m_mode |= S_ISUID; + break; + case 's': + sct->m_mode |= S_ISUID; + /* no break */ + case 'x': + sct->m_mode |= S_IXUSR; + break; + case '-': + break; + default: + parse_error ("invalid user mode"); + } + + switch (*p++) { + case 's': + sct->m_mode |= S_ISGID; + /* no break */ + case 'x': + sct->m_mode |= S_IXGRP; + break; + case 'S': + break; + case '-': + break; + default: + parse_error ("invalid group mode"); + } + + switch (*p) { + case 't': + case 'x': + sct->m_mode |= S_IXOTH; + break; + case 'T': + case '-': + break; + default: + parse_error ("invalid other mode"); + } + + while (isspace (*++p)) { + /* skip whitespace */ + } + + if (isdigit (*p)) { + sct->m_uid = strtol (p, &p, 10); + if (*p++ != '.') + parse_error ("parsing <uid>.<gid>"); + } else { + struct passwd *pwd; + char *p2 = strchr (p, '.'); + + if (!p2) + parse_error ("parsing <uid>.<gid>"); + + *p2 = 0; + pwd = getpwnam (p); + + if (!pwd) + parse_error ("invalid user name"); + + sct->m_uid = pwd->pw_uid; + p = p2 + 1; + } + if (isdigit (*p)) + sct->m_gid = strtol (p, &p, 10); + else { + struct group *grp = getgrnam (p); + + if (!grp) + parse_error ("invalid group name"); + + sct->m_gid = grp->gr_gid; + } + } + break; + } + default: /* unknown - skip */ + break; + } + } else + parse_error ("keyword not within section"); + } + fclose (f); + return 1; + } + } + } + return 0; /* no config file or not readable (not an error) */ + +pe_label: + fprintf (stderr, "Parse error in %s, line %d: %s\n", CONFIG_FILE, lc, err); + + if (f) + fclose (f); + return 0; +} + +#endif + +#endif + +/* END CODE */ +/* +Local Variables: +c-file-style: "linux" +c-basic-offset: 4 +tab-width: 4 +End: +*/ diff --git a/release/src/router/busybox/applets/busybox.c b/release/src/router/busybox/applets/busybox.c new file mode 100644 index 00000000..457a85a6 --- /dev/null +++ b/release/src/router/busybox/applets/busybox.c @@ -0,0 +1,184 @@ +/* vi: set sw=4 ts=4: */ +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> +#include "busybox.h" +#ifdef CONFIG_LOCALE_SUPPORT +#include <locale.h> +#endif + +int been_there_done_that = 0; /* Also used in applets.c */ +const char *bb_applet_name; + +#ifdef CONFIG_FEATURE_INSTALLER +/* + * directory table + * this should be consistent w/ the enum, busybox.h::Location, + * or else... + */ +static const char usr_bin [] ="/usr/bin"; +static const char usr_sbin[] ="/usr/sbin"; + +static const char* const install_dir[] = { + &usr_bin [8], /* "", equivalent to "/" for concat_path_file() */ + &usr_bin [4], /* "/bin" */ + &usr_sbin[4], /* "/sbin" */ + usr_bin, + usr_sbin +}; + +/* abstract link() */ +typedef int (*__link_f)(const char *, const char *); + +/* + * Where in the filesystem is this busybox? + * [return] + * malloc'd string w/ full pathname of busybox's location + * NULL on failure + */ +static inline char *busybox_fullpath(void) +{ + return xreadlink("/proc/self/exe"); +} + +/* create (sym)links for each applet */ +static void install_links(const char *busybox, int use_symbolic_links) +{ + __link_f Link = link; + + char *fpc; + int i; + int rc; + + if (use_symbolic_links) + Link = symlink; + + for (i = 0; applets[i].name != NULL; i++) { + fpc = concat_path_file( + install_dir[applets[i].location], applets[i].name); + rc = Link(busybox, fpc); + if (rc!=0 && errno!=EEXIST) { + bb_perror_msg("%s", fpc); + } + free(fpc); + } +} + +#endif /* CONFIG_FEATURE_INSTALLER */ + +int main(int argc, char **argv) +{ + const char *s; + + bb_applet_name = argv[0]; + + if (bb_applet_name[0] == '-') + bb_applet_name++; + + for (s = bb_applet_name; *s != '\0';) { + if (*s++ == '/') + bb_applet_name = s; + } + +#ifdef CONFIG_LOCALE_SUPPORT +#ifdef CONFIG_INIT + if(getpid()!=1) /* Do not set locale for `init' */ +#endif + { + setlocale(LC_ALL, ""); + } +#endif + + run_applet_by_name(bb_applet_name, argc, argv); + bb_error_msg_and_die("applet not found"); +} + + +int busybox_main(int argc, char **argv) +{ + int col = 0, len, i; + +#ifdef CONFIG_FEATURE_INSTALLER + /* + * This style of argument parsing doesn't scale well + * in the event that busybox starts wanting more --options. + * If someone has a cleaner approach, by all means implement it. + */ + if (argc > 1 && (strcmp(argv[1], "--install") == 0)) { + int use_symbolic_links = 0; + int rc = 0; + char *busybox; + + /* to use symlinks, or not to use symlinks... */ + if (argc > 2) { + if ((strcmp(argv[2], "-s") == 0)) { + use_symbolic_links = 1; + } + } + + /* link */ + busybox = busybox_fullpath(); + if (busybox) { + install_links(busybox, use_symbolic_links); + free(busybox); + } else { + rc = 1; + } + return rc; + } +#endif /* CONFIG_FEATURE_INSTALLER */ + + argc--; + + /* If we've already been here once, exit now */ + if (been_there_done_that == 1 || argc < 1) { + const struct BB_applet *a = applets; + + fprintf(stderr, "%s\n\n" + "Usage: busybox [function] [arguments]...\n" + " or: [function] [arguments]...\n\n" + "\tBusyBox is a multi-call binary that combines many common Unix\n" + "\tutilities into a single executable. Most people will create a\n" + "\tlink to busybox for each function they wish to use, and BusyBox\n" + "\twill act like whatever it was invoked as.\n" + "\nCurrently defined functions:\n", bb_msg_full_version); + + while (a->name != 0) { + col += + fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "), + (a++)->name); + if (col > 60 && a->name != 0) { + fprintf(stderr, ",\n"); + col = 0; + } + } + fprintf(stderr, "\n\n"); + exit(0); + } + + /* Flag that we've been here already */ + been_there_done_that = 1; + + /* Move the command line down a notch */ + len = argv[argc] + strlen(argv[argc]) - argv[1]; + memmove(argv[0], argv[1], len); + memset(argv[0] + len, 0, argv[1] - argv[0]); + + /* Fix up the argv pointers */ + len = argv[1] - argv[0]; + memmove(argv, argv + 1, sizeof(char *) * (argc + 1)); + for (i = 0; i < argc; i++) + argv[i] -= len; + + return (main(argc, argv)); +} + +/* +Local Variables: +c-file-style: "linux" +c-basic-offset: 4 +tab-width: 4 +End: +*/ diff --git a/release/src/router/busybox/applets/busybox.mkll b/release/src/router/busybox/applets/busybox.mkll new file mode 100755 index 00000000..5b6677d0 --- /dev/null +++ b/release/src/router/busybox/applets/busybox.mkll @@ -0,0 +1,24 @@ +#!/bin/sh +# Make busybox links list file. + +# input $1: full path to Config.h +# input $2: full path to applets.h +# output (stdout): list of pathnames that should be linked to busybox + +# Maintainer: Larry Doolittle <ldoolitt@recycle.lbl.gov> + +export LC_ALL=POSIX +export LC_CTYPE=POSIX + +CONFIG_H=${1:-include/config.h} +APPLETS_H=${2:-include/applets.h} +gcc -E -DMAKE_LINKS -include $CONFIG_H $APPLETS_H | + awk '/^[ \t]*LINK/{ + dir=substr($2,8) + gsub("_","/",dir) + if(dir=="/ROOT") dir="" + file=$3 + gsub("\"","",file) + if (file=="busybox") next + print tolower(dir) "/" file + }' diff --git a/release/src/router/busybox/applets/install.sh b/release/src/router/busybox/applets/install.sh new file mode 100755 index 00000000..d163a2ef --- /dev/null +++ b/release/src/router/busybox/applets/install.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +export LC_ALL=POSIX +export LC_CTYPE=POSIX + +prefix=$1 +if [ "$prefix" = "" ]; then + echo "No installation directory, aborting." + exit 1; +fi +if [ "$2" = "--hardlinks" ]; then + linkopts="-f" +else + linkopts="-fs" +fi +h=`sort busybox.links | uniq` + + +rm -f $prefix/bin/busybox || exit 1 +mkdir -p $prefix/bin || exit 1 +install -m 755 busybox $prefix/bin/busybox || exit 1 + +for i in $h ; do + appdir=`dirname $i` + mkdir -p $prefix/$appdir || exit 1 + if [ "$2" = "--hardlinks" ]; then + bb_path="$prefix/bin/busybox" + else + case "$appdir" in + /) + bb_path="bin/busybox" + ;; + /bin) + bb_path="busybox" + ;; + /sbin) + bb_path="../bin/busybox" + ;; + /usr/bin|/usr/sbin) + bb_path="../../bin/busybox" + ;; + *) + echo "Unknown installation directory: $appdir" + exit 1 + ;; + esac + fi + echo " $prefix$i -> $bb_path" + ln $linkopts $bb_path $prefix$i || exit 1 +done + +exit 0 diff --git a/release/src/router/busybox/applets/usage.c b/release/src/router/busybox/applets/usage.c new file mode 100644 index 00000000..dfea1f96 --- /dev/null +++ b/release/src/router/busybox/applets/usage.c @@ -0,0 +1,10 @@ +#include "busybox.h" + +const char usage_messages[] = + +#define MAKE_USAGE +#include "usage.h" + +#include "applets.h" + +; |