Beispiel #1
0
int main(int ac, char **av)
{
	if (!av[1])
		printf("need config file\n"), exit(1);
	if (parse_config_file(av[1]) < 0)
		printf("cannot parse config file\n"), exit(1);
	char *type;
	char *header;
	char *name;
	int n;
	while (scanf("%as %as %as", &type, &header, &name) == 3) {
		switch (type[0]) {
		case 'n':
			if (config_number(header, name, "%d", &n) < 0)
				printf("Cannot parse number %s %s\n", header, name);
			else
				printf("res %d\n", n);
			break;
		case 's':
			printf("res %s\n", config_string(header, name));
			break;
		case 'b':
			printf("res %d\n", config_bool(header, name));
			break;
		default:
			printf("unknown type %s\n", type);
			break;
		}
		free(type);
		free(header);
		free(name);
	}
	return 0;
}
Beispiel #2
0
static BOOL STDCALL
_main_console_handler(DWORD control_type) {
	const char* control_name = "UNKNOWN";
	bool post_terminate = false;
	bool handled = true;

	switch (control_type) {
	case CTRL_C_EVENT:         control_name = "CTRL_C"; post_terminate = true; break;
	case CTRL_BREAK_EVENT:     control_name = "CTRL_BREAK"; break;
	case CTRL_CLOSE_EVENT:     control_name = "CTRL_CLOSE"; post_terminate = true; break;
	case CTRL_LOGOFF_EVENT:    control_name = "CTRL_LOGOFF";
		post_terminate = !config_bool(HASH_APPLICATION, HASH_DAEMON); break;
	case CTRL_SHUTDOWN_EVENT:  control_name = "CTRL_SHUTDOWN"; post_terminate = true; break;
	default:                   handled = false; break;
	}
	log_infof(0, STRING_CONST("Caught console control: %s (%d)"), control_name, control_type);
	if (post_terminate) {
		/*lint -e{970} */
		unsigned long level = 0, flags = 0;

		system_post_event(FOUNDATIONEVENT_TERMINATE);

		GetProcessShutdownParameters(&level, &flags);
		SetProcessShutdownParameters(level, SHUTDOWN_NORETRY);

		thread_sleep(1000);
	}
	return handled;
}
static int config_bool(snd_config_t *n, int doit)
{
	const char *str;
	long val;
	long long lval;

	switch (snd_config_get_type(n)) {
	case SND_CONFIG_TYPE_INTEGER:
		snd_config_get_integer(n, &val);
		if (val < 0 || val > 1)
			return -1;
		return val;
	case SND_CONFIG_TYPE_INTEGER64:
		snd_config_get_integer64(n, &lval);
		if (lval < 0 || lval > 1)
			return -1;
		return (int) lval;
	case SND_CONFIG_TYPE_STRING:
		snd_config_get_string(n, &str);
		break;
	case SND_CONFIG_TYPE_COMPOUND:
		if (!force_restore || !doit)
			return -1;
		n = snd_config_iterator_entry(snd_config_iterator_first(n));
		return config_bool(n, doit);
	default:
		return -1;
	}
	if (strcmp(str, "on") == 0 || strcmp(str, "true") == 0)
		return 1;
	if (strcmp(str, "off") == 0 || strcmp(str, "false") == 0)
		return 0;
	return -1;
}
Beispiel #4
0
static void client_srv_passive(char *arg)
{
	int h1, h2, h3, h4, p1, p2;
	u_int32_t addr, ladr;
	u_int16_t port;
	int       incr;

	if (arg == NULL)		/* Basic sanity check	*/
		return;

	/*
	** Read the port. According to RFC 1123, 4.1.2.6,
	** we have to scan the string for the first digit.
	*/
	while (*arg < '0' || *arg > '9')
		arg++;
	if (sscanf(arg, "%d,%d,%d,%d,%d,%d",
			&h1, &h2, &h3, &h4, &p1, &p2) != 6) {
		syslog_error("bad PASV 277 response from server for %s",
						ctx.cli_ctrl->peer);
		client_respond(425, NULL, "Can't open data connection");
		client_data_reset(MOD_RESET);
		ctx.expect = EXP_IDLE;
		return;
	}
	addr = (u_int32_t) ((h1 << 24) + (h2 << 16) + (h3 << 8) + h4);
	port = (u_int16_t) ((p1 <<  8) +  p2);
	syslog_write(T_DBG, "got SRV-PASV %s:%d for %s:%d",
	                    socket_addr2str(addr), port,
	                    ctx.cli_ctrl->peer, ctx.cli_ctrl->port);

	/*
	** should we bind a rand(port-range) or increment?
	*/
	incr = !config_bool(NULL,"SockBindRand", 0);

	/*
	** Open a connection to the server at the given port
	*/
	ladr = socket_sck2addr(ctx.srv_ctrl->sock, LOC_END, NULL);
	if (socket_d_connect(addr, port, ladr, ctx.srv_lrng,
			ctx.srv_urng, &(ctx.srv_data),
			"Srv-Data", incr) == 0)
	{
		syslog_error("can't connect Srv-Data for %s",
						ctx.cli_ctrl->peer);
		client_respond(425, NULL, "Can't open data connection");
		client_data_reset(MOD_RESET);
		ctx.expect = EXP_IDLE;
		return;
	}

	/*
	** Finally send the original command from the client
	*/
	client_xfer_fireup();
}
Beispiel #5
0
/* Use getopt_long struct option array to process config file */
void config_options(struct option *opts, int (*func)(int))
{
	for (; opts->name; opts++) {
		if (!opts->has_arg) {
			if (config_bool("global", opts->name) != 1)
				continue;
			if (opts->flag) {
				*(opts->flag) = opts->val;
				continue;
			}
		} else {
			char *s = config_string("global", opts->name);
			if (s == NULL)
				continue;
			optarg = s;
		}
		func(opts->val);
	}
}
Beispiel #6
0
int
main(__unused int argc, char *argv[])
{
	char pkgpath[MAXPATHLEN];
	bool yes = false;

	snprintf(pkgpath, MAXPATHLEN, "%s/sbin/pkg",
	    getenv("LOCALBASE") ? getenv("LOCALBASE") : _LOCALBASE);

	if (access(pkgpath, X_OK) == -1) {
		/* 
		 * To allow 'pkg -N' to be used as a reliable test for whether
		 * a system is configured to use pkg, don't bootstrap pkg
		 * when that argument is given as argv[1].
		 */
		if (argv[1] != NULL && strcmp(argv[1], "-N") == 0)
			errx(EXIT_FAILURE, "pkg is not installed");

		/*
		 * Do not ask for confirmation if either of stdin or stdout is
		 * not tty. Check the environment to see if user has answer
		 * tucked in there already.
		 */
		config_init();
		config_bool(ASSUME_ALWAYS_YES, &yes);
		if (!yes) {
			printf("%s", confirmation_message);
			if (!isatty(fileno(stdin)))
				exit(EXIT_FAILURE);

			if (pkg_query_yes_no() == 0)
				exit(EXIT_FAILURE);
		}
		if (bootstrap_pkg() != 0)
			exit(EXIT_FAILURE);
		config_finish();
	}

	execv(pkgpath, argv);

	/* NOT REACHED */
	return (EXIT_FAILURE);
}
Beispiel #7
0
int config_trigger(const char *header, const char *base, struct bucket_conf *bc)
{
	char *s;
	char *name;
	int n;

	asprintf(&name, "%s-threshold", base);
	s = config_string(header, name);
	if (s) {
		if (bucket_conf_init(bc, s) < 0) {
			unparseable("trigger", header, name);
			return -1;
		}
	}
	free(name);

	asprintf(&name, "%s-trigger", base);
	s = config_string(header, name);
	if (s) {
		/* no $PATH */
		if (trigger_check(s) != 0) {
			SYSERRprintf("Trigger `%s' not executable\n", s);
			exit(1);
		}
		bc->trigger = s;
	}
	free(name);

	bc->log = 0;
	asprintf(&name, "%s-log", base);
	n = config_bool(header, name);
	if (n >= 0)
		bc->log = n;
	free(name);

	return 0;
}
Beispiel #8
0
static void client_xfer_fireup(void)
{
	u_int32_t ladr = INADDR_ANY;
	int       incr;

	/*
	** should we bind a rand(port-range) or increment?
	*/
	incr = !config_bool(NULL,"SockBindRand", 0);

	/*
	** If appropriate, connect to the client's data port
	*/
	if (ctx.cli_mode == MOD_ACT_FTP) {
		/*
		** TransProxy mode: check if we can use our real
		** ip instead of the server's one as our local ip,
		** we pre-bind the socket/ports to before connect.
		*/
		if(config_bool(NULL, "AllowTransProxy", 0)) {
			ladr = config_addr(NULL, "Listen",
					(u_int32_t)INADDR_ANY);
		}
		if(INADDR_ANY == ladr) {
			ladr = socket_sck2addr(ctx.cli_ctrl->sock,
						LOC_END, NULL);
		}
		if (socket_d_connect(ctx.cli_addr, ctx.cli_port,
				ladr, ctx.act_lrng, ctx.act_urng,
				&(ctx.cli_data), "Cli-Data", incr) == 0)
		{
			syslog_error("can't connect Cli-Data for %s",
						ctx.cli_ctrl->peer);
			client_respond(425, NULL,
					"Can't open data connection");
			client_data_reset(MOD_RESET);
			ctx.expect = EXP_IDLE;
			return;
		}
	}

	/*
	** Send the original command from the client
	*/
	if (ctx.xfer_arg[0] != '\0') {
		socket_printf(ctx.srv_ctrl, "%s %s\r\n",
				ctx.xfer_cmd, ctx.xfer_arg);
		syslog_write(T_INF, "'%s %s' sent for %s",
			ctx.xfer_cmd, ctx.xfer_arg, ctx.cli_ctrl->peer);
	} else {
		socket_printf(ctx.srv_ctrl, "%s\r\n", ctx.xfer_cmd);
		syslog_write(T_INF, "'%s' sent for %s",
			ctx.xfer_cmd, ctx.cli_ctrl->peer);
	}

	/*
	** Prepare the handling and statistics buffers
	*/
	memset(ctx.xfer_rep, 0, sizeof(ctx.xfer_rep));
	ctx.xfer_beg = time(NULL);

	ctx.expect = EXP_XFER;		/* Expect 226 complete	*/
}
Beispiel #9
0
static void client_srv_ctrl_read(char *str)
{
	int code, c1, c2, c3;
	char *arg;

	if (str == NULL)		/* Basic sanity check	*/
		return;

	syslog_write(T_DBG, "from Server-PI (%d): '%.512s'",
	             ctx.srv_ctrl->sock, str);
#if defined(COMPILE_DEBUG)
	debug(1, "from Server-PI (%d): '%.512s'",
					ctx.srv_ctrl->sock, str);
#endif

	/*
	** Intermediate responses can usually be forwarded
	*/
	if (*str < '2' || *str > '5' || str[3] != ' ') {
		/*
		** If this is the destination host's
		** welcome message let's discard it.
		*/
		if (ctx.expect == EXP_CONN)
			return;
		if (ctx.expect == EXP_USER && UAUTH_NONE != ctx.auth_mode)
			return;

#if defined(COMPILE_DEBUG)
		debug(2, "'%.4s'... forwarded to %s %d=%s", str,
			ctx.cli_ctrl->ctyp, ctx.cli_ctrl->sock,
			ctx.cli_ctrl->peer);
#endif
		socket_printf(ctx.cli_ctrl, "%s\r\n", str);
		return;
	}

	/*
	** Consider only valid final response codes
	*/
	if ((code = atoi(str)) < 200 || code > 599) {
		syslog_error("bad response %d from server for %s",
					code, ctx.srv_ctrl->peer);
		return;
	}
	c1 =  code / 100;
	c2 = (code % 100) / 10;
	c3 =  code % 10;
	for (arg = str + 3; *arg == ' '; arg++)
		;

	/*
	** We have a response code, go see what we expected
	*/
	switch (ctx.expect) {
		case EXP_CONN:
			/*
			** Waiting for a 220 Welcome
			*/
			if (c1 == 2) {
				socket_printf(ctx.srv_ctrl,
				              "USER %s\r\n",
				              ctx.username);
				ctx.expect = EXP_USER;
			} else {
				if(UAUTH_NONE != ctx.auth_mode) {
					client_respond(530, NULL,
					               "Login incorrect");
				} else {
					socket_printf(ctx.cli_ctrl,
					              "%s\r\n", str);
				}
				ctx.expect = EXP_IDLE;
				ctx.cli_ctrl->kill = 1;
			}
			break;

		case EXP_USER:
			/*
			** Only the following codes are useful:
			**	230=logged in,
			**	331=need password,
			**	332=need password+account
			*/
			if(UAUTH_NONE != ctx.auth_mode) {
				/*
				** logged in, NO password needed
				*/
				if(c1 == 2 && c2 == 3) {
					client_respond(230, NULL,
					               "User logged in, proceed.");
					ctx.expect = EXP_IDLE;
					break;
				} else
				/*
				** OK, password (+account) needed
				*/
				if(c1 == 3 && c2 == 3) {
					if(ctx.userpass) {
						socket_printf(ctx.srv_ctrl,
						              "PASS %s\r\n",
						              ctx.userpass);
						misc_free(FL, ctx.userpass);
						ctx.userpass = NULL;
					} else {
						socket_printf(ctx.srv_ctrl,
						              "PASS \r\n");
					}
					ctx.expect = EXP_PTHR;
					break;
				}
			}
			/*
			** pass server response through to client
			*/
			socket_printf(ctx.cli_ctrl, "%s\r\n", str);
			if (c1 != 2 && c1 != 3) {
				ctx.cli_ctrl->kill = 1;
			}
			ctx.expect = EXP_IDLE;
			break;

		case EXP_ABOR:
			if (c1 == 2) {
				client_data_reset(MOD_RESET);
				ctx.expect = EXP_IDLE;
			}
			break;

		case EXP_PASV:
			if (code == 227 && *arg != '\0') {
				client_srv_passive(arg);
			} else {
				socket_printf(ctx.cli_ctrl,
						"%s\r\n", str);
				client_data_reset(MOD_RESET);
				ctx.expect = EXP_IDLE;
			}
			break;

		case EXP_PORT:
			if (code == 200) {
				client_xfer_fireup();
			} else {
				socket_printf(ctx.cli_ctrl,
						"%s\r\n", str);
				client_data_reset(MOD_RESET);
				ctx.expect = EXP_IDLE;
			}
			break;

		case EXP_XFER:
			/*
			** Distinguish between success and failure
			*/
			if (c1 == 2) {
				misc_strncpy(ctx.xfer_rep, str,
					sizeof(ctx.xfer_rep));
			} else {
				socket_printf(ctx.cli_ctrl,
						"%s\r\n", str);
				if(config_bool(NULL,"FailResetsPasv", 0)) {
					client_data_reset(MOD_RESET);
				} else {
					client_data_reset(ctx.cli_mode);
				}
			}
			ctx.expect = EXP_IDLE;
			break;

		case EXP_PTHR:
			socket_printf(ctx.cli_ctrl, "%s\r\n", str);
			ctx.expect = EXP_IDLE;
			break;

		case EXP_IDLE:
			socket_printf(ctx.cli_ctrl, "%s\r\n", str);
			if (code == 421) {
				syslog_write(T_WRN,
					"server closed connection "
					"for %s", ctx.cli_ctrl->peer);
				ctx.cli_ctrl->kill = 1;
			} else {
				syslog_write(T_WRN,
					"bogus '%.512s' from "
					"Server-PI for %s",
					ctx.cli_ctrl->peer, str);
			}
			break;
	}
}
Beispiel #10
0
static int client_setup_file(CONTEXT *ctx, char *who)
{
	char      *p;
	u_int16_t  l, u;

	/*
	** little bit sanity check
	*/
	if( !(ctx && who && *who)) {
		return -1;
	}

	/*
	** Inform the auditor that we are using the config file
	*/
	syslog_write(U_INF, "reading data for '%s' from cfg-file", who);

	/*
	** Evaluate DestinationAddress, except we have magic_addr
	*/
	if (INADDR_ANY != ctx->magic_addr) {
		ctx->srv_addr = ctx->magic_addr;
	} else {
		ctx->srv_addr = config_addr(who, "DestinationAddress",
		                                 INADDR_ANY);
#if defined(COMPILE_DEBUG)
		debug(2, "file DestAddr for %s: '%s'",
		      ctx->cli_ctrl->peer, socket_addr2str(ctx->srv_addr));
#endif
	}

	/*
	** Evaluate DestinationPort, except we have magic_port
	*/
	if (INPORT_ANY != ctx->magic_port) {
		ctx->srv_port = ctx->magic_port;
	} else {
		ctx->srv_port = config_port(who, "DestinationPort",
		                                 IPPORT_FTP);
#if defined(COMPILE_DEBUG)
		debug(2, "file DestPort for %s: %d",
		      ctx->cli_ctrl->peer, (int) ctx->srv_port);
#endif
	}

	/*
	** Evaluate the destination transfer mode
	*/
	p = config_str(who, "DestinationTransferMode", "client");
	if(0 == strcasecmp(p, "active")) {
		ctx->srv_mode = MOD_ACT_FTP;
	} else
	if(0 == strcasecmp(p, "passive")) {
		ctx->srv_mode = MOD_PAS_FTP;
	} else
	if(0 == strcasecmp(p, "client")) {
		ctx->srv_mode = MOD_CLI_FTP;
	} else {
		syslog_error("can't eval DestMode for %s",
		             ctx->cli_ctrl->peer);
		return -1;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestMode for %s: %s", ctx->cli_ctrl->peer, p);
#endif

	/*
	** Evaluate min/max destination port range
	*/
	l = config_port(who, "DestinationMinPort", INPORT_ANY);
	u = config_port(who, "DestinationMaxPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->srv_lrng = l;
		ctx->srv_urng = u;
	} else {
		ctx->srv_lrng = INPORT_ANY;
		ctx->srv_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->srv_lrng, ctx->srv_urng);
#endif

	/*
	** Evaluate min/max active port range
	*/
	l = config_port(who, "ActiveMinDataPort", INPORT_ANY);
	u = config_port(who, "ActiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->act_lrng = l;
		ctx->act_urng = u;
	} else {
		/* do not try to bind a port < 1024 if running as UID != 0 */
		if(0 == getuid()) {
			ctx->act_lrng = (IPPORT_FTP - 1);
			ctx->act_urng = (IPPORT_FTP - 1);
		} else {
			ctx->act_lrng = INPORT_ANY;
			ctx->act_urng = INPORT_ANY;
		}
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file ActiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->act_lrng, ctx->act_urng);
#endif

	/*
	** Evaluate min/max passive port range
	*/
	l = config_port(who, "PassiveMinDataPort", INPORT_ANY);
	u = config_port(who, "PassiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->pas_lrng = l;
		ctx->pas_urng = u;
	} else {
		ctx->pas_lrng = INPORT_ANY;
		ctx->pas_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file PassiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->pas_lrng, ctx->pas_urng);
#endif

	/*
	** Setup other configuration options
	*/
	ctx->same_adr = config_bool(who, "SameAddress", 1);
	ctx->timeout  = config_int (who, "TimeOut",   900);
#if defined(COMPILE_DEBUG)
	debug(2, "file SameAddress for %s: %s", ctx->cli_ctrl->peer,
	                                        ctx->same_adr ? "yes" : "no");
	debug(2, "file TimeOut for %s: %d", ctx->cli_ctrl->peer, ctx->timeout);
#endif

	/*
	** Adjust the allow/deny flags for the commands
	*/
	p = config_str(who, "ValidCommands", NULL);
	cmds_set_allow(p);

	return 0;
}
Beispiel #11
0
void client_run(void)
{
	int  sock, need, diff;
	char str[MAX_PATH_SIZE * 2];
	char *p, *q;
	FILE *fp;
	BUF  *buf;

	/*
	** Setup client signal handling (mostly graceful exit)
	*/
	signal(SIGINT,  client_signal);
	signal(SIGTERM, client_signal);
	signal(SIGQUIT, client_signal);
	signal(SIGHUP,  client_signal);
	signal(SIGCHLD, SIG_IGN);
	signal(SIGUSR1, SIG_IGN);

	/*
	** Prepare our general client context
	*/
	memset(&ctx, 0, sizeof(ctx));
	ctx.sess_beg = time(NULL);
	ctx.cli_mode = MOD_ACT_FTP;
	ctx.expect   = EXP_IDLE;
	ctx.timeout  = config_int(NULL, "TimeOut", 900);

	sock = fileno(stdin);		/* "recover" our socket */

	/*
	** Check whether a DenyMessage file exists. This
	** indicates that we are currently not willing
	** to serve any clients.
	*/
	p = config_str(NULL, "DenyMessage", NULL);
	if (p != NULL && (fp = fopen(p, "r")) != NULL) {
		while (fgets(str, sizeof(str) - 4, fp) != NULL) {
			p = socket_msgline(str);
			if ((q = strchr(p, '\n')) != NULL)
				strcpy(q, "\r\n");
			else
				strcat(p, "\r\n");
			send(sock, "421-", 4, 0);
			send(sock, p, strlen(p), 0);
		}
		fclose(fp);
		if ((p = config_str(NULL, "DenyString", NULL)) != NULL)
			p = socket_msgline(p);
		else
			p = "Service not available";
		send(sock, "421 ", 4, 0);
		send(sock, p, strlen(p), 0);
		send(sock, ".\r\n", 3, 0);
		p = socket_addr2str(socket_sck2addr(sock, REM_END, NULL));
		close(sock);
		syslog_write(U_ERR, "reject: '%s' (DenyMessage)", p);
		exit(EXIT_SUCCESS);
	}

	/*
	** Create a High Level Socket for the client's User-PI
	*/
	if ((ctx.cli_ctrl = socket_init(sock)) == NULL)
		misc_die(FL, "client_run: ?cli_ctrl?");
	ctx.cli_ctrl->ctyp = "Cli-Ctrl";

	/*
	** Announce the connection request
	*/
	syslog_write(U_INF, "connect from %s", ctx.cli_ctrl->peer);

	/*
	** Display the welcome message (invite the user to login)
	*/
	if ((p = config_str(NULL, "WelcomeString", NULL)) == NULL)
		p = "%h FTP server (Version %v - %b) ready";
	misc_strncpy(str, socket_msgline(p), sizeof(str));
	client_respond(220,
		config_str(NULL, "WelcomeMessage", NULL), str);

	/*
	** Enter the client mainloop
	*/
	while (close_flag == 0) {
		/*
		** We need to go into select() only
		** if all input has been processed
		**   or
		** we wait for more data to get a line
		** complete (partially sent, no EOL).
		**
		** (data buffers are never splited)
		*/
		need = 1;
		if (ctx.cli_ctrl && ctx.cli_ctrl->rbuf)
			need = 0;
		if (ctx.srv_ctrl && ctx.srv_ctrl->rbuf)
			need = 0;
		if((ctx.cli_ctrl && ctx.cli_ctrl->more>0) ||
		   (ctx.srv_ctrl && ctx.srv_ctrl->more>0))
			need = 1;

		/*
		** use higher priority to writes;
		** read only if nothing to write...
		*/
		if(ctx.srv_data && ctx.cli_data) {
			if(ctx.srv_data->wbuf) {
				ctx.cli_data->more = -1;
			} else {
				ctx.cli_data->more = 0;
			}
			if(ctx.cli_data->wbuf) {
				ctx.srv_data->more = -1;
			} else {
				ctx.srv_data->more = 0;
			}
		}

		if (need != 0) {
			if (socket_exec(ctx.timeout, &close_flag) <= 0)
				break;	/* Timed out or worse */
		}
#if defined(COMPILE_DEBUG)
		debug(4, "client-loop ...");
#endif

		/*
		** Check if any zombie sockets can be removed
		*/
		if (ctx.cli_ctrl != NULL && ctx.cli_ctrl->sock == -1)
			close_flag = 1;		/* Oops, forget it ... */

		if (ctx.srv_ctrl != NULL && ctx.srv_ctrl->sock == -1) {
#if defined(COMPILE_DEBUG)
			debug(3, "about to destroy Srv-Ctrl");
#endif
			/*
			** If we have any open data connections,
			** make really sure they don't survive.
			*/
			if (ctx.cli_data != NULL)
				ctx.cli_data->kill = 1;
			if (ctx.srv_data != NULL)
				ctx.srv_data->kill = 1;

			/*
			** Our client should be informed
			*/
			if (ctx.cli_ctrl->kill == 0) {
				client_respond(421, NULL,
					"Service not available, "
					"closing control connection");
			}

			/*
			** Don't forget to remove the dead socket
			*/
			socket_kill(ctx.srv_ctrl);
			ctx.srv_ctrl = NULL;
		}

		if (ctx.cli_data != NULL && ctx.cli_data->sock == -1) {
#if defined(COMPILE_DEBUG)
			debug(3, "about to destroy Cli-Data");
#endif
			/*
			** If we have an outstanding server reply
			** (e.g. 226 Transfer complete), send it.
			*/
			if (ctx.xfer_rep[0] != '\0') {
				socket_printf(ctx.cli_ctrl,
					"%s\r\n", ctx.xfer_rep);
				memset(ctx.xfer_rep, 0,
					sizeof(ctx.xfer_rep));
			} else {
				if(ctx.expect == EXP_XFER)
					ctx.expect = EXP_PTHR;
			}

			/*
			** Good time for statistics and data reset
			*/
			if (ctx.xfer_beg == 0)
				ctx.xfer_beg = time(NULL);
			diff = (int) (time(NULL) - ctx.xfer_beg);
			if (diff < 1)
				diff = 1;

			/*
			** print our current statistic
			*/
			syslog_write(U_INF,
				"Transfer for %s %s: %s '%s' %s %u/%d byte/sec",
				ctx.cli_ctrl->peer,
				ctx.cli_data->ernr ?  "failed" : "completed",
				ctx.xfer_cmd, ctx.xfer_arg,
				ctx.cli_data->rcnt ? "sent" : "read",
				ctx.cli_data->rcnt ? ctx.cli_data->rcnt
				                   : ctx.cli_data->wcnt,
				diff);

			/*
			** update session statistics data
			*/
			if(ctx.cli_data->rcnt)
				ctx.xfer_rsec += diff;
			ctx.xfer_rcnt += ctx.cli_data->rcnt;
			if(ctx.cli_data->wcnt)
				ctx.xfer_wsec += diff;
			ctx.xfer_wcnt += ctx.cli_data->wcnt;

			/*
			** reset data transfer state
			*/
			client_data_reset(MOD_RESET);

			/*
			** Doom the corresponding server socket
			*/
			if (ctx.srv_data != NULL)
				ctx.srv_data->kill = 1;

			/*
			** Don't forget to remove the dead socket
			*/
			socket_kill(ctx.cli_data);
			ctx.cli_data = NULL;
		}

		if (ctx.srv_data != NULL && ctx.srv_data->sock == -1) {

#if defined(COMPILE_DEBUG)
			debug(3, "about to destroy Srv-Data");
#endif
			/*
			** Doom the corresponding client socket if an
			** error occured, FailResetsPasv=yes or we
			** expect other response than PASV (Netscape!)
			*/
			if(ctx.cli_data != NULL) {
				if(0 != ctx.srv_data->ernr) {
					ctx.cli_data->ernr = -1;
					ctx.cli_data->kill =  1;
				}
				if(config_bool(NULL,"FailResetsPasv", 0)) {
					ctx.cli_data->kill = 1;
				} else if(ctx.expect != EXP_PASV) {
					ctx.cli_data->kill = 1;
				}
			}

			/*
			** Don't forget to remove the dead socket
			*/
			socket_kill(ctx.srv_data);
			ctx.srv_data = NULL;
		}

		/*
		** Serve the control connections
		*/
		if (ctx.cli_ctrl != NULL && ctx.cli_ctrl->rbuf != NULL) {
			if (socket_gets(ctx.cli_ctrl,
					str, sizeof(str)) != NULL)
				client_cli_ctrl_read(str);
		}
		if (ctx.srv_ctrl != NULL && ctx.srv_ctrl->rbuf != NULL) {
			if (socket_gets(ctx.srv_ctrl,
					str, sizeof(str)) != NULL)
				client_srv_ctrl_read(str);
		}

		/*
		** Serve the data connections. This is a bit tricky,
		** since all we do is move the buffer pointers.
		*/
		if (ctx.cli_data != NULL && ctx.srv_data != NULL) {
			if (ctx.cli_data->rbuf != NULL) {
#if defined(COMPILE_DEBUG)
				debug(2, "Cli-Data -> Srv-Data");
#endif
				if (ctx.srv_data->wbuf == NULL) {
					ctx.srv_data->wbuf =
						ctx.cli_data->rbuf;
				} else {
					for (buf = ctx.srv_data->wbuf;
							buf && buf->next;
							buf = buf->next)
						;
					buf->next = ctx.cli_data->rbuf;
				}
				ctx.cli_data->rbuf = NULL;
			}
			if (ctx.srv_data->rbuf != NULL) {
#if defined(COMPILE_DEBUG)
				debug(2, "Srv-Data -> Cli-Data");
#endif
				if (ctx.cli_data->wbuf == NULL) {
					ctx.cli_data->wbuf =
						ctx.srv_data->rbuf;
				} else {
					for (buf = ctx.cli_data->wbuf;
							buf && buf->next;
							buf = buf->next)
						;
					buf->next = ctx.srv_data->rbuf;
				}
				ctx.srv_data->rbuf = NULL;
			}
		}
		/* at this point the main loop resumes ... */
	}

	/*
	** Display basic session statistics...
	**   in secs since session begin
	**   downloads / read (xfer-reads from server)
	**   uploads   / send (xfer-sends from server)
	*/
	syslog_write(U_INF, "closing connect from %s after %d secs - "
	                    "read %d/%d, sent %d/%d byte/sec",
	             ctx.cli_ctrl ? ctx.cli_ctrl->peer : "unknown peer",
	             time(NULL)-ctx.sess_beg,
	             ctx.xfer_wcnt, ctx.xfer_wsec,
	             ctx.xfer_rcnt, ctx.xfer_rsec);

	/*
	** Free allocated memory
	*/
	ctx.magic_auth = NULL;
	if (ctx.userauth != NULL) {
		misc_free(FL, ctx.userauth);
		ctx.userauth = NULL;
	}
	if (ctx.username != NULL) {
		misc_free(FL, ctx.username);
		ctx.username = NULL;
	}
	if(ctx.userpass != NULL) {
		misc_free(FL, ctx.userpass);
		ctx.userpass = NULL;
	}

#if defined(COMPILE_DEBUG)
	debug(1, "}}}}} %s client-exit", misc_getprog());
#endif
	exit(EXIT_SUCCESS);
}
Beispiel #12
0
void client_srv_open(void)
{
	struct sockaddr_in saddr;
	u_int16_t          lprt, lowrng, res;
	int                sock, incr, retry;

	/*
	** should we bind a rand(port-range) or increment?
	*/
	incr = !config_bool(NULL,"SockBindRand", 0);

	/*
	** mark socket invalid
	*/
	sock = -1;

	/*
	** Forward connection to destination
	*/
	retry = MAX_RETRIES;
	lprt  = ctx.srv_lrng;
	while(0 <= retry--) {
		/*
		** First of all, get a socket
		*/
		if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
			syslog_error("Srv-Ctrl: can't create socket for %s",
			             ctx.cli_ctrl->peer);
			exit(EXIT_FAILURE);
		}
		socket_opts(sock, SK_CONTROL);

		/*
		** check if we have to take care to a port range
		*/
		if( !(INPORT_ANY == ctx.srv_lrng &&
                      INPORT_ANY == ctx.srv_urng))
		{
			u_int32_t ladr = INADDR_ANY;

			/*
			** bind the socket, taking care of a given port range
			*/
			if(incr) {
				lowrng = lprt;
#if defined(COMPILE_DEBUG)
				debug(2, "Srv-Ctrl: "
				         "about to bind to %s:range(%d-%d)",
				         socket_addr2str(ladr),
				         lowrng, ctx.srv_urng);
#endif
				res = socket_d_bind(sock, ladr,
				       lowrng, ctx.srv_urng, incr);
			} else {
				lowrng = ctx.srv_lrng;
#if defined(COMPILE_DEBUG)
				debug(2, "Srv-Ctrl: "
				         "about to bind to %s:range(%d-%d)",
				         socket_addr2str(ladr),
				         lowrng, ctx.srv_urng);
#endif
				res = socket_d_bind(sock, ladr,
				           lowrng, ctx.srv_urng, incr);
			}

			if (INPORT_ANY == res) {
				/* nothing found? */
				close(sock);
				syslog_error("Srv-Ctrl: can't bind to"
				             " %s:%d for %s",
					     socket_addr2str(ladr),
					     (int)lprt, ctx.cli_ctrl->peer);
				exit(EXIT_FAILURE);
			} else {
				lprt = res;
			}
		} else lprt = INPORT_ANY;

		/*
		** Okay, now try the actual connect to the server
		*/
		memset(&saddr, 0, sizeof(saddr));
		saddr.sin_addr.s_addr = htonl(ctx.srv_addr);
		saddr.sin_family      = AF_INET;
		saddr.sin_port        = htons(ctx.srv_port);

		if (connect(sock, (struct sockaddr *)&saddr,
		            sizeof(saddr)) < 0)
		{
#if defined(COMPILE_DEBUG)
				debug(2, "Srv-Ctrl: connect failed with '%s'",
				      strerror(errno));
#endif
			close(sock);
			sock = -1;
			/* check if is makes sense to retry?
			** perhaps we only need an other
			** local port (EADDRNOTAVAIL) for
			** this destination?
			*/
			if( !(EINTR == errno ||
			      EAGAIN == errno ||
			      EADDRINUSE == errno ||
			      EADDRNOTAVAIL == errno))
			{
				/*
				** an other (real) error ocurred
				*/
				syslog_error("Srv-Ctrl: "
				             "can't connect %s:%d for %s",
				             socket_addr2str(ctx.srv_addr),
				             (int) ctx.srv_port,
				             ctx.cli_ctrl->peer);
				exit(EXIT_FAILURE);
			}
			if(incr && INPORT_ANY != lprt) {
				/* increment lower range if we use
				** increment mode and have a range
				*/
				if(lprt < ctx.srv_urng) {
					lprt++;
				} else {
				/*
				** no more ports in range we can try
				*/
				syslog_error("Srv-Ctrl: "
				             "can't connect %s:%d for %s",
				             socket_addr2str(ctx.srv_addr),
				             (int) ctx.srv_port,
				             ctx.cli_ctrl->peer);
				exit(EXIT_FAILURE);
				}
			}
		} else break;
	}

	/*
	** check if we have a valid, connected socket
	*/
	if(-1 == sock) {
		syslog_error("Srv-Ctrl: can't connect %s:%d for %s",
		             socket_addr2str(ctx.srv_addr),
		             (int) ctx.srv_port,
		             ctx.cli_ctrl->peer);
		exit(EXIT_FAILURE);
	}

	if ((ctx.srv_ctrl = socket_init(sock)) == NULL)
		misc_die(FL, "cmds_user: ?srv_ctrl?");
	ctx.srv_ctrl->ctyp = "Srv-Ctrl";

#if defined(COMPILE_DEBUG)
		debug(2, "Srv-Ctrl is %s:%d",
			ctx.srv_ctrl->peer, (int) ctx.srv_port);
#endif

	ctx.expect = EXP_CONN;		/* Expect Welcome	*/
}
Beispiel #13
0
int mem_config_line( AVP *av )
{
	MTYPE *mt;
	char *d;
	int t;

	if( !( d = strchr( av->att, '.' ) ) )
	{
		// just the singles
		if( attIs( "maxMb" ) || attIs( "maxSize" ) )
			ctl->mem->max_kb = 1024 * atoi( av->val );
		else if( attIs( "maxKb") )
			ctl->mem->max_kb = atoi( av->val );
		else if( attIs( "interval" ) || attIs( "msec" ) )
			ctl->mem->interval = atoi( av->val );
		else if( attIs( "hashSize" ) )
			ctl->mem->hashsize = atoi( av->val );
		else if( attIs( "stackSize" ) )
		{
			// gets converted to KB
			ctl->mem->stacksize = atoi( av->val );
			debug( "Stack size set to %d KB.", ctl->mem->stacksize );
		}
		else if( attIs( "gc" ) )
			ctl->mem->gc_enabled = config_bool( av );
		else if( attIs( "gcThresh" ) )
		{
			t = atoi( av->val );
			if( !t )
				t = DEFAULT_GC_THRESH;
			debug( "Garbage collection threshold set to %d stats intervals.", t );
			ctl->mem->gc_thresh = t;
		}
		else if( attIs( "gcGaugeThresh" ) )
		{
			t = atoi( av->val );
			if( !t )
				t = DEFAULT_GC_GG_THRESH;
			debug( "Gauge garbage collection threshold set to %d stats intervals.", t );
			ctl->mem->gc_gg_thresh = t;
		}
		else
			return -1;

		return 0;
	}

	*d++ = '\0';

	// after this, it's per-type control
	if( !strncasecmp( av->att, "hosts.", 6 ) )
		mt = ctl->mem->hosts;
	else if( !strncasecmp( av->att, "iobufs.", 7 ) )
		mt = ctl->mem->iobufs;
	else if( !strncasecmp( av->att, "points.", 7 ) )
		mt = ctl->mem->points;
	else if( !strncasecmp( av->att, "dhash.", 6 ) )
		mt = ctl->mem->dhash;
	else if( !strncasecmp( av->att, "iolist.", 7 ) )
		mt = ctl->mem->iolist;
	else if( !strncasecmp( av->att, "token.", 6 ) )
		mt = ctl->mem->token;
	else
		return -1;

	if( !strcasecmp( d, "block" ) )
	{
		mt->alloc_ct = (uint32_t) strtoul( av->val, NULL, 10 );
		debug( "Allocation block for %s set to %u", av->att, mt->alloc_ct );
	}
	else
		return -1;

	// done this way because GC might become a thing

	return 0;
}
Beispiel #14
0
static int client_setup_file(CONTEXT *ctx, char *who)
{
	char      *p;

	u_int16_t  l, u;

	/*
	** little bit sanity check
	*/
	if( !(ctx && who && *who)) {
		return -1;
	}

	/*
	** Inform the auditor that we are using the config file
	*/
	syslog_write(U_INF, "[ %s ] reading data for '%s' from cfg-file", ctx->cli_ctrl->peer, who);

	/*
	** Evaluate DestinationAddress, except we have magic_addr
	*/
	if (INADDR_ANY != ctx->magic_addr) {
		ctx->srv_addr = ctx->magic_addr;
	} else {
		ctx->srv_addr = config_addr(who, "DestinationAddress",
		                                 INADDR_ANY);
#if defined(COMPILE_DEBUG)
		debug(2, "[ %s ] file DestAddr for %s: '%s'", ctx->cli_ctrl->peer,
		      ctx->cli_ctrl->peer, socket_addr2str(ctx->srv_addr));
#endif
	}

	/*
	** Evaluate DestinationPort, except we have magic_port
	*/
	if (INPORT_ANY != ctx->magic_port) {
		ctx->srv_port = ctx->magic_port;
	} else {
		ctx->srv_port = config_port(who, "DestinationPort",
		                                 IPPORT_FTP);
#if defined(COMPILE_DEBUG)
		debug(2, "[ %s ] file DestPort for %s: %d", ctx->cli_ctrl->peer,
		      ctx->cli_ctrl->peer, (int) ctx->srv_port);
#endif
	}

	/*
	** Evaluate the destination transfer mode
	*/
	p = config_str(who, "DestinationTransferMode", "client");
	if(0 == strcasecmp(p, "active")) {
		ctx->srv_mode = MOD_ACT_FTP;
	} else
	if(0 == strcasecmp(p, "passive")) {
		ctx->srv_mode = MOD_PAS_FTP;
	} else
	if(0 == strcasecmp(p, "client")) {
		ctx->srv_mode = MOD_CLI_FTP;
	} else {
		syslog_error("can't eval DestMode for %s",
		             ctx->cli_ctrl->peer);
		return -1;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestMode for %s: %s", ctx->cli_ctrl->peer, p);
#endif

	/*
	** Evaluate min/max destination port range
	*/
	l = config_port(who, "DestinationMinPort", INPORT_ANY);
	u = config_port(who, "DestinationMaxPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->srv_lrng = l;
		ctx->srv_urng = u;
	} else {
		ctx->srv_lrng = INPORT_ANY;
		ctx->srv_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file DestRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->srv_lrng, ctx->srv_urng);
#endif

	/*
	** Evaluate min/max active port range
	*/
	l = config_port(who, "ActiveMinDataPort", INPORT_ANY);
	u = config_port(who, "ActiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->act_lrng = l;
		ctx->act_urng = u;
	} else {
		/* do not try to bind a port < 1024 if running as UID != 0 */
		if(0 == getuid()) {
			ctx->act_lrng = (IPPORT_FTP - 1);
			ctx->act_urng = (IPPORT_FTP - 1);
		} else {
			ctx->act_lrng = INPORT_ANY;
			ctx->act_urng = INPORT_ANY;
		}
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file ActiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->act_lrng, ctx->act_urng);
#endif

	/*
	** Evaluate min/max passive port range
	*/
	l = config_port(who, "PassiveMinDataPort", INPORT_ANY);
	u = config_port(who, "PassiveMaxDataPort", INPORT_ANY);
	if (l > 0 && u > 0 && u >= l) {
		ctx->pas_lrng = l;
		ctx->pas_urng = u;
	} else {
		ctx->pas_lrng = INPORT_ANY;
		ctx->pas_urng = INPORT_ANY;
	}
#if defined(COMPILE_DEBUG)
	debug(2, "file PassiveRange for %s: %u-%u", ctx->cli_ctrl->peer,
	         ctx->pas_lrng, ctx->pas_urng);
#endif

	/*
	** Setup other configuration options
	*/
	ctx->same_adr = config_bool(who, "SameAddress", 1);
	ctx->timeout  = config_int (who, "TimeOut",   900);
#if defined(COMPILE_DEBUG)
	debug(2, "file SameAddress for %s: %s", ctx->cli_ctrl->peer,
	                                        ctx->same_adr ? "yes" : "no");
	debug(2, "file TimeOut for %s: %d", ctx->cli_ctrl->peer, ctx->timeout);
#endif

/*** Adjust the allow/deny flags for the commands ** Fred patch */
	
	char dest[17];
	char ipdest[17];
	char ipsrc[17];
	strcpy (ipsrc,ctx->cli_ctrl->peer);
	strcpy (ipdest, socket_addr2str(ctx->srv_addr));
	syslog_write(U_INF, "\n");	
	syslog_write(U_INF, "[ %s ] Fred Patch rules dest: %s src: %s", ipsrc, ipdest, ipsrc);	

	char groupname[]="group";
	char commandename[]="ValidCommands";
	char *group;
	FILE *fp;
	group = "group1";
	int ix;
	int ix2;
	u_int32_t dnsaddr;
	for(ix=1; group != NULL; ix++) {
		sprintf (&groupname[5],"%d",ix);
		group = config_str(who, groupname, NULL);
		}
	
	syslog_write(U_INF, "[ %s ] Number of groups: %d", ipsrc, ix-2);
		
	for (ix2=1; ix2 <= ix-2; ix2++) {
		sprintf (&groupname[5],"%d",ix2);
		group = config_str(who, groupname, NULL);
		syslog_write(U_INF, "[ %s ] Reading: %s",ipsrc, group );
		if ((fp = fopen(group, "r")) == NULL)
			{
			syslog_write(U_INF, "File not found");
			return 0;
			}
		else
			{	
			fseek(fp, 0, SEEK_SET);
			while (fgets(dest, 17 , fp) != NULL)
				{	
				// Pour une IP
				// Correction Bug Ligne sans \n 
					dest[16] = '\n';
					char *c = strchr (dest, '\n');
					*c = 0;
					/*  Dns resolution */
					if (ipdest != dest) {
						dnsaddr = socket_str2addr(dest, INADDR_ANY);
						if (dnsaddr != 0) 
							strcpy (dest, socket_addr2str(dnsaddr));
						}
					if (strcmp(dest,ipdest) == 0 || strcmp(dest,ipsrc) == 0)
					{
						sprintf (&commandename[13],"%d",ix);
						p = config_str(who,commandename, NULL);
						cmds_set_allow(p);
						syslog_write(U_INF, "[ %s ] Apply rules for: %s dst: %s",ipsrc, ipsrc, ipdest);
						syslog_write(U_INF, "[ %s ] Server match %s ",ipsrc, group );
						syslog_write(U_INF, "\n");
						fclose(fp);
						return 0;
					}
			// Network
				if (strchr(dest, 'x') != NULL)
					{ 
						char *c = strchr(dest, 'x');
						*c = 0;
						int longueur;
						longueur = strlen(dest);
						if (strncmp(dest,ipdest,longueur) == 0 || strncmp(dest,ipsrc,longueur) == 0)
						{
							sprintf (&commandename[13],"%d",ix);
							p = config_str(who,commandename, NULL);
							cmds_set_allow(p);
							syslog_write(U_INF, "[ %s ] Apply rules for Network: %s src: %s",ipsrc, ipdest, ipsrc);
							syslog_write(U_INF, "[ %s ] Server match %s ",ipsrc, group );
							syslog_write(U_INF, "\n");
							fclose(fp);
							return 0;
						}
					}
				}

			fclose(fp);
			}	
		}
	syslog_write(U_INF, "[ %s ] Oh, Oh, no rule found -> defaultrules", ipsrc) ;
	p = config_str(who, "defaultrules", NULL);
	cmds_set_allow(p); 
	return 0;
}