Merge branch 'master' into master

This commit is contained in:
Hossein Shafagh 2019-01-29 16:30:15 -08:00 committed by GitHub
commit 7f4f4ffded
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 98 additions and 60 deletions

View File

@ -227,6 +227,10 @@ class Certificate(db.Model):
def location(self): def location(self):
return defaults.location(self.parsed_cert) return defaults.location(self.parsed_cert)
@property
def distinguished_name(self):
return self.parsed_cert.subject.rfc4514_string()
@property @property
def key_type(self): def key_type(self):
if isinstance(self.parsed_cert.public_key(), rsa.RSAPublicKey): if isinstance(self.parsed_cert.public_key(), rsa.RSAPublicKey):

View File

@ -206,6 +206,7 @@ class CertificateOutputSchema(LemurOutputSchema):
cn = fields.String() cn = fields.String()
common_name = fields.String(attribute='cn') common_name = fields.String(attribute='cn')
distinguished_name = fields.String()
not_after = fields.DateTime() not_after = fields.DateTime()
validity_end = ArrowDateTime(attribute='not_after') validity_end = ArrowDateTime(attribute='not_after')

View File

@ -273,10 +273,11 @@ class CreateUser(Command):
Option('-u', '--username', dest='username', required=True), Option('-u', '--username', dest='username', required=True),
Option('-e', '--email', dest='email', required=True), Option('-e', '--email', dest='email', required=True),
Option('-a', '--active', dest='active', default=True), Option('-a', '--active', dest='active', default=True),
Option('-r', '--roles', dest='roles', action='append', default=[]) Option('-r', '--roles', dest='roles', action='append', default=[]),
Option('-p', '--password', dest='password', default=None)
) )
def run(self, username, email, active, roles): def run(self, username, email, active, roles, password):
role_objs = [] role_objs = []
for r in roles: for r in roles:
role_obj = role_service.get_by_name(r) role_obj = role_service.get_by_name(r)
@ -286,14 +287,16 @@ class CreateUser(Command):
sys.stderr.write("[!] Cannot find role {0}\n".format(r)) sys.stderr.write("[!] Cannot find role {0}\n".format(r))
sys.exit(1) sys.exit(1)
password1 = prompt_pass("Password") if not password:
password2 = prompt_pass("Confirm Password") password1 = prompt_pass("Password")
password2 = prompt_pass("Confirm Password")
password = password1
if password1 != password2: if password1 != password2:
sys.stderr.write("[!] Passwords do not match!\n") sys.stderr.write("[!] Passwords do not match!\n")
sys.exit(1) sys.exit(1)
user_service.create(username, password1, email, active, None, role_objs) user_service.create(username, password, email, active, None, role_objs)
sys.stdout.write("[+] Created new user: {0}\n".format(username)) sys.stdout.write("[+] Created new user: {0}\n".format(username))

View File

@ -5,7 +5,7 @@ import dns.exception
import dns.name import dns.name
import dns.query import dns.query
import dns.resolver import dns.resolver
from dyn.tm.errors import DynectCreateError from dyn.tm.errors import DynectCreateError, DynectGetError
from dyn.tm.session import DynectSession from dyn.tm.session import DynectSession
from dyn.tm.zones import Node, Zone, get_all_zones from dyn.tm.zones import Node, Zone, get_all_zones
from flask import current_app from flask import current_app
@ -119,7 +119,11 @@ def delete_txt_record(change_id, account_number, domain, token):
zone = Zone(zone_name) zone = Zone(zone_name)
node = Node(zone_name, fqdn) node = Node(zone_name, fqdn)
all_txt_records = node.get_all_records_by_type('TXT') try:
all_txt_records = node.get_all_records_by_type('TXT')
except DynectGetError:
# No Text Records remain or host is not in the zone anymore because all records have been deleted.
return
for txt_record in all_txt_records: for txt_record in all_txt_records:
if txt_record.txtdata == ("{}".format(token)): if txt_record.txtdata == ("{}".format(token)):
current_app.logger.debug("Deleting TXT record name: {0}".format(fqdn)) current_app.logger.debug("Deleting TXT record name: {0}".format(fqdn))

View File

@ -10,6 +10,9 @@
import json import json
import requests import requests
import base64
import hmac
import hashlib
from flask import current_app from flask import current_app
@ -48,6 +51,21 @@ class CfsslIssuerPlugin(IssuerPlugin):
data = {'certificate_request': csr} data = {'certificate_request': csr}
data = json.dumps(data) data = json.dumps(data)
try:
hex_key = current_app.config.get('CFSSL_KEY')
key = bytes.fromhex(hex_key)
except (ValueError, NameError):
# unable to find CFSSL_KEY in config, continue using normal sign method
pass
else:
data = data.encode()
token = base64.b64encode(hmac.new(key, data, digestmod=hashlib.sha256).digest())
data = base64.b64encode(data)
data = json.dumps({'token': token.decode('utf-8'), 'request': data.decode('utf-8')})
url = "{0}{1}".format(current_app.config.get('CFSSL_URL'), '/api/v1/cfssl/authsign')
response = self.session.post(url, data=data.encode(encoding='utf_8', errors='strict')) response = self.session.post(url, data=data.encode(encoding='utf_8', errors='strict'))
if response.status_code > 399: if response.status_code > 399:
metrics.send('cfssl_create_certificate_failure', 'counter', 1) metrics.send('cfssl_create_certificate_failure', 'counter', 1)

View File

@ -83,6 +83,8 @@
</div> </div>
<!-- Certificate fields --> <!-- Certificate fields -->
<div class="list-group-item"> <div class="list-group-item">
<dt>Distinguished Name</dt>
<dd>{{ certificate.distinguishedName }}</dd>
<dt>Certificate Authority</dt> <dt>Certificate Authority</dt>
<dd>{{ certificate.authority ? certificate.authority.name : "Imported" }} <span class="text-muted">({{ certificate.issuer }})</span></dd> <dd>{{ certificate.authority ? certificate.authority.name : "Imported" }} <span class="text-muted">({{ certificate.issuer }})</span></dd>
<dt>Serial</dt> <dt>Serial</dt>

View File

@ -619,6 +619,12 @@ def test_certificate_get_body(client):
response_body = client.get(api.url_for(Certificates, certificate_id=1), headers=VALID_USER_HEADER_TOKEN).json response_body = client.get(api.url_for(Certificates, certificate_id=1), headers=VALID_USER_HEADER_TOKEN).json
assert response_body['serial'] == '211983098819107449768450703123665283596' assert response_body['serial'] == '211983098819107449768450703123665283596'
assert response_body['serialHex'] == '9F7A75B39DAE4C3F9524C68B06DA6A0C' assert response_body['serialHex'] == '9F7A75B39DAE4C3F9524C68B06DA6A0C'
assert response_body['distinguishedName'] == ('CN=LemurTrust Unittests Class 1 CA 2018,'
'O=LemurTrust Enterprises Ltd,'
'OU=Unittesting Operations Center,'
'C=EE,'
'ST=N/A,'
'L=Earth')
@pytest.mark.parametrize("token,status", [ @pytest.mark.parametrize("token,status", [

View File

@ -4,14 +4,14 @@
# #
# pip-compile --no-index --output-file requirements-dev.txt requirements-dev.in # pip-compile --no-index --output-file requirements-dev.txt requirements-dev.in
# #
aspy.yaml==1.1.1 # via pre-commit aspy.yaml==1.1.2 # via pre-commit
bleach==3.1.0 # via readme-renderer bleach==3.1.0 # via readme-renderer
certifi==2018.11.29 # via requests certifi==2018.11.29 # via requests
cfgv==1.4.0 # via pre-commit cfgv==1.4.0 # via pre-commit
chardet==3.0.4 # via requests chardet==3.0.4 # via requests
docutils==0.14 # via readme-renderer docutils==0.14 # via readme-renderer
flake8==3.5.0 flake8==3.5.0
identify==1.1.8 # via pre-commit identify==1.2.1 # via pre-commit
idna==2.8 # via requests idna==2.8 # via requests
importlib-metadata==0.8 # via pre-commit importlib-metadata==0.8 # via pre-commit
importlib-resources==1.0.2 # via pre-commit importlib-resources==1.0.2 # via pre-commit
@ -19,19 +19,19 @@ invoke==1.2.0
mccabe==0.6.1 # via flake8 mccabe==0.6.1 # via flake8
nodeenv==1.3.3 nodeenv==1.3.3
pkginfo==1.5.0.1 # via twine pkginfo==1.5.0.1 # via twine
pre-commit==1.14.0 pre-commit==1.14.2
pycodestyle==2.3.1 # via flake8 pycodestyle==2.3.1 # via flake8
pyflakes==1.6.0 # via flake8 pyflakes==1.6.0 # via flake8
pygments==2.3.1 # via readme-renderer pygments==2.3.1 # via readme-renderer
pyyaml==3.13 # via aspy.yaml, pre-commit pyyaml==3.13 # via aspy.yaml, pre-commit
readme-renderer==24.0 # via twine readme-renderer==24.0 # via twine
requests-toolbelt==0.8.0 # via twine requests-toolbelt==0.9.0 # via twine
requests==2.21.0 # via requests-toolbelt, twine requests==2.21.0 # via requests-toolbelt, twine
six==1.12.0 # via bleach, cfgv, pre-commit, readme-renderer six==1.12.0 # via bleach, cfgv, pre-commit, readme-renderer
toml==0.10.0 # via pre-commit toml==0.10.0 # via pre-commit
tqdm==4.29.0 # via twine tqdm==4.30.0 # via twine
twine==1.12.1 twine==1.12.1
urllib3==1.24.1 # via requests urllib3==1.24.1 # via requests
virtualenv==16.2.0 # via pre-commit virtualenv==16.3.0 # via pre-commit
webencodings==0.5.1 # via bleach webencodings==0.5.1 # via bleach
zipp==0.3.3 # via importlib-metadata zipp==0.3.3 # via importlib-metadata

View File

@ -4,28 +4,28 @@
# #
# pip-compile --no-index --output-file requirements-docs.txt requirements-docs.in # pip-compile --no-index --output-file requirements-docs.txt requirements-docs.in
# #
acme==0.30.0 acme==0.30.2
alabaster==0.7.12 # via sphinx alabaster==0.7.12 # via sphinx
alembic-autogenerate-enums==0.0.2 alembic-autogenerate-enums==0.0.2
alembic==1.0.5 alembic==1.0.7
amqp==2.3.2 amqp==2.4.0
aniso8601==4.1.0 aniso8601==4.1.0
arrow==0.13.0 arrow==0.13.0
asn1crypto==0.24.0 asn1crypto==0.24.0
asyncpool==1.0 asyncpool==1.0
babel==2.6.0 # via sphinx babel==2.6.0 # via sphinx
bcrypt==3.1.5 bcrypt==3.1.6
billiard==3.5.0.5 billiard==3.5.0.5
blinker==1.4 blinker==1.4
boto3==1.9.76 boto3==1.9.86
botocore==1.12.76 botocore==1.12.86
celery[redis]==4.2.1 celery[redis]==4.2.1
certifi==2018.11.29 certifi==2018.11.29
cffi==1.11.5 cffi==1.11.5
chardet==3.0.4 chardet==3.0.4
click==7.0 click==7.0
cloudflare==2.1.0 cloudflare==2.1.0
cryptography==2.4.2 cryptography==2.5
dnspython3==1.15.0 dnspython3==1.15.0
dnspython==1.15.0 dnspython==1.15.0
docutils==0.14 docutils==0.14
@ -54,22 +54,22 @@ lockfile==0.12.2
mako==1.0.7 mako==1.0.7
markupsafe==1.1.0 markupsafe==1.1.0
marshmallow-sqlalchemy==0.15.0 marshmallow-sqlalchemy==0.15.0
marshmallow==2.17.0 marshmallow==2.18.0
mock==2.0.0 mock==2.0.0
ndg-httpsclient==0.5.1 ndg-httpsclient==0.5.1
packaging==18.0 # via sphinx packaging==19.0 # via sphinx
paramiko==2.4.2 paramiko==2.4.2
pbr==5.1.1 pbr==5.1.1
pem==18.2.0 pem==18.2.0
psycopg2==2.7.6.1 psycopg2==2.7.7
pyasn1-modules==0.2.3 pyasn1-modules==0.2.4
pyasn1==0.4.5 pyasn1==0.4.5
pycparser==2.19 pycparser==2.19
pygments==2.3.1 # via sphinx pygments==2.3.1 # via sphinx
pyjwt==1.7.1 pyjwt==1.7.1
pynacl==1.3.0 pynacl==1.3.0
pyopenssl==18.0.0 pyopenssl==19.0.0
pyparsing==2.3.0 # via packaging pyparsing==2.3.1 # via packaging
pyrfc3339==1.1 pyrfc3339==1.1
python-dateutil==2.7.5 python-dateutil==2.7.5
python-editor==1.0.3 python-editor==1.0.3
@ -77,7 +77,7 @@ pytz==2018.9
pyyaml==3.13 pyyaml==3.13
raven[flask]==6.10.0 raven[flask]==6.10.0
redis==2.10.6 redis==2.10.6
requests-toolbelt==0.8.0 requests-toolbelt==0.9.0
requests[security]==2.21.0 requests[security]==2.21.0
retrying==1.3.3 retrying==1.3.3
s3transfer==0.1.13 s3transfer==0.1.13
@ -87,9 +87,9 @@ sphinx-rtd-theme==0.4.2
sphinx==1.8.3 sphinx==1.8.3
sphinxcontrib-httpdomain==1.7.0 sphinxcontrib-httpdomain==1.7.0
sphinxcontrib-websupport==1.1.0 # via sphinx sphinxcontrib-websupport==1.1.0 # via sphinx
sqlalchemy-utils==0.33.10 sqlalchemy-utils==0.33.11
sqlalchemy==1.2.15 sqlalchemy==1.2.17
tabulate==0.8.2 tabulate==0.8.3
urllib3==1.24.1 urllib3==1.24.1
vine==1.2.0 vine==1.2.0
werkzeug==0.14.1 werkzeug==0.14.1

View File

@ -8,30 +8,30 @@ asn1crypto==0.24.0 # via cryptography
atomicwrites==1.2.1 # via pytest atomicwrites==1.2.1 # via pytest
attrs==18.2.0 # via pytest attrs==18.2.0 # via pytest
aws-xray-sdk==0.95 # via moto aws-xray-sdk==0.95 # via moto
boto3==1.9.76 # via moto boto3==1.9.86 # via moto
boto==2.49.0 # via moto boto==2.49.0 # via moto
botocore==1.12.76 # via boto3, moto, s3transfer botocore==1.12.86 # via boto3, moto, s3transfer
certifi==2018.11.29 # via requests certifi==2018.11.29 # via requests
cffi==1.11.5 # via cryptography cffi==1.11.5 # via cryptography
chardet==3.0.4 # via requests chardet==3.0.4 # via requests
click==7.0 # via flask click==7.0 # via flask
coverage==4.5.2 coverage==4.5.2
cryptography==2.4.2 # via moto cryptography==2.5 # via moto
docker-pycreds==0.4.0 # via docker docker-pycreds==0.4.0 # via docker
docker==3.6.0 # via moto docker==3.7.0 # via moto
docutils==0.14 # via botocore docutils==0.14 # via botocore
ecdsa==0.13 # via python-jose ecdsa==0.13 # via python-jose
factory-boy==2.11.1 factory-boy==2.11.1
faker==1.0.1 faker==1.0.2
flask==1.0.2 # via pytest-flask flask==1.0.2 # via pytest-flask
freezegun==0.3.11 freezegun==0.3.11
future==0.17.1 # via python-jose future==0.17.1 # via python-jose
idna==2.8 # via cryptography, requests idna==2.8 # via requests
itsdangerous==1.1.0 # via flask itsdangerous==1.1.0 # via flask
jinja2==2.10 # via flask, moto jinja2==2.10 # via flask, moto
jmespath==0.9.3 # via boto3, botocore jmespath==0.9.3 # via boto3, botocore
jsondiff==1.1.1 # via moto jsondiff==1.1.1 # via moto
jsonpickle==1.0 # via aws-xray-sdk jsonpickle==1.1 # via aws-xray-sdk
markupsafe==1.1.0 # via jinja2 markupsafe==1.1.0 # via jinja2
mock==2.0.0 # via moto mock==2.0.0 # via moto
more-itertools==5.0.0 # via pytest more-itertools==5.0.0 # via pytest
@ -42,11 +42,11 @@ pluggy==0.8.1 # via pytest
py==1.7.0 # via pytest py==1.7.0 # via pytest
pyaml==18.11.0 # via moto pyaml==18.11.0 # via moto
pycparser==2.19 # via cffi pycparser==2.19 # via cffi
pycryptodome==3.7.2 # via python-jose pycryptodome==3.7.3 # via python-jose
pyflakes==2.0.0 pyflakes==2.1.0
pytest-flask==0.14.0 pytest-flask==0.14.0
pytest-mock==1.10.0 pytest-mock==1.10.0
pytest==4.1.0 pytest==4.1.1
python-dateutil==2.7.5 # via botocore, faker, freezegun, moto python-dateutil==2.7.5 # via botocore, faker, freezegun, moto
python-jose==2.0.2 # via moto python-jose==2.0.2 # via moto
pytz==2018.9 # via moto pytz==2018.9 # via moto
@ -60,5 +60,5 @@ text-unidecode==1.2 # via faker
urllib3==1.24.1 # via botocore, requests urllib3==1.24.1 # via botocore, requests
websocket-client==0.54.0 # via docker websocket-client==0.54.0 # via docker
werkzeug==0.14.1 # via flask, moto, pytest-flask werkzeug==0.14.1 # via flask, moto, pytest-flask
wrapt==1.11.0 # via aws-xray-sdk wrapt==1.11.1 # via aws-xray-sdk
xmltodict==0.11.0 # via moto xmltodict==0.11.0 # via moto

View File

@ -4,26 +4,26 @@
# #
# pip-compile --no-index --output-file requirements.txt requirements.in # pip-compile --no-index --output-file requirements.txt requirements.in
# #
acme==0.30.0 acme==0.30.2
alembic-autogenerate-enums==0.0.2 alembic-autogenerate-enums==0.0.2
alembic==1.0.5 # via flask-migrate alembic==1.0.7 # via flask-migrate
amqp==2.3.2 # via kombu amqp==2.4.0 # via kombu
aniso8601==4.1.0 # via flask-restful aniso8601==4.1.0 # via flask-restful
arrow==0.13.0 arrow==0.13.0
asn1crypto==0.24.0 # via cryptography asn1crypto==0.24.0 # via cryptography
asyncpool==1.0 asyncpool==1.0
bcrypt==3.1.5 # via flask-bcrypt, paramiko bcrypt==3.1.6 # via flask-bcrypt, paramiko
billiard==3.5.0.5 # via celery billiard==3.5.0.5 # via celery
blinker==1.4 # via flask-mail, flask-principal, raven blinker==1.4 # via flask-mail, flask-principal, raven
boto3==1.9.76 boto3==1.9.86
botocore==1.12.76 botocore==1.12.86
celery[redis]==4.2.1 celery[redis]==4.2.1
certifi==2018.11.29 certifi==2018.11.29
cffi==1.11.5 # via bcrypt, cryptography, pynacl cffi==1.11.5 # via bcrypt, cryptography, pynacl
chardet==3.0.4 # via requests chardet==3.0.4 # via requests
click==7.0 # via flask click==7.0 # via flask
cloudflare==2.1.0 cloudflare==2.1.0
cryptography==2.4.2 cryptography==2.5
dnspython3==1.15.0 dnspython3==1.15.0
dnspython==1.15.0 # via dnspython3 dnspython==1.15.0 # via dnspython3
docutils==0.14 # via botocore docutils==0.14 # via botocore
@ -39,7 +39,7 @@ flask-sqlalchemy==2.3.2
flask==1.0.2 flask==1.0.2
future==0.17.1 future==0.17.1
gunicorn==19.9.0 gunicorn==19.9.0
idna==2.8 # via cryptography, requests idna==2.8 # via requests
inflection==0.3.1 inflection==0.3.1
itsdangerous==1.1.0 # via flask itsdangerous==1.1.0 # via flask
jinja2==2.10 jinja2==2.10
@ -51,19 +51,19 @@ lockfile==0.12.2
mako==1.0.7 # via alembic mako==1.0.7 # via alembic
markupsafe==1.1.0 # via jinja2, mako markupsafe==1.1.0 # via jinja2, mako
marshmallow-sqlalchemy==0.15.0 marshmallow-sqlalchemy==0.15.0
marshmallow==2.17.0 marshmallow==2.18.0
mock==2.0.0 # via acme mock==2.0.0 # via acme
ndg-httpsclient==0.5.1 ndg-httpsclient==0.5.1
paramiko==2.4.2 paramiko==2.4.2
pbr==5.1.1 # via mock pbr==5.1.1 # via mock
pem==18.2.0 pem==18.2.0
psycopg2==2.7.6.1 psycopg2==2.7.7
pyasn1-modules==0.2.3 # via python-ldap pyasn1-modules==0.2.4 # via python-ldap
pyasn1==0.4.5 # via ndg-httpsclient, paramiko, pyasn1-modules, python-ldap pyasn1==0.4.5 # via ndg-httpsclient, paramiko, pyasn1-modules, python-ldap
pycparser==2.19 # via cffi pycparser==2.19 # via cffi
pyjwt==1.7.1 pyjwt==1.7.1
pynacl==1.3.0 # via paramiko pynacl==1.3.0 # via paramiko
pyopenssl==18.0.0 pyopenssl==19.0.0
pyrfc3339==1.1 # via acme pyrfc3339==1.1 # via acme
python-dateutil==2.7.5 # via alembic, arrow, botocore python-dateutil==2.7.5 # via alembic, arrow, botocore
python-editor==1.0.3 # via alembic python-editor==1.0.3 # via alembic
@ -72,14 +72,14 @@ pytz==2018.9 # via acme, celery, flask-restful, pyrfc3339
pyyaml==3.13 # via cloudflare pyyaml==3.13 # via cloudflare
raven[flask]==6.10.0 raven[flask]==6.10.0
redis==2.10.6 redis==2.10.6
requests-toolbelt==0.8.0 # via acme requests-toolbelt==0.9.0 # via acme
requests[security]==2.21.0 requests[security]==2.21.0
retrying==1.3.3 retrying==1.3.3
s3transfer==0.1.13 # via boto3 s3transfer==0.1.13 # via boto3
six==1.12.0 six==1.12.0
sqlalchemy-utils==0.33.10 sqlalchemy-utils==0.33.11
sqlalchemy==1.2.15 # via alembic, flask-sqlalchemy, marshmallow-sqlalchemy, sqlalchemy-utils sqlalchemy==1.2.17 # via alembic, flask-sqlalchemy, marshmallow-sqlalchemy, sqlalchemy-utils
tabulate==0.8.2 tabulate==0.8.3
urllib3==1.24.1 # via botocore, requests urllib3==1.24.1 # via botocore, requests
vine==1.2.0 # via amqp vine==1.2.0 # via amqp
werkzeug==0.14.1 # via flask werkzeug==0.14.1 # via flask