summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Encryption.py
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-11-12 15:10:10 -0500
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-11-12 15:16:17 -0500
commitb5b26415161e715fe4d22d69328b06801ff7124d (patch)
treec8c006c243930e28269e7d507fdb4383b36d83d8 /src/lib/Bcfg2/Server/Encryption.py
parent6ca45226e27fa8407262bd819fb837d0042ec774 (diff)
downloadbcfg2-b5b26415161e715fe4d22d69328b06801ff7124d.tar.gz
bcfg2-b5b26415161e715fe4d22d69328b06801ff7124d.tar.bz2
bcfg2-b5b26415161e715fe4d22d69328b06801ff7124d.zip
bcfg2-crypt: Fixed several bugs in autodetection of encrypt/decrypt mode
Diffstat (limited to 'src/lib/Bcfg2/Server/Encryption.py')
-rwxr-xr-xsrc/lib/Bcfg2/Server/Encryption.py99
1 files changed, 58 insertions, 41 deletions
diff --git a/src/lib/Bcfg2/Server/Encryption.py b/src/lib/Bcfg2/Server/Encryption.py
index 02c7a0eb8..c6b09df56 100755
--- a/src/lib/Bcfg2/Server/Encryption.py
+++ b/src/lib/Bcfg2/Server/Encryption.py
@@ -229,6 +229,10 @@ class PassphraseError(Exception):
passphrase to encrypt or decrypt with """
+class DecryptError(Exception):
+ """ Exception raised when decryption fails. """
+
+
class CryptoTool(object):
""" Generic decryption/encryption interface base object """
@@ -330,21 +334,17 @@ class CfgDecryptor(Decryptor):
try:
return ssl_decrypt(self.data, self.passphrase)
except EVPError:
- self.logger.info("Could not decrypt %s with the "
- "specified passphrase" % self.filename)
- return False
+ raise DecryptError("Could not decrypt %s with the "
+ "specified passphrase" % self.filename)
except:
- err = sys.exc_info()[1]
- self.logger.error("Error decrypting %s: %s" %
- (self.filename, err))
- return False
+ raise DecryptError("Error decrypting %s: %s" %
+ (self.filename, sys.exc_info()[1]))
else: # no passphrase given, brute force
try:
return bruteforce_decrypt(self.data)
except EVPError:
- self.logger.info("Could not decrypt %s with any passphrase" %
- self.filename)
- return False
+ raise DecryptError("Could not decrypt %s with any passphrase" %
+ self.filename)
def get_destination_filename(self, original_filename):
if original_filename.endswith(".crypt"):
@@ -444,19 +444,20 @@ class PropertiesDecryptor(Decryptor, PropertiesCryptoMixin):
default_xpath = '//*[@encrypted]'
def decrypt(self):
+ decrypted = False
xdata = lxml.etree.XML(self.data, parser=XMLParser)
for elt in self._get_elements(xdata):
try:
pname, passphrase = self._get_element_passphrase(elt)
except PassphraseError:
- self.logger.error(str(sys.exc_info()[1]))
- return False
+ raise DecryptError(str(sys.exc_info()[1]))
self.logger.debug("Decrypting %s" % print_xml(elt))
try:
decrypted = ssl_decrypt(elt.text, passphrase).strip()
elt.text = decrypted.encode('ascii', 'xmlcharrefreplace')
elt.set("encrypted", pname)
- except Bcfg2.Encryption.EVPError:
+ decrypted = True
+ except (EVPError, TypeError):
self.logger.error("Could not decrypt %s, skipping" %
print_xml(elt))
except UnicodeDecodeError:
@@ -467,7 +468,11 @@ class PropertiesDecryptor(Decryptor, PropertiesCryptoMixin):
# a different key, and wound up with gibberish.
self.logger.warning("Decrypted %s to gibberish, skipping" %
elt.tag)
- return xdata
+ if decrypted:
+ return xdata
+ else:
+ raise DecryptError("Failed to decrypt any data in %s" %
+ self.filename)
def _write(self, filename, data):
PropertiesCryptoMixin._write(self, filename, data)
@@ -507,11 +512,11 @@ class CLI(object):
Bcfg2.Options.PathOption(
"files", help="File(s) to encrypt or decrypt", nargs='+')]
- def __init__(self):
+ def __init__(self, argv=None):
parser = Bcfg2.Options.get_parser(
description="Encrypt and decrypt Bcfg2 data",
components=[self, _OptionContainer])
- parser.parse()
+ parser.parse(argv=argv)
self.logger = logging.getLogger(parser.prog)
if Bcfg2.Options.setup.decrypt:
@@ -560,16 +565,7 @@ class CLI(object):
if Bcfg2.Options.setup.remove:
self.logger.info("Cannot use --remove with Properties "
"file %s, ignoring for this file" % fname)
- try:
- tools = (PropertiesEncryptor(fname),
- PropertiesDecryptor(fname))
- except PassphraseError:
- self.logger.error(str(sys.exc_info()[1]))
- continue
- except IOError:
- self.logger.error("Error reading %s, skipping: %s" %
- (fname, err))
- continue
+ tools = (PropertiesEncryptor, PropertiesDecryptor)
else:
ftype = "Cfg"
if Bcfg2.Options.setup.xpath:
@@ -580,8 +576,13 @@ class CLI(object):
self.logger.error("Cannot use interactive mode with "
"--cfg, ignoring --interactive")
Bcfg2.Options.setup.interactive = False
+ tools = (CfgEncryptor, CfgDecryptor)
+
+ data = None
+ mode = None
+ if Bcfg2.Options.setup.encrypt:
try:
- tools = (CfgEncryptor(fname), CfgDecryptor(fname))
+ tool = tools[0](fname)
except PassphraseError:
self.logger.error(str(sys.exc_info()[1]))
continue
@@ -589,40 +590,56 @@ class CLI(object):
self.logger.error("Error reading %s, skipping: %s" %
(fname, err))
continue
-
- data = None
- mode = None
- if Bcfg2.Options.setup.encrypt:
- tool = tools[0]
mode = "encrypt"
self.logger.debug("Encrypting %s file %s" % (ftype, fname))
elif Bcfg2.Options.setup.decrypt:
- tool = tools[1]
+ try:
+ tool = tools[1](fname)
+ except PassphraseError:
+ self.logger.error(str(sys.exc_info()[1]))
+ continue
+ except IOError:
+ self.logger.error("Error reading %s, skipping: %s" %
+ (fname, err))
+ continue
mode = "decrypt"
self.logger.debug("Decrypting %s file %s" % (ftype, fname))
else:
self.logger.info("Neither --encrypt nor --decrypt specified, "
"determining mode")
- tool = tools[1]
+ try:
+ tool = tools[1](fname)
+ except PassphraseError:
+ self.logger.error(str(sys.exc_info()[1]))
+ continue
+ except IOError:
+ self.logger.error("Error reading %s, skipping: %s" %
+ (fname, err))
+ continue
try:
self.logger.debug("Trying to decrypt %s file %s" % (ftype,
fname))
data = tool.decrypt()
mode = "decrypt"
self.logger.debug("Decrypted %s file %s" % (ftype, fname))
- except: # pylint: disable=W0702
- pass
- if data is False:
- data = None
+ except DecryptError:
self.logger.info("Failed to decrypt %s, trying encryption"
% fname)
- tool = tools[0]
+ try:
+ tool = tools[0](fname)
+ except PassphraseError:
+ self.logger.error(str(sys.exc_info()[1]))
+ continue
+ except IOError:
+ self.logger.error("Error reading %s, skipping: %s" %
+ (fname, err))
+ continue
mode = "encrypt"
self.logger.debug("Encrypting %s file %s" % (ftype, fname))
- if data is None:
+ try:
data = getattr(tool, mode)()
- if data in [False, None]:
+ except DecryptError:
self.logger.error("Failed to %s %s, skipping" % (mode, fname))
continue
if Bcfg2.Options.setup.stdout: