Validator chains now exit on the first error
Also, added some more robust error handling for buggy validators. A broken validator will now cause Anchor to fail-closed and deny a certificate, exactly as if that validator test had failed normally. A message is logged giving information about the error and a 500 is returned to the calling service with minimal information. Change-Id: Iddbd0e831a52cc02cc569f220aebf82bd59554d0
This commit is contained in:
parent
abd2fef7a8
commit
a573aa7e04
@ -106,20 +106,22 @@ def validate_csr(auth_result, csr, request):
|
|||||||
# so we set the initial state to valid.
|
# so we set the initial state to valid.
|
||||||
valid = True
|
valid = True
|
||||||
|
|
||||||
for name, vset in jsonloader.conf.validators.iteritems():
|
try:
|
||||||
logger.debug("validate_csr: checking {}".format(name))
|
for name, vset in jsonloader.conf.validators.iteritems():
|
||||||
|
logger.debug("validate_csr: checking with set {}".format(name))
|
||||||
|
for vname, validator in vset.iteritems():
|
||||||
|
valid = _run_validator(vname, validator, args)
|
||||||
|
if not valid:
|
||||||
|
break # early out at the first error
|
||||||
|
|
||||||
results = [_run_validator(x, y, args) for x, y in vset.iteritems()]
|
except Exception as e:
|
||||||
results.append(valid) # track previous failures
|
logger.exception("Error running validator <%s> - %s", vname, e)
|
||||||
valid = all(results)
|
pecan.abort(500, "Internal Validation Error running validator "
|
||||||
|
"'{}' in set '{}'".format(vname, name))
|
||||||
# valid here says that either (1) we didn't run any tests, or (2) we
|
|
||||||
# ran some tests and they all passed. Either way, we can just return.
|
|
||||||
if valid:
|
|
||||||
return
|
|
||||||
|
|
||||||
# something failed, return a 400 to the client
|
# something failed, return a 400 to the client
|
||||||
pecan.abort(400, "CSR failed validation")
|
if not valid:
|
||||||
|
pecan.abort(400, "CSR failed validation")
|
||||||
|
|
||||||
|
|
||||||
def sign(csr):
|
def sign(csr):
|
||||||
|
@ -25,6 +25,7 @@ import pecan
|
|||||||
from pecan import testing as pecan_testing
|
from pecan import testing as pecan_testing
|
||||||
|
|
||||||
from anchor import jsonloader
|
from anchor import jsonloader
|
||||||
|
from anchor import validators
|
||||||
from anchor.X509 import certificate as X509_cert
|
from anchor.X509 import certificate as X509_cert
|
||||||
import config
|
import config
|
||||||
|
|
||||||
@ -154,3 +155,21 @@ class TestFunctional(unittest.TestCase):
|
|||||||
# make sure the cert was issued by anchor
|
# make sure the cert was issued by anchor
|
||||||
self.assertEqual("/C=UK/ST=Some-State/O=OSSG/CN=anchor.example.com",
|
self.assertEqual("/C=UK/ST=Some-State/O=OSSG/CN=anchor.example.com",
|
||||||
str(cert.get_issuer()))
|
str(cert.get_issuer()))
|
||||||
|
|
||||||
|
def test_check_broken_validator(self):
|
||||||
|
data = {'user': 'myusername',
|
||||||
|
'secret': 'simplepassword',
|
||||||
|
'encoding': 'pem',
|
||||||
|
'csr': TestFunctional.csr_good}
|
||||||
|
|
||||||
|
def derp(**kwdargs):
|
||||||
|
raise Exception("BOOM")
|
||||||
|
|
||||||
|
validators.broken_validator = derp
|
||||||
|
jsonloader.conf.validators["default"]["broken_validator"] = {}
|
||||||
|
|
||||||
|
resp = self.app.post('/sign', data, expect_errors=True)
|
||||||
|
self.assertEqual(500, resp.status_int)
|
||||||
|
self.assertTrue(("Internal Validation Error running "
|
||||||
|
"validator 'broken_validator' "
|
||||||
|
"in set 'default'") in str(resp))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user