summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-01-17 08:01:44 -0500
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-01-17 09:27:07 -0500
commit72a80f89361145f1560ccc248f357a9de82eded6 (patch)
treee6827a6ec1e219c3d1a7f40a185aba67e6af738b /src
parentebe7542db7217c2fac3d7111e80f94caedfb69e2 (diff)
downloadbcfg2-72a80f89361145f1560ccc248f357a9de82eded6.tar.gz
bcfg2-72a80f89361145f1560ccc248f357a9de82eded6.tar.bz2
bcfg2-72a80f89361145f1560ccc248f357a9de82eded6.zip
abstracted encryption support from Properties/CfgPrivateKeyCreator to StructFile
Diffstat (limited to 'src')
-rw-r--r--src/lib/Bcfg2/Server/Plugin/helpers.py64
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py43
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgPublicKeyCreator.py3
-rw-r--r--src/lib/Bcfg2/Server/Plugins/FileProbes.py13
-rw-r--r--src/lib/Bcfg2/Server/Plugins/NagiosGen.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py2
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Properties.py43
-rw-r--r--src/lib/Bcfg2/Server/Plugins/SSLCA.py1
8 files changed, 81 insertions, 92 deletions
diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py
index 7b22d52ca..879c68b85 100644
--- a/src/lib/Bcfg2/Server/Plugin/helpers.py
+++ b/src/lib/Bcfg2/Server/Plugin/helpers.py
@@ -18,6 +18,12 @@ from Bcfg2.Server.Plugin.exceptions import SpecificityError, \
PluginExecutionError
try:
+ import Bcfg2.Encryption
+ HAS_CRYPTO = True
+except ImportError:
+ HAS_CRYPTO = False
+
+try:
import django # pylint: disable=W0611
HAS_DJANGO = True
except ImportError:
@@ -571,13 +577,69 @@ class XMLFileBacked(FileBacked):
class StructFile(XMLFileBacked):
""" StructFiles are XML files that contain a set of structure file
formatting logic for handling ``<Group>`` and ``<Client>``
- tags. """
+ tags.
+
+ .. -----
+ .. autoattribute:: __identifier__
+ """
#: If ``__identifier__`` is not None, then it must be the name of
#: an XML attribute that will be required on the top-level tag of
#: the file being cached
__identifier__ = None
+ #: Whether or not encryption support is enabled in this file
+ encryption = True
+
+ def __init__(self, filename, fam=None, should_monitor=False):
+ XMLFileBacked.__init__(self, filename, fam=fam,
+ should_monitor=should_monitor)
+ self.setup = Bcfg2.Options.get_option_parser()
+
+ def Index(self):
+ Bcfg2.Server.Plugin.XMLFileBacked.Index(self)
+ if self.encryption:
+ strict = self.xdata.get(
+ "decrypt",
+ self.setup.cfp.get(Bcfg2.Encryption.CFG_SECTION, "decrypt",
+ default="strict")) == "strict"
+ for el in self.xdata.xpath("//*[@encrypted]"):
+ if not HAS_CRYPTO:
+ raise PluginExecutionError("Properties: M2Crypto is not "
+ "available: %s" % self.name)
+ try:
+ el.text = self._decrypt(el).encode('ascii',
+ 'xmlcharrefreplace')
+ except UnicodeDecodeError:
+ LOGGER.info("%s: Decrypted %s to gibberish, skipping" %
+ (self.name, el.tag))
+ except Bcfg2.Encryption.EVPError:
+ msg = "Failed to decrypt %s element in %s" % (el.tag,
+ self.name)
+ if strict:
+ raise PluginExecutionError(msg)
+ else:
+ LOGGER.warning(msg)
+ Index.__doc__ = XMLFileBacked.Index.__doc__
+
+ def _decrypt(self, element):
+ """ Decrypt a single encrypted properties file element """
+ if not element.text or not element.text.strip():
+ return
+ passes = Bcfg2.Encryption.get_passphrases()
+ try:
+ passphrase = passes[element.get("encrypted")]
+ try:
+ return Bcfg2.Encryption.ssl_decrypt(element.text, passphrase)
+ except Bcfg2.Encryption.EVPError:
+ # error is raised below
+ pass
+ except KeyError:
+ # bruteforce_decrypt raises an EVPError with a sensible
+ # error message, so we just let it propagate up the stack
+ return Bcfg2.Encryption.bruteforce_decrypt(element.text)
+ raise Bcfg2.Encryption.EVPError("Failed to decrypt")
+
def _include_element(self, item, metadata):
""" determine if an XML element matches the metadata """
if isinstance(item, lxml.etree._Comment): # pylint: disable=W0212
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py
index 54fa75b41..4d6639e4d 100644
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py
+++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPrivateKeyCreator.py
@@ -5,7 +5,7 @@ import shutil
import tempfile
import subprocess
from Bcfg2.Options import get_option_parser
-from Bcfg2.Server.Plugin import PluginExecutionError, StructFile
+from Bcfg2.Server.Plugin import StructFile
from Bcfg2.Server.Plugins.Cfg import CfgCreator, CfgCreationError
from Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator import CfgPublicKeyCreator
try:
@@ -211,44 +211,3 @@ class CfgPrivateKeyCreator(CfgCreator, StructFile):
finally:
shutil.rmtree(os.path.dirname(filename))
# pylint: enable=W0221
-
- def Index(self):
- StructFile.Index(self)
- if HAS_CRYPTO:
- strict = self.xdata.get(
- "decrypt",
- SETUP.cfp.get(Bcfg2.Encryption.CFG_SECTION, "decrypt",
- default="strict")) == "strict"
- for el in self.xdata.xpath("//*[@encrypted]"):
- try:
- el.text = self._decrypt(el).encode('ascii',
- 'xmlcharrefreplace')
- except UnicodeDecodeError:
- self.logger.info("Cfg: Decrypted %s to gibberish, skipping"
- % el.tag)
- except Bcfg2.Encryption.EVPError:
- msg = "Cfg: Failed to decrypt %s element in %s" % \
- (el.tag, self.name)
- if strict:
- raise PluginExecutionError(msg)
- else:
- self.logger.warning(msg)
- Index.__doc__ = StructFile.Index.__doc__
-
- def _decrypt(self, element):
- """ Decrypt a single encrypted element """
- if not element.text or not element.text.strip():
- return
- passes = Bcfg2.Encryption.get_passphrases()
- try:
- passphrase = passes[element.get("encrypted")]
- try:
- return Bcfg2.Encryption.ssl_decrypt(element.text, passphrase)
- except Bcfg2.Encryption.EVPError:
- # error is raised below
- pass
- except KeyError:
- # bruteforce_decrypt raises an EVPError with a sensible
- # error message, so we just let it propagate up the stack
- return Bcfg2.Encryption.bruteforce_decrypt(element.text)
- raise Bcfg2.Encryption.EVPError("Failed to decrypt")
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPublicKeyCreator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPublicKeyCreator.py
index 6be438462..4c61e338e 100644
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPublicKeyCreator.py
+++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgPublicKeyCreator.py
@@ -23,6 +23,9 @@ class CfgPublicKeyCreator(CfgCreator, StructFile):
#: Handle XML specifications of private keys
__basenames__ = ['pubkey.xml']
+ #: No text content on any tags, so encryption support disabled
+ encryption = False
+
def __init__(self, fname):
CfgCreator.__init__(self, fname)
StructFile.__init__(self, fname)
diff --git a/src/lib/Bcfg2/Server/Plugins/FileProbes.py b/src/lib/Bcfg2/Server/Plugins/FileProbes.py
index 5ec0d7280..365549e85 100644
--- a/src/lib/Bcfg2/Server/Plugins/FileProbes.py
+++ b/src/lib/Bcfg2/Server/Plugins/FileProbes.py
@@ -51,6 +51,11 @@ print(Bcfg2.Client.XML.tostring(data, xml_declaration=False).decode('UTF-8'))
"""
+class FileProbesConfig(Bcfg2.Server.Plugin.StructFile):
+ """ Config file for FileProbes """
+ encryption = False
+
+
class FileProbes(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Probing):
""" This module allows you to probe a client for a file, which is then
@@ -63,11 +68,9 @@ class FileProbes(Bcfg2.Server.Plugin.Plugin,
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Probing.__init__(self)
- self.config = \
- Bcfg2.Server.Plugin.StructFile(os.path.join(self.data,
- 'config.xml'),
- fam=core.fam,
- should_monitor=True)
+ self.config = FileProbesConfig(os.path.join(self.data, 'config.xml'),
+ fam=core.fam,
+ should_monitor=True)
self.entries = dict()
self.probes = dict()
diff --git a/src/lib/Bcfg2/Server/Plugins/NagiosGen.py b/src/lib/Bcfg2/Server/Plugins/NagiosGen.py
index c39bd4c42..baea5fe23 100644
--- a/src/lib/Bcfg2/Server/Plugins/NagiosGen.py
+++ b/src/lib/Bcfg2/Server/Plugins/NagiosGen.py
@@ -15,12 +15,14 @@ LOGGER = logging.getLogger(__name__)
class NagiosGenConfig(Bcfg2.Server.Plugin.StructFile):
""" NagiosGen config file handler """
+ encryption = False
+
def __init__(self, filename, fam):
# create config.xml if missing
if not os.path.exists(filename):
LOGGER.warning("NagiosGen: %s missing. "
"Creating empty one for you." % filename)
- open(filename, "w").write("<NagiosGen></NagiosGen>")
+ open(filename, "w").write("<NagiosGen/>")
Bcfg2.Server.Plugin.StructFile.__init__(self, filename, fam=fam,
should_monitor=True)
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py
index 2735e389a..afa5da4c5 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py
@@ -17,6 +17,8 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile,
__identifier__ = None
+ encryption = False
+
def __init__(self, filename, cachepath, fam, packages, setup):
"""
:param filename: The full path to ``sources.xml``
diff --git a/src/lib/Bcfg2/Server/Plugins/Properties.py b/src/lib/Bcfg2/Server/Plugins/Properties.py
index c5b5ea2d1..24daa2107 100644
--- a/src/lib/Bcfg2/Server/Plugins/Properties.py
+++ b/src/lib/Bcfg2/Server/Plugins/Properties.py
@@ -203,49 +203,6 @@ class XMLPropertyFile(Bcfg2.Server.Plugin.StructFile, PropertyFile):
return True
validate_data.__doc__ = PropertyFile.validate_data.__doc__
- def Index(self):
- Bcfg2.Server.Plugin.StructFile.Index(self)
- strict = self.xdata.get(
- "decrypt",
- SETUP.cfp.get(Bcfg2.Encryption.CFG_SECTION, "decrypt",
- default="strict")) == "strict"
- for el in self.xdata.xpath("//*[@encrypted]"):
- if not HAS_CRYPTO:
- raise PluginExecutionError("Properties: M2Crypto is not "
- "available: %s" % self.name)
- try:
- el.text = self._decrypt(el).encode('ascii',
- 'xmlcharrefreplace')
- except UnicodeDecodeError:
- LOGGER.info("Properties: Decrypted %s to gibberish, "
- "skipping" % el.tag)
- except Bcfg2.Encryption.EVPError:
- msg = "Properties: Failed to decrypt %s element in %s" % \
- (el.tag, self.name)
- if strict:
- raise PluginExecutionError(msg)
- else:
- LOGGER.warning(msg)
- Index.__doc__ = Bcfg2.Server.Plugin.StructFile.Index.__doc__
-
- def _decrypt(self, element):
- """ Decrypt a single encrypted properties file element """
- if not element.text or not element.text.strip():
- return
- passes = Bcfg2.Encryption.get_passphrases()
- try:
- passphrase = passes[element.get("encrypted")]
- try:
- return Bcfg2.Encryption.ssl_decrypt(element.text, passphrase)
- except Bcfg2.Encryption.EVPError:
- # error is raised below
- pass
- except KeyError:
- # bruteforce_decrypt raises an EVPError with a sensible
- # error message, so we just let it propagate up the stack
- return Bcfg2.Encryption.bruteforce_decrypt(element.text)
- raise Bcfg2.Encryption.EVPError("Failed to decrypt")
-
def get_additional_data(self, metadata):
if self.setup.cfp.getboolean("properties", "automatch", default=False):
default_automatch = "true"
diff --git a/src/lib/Bcfg2/Server/Plugins/SSLCA.py b/src/lib/Bcfg2/Server/Plugins/SSLCA.py
index 0d51adf18..cc1a2ceac 100644
--- a/src/lib/Bcfg2/Server/Plugins/SSLCA.py
+++ b/src/lib/Bcfg2/Server/Plugins/SSLCA.py
@@ -17,6 +17,7 @@ LOGGER = logging.getLogger(__name__)
class SSLCAXMLSpec(Bcfg2.Server.Plugin.StructFile):
""" Base class to handle key.xml and cert.xml """
+ encryption = False
attrs = dict()
tag = None