Example #1
0
def test_send_cmd_unix_endings(unicode_chr):
    """Ensure the correct line ending is used when unix is specified."""

    runner = Bladerunner({
        "unix_line_endings": True,
        "windows_line_endings": False,
        "second_password": "hunter55",
    })
    server = Mock()
    # server.expect returns an integer of the prompt matched in its list
    # we want to return N+1 to simulate matching a passwd prompt
    server.expect = Mock(return_value=(
        len(runner.options["shell_prompts"]) +
        len(runner.options["extra_prompts"]) +
        1
    ))

    with patch.object(base, "format_output") as p_format_out:
        runner._send_cmd("fake", server)

    p_format_out.assert_called_once_with(server.before, "fake", runner.options)
    server.send.assert_called_once_with("fake{0}".format(unicode_chr(0x000A)))

    # the second password should be send with sendline
    server.sendline.assert_called_once_with("hunter55")

    assert server.expect.call_count == 2
Example #2
0
def test_login_new_host():
    """The first passwd prompt is a match for a new ssh key identity."""

    runner = Bladerunner()
    sshc = Mock()
    sshc.expect = Mock(side_effect=iter([2, 22]))  # passwd, then shell
    assert runner.login(sshc, "fake", 0) == (sshc, 1)
    assert sshc.sendline.mock_calls == [call("yes"), call("fake")]
Example #3
0
def test_login_send_password():
    """Ensure then calls when logging in properly with a passwd prompt."""

    runner = Bladerunner()
    sshc = Mock()
    sshc.expect = Mock(return_value=22)
    assert runner.login(sshc, "mock word", 1) == (sshc, 1)
    sshc.sendline.assert_called_once_with("mock word")
Example #4
0
def test_fallback_prompt_guess(pexpect_exceptions):
    """If a TIMEOUT or EOF error is raised, call _try_for_unmatched_prompt."""

    server = Mock()
    server.expect = Mock(side_effect=pexpect_exceptions("mock exception"))
    runner = Bladerunner({"username": "guy", "password": "hunter2"})

    with patch.object(runner, "_try_for_unmatched_prompt") as p_try_for:
        runner._send_cmd("not real", server)

    p_try_for.assert_called_once_with(server, server.before, "not real")
Example #5
0
def test_login_new_host_failures(pexpect_exceptions):
    """Catch the pexpect EOF and TIMEOUT exceptions after accepting the key."""

    runner = Bladerunner()
    sshc = Mock()
    sshc.expect = Mock(side_effect=pexpect_exceptions("fake exception"))

    with patch.object(runner, "send_interrupt") as p_interrupt:
        assert runner.login(sshc, "hunter12", 0) == (None, -1)

    sshc.sendline.assert_called_once_with("yes")
    p_interrupt.assert_called_once_with(sshc)
Example #6
0
def test_login_passwd_fail():
    """Ensure the calls when receiving another passwd prompt after sending."""

    runner = Bladerunner()
    sshc = Mock()
    sshc.expect = Mock(return_value=1)

    with patch.object(runner, "send_interrupt") as p_interrupt:
        assert runner.login(sshc, "fakepasswd", 1) == (sshc, -5)

    sshc.sendline.assert_called_once_with("fakepasswd")
    p_interrupt.assert_called_once_with(sshc)
Example #7
0
def test_login_fail_guess(pexpect_exceptions):
    """When sending a password fails try to guess the shell prompt."""

    runner = Bladerunner()
    sshc = Mock()
    sshc.expect = Mock(side_effect=pexpect_exceptions("fake explosion"))

    with patch.object(runner, "_try_for_unmatched_prompt") as p_try_for:
        runner.login(sshc, "passwerd", 1)

    sshc.sendline.assert_called_once_with("passwerd")
    p_try_for.assert_called_once_with(sshc, sshc.before, "login", _from_login=True)
Example #8
0
def side_effect(*args, **kwargs):

    m = Mock()

    def expect(patterns, timeout):
        return responder(m, side_effect.responses, patterns, timeout)

    m.expect = expect

    # TODO: implements a exact match
    m.expect_exact = expect

    return m
Example #9
0
def test_close_keep_open(pexpect_exceptions):
    """Ensure we can close a connection inside another, for jumpboxes."""

    runner = Bladerunner()
    sshc = Mock()
    # exceptions are ignored here, we hope we're back on the jumpbox
    sshc.expect = Mock(side_effect=pexpect_exceptions("mock exception"))

    runner.close(sshc, False)
    sshc.sendline.assert_called_once_with("exit")
    sshc.expect.assert_called_once_with(
        runner.options["shell_prompts"] + runner.options["extra_prompts"], runner.options["cmd_timeout"]
    )
Example #10
0
def test_push_expect_forward(pexpect_exceptions):
    """Verify the calls made to push the pexpect connection object forward."""

    runr = Bladerunner()
    sshc = Mock()
    # any EOF or TIMEOUT exceptions are ignored
    sshc.expect = Mock(side_effect=pexpect_exceptions("faked exception"))

    runr._push_expect_forward(sshc)

    assert sshc.expect.mock_calls == [
        call(runr.options["shell_prompts"] + runr.options["extra_prompts"], 2),
        call(runr.options["shell_prompts"] + runr.options["extra_prompts"], 2),
    ]
Example #11
0
def test_try_for_unmatched_fails():
    """Bladerunner "hits enter" up to 3 times to try to guess the prompt."""

    runner = Bladerunner()
    server = Mock()
    server.expect = Mock(side_effect=pexpect.TIMEOUT("fake"))
    server.before = bytes_or_string("mock output")

    with patch.object(runner, "send_interrupt") as p_interrupt:
        ret = runner._try_for_unmatched_prompt(server, bytes_or_string("out"), "fake")

    assert ret == -1
    assert "out" in runner.options["shell_prompts"]
    p_interrupt.assert_called_once_with(server)
Example #12
0
def test_try_unmatched_fails_from_login():
    """When trying to guess on login, return None, -6 on error."""

    runner = Bladerunner()
    server = Mock()
    server.expect = Mock(side_effect=pexpect.TIMEOUT("fake"))
    server.before = bytes_or_string("mock output")

    with patch.object(runner, "send_interrupt") as p_interrupt:
        ret = runner._try_for_unmatched_prompt(server, bytes_or_string("out"), "fake", True)

    assert ret == (None, -6)
    assert "out" in runner.options["shell_prompts"]
    p_interrupt.assert_called_once_with(server)
Example #13
0
def test_send_cmd_no_preference():
    """Ensure we call to pexpect's sendline which uses os.linesep."""

    runner = Bladerunner()
    server = Mock()
    server.expect = Mock(return_value=1)

    with patch.object(base, "format_output") as p_format_out:
        runner._send_cmd("mock", server)

    p_format_out.assert_called_once_with(server.before, "mock", runner.options)
    server.sendline.assert_called_once_with("mock")

    assert server.expect.call_count == 1
Example #14
0
def test_connect_new_exceptions(pexpect_exceptions):
    """If TIMEOUT or EOF exceptions are raised, connect returns (None, -7)."""

    runner = Bladerunner({"debug": 2, "jump_host": "nowhere"})
    sshr = Mock()
    sshr.expect = Mock(side_effect=pexpect_exceptions("faked"))
    sshr.isalive = Mock(return_value=False)

    with patch.object(base, "can_resolve", return_value=True):
        with patch.object(base.pexpect, "spawn", return_value=sshr) as p_spawn:
            res = runner.connect("nowhere", "noone", "hunter29", 99)

    p_spawn.assert_called_once_with("ssh -p 99 -t -vv noone@nowhere", timeout=20)  # default timeout
    assert res == (None, -7)
Example #15
0
def test_send_interrupt(unicode_chr, pexpect_exceptions):
    """Ensure Bladerunner sends ^c to the sshc when jumpboxing."""

    runner = Bladerunner()
    sshc = Mock()
    # any EOF or TIMEOUT exceptions are ignored
    sshc.expect = Mock(side_effect=pexpect_exceptions("faked exception"))

    with patch.object(runner, "_push_expect_forward") as p_push:
        runner.send_interrupt(sshc)

    sshc.sendline.assert_called_once_with(unicode_chr(0x003))
    sshc.expect.assert_called_once_with(runner.options["shell_prompts"] + runner.options["extra_prompts"], 3)
    p_push.assert_called_once_with(sshc)
Example #16
0
def test_send_cmd_winderps_endings(unicode_chr):
    """Ensure the wrong line endings are used when winderps is required."""

    runner = Bladerunner({"unix_line_endings": False, "windows_line_endings": True})
    server = Mock()
    server.expect = Mock(return_value=1)

    with patch.object(base, "format_output") as p_format_out:
        runner._send_cmd("fake", server)

    p_format_out.assert_called_once_with(server.before, "fake", runner.options)
    server.send.assert_called_once_with("fake{0}{1}".format(unicode_chr(0x000D), unicode_chr(0x000A)))

    assert server.expect.call_count == 1
Example #17
0
def test_send_cmd_no_line_endings():
    """If are False, pexpect's sendline should be called (which uses os)."""

    runner = Bladerunner()
    # we need to update after init as init will fallback to os preferred
    runner.options.update({"unix_line_endings": False, "windows_line_endings": False})
    server = Mock()
    server.expect = Mock(return_value=1)

    with patch.object(base, "format_output") as p_format_out:
        runner._send_cmd("fake_cmd", server)

    p_format_out.assert_called_once_with(server.before, "fake_cmd", runner.options)
    server.sendline.assert_called_once_with("fake_cmd")

    assert server.expect.call_count == 1
Example #18
0
def test_connect_exception_guess(pexpect_exceptions):
    """If the pexpect object is alive on connect timeout, guess the prompt."""

    runner = Bladerunner({"timeout": "fake"})
    sshr = Mock()
    sshr.expect = Mock(side_effect=pexpect_exceptions("not real"))
    sshr.before = Mock(return_value="what")
    sshr.isalive = Mock(return_value=True)

    with patch.object(base, "can_resolve", return_value=True):
        with patch.object(base.pexpect, "spawn", return_value=sshr) as p_spawn:
            with patch.object(runner, "_try_for_unmatched_prompt") as p_guess:
                runner.connect("fence", "tim", "hunter1", 4)

    p_spawn.assert_called_once_with("ssh -p 4 -t tim@fence", timeout="fake")
    p_guess.assert_called_once_with(sshr, sshr.before, "ssh -p 4 -t tim@fence", _from_login=True)
Example #19
0
def test_connect_new_connection():
    """Ensure Bladerunner creates the initial pexpect object correctly."""

    runner = Bladerunner({"debug": 2, "jump_host": "nowhere", "timeout": 14})
    sshr = Mock()
    sshr.expect = Mock(return_value="faked")

    with patch.object(base, "can_resolve", return_value=True):
        with patch.object(base.pexpect, "spawn", return_value=sshr) as p_spawn:
            with patch.object(runner, "_multipass") as p_multipass:
                runner.connect("nowhere", "bobby", "hunter44", 15)

    p_spawn.assert_called_once_with("ssh -p 15 -t -vv bobby@nowhere", timeout=14)
    p_multipass.assert_called_once_with(sshr, "hunter44", "faked")
    sshr.expect.assert_called_once_with(
        runner.options["passwd_prompts"] + runner.options["shell_prompts"] + runner.options["extra_prompts"],
        runner.options["timeout"],
    )
    assert runner.sshc == sshr  # could be used as a jumpbox in future connects
    assert sshr.logfile_read == FakeStdOut  # debug is set, logging to stdout