mirror of
https://github.com/moepman/acertmgr.git
synced 2024-12-29 10:31:49 +01:00
acertmgr: implement deployment error handling
Remove the long-standing todo from cert_put and implement useful error handling and defaults for certificate deployment. Also do a separate try/expect for each deployed file on every single certificate.
This commit is contained in:
parent
7c9e7f7d0c
commit
89be66dc87
@ -99,11 +99,11 @@ By default the directory (work_dir) containing the working data (csr,certificate
|
|||||||
| nsupdate_keyalgorithm | **d**,g | [dns.nsupdate] TSIG key algorithm to use for updates | HMAC-MD5.SIG-ALG.REG.INT |
|
| nsupdate_keyalgorithm | **d**,g | [dns.nsupdate] TSIG key algorithm to use for updates | HMAC-MD5.SIG-ALG.REG.INT |
|
||||||
| defaults: | **g** | Default deployment action settings used by all domains | |
|
| defaults: | **g** | Default deployment action settings used by all domains | |
|
||||||
| path | **d** | (deployment) deploy certificate data to the given file | |
|
| path | **d** | (deployment) deploy certificate data to the given file | |
|
||||||
| user | **d**,g(defaults) | (deployment) change the user of the file deployed at path to this value | |
|
|
||||||
| group | **d**,g(defaults) | (deployment) change the group of the file deployed at path to this value | |
|
|
||||||
| perm | **d**,g(defaults) | (deployment) change the permissions of the file deployed at path to this value | |
|
|
||||||
| format | **d**,g(defaults) | (deployment) deploy one or more of the following data to the file at path: key,crt,ca | |
|
| format | **d**,g(defaults) | (deployment) deploy one or more of the following data to the file at path: key,crt,ca | |
|
||||||
| action | **d**,g(defaults) | (deployment) run the following action after deployment is finished. This command will be run in a shell and therefore supports shell syntax. | |
|
| user | **d**,g(defaults) | (deployment) change the user of the file deployed at path to this value (optional, defaults to acertmgr current effective user) | |
|
||||||
|
| group | **d**,g(defaults) | (deployment) change the group of the file deployed at path to this value (optional,defaults to acertmgr current effective group) | |
|
||||||
|
| perm | **d**,g(defaults) | (deployment) change the permissions of the file deployed at path to this value (optional, CAUTION: uses system defaults for new files) | |
|
||||||
|
| action | **d**,g(defaults) | (deployment) run the following action after deployment is finished. This command will be run in a shell and supports it's syntax. (optional) | |
|
||||||
|
|
||||||
Security
|
Security
|
||||||
--------
|
--------
|
||||||
|
@ -70,52 +70,41 @@ def cert_get(settings):
|
|||||||
# @param settings the domain's configuration options
|
# @param settings the domain's configuration options
|
||||||
# @return the action to be executed after the certificate update
|
# @return the action to be executed after the certificate update
|
||||||
def cert_put(settings):
|
def cert_put(settings):
|
||||||
# TODO error handling
|
if 'path' not in settings:
|
||||||
ca_file = settings['ca_file']
|
raise ValueError('Deployment settings are missing required element: path')
|
||||||
crt_user = settings['user']
|
if 'format' not in settings:
|
||||||
crt_group = settings['group']
|
raise ValueError('Deployment settings are missing required element: format')
|
||||||
crt_perm = settings['perm']
|
|
||||||
crt_path = settings['path']
|
|
||||||
crt_format = settings['format'].split(",")
|
|
||||||
crt_format = [str.strip(x) for x in crt_format]
|
|
||||||
crt_action = settings['action']
|
|
||||||
|
|
||||||
key_file = settings['key_file']
|
with io.open(settings['path'], "w+") as crt_fd:
|
||||||
crt_final = settings['cert_file']
|
for fmt in [str.strip(x) for x in settings['format'].split(",")]:
|
||||||
|
|
||||||
with io.open(crt_path, "w+") as crt_fd:
|
|
||||||
for fmt in crt_format:
|
|
||||||
if fmt == "crt":
|
if fmt == "crt":
|
||||||
src_fd = io.open(crt_final, "r")
|
with io.open(settings['cert_file'], "r") as src_fd:
|
||||||
crt_fd.write(src_fd.read())
|
crt_fd.write(src_fd.read())
|
||||||
src_fd.close()
|
elif fmt == "key":
|
||||||
if fmt == "key":
|
with io.open(settings['key_file'], "r") as src_fd:
|
||||||
src_fd = io.open(key_file, "r")
|
crt_fd.write(src_fd.read())
|
||||||
crt_fd.write(src_fd.read())
|
elif fmt == "ca":
|
||||||
src_fd.close()
|
with io.open(settings['ca_file'], "r") as src_fd:
|
||||||
if fmt == "ca":
|
crt_fd.write(src_fd.read())
|
||||||
if not os.path.isfile(ca_file):
|
|
||||||
raise FileNotFoundError("The CA certificate file (%s) is missing!" % ca_file)
|
|
||||||
src_fd = io.open(ca_file, "r")
|
|
||||||
crt_fd.write(src_fd.read())
|
|
||||||
src_fd.close()
|
|
||||||
else:
|
else:
|
||||||
# TODO error handling
|
log("Ignored unknown deployment format key: {}".format(fmt), warning=True)
|
||||||
pass
|
|
||||||
|
|
||||||
# set owner and permissions
|
# set owner and group
|
||||||
uid = pwd.getpwnam(crt_user).pw_uid
|
if 'user' in settings or 'group' in settings:
|
||||||
gid = grp.getgrnam(crt_group).gr_gid
|
try:
|
||||||
try:
|
uid = pwd.getpwnam(settings['user']).pw_uid if 'user' in settings else os.geteuid()
|
||||||
os.chown(crt_path, uid, gid)
|
gid = grp.getgrnam(settings['group']).gr_gid if 'group' in settings else os.getegid()
|
||||||
except OSError:
|
os.chown(settings['path'], uid, gid)
|
||||||
log('Could not set certificate file ownership!', warning=True)
|
except OSError as e:
|
||||||
try:
|
log('Could not set certificate file ownership', e, warning=True)
|
||||||
os.chmod(crt_path, int(crt_perm, 8))
|
# set permissions
|
||||||
except OSError:
|
if 'perm' in settings:
|
||||||
log('Could not set certificate file permissions!', warning=True)
|
try:
|
||||||
|
os.chmod(settings['path'], int(settings['perm'], 8))
|
||||||
|
except OSError as e:
|
||||||
|
log('Could not set certificate file permissions', e, warning=True)
|
||||||
|
|
||||||
return crt_action
|
return settings['action']
|
||||||
|
|
||||||
|
|
||||||
def cert_revoke(cert, configs, fallback_authority, reason=None):
|
def cert_revoke(cert, configs, fallback_authority, reason=None):
|
||||||
@ -169,15 +158,15 @@ def main():
|
|||||||
# deploy new certificates after all are renewed
|
# deploy new certificates after all are renewed
|
||||||
deployment_success = True
|
deployment_success = True
|
||||||
for config in domainconfigs:
|
for config in domainconfigs:
|
||||||
try:
|
for cfg in config['actions']:
|
||||||
for cfg in config['actions']:
|
try:
|
||||||
if not tools.target_is_current(cfg['path'], config['cert_file']):
|
if not tools.target_is_current(cfg['path'], config['cert_file']):
|
||||||
log("Updating '{}' due to newer version".format(cfg['path']))
|
|
||||||
actions.add(cert_put(cfg))
|
actions.add(cert_put(cfg))
|
||||||
except Exception as e:
|
log("Updated '{}' due to newer version".format(cfg['path']))
|
||||||
log("Certificate deployment failed", e, error=True)
|
except Exception as e:
|
||||||
exceptions.append(e)
|
log("Certificate deployment to {} failed".format(cfg['path']), e, error=True)
|
||||||
deployment_success = False
|
exceptions.append(e)
|
||||||
|
deployment_success = False
|
||||||
|
|
||||||
# run post-update actions
|
# run post-update actions
|
||||||
for action in actions:
|
for action in actions:
|
||||||
|
Loading…
Reference in New Issue
Block a user