summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py
diff options
context:
space:
mode:
authorChris St. Pierre <chris.a.st.pierre@gmail.com>2013-01-03 13:40:24 -0600
committerChris St. Pierre <chris.a.st.pierre@gmail.com>2013-01-03 13:40:24 -0600
commit14406cc14a4d832fe83df5da27937051e41dd093 (patch)
tree1fb429513bc5483251412af8251aa24517bcbb68 /src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py
parent10326a34dd813b88c6c8816115e91977a93a1f10 (diff)
downloadbcfg2-14406cc14a4d832fe83df5da27937051e41dd093.tar.gz
bcfg2-14406cc14a4d832fe83df5da27937051e41dd093.tar.bz2
bcfg2-14406cc14a4d832fe83df5da27937051e41dd093.zip
Cfg: Added feature to provide generation of SSH keys, authorized_keys file
Diffstat (limited to 'src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py')
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py
new file mode 100644
index 000000000..824d01023
--- /dev/null
+++ b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgAuthorizedKeysGenerator.py
@@ -0,0 +1,101 @@
+""" The CfgAuthorizedKeysGenerator generates ``authorized_keys`` files
+based on an XML specification of which SSH keypairs should granted
+access. """
+
+import lxml.etree
+from Bcfg2.Server.Plugin import StructFile, PluginExecutionError
+from Bcfg2.Server.Plugins.Cfg import CfgGenerator, SETUP, CFG
+from Bcfg2.Server.Plugins.Metadata import ClientMetadata
+
+
+class CfgAuthorizedKeysGenerator(CfgGenerator, StructFile):
+ """ The CfgAuthorizedKeysGenerator generates authorized_keys files
+ based on an XML specification of which SSH keypairs should granted
+ access. """
+
+ #: Different configurations for different clients/groups can be
+ #: handled with Client and Group tags within authorizedkeys.xml
+ __specific__ = False
+
+ #: Handle authorized keys XML files
+ __basenames__ = ['authorizedkeys.xml', 'authorized_keys.xml']
+
+ #: This handler is experimental, in part because it depends upon
+ #: the (experimental) CfgPrivateKeyCreator handler
+ experimental = True
+
+ def __init__(self, fname):
+ CfgGenerator.__init__(self, fname, None, None)
+ StructFile.__init__(self, fname)
+ self.cache = dict()
+ self.core = CFG.core
+ __init__.__doc__ = CfgGenerator.__init__.__doc__
+
+ @property
+ def category(self):
+ """ The name of the metadata category that generated keys are
+ specific to """
+ if (SETUP.cfp.has_section("sshkeys") and
+ SETUP.cfp.has_option("sshkeys", "category")):
+ return SETUP.cfp.get("sshkeys", "category")
+ return None
+
+ def handle_event(self, event):
+ CfgGenerator.handle_event(self, event)
+ StructFile.HandleEvent(self, event)
+ self.cache = dict()
+ handle_event.__doc__ = CfgGenerator.handle_event.__doc__
+
+ def get_data(self, entry, metadata):
+ spec = self.XMLMatch(metadata)
+ rv = []
+ for allow in spec.findall("Allow"):
+ params = ''
+ if allow.find("Params") is not None:
+ params = ",".join("=".join(p)
+ for p in allow.find("Params").attrib.items())
+
+ pubkey_name = allow.get("from")
+ if pubkey_name:
+ host = allow.get("host")
+ group = allow.get("group")
+ if host:
+ key_md = self.core.build_metadata(host)
+ elif group:
+ key_md = ClientMetadata("dummy", group, [group], [],
+ set(), set(), dict(), None,
+ None, None, None)
+ elif (self.category and
+ not metadata.group_in_category(self.category)):
+ self.logger.warning("Cfg: %s ignoring Allow from %s: "
+ "No group in category %s" %
+ (metadata.hostname, pubkey_name,
+ self.category))
+ continue
+ else:
+ key_md = metadata
+
+ key_entry = lxml.etree.Element("Path", name=pubkey_name)
+ try:
+ self.core.Bind(key_entry, key_md)
+ except PluginExecutionError:
+ self.logger.info("Cfg: %s skipping Allow from %s: "
+ "No key found" % (metadata.hostname,
+ pubkey_name))
+ continue
+ if not key_entry.text:
+ self.logger.warning("Cfg: %s skipping Allow from %s: "
+ "Empty public key" %
+ (metadata.hostname, pubkey_name))
+ continue
+ pubkey = key_entry.text
+ elif allow.text:
+ pubkey = allow.text.strip()
+ else:
+ self.logger.warning("Cfg: %s ignoring empty Allow tag: %s" %
+ (metadata.hostname,
+ lxml.etree.tostring(allow)))
+ continue
+ rv.append(" ".join([params, pubkey]).strip())
+ return "\n".join(rv)
+ get_data.__doc__ = CfgGenerator.get_data.__doc__