[server] first pass at eliminating popen() write calls with run_extcmd_write() (used for PF firewalls)
This commit is contained in:
+97
-3
@@ -96,7 +96,7 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
|
||||
|
||||
pid_t pid=0;
|
||||
FILE *output;
|
||||
int retval = 0;
|
||||
int retval = EXTCMD_SUCCESS_ALL_OUTPUT;
|
||||
int line_ctr = 0, found_str = 0;
|
||||
|
||||
*pid_status = 0;
|
||||
@@ -252,7 +252,7 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
|
||||
/* Retval is forced to 0 as we don't care about the exit status of
|
||||
* the child (for now)
|
||||
*/
|
||||
retval = 0;
|
||||
retval = EXTCMD_SUCCESS_ALL_OUTPUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -262,13 +262,14 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
|
||||
if(output == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR, "Got popen error %i: %s", errno, strerror(errno));
|
||||
retval = -1;
|
||||
retval = EXTCMD_OPEN_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(so_buf, 0x0, so_buf_sz);
|
||||
while((fgets(so_read_buf, IO_READ_BUF_LEN, output)) != NULL)
|
||||
{
|
||||
line_ctr++;
|
||||
if(so_buf != NULL)
|
||||
{
|
||||
strlcat(so_buf, so_read_buf, so_buf_sz);
|
||||
@@ -539,6 +540,91 @@ _run_extcmd(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
|
||||
}
|
||||
#endif
|
||||
|
||||
int _run_extcmd_write(const char *cmd, const char *cmd_write, int *pid_status,
|
||||
const fko_srv_options_t * const opts)
|
||||
{
|
||||
int retval = EXTCMD_SUCCESS_ALL_OUTPUT;
|
||||
|
||||
#if HAVE_EXECVPE
|
||||
char *argv_new[MAX_CMDLINE_ARGS]; /* for execvpe() */
|
||||
int argc_new=0;
|
||||
int pipe_fd[2];
|
||||
pid_t pid=0;
|
||||
#else
|
||||
FILE *fd = NULL;
|
||||
#endif
|
||||
|
||||
*pid_status = 0;
|
||||
|
||||
#if HAVE_EXECVPE
|
||||
|
||||
if(opts->verbose > 1)
|
||||
log_msg(LOG_INFO, "run_extcmd_write() (with execvpe()): running CMD: %s", cmd);
|
||||
|
||||
memset(argv_new, 0x0, sizeof(argv_new));
|
||||
|
||||
if(strtoargv(cmd, argv_new, &argc_new, opts) != 1)
|
||||
{
|
||||
log_msg(LOG_ERR,
|
||||
"run_extcmd_write(): Error converting cmd str to argv via strtoargv()");
|
||||
return EXTCMD_ARGV_ERROR;
|
||||
}
|
||||
|
||||
if(pipe(pipe_fd) < 0)
|
||||
{
|
||||
log_msg(LOG_ERR, "run_extcmd_write(): pipe() failed: %s", strerror(errno));
|
||||
free_argv(argv_new, &argc_new);
|
||||
return EXTCMD_PIPE_ERROR;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (pid == 0)
|
||||
{
|
||||
if(chdir("/") != 0)
|
||||
exit(EXTCMD_CHDIR_ERROR);
|
||||
|
||||
close(pipe_fd[1]);
|
||||
dup2(pipe_fd[0], STDIN_FILENO);
|
||||
|
||||
/* don't use env
|
||||
*/
|
||||
execvpe(argv_new[0], argv_new, (char * const *)NULL);
|
||||
}
|
||||
else if(pid == -1)
|
||||
{
|
||||
log_msg(LOG_ERR, "run_extcmd_write(): fork() failed: %s", strerror(errno));
|
||||
free_argv(argv_new, &argc_new);
|
||||
return EXTCMD_FORK_ERROR;
|
||||
}
|
||||
|
||||
close(pipe_fd[0]);
|
||||
if(write(pipe_fd[1], cmd_write, strlen(cmd_write)) < 0)
|
||||
retval = EXTCMD_WRITE_ERROR;
|
||||
|
||||
free_argv(argv_new, &argc_new);
|
||||
|
||||
waitpid(pid, pid_status, 0);
|
||||
|
||||
#else
|
||||
if ((fd = popen(cmd, "w")) == NULL)
|
||||
{
|
||||
log_msg(LOG_ERR, "Got popen error %i: %s", errno, strerror(errno));
|
||||
retval = EXTCMD_OPEN_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fwrite(cmd_write, strlen(cmd_write), 1, fd) != 1)
|
||||
{
|
||||
log_msg(LOG_ERR, "Could not write to cmd stdin");
|
||||
retval = -1;
|
||||
}
|
||||
pclose(fd);
|
||||
}
|
||||
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* _run_extcmd() wrapper, run an external command.
|
||||
*/
|
||||
int
|
||||
@@ -571,3 +657,11 @@ search_extcmd(const char *cmd, const int want_stderr, const int timeout,
|
||||
return _run_extcmd(0, 0, cmd, NULL, 0, want_stderr, timeout,
|
||||
substr_search, pid_status, opts);
|
||||
}
|
||||
|
||||
/* _run_extcmd_write() wrapper, run a command which is expecting input via stdin
|
||||
*/
|
||||
int run_extcmd_write(const char *cmd, const char *cmd_write, int *pid_status,
|
||||
const fko_srv_options_t * const opts)
|
||||
{
|
||||
return _run_extcmd_write(cmd, cmd_write, pid_status, opts);
|
||||
}
|
||||
|
||||
+3
-1
@@ -41,6 +41,7 @@
|
||||
* may end up in.
|
||||
*/
|
||||
enum {
|
||||
EXTCMD_WRITE_ERROR = -9,
|
||||
EXTCMD_CHDIR_ERROR = -8,
|
||||
EXTCMD_OPEN_ERROR = -7,
|
||||
EXTCMD_ARGV_ERROR = -6,
|
||||
@@ -87,7 +88,8 @@ int run_extcmd_as(uid_t uid, gid_t gid, const char *cmd, char *so_buf,
|
||||
int search_extcmd(const char *cmd, const int want_stderr,
|
||||
const int timeout, const char *substr_search,
|
||||
int *pid_status, const fko_srv_options_t * const opts);
|
||||
|
||||
int run_extcmd_write(const char *cmd, const char *cmd_write, int *pid_status,
|
||||
const fko_srv_options_t * const opts);
|
||||
#endif /* EXTCMD_H */
|
||||
|
||||
/***EOF***/
|
||||
|
||||
+11
-23
@@ -94,7 +94,7 @@ fw_dump_rules(const fko_srv_options_t * const opts)
|
||||
static int
|
||||
anchor_active(const fko_srv_options_t *opts)
|
||||
{
|
||||
int res = 0, pid_status = 0;
|
||||
int pid_status = 0;
|
||||
char anchor_search_str[MAX_PF_ANCHOR_SEARCH_LEN] = {0};
|
||||
|
||||
/* Build our anchor search string
|
||||
@@ -113,6 +113,7 @@ anchor_active(const fko_srv_options_t *opts)
|
||||
if(search_extcmd(cmd_buf, WANT_STDERR, NO_TIMEOUT,
|
||||
anchor_search_str, &pid_status, opts) > 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -194,8 +195,6 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
char new_rule[MAX_PF_NEW_RULE_LEN] = {0};
|
||||
char write_cmd[CMD_BUFSIZE] = {0};
|
||||
|
||||
FILE *pfctl_fd = NULL;
|
||||
|
||||
acc_port_list_t *port_list = NULL;
|
||||
acc_port_list_t *ple;
|
||||
|
||||
@@ -261,15 +260,9 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
opts->fw_config->anchor
|
||||
);
|
||||
|
||||
if ((pfctl_fd = popen(write_cmd, "w")) == NULL)
|
||||
{
|
||||
log_msg(LOG_WARNING, "Could not execute command: %s",
|
||||
write_cmd);
|
||||
free_acc_port_list(port_list);
|
||||
return(-1);
|
||||
}
|
||||
res = run_extcmd_write(write_cmd, cmd_out, &pid_status, opts);
|
||||
|
||||
if (fwrite(cmd_out, strlen(cmd_out), 1, pfctl_fd) == 1)
|
||||
if(EXTCMD_IS_SUCCESS(res))
|
||||
{
|
||||
log_msg(LOG_INFO, "Added Rule for %s, %s expires at %u",
|
||||
spadat->use_src_ip,
|
||||
@@ -286,9 +279,11 @@ process_spa_request(const fko_srv_options_t * const opts,
|
||||
fwc.next_expire = exp_ts;
|
||||
}
|
||||
else
|
||||
{
|
||||
log_msg(LOG_WARNING, "Could not write rule to pf anchor");
|
||||
|
||||
pclose(pfctl_fd);
|
||||
free_acc_port_list(port_list);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -345,8 +340,6 @@ check_firewall_rules(const fko_srv_options_t * const opts)
|
||||
time_t now, rule_exp, min_exp=0;
|
||||
int i=0, res=0, anchor_ndx=0, is_delete=0, pid_status=0;
|
||||
|
||||
FILE *pfctl_fd = NULL;
|
||||
|
||||
/* If we have not yet reached our expected next expire
|
||||
time, continue.
|
||||
*/
|
||||
@@ -504,18 +497,13 @@ check_firewall_rules(const fko_srv_options_t * const opts)
|
||||
opts->fw_config->anchor
|
||||
);
|
||||
|
||||
if ((pfctl_fd = popen(write_cmd, "w")) == NULL)
|
||||
res = run_extcmd_write(write_cmd, anchor_rules_copy, &pid_status, opts);
|
||||
if(! EXTCMD_IS_SUCCESS(res))
|
||||
{
|
||||
log_msg(LOG_WARNING, "Could not execute command: %s",
|
||||
write_cmd);
|
||||
write_cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fwrite(anchor_rules_copy, strlen(anchor_rules_copy), 1, pfctl_fd) != 1)
|
||||
{
|
||||
log_msg(LOG_WARNING, "Could not write rules to pf anchor");
|
||||
}
|
||||
pclose(pfctl_fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+2
-2
@@ -45,9 +45,9 @@
|
||||
#define PF_ADD_RULE_ARGS "pass in quick proto %u from %s to any port %u keep state label " EXPIRE_COMMENT_PREFIX "%u"
|
||||
#define PF_WRITE_ANCHOR_RULES_ARGS "-a %s -f -"
|
||||
#if HAVE_EXECVPE
|
||||
#define PF_LIST_ANCHOR_RULES_ARGS "-a %s -s rules 2> /dev/null"
|
||||
#else
|
||||
#define PF_LIST_ANCHOR_RULES_ARGS "-a %s -s rules"
|
||||
#else
|
||||
#define PF_LIST_ANCHOR_RULES_ARGS "-a %s -s rules 2> /dev/null"
|
||||
#endif
|
||||
#define PF_ANCHOR_CHECK_ARGS "-s Anchor" SH_REDIR /* to check for fwknop anchor */
|
||||
#define PF_DEL_ALL_ANCHOR_RULES "-a %s -F all" SH_REDIR
|
||||
|
||||
Reference in New Issue
Block a user