summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Francy <zoredache@users.noreply.github.com>2023-11-22 01:55:01 +0100
committerGitHub <noreply@github.com>2023-11-22 01:55:01 +0100
commita4b00793be46f703e32ee4c440f303d19d2c652d (patch)
tree8340e0643a4e0da8bf82374dd85a311409bf14e9
parentunarchive: support 8 character permission strings (#81705) (diff)
downloadansible-a4b00793be46f703e32ee4c440f303d19d2c652d.tar.xz
ansible-a4b00793be46f703e32ee4c440f303d19d2c652d.zip
Update known_hosts module to better handle @cert-authority keys (#70340)
Signed-off-by: Chris Francy <zoredache@gmail.com> Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
-rw-r--r--changelogs/fragments/known_hosts_cert-authority_keys.yml2
-rw-r--r--lib/ansible/modules/known_hosts.py20
-rw-r--r--test/integration/targets/known_hosts/defaults/main.yml7
-rw-r--r--test/integration/targets/known_hosts/files/existing_known_hosts1
-rw-r--r--test/integration/targets/known_hosts/tasks/main.yml106
5 files changed, 126 insertions, 10 deletions
diff --git a/changelogs/fragments/known_hosts_cert-authority_keys.yml b/changelogs/fragments/known_hosts_cert-authority_keys.yml
new file mode 100644
index 0000000000..0f3e31709c
--- /dev/null
+++ b/changelogs/fragments/known_hosts_cert-authority_keys.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - known_hosts - Fix issue with `@cert-authority` entries in known_hosts incorrectly being removed.
diff --git a/lib/ansible/modules/known_hosts.py b/lib/ansible/modules/known_hosts.py
index b742384fdb..8235258c66 100644
--- a/lib/ansible/modules/known_hosts.py
+++ b/lib/ansible/modules/known_hosts.py
@@ -273,12 +273,20 @@ def search_for_host_key(module, host, key, path, sshkeygen):
module.fail_json(msg="failed to parse output of ssh-keygen for line number: '%s'" % l)
else:
found_key = normalize_known_hosts_key(l)
- if new_key['host'][:3] == '|1|' and found_key['host'][:3] == '|1|': # do not change host hash if already hashed
- new_key['host'] = found_key['host']
- if new_key == found_key: # found a match
- return True, False, found_line # found exactly the same key, don't replace
- elif new_key['type'] == found_key['type']: # found a different key for the same key type
- return True, True, found_line
+
+ if 'options' in found_key and found_key['options'][:15] == '@cert-authority':
+ if new_key == found_key: # found a match
+ return True, False, found_line # found exactly the same key, don't replace
+ elif 'options' in found_key and found_key['options'][:7] == '@revoke':
+ if new_key == found_key: # found a match
+ return True, False, found_line # found exactly the same key, don't replace
+ else:
+ if new_key['host'][:3] == '|1|' and found_key['host'][:3] == '|1|': # do not change host hash if already hashed
+ new_key['host'] = found_key['host']
+ if new_key == found_key: # found a match
+ return True, False, found_line # found exactly the same key, don't replace
+ elif new_key['type'] == found_key['type']: # found a different key for the same key type
+ return True, True, found_line
# No match found, return found and replace, but no line
return True, True, None
diff --git a/test/integration/targets/known_hosts/defaults/main.yml b/test/integration/targets/known_hosts/defaults/main.yml
index cd438430fa..849fb4b9bd 100644
--- a/test/integration/targets/known_hosts/defaults/main.yml
+++ b/test/integration/targets/known_hosts/defaults/main.yml
@@ -1,6 +1,11 @@
---
example_org_rsa_key: >
example.org ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAglyZmHHWskQ9wkh8LYbIqzvg99/oloneH7BaZ02ripJUy/2Zynv4tgUfm9fdXvAb1XXCEuTRnts9FBer87+voU0FPRgx3CfY9Sgr0FspUjnm4lqs53FIab1psddAaS7/F7lrnjl6VqBtPwMRQZG7qlml5uogGJwYJHxX0PGtsdoTJsM=
-
example_org_ed25519_key: >
example.org ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIzlnSq5ESxLgW0avvPk3j7zLV59hcAPkxrMNdnZMKP2
+host_example_com_ed25519_key: >
+ host.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFp8VtD59XAcxkj1qbfCtB1in9nm5WiipORjtVJUBA6I
+example_com_ed25519_ca: >
+ @cert-authority *.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPx6KAHnQhaWdYQoaclJMWfneZckvYOkZ32gUJO1zzJK
+host_example_com_ed25519_signedhost: >
+ host.example.com ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIHgrfzePvYcPiRDh/3yKt2sJBk6mftlLGPpAlgveY8amAAAAIE/humEfyhaw5kawq/RC8tOoVJFgu6v+AYV2koz4bULNAAAAAAAAAAAAAAACAAAAFGhvc3QuZXhhbXBsZS5jb20ucHViAAAAFAAAABBob3N0LmV4YW1wbGUuY29tAAAAAAAAAAD//////////wAAAAAAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAg/HooAedCFpZ1hChpyUkxZ+d5lyS9g6RnfaBQk7XPMkoAAABTAAAAC3NzaC1lZDI1NTE5AAAAQPrSxFZ57dZvHy+ZqhudHBj5C1xU/aiAcMjbpyg3PwR/T/ym8B299uyhRj4g6wbby389xuTFkIYYgGlzh1vAkA0=
diff --git a/test/integration/targets/known_hosts/files/existing_known_hosts b/test/integration/targets/known_hosts/files/existing_known_hosts
index 2564f409b8..7aac98fdde 100644
--- a/test/integration/targets/known_hosts/files/existing_known_hosts
+++ b/test/integration/targets/known_hosts/files/existing_known_hosts
@@ -2,4 +2,5 @@ example.com ssh-dss AAAAB3NzaC1kc3MAAACBALT8YHxZ59d8yX4oQNPbpdK9AMPRQGKFY9X13S2f
|1|d71/U7CbOH3Su+d2zxlbmiNfXtI=|g2YSPAVoK7bmg16FCOOPKTZe2BM= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
|1|L0TqxOhAVh6mLZ2lbHdTv3owun0=|vn0La5pbHNxin3XzQQdvaOulvVU= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCNLCAA/SjVF3jkmlAlkgh+GtZdgxtusHaK66fcA7XSgCpQOdri1dGmND6pQDGwsxiKMy4Ou1GB2DR4N0G9T5E8=
|1|WPo7yAOdlQKLSuRatNJCmDoga0k=|D/QybGglKokWuEQUe9Okpy5uSh0= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBCNLCAA/SjVF3jkmlAlkgh+GtZdgxtusHaK66fcA7XSgCpQOdri1dGmND6pQDGwsxiKMy4Ou1GB2DR4N0G9T5E8=
+@cert-authority *.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDXh1gk2xgS2MekPvo7ZEKiOT7HoyvOAzai2GqoLXGHO
# example.net ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM6OSqweGdPdQ/metQaf738AdN3P+itYp1AypOTgXkyj root@localhost
diff --git a/test/integration/targets/known_hosts/tasks/main.yml b/test/integration/targets/known_hosts/tasks/main.yml
index d5ffec4dc6..2e5ecc7ebb 100644
--- a/test/integration/targets/known_hosts/tasks/main.yml
+++ b/test/integration/targets/known_hosts/tasks/main.yml
@@ -57,7 +57,8 @@
that:
- 'result is changed'
- 'known_hosts.stdout_lines[0].startswith("example.com")'
- - 'known_hosts.stdout_lines[4].startswith("# example.net")'
+ - 'known_hosts.stdout_lines[4].startswith("@cert-authority")'
+ - 'known_hosts.stdout_lines[5].startswith("# example.net")'
- 'known_hosts.stdout_lines[-1].strip() == example_org_rsa_key.strip()'
# test idempotence of addition
@@ -222,7 +223,7 @@
that:
- 'result is changed'
- 'known_hosts_v5.stdout_lines[0].startswith("example.com")'
- - 'known_hosts_v5.stdout_lines[4].startswith("# example.net")'
+ - 'known_hosts_v5.stdout_lines[5].startswith("# example.net")'
- 'known_hosts_v5.stdout_lines[-1].strip().startswith("|1|")'
- 'known_hosts_v5.stdout_lines[-1].strip().endswith(example_org_rsa_key.strip().split()[-1])'
@@ -342,7 +343,7 @@
- name: assert the plaintext host is there
assert:
that:
- - 'known_hosts_v10.stdout_lines[5].strip() == example_org_rsa_key.strip()'
+ - 'known_hosts_v10.stdout_lines[6].strip() == example_org_rsa_key.strip()'
# ... and remove the host again for the next test
@@ -378,6 +379,105 @@
that:
- 'known_hosts_v11.stdout_lines[-1].strip().endswith("RANDOM=")'
+- name: add the ed25519 host key
+ known_hosts:
+ name: host.example.com
+ key: "{{ host_example_com_ed25519_key }}"
+ state: present
+ path: "{{remote_tmp_dir}}/known_hosts"
+ register: result
+
+- name: get the file content
+ command: "cat {{remote_tmp_dir}}/known_hosts"
+ register: known_hosts_v12
+
+- name: assert that the key was added and ordering preserved
+ assert:
+ that:
+ - 'result is changed'
+ - 'known_hosts_v12.stdout_lines[0].startswith("example.com")'
+ - 'known_hosts_v12.stdout_lines[4].startswith("@cert-authority")'
+ - 'known_hosts_v12.stdout_lines[5].startswith("# example.net")'
+ - 'known_hosts_v12.stdout_lines[-1].strip() == host_example_com_ed25519_key.strip()'
+
+- name: add the ed25519 ca key
+ known_hosts:
+ name: '*.example.com'
+ key: "{{ example_com_ed25519_ca }}"
+ state: present
+ path: "{{remote_tmp_dir}}/known_hosts"
+ register: result
+
+- name: get the file content
+ command: "cat {{remote_tmp_dir}}/known_hosts"
+ register: known_hosts_v13
+
+- name: assert that the key was added and ordering preserved
+ assert:
+ that:
+ - 'result is changed'
+ - 'known_hosts_v13.stdout_lines[0].startswith("example.com")'
+ - 'known_hosts_v13.stdout_lines[4].startswith("@cert-authority")'
+ - 'known_hosts_v13.stdout_lines[5].startswith("# example.net")'
+ - 'known_hosts_v13.stdout_lines[-1].strip() == example_com_ed25519_ca.strip()'
+
+- name: Remove the ed25519 ca key
+ known_hosts:
+ name: '*.example.com'
+ key: "{{ example_com_ed25519_ca }}"
+ state: absent
+ path: "{{remote_tmp_dir}}/known_hosts"
+ register: result
+
+- name: get the file content
+ command: "cat {{remote_tmp_dir}}/known_hosts"
+ register: known_hosts_v14
+
+- name: assert that the key was removed and ordering preserved
+ assert:
+ that:
+ - 'result is changed'
+ - 'known_hosts_v12.stdout == known_hosts_v14.stdout'
+
+- name: add the revoked ed25519 host key
+ known_hosts:
+ name: 'host.example.com'
+ key: "@revoked {{ host_example_com_ed25519_signedhost }}"
+ state: present
+ path: "{{remote_tmp_dir}}/known_hosts"
+ register: result
+
+- name: get the file content
+ command: "cat {{remote_tmp_dir}}/known_hosts"
+ register: known_hosts_v15
+
+- name: assert that the key was added and ordering preserved
+ assert:
+ that:
+ - 'result is changed'
+ - 'known_hosts_v15.stdout_lines[0].startswith("example.com")'
+ - 'known_hosts_v15.stdout_lines[4].startswith("@cert-authority")'
+ - 'known_hosts_v15.stdout_lines[5].startswith("# example.net")'
+ - 'known_hosts_v15.stdout_lines[-1].strip() == "@revoked " ~ host_example_com_ed25519_signedhost.strip()'
+
+- name: remove the revoked ed25519 host key
+ known_hosts:
+ name: 'host.example.com'
+ key: "@revoked {{ host_example_com_ed25519_signedhost }}"
+ state: absent
+ path: "{{remote_tmp_dir}}/known_hosts"
+ register: result
+
+- name: get the file content
+ command: "cat {{remote_tmp_dir}}/known_hosts"
+ register: known_hosts_v16
+
+- name: assert that the key was removed and ordering preserved
+ assert:
+ that:
+ - 'result is changed'
+ - 'known_hosts_v12.stdout == known_hosts_v16.stdout'
+
# test errors
- name: Try using a comma separated list of hosts