diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2007-11-29 16:56:29 -0800 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2007-11-29 16:56:29 -0800 |
commit | 05ac050c585a52df2f475bface59562656b08b4e (patch) | |
tree | c10f3fcd19bd7d1698938772c155f7361f651a10 | |
parent | 027bd747d8dd050937dc6344c207530e79808b89 (diff) | |
download | vyatta-bash-05ac050c585a52df2f475bface59562656b08b4e.tar.gz vyatta-bash-05ac050c585a52df2f475bface59562656b08b4e.zip |
restricted modes:
* do not restart completion after a "connector" or a '`'.
* only allow simple commands and "pipe" in "full" mode.
* add mechanism to limit allowed pipe commands.
* remove unnecessary command checks (non-interactive and same command).
-rw-r--r-- | bashline.c | 21 | ||||
-rw-r--r-- | eval.c | 91 |
2 files changed, 101 insertions, 11 deletions
@@ -941,9 +941,12 @@ find_cmd_start (start) register int s, os; os = 0; - while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS)) <= start) && - rl_line_buffer[s]) - os = s+1; + if (!in_vyatta_restricted_mode(OUTPUT)) { + while (((s = skip_to_delim (rl_line_buffer, os, COMMAND_SEPARATORS)) + <= start) + && rl_line_buffer[s]) + os = s+1; + } return os; } @@ -953,7 +956,11 @@ find_cmd_end (end) { register int e; - e = skip_to_delim (rl_line_buffer, end, COMMAND_SEPARATORS); + if (!in_vyatta_restricted_mode(OUTPUT)) { + e = skip_to_delim (rl_line_buffer, end, COMMAND_SEPARATORS); + } else { + e = strlen(rl_line_buffer); + } return e; } @@ -1038,7 +1045,9 @@ attempt_shell_completion (text, start, end) } else if (member (rl_line_buffer[ti], command_separator_chars)) { - in_command_position++; + if (!in_vyatta_restricted_mode(OUTPUT)) { + in_command_position++; + } if (check_redir (ti) == 1) in_command_position = 0; @@ -1060,7 +1069,7 @@ attempt_shell_completion (text, start, end) it can be the start or end of an old-style command substitution, or unmatched. If it's unmatched, both calls to unclosed_pair will succeed. */ - if (*text == '`' && + if (*text == '`' && !in_vyatta_restricted_mode(OUTPUT) && (in_command_position || (unclosed_pair (rl_line_buffer, start, "`") && unclosed_pair (rl_line_buffer, end, "`")))) matches = rl_completion_matches (text, command_subst_completion_function); @@ -199,7 +199,7 @@ send_pwd_to_eterm () } static int -is_in_command_list(const char *cmd, const char *cmds[]) +is_in_command_list(const char *cmd, char *cmds[]) { int idx = 0; for (idx = 0; cmds[idx]; idx++) { @@ -211,6 +211,64 @@ is_in_command_list(const char *cmd, const char *cmds[]) } static int +is_vyatta_restricted_pipe_command(WORD_LIST *words) +{ + char *allowed_commands[] = { "more", NULL }; + if (words) { + if (!words->next) { + /* only 1 word */ + if (is_in_command_list(words->word->word, allowed_commands)) { + /* allowed */ + return 1; + } + } + } + /* not allowed */ + return 0; +} + +static int +is_vyatta_restricted_command(COMMAND *cmd) +{ + struct simple_com *cS; + struct connection *cC; + + if (!cmd) { + return 1; + } + + switch (cmd->type) { + case cm_simple: + cS = cmd->value.Simple; + if (!(cS->redirects)) { + /* simple command, no redirects => allowed */ + return 1; + } + break; + case cm_connection: + cC = cmd->value.Connection; + if (cC->connector == '|') { + if ((cC->first->type == cm_simple) && (cC->second->type == cm_simple)) { + struct simple_com *cS1 = cC->first->value.Simple; + struct simple_com *cS2 = cC->second->value.Simple; + if (!(cS1->redirects) && !(cS2->redirects)) { + /* both are simple and no redirects */ + if (is_vyatta_restricted_pipe_command(cS2->words)) { + /* pipe command is allowed => allowed */ + return 1; + } + } + } + } + break; + default: + break; + } + /* not allowed */ + return 0; +} + +static int is_vyatta_cfg_command(const char *cmd) { char *valid_commands[] = { "set", "delete", "commit", "save", "load", @@ -243,8 +301,10 @@ is_vyatta_op_command(const char *cmd) return (ret) ? 1 : is_in_command_list(cmd, other_commands); } +static char *prev_cmdline = NULL; + static int -is_vyatta_command(char *cmdline) +is_vyatta_command(char *cmdline, COMMAND *cmd) { char *cfg = getenv("_OFR_CONFIGURE"); int in_cfg = (cfg) ? (strcmp(cfg, "ok") == 0) : 0; @@ -252,11 +312,25 @@ is_vyatta_command(char *cmdline) char *end = NULL; char save = 0; int ret = 0; + + if (!prev_cmdline) { + prev_cmdline = strdup(""); + } + if (strcmp(cmdline, prev_cmdline) == 0) { + /* still at the same line. not checking. */ + return 1; + } + if (!is_vyatta_restricted_command(cmd)) { + return 0; + } + while (*start && (whitespace(*start) || *start == '\n')) { start++; } if (*start == 0) { - /* empty command line */ + /* empty command line is valid */ + free(prev_cmdline); + prev_cmdline = strdup(cmdline); return 1; } end = start; @@ -272,6 +346,12 @@ is_vyatta_command(char *cmdline) ret = is_vyatta_op_command(start); } *end = save; + + if (ret) { + /* valid command */ + free(prev_cmdline); + prev_cmdline = strdup(cmdline); + } return ret; } @@ -305,8 +385,9 @@ parse_command () r = yyparse (); #if defined (READLINE) - if (in_vyatta_restricted_mode(FULL) && current_readline_line) { - if (!is_vyatta_command(current_readline_line)) { + if (interactive && in_vyatta_restricted_mode(FULL) + && current_readline_line) { + if (!is_vyatta_command(current_readline_line, global_command)) { printf("Invalid command\n"); current_readline_line_index = 0; current_readline_line[0] = '\n'; |