checksts.py hinzugefügt
This commit is contained in:
parent
c7121b3532
commit
d4c86ad1fa
1 changed files with 222 additions and 0 deletions
222
checksts.py
Normal file
222
checksts.py
Normal file
|
@ -0,0 +1,222 @@
|
|||
#!/opt/vmware/bin/python
|
||||
|
||||
|
||||
"""
|
||||
Copyright 2020-2022 VMware, Inc. All rights reserved. -- VMware Confidential
|
||||
Author: Keenan Matheny (keenanm@vmware.com)
|
||||
|
||||
"""
|
||||
##### BEGIN IMPORTS #####
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import subprocess
|
||||
import re
|
||||
import pprint
|
||||
import ssl
|
||||
from datetime import datetime, timedelta
|
||||
import textwrap
|
||||
from codecs import encode, decode
|
||||
import subprocess
|
||||
from time import sleep
|
||||
try:
|
||||
# Python 3 hack.
|
||||
import urllib.request as urllib2
|
||||
import urllib.parse as urlparse
|
||||
except ImportError:
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
sys.path.append(os.environ['VMWARE_PYTHON_PATH'])
|
||||
from cis.defaults import def_by_os
|
||||
sys.path.append(os.path.join(os.environ['VMWARE_CIS_HOME'],
|
||||
def_by_os('vmware-vmafd/lib64', 'vmafdd')))
|
||||
import vmafd
|
||||
from OpenSSL.crypto import (load_certificate, dump_privatekey, dump_certificate, X509, X509Name, PKey)
|
||||
from OpenSSL.crypto import (TYPE_DSA, TYPE_RSA, FILETYPE_PEM, FILETYPE_ASN1 )
|
||||
|
||||
today = datetime.now()
|
||||
today = today.strftime("%d-%m-%Y")
|
||||
|
||||
vcsa_kblink = "https://kb.vmware.com/s/article/76719"
|
||||
win_kblink = "https://kb.vmware.com/s/article/79263"
|
||||
|
||||
##### END IMPORTS #####
|
||||
|
||||
class parseCert( object ):
|
||||
# Certificate parsing
|
||||
|
||||
def format_subject_issuer(self, x509name):
|
||||
items = []
|
||||
for item in x509name.get_components():
|
||||
items.append('%s=%s' % (decode(item[0],'utf-8'), decode(item[1],'utf-8')))
|
||||
return ", ".join(items)
|
||||
|
||||
def format_asn1_date(self, d):
|
||||
return datetime.strptime(decode(d,'utf-8'), '%Y%m%d%H%M%SZ').strftime("%Y-%m-%d %H:%M:%S GMT")
|
||||
|
||||
def merge_cert(self, extensions, certificate):
|
||||
z = certificate.copy()
|
||||
z.update(extensions)
|
||||
return z
|
||||
|
||||
def __init__(self, certdata):
|
||||
|
||||
built_cert = certdata
|
||||
self.x509 = load_certificate(FILETYPE_PEM, built_cert)
|
||||
keytype = self.x509.get_pubkey().type()
|
||||
keytype_list = {TYPE_RSA:'rsaEncryption', TYPE_DSA:'dsaEncryption', 408:'id-ecPublicKey'}
|
||||
extension_list = ["extendedKeyUsage",
|
||||
"keyUsage",
|
||||
"subjectAltName",
|
||||
"subjectKeyIdentifier",
|
||||
"authorityKeyIdentifier"]
|
||||
key_type_str = keytype_list[keytype] if keytype in keytype_list else 'other'
|
||||
|
||||
certificate = {}
|
||||
extension = {}
|
||||
for i in range(self.x509.get_extension_count()):
|
||||
critical = 'critical' if self.x509.get_extension(i).get_critical() else ''
|
||||
|
||||
if decode(self.x509.get_extension(i).get_short_name(),'utf-8') in extension_list:
|
||||
extension[decode(self.x509.get_extension(i).get_short_name(),'utf-8')] = self.x509.get_extension(i).__str__()
|
||||
|
||||
certificate = {'Thumbprint': decode(self.x509.digest('sha1'),'utf-8'), 'Version': self.x509.get_version(),
|
||||
'SignatureAlg' : decode(self.x509.get_signature_algorithm(),'utf-8'), 'Issuer' :self.format_subject_issuer(self.x509.get_issuer()),
|
||||
'Valid From' : self.format_asn1_date(self.x509.get_notBefore()), 'Valid Until' : self.format_asn1_date(self.x509.get_notAfter()),
|
||||
'Subject' : self.format_subject_issuer(self.x509.get_subject())}
|
||||
|
||||
combined = self.merge_cert(extension,certificate)
|
||||
cert_output = json.dumps(combined)
|
||||
|
||||
self.subjectAltName = combined.get('subjectAltName')
|
||||
self.subject = combined.get('Subject')
|
||||
self.validfrom = combined.get('Valid From')
|
||||
self.validuntil = combined.get('Valid Until')
|
||||
self.thumbprint = combined.get('Thumbprint')
|
||||
self.subjectkey = combined.get('subjectKeyIdentifier')
|
||||
self.authkey = combined.get('authorityKeyIdentifier')
|
||||
self.combined = combined
|
||||
|
||||
class parseSts( object ):
|
||||
|
||||
def __init__(self):
|
||||
self.processed = []
|
||||
self.results = {}
|
||||
self.results['expired'] = {}
|
||||
self.results['expired']['root'] = []
|
||||
self.results['expired']['leaf'] = []
|
||||
self.results['valid'] = {}
|
||||
self.results['valid']['root'] = []
|
||||
self.results['valid']['leaf'] = []
|
||||
|
||||
def get_certs(self,force_refresh):
|
||||
urllib2.getproxies = lambda: {}
|
||||
vmafd_client = vmafd.client('localhost')
|
||||
domain_name = vmafd_client.GetDomainName()
|
||||
|
||||
dc_name = vmafd_client.GetAffinitizedDC(domain_name, force_refresh)
|
||||
if vmafd_client.GetPNID() == dc_name:
|
||||
url = (
|
||||
'http://localhost:7080/idm/tenant/%s/certificates?scope=TENANT'
|
||||
% domain_name)
|
||||
else:
|
||||
url = (
|
||||
'https://%s/idm/tenant/%s/certificates?scope=TENANT'
|
||||
% (dc_name,domain_name))
|
||||
return json.loads(urllib2.urlopen(url).read().decode('utf-8'))
|
||||
|
||||
def check_cert(self,certificate):
|
||||
cert = parseCert(certificate)
|
||||
certdetail = cert.combined
|
||||
|
||||
# Attempt to identify what type of certificate it is
|
||||
if cert.authkey:
|
||||
cert_type = "leaf"
|
||||
else:
|
||||
cert_type = "root"
|
||||
|
||||
# Try to only process a cert once
|
||||
if cert.thumbprint not in self.processed:
|
||||
# Date conversion
|
||||
self.processed.append(cert.thumbprint)
|
||||
exp = cert.validuntil.split()[0]
|
||||
conv_exp = datetime.strptime(exp, '%Y-%m-%d')
|
||||
exp = datetime.strftime(conv_exp, '%d-%m-%Y')
|
||||
now = datetime.strptime(today, '%d-%m-%Y')
|
||||
exp_date = datetime.strptime(exp, '%d-%m-%Y')
|
||||
|
||||
# Get number of days until it expires
|
||||
diff = exp_date - now
|
||||
certdetail['daysUntil'] = diff.days
|
||||
|
||||
# Sort expired certs into leafs and roots, put the rest in goodcerts.
|
||||
if exp_date <= now:
|
||||
self.results['expired'][cert_type].append(certdetail)
|
||||
else:
|
||||
self.results['valid'][cert_type].append(certdetail)
|
||||
|
||||
def execute(self):
|
||||
|
||||
json = self.get_certs(force_refresh=False)
|
||||
for item in json:
|
||||
for certificate in item['certificates']:
|
||||
self.check_cert(certificate['encoded'])
|
||||
return self.results
|
||||
|
||||
def main():
|
||||
|
||||
warning = False
|
||||
warningmsg = '''
|
||||
WARNING!
|
||||
You have expired STS certificates. Please follow the KB corresponding to your OS:
|
||||
VCSA: %s
|
||||
Windows: %s
|
||||
''' % (vcsa_kblink, win_kblink)
|
||||
parse_sts = parseSts()
|
||||
results = parse_sts.execute()
|
||||
valid_count = len(results['valid']['leaf']) + len(results['valid']['root'])
|
||||
expired_count = len(results['expired']['leaf']) + len(results['expired']['root'])
|
||||
|
||||
|
||||
#### Display Valid ####
|
||||
print("\n%s VALID CERTS\n================" % valid_count)
|
||||
print("\n\tLEAF CERTS:\n")
|
||||
if len(results['valid']['leaf']) > 0:
|
||||
for cert in results['valid']['leaf']:
|
||||
print("\t[] Certificate %s will expire in %s days (%s years)." % (cert['Thumbprint'], cert['daysUntil'], round(cert['daysUntil']/365)))
|
||||
else:
|
||||
print("\tNone")
|
||||
print("\n\tROOT CERTS:\n")
|
||||
if len(results['valid']['root']) > 0:
|
||||
for cert in results['valid']['root']:
|
||||
print("\t[] Certificate %s will expire in %s days (%s years)." % (cert['Thumbprint'], cert['daysUntil'], round(cert['daysUntil']/365)))
|
||||
else:
|
||||
print("\tNone")
|
||||
|
||||
|
||||
#### Display expired ####
|
||||
print("\n%s EXPIRED CERTS\n================" % expired_count)
|
||||
print("\n\tLEAF CERTS:\n")
|
||||
if len(results['expired']['leaf']) > 0:
|
||||
for cert in results['expired']['leaf']:
|
||||
print("\t[] Certificate: %s expired on %s!" % (cert.get('Thumbprint'),cert.get('Valid Until')))
|
||||
continue
|
||||
else:
|
||||
print("\tNone")
|
||||
|
||||
print("\n\tROOT CERTS:\n")
|
||||
if len(results['expired']['root']) > 0:
|
||||
for cert in results['expired']['root']:
|
||||
print("\t[] Certificate: %s expired on %s!" % (cert.get('Thumbprint'),cert.get('Valid Until')))
|
||||
continue
|
||||
else:
|
||||
print("\tNone")
|
||||
|
||||
if expired_count > 0:
|
||||
print(warningmsg)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit(main())
|
Loading…
Add table
Add a link
Reference in a new issue