Merge pull request #68 from kevgliss/crons

Crons
This commit is contained in:
kevgliss 2015-09-02 09:35:46 -07:00
commit 089c0b2b1b
4 changed files with 85 additions and 62 deletions

View File

@ -6,8 +6,6 @@ develop: update-submodules setup-git
npm install npm install
pip install "setuptools>=0.9.8" pip install "setuptools>=0.9.8"
# order matters here, base package must install first # order matters here, base package must install first
# this is temporary until the version we need is released
pip install -e 'git+https://git@github.com/pyca/cryptography.git#egg=cryptography-1.0.dev1'
pip install -e . pip install -e .
pip install "file://`pwd`#egg=lemur[dev]" pip install "file://`pwd`#egg=lemur[dev]"
pip install "file://`pwd`#egg=lemur[tests]" pip install "file://`pwd`#egg=lemur[tests]"

View File

@ -6,14 +6,28 @@
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com> .. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
""" """
import os import os
import re
import hashlib
import requests import requests
import subprocess import subprocess
from OpenSSL import crypto from OpenSSL import crypto
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from flask import current_app from flask import current_app
from contextlib import contextmanager
from tempfile import NamedTemporaryFile
@contextmanager
def mktempfile():
with NamedTemporaryFile(delete=False) as f:
name = f.name
try:
yield name
finally:
os.unlink(name)
def ocsp_verify(cert_path, issuer_chain_path): def ocsp_verify(cert_path, issuer_chain_path):
""" """
@ -53,26 +67,17 @@ def crl_verify(cert_path):
:return: True if certificate is valid, False otherwise :return: True if certificate is valid, False otherwise
:raise Exception: If certificate does not have CRL :raise Exception: If certificate does not have CRL
""" """
s = "(http(s)?\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}/\S*?$)" with open(cert_path, 'rt') as c:
regex = re.compile(s, re.MULTILINE) cert = x509.load_pem_x509_certificate(c.read(), default_backend())
x509 = crypto.load_certificate(crypto.FILETYPE_PEM, open(cert_path, 'rt').read()) distribution_points = cert.extensions.get_extension_for_oid(x509.OID_CRL_DISTRIBUTION_POINTS).value
for x in range(x509.get_extension_count()): for p in distribution_points:
ext = x509.get_extension(x) point = p.full_name[0].value
if ext.get_short_name() == 'crlDistributionPoints':
r = regex.search(ext.get_data())
points = r.groups()
break
else:
raise Exception("Certificate does not have a CRL distribution point")
for point in points:
if point:
response = requests.get(point) response = requests.get(point)
crl = crypto.load_crl(crypto.FILETYPE_ASN1, response.content) crl = crypto.load_crl(crypto.FILETYPE_ASN1, response.content) # TODO this should be switched to cryptography when support exists
revoked = crl.get_revoked() revoked = crl.get_revoked()
for r in revoked: for r in revoked:
if x509.get_serial_number() == r.get_serial(): if cert.serial == r.get_serial():
return return
return True return True
@ -99,22 +104,6 @@ def verify(cert_path, issuer_chain_path):
raise Exception("Failed to verify") raise Exception("Failed to verify")
def make_tmp_file(string):
"""
Creates a temporary file for a given string
:param string:
:return: Full file path to created file
"""
m = hashlib.md5()
m.update(string)
hexdigest = m.hexdigest()
path = os.path.join(os.path.dirname(os.path.abspath(__file__)), hexdigest)
with open(path, 'w') as f:
f.write(string)
return path
def verify_string(cert_string, issuer_string): def verify_string(cert_string, issuer_string):
""" """
Verify a certificate given only it's string value Verify a certificate given only it's string value
@ -123,13 +112,11 @@ def verify_string(cert_string, issuer_string):
:param issuer_string: :param issuer_string:
:return: True if valid, False otherwise :return: True if valid, False otherwise
""" """
cert_path = make_tmp_file(cert_string) with mktempfile() as cert_tmp:
issuer_path = make_tmp_file(issuer_string) with open(cert_tmp, 'w') as f:
status = verify(cert_path, issuer_path) f.write(cert_string)
remove_tmp_file(cert_path) with mktempfile() as issuer_tmp:
remove_tmp_file(issuer_path) with open(issuer_tmp, 'w') as f:
f.write(issuer_string)
status = verify(cert_tmp, issuer_tmp)
return status return status
def remove_tmp_file(file_path):
os.remove(file_path)

View File

@ -4,6 +4,8 @@ import os
import sys import sys
import base64 import base64
import time import time
import requests
import json
from gunicorn.config import make_settings from gunicorn.config import make_settings
from cryptography.fernet import Fernet from cryptography.fernet import Fernet
@ -146,12 +148,15 @@ def check_revoked():
as `unknown`. as `unknown`.
""" """
for cert in cert_service.get_all_certs(): for cert in cert_service.get_all_certs():
try:
if cert.chain: if cert.chain:
status = verify_string(cert.body, cert.chain) status = verify_string(cert.body, cert.chain)
else: else:
status = verify_string(cert.body, "") status = verify_string(cert.body, "")
cert.status = 'valid' if status else "invalid" cert.status = 'valid' if status else 'invalid'
except Exception as e:
cert.status = 'unknown'
database.update(cert) database.update(cert)
@ -181,7 +186,7 @@ def generate_settings():
return output return output
@manager.option('-s', '--sources', dest='labels', default='', required=False) @manager.option('-s', '--sources', dest='labels')
def sync_sources(labels): def sync_sources(labels):
""" """
Attempts to run several methods Certificate discovery. This is Attempts to run several methods Certificate discovery. This is
@ -207,13 +212,14 @@ def sync_sources(labels):
try: try:
sync_lock.acquire(timeout=10) # wait up to 10 seconds sync_lock.acquire(timeout=10) # wait up to 10 seconds
if labels:
sys.stdout.write("[+] Staring to sync sources: {labels}!\n".format(labels=labels)) sys.stdout.write("[+] Staring to sync sources: {labels}!\n".format(labels=labels))
labels = labels.split(",") labels = labels.split(",")
else:
sys.stdout.write("[+] Starting to sync ALL sources!\n")
if labels[0] == 'all':
sync()
else:
sync(labels=labels) sync(labels=labels)
sys.stdout.write( sys.stdout.write(
"[+] Finished syncing sources. Run Time: {time}\n".format( "[+] Finished syncing sources. Run Time: {time}\n".format(
time=(time.time() - start_time) time=(time.time() - start_time)
@ -680,6 +686,38 @@ class ProvisionELB(Command):
done = True done = True
@manager.command
def publish_verisign_units():
"""
Simple function that queries verisign for API units and posts the mertics to
Atlas API for other teams to consume.
:return:
"""
from lemur.plugins import plugins
v = plugins.get('verisign-issuer')
units = v.get_available_units()
metrics = {}
for item in units:
if item['@type'] in metrics.keys():
metrics[item['@type']] += int(item['@remaining'])
else:
metrics.update({item['@type']: int(item['@remaining'])})
for name, value in metrics.items():
metric = [
{
"timestamp": 1321351651,
"type": "GAUGE",
"name": "Symantec {0} Unit Count".format(name),
"tags": {},
"value": value
}
]
requests.post('http://localhost:8078/metrics', data=json.dumps(metric))
def main(): def main():
manager.add_command("start", LemurServer()) manager.add_command("start", LemurServer())
manager.add_command("runserver", Server(host='127.0.0.1')) manager.add_command("runserver", Server(host='127.0.0.1'))

View File

@ -39,7 +39,7 @@ install_requires = [
'six==1.9.0', 'six==1.9.0',
'gunicorn==19.3.0', 'gunicorn==19.3.0',
'pycrypto==2.6.1', 'pycrypto==2.6.1',
'cryptography>=1.0dev', 'cryptography==1.0',
'pyopenssl==0.15.1', 'pyopenssl==0.15.1',
'pyjwt==1.0.1', 'pyjwt==1.0.1',
'xmltodict==0.9.2', 'xmltodict==0.9.2',