|
|
0a07cd |
From 8e168f17b0c138d589f7b3bea4a4b6fcc8e5e03f Mon Sep 17 00:00:00 2001
|
|
|
0a07cd |
From: Eduardo Otubo <otubo@redhat.com>
|
|
|
0a07cd |
Date: Wed, 6 Mar 2019 14:20:18 +0100
|
|
|
0a07cd |
Subject: azure: Filter list of ssh keys pulled from fabric
|
|
|
0a07cd |
|
|
|
0a07cd |
RH-Author: Eduardo Otubo <otubo@redhat.com>
|
|
|
0a07cd |
Message-id: <20190306142018.8902-1-otubo@redhat.com>
|
|
|
0a07cd |
Patchwork-id: 84807
|
|
|
0a07cd |
O-Subject: [RHEL-7.7 cloud-init PATCH] azure: Filter list of ssh keys pulled from fabric
|
|
|
0a07cd |
Bugzilla: 1684040
|
|
|
0a07cd |
RH-Acked-by: Cathy Avery <cavery@redhat.com>
|
|
|
0a07cd |
RH-Acked-by: Vitaly Kuznetsov <vkuznets@redhat.com>
|
|
|
0a07cd |
|
|
|
0a07cd |
From: "Jason Zions (MSFT)" <jasonzio@microsoft.com>
|
|
|
0a07cd |
|
|
|
0a07cd |
commit 34f54360fcc1e0f805002a0b639d0a84eb2cb8ee
|
|
|
0a07cd |
Author: Jason Zions (MSFT) <jasonzio@microsoft.com>
|
|
|
0a07cd |
Date: Fri Feb 22 13:26:31 2019 +0000
|
|
|
0a07cd |
|
|
|
0a07cd |
azure: Filter list of ssh keys pulled from fabric
|
|
|
0a07cd |
|
|
|
0a07cd |
The Azure data source is expected to expose a list of
|
|
|
0a07cd |
ssh keys for the user-to-be-provisioned in the crawled
|
|
|
0a07cd |
metadata. When configured to use the __builtin__ agent
|
|
|
0a07cd |
this list is built by the WALinuxAgentShim. The shim
|
|
|
0a07cd |
retrieves the full set of certificates and public keys
|
|
|
0a07cd |
exposed to the VM from the wireserver, extracts any
|
|
|
0a07cd |
ssh keys it can, and returns that list.
|
|
|
0a07cd |
|
|
|
0a07cd |
This fix reduces that list of ssh keys to just the
|
|
|
0a07cd |
ones whose fingerprints appear in the "administrative
|
|
|
0a07cd |
user" section of the ovf-env.xml file. The Azure
|
|
|
0a07cd |
control plane exposes other ssh keys to the VM for
|
|
|
0a07cd |
other reasons, but those should not be added to the
|
|
|
0a07cd |
authorized_keys file for the provisioned user.
|
|
|
0a07cd |
|
|
|
0a07cd |
Signed-off-by: Eduardo Otubo <otubo@redhat.com>
|
|
|
0a07cd |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
0a07cd |
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
|
|
|
0a07cd |
---
|
|
|
0a07cd |
cloudinit/sources/DataSourceAzure.py | 13 +-
|
|
|
0a07cd |
cloudinit/sources/helpers/azure.py | 109 +++++++++----
|
|
|
0a07cd |
.../azure/parse_certificates_fingerprints | 4 +
|
|
|
0a07cd |
tests/data/azure/parse_certificates_pem | 152 ++++++++++++++++++
|
|
|
0a07cd |
tests/data/azure/pubkey_extract_cert | 13 ++
|
|
|
0a07cd |
tests/data/azure/pubkey_extract_ssh_key | 1 +
|
|
|
0a07cd |
.../test_datasource/test_azure_helper.py | 71 +++++++-
|
|
|
0a07cd |
7 files changed, 322 insertions(+), 41 deletions(-)
|
|
|
0a07cd |
create mode 100644 tests/data/azure/parse_certificates_fingerprints
|
|
|
0a07cd |
create mode 100644 tests/data/azure/parse_certificates_pem
|
|
|
0a07cd |
create mode 100644 tests/data/azure/pubkey_extract_cert
|
|
|
0a07cd |
create mode 100644 tests/data/azure/pubkey_extract_ssh_key
|
|
|
0a07cd |
|
|
|
0a07cd |
diff --git a/cloudinit/sources/DataSourceAzure.py b/cloudinit/sources/DataSourceAzure.py
|
|
|
0a07cd |
index 7dbeb04c..2062ca5d 100644
|
|
|
0a07cd |
--- a/cloudinit/sources/DataSourceAzure.py
|
|
|
0a07cd |
+++ b/cloudinit/sources/DataSourceAzure.py
|
|
|
0a07cd |
@@ -627,9 +627,11 @@ class DataSourceAzure(sources.DataSource):
|
|
|
0a07cd |
if self.ds_cfg['agent_command'] == AGENT_START_BUILTIN:
|
|
|
0a07cd |
self.bounce_network_with_azure_hostname()
|
|
|
0a07cd |
|
|
|
0a07cd |
+ pubkey_info = self.cfg.get('_pubkeys', None)
|
|
|
0a07cd |
metadata_func = partial(get_metadata_from_fabric,
|
|
|
0a07cd |
fallback_lease_file=self.
|
|
|
0a07cd |
- dhclient_lease_file)
|
|
|
0a07cd |
+ dhclient_lease_file,
|
|
|
0a07cd |
+ pubkey_info=pubkey_info)
|
|
|
0a07cd |
else:
|
|
|
0a07cd |
metadata_func = self.get_metadata_from_agent
|
|
|
0a07cd |
|
|
|
0a07cd |
@@ -642,6 +644,7 @@ class DataSourceAzure(sources.DataSource):
|
|
|
0a07cd |
"Error communicating with Azure fabric; You may experience."
|
|
|
0a07cd |
"connectivity issues.", exc_info=True)
|
|
|
0a07cd |
return False
|
|
|
0a07cd |
+
|
|
|
0a07cd |
util.del_file(REPORTED_READY_MARKER_FILE)
|
|
|
0a07cd |
util.del_file(REPROVISION_MARKER_FILE)
|
|
|
0a07cd |
return fabric_data
|
|
|
0a07cd |
@@ -909,13 +912,15 @@ def find_child(node, filter_func):
|
|
|
0a07cd |
def load_azure_ovf_pubkeys(sshnode):
|
|
|
0a07cd |
# This parses a 'SSH' node formatted like below, and returns
|
|
|
0a07cd |
# an array of dicts.
|
|
|
0a07cd |
- # [{'fp': '6BE7A7C3C8A8F4B123CCA5D0C2F1BE4CA7B63ED7',
|
|
|
0a07cd |
- # 'path': 'where/to/go'}]
|
|
|
0a07cd |
+ # [{'fingerprint': '6BE7A7C3C8A8F4B123CCA5D0C2F1BE4CA7B63ED7',
|
|
|
0a07cd |
+ # 'path': '/where/to/go'}]
|
|
|
0a07cd |
#
|
|
|
0a07cd |
# <SSH><PublicKeys>
|
|
|
0a07cd |
- # <PublicKey><Fingerprint>ABC</FingerPrint><Path>/ABC</Path>
|
|
|
0a07cd |
+ # <PublicKey><Fingerprint>ABC</FingerPrint><Path>/x/y/z</Path>
|
|
|
0a07cd |
# ...
|
|
|
0a07cd |
# </PublicKeys></SSH>
|
|
|
0a07cd |
+ # Under some circumstances, there may be a <Value> element along with the
|
|
|
0a07cd |
+ # Fingerprint and Path. Pass those along if they appear.
|
|
|
0a07cd |
results = find_child(sshnode, lambda n: n.localName == "PublicKeys")
|
|
|
0a07cd |
if len(results) == 0:
|
|
|
0a07cd |
return []
|
|
|
0a07cd |
diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
|
|
|
0a07cd |
index e5696b1f..2829dd20 100644
|
|
|
0a07cd |
--- a/cloudinit/sources/helpers/azure.py
|
|
|
0a07cd |
+++ b/cloudinit/sources/helpers/azure.py
|
|
|
0a07cd |
@@ -138,9 +138,36 @@ class OpenSSLManager(object):
|
|
|
0a07cd |
self.certificate = certificate
|
|
|
0a07cd |
LOG.debug('New certificate generated.')
|
|
|
0a07cd |
|
|
|
0a07cd |
- def parse_certificates(self, certificates_xml):
|
|
|
0a07cd |
- tag = ElementTree.fromstring(certificates_xml).find(
|
|
|
0a07cd |
- './/Data')
|
|
|
0a07cd |
+ @staticmethod
|
|
|
0a07cd |
+ def _run_x509_action(action, cert):
|
|
|
0a07cd |
+ cmd = ['openssl', 'x509', '-noout', action]
|
|
|
0a07cd |
+ result, _ = util.subp(cmd, data=cert)
|
|
|
0a07cd |
+ return result
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ def _get_ssh_key_from_cert(self, certificate):
|
|
|
0a07cd |
+ pub_key = self._run_x509_action('-pubkey', certificate)
|
|
|
0a07cd |
+ keygen_cmd = ['ssh-keygen', '-i', '-m', 'PKCS8', '-f', '/dev/stdin']
|
|
|
0a07cd |
+ ssh_key, _ = util.subp(keygen_cmd, data=pub_key)
|
|
|
0a07cd |
+ return ssh_key
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ def _get_fingerprint_from_cert(self, certificate):
|
|
|
0a07cd |
+ """openssl x509 formats fingerprints as so:
|
|
|
0a07cd |
+ 'SHA1 Fingerprint=07:3E:19:D1:4D:1C:79:92:24:C6:A0:FD:8D:DA:\
|
|
|
0a07cd |
+ B6:A8:BF:27:D4:73\n'
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ Azure control plane passes that fingerprint as so:
|
|
|
0a07cd |
+ '073E19D14D1C799224C6A0FD8DDAB6A8BF27D473'
|
|
|
0a07cd |
+ """
|
|
|
0a07cd |
+ raw_fp = self._run_x509_action('-fingerprint', certificate)
|
|
|
0a07cd |
+ eq = raw_fp.find('=')
|
|
|
0a07cd |
+ octets = raw_fp[eq+1:-1].split(':')
|
|
|
0a07cd |
+ return ''.join(octets)
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ def _decrypt_certs_from_xml(self, certificates_xml):
|
|
|
0a07cd |
+ """Decrypt the certificates XML document using the our private key;
|
|
|
0a07cd |
+ return the list of certs and private keys contained in the doc.
|
|
|
0a07cd |
+ """
|
|
|
0a07cd |
+ tag = ElementTree.fromstring(certificates_xml).find('.//Data')
|
|
|
0a07cd |
certificates_content = tag.text
|
|
|
0a07cd |
lines = [
|
|
|
0a07cd |
b'MIME-Version: 1.0',
|
|
|
0a07cd |
@@ -151,32 +178,30 @@ class OpenSSLManager(object):
|
|
|
0a07cd |
certificates_content.encode('utf-8'),
|
|
|
0a07cd |
]
|
|
|
0a07cd |
with cd(self.tmpdir):
|
|
|
0a07cd |
- with open('Certificates.p7m', 'wb') as f:
|
|
|
0a07cd |
- f.write(b'\n'.join(lines))
|
|
|
0a07cd |
out, _ = util.subp(
|
|
|
0a07cd |
- 'openssl cms -decrypt -in Certificates.p7m -inkey'
|
|
|
0a07cd |
+ 'openssl cms -decrypt -in /dev/stdin -inkey'
|
|
|
0a07cd |
' {private_key} -recip {certificate} | openssl pkcs12 -nodes'
|
|
|
0a07cd |
' -password pass:'.format(**self.certificate_names),
|
|
|
0a07cd |
- shell=True)
|
|
|
0a07cd |
- private_keys, certificates = [], []
|
|
|
0a07cd |
+ shell=True, data=b'\n'.join(lines))
|
|
|
0a07cd |
+ return out
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ def parse_certificates(self, certificates_xml):
|
|
|
0a07cd |
+ """Given the Certificates XML document, return a dictionary of
|
|
|
0a07cd |
+ fingerprints and associated SSH keys derived from the certs."""
|
|
|
0a07cd |
+ out = self._decrypt_certs_from_xml(certificates_xml)
|
|
|
0a07cd |
current = []
|
|
|
0a07cd |
+ keys = {}
|
|
|
0a07cd |
for line in out.splitlines():
|
|
|
0a07cd |
current.append(line)
|
|
|
0a07cd |
if re.match(r'[-]+END .*?KEY[-]+$', line):
|
|
|
0a07cd |
- private_keys.append('\n'.join(current))
|
|
|
0a07cd |
+ # ignore private_keys
|
|
|
0a07cd |
current = []
|
|
|
0a07cd |
elif re.match(r'[-]+END .*?CERTIFICATE[-]+$', line):
|
|
|
0a07cd |
- certificates.append('\n'.join(current))
|
|
|
0a07cd |
+ certificate = '\n'.join(current)
|
|
|
0a07cd |
+ ssh_key = self._get_ssh_key_from_cert(certificate)
|
|
|
0a07cd |
+ fingerprint = self._get_fingerprint_from_cert(certificate)
|
|
|
0a07cd |
+ keys[fingerprint] = ssh_key
|
|
|
0a07cd |
current = []
|
|
|
0a07cd |
- keys = []
|
|
|
0a07cd |
- for certificate in certificates:
|
|
|
0a07cd |
- with cd(self.tmpdir):
|
|
|
0a07cd |
- public_key, _ = util.subp(
|
|
|
0a07cd |
- 'openssl x509 -noout -pubkey |'
|
|
|
0a07cd |
- 'ssh-keygen -i -m PKCS8 -f /dev/stdin',
|
|
|
0a07cd |
- data=certificate,
|
|
|
0a07cd |
- shell=True)
|
|
|
0a07cd |
- keys.append(public_key)
|
|
|
0a07cd |
return keys
|
|
|
0a07cd |
|
|
|
0a07cd |
|
|
|
0a07cd |
@@ -206,7 +231,6 @@ class WALinuxAgentShim(object):
|
|
|
0a07cd |
self.dhcpoptions = dhcp_options
|
|
|
0a07cd |
self._endpoint = None
|
|
|
0a07cd |
self.openssl_manager = None
|
|
|
0a07cd |
- self.values = {}
|
|
|
0a07cd |
self.lease_file = fallback_lease_file
|
|
|
0a07cd |
|
|
|
0a07cd |
def clean_up(self):
|
|
|
0a07cd |
@@ -328,8 +352,9 @@ class WALinuxAgentShim(object):
|
|
|
0a07cd |
LOG.debug('Azure endpoint found at %s', endpoint_ip_address)
|
|
|
0a07cd |
return endpoint_ip_address
|
|
|
0a07cd |
|
|
|
0a07cd |
- def register_with_azure_and_fetch_data(self):
|
|
|
0a07cd |
- self.openssl_manager = OpenSSLManager()
|
|
|
0a07cd |
+ def register_with_azure_and_fetch_data(self, pubkey_info=None):
|
|
|
0a07cd |
+ if self.openssl_manager is None:
|
|
|
0a07cd |
+ self.openssl_manager = OpenSSLManager()
|
|
|
0a07cd |
http_client = AzureEndpointHttpClient(self.openssl_manager.certificate)
|
|
|
0a07cd |
LOG.info('Registering with Azure...')
|
|
|
0a07cd |
attempts = 0
|
|
|
0a07cd |
@@ -347,16 +372,37 @@ class WALinuxAgentShim(object):
|
|
|
0a07cd |
attempts += 1
|
|
|
0a07cd |
LOG.debug('Successfully fetched GoalState XML.')
|
|
|
0a07cd |
goal_state = GoalState(response.contents, http_client)
|
|
|
0a07cd |
- public_keys = []
|
|
|
0a07cd |
- if goal_state.certificates_xml is not None:
|
|
|
0a07cd |
+ ssh_keys = []
|
|
|
0a07cd |
+ if goal_state.certificates_xml is not None and pubkey_info is not None:
|
|
|
0a07cd |
LOG.debug('Certificate XML found; parsing out public keys.')
|
|
|
0a07cd |
- public_keys = self.openssl_manager.parse_certificates(
|
|
|
0a07cd |
+ keys_by_fingerprint = self.openssl_manager.parse_certificates(
|
|
|
0a07cd |
goal_state.certificates_xml)
|
|
|
0a07cd |
- data = {
|
|
|
0a07cd |
- 'public-keys': public_keys,
|
|
|
0a07cd |
- }
|
|
|
0a07cd |
+ ssh_keys = self._filter_pubkeys(keys_by_fingerprint, pubkey_info)
|
|
|
0a07cd |
self._report_ready(goal_state, http_client)
|
|
|
0a07cd |
- return data
|
|
|
0a07cd |
+ return {'public-keys': ssh_keys}
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ def _filter_pubkeys(self, keys_by_fingerprint, pubkey_info):
|
|
|
0a07cd |
+ """cloud-init expects a straightforward array of keys to be dropped
|
|
|
0a07cd |
+ into the user's authorized_keys file. Azure control plane exposes
|
|
|
0a07cd |
+ multiple public keys to the VM via wireserver. Select just the
|
|
|
0a07cd |
+ user's key(s) and return them, ignoring any other certs.
|
|
|
0a07cd |
+ """
|
|
|
0a07cd |
+ keys = []
|
|
|
0a07cd |
+ for pubkey in pubkey_info:
|
|
|
0a07cd |
+ if 'value' in pubkey and pubkey['value']:
|
|
|
0a07cd |
+ keys.append(pubkey['value'])
|
|
|
0a07cd |
+ elif 'fingerprint' in pubkey and pubkey['fingerprint']:
|
|
|
0a07cd |
+ fingerprint = pubkey['fingerprint']
|
|
|
0a07cd |
+ if fingerprint in keys_by_fingerprint:
|
|
|
0a07cd |
+ keys.append(keys_by_fingerprint[fingerprint])
|
|
|
0a07cd |
+ else:
|
|
|
0a07cd |
+ LOG.warning("ovf-env.xml specified PublicKey fingerprint "
|
|
|
0a07cd |
+ "%s not found in goalstate XML", fingerprint)
|
|
|
0a07cd |
+ else:
|
|
|
0a07cd |
+ LOG.warning("ovf-env.xml specified PublicKey with neither "
|
|
|
0a07cd |
+ "value nor fingerprint: %s", pubkey)
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ return keys
|
|
|
0a07cd |
|
|
|
0a07cd |
def _report_ready(self, goal_state, http_client):
|
|
|
0a07cd |
LOG.debug('Reporting ready to Azure fabric.')
|
|
|
0a07cd |
@@ -373,11 +419,12 @@ class WALinuxAgentShim(object):
|
|
|
0a07cd |
LOG.info('Reported ready to Azure fabric.')
|
|
|
0a07cd |
|
|
|
0a07cd |
|
|
|
0a07cd |
-def get_metadata_from_fabric(fallback_lease_file=None, dhcp_opts=None):
|
|
|
0a07cd |
+def get_metadata_from_fabric(fallback_lease_file=None, dhcp_opts=None,
|
|
|
0a07cd |
+ pubkey_info=None):
|
|
|
0a07cd |
shim = WALinuxAgentShim(fallback_lease_file=fallback_lease_file,
|
|
|
0a07cd |
dhcp_options=dhcp_opts)
|
|
|
0a07cd |
try:
|
|
|
0a07cd |
- return shim.register_with_azure_and_fetch_data()
|
|
|
0a07cd |
+ return shim.register_with_azure_and_fetch_data(pubkey_info=pubkey_info)
|
|
|
0a07cd |
finally:
|
|
|
0a07cd |
shim.clean_up()
|
|
|
0a07cd |
|
|
|
0a07cd |
diff --git a/tests/data/azure/parse_certificates_fingerprints b/tests/data/azure/parse_certificates_fingerprints
|
|
|
0a07cd |
new file mode 100644
|
|
|
0a07cd |
index 00000000..f7293c56
|
|
|
0a07cd |
--- /dev/null
|
|
|
0a07cd |
+++ b/tests/data/azure/parse_certificates_fingerprints
|
|
|
0a07cd |
@@ -0,0 +1,4 @@
|
|
|
0a07cd |
+ECEDEB3B8488D31AF3BC4CCED493F64B7D27D7B1
|
|
|
0a07cd |
+073E19D14D1C799224C6A0FD8DDAB6A8BF27D473
|
|
|
0a07cd |
+4C16E7FAD6297D74A9B25EB8F0A12808CEBE293E
|
|
|
0a07cd |
+929130695289B450FE45DCD5F6EF0CDE69865867
|
|
|
0a07cd |
diff --git a/tests/data/azure/parse_certificates_pem b/tests/data/azure/parse_certificates_pem
|
|
|
0a07cd |
new file mode 100644
|
|
|
0a07cd |
index 00000000..3521ea3a
|
|
|
0a07cd |
--- /dev/null
|
|
|
0a07cd |
+++ b/tests/data/azure/parse_certificates_pem
|
|
|
0a07cd |
@@ -0,0 +1,152 @@
|
|
|
0a07cd |
+Bag Attributes
|
|
|
0a07cd |
+ localKeyID: 01 00 00 00
|
|
|
0a07cd |
+ Microsoft CSP Name: Microsoft Enhanced Cryptographic Provider v1.0
|
|
|
0a07cd |
+Key Attributes
|
|
|
0a07cd |
+ X509v3 Key Usage: 10
|
|
|
0a07cd |
+-----BEGIN PRIVATE KEY-----
|
|
|
0a07cd |
+MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDlEe5fUqwdrQTP
|
|
|
0a07cd |
+W2oVlGK2f31q/8ULT8KmOTyUvL0RPdJQ69vvHOc5Q2CKg2eviHC2LWhF8WmpnZj6
|
|
|
0a07cd |
+61RL0GeFGizwvU8Moebw5p3oqdcgoGpHVtxf+mr4QcWF58/Fwez0dA4hcsimVNBz
|
|
|
0a07cd |
+eNpBBUIKNBMTBG+4d6hcQBUAGKUdGRcCGEyTqXLU0MgHjxC9JgVqWJl+X2LcAGj5
|
|
|
0a07cd |
+7J+tGYGTLzKJmeCeGVNN5ZtJ0T85MYHCKQk1/FElK+Kq5akovXffQHjlnCPcx0NJ
|
|
|
0a07cd |
+47NBjlPaFp2gjnAChn79bT4iCjOFZ9avWpqRpeU517UCnY7djOr3fuod/MSQyh3L
|
|
|
0a07cd |
+Wuem1tWBAgMBAAECggEBAM4ZXQRs6Kjmo95BHGiAEnSqrlgX+dycjcBq3QPh8KZT
|
|
|
0a07cd |
+nifqnf48XhnackENy7tWIjr3DctoUq4mOp8AHt77ijhqfaa4XSg7fwKeK9NLBGC5
|
|
|
0a07cd |
+lAXNtAey0o2894/sKrd+LMkgphoYIUnuI4LRaGV56potkj/ZDP/GwTcG/R4SDnTn
|
|
|
0a07cd |
+C1Nb05PNTAPQtPZrgPo7TdM6gGsTnFbVrYHQLyg2Sq/osHfF15YohB01esRLCAwb
|
|
|
0a07cd |
+EF8JkRC4hWIZoV7BsyQ39232zAJQGGla7+wKFs3kObwh3VnFkQpT94KZnNiZuEfG
|
|
|
0a07cd |
+x5pW4Pn3gXgNsftscXsaNe/M9mYZqo//Qw7NvUIvAvECgYEA9AVveyK0HOA06fhh
|
|
|
0a07cd |
++3hUWdvw7Pbrl+e06jO9+bT1RjQMbHKyI60DZyVGuAySN86iChJRoJr5c6xj+iXU
|
|
|
0a07cd |
+cR6BVJDjGH5t1tyiK2aYf6hEpK9/j8Z54UiVQ486zPP0PGfT2TO4lBLK+8AUmoaH
|
|
|
0a07cd |
+gk21ul8QeVCeCJa/o+xEoRFvzcUCgYEA8FCbbvInrUtNY+9eKaUYoNodsgBVjm5X
|
|
|
0a07cd |
+I0YPUL9D4d+1nvupHSV2NVmQl0w1RaJwrNTafrl5LkqjhQbmuWNta6QgfZzSA3LB
|
|
|
0a07cd |
+lWXo1Mm0azKdcD3qMGbvn0Q3zU+yGNEgmB/Yju3/NtgYRG6tc+FCWRbPbiCnZWT8
|
|
|
0a07cd |
+v3C2Y0XggI0CgYEA2/jCZBgGkTkzue5kNVJlh5OS/aog+pCvL6hxCtarfBuTT3ed
|
|
|
0a07cd |
+Sje+p46cz3DVpmUpATc+Si8py7KNdYQAm/BJ2be6X+woi9Xcgo87zWgcaPCjZzId
|
|
|
0a07cd |
+0I2jsIE/Gl6XvpRCDrxnGWRPgt3GNP4szbPLrDPiH9oie8+Y9eYYf7G+PZkCgYEA
|
|
|
0a07cd |
+nRSzZOPYV4f/QDF4pVQLMykfe/iH9B/fyWjEHg3He19VQmRReIHCMMEoqBziPXAe
|
|
|
0a07cd |
+onpHj8oAkeer1wpZyhhZr6CKtFDLXgGm09bXSC/IRMHC81klORovyzU2HHfZfCtG
|
|
|
0a07cd |
+WOmIDnU2+0xpIGIP8sztJ3qnf97MTJSkOSadsWo9gwkCgYEAh5AQmJQmck88Dff2
|
|
|
0a07cd |
+qIfJIX8d+BDw47BFJ89OmMFjGV8TNB+JO+AV4Vkodg4hxKpLqTFZTTUFgoYfy5u1
|
|
|
0a07cd |
+1/BhAjpmCDCrzubCFhx+8VEoM2+2+MmnuQoMAm9+/mD/IidwRaARgXgvEmp7sfdt
|
|
|
0a07cd |
+RyWd+p2lYvFkC/jORQtDMY4uW1o=
|
|
|
0a07cd |
+-----END PRIVATE KEY-----
|
|
|
0a07cd |
+Bag Attributes
|
|
|
0a07cd |
+ localKeyID: 02 00 00 00
|
|
|
0a07cd |
+ Microsoft CSP Name: Microsoft Strong Cryptographic Provider
|
|
|
0a07cd |
+Key Attributes
|
|
|
0a07cd |
+ X509v3 Key Usage: 10
|
|
|
0a07cd |
+-----BEGIN PRIVATE KEY-----
|
|
|
0a07cd |
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDlQhPrZwVQYFV4
|
|
|
0a07cd |
+FBc0H1iTXYaznMpwZvEITKtXWACzTdguUderEVOkXW3HTi5HvC2rMayt0nqo3zcd
|
|
|
0a07cd |
+x1eGiqdjpZQ/wMrkz9wNEM/nNMsXntEwxk0jCVNKB/jz6vf+BOtrSI01SritAGZW
|
|
|
0a07cd |
+dpKoTUyztT8C2mA3X6D8g3m4Dd07ltnzxaDqAQIU5jBHh3f/Q14tlPNZWUIiqVTC
|
|
|
0a07cd |
+gDxgAe7MDmfs9h3CInTBX1XM5J4UsLTL23/padgeSvP5YF5qr1+0c7Tdftxr2lwA
|
|
|
0a07cd |
+N3rLkisf5EiLAToVyJJlgP/exo2I8DaIKe7DZzD3Y1CrurOpkcMKYu5kM1Htlbua
|
|
|
0a07cd |
+tDkAa2oDAgMBAAECggEAOvdueS9DyiMlCKAeQb1IQosdQOh0l0ma+FgEABC2CWhd
|
|
|
0a07cd |
+0LgjQTBRM6cGO+urcq7/jhdWQ1UuUG4tVn71z7itCi/F/Enhxc2C22d2GhFVpWsn
|
|
|
0a07cd |
+giSXJYpZ/mIjkdVfWNo6FRuRmmHwMys1p0qTOS+8qUJWhSzW75csqJZGgeUrAI61
|
|
|
0a07cd |
+LBV5F0SGR7dR2xZfy7PeDs9xpD0QivDt5DpsZWPaPvw4QlhdLgw6/YU1h9vtm6ci
|
|
|
0a07cd |
+xLjnPRLZ7JMpcQHO8dUDl6FiEI7yQ11BDm253VQAVMddYRPQABn7SpEF8kD/aZVh
|
|
|
0a07cd |
+2Clvz61Rz80SKjPUthMPLWMCRp7zB0xDMzt3/1i+tQKBgQD6Ar1/oD3eFnRnpi4u
|
|
|
0a07cd |
+n/hdHJtMuXWNfUA4dspNjP6WGOid9sgIeUUdif1XyVJ+afITzvgpWc7nUWIqG2bQ
|
|
|
0a07cd |
+WxJ/4q2rjUdvjNXTy1voVungR2jD5WLQ9DKeaTR0yCliWlx4JgdPG7qGI5MMwsr+
|
|
|
0a07cd |
+R/PUoUUhGeEX+o/sCSieO3iUrQKBgQDqwBEMvIdhAv/CK2sG3fsKYX8rFT55ZNX3
|
|
|
0a07cd |
+Tix9DbUGY3wQColNuI8U1nDlxE9U6VOfT9RPqKelBLCgbzB23kdEJnjSlnqlTxrx
|
|
|
0a07cd |
+E+Hkndyf2ckdJAR3XNxoQ6SRLJNBsgoBj/z5tlfZE9/Jc+uh0mYy3e6g6XCVPBcz
|
|
|
0a07cd |
+MgoIc+ofbwKBgQCGQhZ1hR30N+bHCozeaPW9OvGDIE0qcEqeh9xYDRFilXnF6pK9
|
|
|
0a07cd |
+SjJ9jG7KR8jPLiHb1VebDSl5O1EV/6UU2vNyTc6pw7LLCryBgkGW4aWy1WZDXNnW
|
|
|
0a07cd |
+EG1meGS9GghvUss5kmJ2bxOZmV0Mi0brisQ8OWagQf+JGvtS7BAt+Q3l+QKBgAb9
|
|
|
0a07cd |
+8YQPmXiqPjPqVyW9Ntz4SnFeEJ5NApJ7IZgX8GxgSjGwHqbR+HEGchZl4ncE/Bii
|
|
|
0a07cd |
+qBA3Vcb0fM5KgYcI19aPzsl28fA6ivLjRLcqfIfGVNcpW3iyq13vpdctHLW4N9QU
|
|
|
0a07cd |
+FdTaOYOds+ysJziKq8CYG6NvUIshXw+HTgUybqbBAoGBAIIOqcmmtgOClAwipA17
|
|
|
0a07cd |
+dAHsI9Sjk+J0+d4JU6o+5TsmhUfUKIjXf5+xqJkJcQZMEe5GhxcCuYkgFicvh4Hz
|
|
|
0a07cd |
+kv2H/EU35LcJTqC6KTKZOWIbGcn1cqsvwm3GQJffYDiO8fRZSwCaif2J3F2lfH4Y
|
|
|
0a07cd |
+R/fA67HXFSTT+OncdRpY1NOn
|
|
|
0a07cd |
+-----END PRIVATE KEY-----
|
|
|
0a07cd |
+Bag Attributes: <Empty Attributes>
|
|
|
0a07cd |
+subject=/CN=CRP/OU=AzureRT/O=Microsoft Corporation/L=Redmond/ST=WA/C=US
|
|
|
0a07cd |
+issuer=/CN=Root Agency
|
|
|
0a07cd |
+-----BEGIN CERTIFICATE-----
|
|
|
0a07cd |
+MIIB+TCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDDAtSb290
|
|
|
0a07cd |
+IEFnZW5jeTAeFw0xOTAyMTUxOTA0MDRaFw0yOTAyMTUxOTE0MDRaMGwxDDAKBgNV
|
|
|
0a07cd |
+BAMMA0NSUDEQMA4GA1UECwwHQXp1cmVSVDEeMBwGA1UECgwVTWljcm9zb2Z0IENv
|
|
|
0a07cd |
+cnBvcmF0aW9uMRAwDgYDVQQHDAdSZWRtb25kMQswCQYDVQQIDAJXQTELMAkGA1UE
|
|
|
0a07cd |
+BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIlPjJXzrRih4C
|
|
|
0a07cd |
+k/XsoI01oqo7IUxH3dA2F7vHGXQoIpKCp8Qe6Z6cFfdD8Uj+s+B1BX6hngwzIwjN
|
|
|
0a07cd |
+jE/23X3SALVzJVWzX4Y/IEjbgsuao6sOyNyB18wIU9YzZkVGj68fmMlUw3LnhPbe
|
|
|
0a07cd |
+eWkufZaJCaLyhQOwlRMbOcn48D6Ys8fccOyXNzpq3rH1OzeQpxS2M8zaJYP4/VZ/
|
|
|
0a07cd |
+sf6KRpI7bP+QwyFvNKfhcaO9/gj4kMo9lVGjvDU20FW6g8UVNJCV9N4GO6mOcyqo
|
|
|
0a07cd |
+OhuhVfjCNGgW7N1qi0TIVn0/MQM4l4dcT2R7Z/bV9fhMJLjGsy5A4TLAdRrhKUHT
|
|
|
0a07cd |
+bzi9HyDvAgMBAAEwDQYJKoZIhvcNAQEFBQADAQA=
|
|
|
0a07cd |
+-----END CERTIFICATE-----
|
|
|
0a07cd |
+Bag Attributes
|
|
|
0a07cd |
+ localKeyID: 01 00 00 00
|
|
|
0a07cd |
+subject=/C=US/ST=WASHINGTON/L=Seattle/O=Microsoft/OU=Azure/CN=AnhVo/emailAddress=redacted@microsoft.com
|
|
|
0a07cd |
+issuer=/C=US/ST=WASHINGTON/L=Seattle/O=Microsoft/OU=Azure/CN=AnhVo/emailAddress=redacted@microsoft.com
|
|
|
0a07cd |
+-----BEGIN CERTIFICATE-----
|
|
|
0a07cd |
+MIID7TCCAtWgAwIBAgIJALQS3yMg3R41MA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
|
|
|
0a07cd |
+VQQGEwJVUzETMBEGA1UECAwKV0FTSElOR1RPTjEQMA4GA1UEBwwHU2VhdHRsZTES
|
|
|
0a07cd |
+MBAGA1UECgwJTWljcm9zb2Z0MQ4wDAYDVQQLDAVBenVyZTEOMAwGA1UEAwwFQW5o
|
|
|
0a07cd |
+Vm8xIjAgBgkqhkiG9w0BCQEWE2FuaHZvQG1pY3Jvc29mdC5jb20wHhcNMTkwMjE0
|
|
|
0a07cd |
+MjMxMjQwWhcNMjExMTEwMjMxMjQwWjCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAgM
|
|
|
0a07cd |
+CldBU0hJTkdUT04xEDAOBgNVBAcMB1NlYXR0bGUxEjAQBgNVBAoMCU1pY3Jvc29m
|
|
|
0a07cd |
+dDEOMAwGA1UECwwFQXp1cmUxDjAMBgNVBAMMBUFuaFZvMSIwIAYJKoZIhvcNAQkB
|
|
|
0a07cd |
+FhNhbmh2b0BtaWNyb3NvZnQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
|
|
0a07cd |
+CgKCAQEA5RHuX1KsHa0Ez1tqFZRitn99av/FC0/Cpjk8lLy9ET3SUOvb7xznOUNg
|
|
|
0a07cd |
+ioNnr4hwti1oRfFpqZ2Y+utUS9BnhRos8L1PDKHm8Oad6KnXIKBqR1bcX/pq+EHF
|
|
|
0a07cd |
+hefPxcHs9HQOIXLIplTQc3jaQQVCCjQTEwRvuHeoXEAVABilHRkXAhhMk6ly1NDI
|
|
|
0a07cd |
+B48QvSYFaliZfl9i3ABo+eyfrRmBky8yiZngnhlTTeWbSdE/OTGBwikJNfxRJSvi
|
|
|
0a07cd |
+quWpKL1330B45Zwj3MdDSeOzQY5T2hadoI5wAoZ+/W0+IgozhWfWr1qakaXlOde1
|
|
|
0a07cd |
+Ap2O3Yzq937qHfzEkMody1rnptbVgQIDAQABo1AwTjAdBgNVHQ4EFgQUPvdgLiv3
|
|
|
0a07cd |
+pAk4r0QTPZU3PFOZJvgwHwYDVR0jBBgwFoAUPvdgLiv3pAk4r0QTPZU3PFOZJvgw
|
|
|
0a07cd |
+DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAVUHZT+h9+uCPLTEl5IDg
|
|
|
0a07cd |
+kqd9WpzXA7PJd/V+7DeDDTkEd06FIKTWZLfxLVVDjQJnQqubQb//e0zGu1qKbXnX
|
|
|
0a07cd |
+R7xqWabGU4eyPeUFWddmt1OHhxKLU3HbJNJJdL6XKiQtpGGUQt/mqNQ/DEr6hhNF
|
|
|
0a07cd |
+im5I79iA8H/dXA2gyZrj5Rxea4mtsaYO0mfp1NrFtJpAh2Djy4B1lBXBIv4DWG9e
|
|
|
0a07cd |
+mMEwzcLCOZj2cOMA6+mdLMUjYCvIRtnn5MKUHyZX5EmX79wsqMTvVpddlVLB9Kgz
|
|
|
0a07cd |
+Qnvft9+SBWh9+F3ip7BsL6Q4Q9v8eHRbnP0ya7ddlgh64uwf9VOfZZdKCnwqudJP
|
|
|
0a07cd |
+3g==
|
|
|
0a07cd |
+-----END CERTIFICATE-----
|
|
|
0a07cd |
+Bag Attributes
|
|
|
0a07cd |
+ localKeyID: 02 00 00 00
|
|
|
0a07cd |
+subject=/CN=/subscriptions/redacted/resourcegroups/redacted/providers/Microsoft.Compute/virtualMachines/redacted
|
|
|
0a07cd |
+issuer=/CN=Microsoft.ManagedIdentity
|
|
|
0a07cd |
+-----BEGIN CERTIFICATE-----
|
|
|
0a07cd |
+MIIDnTCCAoWgAwIBAgIUB2lauSRccvFkoJybUfIwOUqBN7MwDQYJKoZIhvcNAQEL
|
|
|
0a07cd |
+BQAwJDEiMCAGA1UEAxMZTWljcm9zb2Z0Lk1hbmFnZWRJZGVudGl0eTAeFw0xOTAy
|
|
|
0a07cd |
+MTUxOTA5MDBaFw0xOTA4MTQxOTA5MDBaMIGUMYGRMIGOBgNVBAMTgYYvc3Vic2Ny
|
|
|
0a07cd |
+aXB0aW9ucy8yN2I3NTBjZC1lZDQzLTQyZmQtOTA0NC04ZDc1ZTEyNGFlNTUvcmVz
|
|
|
0a07cd |
+b3VyY2Vncm91cHMvYW5oZXh0cmFzc2gvcHJvdmlkZXJzL01pY3Jvc29mdC5Db21w
|
|
|
0a07cd |
+dXRlL3ZpcnR1YWxNYWNoaW5lcy9hbmh0ZXN0Y2VydDCCASIwDQYJKoZIhvcNAQEB
|
|
|
0a07cd |
+BQADggEPADCCAQoCggEBAOVCE+tnBVBgVXgUFzQfWJNdhrOcynBm8QhMq1dYALNN
|
|
|
0a07cd |
+2C5R16sRU6RdbcdOLke8LasxrK3SeqjfNx3HV4aKp2OllD/AyuTP3A0Qz+c0yxee
|
|
|
0a07cd |
+0TDGTSMJU0oH+PPq9/4E62tIjTVKuK0AZlZ2kqhNTLO1PwLaYDdfoPyDebgN3TuW
|
|
|
0a07cd |
+2fPFoOoBAhTmMEeHd/9DXi2U81lZQiKpVMKAPGAB7swOZ+z2HcIidMFfVczknhSw
|
|
|
0a07cd |
+tMvbf+lp2B5K8/lgXmqvX7RztN1+3GvaXAA3esuSKx/kSIsBOhXIkmWA/97GjYjw
|
|
|
0a07cd |
+Nogp7sNnMPdjUKu6s6mRwwpi7mQzUe2Vu5q0OQBragMCAwEAAaNWMFQwDgYDVR0P
|
|
|
0a07cd |
+AQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHwYD
|
|
|
0a07cd |
+VR0jBBgwFoAUOJvzEsriQWdJBndPrK+Me1bCPjYwDQYJKoZIhvcNAQELBQADggEB
|
|
|
0a07cd |
+AFGP/g8o7Hv/to11M0UqfzJuW/AyH9RZtSRcNQFLZUndwweQ6fap8lFsA4REUdqe
|
|
|
0a07cd |
+7Quqp5JNNY1XzKLWXMPoheIDH1A8FFXdsAroArzlNs9tO3TlIHE8A7HxEVZEmR4b
|
|
|
0a07cd |
+7ZiixmkQPS2RkjEoV/GM6fheBrzuFn7X5kVZyE6cC5sfcebn8xhk3ZcXI0VmpdT0
|
|
|
0a07cd |
+jFBsf5IvFCIXXLLhJI4KXc8VMoKFU1jT9na/jyaoGmfwovKj4ib8s2aiXGAp7Y38
|
|
|
0a07cd |
+UCmY+bJapWom6Piy5Jzi/p/kzMVdJcSa+GqpuFxBoQYEVs2XYVl7cGu/wPM+NToC
|
|
|
0a07cd |
+pkSoWwF1QAnHn0eokR9E1rU=
|
|
|
0a07cd |
+-----END CERTIFICATE-----
|
|
|
0a07cd |
+Bag Attributes: <Empty Attributes>
|
|
|
0a07cd |
+subject=/CN=CRP/OU=AzureRT/O=Microsoft Corporation/L=Redmond/ST=WA/C=US
|
|
|
0a07cd |
+issuer=/CN=Root Agency
|
|
|
0a07cd |
+-----BEGIN CERTIFICATE-----
|
|
|
0a07cd |
+MIIB+TCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDDAtSb290
|
|
|
0a07cd |
+IEFnZW5jeTAeFw0xOTAyMTUxOTA0MDRaFw0yOTAyMTUxOTE0MDRaMGwxDDAKBgNV
|
|
|
0a07cd |
+BAMMA0NSUDEQMA4GA1UECwwHQXp1cmVSVDEeMBwGA1UECgwVTWljcm9zb2Z0IENv
|
|
|
0a07cd |
+cnBvcmF0aW9uMRAwDgYDVQQHDAdSZWRtb25kMQswCQYDVQQIDAJXQTELMAkGA1UE
|
|
|
0a07cd |
+BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHU9IDclbKVYVb
|
|
|
0a07cd |
+Yuv0+zViX+wTwlKspslmy/uf3hkWLh7pyzyrq70S7qtSW2EGixUPxZS/R8pOLHoi
|
|
|
0a07cd |
+nlKF9ILgj0gVTCJsSwnWpXRg3rhZwIVoYMHN50BHS1SqVD0lsWNMXmo76LoJcjmW
|
|
|
0a07cd |
+vwIznvj5C/gnhU+K7+c3m7AlCyU2wjwpBAEYj7PQs6l/wTqpEiaqC5NytNBd7qp+
|
|
|
0a07cd |
+lYYysVrpa1PFL0Nj4MMZARIfjkiJtL9qDhy9YZeJRQ6q/Fhz0kjvkZnfxixfKF4y
|
|
|
0a07cd |
+WzOfhBrAtpF6oOnuYKk3hxjh9KjTTX4/U8zdLojalX09iyHyEjwJKGlGEpzh1aY7
|
|
|
0a07cd |
+t5btUyvpAgMBAAEwDQYJKoZIhvcNAQEFBQADAQA=
|
|
|
0a07cd |
+-----END CERTIFICATE-----
|
|
|
0a07cd |
diff --git a/tests/data/azure/pubkey_extract_cert b/tests/data/azure/pubkey_extract_cert
|
|
|
0a07cd |
new file mode 100644
|
|
|
0a07cd |
index 00000000..ce9b852d
|
|
|
0a07cd |
--- /dev/null
|
|
|
0a07cd |
+++ b/tests/data/azure/pubkey_extract_cert
|
|
|
0a07cd |
@@ -0,0 +1,13 @@
|
|
|
0a07cd |
+-----BEGIN CERTIFICATE-----
|
|
|
0a07cd |
+MIIB+TCCAeOgAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQDDAtSb290
|
|
|
0a07cd |
+IEFnZW5jeTAeFw0xOTAyMTUxOTA0MDRaFw0yOTAyMTUxOTE0MDRaMGwxDDAKBgNV
|
|
|
0a07cd |
+BAMMA0NSUDEQMA4GA1UECwwHQXp1cmVSVDEeMBwGA1UECgwVTWljcm9zb2Z0IENv
|
|
|
0a07cd |
+cnBvcmF0aW9uMRAwDgYDVQQHDAdSZWRtb25kMQswCQYDVQQIDAJXQTELMAkGA1UE
|
|
|
0a07cd |
+BhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHU9IDclbKVYVb
|
|
|
0a07cd |
+Yuv0+zViX+wTwlKspslmy/uf3hkWLh7pyzyrq70S7qtSW2EGixUPxZS/R8pOLHoi
|
|
|
0a07cd |
+nlKF9ILgj0gVTCJsSwnWpXRg3rhZwIVoYMHN50BHS1SqVD0lsWNMXmo76LoJcjmW
|
|
|
0a07cd |
+vwIznvj5C/gnhU+K7+c3m7AlCyU2wjwpBAEYj7PQs6l/wTqpEiaqC5NytNBd7qp+
|
|
|
0a07cd |
+lYYysVrpa1PFL0Nj4MMZARIfjkiJtL9qDhy9YZeJRQ6q/Fhz0kjvkZnfxixfKF4y
|
|
|
0a07cd |
+WzOfhBrAtpF6oOnuYKk3hxjh9KjTTX4/U8zdLojalX09iyHyEjwJKGlGEpzh1aY7
|
|
|
0a07cd |
+t5btUyvpAgMBAAEwDQYJKoZIhvcNAQEFBQADAQA=
|
|
|
0a07cd |
+-----END CERTIFICATE-----
|
|
|
0a07cd |
diff --git a/tests/data/azure/pubkey_extract_ssh_key b/tests/data/azure/pubkey_extract_ssh_key
|
|
|
0a07cd |
new file mode 100644
|
|
|
0a07cd |
index 00000000..54d749ed
|
|
|
0a07cd |
--- /dev/null
|
|
|
0a07cd |
+++ b/tests/data/azure/pubkey_extract_ssh_key
|
|
|
0a07cd |
@@ -0,0 +1 @@
|
|
|
0a07cd |
+ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDHU9IDclbKVYVbYuv0+zViX+wTwlKspslmy/uf3hkWLh7pyzyrq70S7qtSW2EGixUPxZS/R8pOLHoinlKF9ILgj0gVTCJsSwnWpXRg3rhZwIVoYMHN50BHS1SqVD0lsWNMXmo76LoJcjmWvwIznvj5C/gnhU+K7+c3m7AlCyU2wjwpBAEYj7PQs6l/wTqpEiaqC5NytNBd7qp+lYYysVrpa1PFL0Nj4MMZARIfjkiJtL9qDhy9YZeJRQ6q/Fhz0kjvkZnfxixfKF4yWzOfhBrAtpF6oOnuYKk3hxjh9KjTTX4/U8zdLojalX09iyHyEjwJKGlGEpzh1aY7t5btUyvp
|
|
|
0a07cd |
diff --git a/tests/unittests/test_datasource/test_azure_helper.py b/tests/unittests/test_datasource/test_azure_helper.py
|
|
|
0a07cd |
index 26b2b93d..02556165 100644
|
|
|
0a07cd |
--- a/tests/unittests/test_datasource/test_azure_helper.py
|
|
|
0a07cd |
+++ b/tests/unittests/test_datasource/test_azure_helper.py
|
|
|
0a07cd |
@@ -1,11 +1,13 @@
|
|
|
0a07cd |
# This file is part of cloud-init. See LICENSE file for license information.
|
|
|
0a07cd |
|
|
|
0a07cd |
import os
|
|
|
0a07cd |
+import unittest2
|
|
|
0a07cd |
from textwrap import dedent
|
|
|
0a07cd |
|
|
|
0a07cd |
from cloudinit.sources.helpers import azure as azure_helper
|
|
|
0a07cd |
from cloudinit.tests.helpers import CiTestCase, ExitStack, mock, populate_dir
|
|
|
0a07cd |
|
|
|
0a07cd |
+from cloudinit.util import load_file
|
|
|
0a07cd |
from cloudinit.sources.helpers.azure import WALinuxAgentShim as wa_shim
|
|
|
0a07cd |
|
|
|
0a07cd |
GOAL_STATE_TEMPLATE = """\
|
|
|
0a07cd |
@@ -289,6 +291,50 @@ class TestOpenSSLManager(CiTestCase):
|
|
|
0a07cd |
self.assertEqual([mock.call(manager.tmpdir)], del_dir.call_args_list)
|
|
|
0a07cd |
|
|
|
0a07cd |
|
|
|
0a07cd |
+class TestOpenSSLManagerActions(CiTestCase):
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ def setUp(self):
|
|
|
0a07cd |
+ super(TestOpenSSLManagerActions, self).setUp()
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ self.allowed_subp = True
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ def _data_file(self, name):
|
|
|
0a07cd |
+ path = 'tests/data/azure'
|
|
|
0a07cd |
+ return os.path.join(path, name)
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ @unittest2.skip("todo move to cloud_test")
|
|
|
0a07cd |
+ def test_pubkey_extract(self):
|
|
|
0a07cd |
+ cert = load_file(self._data_file('pubkey_extract_cert'))
|
|
|
0a07cd |
+ good_key = load_file(self._data_file('pubkey_extract_ssh_key'))
|
|
|
0a07cd |
+ sslmgr = azure_helper.OpenSSLManager()
|
|
|
0a07cd |
+ key = sslmgr._get_ssh_key_from_cert(cert)
|
|
|
0a07cd |
+ self.assertEqual(good_key, key)
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ good_fingerprint = '073E19D14D1C799224C6A0FD8DDAB6A8BF27D473'
|
|
|
0a07cd |
+ fingerprint = sslmgr._get_fingerprint_from_cert(cert)
|
|
|
0a07cd |
+ self.assertEqual(good_fingerprint, fingerprint)
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+ @unittest2.skip("todo move to cloud_test")
|
|
|
0a07cd |
+ @mock.patch.object(azure_helper.OpenSSLManager, '_decrypt_certs_from_xml')
|
|
|
0a07cd |
+ def test_parse_certificates(self, mock_decrypt_certs):
|
|
|
0a07cd |
+ """Azure control plane puts private keys as well as certificates
|
|
|
0a07cd |
+ into the Certificates XML object. Make sure only the public keys
|
|
|
0a07cd |
+ from certs are extracted and that fingerprints are converted to
|
|
|
0a07cd |
+ the form specified in the ovf-env.xml file.
|
|
|
0a07cd |
+ """
|
|
|
0a07cd |
+ cert_contents = load_file(self._data_file('parse_certificates_pem'))
|
|
|
0a07cd |
+ fingerprints = load_file(self._data_file(
|
|
|
0a07cd |
+ 'parse_certificates_fingerprints')
|
|
|
0a07cd |
+ ).splitlines()
|
|
|
0a07cd |
+ mock_decrypt_certs.return_value = cert_contents
|
|
|
0a07cd |
+ sslmgr = azure_helper.OpenSSLManager()
|
|
|
0a07cd |
+ keys_by_fp = sslmgr.parse_certificates('')
|
|
|
0a07cd |
+ for fp in keys_by_fp.keys():
|
|
|
0a07cd |
+ self.assertIn(fp, fingerprints)
|
|
|
0a07cd |
+ for fp in fingerprints:
|
|
|
0a07cd |
+ self.assertIn(fp, keys_by_fp)
|
|
|
0a07cd |
+
|
|
|
0a07cd |
+
|
|
|
0a07cd |
class TestWALinuxAgentShim(CiTestCase):
|
|
|
0a07cd |
|
|
|
0a07cd |
def setUp(self):
|
|
|
0a07cd |
@@ -329,18 +375,31 @@ class TestWALinuxAgentShim(CiTestCase):
|
|
|
0a07cd |
|
|
|
0a07cd |
def test_certificates_used_to_determine_public_keys(self):
|
|
|
0a07cd |
shim = wa_shim()
|
|
|
0a07cd |
- data = shim.register_with_azure_and_fetch_data()
|
|
|
0a07cd |
+ """if register_with_azure_and_fetch_data() isn't passed some info about
|
|
|
0a07cd |
+ the user's public keys, there's no point in even trying to parse
|
|
|
0a07cd |
+ the certificates
|
|
|
0a07cd |
+ """
|
|
|
0a07cd |
+ mypk = [{'fingerprint': 'fp1', 'path': 'path1'},
|
|
|
0a07cd |
+ {'fingerprint': 'fp3', 'path': 'path3', 'value': ''}]
|
|
|
0a07cd |
+ certs = {'fp1': 'expected-key',
|
|
|
0a07cd |
+ 'fp2': 'should-not-be-found',
|
|
|
0a07cd |
+ 'fp3': 'expected-no-value-key',
|
|
|
0a07cd |
+ }
|
|
|
0a07cd |
+ sslmgr = self.OpenSSLManager.return_value
|
|
|
0a07cd |
+ sslmgr.parse_certificates.return_value = certs
|
|
|
0a07cd |
+ data = shim.register_with_azure_and_fetch_data(pubkey_info=mypk)
|
|
|
0a07cd |
self.assertEqual(
|
|
|
0a07cd |
[mock.call(self.GoalState.return_value.certificates_xml)],
|
|
|
0a07cd |
- self.OpenSSLManager.return_value.parse_certificates.call_args_list)
|
|
|
0a07cd |
- self.assertEqual(
|
|
|
0a07cd |
- self.OpenSSLManager.return_value.parse_certificates.return_value,
|
|
|
0a07cd |
- data['public-keys'])
|
|
|
0a07cd |
+ sslmgr.parse_certificates.call_args_list)
|
|
|
0a07cd |
+ self.assertIn('expected-key', data['public-keys'])
|
|
|
0a07cd |
+ self.assertIn('expected-no-value-key', data['public-keys'])
|
|
|
0a07cd |
+ self.assertNotIn('should-not-be-found', data['public-keys'])
|
|
|
0a07cd |
|
|
|
0a07cd |
def test_absent_certificates_produces_empty_public_keys(self):
|
|
|
0a07cd |
+ mypk = [{'fingerprint': 'fp1', 'path': 'path1'}]
|
|
|
0a07cd |
self.GoalState.return_value.certificates_xml = None
|
|
|
0a07cd |
shim = wa_shim()
|
|
|
0a07cd |
- data = shim.register_with_azure_and_fetch_data()
|
|
|
0a07cd |
+ data = shim.register_with_azure_and_fetch_data(pubkey_info=mypk)
|
|
|
0a07cd |
self.assertEqual([], data['public-keys'])
|
|
|
0a07cd |
|
|
|
0a07cd |
def test_correct_url_used_for_report_ready(self):
|
|
|
0a07cd |
--
|
|
|
0a07cd |
2.20.1
|
|
|
0a07cd |
|