From aee7a3ed6809c93a81307466503eec630a343d9e Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Thu, 12 Nov 2020 13:40:59 +1000 Subject: [PATCH] Fix FreeBSD HTTP Kerberos setup (#72595) --- .../targets/get_url/tasks/use_gssapi.yml | 41 +++++---------- .../library/httptester_kinit.py | 20 ++++--- .../prepare_http_tests/tasks/kerberos.yml | 6 ++- .../targets/uri/tasks/use_gssapi.yml | 52 +++++++------------ 4 files changed, 48 insertions(+), 71 deletions(-) diff --git a/test/integration/targets/get_url/tasks/use_gssapi.yml b/test/integration/targets/get_url/tasks/use_gssapi.yml index 121cbacd100..f3d2d1fbeb1 100644 --- a/test/integration/targets/get_url/tasks/use_gssapi.yml +++ b/test/integration/targets/get_url/tasks/use_gssapi.yml @@ -1,37 +1,22 @@ -- name: Skip explicit auth tests on FreeBSD as Heimdal there does not have gss_acquire_cred_with_password - when: ansible_facts.os_family != 'FreeBSD' - block: - - name: test Negotiate auth over HTTP with explicit credentials - get_url: - url: http://{{ httpbin_host }}/gssapi - dest: '{{ remote_tmp_dir }}/gssapi_explicit.txt' - use_gssapi: yes - url_username: '{{ krb5_username }}' - url_password: '{{ krb5_password }}' - register: http_explicit - - - name: get result of test Negotiate auth over HTTP with explicit credentials - slurp: - path: '{{ remote_tmp_dir }}/gssapi_explicit.txt' - register: http_explicit_actual - - - name: assert test Negotiate auth with implicit credentials - assert: - that: - - http_explicit.status_code == 200 - - http_explicit_actual.content | b64decode | trim == 'Microsoft Rulz' - -- name: FreeBSD - verify it fails with explicit credential +- name: test Negotiate auth over HTTP with explicit credentials get_url: url: http://{{ httpbin_host }}/gssapi dest: '{{ remote_tmp_dir }}/gssapi_explicit.txt' use_gssapi: yes url_username: '{{ krb5_username }}' url_password: '{{ krb5_password }}' - register: explicit_failure - when: ansible_facts.os_family == 'FreeBSD' - failed_when: - - '"Platform GSSAPI library does not support gss_acquire_cred_with_password, cannot acquire GSSAPI credential with explicit username and password" not in explicit_failure.msg' + register: http_explicit + +- name: get result of test Negotiate auth over HTTP with explicit credentials + slurp: + path: '{{ remote_tmp_dir }}/gssapi_explicit.txt' + register: http_explicit_actual + +- name: assert test Negotiate auth with implicit credentials + assert: + that: + - http_explicit.status_code == 200 + - http_explicit_actual.content | b64decode | trim == 'Microsoft Rulz' - name: skip tests on macOS, I cannot seem to get it to read a credential from a custom ccache when: ansible_facts.distribution != 'MacOSX' diff --git a/test/integration/targets/prepare_http_tests/library/httptester_kinit.py b/test/integration/targets/prepare_http_tests/library/httptester_kinit.py index 3a93c17df44..4f7b7ad4db3 100644 --- a/test/integration/targets/prepare_http_tests/library/httptester_kinit.py +++ b/test/integration/targets/prepare_http_tests/library/httptester_kinit.py @@ -92,9 +92,19 @@ def main(): required_together=[('username', 'password')], ) + # Heimdal has a few quirks that we want to paper over in this module + # 1. KRB5_TRACE does not work in any released version (<=7.7), we need to use a custom krb5.config to enable it + # 2. When reading the password it reads from the pty not stdin by default causing an issue with subprocess. We + # can control that behaviour with '--password-file=STDIN' + # Also need to set the custom path to krb5-config and kinit as FreeBSD relies on the newer Heimdal version in the + # port package. + sysname = os.uname()[0] + prefix = '/usr/local/bin/' if sysname == 'FreeBSD' else '' + is_heimdal = sysname in ['Darwin', 'FreeBSD'] + # Debugging purposes, get the Kerberos version. On platforms like OpenSUSE this may not be on the PATH. try: - process = subprocess.Popen(['krb5-config', '--version'], stdout=subprocess.PIPE) + process = subprocess.Popen(['%skrb5-config' % prefix, '--version'], stdout=subprocess.PIPE) stdout, stderr = process.communicate() version = to_text(stdout) except OSError as e: @@ -102,13 +112,7 @@ def main(): raise version = 'Unknown (no krb5-config)' - # Heimdal has a few quirks that we want to paper over in this module - # 1. KRB5_TRACE does not work in any released version (<=7.7), we need to use a custom krb5.config to enable it - # 2. When reading the password it reads from the pty not stdin by default causing an issue with subprocess. We - # can control that behaviour with '--password-file=STDIN' - is_heimdal = os.uname()[0] in ['Darwin', 'FreeBSD'] - - kinit_args = ['kinit'] + kinit_args = ['%skinit' % prefix] config = {} if is_heimdal: kinit_args.append('--password-file=STDIN') diff --git a/test/integration/targets/prepare_http_tests/tasks/kerberos.yml b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml index 9d5956fb4d2..d9fc56a4eb5 100644 --- a/test/integration/targets/prepare_http_tests/tasks/kerberos.yml +++ b/test/integration/targets/prepare_http_tests/tasks/kerberos.yml @@ -43,8 +43,10 @@ state: present extra_args: '-c {{ remote_constraints }}' environment: - # Need this custom path for OpenSUSE as krb5-config is placed there - PATH: '{{ ansible_facts.env.PATH }}:/usr/lib/mit/bin' + # Put /usr/local/bin for FreeBSD as we need to use the heimdal port over the builtin version + # https://github.com/pythongssapi/python-gssapi/issues/228 + # Need the /usr/lib/mit/bin custom path for OpenSUSE as krb5-config is placed there + PATH: '/usr/local/bin:{{ ansible_facts.env.PATH }}:/usr/lib/mit/bin' notify: Remove python gssapi - name: test the environment to make sure Kerberos is working properly diff --git a/test/integration/targets/uri/tasks/use_gssapi.yml b/test/integration/targets/uri/tasks/use_gssapi.yml index 2a084888dd3..6629cee7da1 100644 --- a/test/integration/targets/uri/tasks/use_gssapi.yml +++ b/test/integration/targets/uri/tasks/use_gssapi.yml @@ -5,45 +5,31 @@ register: no_auth_failure failed_when: no_auth_failure.www_authenticate != 'Negotiate' -- name: Skip explicit auth tests on FreeBSD as Heimdal there does not have gss_acquire_cred_with_password - when: ansible_facts.os_family != 'FreeBSD' - block: - - name: test Negotiate auth over HTTP with explicit credentials - uri: - url: http://{{ httpbin_host }}/gssapi - use_gssapi: yes - url_username: '{{ krb5_username }}' - url_password: '{{ krb5_password }}' - return_content: yes - register: http_explicit +- name: test Negotiate auth over HTTP with explicit credentials + uri: + url: http://{{ httpbin_host }}/gssapi + use_gssapi: yes + url_username: '{{ krb5_username }}' + url_password: '{{ krb5_password }}' + return_content: yes + register: http_explicit - - name: test Negotiate auth over HTTPS with explicit credentials - uri: - url: https://{{ httpbin_host }}/gssapi - use_gssapi: yes - url_username: '{{ krb5_username }}' - url_password: '{{ krb5_password }}' - return_content: yes - register: https_explicit - - - name: assert test Negotiate auth with implicit credentials - assert: - that: - - http_explicit.status == 200 - - http_explicit.content | trim == 'Microsoft Rulz' - - https_explicit.status == 200 - - https_explicit.content | trim == 'Microsoft Rulz' - -- name: FreeBSD - verify it fails with explicit credential +- name: test Negotiate auth over HTTPS with explicit credentials uri: url: https://{{ httpbin_host }}/gssapi use_gssapi: yes url_username: '{{ krb5_username }}' url_password: '{{ krb5_password }}' - register: explicit_failure - when: ansible_facts.os_family == 'FreeBSD' - failed_when: - - '"Platform GSSAPI library does not support gss_acquire_cred_with_password, cannot acquire GSSAPI credential with explicit username and password" not in explicit_failure.msg' + return_content: yes + register: https_explicit + +- name: assert test Negotiate auth with implicit credentials + assert: + that: + - http_explicit.status == 200 + - http_explicit.content | trim == 'Microsoft Rulz' + - https_explicit.status == 200 + - https_explicit.content | trim == 'Microsoft Rulz' - name: skip tests on macOS, I cannot seem to get it to read a credential from a custom ccache when: ansible_facts.distribution != 'MacOSX'