Esempio n. 1
0
static pid_t fork_with_pipes(int pipefd_in[2], int pipefd_out[2])
{
	pid_t child_pid;

	if (pipe(pipefd_in) < 0) {
		messagef(HAKA_LOG_ERROR, MODULE_NAME, "%s", errno_error(errno));
		return -1;
	}

	if (pipefd_out) {
		if (pipe(pipefd_out) < 0) {
			messagef(HAKA_LOG_ERROR, MODULE_NAME, "%s", errno_error(errno));
			close(pipefd_in[0]);
			close(pipefd_in[1]);
			return -1;
		}
	}

	child_pid = fork();
	if (child_pid < 0) {
		messagef(HAKA_LOG_ERROR, MODULE_NAME, "%s", errno_error(errno));
		close(pipefd_in[0]);
		close(pipefd_in[1]);

		if (pipefd_out) {
			close(pipefd_out[0]);
			close(pipefd_out[1]);
		}
		return -1;
	}

	return child_pid;
}
Esempio n. 2
0
void
id_trap(void)
{
	short dir, row, col, d, t;

	messagef(0, "direction? ");

	while (!is_direction(dir = rgetchar(), &d)) {
		beep();
	}
	check_message();

	if (dir == CANCEL) {
		return;
	}
	row = rogue.row;
	col = rogue.col;

	get_dir_rc(d, &row, &col, 0);

	if ((dungeon[row][col] & TRAP) && (!(dungeon[row][col] & HIDDEN))) {
		t = trap_at(row, col);
		messagef(0, "%s", trap_strings[t*2]);
	} else {
		messagef(0, "no trap there");
	}
}
Esempio n. 3
0
static int open_send_socket(bool mark)
{
	int fd;
	int one = 1;

	fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
	if (fd < 0) {
		messagef(HAKA_LOG_ERROR, MODULE_NAME, L"cannot open send socket: %s", errno_error(errno));
		return -1;
	}

	if (setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0) {
		messagef(HAKA_LOG_ERROR, MODULE_NAME, L"cannot setup send socket: %s", errno_error(errno));
		return -1;
	}

	if (mark) {
		one = 0xffff;
		if (setsockopt(fd, SOL_SOCKET, SO_MARK, &one, sizeof(one)) < 0) {
			messagef(HAKA_LOG_ERROR, MODULE_NAME, L"cannot setup send socket: %s", errno_error(errno));
			return -1;
		}
	}

	return fd;
}
Esempio n. 4
0
void
trap_player(short row, short col)
{
	short t;

	if ((t = trap_at(row, col)) == NO_TRAP) {
		return;
	}
	dungeon[row][col] &= (~HIDDEN);
	if (rand_percent(rogue.exp + ring_exp)) {
		messagef(1, "the trap failed");
		return;
	}
	switch(t) {
	case TRAP_DOOR:
		trap_door = 1;
		new_level_message = trap_strings[(t*2)+1];
		break;
	case BEAR_TRAP:
		messagef(1, "%s", trap_strings[(t*2)+1]);
		bear_trap = get_rand(4, 7);
		break;
	case TELE_TRAP:
		mvaddch(rogue.row, rogue.col, '^');
		tele();
		break;
	case DART_TRAP:
		messagef(1, "%s", trap_strings[(t*2)+1]);
		rogue.hp_current -= get_damage("1d6", 1);
		if (rogue.hp_current <= 0) {
			rogue.hp_current = 0;
		}
		if ((!sustain_strength) && rand_percent(40) &&
			(rogue.str_current >= 3)) {
			rogue.str_current--;
		}
		print_stats(STAT_HP | STAT_STRENGTH);
		if (rogue.hp_current <= 0) {
			killed_by((object *) 0, POISON_DART);
		}
		break;
	case SLEEPING_GAS_TRAP:
		messagef(1, "%s", trap_strings[(t*2)+1]);
		take_a_nap();
		break;
	case RUST_TRAP:
		messagef(1, "%s", trap_strings[(t*2)+1]);
		rust((object *) 0);
		break;
	}
}
void
create_monster(void)
{
	short row, col;
	short i;
	boolean found = 0;
	object *monster;

	row = rogue.row;
	col = rogue.col;

	for (i = 0; i < 9; i++) {
		rand_around(i, &row, &col);
		if (((row == rogue.row) && (col == rogue.col)) ||
				(row < MIN_ROW) || (row > (DROWS-2)) ||
				(col < 0) || (col > (DCOLS-1))) {
			continue;
		}
		if ((!(dungeon[row][col] & MONSTER)) &&
			  (dungeon[row][col] & (FLOOR|TUNNEL|STAIRS|DOOR))) {
			found = 1;
			break;
		}
	}
	if (found) {
		monster = gr_monster((object *)0, 0);
		put_m_at(row, col, monster);
		mvaddch(row, col, gmc(monster));
		if (monster->m_flags & (WANDERS | WAKENS)) {
			wake_up(monster);
		}
	} else {
		messagef(0, "you hear a faint cry of anguish in the distance");
	}
}
Esempio n. 6
0
static int packet_do_receive(struct packet_module_state *state, struct packet **pkt)
{
	const int rv = recv(state->fd, state->receive_buffer,
			sizeof(state->receive_buffer), 0);
	if (rv < 0) {
		messagef(HAKA_LOG_ERROR, MODULE_NAME, L"packet reception failed, %s", errno_error(errno));
		return 0;
	}

	if (nfq_handle_packet(state->handle, state->receive_buffer, rv) == 0) {
		if (state->current_packet) {
			state->current_packet->state = state;
			*pkt = (struct packet*)state->current_packet;

			if (pcap) {
				dump_pcap(&pcap->in, state->current_packet);
			}

			state->current_packet = NULL;
			return 0;
		}
		else {
			return state->error;
		}
	}
	else {
		message(HAKA_LOG_ERROR, MODULE_NAME, L"packet processing failed");
		return 0;
	}
}
Esempio n. 7
0
static void report_error(struct luadebug_remote_user *user, int err)
{
	if (!user->error) {
		messagef(HAKA_LOG_ERROR, MODULE, L"remote communication error: %s", errno_error(err));
		user->error = true;
	}
}
Esempio n. 8
0
/*
 * try not to put in room NR
 */
void
put_player(short nr)
{
    short rn = nr, misses;
    short row, col;

    for (misses = 0; ((misses < 2) && (rn == nr)); misses++) {
        gr_row_col(&row, &col, (FLOOR | TUNNEL | OBJECT | STAIRS));
        rn = get_room_number(row, col);
    }
    rogue.row = row;
    rogue.col = col;

    if (dungeon[rogue.row][rogue.col] & TUNNEL) {
        cur_room = PASSAGE;
    } else {
        cur_room = rn;
    }
    if (cur_room != PASSAGE) {
        light_up_room(cur_room);
    } else {
        light_passage(rogue.row, rogue.col);
    }
    rn = get_room_number(rogue.row, rogue.col);
    wake_room(rn, 1, rogue.row, rogue.col);
    if (new_level_message) {
        messagef(0, "%s", new_level_message);
        new_level_message = NULL;
    }
    mvaddch(rogue.row, rogue.col, rogue.fchar);
}
Esempio n. 9
0
int
drop_check(void)
{
    if (wizard) {
        return(1);
    }
    if (dungeon[rogue.row][rogue.col] & STAIRS) {
        if (levitate) {
            messagef(0, "you're floating in the air!");
            return(0);
        }
        return(1);
    }
    messagef(0, "I see no way down");
    return(0);
}
Esempio n. 10
0
void
add_exp(int e, boolean promotion)
{
    short new_exp;
    short i, hp;

    rogue.exp_points += e;

    if (rogue.exp_points >= level_points[rogue.exp-1]) {
        new_exp = get_exp_level(rogue.exp_points);
        if (rogue.exp_points > MAX_EXP) {
            rogue.exp_points = MAX_EXP + 1;
        }
        for (i = rogue.exp+1; i <= new_exp; i++) {
            messagef(0, "welcome to level %d", i);
            if (promotion) {
                hp = hp_raise();
                rogue.hp_current += hp;
                rogue.hp_max += hp;
            }
            rogue.exp = i;
            print_stats(STAT_HP | STAT_EXP);
        }
    } else {
        print_stats(STAT_EXP);
    }
}
Esempio n. 11
0
void module_release(struct module *module)
{
	if (atomic_dec(&module->ref) == 0) {
		/* Cleanup the module */
		messagef(HAKA_LOG_INFO, L"core", L"unload module '%ls'", module->name);
		module->cleanup();
		dlclose(module->handle);
	}
}
Esempio n. 12
0
static struct thread_state *init_thread_state(struct packet_module *packet_module,
		int thread_id, bool dissector_graph)
{
	struct thread_state *state;

	assert(packet_module);

	state = malloc(sizeof(struct thread_state));
	if (!state) {
		return NULL;
	}

	memset(state, 0, sizeof(struct thread_state));

	state->thread_id = thread_id;
	state->packet_module = packet_module;
	state->state = STATE_NOTSARTED;
	state->engine = NULL;

	messagef(HAKA_LOG_INFO, "core", "initializing thread %d", thread_id);

	state->lua = lua_state_init();
	if (!state->lua) {
		message(HAKA_LOG_FATAL, "core", "unable to create lua state");
		cleanup_thread_state(state);
		return NULL;
	}

	/* Set grammar debugging */
	lua_getglobal(state->lua->L, "haka");
	lua_getfield(state->lua->L, -1, "grammar");
	lua_pushboolean(state->lua->L, dissector_graph);
	lua_setfield(state->lua->L, -2, "debug");

	/* Set state machine debugging */
	lua_getglobal(state->lua->L, "haka");
	lua_getfield(state->lua->L, -1, "state_machine");
	lua_pushboolean(state->lua->L, dissector_graph);
	lua_setfield(state->lua->L, -2, "debug");

	/* Load Lua sources */
	lua_state_require(state->lua, "rule");
	lua_state_require(state->lua, "rule_group");
	lua_state_require(state->lua, "interactive");
	lua_state_require(state->lua, "protocol/raw");

	state->capture = packet_module->init_state(thread_id);
	if (!state->capture) {
		message(HAKA_LOG_FATAL, "core", "unable to create packet capture state");
		cleanup_thread_state(state);
		return NULL;
	}

	return state;
}
Esempio n. 13
0
static int
mkmount(register Cs_t* state, int mode, int uid, int gid, char* endserv, char* endhost, char* endtype)
{
	*(state->control - 1) = 0;
	if (eaccess(state->mount, R_OK|W_OK|X_OK))
	{
		if (errno != ENOENT)
			goto bad;
		if (!endserv && !(endserv = strrchr(state->mount, '/')))
			goto bad;
		*endserv = 0;
		if (eaccess(state->mount, X_OK))
		{
			if (!endhost && !(endhost = strrchr(state->mount, '/')))
				goto bad;
			*endhost = 0;
			if (eaccess(state->mount, X_OK))
			{
				if (!endtype && !(endtype = strrchr(state->mount, '/')))
					goto bad;
				*endtype = 0;
				if (eaccess(state->mount, X_OK) && (mkdir(state->mount, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(state->mount, S_IRWXU|S_IRWXG|S_IRWXO)))
					goto bad;
				*endtype = '/';
				if (mkdir(state->mount, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(state->mount, S_IRWXU|S_IRWXG|S_IRWXO))
					goto bad;
			}
			*endhost = '/';
			if (mkdir(state->mount, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(state->mount, S_IRWXU|S_IRWXG|S_IRWXO))
				goto bad;
		}
		*endserv = '/';
		if (mkdir(state->mount, mode))
			goto bad;
		if (mode != (S_IRWXU|S_IRWXG|S_IRWXO) && (uid >= 0 || gid >= 0 && (mode |= S_ISGID)) && (chown(state->mount, uid, gid) || chmod(state->mount, mode)))
		{
			rmdir(state->mount);
			goto bad;
		}
	}
	*(state->control - 1) = '/';
	return 0;
 bad:
	if (endtype && !*endtype)
		*endtype = '/';
	if (endhost && !*endhost)
		*endhost = '/';
	if (endserv && !*endserv)
		*endserv = '/';
	*(state->control - 1) = '/';
	messagef((state->id, NiL, -1, "mkmount: %s: cannot access physical mount directory", state->mount));
	return -1;
}
Esempio n. 14
0
void
search(short n, boolean is_auto)
{
	short s, i, j, row, col, t;
	short shown = 0, found = 0;
	static boolean reg_search;

	for (i = -1; i <= 1; i++) {
		for (j = -1; j <= 1; j++) {
			row = rogue.row + i;
			col = rogue.col + j;
			if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
					(col < 0) || (col >= DCOLS)) {
				continue;
			}
			if (dungeon[row][col] & HIDDEN) {
				found++;
			}
		}
	}
	for (s = 0; s < n; s++) {
		for (i = -1; i <= 1; i++) {
			for (j = -1; j <= 1; j++) {
				row = rogue.row + i;
				col = rogue.col + j ;
				if ((row < MIN_ROW) || (row >= (DROWS-1)) ||
						(col < 0) || (col >= DCOLS)) {
					continue;
				}
				if (dungeon[row][col] & HIDDEN) {
					if (rand_percent(17 + (rogue.exp + ring_exp))) {
						dungeon[row][col] &= (~HIDDEN);
						if ((!blind) && ((row != rogue.row) ||
								(col != rogue.col))) {
							mvaddch(row, col, get_dungeon_char(row, col));
						}
						shown++;
						if (dungeon[row][col] & TRAP) {
							t = trap_at(row, col);
							messagef(1, "%s", trap_strings[t*2]);
						}
					}
				}
				if (((shown == found) && (found > 0)) || interrupted) {
					return;
				}
			}
		}
		if ((!is_auto) && (reg_search = !reg_search)) {
			(void) reg_move();
		}
	}
}
Esempio n. 15
0
int
check_up(void)
{
    if (!wizard) {
        if (!(dungeon[rogue.row][rogue.col] & STAIRS)) {
            messagef(0, "I see no way up");
            return(0);
        }
        if (!has_amulet()) {
            messagef(0, "your way is magically blocked");
            return(0);
        }
    }
    new_level_message = "you feel a wrenching sensation in your gut";
    if (cur_level == 1) {
        win();
    } else {
        cur_level -= 2;
        return(1);
    }
    return(0);
}
Esempio n. 16
0
int
csping(register Cs_t* state, const char* name)
{
	register int	fd;
	register int	n;

	sfsprintf(state->temp, sizeof(state->path), "/dev/tcp/%s/inet.echo", name);
	if ((fd = csopen(state, state->temp, 0)) < 0) return -1;
	n = (cswrite(state, fd, M, N) != N || csread(state, fd, state->temp, N, CS_LINE) != N || strncmp(M, state->temp, N)) ? -1 : 0;
	close(fd);
	if (n) messagef((state->id, NiL, -1, "ping: %s: no contact", name));
	return n;
}
Esempio n. 17
0
static int run_console(int fd, int argc, char *argv[])
{
	struct lua_state *state;
	struct luadebug_user *user;

	state = lua_state_init();
	if (!state) {
		messagef(HAKA_LOG_FATAL, "hakactl", clear_error());
		return COMMAND_FAILED;
	}

	console_fd = fd;

	lua_pushcfunction(state->L, luaopen_hakactl);
	lua_call(state->L, 0, 1);
	lua_setglobal(state->L, "hakactl");

	if (!initialize_console(state)) {
		messagef(HAKA_LOG_FATAL, "hakactl", clear_error());
		lua_state_close(state);
		return COMMAND_FAILED;
	}

	user = luadebug_user_readline();
	if (!user) {
		messagef(HAKA_LOG_FATAL, "hakactl", clear_error());
		lua_state_close(state);
		return COMMAND_FAILED;
	}

	/* Load Lua console utilities */
	luadebug_interactive_enter(state->L, ">  ", ">> ", NULL, -1, user);
	luadebug_user_release(&user);

	lua_state_close(state);

	return COMMAND_SUCCESS;
}
Esempio n. 18
0
void
show_average_hp(void)
{
    float real_average;
    float effective_average;

    if (rogue.exp == 1) {
        real_average = effective_average = 0.00;
    } else {
        real_average = (float)
                       ((rogue.hp_max - extra_hp - INIT_HP) + less_hp) / (rogue.exp - 1);
        effective_average = (float)(rogue.hp_max - INIT_HP) / (rogue.exp - 1);

    }
    messagef(0, "R-Hp: %.2f, E-Hp: %.2f (!: %d, V: %d)", real_average,
             effective_average, extra_hp, less_hp);
}
void
aggravate(void)
{
	object *monster;

	messagef(0, "you hear a high pitched humming noise");

	monster = level_monsters.next_monster;

	while (monster) {
		wake_up(monster);
		monster->m_flags &= (~IMITATES);
		if (rogue_can_see(monster->row, monster->col)) {
			mvaddch(monster->row, monster->col, monster->m_char);
		}
		monster = monster->next_monster;
	}
}
Esempio n. 20
0
static int
initiate(Cs_t* state, const char* svc, char* cmd)
{
	pid_t	pid;
	pid_t	n;
	char*	av[3];

#ifdef SIGCHLD
	Handler_t	fun;

	children = 0;
	if ((fun = signal(SIGCHLD, child)) == SIG_DFL) signal(SIGCHLD, fun);
	else if (children) children++;
#endif
	pathcanon(cmd, 0, 0);
	av[0] = cmd;
	av[1] = (char*)svc;
	av[2] = 0;
	if ((pid = spawnveg(av[0], av, environ, 0)) == -1)
	{
		messagef((state->id, NiL, -1, "local: %s: cannot initiate %s", svc, cmd));
		return -1;
	}
	while ((n = waitpid(pid, NiL, 0)) == -1 && errno == EINTR);
#ifdef SIGCHLD
	if (fun != SIG_DFL)
	{
		signal(SIGCHLD, fun);
		if (fun != SIG_IGN)
			while (--children > 0)
				(*fun)(SIGCHLD);
	}
#endif

	/*
	 * yuk: looks like we have to give fdp services time
	 *	to start up -- a few seconds shouldn't hurt
	 */

	sleep(2);
	return n;
}
Esempio n. 21
0
void luadebug_user_remote_server(int fd, struct luadebug_user *user)
{
	char command;
	while ((read(fd, &command, 1) == 1)) {
		switch (command) {
		case 's':
		{
			char *line = read_string(fd);
			if (!line) {
				messagef(HAKA_LOG_ERROR, MODULE, L"remote communication error: %s", errno_error(errno));
				return;
			}

			user->start(user, line);
			free(line);

			if (!luadebug_user_remote_server_session(fd, user)) {
				message(HAKA_LOG_ERROR, MODULE, L"remote communication error");
				return;
			}
			break;
		}

		case 'P':
		{
			break;
		}

		default:
			message(HAKA_LOG_ERROR, MODULE, L"remote communication error");
			return;
		}
	}

	luadebug_user_release(&user);
}
Esempio n. 22
0
int save_iptables(const char *table, char **conf, bool all_targets)
{
	int pipefd_out[2];
	int pipefd_err[2];
	pid_t child_pid;
	int error = 0;

	assert(conf);

	child_pid = fork_with_pipes(pipefd_out, pipefd_err);
	if (child_pid < 0) {
		return error;
	}

	if (child_pid == 0) {
		/* child */
		close(pipefd_out[0]);
		close(pipefd_err[0]);

		if (dup2(pipefd_out[1], STDOUT_FILENO) == -1 ||
		    dup2(pipefd_err[1], STDERR_FILENO) == -1) {
			fprintf(stderr, "%s\n", strerror(errno));
			exit(1);
		}
		close(pipefd_out[1]);
		close(pipefd_err[1]);

		execl(IPTABLES_SAVE, "iptables-save", "-t", table, NULL);

		/* an error occured */
		fprintf(stderr, "%s\n", strerror(errno));
		exit(1);
	}
	else {
		/* parent */
		int status;
		pid_t ret;
		char *buffer = NULL;
		size_t buffer_size = 0, read_size = 0;
		ssize_t line_size;
		FILE *input = fdopen(pipefd_out[0], "r");
		FILE *err = fdopen(pipefd_err[0], "r");
		bool filtering = false;
		bool pre_found = false, out_found = false;
		fd_set fds, curfds;
		int max_fd, fd_count;

		if (!input || !err) {
			messagef(HAKA_LOG_ERROR, MODULE_NAME, "iptables-save: %s", errno_error(errno));
			fclose(input);
			fclose(err);
			return errno;
		}

		close(pipefd_out[1]);
		close(pipefd_err[1]);

		pipefd_out[1] = fileno(input);
		pipefd_err[1] = fileno(err);

		FD_ZERO(&fds);
		FD_SET(pipefd_out[1], &fds);
		FD_SET(pipefd_err[1], &fds);
		max_fd = pipefd_out[1] > pipefd_err[1] ? pipefd_out[1] : pipefd_err[1];
		fd_count = 2;

		while (fd_count > 0) {
			int rc;
			curfds = fds;

			rc = select(max_fd+1, &curfds, NULL, NULL, NULL);
			if (rc < 0) {
				messagef(HAKA_LOG_ERROR, MODULE_NAME, "iptables-save: %s", errno_error(errno));
				free(buffer);
				fclose(input);
				fclose(err);
				return errno;
			}

			if (FD_ISSET(pipefd_err[1], &curfds)) {
				line_size = getline(&buffer, &buffer_size, err);
				if (line_size > 1) {
					buffer[line_size-1] = '\0';
					messagef(HAKA_LOG_INFO, MODULE_NAME, "iptables-save: %s", buffer);
				}
				else {
					FD_CLR(pipefd_err[1], &fds);
					--fd_count;
				}
			}

			if (FD_ISSET(pipefd_out[1], &curfds)) {
				line_size = getline(&buffer, &buffer_size, input);
				if (line_size > 0) {
					if (filtering) {
						if (strcmp(buffer, "COMMIT\n") != 0) {
							/*
							 * If all_targets is true, we only want to include the rule in the
							 * targets HAKA_TARGET_PRE and HAKA_TARGET_OUT. So we need to filter
							 * each line to only include those but being careful not to add the
							 * line from another target that jump to one of the haka target
							 * (ie. -A PREROUTING -j haka-pre)
							 */
							char *pattern, *current = buffer;
							bool skip = true;

							while (true) {
								if ((pattern = strstr(current, "-j " HAKA_TARGET))) {
									pattern += 3; /* Skip '-j ' */

									if (check_haka_target(pattern, HAKA_TARGET_PRE) ||
										check_haka_target(pattern, HAKA_TARGET_OUT)) {
										skip = true;
										break;
									}

									/*
									 * Advance one more to avoid the next test case to match
									 * (ie. pattern = strstr(current, HAKA_TARGET))
									 */
									current = pattern+1;
								}
								else if ((pattern = strstr(current, HAKA_TARGET))) {
									if (check_haka_target(pattern, HAKA_TARGET_PRE)) {
										skip = false;
										pre_found = true;
										break;
									}
									else if (check_haka_target(pattern, HAKA_TARGET_OUT)) {
										skip = false;
										out_found = true;
										break;
									}

									current = pattern+1;
								}
								else {
									skip = true;
									break;
								}
							}

							if (!all_targets && skip) {
								continue;
							}
						}
						else {
							/*
							 * The target HAKA_TARGET_PRE or HAKA_TARGET_OUT do not
							 * exist.
							 * In this case, iptables-restore will be unable to remove them.
							 * As a workaround, we just install new empty targets to cleanup
							 * Haka rules. This case only appears when the user sets the option
							 * enable_iptables=no which is not the default.
							 */

							if (!pre_found) {
								if (!append_string(conf, &read_size, iptables_empty_haka_pre_target, -1)) {
									free(buffer);
									fclose(input);
									fclose(err);
									return ENOMEM;
								}
							}

							if (!out_found) {
								if (!append_string(conf, &read_size, iptables_empty_haka_out_target, -1)) {
									free(buffer);
									fclose(input);
									fclose(err);
									return ENOMEM;
								}
							}

							/* COMMIT and the text after it should not be skipped  */
							filtering = false;
						}
					}

					if (buffer[0] == '*') {
						filtering = true;
					}

					if (!append_string(conf, &read_size, buffer, line_size)) {
						free(buffer);
						fclose(input);
						fclose(err);
						return ENOMEM;
					}
				}
				else {
					FD_CLR(pipefd_out[1], &fds);
					--fd_count;
				}
			}
		}

		free(buffer);
		fclose(input);
		fclose(err);

		if (error) {
			free(*conf);
			*conf = NULL;
			return error;
		}

		/* Wait for the child to finish */
		do {
			ret = waitpid(child_pid, &status, 0);
			if (ret == -1) {
				free(*conf);
				*conf = NULL;
				return errno;
			}
		}
		while (!WIFEXITED(status) && !WIFSIGNALED(status));

		if (WEXITSTATUS(status) != 0) {
			free(*conf);
			*conf = NULL;
			return 1;
		}

		return 0;
	}
}
Esempio n. 23
0
gboolean osm_download(GtkWidget *parent, settings_t *settings,
		      project_t *project) {
  printf("download osm ...\n");

  g_assert(project->server);

  /* check if server name contains string "0.5" and adjust it */
  if(project->server == project->rserver) {
    if(strstr(project->rserver, "0.5") != NULL) {
      strstr(project->rserver, "0.5")[2] = '6';

      messagef(parent, _("Server changed"),
               _("It seems your current project uses a server/protocol no "
               "longer in use by OSM. It has thus been changed to:\n\n%s"),
               project->server);
    }

    /* server url should not end with a slash */
    if(project->rserver[strlen(project->rserver)-1] == '/') {
      printf("removing trailing slash\n");
      project->rserver[strlen(project->rserver)-1] = 0;
    }

    if(strcmp(project->rserver, settings->server) == 0) {
      g_free(project->rserver);
      project->rserver = NULL;
      project->server = settings->server;
    }
  }

  char minlon[G_ASCII_DTOSTR_BUF_SIZE], minlat[G_ASCII_DTOSTR_BUF_SIZE];
  char maxlon[G_ASCII_DTOSTR_BUF_SIZE], maxlat[G_ASCII_DTOSTR_BUF_SIZE];

  g_ascii_formatd(minlon, sizeof(minlon), LL_FORMAT, project->min.lon);
  g_ascii_formatd(minlat, sizeof(minlat), LL_FORMAT, project->min.lat);
  g_ascii_formatd(maxlon, sizeof(maxlon), LL_FORMAT, project->max.lon);
  g_ascii_formatd(maxlat, sizeof(maxlat), LL_FORMAT, project->max.lat);

  gchar *url = g_strconcat(project->server, "/map?bbox=",
		     minlon, ",", minlat,
		",", maxlon, ",", maxlat, NULL);

  /* Download the new file to a new name. If something goes wrong then the
   * old file will still be in place to be opened. */
  gchar *update = g_strconcat(project->path, "update.osm", NULL);
  g_remove(update);

  gboolean result = net_io_download_file(parent, settings, url, update,
                                         project->name);
  g_free(url);

  /* if there's a new file use this from now on */
  if(result && g_file_test(update, G_FILE_TEST_IS_REGULAR)) {
    printf("download ok, replacing previous file\n");

    if(project->osm[0] == '/') {
      g_rename(update, project->osm);
    } else {
      gchar *fname = g_strconcat(project->path, project->osm, NULL);
      g_rename(update, fname);
      g_free(fname);
    }

    result = TRUE;
  }

  g_free(update);

  return result;
}
Esempio n. 24
0
bool initialize_console(struct lua_state *state)
{
	const char *haka_path_s = haka_path();
	char *console_path;
	size_t size;
	DIR *dir;
	struct dirent entry, *result = NULL;

	/* Load all console utilities */
	lua_newtable(state->L);
	lua_setglobal(state->L, "console");
	lua_getglobal(state->L, "console");

	/* <haka_path_s><HAKA_CONSOLE/\0 */
	size = strlen(haka_path_s) + strlen(HAKA_CONSOLE) + 1;

	console_path = malloc(size);
	if (!console_path) {
		error("memory error");
		return false;
	}

	snprintf(console_path, size, "%s%s", haka_path_s, HAKA_CONSOLE);

	dir = opendir(console_path);
	if (!dir) {
		error("cannot open console script folder: %s", console_path);
		return false;
	}
	else {
		while (!readdir_r(dir, &entry, &result) && result) {
			const size_t len = strlen(entry.d_name);
			char fullfilename[PATH_MAX];
			const int level = lua_gettop(state->L);

			snprintf(fullfilename, sizeof(fullfilename), "%s/%s",
					console_path, entry.d_name);

			if (len > 4 && strcmp(entry.d_name + (len - 4), ".lua") == 0) {
				entry.d_name[len - 4] = 0;
			}
			else if (len > 3
			         && strcmp(entry.d_name + (len - 3), ".bc") == 0) {
				entry.d_name[len - 3] = 0;
			}
			else {
				continue;
			}

			messagef(HAKA_LOG_DEBUG, "hakactl", "loading console script '%s'", entry.d_name);

			if (luaL_dofile(state->L, fullfilename)) {
				const char *msg = lua_tostring(state->L, -1);
				messagef(HAKA_LOG_ERROR, "hakactl", "cannot open console script '%s': %s",
				         entry.d_name, msg);
				lua_pop(state->L, 1);
			}
			else {
				const int res = lua_gettop(state->L) - level;
				if (res == 1) {
					lua_setfield(state->L, -2, entry.d_name);
				}
				else {
					lua_pop(state->L, res);
				}
			}
		}
	}

	return true;
}
Esempio n. 25
0
static bool luadebug_user_remote_server_session(int fd, struct luadebug_user *user)
{
	char command;

	server_completion_fd = fd;
	user->completion = remote_completion;

	while ((read(fd, &command, 1) == 1)) {
		switch (command) {
		case 'e':
		{
			user->stop(user);
			return true;
		}

		case 'p':
		{
			char *line = read_string(fd);
			if (!line) {
				messagef(HAKA_LOG_ERROR, MODULE, L"remote communication error: %s", errno_error(errno));
				return false;
			}

			user->print(user, line);
			free(line);
			break;
		}

		case 'h':
		{
			char *line = read_string(fd);
			if (!line) {
				messagef(HAKA_LOG_ERROR, MODULE, L"remote communication error: %s", errno_error(errno));
				return false;
			}

			user->addhistory(user, line);
			free(line);
			break;
		}

		case 'r':
		{
			char *line = read_string(fd);
			if (!line) {
				messagef(HAKA_LOG_ERROR, MODULE, L"remote communication error: %s", errno_error(errno));
				return false;
			}

			char *rdline = user->readline(user, line);
			if (!rdline) {
				messagef(HAKA_LOG_ERROR, MODULE, L"remote communication error: %s", errno_error(errno));
				free(line);
				return false;
			}

			free(line);

			command = '1';
			write(fd, &command, 1);
			write_string(fd, rdline);
			free(rdline);
			break;
		}

		case 'P':
		{
			break;
		}

		default:
			messagef(HAKA_LOG_ERROR, MODULE, L"remote communication error: %s", errno_error(errno));
			return false;
		}
	}

	return false;
}
Esempio n. 26
0
int
cslocal(register Cs_t* state, const char* path)
{
	register char*	s;
	register char*	p;
	register char*	t;
	register char*	v;
	struct stat	st;
	char		cmd[PATH_MAX / 8];
	char		exe[PATH_MAX + 1];
	char		tmp[PATH_MAX + 1];
#if CS_LIB_STREAM || CS_LIB_V10 || CS_LIB_SOCKET_UN
	int		fd;
	int		n;
#endif

	messagef((state->id, NiL, -8, "local(%s) call", path));

	/*
	 * validate the path
	 */

	p = (char*)path;
	if (strncmp(p, DEVLOCAL, sizeof(DEVLOCAL) - 1))
	{
		messagef((state->id, NiL, -1, "local: %s: %s* expected", path, DEVLOCAL));
		goto sorry;
	}
	p += sizeof(DEVLOCAL) - 1;
	for (t = p; *t && *t != '/'; t++);
	if (!streq(t + 1, "user"))
	{
		messagef((state->id, NiL, -1, "local: %s: %s*/user expected", path, DEVLOCAL));
		goto sorry;
	}

	/*
	 * locate the service
	 */

	s = cmd;
	for (v = p; p <= t; *s++ = *p++);
	t = s - 1;
	for (p = v; p <= t; *s++ = *p++);
	for (p = CS_SVC_SUFFIX; *s++ = *p++;);
	p = pathbin();
	for (;;)
	{
		p = pathcat(p, ':', "../lib/cs/fdp", cmd, exe, PATH_MAX + 1);
		if (!eaccess(exe, X_OK) && !stat(exe, &st)) break;
		if (!p)
		{
			messagef((state->id, NiL, -1, "local: %s: %s: cannot locate service on ../lib/cs/fdp", path, cmd));
			goto sorry;
		}
	}
	*t = 0;
	sfsprintf(tmp, sizeof(tmp), "%s/fdp/%s/%s/%d-%d-/%c%s", csvar(state, CS_VAR_LOCAL, 0), csname(state, 0), cmd, st.st_uid, geteuid(), CS_MNT_STREAM, CS_MNT_TAIL);

#if CS_LIB_STREAM || CS_LIB_V10

	for (n = 0; (fd = open(tmp, O_RDWR)) < 0; n++)
		if (n || errno == EACCES)
		{
			messagef((state->id, NiL, -1, "local: %s: %s: cannot open service", path, tmp));
			return -1;
		}
		else if (initiate(state, path, exe) < 0)
		{
			messagef((state->id, NiL, -1, "local: %s: %s: cannot initiate service %s", path, tmp, exe));
			return -1;
		}
	messagef((state->id, NiL, -8, "local(%s) fd=%d server=%s stream=%s", path, fd, exe, tmp));
	return fd;

#else

#if CS_LIB_SOCKET_UN

	{
		int			namlen;
		struct sockaddr_un	nam;

		nam.sun_family = AF_UNIX;
		strcpy(nam.sun_path, tmp);
		namlen = sizeof(nam.sun_family) + strlen(tmp);
		n = 0;
		fd = -1;
		for (;;)
		{
			if (fd < 0 && (fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
			{
				messagef((state->id, NiL, -1, "local: %s: AF_UNIX socket error", path));
				return -1;
			}
			if (!connect(fd, (struct sockaddr*)&nam, namlen))
			{
#if CS_LIB_SOCKET_RIGHTS
				if (read(fd, cmd, 1) != 1)
					messagef((state->id, NiL, -1, "local: %s: connect ack read error", path));
				else if (cssend(state, fd, NiL, 0))
					messagef((state->id, NiL, -1, "local: %s: connect authentication send error", path));
				else
#endif
				return fd;
#if CS_LIB_SOCKET_RIGHTS
				close(fd);
				fd = -1;
#endif
			}
			else messagef((state->id, NiL, -1, "local: %s: connect error", path));
			if (errno != EACCES) errno = ENOENT;
			if (n || errno == EACCES || initiate(state, path, exe) < 0)
			{
				if (fd >= 0) close(fd);
				return -1;
			}
			n = 1;
			messagef((state->id, NiL, -1, "local: %s: connect retry", path));
		}
	}

#endif

#endif

 sorry:
	errno = ENOENT;
	return -1;
}
Esempio n. 27
0
static int init(struct parameters *args)
{
	char *new_iptables_config = NULL;
	char *interfaces_buf = NULL;
	char **ifaces = NULL;
	int thread_count = thread_get_packet_capture_cpu_count();
	const char *file_in = NULL;
	const char *file_out = NULL;
	const char *file_drop = NULL;
	int count;
	bool dump = false;

	/* Setup iptables rules */
	if (save_iptables("raw", &iptables_saved)) {
		message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot save iptables rules");
		cleanup();
		return 1;
	}

	{
		const char *iter;
		const char *interfaces = parameters_get_string(args, "interfaces", NULL);
		if (!interfaces) {
			message(HAKA_LOG_ERROR, MODULE_NAME, L"no interfaces selected");
			cleanup();
			return 1;
		}

		for (count = 0, iter = interfaces; *iter; ++iter) {
			if (*iter == ',')
				++count;
		}

		interfaces_buf = strdup(interfaces);
		if (!interfaces_buf) {
			error(L"memory error");
			cleanup();
			return 1;
		}

		++count;
	}

	ifaces = malloc((sizeof(char *) * (count + 1)));
	if (!ifaces) {
		message(HAKA_LOG_ERROR, MODULE_NAME, L"memory error");
		free(interfaces_buf);
		cleanup();
		return 1;
	}

	messagef(HAKA_LOG_INFO, MODULE_NAME, L"installing iptables rules for device(s) %s", interfaces_buf);

	{
		int index = 0;
		char *str, *ptr = NULL;
		for (index = 0, str = interfaces_buf; index < count; index++, str = NULL) {
			char *token = strtok_r(str, ",", &ptr);
			assert(token != NULL);
			ifaces[index] = token;
		}
		ifaces[index] = NULL;
	}

	new_iptables_config = iptables_config(ifaces, thread_count);
	if (!new_iptables_config) {
		message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot generate iptables rules");
		free(ifaces);
		free(interfaces_buf);
		cleanup();
		return 1;
	}
	free(ifaces);
	ifaces = NULL;
	free(interfaces_buf);
	interfaces_buf = NULL;

	if (apply_iptables(new_iptables_config)) {
		message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot setup iptables rules");
		free(new_iptables_config);
		cleanup();
		return 1;
	}

	free(new_iptables_config);

	/* Setup pcap dump */
	dump = parameters_get_boolean(args, "dump", false);
	if (dump) {
		file_in = parameters_get_string(args, "dump_input", NULL);
		file_out = parameters_get_string(args, "dump_output", NULL);
		file_drop = parameters_get_string(args, "dump_drop", NULL);
		if (!(file_in || file_out || file_drop)) {
			message(HAKA_LOG_WARNING, MODULE_NAME, L"no dump pcap files specified");
		}
		else {
			pcap = malloc(sizeof(struct pcap_sinks));
			if (!pcap) {
				message(HAKA_LOG_ERROR, MODULE_NAME, L"memory error");
				cleanup();
				return 1;
			}
			memset(pcap, 0, sizeof(struct pcap_sinks));

			if (file_in) {
				open_pcap(&pcap->in, file_in);
				messagef(HAKA_LOG_INFO, MODULE_NAME, L"dumping received packets into '%s'", file_in);
			}
			if (file_out) {
				open_pcap(&pcap->out, file_out);
				messagef(HAKA_LOG_INFO, MODULE_NAME, L"dumping emitted packets into '%s'", file_out);
			}
			if (file_drop) {
				open_pcap(&pcap->drop, file_drop);
				messagef(HAKA_LOG_INFO, MODULE_NAME, L"dumping dropped packets into '%s'", file_drop);
			}
		}
	}

	return 0;
}
Esempio n. 28
0
int
csopen(register Cs_t* state, const char* apath, int op)
{
	register char*	path = (char*)apath;
	register char*	b;
	register char*	s;
	register int	n;
	int		fd;
	char*		t;
	char*		u;
	char*		type;
	char*		endtype;
	char*		host;
	char*		endhost;
	char*		serv;
	char*		endserv;
	char*		qual;
	char*		endqual;
	char*		opath;
	char*		user = 0;
	char*		group = 0;
	char*		trust = 0;
	char*		arg = 0;
	int		nfd = -1;
	int		uid = -1;
	int		gid = -1;
	int		sid = -1;
	int		auth = 1;
	int		mode;
	unsigned long	addr;
	unsigned long	port = 0;
	struct stat	st;
	char		buf[PATH_MAX];
	char		tmp[PATH_MAX];

	if (!path)
	{
		errno = EFAULT;
		return -1;
	}
	csprotect(&cs);
	if (op < 0)
		op = CS_OPEN_TEST;
	messagef((state->id, NiL, -8, "open(%s,%o) call", path, op));

	/*
	 * blast out the parts
	 */

	opath = path;
	if (pathgetlink(path, buf, sizeof(buf)) <= 0)
	{
		if (strlen(path) >= sizeof(buf))
			return -1;
		strcpy(buf, path);
	}
	else if ((state->flags & CS_ADDR_LOCAL) && (s = strrchr(buf, '/')))
	{
		/*
		 * dynamic ip assignment can change the addr
		 * underfoot in some implementations so we
		 * double check the local ip here
		 */

		strcpy(tmp, buf);
		if (tokscan(tmp, NiL, "/dev/%s/%s/%s", &type, NiL, &serv) == 3)
			sfsprintf(buf, sizeof(buf), "/dev/%s/%s/%s", type, csntoa(state, 0), serv);
	}
	path = buf;
	pathcanon(path, 0, 0);
	errno = ENOENT;
	strcpy(state->path, path);
	b = path;
	if ((*b++ != '/') || !(s = strchr(b, '/')))
		return -1;
	*s++ = 0;
	if (!streq(b, "dev"))
		return -1;
	if (b = strchr(s, '/'))
		*b++ = 0;
	if (streq(s, "fdp"))
	{
#if !( CS_LIB_SOCKET_UN || CS_LIB_STREAM || CS_LIB_V10 )
		if (access(CS_PROC_FD_TST, F_OK))
		{
			errno = ENODEV;
			messagef((state->id, NiL, -1, "open: %s: %s: not supported", state->path, s));
			return -1;
		}
#endif
	}
	else if (!streq(s, "tcp") && !streq(s, "udp"))
	{
		messagef((state->id, NiL, -1, "open: %s: %s: invalid type", state->path, s));
		return -1;
	}
#if !( CS_LIB_SOCKET || CS_LIB_STREAM || CS_LIB_V10 )
	else
	{
		errno = ENODEV;
		messagef((state->id, NiL, -1, "open: %s: %s: not supported", state->path, s));
		return -1;
	}
#endif
	type = s;
	qual = state->qual;
	if (!b)
		host = serv = 0;
	else
	{
		host = b;
		if (!(s = strchr(b, '/')))
			serv = 0;
		else
		{
			*s++ = 0;
			serv = s;

			/*
			 * grab the next fd to preserve open semantics
			 */

			for (n = 0; n < 10; n++)
				if ((nfd = dup(n)) >= 0)
					break;

			/*
			 * get qual, perm and arg
			 */

			mode = S_IRWXU|S_IRWXG|S_IRWXO;
			if (b = strchr(s, '/'))
			{
				*b++ = 0;
				do
				{
					if (*b == '#')
					{
						arg = b + 1;
						break;
					}
					if (u = strchr(b, '/'))
						*u++ = 0;
					if (s = strchr(b, '='))
						*s++ = 0;
					for (n = 0, t = b; *t; n = HASHKEYPART(n, *t++));
					switch (n)
					{
					case HASHKEY5('g','r','o','u','p'):
						group = s ? s : "";
						break;
					case HASHKEY5('l','o','c','a','l'):
						op |= CS_OPEN_LOCAL;
						break;
					case HASHKEY3('n','o','w'):
						op |= CS_OPEN_NOW;
						break;
					case HASHKEY5('o','t','h','e','r'):
						auth = 0;
						break;
					case HASHKEY6('r','e','m','o','t','e'):
						op |= CS_OPEN_REMOTE;
						break;
					case HASHKEY5('s','h','a','r','e'):
						op |= CS_OPEN_SHARE;
						break;
					case HASHKEY5('s','l','a','v','e'):
						op |= CS_OPEN_SLAVE;
						break;
					case HASHKEY4('t','e','s','t'):
						op |= CS_OPEN_TEST;
						break;
					case HASHKEY5('t','r','u','s','t'):
						op |= CS_OPEN_TRUST;
						trust = s;
						break;
					case HASHKEY4('u','s','e','r'):
						user = s ? s : "";
						break;
					default:
						qual += sfsprintf(qual, sizeof(state->qual) - (qual - state->qual) - 1, "%s%s", qual == state->qual ? "" : "-", b);
						if (s)
							*(s - 1) = '=';
						break;
					}
				} while (b = u);
			}
		}
	}
	if (*type != 't')
		auth = 0;
	strncpy(state->type, type, sizeof(state->type) - 1);
	qual = (qual == state->qual) ? (char*)0 : state->qual;
	messagef((state->id, NiL, -8, "open: type=%s host=%s serv=%s qual=%s", type, host, serv, qual));
	if (host)
	{
		/*
		 * validate host
		 */

		if (!(state->addr = addr = csaddr(state, host)))
		{
			if (serv && !(op & CS_OPEN_CREATE) && *type == 't' && (port = csport(state, type, serv)) >= CS_PORT_MIN && port <= CS_PORT_MAX)
			{
				/*
				 * attempt proxy connection
				 */

				if (nfd >= 0)
				{
					close(nfd);
					nfd = -1;
				}
				if ((fd = state->proxy.addr ? csbind(state, type, state->proxy.addr, state->proxy.port, 0L) : reopen(state, csvar(state, CS_VAR_PROXY, 0))) >= 0)
				{
					state->proxy.addr = state->addr;
					state->proxy.port = state->port;
					n = sfsprintf(tmp, sizeof(tmp), "\n%s!%s!%d\n\n%s\n%s\n0\n-1\n-1\n", type, host, port, csname(state, 0), error_info.id ? error_info.id : state->id);
					if (cswrite(state, fd, tmp, n) == n && (n = csread(state, fd, tmp, sizeof(tmp), CS_LINE)) >= 2)
					{
						if (tmp[0] == '0' && tmp[1] == '\n')
							return fd;
						if (error_info.trace <= -4 && n > 2)
						{
							s = tmp;
							s[n - 1] = 0;
							while (*s && *s++ != '\n');
							messagef((state->id, NiL, -4, "%s error message `%s'", csvar(state, CS_VAR_PROXY, 0), s));
						}
					}
					close(fd);
				}
			}
#ifdef EADDRNOTAVAIL
			errno = EADDRNOTAVAIL;
#else
			errno = ENOENT;
#endif
			goto bad;
		}
		if (op & CS_OPEN_LOCAL)
		{
			state->flags |= CS_ADDR_LOCAL;
			state->flags &= ~CS_ADDR_REMOTE;
		}
		if (op & CS_OPEN_NOW)
			state->flags |= CS_ADDR_NOW;
		if ((op & (CS_OPEN_AGENT|CS_OPEN_REMOTE)) == CS_OPEN_REMOTE)
		{
			state->flags |= CS_ADDR_REMOTE;
			state->flags &= ~CS_ADDR_LOCAL;
		}
		if (op & CS_OPEN_SHARE)
			state->flags |= CS_ADDR_SHARE;
		if (op & CS_OPEN_SLAVE)
			state->flags |= CS_DAEMON_SLAVE;
		if (op & CS_OPEN_TEST)
			state->flags |= CS_ADDR_TEST;
		if (op & CS_OPEN_TRUST)
			state->flags |= CS_ADDR_TRUST;
		if ((state->flags & CS_ADDR_REMOTE) && (!serv || !strneq(serv, CS_SVC_INET, sizeof(CS_SVC_INET) - 1) && (strtol(serv, &t, 0), *t)))
			return agent(state, state->host, state->user, state->path);
		if (s = user)
		{
			n = geteuid();
			if (*s)
			{
				if ((uid = struid(s)) < 0)
				{
					uid = strtol(s, &t, 0);
					if (*t)
					{
						errno = EACCES;
						goto bad;
					}
				}
				if (n && uid != n)
				{
					errno = EACCES;
					goto bad;
				}
			}
			else
				uid = n;
			mode &= ~(S_IRWXG|S_IRWXO);
		}
		if (s = group)
		{
			n = getegid();
			if (*s)
			{
				if ((gid = strgid(s)) < 0)
				{
					gid = strtol(s, &t, 0);
					if (*t)
					{
						errno = EACCES;
						goto bad;
					}
				}
				if (geteuid() && gid != n)
				{
					gid_t*	groups;
					int	g;

					if ((g = getgroups(0, NiL)) <= 0)
						g = getconf("NGROUPS_MAX");
					if (groups = newof(0, gid_t, g, 0))
					{
						for (n = getgroups(g, groups); n >= 0; n--)
							if (gid == groups[n])
								break;
						free(groups);
					}
					else
						n = -1;
					if (n < 0)
					{
						errno = EACCES;
						goto bad;
					}
				}
			}
			else
				gid = n;
			mode &= ~S_IRWXO;
		}
		if (s = trust)
		{
			if (!*s)
				sid = geteuid();
			else if ((sid = struid(s)) < 0)
			{
				sid = strtol(s, &t, 0);
				if (*t)
				{
					errno = EACCES;
					goto bad;
				}
			}
		}
		if (state->flags & CS_ADDR_SHARE)
			host = CS_HOST_SHARE;
		else
		{
			host = state->host;
			if (!(state->flags & CS_ADDR_LOCAL))
			{
				if (*type == 'f')
				{
					errno = ENODEV;
					goto bad;
				}
				if (op & CS_OPEN_CREATE)
				{
					errno = EROFS;
					goto bad;
				}
			}
			if (serv && !qual && *type != 'f' && (port = csport(state, type, serv)) != CS_PORT_INVALID)
			{
				if (op & CS_OPEN_CREATE)
					addr = 0;
				else if (port == CS_PORT_RESERVED || port == CS_PORT_NORMAL)
					goto bad;
				if (nfd >= 0)
				{
					close(nfd);
					nfd = -1;
				}
				state->control = 0;
				if ((fd = csbind(state, type, addr, port, 0L)) >= 0)
				{
					if (mode != (S_IRWXU|S_IRWXG|S_IRWXO) && csauth(state, fd, NiL, NiL))
					{
						close(fd);
						return -1;
					}
					return fd;
				}
			}
		}
	}

	/*
	 * get the mount dir prefix
	 */

	if (opath == (b = path = state->mount))
	{
#ifdef ELOOP
		errno = ELOOP;
#else
		errno = EINVAL;
#endif
		goto bad;
	}
	if (*type == 'f')
	{
		if (host && !(state->flags & CS_ADDR_LOCAL))
		{
			errno = ENODEV;
			goto bad;
		}
		b += sfsprintf(b, sizeof(state->mount) - (b - path), "%s", csvar(state, CS_VAR_LOCAL, 0));
		if ((op & CS_OPEN_CREATE) && eaccess(path, X_OK) && (mkdir(path, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(path, S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)))
			goto bad;
	}
	else
	{
		if (op & CS_OPEN_TRUST)
		{
			if (!pathaccess(csvar(state, CS_VAR_TRUST, 1), csvar(state, CS_VAR_SHARE, 1), NiL, PATH_EXECUTE, b, sizeof(state->mount) - (b - state->mount)))
				goto bad;
		}
		else if (!pathpath(csvar(state, CS_VAR_SHARE, 0), "", PATH_EXECUTE, b, sizeof(state->mount) - (b - state->mount)))
			goto bad;
		b += strlen(b);
	}

	/*
	 * add the type
	 */

	b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", type);
	if (!host)
	{
		*(state->control = b + 1) = 0;
		if (nfd >= 0)
			close(nfd);
		if ((fd = open(path, O_RDONLY)) < 0)
		{
			mkmount(state, S_IRWXU|S_IRWXG|S_IRWXO, -1, -1, NiL, NiL, NiL);
			fd = open(path, O_RDONLY);
		}
		if (fd < 0)
			messagef((state->id, NiL, -1, "open: %s: %s: open error", state->path, path));
		return fd;
	}
	endtype = b;

	/*
	 * add the host
	 */

	if (strlen(host) <= CS_MNT_MAX)
		b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", host);
	else
	{
		s = csntoa(state, addr);
		if (strlen(s) <= CS_MNT_MAX)
			b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", s);
		else
		{
			unsigned char*	a = (unsigned char*)&addr;

			b += sfsprintf(b, sizeof(state->mount) - (b - path), "/0x%X.%X.%X.%X", a[0], a[1], a[2], a[3]);
		}
	}
	messagef((state->id, NiL, -8, "%s:%d host=`%s' path=`%s'", __FILE__, __LINE__, host, path));
	if (!serv)
	{
		*(state->control = b + 1) = 0;
		if (nfd >= 0)
			close(nfd);
		if ((fd = open(path, O_RDONLY)) < 0)
			messagef((state->id, NiL, -1, "open: %s: %s: open error", state->path, path));
		return fd;
	}
	endhost = b;

	/*
	 * add the service
	 */

	sfsprintf(b, sizeof(state->mount) - (b - path), "%s/%s/%s/%s%s", CS_SVC_DIR, type, serv, serv, CS_SVC_SUFFIX);
	if (!pathpath(b, "", PATH_ABSOLUTE|PATH_EXECUTE, tmp, sizeof(tmp)) || stat(tmp, &st))
		op |= CS_OPEN_TEST;
	else
	{
		*strrchr(tmp, '/') = 0;
		if (!(op & CS_OPEN_TRUST))
			sid = st.st_uid;
		if (!st.st_size)
			op |= CS_OPEN_TEST;
	}
	b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%s", serv);
	endserv = b;

	/*
	 * add the qualifier and perm
	 */

	if (sid >= 0)
		b += sfsprintf(b, sizeof(state->mount) - (b - path), "/%d-", sid);
	else
		b += sfsprintf(b, sizeof(state->mount) - (b - path), "/-");
	if (uid >= 0)
		b += sfsprintf(b, sizeof(state->mount) - (b - path), "%d-", uid);
	else if (gid >= 0)
		b += sfsprintf(b, sizeof(state->mount) - (b - path), "-%d", gid);
	else
		b += sfsprintf(b, sizeof(state->mount) - (b - path), "-");
#if limit_qualifier_length
	endqual = endserv + CS_MNT_MAX + 1;
#else
	endqual = state->mount + sizeof(state->mount) - 1;
#endif
	if (qual)
	{
		if (b < endqual)
			*b++ = '-';
		while (b < endqual && *qual)
			*b++ = *qual++;
	}
	if (*type == 't' && !auth)
	{
		if (b >= endqual)
			b--;
		*b++ = CS_MNT_OTHER;
	}

	/*
	 * add in the connect stream control
	 */

	*b++ = '/';
	*b = CS_MNT_STREAM;
	strcpy(b + 1, CS_MNT_TAIL);
	messagef((state->id, NiL, -8, "%s:%d %s", __FILE__, __LINE__, state->mount));
	state->control = b;

	/*
	 * create the mount subdirs if necessary
	 */

	if ((op & CS_OPEN_CREATE) && mkmount(state, mode, uid, gid, endserv, endhost, endtype))
		goto bad;
	mode &= S_IRWXU|S_IRWXG|S_IRWXO;
	if (nfd >= 0)
	{
		close(nfd);
		nfd = -1;
	}
	if (op & CS_OPEN_MOUNT)
	{
		messagef((state->id, NiL, -1, "open(%s,%o) = %d, mount = %s", state->path, op, state->mount));
		return 0;
	}
	if (*type == 'f')
	{
		/*
		 * {fdp}
		 */

		if ((fd = doattach(state, path, op, mode, user, opath, tmp, serv, b)) < 0)
			return -1;
	}
	else
	{
		/*
		 * {tcp,udp}
		 */

		messagef((state->id, NiL, -8, "%s:%d %s", __FILE__, __LINE__, state->mount));
		if ((fd = reopen(state, path)) < 0)
		{
			/*
			 * check for old single char cs mount
			 */

			*(state->control + 1) = 0;
			if ((fd = reopen(state, path)) < 0)
				messagef((state->id, NiL, -1, "open: %s: %s: reopen error", state->path, path));
			*(state->control + 1) = CS_MNT_TAIL[0];
		}
		if (op & CS_OPEN_CREATE)
		{
			if (fd >= 0)
			{
				close(fd);
				errno = EEXIST;
				return -1;
			}
			if (errno != ENOENT && errno != ENOTDIR)
				return -1;
			sigcritical(1);
			*state->control = CS_MNT_LOCK;
			if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0)) < 0)
			{
				if (stat(path, &st))
				{
					messagef((state->id, NiL, -1, "open: %s: %s: creat error", state->path, path));
					goto unblock;
				}
				if ((CSTIME() - (unsigned long)st.st_ctime) < 2 * 60)
				{
					errno = EEXIST;
					messagef((state->id, NiL, -1, "open: %s: %s: another server won the race", state->path, path));
					goto unblock;
				}
				if (remove(path))
				{
					messagef((state->id, NiL, -1, "open: %s: %s: remove error", state->path, path));
					goto unblock;
				}
				if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0)) < 0)
				{
					messagef((state->id, NiL, -1, "open: %s: %s: creat error", state->path, path));
					goto unblock;
				}
			}
			close(fd);
			if (!port && (n = strtol(serv, &t, 0)) && t > serv && !*t)
				port = n;
			else if (geteuid())
				port = CS_NORMAL;
			else
				port = CS_RESERVED;
			if ((fd = csbind(state, type, 0L, port, 0L)) >= 0)
			{
				*state->control = CS_MNT_STREAM;
				remove(path);
				if (pathsetlink(cspath(state, fd, 0), path))
				{
					messagef((state->id, NiL, -1, "open: %s: %s: link error", cspath(state, fd, 0), path));
					close(fd);
					fd = -1;
				}
			}
		unblock:
			*state->control = CS_MNT_LOCK;
			remove(path);
			sigcritical(0);
			*state->control = CS_MNT_STREAM;
			if (fd < 0)
				return -1;
		}
		else if (fd < 0 && ((op & CS_OPEN_TEST) || initiate(state, user, opath, tmp, serv) || (fd = reopen(state, path)) < 0))
		{
			messagef((state->id, NiL, -1, "open: %s: %s: reopen/initiate error", state->path, path));
			return -1;
		}
		else if (!(op & CS_OPEN_AGENT))
		{
			*state->control = CS_MNT_AUTH;
			n = csauth(state, fd, path, arg);
			*state->control = CS_MNT_STREAM;
			if (n)
			{
				close(fd);
				messagef((state->id, NiL, -1, "open: %s: %s: authentication error", state->path, path));
				return -1;
			}
		}
	}

	/*
	 * fd is open at this point
	 * make sure its not a bogus mount
	 */

	if (mode != (S_IRWXU|S_IRWXG|S_IRWXO))
	{
		*state->control = 0;
		n = stat(path, &st);
		*state->control = CS_MNT_STREAM;
		if (n)
		{
			messagef((state->id, NiL, -1, "open: %s: %s: stat error", state->path, path));
			close(fd);
			return -1;
		}
		if (uid >= 0 && st.st_uid != uid || gid >= 0 && st.st_gid != gid)
		{
			close(fd);
			errno = EPERM;
			messagef((state->id, NiL, -1, "open: %s: %s: uid/gid error", state->path, path));
			return -1;
		}
	}
	return fd;
 bad:
	if (nfd >= 0)
		close(nfd);
	return -1;
}
Esempio n. 29
0
int apply_iptables(const char *table, const char *conf, bool noflush)
{
	int pipefd_in[2];
	int pipefd_out[2];
	pid_t child_pid;
	int error = 0;

	child_pid = fork_with_pipes(pipefd_in, pipefd_out);
	if (child_pid < 0) {
		return error;
	}

	if (child_pid == 0) {
		/* child */
		close(pipefd_in[1]);
		close(pipefd_out[0]);

		if (dup2(pipefd_in[0], STDIN_FILENO) == -1 ||
		    dup2(pipefd_out[1], STDOUT_FILENO) == -1 ||
		    dup2(pipefd_out[1], STDERR_FILENO) == -1) {
			fprintf(stderr, "%s\n", strerror(errno));
			exit(1);
		}
		close(pipefd_in[0]);
		close(pipefd_out[1]);

		if (noflush) {
			execl(IPTABLES_RESTORE, "iptables-restore", "-T", table, "-n", NULL);
		}
		else {
			execl(IPTABLES_RESTORE, "iptables-restore", "-T", table, NULL);
		}

		/* an error occured */
		fprintf(stderr, "%s\n", strerror(errno));
		exit(1);
	}
	else {
		/* parent */
		int status;
		pid_t ret;
		char *buffer = NULL;
		size_t buffer_size = 0;
		ssize_t line_size;
		FILE *output = fdopen(pipefd_out[0], "r");
		if (!output) {
			messagef(HAKA_LOG_ERROR, MODULE_NAME, "iptables-restore: %s", errno_error(errno));
			return errno;
		}

		close(pipefd_in[0]);
		close(pipefd_out[1]);

		status = write(pipefd_in[1], conf, strlen(conf));
		error = errno;
		close(pipefd_in[1]);

		if (status < 0) {
			fclose(output);
			return error;
		}

		while ((line_size = getline(&buffer, &buffer_size, output)) >= 0) {
			if (line_size > 1) {
				buffer[line_size-1] = '\0';
				messagef(HAKA_LOG_INFO, MODULE_NAME, "iptables-restore: %s", buffer);
			}
		}

		free(buffer);
		fclose(output);

		/* wait for the child to finish */
		do {
			ret = waitpid(child_pid, &status, 0);
			if (ret == -1) {
				return errno;
			}
		}
		while (!WIFEXITED(status) && !WIFSIGNALED(status));

		return WEXITSTATUS(status);
	}
}
Esempio n. 30
0
static int
doattach(register Cs_t* state, const char* path, int op, int mode, char* user, char* opath, char* tmp, char* serv, char*b)
{
	register int	n;
	int		fd;
	char*		s;

#if CS_LIB_STREAM || CS_LIB_V10

	int		fds[2];
	struct stat	st;

	if (op & CS_OPEN_CREATE)
	{
		n = errno;
		if (chmod(path, mode))
		{
			remove(path);
			if ((fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, mode)) < 0)
			{
				messagef((state->id, NiL, -1, "open: %s: %s: creat %o error", state->path, path, mode));
				return -1;
			}
			close(fd);
			chmod(path, mode);
		}
		errno = n;
		if (pipe(fds))
		{
			messagef((state->id, NiL, -1, "open: %s: pipe error", state->path, path));
			return -1;
		}

#if CS_LIB_V10

		if ((n = ioctl(fds[1], FIOPUSHLD, &conn_ld)) || fmount(3, fds[1], path, 0))

#else

		if ((n = ioctl(fds[1], I_PUSH, "connld")) || fattach(fds[1], path))

#endif

		{
			messagef((state->id, NiL, -1, "open: %s: %s: %s error", state->path, path, n ? "connld" : "fattach"));
			close(fds[0]);
			close(fds[1]);
			errno = ENXIO;
			return -1;
		}
		close(fds[1]);
		fd = fds[0];
	}
	else
		for (;;)
		{
			if ((fd = open(path, O_RDWR)) >= 0)
			{
				if (!fstat(fd, &st) && !S_ISREG(st.st_mode))
					break;
				close(fd);
				remove(path);
			}
			else if ((op & CS_OPEN_TEST) || errno == EACCES)
			{
				messagef((state->id, NiL, -1, "open: %s: %s: open error", state->path, path));
				return -1;
			}
			if (initiate(state, user, opath, tmp, serv))
			{
				messagef((state->id, NiL, -1, "open: %s: %s: service initiate error", state->path, path));
				return -1;
			}
			op = CS_OPEN_TEST;
		}

#else

#if CS_LIB_SOCKET_UN

	int			pid;
	int			namlen;
	char			c;
	struct sockaddr_un	nam;

	messagef((state->id, NiL, -8, "%s:%d state.path=`%s' state.mount=`%s' path=`%s' opath=`%s' user=`%s' serv=`%s'", __FILE__, __LINE__, state->path, state->mount, path, opath, user, serv));
	nam.sun_family = AF_UNIX;
	strcpy(nam.sun_path, path);
	namlen = sizeof(nam.sun_family) + strlen(path) + 1;
	for (n = 0;; n++)
	{
		if (n >= 10)
		{
			errno = ENXIO;
		badcon:
			close(fd);
			return -1;
		}
		if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
		{
			messagef((state->id, NiL, -1, "open: %s: %s: AF_UNIX socket error", state->path, path));
			return -1;
		}
		if (!connect(fd, (struct sockaddr*)&nam, namlen))
		{
			if (op & CS_OPEN_CREATE)
			{
				errno = EEXIST;
				goto badcon;
			}
#if CS_LIB_SOCKET_RIGHTS
			if (read(fd, &c, 1) == 1 && !cssend(state, fd, NiL, 0))
				break;
#else
			break;
#endif
		}
		else
		{
			messagef((state->id, NiL, -1, "open: %s: %s: connect error", state->path, path));
			if (errno == EACCES)
				goto badcon;
			else if (errno == EADDRNOTAVAIL || errno == ECONNREFUSED)
			{
				c = 0;
				for (;;)
				{
					*b = CS_MNT_PROCESS;
					pid = pathgetlink(path, state->temp, sizeof(state->temp));
					*b = CS_MNT_STREAM;
					if (pid > 0 || ++c >= 5)
						break;
					sleep(1);
				}
				if (pid > 0 && (s = strrchr(state->temp, '/')) && (pid = strtol(s + 1, NiL, 0)) > 0)
				{
					if (!kill(pid, 0) || errno != ESRCH)
					{
						if (op & CS_OPEN_CREATE)
						{
							errno = EEXIST;
							goto badcon;
						}
						close(fd);
						if (n)
							sleep(1);
						continue;
					}
					*b = CS_MNT_PROCESS;
					remove(path);
					*b = CS_MNT_STREAM;
				}
			}
		}
		close(fd);
		errno = ENOENT;
		if (op & CS_OPEN_CREATE)
		{
			if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
			{
				messagef((state->id, NiL, -1, "open: %s: %s: AF_UNIX socket error", state->path, path));
				return -1;
			}
			if (!bind(fd, (struct sockaddr*)&nam, namlen))
			{
				chmod(path, mode);
				if (listen(fd, 32))
				{
					messagef((state->id, NiL, -1, "open: %s: %s: listen error", state->path, path));
					n = errno;
					remove(path);
					errno = n;
					goto badcon;
				}
				break;
			}
			else
				messagef((state->id, NiL, -1, "open: %s: %s: bind error", state->path, path));
			if (errno != EADDRINUSE || n && remove(path) && errno != ENOENT)
				goto badcon;
			close(fd);
		}
		else if (op & CS_OPEN_TEST)
			return -1;
		else if (!n && initiate(state, user, opath, tmp, serv))
		{
			messagef((state->id, NiL, -1, "open: %s: %s: service initiate error", state->path, path));
			return -1;
		}
		else
			sleep(2);
	}

#else

	errno = (op & CS_OPEN_CREATE) ? ENXIO : ENOENT;
	messagef((state->id, NiL, -1, "open: %s: %s: not supported", state->path, path));
	fd = -1;

#endif

#endif

#if CS_LIB_SOCKET_UN || CS_LIB_STREAM || CS_LIB_V10

	touch(path, (time_t)0, (time_t)0, 0);
	strcpy(state->path, path);

#endif

	return fd;
}