summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-12-08 21:21:50 -0500
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-12-09 07:17:30 -0500
commit9a4bc278b4cebf7dfe292951204e760ef70b828e (patch)
tree50088552c44b0f9cc89cbc25a0df29879fa765d1 /src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
parent91558c72f6905991c7fb3f24057ab9e41ecce434 (diff)
downloadbcfg2-9a4bc278b4cebf7dfe292951204e760ef70b828e.tar.gz
bcfg2-9a4bc278b4cebf7dfe292951204e760ef70b828e.tar.bz2
bcfg2-9a4bc278b4cebf7dfe292951204e760ef70b828e.zip
bcfg2-lint: New TemplateAbuse plugin detects templated scripts
TemplateAbuse detects templated scripts (either files that end with a known extension, or that start with a shebang line) and executables (based off of their permissions in info.xml) and warns about them, since templating scripts is dicey at best, and almost always better done by templating a config file for the script to read instead.
Diffstat (limited to 'src/lib/Bcfg2/Server/Lint/TemplateAbuse.py')
-rw-r--r--src/lib/Bcfg2/Server/Lint/TemplateAbuse.py75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
new file mode 100644
index 000000000..fca9d14a9
--- /dev/null
+++ b/src/lib/Bcfg2/Server/Lint/TemplateAbuse.py
@@ -0,0 +1,75 @@
+""" Check for templated scripts or executables. """
+
+import os
+import stat
+import Bcfg2.Server.Lint
+from Bcfg2.Compat import any # pylint: disable=W0622
+from Bcfg2.Server.Plugin import DEFAULT_FILE_METADATA
+from Bcfg2.Server.Plugins.Cfg.CfgInfoXML import CfgInfoXML
+from Bcfg2.Server.Plugins.Cfg.CfgGenshiGenerator import CfgGenshiGenerator
+from Bcfg2.Server.Plugins.Cfg.CfgCheetahGenerator import CfgCheetahGenerator
+from Bcfg2.Server.Plugins.Cfg.CfgEncryptedGenshiGenerator import \
+ CfgEncryptedGenshiGenerator
+from Bcfg2.Server.Plugins.Cfg.CfgEncryptedCheetahGenerator import \
+ CfgEncryptedCheetahGenerator
+
+
+class TemplateAbuse(Bcfg2.Server.Lint.ServerPlugin):
+ """ Check for templated scripts or executables. """
+ templates = [CfgGenshiGenerator, CfgCheetahGenerator,
+ CfgEncryptedGenshiGenerator, CfgEncryptedCheetahGenerator]
+ extensions = [".pl", ".py", ".sh", ".rb"]
+
+ def Run(self):
+ if 'Cfg' in self.core.plugins:
+ for entryset in self.core.plugins['Cfg'].entries.values():
+ for entry in entryset.entries.values():
+ if (self.HandlesFile(entry.name) and
+ any(isinstance(entry, t) for t in self.templates)):
+ self.check_template(entryset, entry)
+
+ @classmethod
+ def Errors(cls):
+ return {"templated-script": "warning",
+ "templated-executable": "warning"}
+
+ def check_template(self, entryset, entry):
+ """ Check a template to see if it's a script or an executable. """
+ # first, check for a known script extension
+ ext = os.path.splitext(entryset.path)[1]
+ if ext in self.extensions:
+ self.LintError("templated-script",
+ "Templated script found: %s\n"
+ "File has a known script extension: %s\n"
+ "Template a config file for the script instead" %
+ (entry.name, ext))
+ return
+
+ # next, check for a shebang line
+ firstline = open(entry.name).readline()
+ if firstline.startswith("#!"):
+ self.LintError("templated-script",
+ "Templated script found: %s\n"
+ "File starts with a shebang: %s\n"
+ "Template a config file for the script instead" %
+ (entry.name, firstline))
+ return
+
+ # finally, check for executable permissions in info.xml
+ for entry in entryset.entries.values():
+ if isinstance(entry, CfgInfoXML):
+ for pinfo in entry.infoxml.pnode.data.xpath("//FileInfo"):
+ try:
+ mode = int(pinfo.get("mode",
+ DEFAULT_FILE_METADATA['mode']), 8)
+ except ValueError:
+ # LintError will be produced by RequiredAttrs plugin
+ self.logger.warning("Non-octal mode: %s" % mode)
+ continue
+ if mode & stat.S_IXUSR != 0:
+ self.LintError(
+ "templated-executable",
+ "Templated executable found: %s\n"
+ "Template a config file for the executable instead"
+ % entry.name)
+ return