Source code for Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator

""" The CfgPublicKeyCreator invokes
:class:`Bcfg2.Server.Plugins.Cfg.CfgPrivateKeyCreator.CfgPrivateKeyCreator`
to create SSH keys on the fly. """

import os
import sys
import tempfile
import lxml.etree
from Bcfg2.Utils import Executor
from Bcfg2.Server.Plugin import StructFile, PluginExecutionError
from Bcfg2.Server.Plugins.Cfg import CfgCreator, CfgCreationError, get_cfg


[docs]class CfgPublicKeyCreator(CfgCreator, StructFile): """ .. currentmodule:: Bcfg2.Server.Plugins.Cfg The CfgPublicKeyCreator creates SSH public keys on the fly. It is invoked by :class:`CfgPrivateKeyCreator.CfgPrivateKeyCreator` to handle the creation of the public key, and can also call :class:`CfgPrivateKeyCreator.CfgPrivateKeyCreator` to trigger the creation of a keypair when a public key is created. """ #: Different configurations for different clients/groups can be #: handled with Client and Group tags within pubkey.xml __specific__ = False #: 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) self.cfg = get_cfg() self.core = self.cfg.core self.cmd = Executor()
[docs] def create_data(self, entry, metadata): if entry.get("name").endswith(".pub"): privkey = entry.get("name")[:-4] else: raise CfgCreationError("Cfg: Could not determine private key for " "%s: Filename does not end in .pub" % entry.get("name")) privkey_entry = lxml.etree.Element("Path", name=privkey) try: self.core.Bind(privkey_entry, metadata) except PluginExecutionError: raise CfgCreationError("Cfg: Could not bind %s (private key for " "%s): %s" % (privkey, self.name, sys.exc_info()[1])) try: eset = self.cfg.entries[privkey] creator = eset.best_matching(metadata, eset.get_handlers(metadata, CfgCreator)) except KeyError: raise CfgCreationError("Cfg: No private key defined for %s (%s)" % (self.name, privkey)) except PluginExecutionError: raise CfgCreationError("Cfg: No privkey.xml defined for %s " "(private key for %s)" % (privkey, self.name)) specificity = creator.get_specificity(metadata) fname = self.get_filename(**specificity) # if the private key didn't exist, then creating it may have # created the private key, too. check for it first. if os.path.exists(fname): return open(fname).read() else: # generate public key from private key fd, privfile = tempfile.mkstemp() try: os.fdopen(fd, 'w').write(privkey_entry.text) cmd = ["ssh-keygen", "-y", "-f", privfile] self.debug_log("Cfg: Extracting SSH public key from %s: %s" % (privkey, " ".join(cmd))) result = self.cmd.run(cmd) if not result.success: raise CfgCreationError("Cfg: Failed to extract public key " "from %s: %s" % (privkey, result.error)) self.write_data(result.stdout, **specificity) return result.stdout finally: os.unlink(privfile)
[docs] def handle_event(self, event): CfgCreator.handle_event(self, event) StructFile.HandleEvent(self, event)
handle_event.__doc__ = CfgCreator.handle_event.__doc__