def test_kssh_spoofed_config(self, test_config): # Test that even when kssh is forced to run by a spoofed config, the CA # bot ignores messages that are in the wrong channel with outputs_audit_log(test_config, filename="/shared/ca.log", expected_number=0): client_config = json.dumps({ "teamname": f"{test_config.subteam}.ssh", "channelname": "", "botname": test_config.bot_username, }) run_put_kvstore_command(f"{test_config.subteam}.ssh", client_config) for s in [ "user@sshd-staging", "root@sshd-staging", "user@sshd-prod", "root@sshd-prod", ]: try: run_command_with_agent( f"bin/kssh -q -o StrictHostKeyChecking=no {s} " f'"sha1sum /etc/unique" ') assert False except subprocess.CalledProcessError as e: assert ( b"Failed to get a signed key from the CA: " b"timed out while waiting for a response from the CA" ) in e.output
def test_kssh_spoofed_config(self, test_config): # Test that even when kssh is forced to run by a spoofed config, the CA bot ignores messages that are in the # wrong channel with outputs_audit_log(test_config, filename="/shared/ca.log", expected_number=0): client_config = json.dumps({ 'teamname': f"{test_config.subteam}.ssh", "channelname": "", "botname": test_config.bot_username }) run_command( f"echo '{client_config}' | keybase fs write /keybase/team/{test_config.subteam}.ssh/kssh-client.config" ) for s in [ 'user@sshd-staging', 'root@sshd-staging', 'user@sshd-prod', 'root@sshd-prod' ]: try: run_command_with_agent( f"""bin/kssh -q -o StrictHostKeyChecking=no {s} "sha1sum /etc/unique" """ ) assert False except subprocess.CalledProcessError as e: assert b"Failed to get a signed key from the CA: timed out while waiting for a response from the CA" in e.output
def test_kssh(self, test_config): # Test ksshing which tests that it is correctly finding a client config with outputs_audit_log( test_config, filename="/shared/ca.log", expected_number=3 ): clear_keys() assert_contains_hash( test_config.expected_hash, run_command_with_agent( 'bin/kssh -q -o StrictHostKeyChecking=no \ user@sshd-staging "sha1sum /etc/unique" ' ), ) clear_keys() assert_contains_hash( test_config.expected_hash, run_command_with_agent( 'bin/kssh -q -o StrictHostKeyChecking=no \ root@sshd-staging "sha1sum /etc/unique" ' ), ) clear_keys() assert_contains_hash( test_config.expected_hash, run_command_with_agent( 'bin/kssh -q -o StrictHostKeyChecking=no \ root@sshd-prod "sha1sum /etc/unique" ' ), )
def test_kssh_reuse(self, test_config): # Test that kssh reuses unexpired keys with outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=1): assert_contains_hash(test_config.expected_hash, run_command_with_agent("""bin/kssh -q -o StrictHostKeyChecking=no root@sshd-prod "sha1sum /etc/unique" """)) start = time.time() assert_contains_hash(test_config.expected_hash, run_command_with_agent("""bin/kssh -q -o StrictHostKeyChecking=no root@sshd-prod "sha1sum /etc/unique" """)) elapsed = time.time() - start assert elapsed < 0.5
def test_kssh_errors_on_two_bots(self, test_config): # Test that kssh does not run if there are multiple bots, no kssh config, and no --bot flag with simulate_two_teams(test_config), outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=0): try: run_command_with_agent("bin/kssh root@sshd-prod") assert False except subprocess.CalledProcessError as e: assert b"Found 2 config files" in e.output
def test_kssh_reject_prod_user(self, test_config): # Test that we can't kssh into prod as user since we aren't in the correct team for that with outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=1): try: run_command_with_agent("""bin/kssh -o StrictHostKeyChecking=no user@sshd-prod "sha1sum /etc/unique" 2>&1 """) assert False except subprocess.CalledProcessError as e: assert b"Permission denied" in e.output assert test_config.expected_hash not in e.output
def test_kssh_override_default_bot(self, test_config): # Test that the --bot flag overrides the local config file with simulate_two_teams(test_config), outputs_audit_log( test_config, filename=test_env_1_log_filename, expected_number=1): run_command_with_agent(f"bin/kssh --set-default-bot otherbotname") assert_contains_hash( test_config.expected_hash, run_command_with_agent( f"bin/kssh --bot {test_config.bot_username} -q -o StrictHostKeyChecking=no root@sshd-prod 'sha1sum /etc/unique'" ))
def test_kssh_set_default_bot(self, test_config): # Test that kssh works with the --set-default-bot flag with simulate_two_teams(test_config), outputs_audit_log( test_config, filename=test_env_1_log_filename, expected_number=1): run_command_with_agent( f"bin/kssh --set-default-bot {test_config.bot_username}") assert_contains_hash( test_config.expected_hash, run_command_with_agent( "bin/kssh -q -o StrictHostKeyChecking=no \ root@sshd-prod 'sha1sum /etc/unique'"), )
def test_kssh_regenerate_expired_keys(self, test_config): # Test that kssh reprovisions a key when the stored keys are expired with outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=1): run_command_with_agent( "mv ~/tests/testFiles/expired ~/.ssh/keybase-signed-key-- && mv ~/tests/testFiles/expired.pub ~/.ssh/keybase-signed-key--.pub && mv ~/tests/testFiles/expired-cert.pub ~/.ssh/keybase-signed-key---cert.pub" ) assert_contains_hash( test_config.expected_hash, run_command_with_agent( """bin/kssh -q -o StrictHostKeyChecking=no root@sshd-prod "sha1sum /etc/unique" """ ))
def test_kssh_no_config_files(self, test_config): # Test that it can't find any config files with outputs_audit_log(test_config, filename="/shared/ca.log", expected_number=0): for s in [ 'user@sshd-staging', 'root@sshd-staging', 'user@sshd-prod', 'root@sshd-prod' ]: try: run_command_with_agent( f"""bin/kssh -q -o StrictHostKeyChecking=no {s} "sha1sum /etc/unique" """ ) assert False except subprocess.CalledProcessError as e: assert b"Did not find any config files in KBFS" in e.output
def test_kssh(self, test_config): # Test ksshing into staging as user with outputs_audit_log(test_config, filename="/shared/ca.log", expected_number=1): assert_contains_hash( test_config.expected_hash, run_command_with_agent( """bin/kssh -q -o StrictHostKeyChecking=no user@sshd-staging "sha1sum /etc/unique" """ ))
def test_kssh_prod_root(self, test_config): # Test ksshing into prod as root with outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=1): assert_contains_hash( test_config.expected_hash, run_command_with_agent( """bin/kssh -q -o StrictHostKeyChecking=no root@sshd-prod "sha1sum /etc/unique" """ ))
def test_kssh_staging_root(self, test_config): # Test ksshing into staging as user with outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=1): assert_contains_hash( test_config.expected_hash, run_command_with_agent( 'bin/kssh -q -o StrictHostKeyChecking=no \ root@sshd-staging "sha1sum /etc/unique" '), )
def test_kssh_alternate_binary(self, test_config): # Test it by creating another keybase binary earlier in the path and running kssh. This isn't a perfect test but it is # enough to smoketest it run_command("echo '#!/bin/bash' | sudo tee /usr/local/bin/keybase") run_command("sudo chmod +x /usr/local/bin/keybase") try: run_command("bin/kssh --set-keybase-binary /usr/bin/keybase") assert_contains_hash(test_config.expected_hash, run_command_with_agent("bin/kssh -q -o StrictHostKeyChecking=no user@sshd-staging 'sha1sum /etc/unique'")) run_command("bin/kssh --set-keybase-binary ''") finally: run_command("sudo rm /usr/local/bin/keybase")
def test_kssh_default_user(self, test_config): # Set the default user to root run_command_with_agent("bin/kssh --set-default-user root") # A normal SSH connection assert_contains_hash(test_config.expected_hash, run_command_with_agent("bin/kssh -q -o StrictHostKeyChecking=no sshd-prod 'sha1sum /etc/unique'")) assert b"root" in run_command_with_agent("bin/kssh -q -o StrictHostKeyChecking=no sshd-prod 'whoami'") # A proxy jump (relies on the ssh agent) assert_contains_hash(test_config.expected_hash, run_command_with_agent("bin/kssh -q -o StrictHostKeyChecking=no -J sshd-staging sshd-prod 'sha1sum /etc/unique'")) # Reset the default user run_command_with_agent("bin/kssh --clear-default-user")
def test_kssh_provision(self, test_config): # Test the `kssh --provision` flag # we have to run all of the below commands in one run_command call so that environment variables are shared # so ssh-agent can work with outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=1): output = run_command_with_agent(""" bin/kssh --provision ssh -q -o StrictHostKeyChecking=no root@sshd-prod "sha1sum /etc/unique" echo -n foo > /tmp/foo scp /tmp/foo root@sshd-prod:/tmp/foo ssh -q -o StrictHostKeyChecking=no root@sshd-prod "sha1sum /tmp/foo" """) assert_contains_hash(test_config.expected_hash, output) assert hashlib.sha1(b"foo").hexdigest().encode('utf-8') in output assert get_principals("~/.ssh/keybase-signed-key---cert.pub") == set([test_config.subteam + ".ssh.staging", test_config.subteam + ".ssh.root_everywhere"])
def test_kssh_clear_default_bot(self, test_config): # Test that kssh --clear-default-bot clears the default bot with simulate_two_teams(test_config), outputs_audit_log(test_config, filename=test_env_1_log_filename, expected_number=0): run_command_with_agent(f"bin/kssh --set-default-bot {test_config.bot_username}") run_command_with_agent("bin/kssh --clear-default-bot") try: # No default set and no bot specified so it will error out run_command_with_agent("bin/kssh root@sshd-prod") assert False except subprocess.CalledProcessError as e: assert b"Found 2 config files" in e.output