Example #1
0
def test_all_passwords_are_hidden():
    """Passwords from Bladerunner.options should be hidden in the output.

    You could use --debug=<int> from the command line to see the unfiltered
    output of all commands, but passwords will be hidden in formatted output.
    """

    options = {
        "password": "******",
        "second_password": "******",
        "jump_password": "******",
    }
    output = (
        "shell_prompt> faked\n"
        "some text which has hunter7 in it, something secret and even a"
        "shared_password as well, crazy.\n"
        "shell_prompt>"
    )
    expected = (
        "some text which has ******* in it, **************** and even a"
        "*************** as well, crazy."
    )

    if sys.version_info > (3,):
        output = bytes(output, "utf-8")

    assert formatting.format_output(output, "faked", options) == expected
Example #2
0
    def _send_cmd(self, command, server):
        """Internal method to send a single command to the pexpect object.

        Args::

            command: the command to send
            server: the pexpect object to send to

        Returns:
            The formatted output of the command as a string, or -1 on timeout
        """

        try:
            if self.options["unix_line_endings"]:
                server.send("{0}{1}".format(
                    command,
                    six.unichr(0x000A),
                ))
            elif self.options["windows_line_endings"]:
                server.send("{0}{1}{2}".format(
                    command,
                    six.unichr(0x000D),
                    six.unichr(0x000A),
                ))
            else:
                server.sendline(command)

            cmd_response = server.expect(
                self.options["shell_prompts"] +
                self.options["extra_prompts"] +
                self.options["passwd_prompts"],
                self.options["cmd_timeout"],
            )

            if cmd_response >= (
                len(self.options["shell_prompts"]) +
                len(self.options["extra_prompts"])
            ) and len(self.options["second_password"] or "") > 0:
                server.sendline(self.options["second_password"])
                server.expect(
                    self.options["shell_prompts"] +
                    self.options["extra_prompts"],
                    self.options["cmd_timeout"],
                )
        except (pexpect.TIMEOUT, pexpect.EOF):
            return self._try_for_unmatched_prompt(
                server,
                server.before,
                command,
            )

        return format_output(server.before, command, self.options)
Example #3
0
def test_format_output():
    """Should remove the first, last, and any line with command in it."""

    command = "super duper secret command"
    fake_output = (
        "someshell# {0}\nlots of interesting\noutput n stuff\nsomeshell#"
    ).format(command)

    if sys.version_info >= (3, 0):
        fake_output = bytes(fake_output, "utf-8")

    output = formatting.format_output(fake_output, command)

    assert output == "lots of interesting\noutput n stuff"
Example #4
0
def test_format_output():
    """Should remove the first, last, and any line with command in it."""

    command = "super duper secret command"
    fake_output = (
        "someshell# {0}\nlots of interesting\noutput n stuff\nsomeshell#"
    ).format(command)

    if sys.version_info >= (3, 0):
        fake_output = bytes(fake_output, "utf-8")

    output = formatting.format_output(fake_output, command)

    assert output == "lots of interesting\noutput n stuff"
Example #5
0
    def test_format_output(self):
        """Should remove the first, last, and any line with command in it."""

        command = "super duper secret command"
        fake_output = [
            "someshell# {0}".format(command),
            "lots of interesting",
            "output n stuff",
            "someshell#",
        ]
        self.assertEqual(
            formatting.format_output("\n".join(fake_output), command),
            "lots of interesting\noutput n stuff",
        )
Example #6
0
    def _send_cmd(self, command, server):
        """Internal method to send a single command to the pexpect object.

        Args::

            command: the command to send
            server: the pexpect object to send to

        Returns:
            The formatted output of the command as a string, or -1 on timeout
        """

        try:
            if self.options["unix_line_endings"]:
                server.send("{0}{1}".format(
                    command,
                    six.unichr(0x000A),
                ))
            elif self.options["windows_line_endings"]:
                server.send("{0}{1}{2}".format(
                    command,
                    six.unichr(0x000D),
                    six.unichr(0x000A),
                ))
            else:
                server.sendline(command)

            cmd_response = server.expect(
                self.options["shell_prompts"] + self.options["extra_prompts"] +
                self.options["passwd_prompts"],
                self.options["cmd_timeout"],
            )

            if cmd_response >= (len(self.options["shell_prompts"]) +
                                len(self.options["extra_prompts"])) and len(
                                    self.options["second_password"] or "") > 0:
                server.sendline(self.options["second_password"])
                server.expect(
                    self.options["shell_prompts"] +
                    self.options["extra_prompts"],
                    self.options["cmd_timeout"],
                )
        except (pexpect.TIMEOUT, pexpect.EOF):
            return self._try_for_unmatched_prompt(
                server,
                server.before,
                command,
            )

        return format_output(server.before, command, self.options)
Example #7
0
def test_command_in_second_line():
    """Long commands and small terminals can lead to leakage."""

    command = (
        "super secret and long rediculous command that receives so many "
        "arguments it spills over into the next line")
    fake_output = ("someshell# {0}\n{1}\nlots of interesting\noutput n stuff\n"
                   "someshell#").format(command[:50], command[50:])

    if sys.version_info >= (3, 0):
        fake_output = bytes(fake_output, "utf-8")

    output = formatting.format_output(fake_output, command)

    assert output == "lots of interesting\noutput n stuff"
Example #8
0
    def test_command_in_second_line(self):
        """Long commands and small terminals can lead to leakage."""

        command = (
            "super secret and long rediculous command that receives so many "
            "arguments it spills over into the next line"
        )
        fake_output = [
            "someshell# {0}\n{1}".format(command[:50], command[50:]),
            "lots of interesting",
            "output n stuff",
            "someshell#",
        ]
        self.assertEqual(
            formatting.format_output("\n".join(fake_output), command),
            "lots of interesting\noutput n stuff",
        )
Example #9
0
def test_command_in_second_line():
    """Long commands and small terminals can lead to leakage."""

    command = (
        "super secret and long rediculous command that receives so many "
        "arguments it spills over into the next line"
    )
    fake_output = (
        "someshell# {0}\n{1}\nlots of interesting\noutput n stuff\n"
        "someshell#"
    ).format(command[:50], command[50:])

    if sys.version_info >= (3, 0):
        fake_output = bytes(fake_output, "utf-8")

    output = formatting.format_output(fake_output, command)

    assert output == "lots of interesting\noutput n stuff"
Example #10
0
def test_all_passwords_are_hidden():
    """Passwords from Bladerunner.options should be hidden in the output.

    You could use --debug=<int> from the command line to see the unfiltered
    output of all commands, but passwords will be hidden in formatted output.
    """

    options = {
        "password": "******",
        "second_password": "******",
        "jump_password": "******",
    }
    output = ("shell_prompt> faked\n"
              "some text which has hunter7 in it, something secret and even a"
              "shared_password as well, crazy.\n"
              "shell_prompt>")
    expected = (
        "some text which has ******* in it, **************** and even a"
        "*************** as well, crazy.")

    if sys.version_info > (3, ):
        output = bytes(output, "utf-8")

    assert formatting.format_output(output, "faked", options) == expected
Example #11
0
    def _try_for_unmatched_prompt(self, server, output, command,
                                  _from_login=False, _attempts_left=3):
        """On command timeout, send newlines to guess the missing shell prompt.

        Args:

            server: the sshc object
            output: the sshc.before after issuing command before the timeout
            command: the command issued that caused the initial timeout
            _from_login: if this is called from the login method, return the
                         (connection, code) tuple, or return formatted_output()
            _attempts_left: internal integer to iterate over this function with

        Returns:
            format_output if it can find a new prompt, or -1 on error
        """

        # prompt is usually in the last 30 chars of the last line of output
        # do /not/ format_line the prompt, it could contain special characters
        try:
            new_prompt = output.splitlines()[-1][-30:]
        except IndexError:
            new_prompt = ""

        if isinstance(new_prompt, bytes):
            new_prompt = codecs.decode(new_prompt, DEFAULT_ENCODING)

        # escape regex characters
        replacements = ["\\", "/", ")", "(", "[", "]", "{", "}", " ", "$",
                        "?", ">", "<", "^", ".", "*"]
        for char in replacements:
            new_prompt = new_prompt.replace(char, "\{0}".format(char))

        if new_prompt and new_prompt not in self.options["shell_prompts"]:
            self.options["shell_prompts"].append(new_prompt)

        try:
            server.sendline()
            server.expect(
                self.options["shell_prompts"] +
                self.options["extra_prompts"],
                2,
            )
        except (pexpect.TIMEOUT, pexpect.EOF):
            if _attempts_left:
                return self._try_for_unmatched_prompt(
                    server,
                    server.before,
                    command,
                    _from_login=_from_login,
                    _attempts_left=(_attempts_left - 1),
                )
        else:
            self._push_expect_forward(server)
            if _from_login:
                return (server, 1)
            else:
                return format_output(output, command, self.options)

        self.send_interrupt(server)

        if _from_login:
            # if we get here, we tried to guess the prompt by sending enter 3
            # times, but still didn't return to that same shell. Something odd
            # is likely happening on the device that needs manual inspection
            return (None, -6)
        else:
            return -1
Example #12
0
    def _try_for_unmatched_prompt(self,
                                  server,
                                  output,
                                  command,
                                  _from_login=False,
                                  _attempts_left=3):
        """On command timeout, send newlines to guess the missing shell prompt.

        Args:

            server: the sshc object
            output: the sshc.before after issuing command before the timeout
            command: the command issued that caused the initial timeout
            _from_login: if this is called from the login method, return the
                         (connection, code) tuple, or return formatted_output()
            _attempts_left: internal integer to iterate over this function with

        Returns:
            format_output if it can find a new prompt, or -1 on error
        """

        # do /not/ format_line the prompt, it could contain special characters
        try:
            new_prompt = output.splitlines()[-1]
        except IndexError:
            new_prompt = ""

        if isinstance(new_prompt, bytes):
            new_prompt = codecs.decode(new_prompt, DEFAULT_ENCODING)

        # escape regex characters
        replacements = [
            "\\", "/", ")", "(", "[", "]", "{", "}", " ", "$", "?", ">", "<",
            "^", ".", "*"
        ]
        for char in replacements:
            new_prompt = new_prompt.replace(char, "\{0}".format(char))

        if new_prompt and new_prompt not in self.options["shell_prompts"]:
            self.options["shell_prompts"].append(new_prompt)

        try:
            server.sendline()
            server.expect(
                self.options["shell_prompts"] + self.options["extra_prompts"],
                2,
            )
        except (pexpect.TIMEOUT, pexpect.EOF):
            if _attempts_left:
                return self._try_for_unmatched_prompt(
                    server,
                    server.before,
                    command,
                    _from_login=_from_login,
                    _attempts_left=(_attempts_left - 1),
                )
        except OSError:
            # we've lost the underlying connection
            return -1
        else:
            self._push_expect_forward(server)
            if _from_login:
                return (server, 1)
            else:
                return format_output(output, command, self.options)

        self.send_interrupt(server)

        if _from_login:
            # if we get here, we tried to guess the prompt by sending enter 3
            # times, but still didn't return to that same shell. Something odd
            # is likely happening on the device that needs manual inspection
            return (None, -6)
        else:
            return -1