diff options
author | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2012-11-14 10:36:53 -0500 |
---|---|---|
committer | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2012-11-14 11:57:06 -0500 |
commit | 5c0e7644cb666ac499718614f011863e6d84f70b (patch) | |
tree | d40fb4c874c269a2b58f428ab49a96b3a79fee22 /src | |
parent | 2fecc7a73e658f3977e0351f900694a68f404db3 (diff) | |
download | bcfg2-5c0e7644cb666ac499718614f011863e6d84f70b.tar.gz bcfg2-5c0e7644cb666ac499718614f011863e6d84f70b.tar.bz2 bcfg2-5c0e7644cb666ac499718614f011863e6d84f70b.zip |
SSLCA: clean up temp files on error, better error messages
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/Bcfg2/Server/Plugins/SSLCA.py | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/src/lib/Bcfg2/Server/Plugins/SSLCA.py b/src/lib/Bcfg2/Server/Plugins/SSLCA.py index 2a621eeb0..a920a9cca 100644 --- a/src/lib/Bcfg2/Server/Plugins/SSLCA.py +++ b/src/lib/Bcfg2/Server/Plugins/SSLCA.py @@ -9,6 +9,7 @@ import lxml.etree import tempfile from subprocess import Popen, PIPE, STDOUT from Bcfg2.Compat import ConfigParser, md5 +from Bcfg2.Server.Plugin import PluginExecutionError class SSLCA(Bcfg2.Server.Plugin.GroupSpool): @@ -235,29 +236,37 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): """ creates a new certificate according to the specification """ - req_config = self.build_req_config(entry, metadata) - req = self.build_request(key_filename, req_config, entry) - ca = self.cert_specs[entry.get('name')]['ca'] - ca_config = self.CAs[ca]['config'] - days = self.cert_specs[entry.get('name')]['days'] - passphrase = self.CAs[ca].get('passphrase') - cmd = ["openssl", "ca", "-config", ca_config, "-in", req, - "-days", days, "-batch"] - if passphrase: - cmd.extend(["-passin", "pass:%s" % passphrase]) - self.debug_log("SSLCA: Generating new certificate: %s" % " ".join(cmd)) - proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) - (cert, err) = proc.communicate() - if proc.wait(): - raise Bcfg2.Server.Plugin.PluginExecutionError( - "SSLCA: Failed to generate cert: %s" % - err.splitlines()[-1]) # pylint: disable=E1103 + req_config = None + req = None try: - os.unlink(req_config) - os.unlink(req) - except OSError: - self.logger.error("SSLCA: Failed to unlink temporary files: %s" % - sys.exc_info()[1]) + req_config = self.build_req_config(entry, metadata) + req = self.build_request(key_filename, req_config, entry) + ca = self.cert_specs[entry.get('name')]['ca'] + ca_config = self.CAs[ca]['config'] + days = self.cert_specs[entry.get('name')]['days'] + passphrase = self.CAs[ca].get('passphrase') + cmd = ["openssl", "ca", "-config", ca_config, "-in", req, + "-days", days, "-batch"] + if passphrase: + cmd.extend(["-passin", "pass:%s" % passphrase]) + self.debug_log("SSLCA: Generating new certificate: %s" % + " ".join(cmd)) + proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) + (cert, err) = proc.communicate() + if proc.wait(): + # pylint: disable=E1103 + raise PluginExecutionError("SSLCA: Failed to generate cert: %s" + % err.splitlines()[-1]) + # pylint: enable=E1103 + finally: + try: + if req_config and os.path.exists(req_config): + os.unlink(req_config) + if req and os.path.exists(req): + os.unlink(req) + except OSError: + self.logger.error("SSLCA: Failed to unlink temporary files: %s" + % sys.exc_info()[1]) if (self.cert_specs[entry.get('name')]['append_chain'] and self.CAs[ca]['chaincert']): cert += open(self.CAs[ca]['chaincert']).read() @@ -269,7 +278,7 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): used to generate the required certificate request """ # create temp request config file - conffile = open(tempfile.mkstemp()[1], 'w') + fh, fname = tempfile.mkstemp() cfp = ConfigParser.ConfigParser({}) cfp.optionxform = str defaults = { @@ -301,19 +310,28 @@ class SSLCA(Bcfg2.Server.Plugin.GroupSpool): cfp.set('req_distinguished_name', item, self.cert_specs[entry.get('name')][item]) cfp.set('req_distinguished_name', 'CN', metadata.hostname) - cfp.write(conffile) - conffile.close() - return conffile.name + self.debug_log("SSLCA: Writing temporary request config to %s" % fname) + try: + cfp.write(os.fdopen(fh, 'w')) + except IOError: + raise PluginExecutionError("SSLCA: Failed to write temporary CSR " + "config file: %s" % sys.exc_info()[1]) + return fname def build_request(self, key_filename, req_config, entry): """ creates the certificate request """ - req = tempfile.mkstemp()[1] + fh, req = tempfile.mkstemp() + os.close(fh) days = self.cert_specs[entry.get('name')]['days'] key = self.data + key_filename cmd = ["openssl", "req", "-new", "-config", req_config, "-days", days, "-key", key, "-text", "-out", req] self.debug_log("SSLCA: Generating new CSR: %s" % " ".join(cmd)) - Popen(cmd, stdout=PIPE).wait() + proc = Popen(cmd, stdout=PIPE, stderr=PIPE) + err = proc.communicate()[1] + if proc.wait(): + raise PluginExecutionError("SSLCA: Failed to generate CSR: %s" % + err) return req |