add option proxy to get_certificate module (#60076)

* add option proxy to get_certificate module

* Add python 2.7 or higher to requirements

* Modify requirements and add create_default_context module import check processing

* add changelog file for get_certificate

* Modify changelog file
pull/60412/merge
sky-joker 5 years ago committed by ansibot
parent 25d396fdfc
commit c27b5ae1a3

@ -0,0 +1,2 @@
minor_changes:
- get_certificate - added ``proxy_*`` options.

@ -34,6 +34,17 @@ options:
- The port to connect to - The port to connect to
type: int type: int
required: true required: true
proxy_host:
description:
- Proxy host used when get a certificate.
type: str
version_added: 2.9
proxy_port:
description:
- Proxy port used when get a certificate.
type: int
default: 8080
version_added: 2.9
timeout: timeout:
description: description:
- The timeout in seconds - The timeout in seconds
@ -44,6 +55,7 @@ notes:
- When using ca_cert on OS X it has been reported that in some conditions the validate will always succeed. - When using ca_cert on OS X it has been reported that in some conditions the validate will always succeed.
requirements: requirements:
- "python >= 2.7 when using C(proxy_host)"
- "pyOpenSSL >= 0.15" - "pyOpenSSL >= 0.15"
''' '''
@ -119,8 +131,18 @@ import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from os.path import isfile from os.path import isfile
from ssl import get_server_certificate from ssl import get_server_certificate, DER_cert_to_PEM_cert, CERT_NONE, CERT_OPTIONAL
from socket import setdefaulttimeout from socket import setdefaulttimeout, socket
import atexit
CREATE_DEFAULT_CONTEXT_IMP_ERR = None
try:
from ssl import create_default_context
except ImportError:
CREATE_DEFAULT_CONTEXT_IMP_ERR = traceback.format_exc()
HAS_CREATE_DEFAULT_CONTEXT = False
else:
HAS_CREATE_DEFAULT_CONTEXT = True
PYOPENSSL_IMP_ERR = None PYOPENSSL_IMP_ERR = None
try: try:
@ -138,6 +160,8 @@ def main():
ca_cert=dict(type='path'), ca_cert=dict(type='path'),
host=dict(type='str', required=True), host=dict(type='str', required=True),
port=dict(type='int', required=True), port=dict(type='int', required=True),
proxy_host=dict(type='str'),
proxy_port=dict(type='int', default=8080),
timeout=dict(type='int', default=10), timeout=dict(type='int', default=10),
), ),
) )
@ -145,6 +169,8 @@ def main():
ca_cert = module.params.get('ca_cert') ca_cert = module.params.get('ca_cert')
host = module.params.get('host') host = module.params.get('host')
port = module.params.get('port') port = module.params.get('port')
proxy_host = module.params.get('proxy_host')
proxy_port = module.params.get('proxy_port')
timeout = module.params.get('timeout') timeout = module.params.get('timeout')
result = dict( result = dict(
@ -161,11 +187,39 @@ def main():
if not isfile(ca_cert): if not isfile(ca_cert):
module.fail_json(msg="ca_cert file does not exist") module.fail_json(msg="ca_cert file does not exist")
try: if proxy_host:
cert = get_server_certificate((host, port), ca_certs=ca_cert) if not HAS_CREATE_DEFAULT_CONTEXT:
x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert) module.fail_json(msg='To use proxy_host, you must run the get_certificate module with Python 2.7 or newer.',
except Exception as e: exception=CREATE_DEFAULT_CONTEXT_IMP_ERR)
module.fail_json(msg="Failed to get cert from port with error: {0}".format(e))
try:
connect = "CONNECT %s:%s HTTP/1.0\r\n\r\n" % (host, port)
sock = socket()
atexit.register(sock.close)
sock.connect((proxy_host, proxy_port))
sock.send(connect.encode())
sock.recv(8192)
ctx = create_default_context()
ctx.check_hostname = False
ctx.verify_mode = CERT_NONE
if ca_cert:
ctx.verify_mode = CERT_OPTIONAL
ctx.load_verify_locations(cafile=ca_cert)
cert = ctx.wrap_socket(sock, server_hostname=host).getpeercert(True)
cert = DER_cert_to_PEM_cert(cert)
x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
except Exception as e:
module.fail_json(msg="Failed to get cert from port with error: {0}".format(e))
else:
try:
cert = get_server_certificate((host, port), ca_certs=ca_cert)
x509 = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
except Exception as e:
module.fail_json(msg="Failed to get cert from port with error: {0}".format(e))
result['cert'] = cert result['cert'] = cert
result['subject'] = {} result['subject'] = {}

Loading…
Cancel
Save