mirror of https://github.com/ansible/ansible.git
Add support for GSSAPI/Kerberos to urls.py (#72113)
* Add support for GSSAPI/Kerberos to urls.py * Test out changes with the latest test container * Get remote hosts working * Fix up httptester_krb5_password reader * Fix tests for opensuse and macOS * Hopefully last lot of testing changes * Dont do CBT on macOS * Fixes from reviewpull/72211/head
parent
c4acd41d6e
commit
caba47dd3f
@ -0,0 +1,3 @@
|
||||
minor_changes:
|
||||
- Added support for GSSAPI/Kerberos authentication with ``urls.py`` that is used by ``uri`` and ``get_url``.
|
||||
- Added support for specify custom credentials for GSSAPI authentication.
|
@ -0,0 +1,60 @@
|
||||
- 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
|
||||
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'
|
||||
|
||||
- name: skip tests on macOS, I cannot seem to get it to read a credential from a custom ccache
|
||||
when: ansible_facts.distribution != 'MacOSX'
|
||||
block:
|
||||
- name: get Kerberos ticket for implicit auth tests
|
||||
httptester_kinit:
|
||||
username: '{{ krb5_username }}'
|
||||
password: '{{ krb5_password }}'
|
||||
|
||||
- name: test Negotiate auth over HTTPS with implicit credentials
|
||||
get_url:
|
||||
url: https://{{ httpbin_host }}/gssapi
|
||||
dest: '{{ remote_tmp_dir }}/gssapi_implicit.txt'
|
||||
use_gssapi: yes
|
||||
register: https_implicit
|
||||
|
||||
- name: get result of test Negotiate auth over HTTPS with implicit credentials
|
||||
slurp:
|
||||
path: '{{ remote_tmp_dir }}/gssapi_implicit.txt'
|
||||
register: https_implicit_actual
|
||||
|
||||
- name: assert test Negotiate auth with implicit credentials
|
||||
assert:
|
||||
that:
|
||||
- https_implicit.status_code == 200
|
||||
- https_implicit_actual.content | b64decode | trim == 'Microsoft Rulz'
|
@ -0,0 +1,2 @@
|
||||
shippable/posix/group1
|
||||
needs/httptester
|
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright: (c) 2020, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: test_perrcert
|
||||
short_description: Test getting the peer certificate of a HTTP response
|
||||
description: Test getting the peer certificate of a HTTP response.
|
||||
options:
|
||||
url:
|
||||
description: The endpoint to get the peer cert for
|
||||
required: true
|
||||
type: str
|
||||
author:
|
||||
- Ansible Project
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
#
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
#
|
||||
'''
|
||||
|
||||
import base64
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_text
|
||||
from ansible.module_utils.urls import getpeercert, Request
|
||||
|
||||
|
||||
def get_x509_shorthand(name, value):
|
||||
prefix = {
|
||||
'countryName': 'C',
|
||||
'stateOrProvinceName': 'ST',
|
||||
'localityName': 'L',
|
||||
'organizationName': 'O',
|
||||
'commonName': 'CN',
|
||||
'organizationalUnitName': 'OU',
|
||||
}[name]
|
||||
|
||||
return '%s=%s' % (prefix, value)
|
||||
|
||||
|
||||
def main():
|
||||
module_args = dict(
|
||||
url=dict(type='str', required=True),
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=module_args,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
result = {
|
||||
'changed': False,
|
||||
'cert': None,
|
||||
'raw_cert': None,
|
||||
}
|
||||
|
||||
req = Request().get(module.params['url'])
|
||||
try:
|
||||
cert = getpeercert(req)
|
||||
b_cert = getpeercert(req, binary_form=True)
|
||||
|
||||
finally:
|
||||
req.close()
|
||||
|
||||
if cert:
|
||||
processed_cert = {
|
||||
'issuer': '',
|
||||
'not_after': cert.get('notAfter', None),
|
||||
'not_before': cert.get('notBefore', None),
|
||||
'serial_number': cert.get('serialNumber', None),
|
||||
'subject': '',
|
||||
'version': cert.get('version', None),
|
||||
}
|
||||
|
||||
for field in ['issuer', 'subject']:
|
||||
field_values = []
|
||||
for x509_part in cert.get(field, []):
|
||||
field_values.append(get_x509_shorthand(x509_part[0][0], x509_part[0][1]))
|
||||
|
||||
processed_cert[field] = ",".join(field_values)
|
||||
|
||||
result['cert'] = processed_cert
|
||||
|
||||
if b_cert:
|
||||
result['raw_cert'] = to_text(base64.b64encode(b_cert))
|
||||
|
||||
module.exit_json(**result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,3 @@
|
||||
dependencies:
|
||||
- prepare_http_tests
|
||||
- setup_remote_tmp_dir
|
@ -0,0 +1,32 @@
|
||||
- name: get peercert for HTTP connection
|
||||
test_peercert:
|
||||
url: http://{{ httpbin_host }}/get
|
||||
register: cert_http
|
||||
|
||||
- name: assert get peercert for HTTP connection
|
||||
assert:
|
||||
that:
|
||||
- cert_http.raw_cert == None
|
||||
|
||||
- name: get peercert for HTTPS connection
|
||||
test_peercert:
|
||||
url: https://{{ httpbin_host }}/get
|
||||
register: cert_https
|
||||
|
||||
# Alpine does not have openssl, just make sure the text was actually set instead
|
||||
- name: check if openssl is installed
|
||||
command: which openssl
|
||||
ignore_errors: yes
|
||||
register: openssl
|
||||
|
||||
- name: get actual certificate from endpoint
|
||||
shell: echo | openssl s_client -connect {{ httpbin_host }}:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
|
||||
register: cert_https_actual
|
||||
changed_when: no
|
||||
when: openssl is successful
|
||||
|
||||
- name: assert get peercert for HTTPS connection
|
||||
assert:
|
||||
that:
|
||||
- cert_https.raw_cert != None
|
||||
- openssl is failed or cert_https.raw_cert == cert_https_actual.stdout_lines[1:-1] | join("")
|
@ -0,0 +1,4 @@
|
||||
- name: Remove python gssapi
|
||||
pip:
|
||||
name: gssapi
|
||||
state: absent
|
@ -0,0 +1,134 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# Copyright: (c) 2020, Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = r'''
|
||||
---
|
||||
module: httptester_kinit
|
||||
short_description: Get Kerberos ticket
|
||||
description: Get Kerberos ticket using kinit non-interactively.
|
||||
options:
|
||||
username:
|
||||
description: The username to get the ticket for.
|
||||
required: true
|
||||
type: str
|
||||
password:
|
||||
description: The password for I(username).
|
||||
required; true
|
||||
type: str
|
||||
author:
|
||||
- Ansible Project
|
||||
'''
|
||||
|
||||
EXAMPLES = r'''
|
||||
#
|
||||
'''
|
||||
|
||||
RETURN = r'''
|
||||
#
|
||||
'''
|
||||
|
||||
import contextlib
|
||||
import errno
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_text
|
||||
|
||||
try:
|
||||
import configparser
|
||||
except ImportError:
|
||||
import ConfigParser as configparser
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def env_path(name, value, default_value):
|
||||
""" Adds a value to a PATH-like env var and preserve the existing value if present. """
|
||||
orig_value = os.environ.get(name, None)
|
||||
os.environ[name] = '%s:%s' % (value, orig_value or default_value)
|
||||
try:
|
||||
yield
|
||||
|
||||
finally:
|
||||
if orig_value:
|
||||
os.environ[name] = orig_value
|
||||
|
||||
else:
|
||||
del os.environ[name]
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def krb5_conf(module, config):
|
||||
""" Runs with a custom krb5.conf file that extends the existing config if present. """
|
||||
if config:
|
||||
ini_config = configparser.ConfigParser()
|
||||
for section, entries in config.items():
|
||||
ini_config.add_section(section)
|
||||
for key, value in entries.items():
|
||||
ini_config.set(section, key, value)
|
||||
|
||||
config_path = os.path.join(module.tmpdir, 'krb5.conf')
|
||||
with open(config_path, mode='wt') as config_fd:
|
||||
ini_config.write(config_fd)
|
||||
|
||||
with env_path('KRB5_CONFIG', config_path, '/etc/krb5.conf'):
|
||||
yield
|
||||
|
||||
else:
|
||||
yield
|
||||
|
||||
|
||||
def main():
|
||||
module_args = dict(
|
||||
username=dict(type='str', required=True),
|
||||
password=dict(type='str', required=True, no_log=True),
|
||||
)
|
||||
module = AnsibleModule(
|
||||
argument_spec=module_args,
|
||||
required_together=[('username', 'password')],
|
||||
)
|
||||
|
||||
# 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)
|
||||
stdout, stderr = process.communicate()
|
||||
version = to_text(stdout)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
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']
|
||||
config = {}
|
||||
if is_heimdal:
|
||||
kinit_args.append('--password-file=STDIN')
|
||||
config['logging'] = {'krb5': 'FILE:/dev/stdout'}
|
||||
kinit_args.append(to_text(module.params['username'], errors='surrogate_or_strict'))
|
||||
|
||||
with krb5_conf(module, config):
|
||||
# Weirdly setting KRB5_CONFIG in the modules environment block does not work unless we pass it in explicitly.
|
||||
# Take a copy of the existing environment to make sure the process has the same env vars as ours. Also set
|
||||
# KRB5_TRACE to output and debug logs helping to identify problems when calling kinit with MIT.
|
||||
kinit_env = os.environ.copy()
|
||||
kinit_env['KRB5_TRACE'] = '/dev/stdout'
|
||||
|
||||
process = subprocess.Popen(kinit_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
env=kinit_env)
|
||||
stdout, stderr = process.communicate(to_bytes(module.params['password'], errors='surrogate_or_strict') + b'\n')
|
||||
rc = process.returncode
|
||||
|
||||
module.exit_json(changed=True, stdout=to_text(stdout), stderr=to_text(stderr), rc=rc, version=version)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -1,2 +1,3 @@
|
||||
dependencies:
|
||||
- setup_remote_tmp_dir
|
||||
- setup_remote_constraints
|
||||
|
@ -0,0 +1,61 @@
|
||||
- set_fact:
|
||||
krb5_config: '{{ remote_tmp_dir }}/krb5.conf'
|
||||
krb5_realm: '{{ httpbin_host.split(".")[1:] | join(".") | upper }}'
|
||||
krb5_provider: '{{ (ansible_facts.os_family == "FreeBSD" or ansible_facts.distribution == "MacOSX") | ternary("Heimdal", "MIT") }}'
|
||||
|
||||
- set_fact:
|
||||
krb5_username: admin@{{ krb5_realm }}
|
||||
|
||||
- name: Create krb5.conf file
|
||||
template:
|
||||
src: krb5.conf.j2
|
||||
dest: '{{ krb5_config }}'
|
||||
|
||||
- name: Include distribution specific variables
|
||||
include_vars: '{{ lookup("first_found", params) }}'
|
||||
vars:
|
||||
params:
|
||||
files:
|
||||
- '{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml'
|
||||
- '{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml'
|
||||
- '{{ ansible_facts.distribution }}.yml'
|
||||
- '{{ ansible_facts.os_family }}.yml'
|
||||
- default.yml
|
||||
paths:
|
||||
- '{{ role_path }}/vars'
|
||||
|
||||
- name: Install Kerberos sytem packages
|
||||
package:
|
||||
name: '{{ krb5_packages }}'
|
||||
state: present
|
||||
when: ansible_facts.distribution not in ['Alpine', 'MacOSX']
|
||||
|
||||
# apk isn't available on ansible-base so just call command
|
||||
- name: Alpine - Install Kerberos system packages
|
||||
command: apk add {{ krb5_packages | join(' ') }}
|
||||
when: ansible_facts.distribution == 'Alpine'
|
||||
|
||||
- name: Install python gssapi
|
||||
pip:
|
||||
name:
|
||||
- gssapi
|
||||
- importlib ; python_version < '2.7'
|
||||
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'
|
||||
notify: Remove python gssapi
|
||||
|
||||
- name: test the environment to make sure Kerberos is working properly
|
||||
httptester_kinit:
|
||||
username: '{{ krb5_username }}'
|
||||
password: '{{ krb5_password }}'
|
||||
environment:
|
||||
KRB5_CONFIG: '{{ krb5_config }}'
|
||||
KRB5CCNAME: FILE:{{ remote_tmp_dir }}/krb5.cc
|
||||
|
||||
- name: remove test credential cache
|
||||
file:
|
||||
path: '{{ remote_tmp_dir }}/krb5.cc'
|
||||
state: absent
|
@ -0,0 +1,25 @@
|
||||
[libdefaults]
|
||||
default_realm = {{ krb5_realm | upper }}
|
||||
dns_lookup_realm = false
|
||||
dns_lookup_kdc = false
|
||||
rdns = false
|
||||
|
||||
[realms]
|
||||
{{ krb5_realm | upper }} = {
|
||||
{% if krb5_provider == 'Heimdal' %}
|
||||
{# Heimdal seems to only use UDP unless TCP is explicitly set and we must use TCP as the SSH tunnel only supports TCP. #}
|
||||
{# The hostname doesn't seem to work when using the alias, just use localhost as that works. #}
|
||||
kdc = tcp/127.0.0.1
|
||||
admin_server = tcp/127.0.0.1
|
||||
{% else %}
|
||||
kdc = {{ httpbin_host }}
|
||||
admin_server = {{ httpbin_host }}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
.{{ krb5_realm | lower }} = {{ krb5_realm | upper }}
|
||||
{{ krb5_realm | lower }} = {{ krb5_realm | upper }}
|
||||
|
||||
[logging]
|
||||
krb5 = FILE:/dev/stdout
|
@ -0,0 +1,3 @@
|
||||
krb5_packages:
|
||||
- krb5
|
||||
- krb5-dev
|
@ -0,0 +1,3 @@
|
||||
krb5_packages:
|
||||
- krb5-user
|
||||
- libkrb5-dev
|
@ -0,0 +1,2 @@
|
||||
krb5_packages:
|
||||
- heimdal
|
@ -0,0 +1,3 @@
|
||||
krb5_packages:
|
||||
- krb5-client
|
||||
- krb5-devel
|
@ -0,0 +1,3 @@
|
||||
krb5_packages:
|
||||
- krb5-devel
|
||||
- krb5-workstation
|
@ -0,0 +1,76 @@
|
||||
- name: test that endpoint offers Negotiate auth
|
||||
uri:
|
||||
url: http://{{ httpbin_host }}/gssapi
|
||||
status_code: 401
|
||||
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 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
|
||||
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'
|
||||
|
||||
- name: skip tests on macOS, I cannot seem to get it to read a credential from a custom ccache
|
||||
when: ansible_facts.distribution != 'MacOSX'
|
||||
block:
|
||||
- name: get Kerberos ticket for implicit auth tests
|
||||
httptester_kinit:
|
||||
username: '{{ krb5_username }}'
|
||||
password: '{{ krb5_password }}'
|
||||
|
||||
- name: test Negotiate auth over HTTP with implicit credentials
|
||||
uri:
|
||||
url: http://{{ httpbin_host }}/gssapi
|
||||
use_gssapi: yes
|
||||
return_content: yes
|
||||
register: http_implicit
|
||||
|
||||
- name: test Negotiate auth over HTTPS with implicit credentials
|
||||
uri:
|
||||
url: https://{{ httpbin_host }}/gssapi
|
||||
use_gssapi: yes
|
||||
return_content: yes
|
||||
register: https_implicit
|
||||
|
||||
- name: assert test Negotiate auth with implicit credentials
|
||||
assert:
|
||||
that:
|
||||
- http_implicit.status == 200
|
||||
- http_implicit.content | trim == 'Microsoft Rulz'
|
||||
- https_implicit.status == 200
|
||||
- https_implicit.content | trim == 'Microsoft Rulz'
|
@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBjzCCATWgAwIBAgIQeNQTxkMgq4BF9tKogIGXUTAKBggqhkjOPQQ
|
||||
DAjAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUzMDA4MDMxN1
|
||||
oXDTE4MDUzMDA4MjMxN1owFTETMBEGA1UEAwwKU0VSVkVSMjAxNjBZM
|
||||
BMGByqGSM49AgEGCCqGSM49AwEHA0IABDAfXTLOaC3ElgErlgk2tBlM
|
||||
wf9XmGlGBw4vBtMJap1hAqbsdxFm6rhK3QU8PFFpv8Z/AtRG7ba3UwQ
|
||||
prkssClejZzBlMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBg
|
||||
EFBQcDAgYIKwYBBQUHAwEwFQYDVR0RBA4wDIIKU0VSVkVSMjAxNjAdB
|
||||
gNVHQ4EFgQUnFDE8824TYAiBeX4fghEEg33UgYwCgYIKoZIzj0EAwID
|
||||
SAAwRQIhAK3rXA4/0i6nm/U7bi6y618Ci2Is8++M3tYIXnEsA7zSAiA
|
||||
w2s6bJoI+D7Xaey0Hp0gkks9z55y976keIEI+n3qkzw==
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,12 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBjjCCATWgAwIBAgIQHVj2AGEwd6pOOSbcf0skQDAKBggqhkjOPQQ
|
||||
DBDAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUzMDA3NTUzOV
|
||||
oXDTE4MDUzMDA4MTUzOVowFTETMBEGA1UEAwwKU0VSVkVSMjAxNjBZM
|
||||
BMGByqGSM49AgEGCCqGSM49AwEHA0IABL8d9S++MFpfzeH8B3vG/PjA
|
||||
AWg8tGJVgsMw9nR+OfC9ltbTUwhB+yPk3JPcfW/bqsyeUgq4//LhaSp
|
||||
lOWFNaNqjZzBlMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBg
|
||||
EFBQcDAgYIKwYBBQUHAwEwFQYDVR0RBA4wDIIKU0VSVkVSMjAxNjAdB
|
||||
gNVHQ4EFgQUKUkCgLlxoeai0EtQrZth1/BSc5kwCgYIKoZIzj0EAwQD
|
||||
RwAwRAIgRrV7CLpDG7KueyFA3ZDced9dPOcv2Eydx/hgrfxYEcYCIBQ
|
||||
D35JvzmqU05kSFV5eTvkhkaDObd7V55vokhm31+Li
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDZDCCAhugAwIBAgIUbo9YpgkeniC5jRmOgFYX3mcVJn4wPgYJKoZIhvcNAQEK
|
||||
MDGgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQC
|
||||
AgDeMBMxETAPBgNVBAMMCE9NSSBSb290MB4XDTIwMDkwNDE4NTMyNloXDTIxMDkw
|
||||
NDE4NTMyNlowGDEWMBQGA1UEAwwNREMwMS5vbWkudGVzdDCCASIwDQYJKoZIhvcN
|
||||
AQEBBQADggEPADCCAQoCggEBANN++3POgcKcPILMdHWIEPiVENtKoJQ8iqKKeL+/
|
||||
j5oUULVuIn15H/RYMNFmStRIvj0dIL1JAq4W411wG2Tf/6niU2YSKPOAOtrVREef
|
||||
gNvMZ06TYlC8UcGCLv4dBkU3q/FELV66lX9x6LcVwf2f8VWfDg4VNuwyg/eQUIgc
|
||||
/yd5VV+1VXTf39QufVV+/hOtPptu+fBKOIuiuKm6FIqroqLri0Ysp6tWrSd7P6V4
|
||||
6zT2yd17981vaEv5Zek2t39PoLYzJb3rvqQmumgFBIUQ1eMPLFCXX8YYYC/9ByK3
|
||||
mdQaEnkD2eIOARLnojr2A228EgPpdM8phQkDzeWeYnhLiysCAwEAAaNJMEcwCQYD
|
||||
VR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGAYDVR0R
|
||||
BBEwD4INREMwMS5vbWkudGVzdDA+BgkqhkiG9w0BAQowMaANMAsGCWCGSAFlAwQC
|
||||
AaEaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgGiBAICAN4DggEBAA66cbtiysjq
|
||||
sCaDiYyRWCS9af2DGxJ6NAyku2aX+xgmRQzUzFAN5TihcPau+zzpk2zQKHDVMhNx
|
||||
ouhTkIe6mq9KegpUuesWwkJ5KEeuBT949tIru2wAtlSVDvDcau5T9pRI/RLlnsWg
|
||||
0sWaUAh/ujL+VKk6AanC4MRV69llwJcAVxlS/tYjwC74Dr8tMT1TQcVDvywB85e9
|
||||
mA3uz8mGKfiMk2TKD6+6on0UwBMB8NbKSB5bcgp+CJ2ceeblmCOgOcOcV5PCGoFj
|
||||
fgAppr7HjfNPYaIV5l59LfKo2Bj9kXPMqA6/D4gJ3hwoJdY/NOtuNyk8cxWMnWUe
|
||||
+E2Mm6ZnB3Y=
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDZDCCAhugAwIBAgIUbo9YpgkeniC5jRmOgFYX3mcVJoEwPgYJKoZIhvcNAQEK
|
||||
MDGgDTALBglghkgBZQMEAgOhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIDogQC
|
||||
AgC+MBMxETAPBgNVBAMMCE9NSSBSb290MB4XDTIwMDkwNDE4NTMyN1oXDTIxMDkw
|
||||
NDE4NTMyN1owGDEWMBQGA1UEAwwNREMwMS5vbWkudGVzdDCCASIwDQYJKoZIhvcN
|
||||
AQEBBQADggEPADCCAQoCggEBANZMAyRDBn54RfveeVtikepqsyKVKooAc471snl5
|
||||
mEEeo6ZvlOrK1VGGmo/VlF4R9iW6f5iqxG792KXk+lDtx8sbapZWk/aQa+6I9wml
|
||||
p17ocW4Otl7XyQ74UTQlxmrped0rgOk+I2Wu3IC7k64gmf/ZbL9mYN/+v8TlYYyO
|
||||
l8DQbO61XWOJpWt7yf18OxZtPcHH0dkoTEyIxIQcv6FDFNvPjmJzubpDgsfnly7R
|
||||
C0Rc2yPU702vmAfF0SGQbd6KoXUqlfy26C85vU0Fqom1Qo22ehKrfU50vZrXdaJ2
|
||||
gX14pm2kuubMjHtX/+bhNyWTxq4anCOl9/aoObZCM1D3+Y8CAwEAAaNJMEcwCQYD
|
||||
VR0TBAIwADALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwGAYDVR0R
|
||||
BBEwD4INREMwMS5vbWkudGVzdDA+BgkqhkiG9w0BAQowMaANMAsGCWCGSAFlAwQC
|
||||
A6EaMBgGCSqGSIb3DQEBCDALBglghkgBZQMEAgOiBAICAL4DggEBAHgTDTn8onIi
|
||||
XFLZ3sWJ5xCBvXypqC37dKALvXxNSo75SQZpOioG4GSdW3zjJWCiudGs7BselkFv
|
||||
sHK7+5sLKTl1RvxeUoyTxnPZZmVlD3yLq8JBPxu5NScvcRwAcgm3stkq0irRnh7M
|
||||
4Clw6oSKCKI7Lc3gnbvR3QLSYHeZpUcQgVCad6O/Hi+vxFMJT8PVigG0YUoTW010
|
||||
pDpi5uh18RxCqRJnnEC7aDrVarxD9aAvqp1wqwWShfP4FZ9m57DH81RTGD2ZzGgP
|
||||
MsZU5JHVYKkO7IKKIBKuLu+O+X2aZZ4OMlMNBt2DUIJGzEBYV41+3TST9bBPD8xt
|
||||
AAIFCBcgUYY=
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGzCCAgOgAwIBAgIQJzshhViMG5hLHIJHxa+TcTANBgkqhkiG9w0
|
||||
BAQQFADAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUzMDA4MD
|
||||
MxNloXDTE4MDUzMDA4MjMxNlowFTETMBEGA1UEAwwKU0VSVkVSMjAxN
|
||||
jCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN9N5GAzI7uq
|
||||
AVlI6vUqhY5+EZWCWWGRwR3FT2DEXE5++AiJxXO0i0ZfAkLu7UggtBe
|
||||
QwVNkaPD27EYzVUhy1iDo37BrFcLNpfjsjj8wVjaSmQmqvLvrvEh/BT
|
||||
C5SBgDrk2+hiMh9PrpJoB3QAMDinz5aW0rEXMKitPBBiADrczyYrliF
|
||||
AlEU6pTlKEKDUAeP7dKOBlDbCYvBxKnR3ddVH74I5T2SmNBq5gzkbKP
|
||||
nlCXdHLZSh74USu93rKDZQF8YzdTO5dcBreJDJsntyj1o49w9WCt6M7
|
||||
+pg6vKvE+tRbpCm7kXq5B9PDi42Nb6//MzNaMYf9V7v5MHapvVSv3+y
|
||||
sCAwEAAaNnMGUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGA
|
||||
QUFBwMCBggrBgEFBQcDATAVBgNVHREEDjAMggpTRVJWRVIyMDE2MB0G
|
||||
A1UdDgQWBBTh4L2Clr9ber6yfY3JFS3wiECL4DANBgkqhkiG9w0BAQQ
|
||||
FAAOCAQEA0JK/SL7SP9/nvqWp52vnsxVefTFehThle5DLzagmms/9gu
|
||||
oSE2I9XkQIttFMprPosaIZWt7WP42uGcZmoZOzU8kFFYJMfg9Ovyca+
|
||||
gnG28jDUMF1E74KrC7uynJiQJ4vPy8ne7F3XJ592LsNJmK577l42gAW
|
||||
u08p3TvEJFNHy2dBk/IwZp0HIPr9+JcPf7v0uL6lK930xHJHP56XLzN
|
||||
YG8vCMpJFR7wVZp3rXkJQUy3GxyHPJPjS8S43I9j+PoyioWIMEotq2+
|
||||
q0IpXU/KeNFkdGV6VPCmzhykijExOMwO6doUzIUM8orv9jYLHXYC+i6
|
||||
IFKSb6runxF1MAik+GCSA==
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGzCCAgOgAwIBAgIQUDHcKGevZohJV+TkIIYC1DANBgkqhkiG9w0
|
||||
BAQ0FADAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUzMDA4MD
|
||||
MxN1oXDTE4MDUzMDA4MjMxN1owFTETMBEGA1UEAwwKU0VSVkVSMjAxN
|
||||
jCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKr9bo/XXvHt
|
||||
D6Qnhb1wyLg9lDQxxe/enH49LQihtVTZMwGf2010h81QrRUe/bkHTvw
|
||||
K22s2lqj3fUpGxtEbYFWLAHxv6IFnIKd+Zi1zaCPGfas9ekqCSj3vZQ
|
||||
j7lCJVGUGuuqnSDvsed6g2Pz/g6mJUa+TzjxN+8wU5oj5YVUK+aing1
|
||||
zPSA2MDCfx3+YzjxVwNoGixOz6Yx9ijT4pUsAYQAf1o9R+6W1/IpGgu
|
||||
oax714QILT9heqIowwlHzlUZc1UAYs0/JA4CbDZaw9hlJyzMqe/aE46
|
||||
efqPDOpO3vCpOSRcSyzh02WijPvEEaPejQRWg8RX93othZ615MT7dqp
|
||||
ECAwEAAaNnMGUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGA
|
||||
QUFBwMCBggrBgEFBQcDATAVBgNVHREEDjAMggpTRVJWRVIyMDE2MB0G
|
||||
A1UdDgQWBBTgod3R6vejt6kOASAApA19xIG6kTANBgkqhkiG9w0BAQ0
|
||||
FAAOCAQEAVfz0okK2bh3OQE8cWNbJ5PjJRSAJEqVUvYaTlS0Nqkyuaj
|
||||
gicP3hb/pF8FvaVaB6r7LqgBxyW5NNL1xwdNLt60M2zaULL6Fhm1vzM
|
||||
sSMc2ynkyN4++ODwii674YcQAnkUh+ZGIx+CTdZBWJfVM9dZb7QjgBT
|
||||
nVukeFwN2EOOBSpiQSBpcoeJEEAq9csDVRhEfcB8Wtz7TTItgOVsilY
|
||||
dQY56ON5XszjCki6UA3GwdQbBEHjWF2WERqXWrojrSSNOYDvxM5mrEx
|
||||
sG1npzUTsaIr9w8ty1beh/2aToCMREvpiPFOXnVV/ovHMU1lFQTNeQ0
|
||||
OI7elR0nJ0peai30eMpQQ=='
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGzCCAgOgAwIBAgIQJg/Mf5sR55xApJRK+kabbTANBgkqhkiG9w0
|
||||
BAQUFADAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUzMDA4MD
|
||||
MxNloXDTE4MDUzMDA4MjMxNlowFTETMBEGA1UEAwwKU0VSVkVSMjAxN
|
||||
jCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALPKwYikjbzL
|
||||
Lo6JtS6cyytdMMjSrggDoTnRUKauC5/izoYJd+2YVR5YqnluBJZpoFp
|
||||
hkCgFFohUOU7qUsI1SkuGnjI8RmWTrrDsSy62BrfX+AXkoPlXo6IpHz
|
||||
HaEPxjHJdUACpn8QVWTPmdAhwTwQkeUutrm3EOVnKPX4bafNYeAyj7/
|
||||
AGEplgibuXT4/ehbzGKOkRN3ds/pZuf0xc4Q2+gtXn20tQIUt7t6iwh
|
||||
nEWjIgopFL/hX/r5q5MpF6stc1XgIwJjEzqMp76w/HUQVqaYneU4qSG
|
||||
f90ANK/TQ3aDbUNtMC/ULtIfHqHIW4POuBYXaWBsqalJL2VL3YYkKTU
|
||||
sCAwEAAaNnMGUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGA
|
||||
QUFBwMCBggrBgEFBQcDATAVBgNVHREEDjAMggpTRVJWRVIyMDE2MB0G
|
||||
A1UdDgQWBBS1jgojcjPu9vqeP1uSKuiIonGwAjANBgkqhkiG9w0BAQU
|
||||
FAAOCAQEAKjHL6k5Dv/Zb7dvbYEZyx0wVhjHkCTpT3xstI3+TjfAFsu
|
||||
3zMmyFqFqzmr4pWZ/rHc3ObD4pEa24kP9hfB8nmr8oHMLebGmvkzh5h
|
||||
0GYc4dIH7Ky1yfQN51hi7/X5iN7jnnBoCJTTlgeBVYDOEBXhfXi3cLT
|
||||
u3d7nz2heyNq07gFP8iN7MfqdPZndVDYY82imLgsgar9w5d+fvnYM+k
|
||||
XWItNNCUH18M26Obp4Es/Qogo/E70uqkMHost2D+tww/7woXi36X3w/
|
||||
D2yBDyrJMJKZLmDgfpNIeCimncTOzi2IhzqJiOY/4XPsVN/Xqv0/dzG
|
||||
TDdI11kPLq4EiwxvPanCg==
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGzCCAgOgAwIBAgIQWkeAtqoFg6pNWF7xC4YXhTANBgkqhkiG9w0
|
||||
BAQsFADAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUyNzA5MD
|
||||
I0NFoXDTE4MDUyNzA5MjI0NFowFTETMBEGA1UEAwwKU0VSVkVSMjAxN
|
||||
jCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALIPKM5uykFy
|
||||
NmVoLyvPSXGk15ZDqjYi3AbUxVFwCkVImqhefLATit3PkTUYFtAT+TC
|
||||
AwK2E4lOu1XHM+Tmp2KIOnq2oUR8qMEvfxYThEf1MHxkctFljFssZ9N
|
||||
vASDD4lzw8r0Bhl+E5PhR22Eu1Wago5bvIldojkwG+WBxPQv3ZR546L
|
||||
MUZNaBXC0RhuGj5w83lbVz75qM98wvv1ekfZYAP7lrVyHxqCTPDomEU
|
||||
I45tQQZHCZl5nRx1fPCyyYfcfqvFlLWD4Q3PZAbnw6mi0MiWJbGYKME
|
||||
1XGicjqyn/zM9XKA1t/JzChS2bxf6rsyA9I7ibdRHUxsm1JgKry2jfW
|
||||
0CAwEAAaNnMGUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGA
|
||||
QUFBwMCBggrBgEFBQcDATAVBgNVHREEDjAMggpTRVJWRVIyMDE2MB0G
|
||||
A1UdDgQWBBQabLGWg1sn7AXPwYPyfE0ER921ZDANBgkqhkiG9w0BAQs
|
||||
FAAOCAQEAnRohyl6ZmOsTWCtxOJx5A8yr//NweXKwWWmFQXRmCb4bMC
|
||||
xhD4zqLDf5P6RotGV0I/SHvqz+pAtJuwmr+iyAF6WTzo3164LCfnQEu
|
||||
psfrrfMkf3txgDwQkA0oPAw3HEwOnR+tzprw3Yg9x6UoZEhi4XqP9AX
|
||||
R49jU92KrNXJcPlz5MbkzNo5t9nr2f8q39b5HBjaiBJxzdM1hxqsbfD
|
||||
KirTYbkUgPlVOo/NDmopPPb8IX8ubj/XETZG2jixD0zahgcZ1vdr/iZ
|
||||
+50WSXKN2TAKBO2fwoK+2/zIWrGRxJTARfQdF+fGKuj+AERIFNh88HW
|
||||
xSDYjHQAaFMcfdUpa9GGQ==
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGzCCAgOgAwIBAgIQEmj1prSSQYRL2zYBEjsm5jANBgkqhkiG9w0
|
||||
BAQwFADAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUzMDA4MD
|
||||
MxN1oXDTE4MDUzMDA4MjMxN1owFTETMBEGA1UEAwwKU0VSVkVSMjAxN
|
||||
jCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKsK5NvHi4xO
|
||||
081fRLMmPqKsKaHvXgPRykLA0SmKxpGJHfTAZzxojHVeVwOm87IvQj2
|
||||
JUh/yrRwSi5Oqrvqx29l2IC/qQt2xkAQsO51/EWkMQ5OSJsl1MN3NXW
|
||||
eRTKVoUuJzBs8XLmeraxQcBPyyLhq+WpMl/Q4ZDn1FrUEZfxV0POXgU
|
||||
dI3ApuQNRtJOb6iteBIoQyMlnof0RswBUnkiWCA/+/nzR0j33j47IfL
|
||||
nkmU4RtqkBlO13f6+e1GZ4lEcQVI2yZq4Zgu5VVGAFU2lQZ3aEVMTu9
|
||||
8HEqD6heyNp2on5G/K/DCrGWYCBiASjnX3wiSz0BYv8f3HhCgIyVKhJ
|
||||
8CAwEAAaNnMGUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGA
|
||||
QUFBwMCBggrBgEFBQcDATAVBgNVHREEDjAMggpTRVJWRVIyMDE2MB0G
|
||||
A1UdDgQWBBQS/SI61S2UE8xwSgHxbkCTpZXo4TANBgkqhkiG9w0BAQw
|
||||
FAAOCAQEAMVV/WMXd9w4jtDfSrIsKaWKGtHtiMPpAJibXmSakBRwLOn
|
||||
5ZGXL2bWI/Ac2J2Y7bSzs1im2ifwmEqwzzqnpVKShIkZmtij0LS0SEr
|
||||
6Fw5IrK8tD6SH+lMMXUTvp4/lLQlgRCwOWxry/YhQSnuprx8IfSPvil
|
||||
kwZ0Ysim4Aa+X5ojlhHpWB53edX+lFrmR1YWValBnQ5DvnDyFyLR6II
|
||||
Ialp4vmkzI9e3/eOgSArksizAhpXpC9dxQBiHXdhredN0X+1BVzbgzV
|
||||
hQBEwgnAIPa+B68oDILaV0V8hvxrP6jFM4IrKoGS1cq0B+Ns0zkG7ZA
|
||||
2Q0W+3nVwSxIr6bd6hw7g==
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,22 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGzCCAgOgAwIBAgIQUDHcKGevZohJV+TkIIYC1DANBgkqhkiG9w0
|
||||
BAQ0FADAVMRMwEQYDVQQDDApTRVJWRVIyMDE2MB4XDTE3MDUzMDA4MD
|
||||
MxN1oXDTE4MDUzMDA4MjMxN1owFTETMBEGA1UEAwwKU0VSVkVSMjAxN
|
||||
jCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKr9bo/XXvHt
|
||||
D6Qnhb1wyLg9lDQxxe/enH49LQihtVTZMwGf2010h81QrRUe/bkHTvw
|
||||
K22s2lqj3fUpGxtEbYFWLAHxv6IFnIKd+Zi1zaCPGfas9ekqCSj3vZQ
|
||||
j7lCJVGUGuuqnSDvsed6g2Pz/g6mJUa+TzjxN+8wU5oj5YVUK+aing1
|
||||
zPSA2MDCfx3+YzjxVwNoGixOz6Yx9ijT4pUsAYQAf1o9R+6W1/IpGgu
|
||||
oax714QILT9heqIowwlHzlUZc1UAYs0/JA4CbDZaw9hlJyzMqe/aE46
|
||||
efqPDOpO3vCpOSRcSyzh02WijPvEEaPejQRWg8RX93othZ615MT7dqp
|
||||
ECAwEAAaNnMGUwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGA
|
||||
QUFBwMCBggrBgEFBQcDATAVBgNVHREEDjAMggpTRVJWRVIyMDE2MB0G
|
||||
A1UdDgQWBBTgod3R6vejt6kOASAApA19xIG6kTANBgkqhkiG9w0BAQ0
|
||||
FAAOCAQEAVfz0okK2bh3OQE8cWNbJ5PjJRSAJEqVUvYaTlS0Nqkyuaj
|
||||
gicP3hb/pF8FvaVaB6r7LqgBxyW5NNL1xwdNLt60M2zaULL6Fhm1vzM
|
||||
sSMc2ynkyN4++ODwii674YcQAnkUh+ZGIx+CTdZBWJfVM9dZb7QjgBT
|
||||
nVukeFwN2EOOBSpiQSBpcoeJEEAq9csDVRhEfcB8Wtz7TTItgOVsilY
|
||||
dQY56ON5XszjCki6UA3GwdQbBEHjWF2WERqXWrojrSSNOYDvxM5mrEx
|
||||
sG1npzUTsaIr9w8ty1beh/2aToCMREvpiPFOXnVV/ovHMU1lFQTNeQ0
|
||||
OI7elR0nJ0peai30eMpQQ=='
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,74 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# (c) 2020 Ansible Project
|
||||
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
import base64
|
||||
import os.path
|
||||
import pytest
|
||||
|
||||
import ansible.module_utils.urls as urls
|
||||
|
||||
|
||||
@pytest.mark.skipif(not urls.HAS_CRYPTOGRAPHY, reason='Requires cryptography to be installed')
|
||||
@pytest.mark.parametrize('certificate, expected', [
|
||||
('rsa_md5.pem', b'\x23\x34\xB8\x47\x6C\xBF\x4E\x6D'
|
||||
b'\xFC\x76\x6A\x5D\x5A\x30\xD6\x64'
|
||||
b'\x9C\x01\xBA\xE1\x66\x2A\x5C\x3A'
|
||||
b'\x13\x02\xA9\x68\xD7\xC6\xB0\xF6'),
|
||||
('rsa_sha1.pem', b'\x14\xCF\xE8\xE4\xB3\x32\xB2\x0A'
|
||||
b'\x34\x3F\xC8\x40\xB1\x8F\x9F\x6F'
|
||||
b'\x78\x92\x6A\xFE\x7E\xC3\xE7\xB8'
|
||||
b'\xE2\x89\x69\x61\x9B\x1E\x8F\x3E'),
|
||||
('rsa_sha256.pem', b'\x99\x6F\x3E\xEA\x81\x2C\x18\x70'
|
||||
b'\xE3\x05\x49\xFF\x9B\x86\xCD\x87'
|
||||
b'\xA8\x90\xB6\xD8\xDF\xDF\x4A\x81'
|
||||
b'\xBE\xF9\x67\x59\x70\xDA\xDB\x26'),
|
||||
('rsa_sha384.pem', b'\x34\xF3\x03\xC9\x95\x28\x6F\x4B'
|
||||
b'\x21\x4A\x9B\xA6\x43\x5B\x69\xB5'
|
||||
b'\x1E\xCF\x37\x58\xEA\xBC\x2A\x14'
|
||||
b'\xD7\xA4\x3F\xD2\x37\xDC\x2B\x1A'
|
||||
b'\x1A\xD9\x11\x1C\x5C\x96\x5E\x10'
|
||||
b'\x75\x07\xCB\x41\x98\xC0\x9F\xEC'),
|
||||
('rsa_sha512.pem', b'\x55\x6E\x1C\x17\x84\xE3\xB9\x57'
|
||||
b'\x37\x0B\x7F\x54\x4F\x62\xC5\x33'
|
||||
b'\xCB\x2C\xA5\xC1\xDA\xE0\x70\x6F'
|
||||
b'\xAE\xF0\x05\x44\xE1\xAD\x2B\x76'
|
||||
b'\xFF\x25\xCF\xBE\x69\xB1\xC4\xE6'
|
||||
b'\x30\xC3\xBB\x02\x07\xDF\x11\x31'
|
||||
b'\x4C\x67\x38\xBC\xAE\xD7\xE0\x71'
|
||||
b'\xD7\xBF\xBF\x2C\x9D\xFA\xB8\x5D'),
|
||||
('rsa-pss_sha256.pem', b'\xF2\x31\xE6\xFF\x3F\x9E\x16\x1B'
|
||||
b'\xC2\xDC\xBB\x89\x8D\x84\x47\x4E'
|
||||
b'\x58\x9C\xD7\xC2\x7A\xDB\xEF\x8B'
|
||||
b'\xD9\xC0\xC0\x68\xAF\x9C\x36\x6D'),
|
||||
('rsa-pss_sha512.pem', b'\x85\x85\x19\xB9\xE1\x0F\x23\xE2'
|
||||
b'\x1D\x2C\xE9\xD5\x47\x2A\xAB\xCE'
|
||||
b'\x42\x0F\xD1\x00\x75\x9C\x53\xA1'
|
||||
b'\x7B\xB9\x79\x86\xB2\x59\x61\x27'),
|
||||
('ecdsa_sha256.pem', b'\xFE\xCF\x1B\x25\x85\x44\x99\x90'
|
||||
b'\xD9\xE3\xB2\xC9\x2D\x3F\x59\x7E'
|
||||
b'\xC8\x35\x4E\x12\x4E\xDA\x75\x1D'
|
||||
b'\x94\x83\x7C\x2C\x89\xA2\xC1\x55'),
|
||||
('ecdsa_sha512.pem', b'\xE5\xCB\x68\xB2\xF8\x43\xD6\x3B'
|
||||
b'\xF4\x0B\xCB\x20\x07\x60\x8F\x81'
|
||||
b'\x97\x61\x83\x92\x78\x3F\x23\x30'
|
||||
b'\xE5\xEF\x19\xA5\xBD\x8F\x0B\x2F'
|
||||
b'\xAA\xC8\x61\x85\x5F\xBB\x63\xA2'
|
||||
b'\x21\xCC\x46\xFC\x1E\x22\x6A\x07'
|
||||
b'\x24\x11\xAF\x17\x5D\xDE\x47\x92'
|
||||
b'\x81\xE0\x06\x87\x8B\x34\x80\x59'),
|
||||
])
|
||||
def test_cbt_with_cert(certificate, expected):
|
||||
with open(os.path.join(os.path.dirname(__file__), 'fixtures', 'cbt', certificate)) as fd:
|
||||
cert_der = base64.b64decode("".join([l.strip() for l in fd.readlines()[1:-1]]))
|
||||
|
||||
actual = urls.get_channel_binding_cert_hash(cert_der)
|
||||
assert actual == expected
|
||||
|
||||
|
||||
def test_cbt_no_cryptography(monkeypatch):
|
||||
monkeypatch.setattr(urls, 'HAS_CRYPTOGRAPHY', False)
|
||||
assert urls.get_channel_binding_cert_hash(None) is None
|
Loading…
Reference in New Issue