Merge "Add audit"

This commit is contained in:
Jenkins 2015-12-01 16:32:44 +00:00 committed by Gerrit Code Review
commit d33ce42512
4 changed files with 121 additions and 10 deletions

91
anchor/audit/__init__.py Normal file
View File

@ -0,0 +1,91 @@
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import logging
from pycadf import cadftaxonomy
from pycadf import event
from pycadf import identifier
from pycadf import resource
logger = logging.getLogger(__name__)
def _emit_event(ev):
# no actual implementation yet
if not ev.is_valid():
logger.error("created invalid audit event: %s", ev)
def _event_defaults(result):
# eventType, id, eventTime are filled in automatically by pyCADF
return {
'outcome': (cadftaxonomy.OUTCOME_SUCCESS if result else
cadftaxonomy.OUTCOME_FAILURE),
}
def _user_resource(username):
return resource.Resource(
# TODO(stan): generate id from username if it's known
# this should also get username from keystone tokens to work correctly
id=identifier.generate_uuid(),
typeURI=cadftaxonomy.ACCOUNT_USER,
name=username)
def _auth_resource(ra_name):
return resource.Resource(
id='anchor://authentication',
typeURI=cadftaxonomy.SERVICE_SECURITY,
domain=ra_name)
def _policy_resource(ra_name):
return resource.Resource(
id='anchor://certificates/policy',
typeURI=cadftaxonomy.SECURITY_POLICY,
domain=ra_name)
def _certificate_resource(fingerprint):
if fingerprint is None:
res_id = identifier.generate_uuid()
else:
res_id = "certificate:%s" % (fingerprint,)
return resource.Resource(
id=res_id,
typeURI=cadftaxonomy.SECURITY_KEY,
)
def emit_auth_event(ra_name, username, result):
params = _event_defaults(result)
params['action'] = 'authenticate'
params['initiator'] = _user_resource(username)
auth_res = _auth_resource(ra_name)
params['observer'] = auth_res
params['target'] = auth_res
_emit_event(event.Event(**params))
def emit_signing_event(ra_name, username, result, fingerprint=None):
params = _event_defaults(result)
params['action'] = 'evaluate'
params['initiator'] = _user_resource(username)
params['observer'] = _policy_resource(ra_name)
params['target'] = _certificate_resource(fingerprint)
# add when pycadf merges event names
# params['name'] = "certificate signing"
_emit_event(event.Event(**params))

View File

@ -123,8 +123,8 @@ def dispatch_sign(ra_name, csr):
logger.exception("Failed to sign the certificate")
pecan.abort(500, "certificate signing error")
fingerprint = certificate_fingerprint(cert_pem, 'sha256')
if ca_conf.get('output_path') is not None:
fingerprint = certificate_fingerprint(cert_pem, 'sha256')
path = os.path.join(
ca_conf['output_path'],
'%s.crt' % fingerprint)
@ -134,7 +134,7 @@ def dispatch_sign(ra_name, csr):
with open(path, "w") as f:
f.write(cert_pem)
return cert_pem
return cert_pem, fingerprint
def _run_fixup(name, body, args):

View File

@ -15,7 +15,9 @@ import logging
import pecan
from pecan import rest
from webob import exc as http_status
from anchor import audit
from anchor import auth
from anchor import certificate_ops
from anchor import jsonloader
@ -46,15 +48,32 @@ class SignInstanceController(GenericInstanceController):
logger.debug("processing signing request in registration authority %s",
ra_name)
auth_result = auth.validate(ra_name,
pecan.request.POST.get('user'),
pecan.request.POST.get('secret'))
csr = certificate_ops.parse_csr(pecan.request.POST.get('csr'),
pecan.request.POST.get('encoding'))
certificate_ops.validate_csr(ra_name, auth_result, csr, pecan.request)
csr = certificate_ops.fixup_csr(ra_name, csr, pecan.request)
try:
auth_result = auth.validate(ra_name,
pecan.request.POST.get('user'),
pecan.request.POST.get('secret'))
audit.emit_auth_event(ra_name, pecan.request.POST.get('user'),
True)
except http_status.HTTPUnauthorized:
audit.emit_auth_event(ra_name, pecan.request.POST.get('user'),
False)
raise
return certificate_ops.dispatch_sign(ra_name, csr)
try:
csr = certificate_ops.parse_csr(pecan.request.POST.get('csr'),
pecan.request.POST.get('encoding'))
certificate_ops.validate_csr(ra_name, auth_result, csr,
pecan.request)
csr = certificate_ops.fixup_csr(ra_name, csr, pecan.request)
cert, fingerprint = certificate_ops.dispatch_sign(ra_name, csr)
audit.emit_signing_event(ra_name, pecan.request.POST.get('user'),
True, fingerprint=fingerprint)
except Exception:
audit.emit_signing_event(ra_name, pecan.request.POST.get('user'),
False)
raise
return cert
class CAInstanceController(GenericInstanceController):

View File

@ -10,3 +10,4 @@ netaddr!=0.7.16,>=0.7.12
ldap3>=0.9.8.2 # LGPLv3
requests!=2.8.0,>=2.5.2
stevedore>=1.5.0 # Apache-2.0
pycadf>=1.1.0