-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add way to enable host key validation for SSH/SFTP
- Loading branch information
1 parent
765ed39
commit 90c0099
Showing
18 changed files
with
338 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
"""Utility functions for SSH.""" | ||
|
||
from logging import Logger | ||
|
||
from paramiko import AutoAddPolicy, SSHClient | ||
|
||
|
||
def setup_host_key_validation(client: SSHClient, spec: dict, logger: Logger) -> None: | ||
"""Set up host key validation for an SSH client. | ||
Args: | ||
client (SSHClient): The SSH client to set up. | ||
spec (dict): The spec for the SSH connection. | ||
logger (logging.Logger): The logger to use. | ||
""" | ||
logger.info("Loading system host keys") | ||
client.load_system_host_keys() | ||
|
||
if ( | ||
"hostKeyValidation" in spec["protocol"] | ||
and spec["protocol"]["hostKeyValidation"] | ||
): | ||
if "knownHostsFile" in spec["protocol"]: | ||
host_key = spec["protocol"]["knownHostsFile"] | ||
logger.info(f"Loading host keys from {host_key}") | ||
client.load_host_keys(host_key) | ||
else: | ||
client.set_missing_host_key_policy(AutoAddPolicy()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"type": "transfer", | ||
"source": { | ||
"hostname": "127.0.0.1", | ||
"directory": "/home/application/testFiles/src", | ||
"fileRegex": ".*\\.txt", | ||
"protocol": { | ||
"name": "sftp", | ||
"port": 1234, | ||
"credentials": { | ||
"username": "{{ SSH_USERNAME }}" | ||
} | ||
} | ||
}, | ||
"destination": [ | ||
{ | ||
"hostname": "{{ HOST_D }}", | ||
"directory": "/home/application/testFiles/dest", | ||
"protocol": { | ||
"name": "sftp", | ||
"credentials": { | ||
"username": "{{ SSH_USERNAME }}" | ||
} | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
# pylint: skip-file | ||
# ruff: noqa | ||
import os | ||
from copy import deepcopy | ||
|
||
import pytest | ||
from pytest_shell import fs | ||
|
@@ -79,6 +80,51 @@ def test_basic_execution(setup_ssh_keys, root_dir): | |
assert os.path.exists(f"{root_dir}/testFiles/ssh_2/dest/execution.txt") | ||
|
||
|
||
def test_basic_execution_host_key_validation(setup_ssh_keys, root_dir): | ||
# Run the above test again, but this time with host key validation | ||
ssh_validation_task_definition = deepcopy(touch_task_definition) | ||
ssh_validation_task_definition["protocol"]["hostKeyValidation"] = True | ||
|
||
# Delete the known hosts file if it exists | ||
user_home = os.path.expanduser("~") | ||
known_hosts_file = f"{user_home}/.ssh/known_hosts" | ||
if os.path.exists(known_hosts_file): | ||
os.remove(known_hosts_file) | ||
|
||
execution_obj = execution.Execution( | ||
None, "ssh-host-key-validation", ssh_validation_task_definition | ||
) | ||
|
||
# Run the execution and expect a false status | ||
assert not execution_obj.run() | ||
|
||
# log a load of blank messages | ||
for _ in range(10): | ||
execution_obj.logger.info("") | ||
|
||
# SSH onto the host manually and accept the host key so it's saved to the system known hosts | ||
cmd = "ssh -o StrictHostKeyChecking=no [email protected] echo 'test' && ssh -o StrictHostKeyChecking=no [email protected] echo 'test' " | ||
result = subprocess.run(cmd, shell=True, capture_output=True) | ||
assert result.returncode == 0 | ||
|
||
# Now rerun the execution, but this time it should work | ||
assert execution_obj.run() | ||
|
||
# Move the known host file elsewhere and pass the new location to the protocol definition | ||
known_hosts_file = f"{user_home}/.ssh/known_hosts" | ||
new_known_hosts_file = f"{user_home}/known_hosts.new" | ||
os.rename(known_hosts_file, new_known_hosts_file) | ||
|
||
ssh_validation_task_definition["protocol"]["knownHostsFile"] = new_known_hosts_file | ||
|
||
execution_obj = execution.Execution( | ||
None, "ssh-host-key-validation", ssh_validation_task_definition | ||
) | ||
|
||
# Run the execution and expect a true status | ||
assert execution_obj.run() | ||
|
||
|
||
def test_basic_execution_cmd_failure(setup_ssh_keys, root_dir): | ||
# Write a test file to the source directory | ||
fs.create_files( | ||
|
Oops, something went wrong.