From 8c010cb5f810c015291099aaeaee6de86ed84ff1 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 16:43:24 -0500 Subject: use certmaster.requester.request_cert instead of utils.create_minion_certs --- func/minion/server.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'func') diff --git a/func/minion/server.py b/func/minion/server.py index 2fa175a..531ac7a 100755 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -28,7 +28,6 @@ from func.commonconfig import FuncdConfig from func import logger from func import certs import func.jobthing as jobthing -import utils # our modules import AuthedXMLRPCServer @@ -36,6 +35,8 @@ import codes import module_loader import func.utils as futils +from certmaster import utils +from certmaster import requester class XmlRpcInterface(object): @@ -271,7 +272,7 @@ def main(argv): print "serving...\n" try: - utils.create_minion_keys() + requester.request_cert() serve() except codes.FuncException, e: print >> sys.stderr, 'error: %s' % e -- cgit From c3584eb2b777402a54790e276922af7076e629ef Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 16:43:47 -0500 Subject: these functions are in certmaster.utils now --- func/minion/utils.py | 72 ---------------------------------------------------- 1 file changed, 72 deletions(-) (limited to 'func') diff --git a/func/minion/utils.py b/func/minion/utils.py index ea8854c..1133866 100755 --- a/func/minion/utils.py +++ b/func/minion/utils.py @@ -65,78 +65,6 @@ def get_hostname(): -def create_minion_keys(): - config_file = '/etc/func/minion.conf' - config = read_config(config_file, FuncdConfig) - cert_dir = config.cert_dir - master_uri = 'http://%s:51235/' % config.certmaster - hn = get_hostname() - - if hn is None: - raise codes.FuncException("Could not determine a hostname other than localhost") - - key_file = '%s/%s.pem' % (cert_dir, hn) - csr_file = '%s/%s.csr' % (cert_dir, hn) - cert_file = '%s/%s.cert' % (cert_dir, hn) - ca_cert_file = '%s/ca.cert' % cert_dir - - - if os.path.exists(cert_file) and os.path.exists(ca_cert_file): - return - - keypair = None - try: - if not os.path.exists(cert_dir): - os.makedirs(cert_dir) - if not os.path.exists(key_file): - keypair = certs.make_keypair(dest=key_file) - if not os.path.exists(csr_file): - if not keypair: - keypair = certs.retrieve_key_from_file(key_file) - csr = certs.make_csr(keypair, dest=csr_file) - except Exception, e: - traceback.print_exc() - raise codes.FuncException, "Could not create local keypair or csr for minion funcd session" - - result = False - log = logger.Logger().logger - while not result: - try: - log.debug("submitting CSR to certmaster %s" % master_uri) - result, cert_string, ca_cert_string = submit_csr_to_master(csr_file, master_uri) - except socket.gaierror, e: - raise codes.FuncException, "Could not locate certmaster at %s" % master_uri - - # logging here would be nice - if not result: - log.warning("no response from certmaster %s, sleeping 10 seconds" % master_uri) - time.sleep(10) - - - if result: - log.debug("received certificate from certmaster %s, storing" % master_uri) - cert_fd = os.open(cert_file, os.O_RDWR|os.O_CREAT, 0644) - os.write(cert_fd, cert_string) - os.close(cert_fd) - - ca_cert_fd = os.open(ca_cert_file, os.O_RDWR|os.O_CREAT, 0644) - os.write(ca_cert_fd, ca_cert_string) - os.close(ca_cert_fd) - -def submit_csr_to_master(csr_file, master_uri): - """" - gets us our cert back from the certmaster.wait_for_cert() method - takes csr_file as path location and master_uri - returns Bool, str(cert), str(ca_cert) - """ - - fo = open(csr_file) - csr = fo.read() - s = xmlrpclib.ServerProxy(master_uri) - - return s.wait_for_cert(csr) - - # this is kind of handy, so keep it around for now # but we really need to fix out server side logging and error # reporting so we don't need it -- cgit From 0f8dec9ab2659fc5e8ddf83cafd45725b73fd697 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 16:46:47 -0500 Subject: more func/certmaster cert path changes --- func/commonconfig.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'func') diff --git a/func/commonconfig.py b/func/commonconfig.py index 292eb45..d282ab6 100644 --- a/func/commonconfig.py +++ b/func/commonconfig.py @@ -2,7 +2,7 @@ from config import BaseConfig, BoolOption, Option class CMConfig(BaseConfig): listen_addr = Option('') - cadir = Option('/etc/pki/func/ca') + cadir = Option('/etc/pki/certmaster/ca') certroot = Option('/var/lib/certmaster/certmaster/certs') csrroot = Option('/var/lib/certmaster/certmaster/csrs') autosign = BoolOption(False) @@ -11,5 +11,5 @@ class CMConfig(BaseConfig): class FuncdConfig(BaseConfig): log_level = Option('INFO') certmaster = Option('certmaster') - cert_dir = Option('/etc/pki/func') + cert_dir = Option('/etc/pki/certmaster') acl_dir = Option('/etc/func/minion-acl.d') -- cgit From 30fb32a3ab011c2132ac6732c4044174ce0c25d9 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 16:59:08 -0500 Subject: resolve some utils namespace issue probably should just combine these --- func/minion/server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'func') diff --git a/func/minion/server.py b/func/minion/server.py index 531ac7a..8097842 100755 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -34,6 +34,7 @@ import AuthedXMLRPCServer import codes import module_loader import func.utils as futils +import func.minion.utils as fmutils from certmaster import utils from certmaster import requester @@ -235,7 +236,7 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, return peer_cert.get_subject().CN def _check_acl(self, cert, ip, method, params): - acls = utils.get_acls_from_config(acldir=self.config.acl_dir) + acls = fmutils.get_acls_from_config(acldir=self.config.acl_dir) # certmaster always gets to run things ca_cn = self._our_ca.get_subject().CN -- cgit From 903cf2e90885bed9f5715e2241b99b335c374250 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 16:59:34 -0500 Subject: fix up some paths. Note: these paths probably shouldn't be as hardcoded as they are now... --- func/overlord/client.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'func') diff --git a/func/overlord/client.py b/func/overlord/client.py index fdcf875..25924b2 100755 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -189,13 +189,15 @@ class Client(object): # certmaster key, cert, ca # funcd key, cert, ca # raise FuncClientError - ol_key = '%s/funcmaster.key' % self.config.cadir - ol_crt = '%s/funcmaster.crt' % self.config.cadir + ol_key = '%s/certmaster.key' % self.config.cadir + ol_crt = '%s/certmaster.crt' % self.config.cadir myname = utils.get_hostname() + + # FIXME: should be config -akl? # maybe /etc/pki/func is a variable somewhere? - fd_key = '/etc/pki/func/%s.pem' % myname - fd_crt = '/etc/pki/func/%s.cert' % myname - self.ca = '%s/funcmaster.crt' % self.config.cadir + fd_key = '/etc/pki/certmaster/%s.pem' % myname + fd_crt = '/etc/pki/certmaster/%s.cert' % myname + self.ca = '%s/certmaster.crt' % self.config.cadir if client_key and client_cert and ca: if (os.access(client_key, os.R_OK) and os.access(client_cert, os.R_OK) and os.access(ca, os.R_OK)): -- cgit From 3903c1725386f3facaa9166aa8f658a433e8b791 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 17:28:09 -0500 Subject: CMConfig is located in certmater.commonconfig now --- func/commonconfig.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'func') diff --git a/func/commonconfig.py b/func/commonconfig.py index d282ab6..66f4cfc 100644 --- a/func/commonconfig.py +++ b/func/commonconfig.py @@ -1,15 +1,22 @@ -from config import BaseConfig, BoolOption, Option +#!/usr/bin/python +""" +func + +Copyright 2007, Red Hat, Inc +see AUTHORS + +This software may be freely redistributed under the terms of the GNU +general public license. -class CMConfig(BaseConfig): - listen_addr = Option('') - cadir = Option('/etc/pki/certmaster/ca') - certroot = Option('/var/lib/certmaster/certmaster/certs') - csrroot = Option('/var/lib/certmaster/certmaster/csrs') - autosign = BoolOption(False) +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +""" + + +from config import BaseConfig, BoolOption, Option class FuncdConfig(BaseConfig): log_level = Option('INFO') - certmaster = Option('certmaster') - cert_dir = Option('/etc/pki/certmaster') acl_dir = Option('/etc/func/minion-acl.d') -- cgit From c6badc5c42b27c8e7042bb099049493a10c8f012 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 17:28:45 -0500 Subject: use both func and certmasters configs --- func/minion/server.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'func') diff --git a/func/minion/server.py b/func/minion/server.py index 8097842..0d73453 100755 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -25,6 +25,7 @@ I18N_DOMAIN = "func" from func.config import read_config from func.commonconfig import FuncdConfig +from certmaster.commonconfig import CMConfig from func import logger from func import certs import func.jobthing as jobthing @@ -48,8 +49,12 @@ class XmlRpcInterface(object): Constructor. """ - config_file = '/etc/func/minion.conf' + cm_config_file = '/etc/certmaster/minion.conf' + print CMConfig + self.cm_config = read_config(cm_config_file, CMConfig) + config_file = "/etc/func/minion.conf" self.config = read_config(config_file, FuncdConfig) + self.logger = logger.Logger().logger self.audit_logger = logger.AuditLogger() self.__setup_handlers() @@ -174,9 +179,9 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, XmlRpcInterface.__init__(self) hn = utils.get_hostname() - self.key = "%s/%s.pem" % (self.config.cert_dir, hn) - self.cert = "%s/%s.cert" % (self.config.cert_dir, hn) - self.ca = "%s/ca.cert" % self.config.cert_dir + self.key = "%s/%s.pem" % (self.cm_config.cert_dir, hn) + self.cert = "%s/%s.cert" % (self.cm_config.cert_dir, hn) + self.ca = "%s/ca.cert" % self.cm_config.cert_dir self._our_ca = certs.retrieve_cert_from_file(self.ca) -- cgit From 6f95e9f2fe5ea8494d0999227926ce2bd7655c24 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 17:29:29 -0500 Subject: use certmaster.commonconfig.CMConfig here instead of the one that used to be in func --- func/overlord/client.py | 2 +- func/overlord/command.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'func') diff --git a/func/overlord/client.py b/func/overlord/client.py index 25924b2..26b1cca 100755 --- a/func/overlord/client.py +++ b/func/overlord/client.py @@ -17,7 +17,7 @@ import sys import glob import os -from func.commonconfig import CMConfig +from certmaster.commonconfig import CMConfig from func.config import read_config, CONFIG_FILE import sslclient diff --git a/func/overlord/command.py b/func/overlord/command.py index 7fb7de4..7cf3623 100644 --- a/func/overlord/command.py +++ b/func/overlord/command.py @@ -15,7 +15,7 @@ import optparse import sys from func.config import read_config, CONFIG_FILE -from func.commonconfig import CMConfig +from certmaster.commonconfig import CMConfig class CommandHelpFormatter(optparse.IndentedHelpFormatter): """ -- cgit From 2c20b2ec4d56b40cf4585cac5852df1d5bcd7862 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 17:31:40 -0500 Subject: remove debug spew --- func/minion/server.py | 1 - 1 file changed, 1 deletion(-) (limited to 'func') diff --git a/func/minion/server.py b/func/minion/server.py index 0d73453..c511598 100755 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -50,7 +50,6 @@ class XmlRpcInterface(object): """ cm_config_file = '/etc/certmaster/minion.conf' - print CMConfig self.cm_config = read_config(cm_config_file, CMConfig) config_file = "/etc/func/minion.conf" self.config = read_config(config_file, FuncdConfig) -- cgit From 85194111b1a959fcb939dbe0e7b9e21aff2b075c Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 17:32:26 -0500 Subject: dont need this anymore --- func/certmaster.py | 247 ----------------------------------------------------- 1 file changed, 247 deletions(-) delete mode 100755 func/certmaster.py (limited to 'func') diff --git a/func/certmaster.py b/func/certmaster.py deleted file mode 100755 index fe5dcbc..0000000 --- a/func/certmaster.py +++ /dev/null @@ -1,247 +0,0 @@ -# FIXME: more intelligent fault raises - -""" -cert master listener - -Copyright 2007, Red Hat, Inc -see AUTHORS - -This software may be freely redistributed under the terms of the GNU -general public license. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -""" - -# standard modules -import SimpleXMLRPCServer -import sys -import os -import os.path -from OpenSSL import crypto -import sha -import glob -import socket -import exceptions - -#from func.server import codes -import certs -import codes -import utils -from config import read_config -from commonconfig import CMConfig - -CERTMASTER_LISTEN_PORT = 51235 -CERTMASTER_CONFIG = "/etc/func/certmaster.conf" - -class CertMaster(object): - def __init__(self, conf_file=CERTMASTER_CONFIG): - self.cfg = read_config(conf_file, CMConfig) - - usename = utils.get_hostname() - - mycn = '%s-CA-KEY' % usename - self.ca_key_file = '%s/funcmaster.key' % self.cfg.cadir - self.ca_cert_file = '%s/funcmaster.crt' % self.cfg.cadir - try: - if not os.path.exists(self.cfg.cadir): - os.makedirs(self.cfg.cadir) - if not os.path.exists(self.ca_key_file) and not os.path.exists(self.ca_cert_file): - certs.create_ca(CN=mycn, ca_key_file=self.ca_key_file, ca_cert_file=self.ca_cert_file) - except (IOError, OSError), e: - print 'Cannot make certmaster certificate authority keys/certs, aborting: %s' % e - sys.exit(1) - - - # open up the cakey and cacert so we have them available - self.cakey = certs.retrieve_key_from_file(self.ca_key_file) - self.cacert = certs.retrieve_cert_from_file(self.ca_cert_file) - - for dirpath in [self.cfg.cadir, self.cfg.certroot, self.cfg.csrroot]: - if not os.path.exists(dirpath): - os.makedirs(dirpath) - - # setup handlers - self.handlers = { - 'wait_for_cert': self.wait_for_cert, - } - - def _dispatch(self, method, params): - if method == 'trait_names' or method == '_getAttributeNames': - return self.handlers.keys() - - if method in self.handlers.keys(): - return self.handlers[method](*params) - else: - raise codes.InvalidMethodException - - def _sanitize_cn(self, commonname): - commonname = commonname.replace('/', '') - commonname = commonname.replace('\\', '') - return commonname - - def wait_for_cert(self, csrbuf): - """ - takes csr as a string - returns True, caller_cert, ca_cert - returns False, '', '' - """ - - try: - csrreq = crypto.load_certificate_request(crypto.FILETYPE_PEM, csrbuf) - except crypto.Error, e: - #XXX need to raise a fault here and document it - but false is just as good - return False, '', '' - - requesting_host = self._sanitize_cn(csrreq.get_subject().CN) - - # get rid of dodgy characters in the filename we're about to make - - certfile = '%s/%s.cert' % (self.cfg.certroot, requesting_host) - csrfile = '%s/%s.csr' % (self.cfg.csrroot, requesting_host) - - # check for old csr on disk - # if we have it - compare the two - if they are not the same - raise a fault - if os.path.exists(csrfile): - oldfo = open(csrfile) - oldcsrbuf = oldfo.read() - oldsha = sha.new() - oldsha.update(oldcsrbuf) - olddig = oldsha.hexdigest() - newsha = sha.new() - newsha.update(csrbuf) - newdig = newsha.hexdigest() - if not newdig == olddig: - # XXX raise a proper fault - return False, '', '' - - # look for a cert: - # if we have it, then return True, etc, etc - if os.path.exists(certfile): - slavecert = certs.retrieve_cert_from_file(certfile) - cert_buf = crypto.dump_certificate(crypto.FILETYPE_PEM, slavecert) - cacert_buf = crypto.dump_certificate(crypto.FILETYPE_PEM, self.cacert) - return True, cert_buf, cacert_buf - - # if we don't have a cert then: - # if we're autosign then sign it, write out the cert and return True, etc, etc - # else write out the csr - - if self.cfg.autosign: - cert_fn = self.sign_this_csr(csrreq) - cert = certs.retrieve_cert_from_file(cert_fn) - cert_buf = crypto.dump_certificate(crypto.FILETYPE_PEM, cert) - cacert_buf = crypto.dump_certificate(crypto.FILETYPE_PEM, self.cacert) - return True, cert_buf, cacert_buf - - else: - # write the csr out to a file to be dealt with by the admin - destfo = open(csrfile, 'w') - destfo.write(crypto.dump_certificate_request(crypto.FILETYPE_PEM, csrreq)) - destfo.close() - del destfo - return False, '', '' - - return False, '', '' - - def get_csrs_waiting(self): - hosts = [] - csrglob = '%s/*.csr' % self.cfg.csrroot - csr_list = glob.glob(csrglob) - for f in csr_list: - hn = os.path.basename(f) - hn = hn[:-4] - hosts.append(hn) - return hosts - - def remove_this_cert(self, hn): - """ removes cert for hostname using unlink """ - cm = self - csrglob = '%s/%s.csr' % (cm.cfg.csrroot, hn) - csrs = glob.glob(csrglob) - certglob = '%s/%s.cert' % (cm.cfg.certroot, hn) - certs = glob.glob(certglob) - if not csrs and not certs: - # FIXME: should be an exception? - print 'No match for %s to clean up' % hn - return - for fn in csrs + certs: - print 'Cleaning out %s for host matching %s' % (fn, hn) - os.unlink(fn) - - def sign_this_csr(self, csr): - """returns the path to the signed cert file""" - csr_unlink_file = None - - if type(csr) is type(''): - if csr.startswith('/') and os.path.exists(csr): # we have a full path to the file - csrfo = open(csr) - csr_buf = csrfo.read() - csr_unlink_file = csr - - elif os.path.exists('%s/%s' % (self.cfg.csrroot, csr)): # we have a partial path? - csrfo = open('%s/%s' % (self.cfg.csrroot, csr)) - csr_buf = csrfo.read() - csr_unlink_file = '%s/%s' % (self.cfg.csrroot, csr) - - # we have a string of some kind - else: - csr_buf = csr - - try: - csrreq = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr_buf) - except crypto.Error, e: - raise exceptions.Exception("Bad CSR: %s" % csr) - - else: # assume we got a bare csr req - csrreq = csr - requesting_host = self._sanitize_cn(csrreq.get_subject().CN) - - certfile = '%s/%s.cert' % (self.cfg.certroot, requesting_host) - thiscert = certs.create_slave_certificate(csrreq, self.cakey, self.cacert, self.cfg.cadir) - destfo = open(certfile, 'w') - destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, thiscert)) - destfo.close() - del destfo - if csr_unlink_file and os.path.exists(csr_unlink_file): - os.unlink(csr_unlink_file) - - return certfile - - -class CertmasterXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer): - def __init__(self, args): - self.allow_reuse_address = True - SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, args) - - -def serve(xmlrpcinstance): - - """ - Code for starting the XMLRPC service. - """ - - server = CertmasterXMLRPCServer((xmlrpcinstance.cfg.listen_addr, CERTMASTER_LISTEN_PORT)) - server.logRequests = 0 # don't print stuff to console - server.register_instance(xmlrpcinstance) - server.serve_forever() - - -def main(argv): - - cm = CertMaster('/etc/func/certmaster.conf') - - if "daemon" in argv or "--daemon" in argv: - utils.daemonize("/var/run/certmaster.pid") - else: - print "serving...\n" - - - # just let exceptions bubble up for now - serve(cm) - - -if __name__ == "__main__": - #textdomain(I18N_DOMAIN) - main(sys.argv) -- cgit From aa9dbd4f06d56bdecc33154fb8977a8f456435fa Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Mon, 25 Feb 2008 17:55:46 -0500 Subject: remove debug spew --- func/SSLCommon.py | 1 - 1 file changed, 1 deletion(-) (limited to 'func') diff --git a/func/SSLCommon.py b/func/SSLCommon.py index b37fc68..6959749 100644 --- a/func/SSLCommon.py +++ b/func/SSLCommon.py @@ -30,7 +30,6 @@ def our_verify(connection, x509, errNum, errDepth, preverifyOK): def CreateSSLContext(pkey, cert, ca_cert): - print pkey, cert, ca_cert for f in pkey, cert, ca_cert: if f and not os.access(f, os.R_OK): print "%s does not exist or is not readable." % f -- cgit