/* 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.
 *
 * 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.
 *
 * Licensed under GPLv2 or later, see file License in this tarball for details.
 */

#include "busybox.h"
#include <unistd.h>
#include <string.h>
#include <assert.h>

#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE
static const char usage_messages[] =
#define MAKE_USAGE
#include "usage.h"
#include "applets.h"
;
#undef MAKE_USAGE
#else
#define usage_messages 0
#endif /* ENABLE_SHOW_USAGE */

#undef APPLET
#undef APPLET_NOUSAGE
#undef PROTOTYPES
#include "applets.h"

static 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_CONFIG

#include <ctype.h>
#include "pwd_.h"
#include "grp_.h"

#define CONFIG_FILE "/etc/busybox.conf"

/* applets [] is const, so we have to define this "override" structure */
static 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;
} *suid_config;

static int suid_cfg_readable;

/* 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;
}

/* This should probably be a libbb routine.  In that case,
 * I'd probably rename it to something like bb_trimmed_slice.
 */
static char *get_trimmed_slice(char *s, char *e)
{
	/* First, consider the value at e to be nul and back up until we
	 * reach a non-space char.  Set the char after that (possibly at
	 * the original e) to nul. */
	while (e-- > s) {
		if (!isspace(*e)) {
			break;
		}
	}
	e[1] = 0;

	/* Next, advance past all leading space and return a ptr to the
	 * first non-space char; possibly the terminating nul. */
	return skip_whitespace(s);
}


#define parse_error(x)  { err=x; goto pe_label; }

/* Don't depend on the tools to combine strings. */
static const char config_file[] = CONFIG_FILE;

/* There are 4 chars + 1 nul for each of user/group/other. */
static const char mode_chars[] = "Ssx-\0Ssx-\0Ttx-";

/* We don't supply a value for the nul, so an index adjustment is
 * necessary below.  Also, we use unsigned short here to save some
 * space even though these are really mode_t values. */
static const unsigned short mode_mask[] = {
	/*  SST         sst                 xxx   --- */
	S_ISUID,    S_ISUID|S_IXUSR,    S_IXUSR,    0,	/* user */
	S_ISGID,    S_ISGID|S_IXGRP,    S_IXGRP,    0,	/* group */
	0,          S_IXOTH,            S_IXOTH,    0	/* other */
};

static void parse_config_file(void)
{
	struct BB_suid_config *sct_head;
	struct BB_suid_config *sct;
	struct BB_applet *applet;
	FILE *f;
	char *err;
	char *s;
	char *e;
	int i, lc, section;
	char buffer[256];
	struct stat st;

	assert(!suid_config);		/* Should be set to NULL by bss init. */

	if ((stat(config_file, &st) != 0)			/* No config file? */
		|| !S_ISREG(st.st_mode)					/* Not a regular file? */
		|| (st.st_uid != 0)						/* Not owned by root? */
		|| (st.st_mode & (S_IWGRP | S_IWOTH))	/* Writable by non-root? */
		|| !(f = fopen(config_file, "r"))		/* Can not open? */
		) {
		return;
	}

	suid_cfg_readable = 1;
	sct_head = NULL;
	section = lc = 0;

	do {
		s = buffer;

		if (!fgets(s, sizeof(buffer), f)) { /* Are we done? */
			if (ferror(f)) {   /* Make sure it wasn't a read error. */
				parse_error("reading");
			}
			fclose(f);
			suid_config = sct_head;	/* Success, so set the pointer. */
			return;
		}

		lc++;					/* Got a (partial) line. */

		/* If a line is too long for our buffer, we consider it an error.
		 * The following test does mistreat one corner case though.
		 * If the final line of the file does not end with a newline and
		 * yet exactly fills the buffer, it will be treated as too long
		 * even though there isn't really a problem.  But it isn't really
		 * worth adding code to deal with such an unlikely situation, and
		 * we do err on the side of caution.  Besides, the line would be
		 * too long if it did end with a newline. */
		if (!strchr(s, '\n') && !feof(f)) {
			parse_error("line too long");
		}

		/* Trim leading and trailing whitespace, ignoring comments, and
		 * check if the resulting string is empty. */
		if (!*(s = get_trimmed_slice(s, strchrnul(s, '#')))) {
			continue;
		}

		/* Check for a section header. */

		if (*s == '[') {
			/* Unlike the old code, we ignore leading and trailing
			 * whitespace for the section name.  We also require that
			 * there are no stray characters after the closing bracket. */
			if (!(e = strchr(s, ']'))	/* Missing right bracket? */
				|| e[1]					/* Trailing characters? */
				|| !*(s = get_trimmed_slice(s+1, e)) /* Missing name? */
				) {
				parse_error("section header");
			}
			/* Right now we only have one section so just check it.
			 * If more sections are added in the future, please don't
			 * resort to cascading ifs with multiple strcasecmp calls.
			 * That kind of bloated code is all too common.  A loop
			 * and a string table would be a better choice unless the
			 * number of sections is very small. */
			if (strcasecmp(s, "SUID") == 0) {
				section = 1;
				continue;
			}
			section = -1;	/* Unknown section so set to skip. */
			continue;
		}

		/* Process sections. */

		if (section == 1) {		/* SUID */
			/* Since we trimmed leading and trailing space above, we're
			 * now looking for strings of the form
			 *    <key>[::space::]*=[::space::]*<value>
			 * where both key and value could contain inner whitespace. */

			/* First get the key (an applet name in our case). */
			if (!!(e = strchr(s, '='))) {
				s = get_trimmed_slice(s, e);
			}
			if (!e || !*s) {	/* Missing '=' or empty key. */
				parse_error("keyword");
			}

			/* Ok, we have an applet name.  Process the rhs if this
			 * applet is currently built in and ignore it otherwise.
			 * Note: This can hide config file bugs which only pop
			 * up when the busybox configuration is changed. */
			if ((applet = find_applet_by_name(s))) {
				/* Note: We currently don't check for duplicates!
				 * The last config line for each applet will be the
				 * one used since we insert at the head of the list.
				 * I suppose this could be considered a feature. */
				sct = xmalloc(sizeof(struct BB_suid_config));
				sct->m_applet = applet;
				sct->m_mode = 0;
				sct->m_next = sct_head;
				sct_head = sct;

				/* Get the specified mode. */

				e = skip_whitespace(e+1);

				for (i=0 ; i < 3 ; i++) {
					const char *q;
					if (!*(q = strchrnul(mode_chars + 5*i, *e++))) {
						parse_error("mode");
					}
					/* Adjust by -i to account for nul. */
					sct->m_mode |= mode_mask[(q - mode_chars) - i];
				}

				/* Now get the the user/group info. */

				s = skip_whitespace(e);

				/* Note: We require whitespace between the mode and the
				 * user/group info. */
				if ((s == e) || !(e = strchr(s, '.'))) {
					parse_error("<uid>.<gid>");
				}
				*e++ = 0;

				/* We can't use get_ug_id here since it would exit()
				 * if a uid or gid was not found.  Oh well... */
				{
					char *e2;

					sct->m_uid = strtoul(s, &e2, 10);
					if (*e2 || (s == e2)) {
						struct passwd *pwd;
						if (!(pwd = getpwnam(s))) {
							parse_error("user");
						}
						sct->m_uid = pwd->pw_uid;
					}

					sct->m_gid = strtoul(e, &e2, 10);
					if (*e2 || (e == e2)) {
						struct group *grp;
						if (!(grp = getgrnam(e))) {
							parse_error("group");
						}
						sct->m_gid = grp->gr_gid;
					}
				}
			}
			continue;
		}

		/* Unknown sections are ignored. */

		/* Encountering configuration lines prior to seeing a
		 * section header is treated as an error.  This is how
		 * the old code worked, but it may not be desirable.
		 * We may want to simply ignore such lines in case they
		 * are used in some future version of busybox. */
		if (!section) {
			parse_error("keyword outside section");
		}

	} while (1);

 pe_label:
	fprintf(stderr, "Parse error in %s, line %d: %s\n",
			config_file, lc, err);

	fclose(f);
	/* Release any allocated memory before returning. */
	while (sct_head) {
		sct = sct_head->m_next;
		free(sct_head);
		sct_head = sct;
	}
	return;
}

#else
#define parse_config_file()
#endif /* CONFIG_FEATURE_SUID_CONFIG */

#ifdef CONFIG_FEATURE_SUID
static void check_suid (struct BB_applet *applet)
{
  uid_t ruid = getuid ();               /* real [ug]id */
  uid_t rgid = getgid ();

#ifdef CONFIG_FEATURE_SUID_CONFIG
  if (suid_cfg_readable) {
	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 */
		xsetgid(sct->m_gid);
	  } else xsetgid(rgid);                /* no sgid -> drop */

	  if (sct->m_mode & S_ISUID) xsetuid(sct->m_uid);
	  else xsetuid(ruid);                  /* no suid -> drop */
	} else {
		/* default: drop all privileges */
	  xsetgid(rgid);
	  xsetuid(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()) bb_error_msg_and_die("Applet requires root privileges!");
  } else if (applet->need_suid == _BB_SUID_NEVER) {
	xsetgid(rgid);                          /* drop all privileges */
	xsetuid(ruid);
  }
}
#else
#define check_suid(x)
#endif /* CONFIG_FEATURE_SUID */



#if ENABLE_FEATURE_COMPRESS_USAGE

#include "usage_compressed.h"
#include "unarchive.h"

static const char *unpack_usage_messages(void)
{
	int input[2], output[2], pid;
	char *buf;

	if(pipe(input) < 0 || pipe(output) < 0)
		exit(1);

	pid = fork();
	switch (pid) {
	case -1: /* error */
		exit(1);
	case 0: /* child */
		close(input[1]);
		close(output[0]);
		uncompressStream(input[0], output[1]);
		exit(0);
	}
	/* parent */

	close(input[0]);
	close(output[1]);
	pid = fork();
	switch (pid) {
	case -1: /* error */
		exit(1);
	case 0: /* child */
		full_write(input[1], packed_usage, sizeof(packed_usage));
		exit(0);
	}
	/* parent */
	close(input[1]);

	buf = xmalloc(SIZEOF_usage_messages);
	full_read(output[0], buf, SIZEOF_usage_messages);
	return buf;
}

#else
#define unpack_usage_messages() usage_messages
#endif /* ENABLE_FEATURE_COMPRESS_USAGE */

void bb_show_usage (void)
{
	if (ENABLE_SHOW_USAGE) {
		const char *format_string;
		const char *usage_string = unpack_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 (bb_default_error_retval);
}

static int applet_name_compare(const void *name, const void *vapplet)
{
  const struct BB_applet *applet = vapplet;

  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)
{
	if (ENABLE_FEATURE_SUID_CONFIG) parse_config_file();

	if (!strncmp(name, "busybox", 7)) busybox_main(argc, argv);
	/* Do a binary search to find the applet entry given the name. */
	applet_using = find_applet_by_name(name);
	if (applet_using) {
		bb_applet_name = applet_using->name;
		if(argc==2 && !strcmp(argv[1], "--help")) bb_show_usage();
		if(ENABLE_FEATURE_SUID) check_suid(applet_using);
		exit((*(applet_using->main))(argc, argv));
	}
}
