usename = utils.get_hostname(talk_to_certmaster=False)
- mycn = '%s-CA-KEY' % usename
- self.ca_key_file = '%s/certmaster.key' % self.cfg.cadir
- self.ca_cert_file = '%s/certmaster.crt' % self.cfg.cadir
-
self.logger = logger.Logger().logger
self.audit_logger = logger.AuditLogger()
- # if ca_key_file exists and ca_cert_file is missing == minion only setup
- if os.path.exists(self.ca_key_file) and not os.path.exists(self.ca_cert_file):
- return
+ self.cakey = {}
+ self.cacert = {}
- 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)
+ for (s_caname,a_ca) in self.cfg.ca.iteritems():
+ s_cadir = a_ca['cadir']
+ if s_caname == "":
+ mycn = '%s-CA-KEY' % usename
+ else:
+ mycn = '%s-%s-CA-KEY' % (s_caname.upper(),usename)
+
+ s_ca_key_file = '%s/certmaster.key' % s_cadir
+ s_ca_cert_file = '%s/certmaster.crt' % s_cadir
- # 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)
+ # if ca_key_file exists and ca_cert_file is missing == minion only setup
+ if os.path.exists(s_ca_key_file) and not os.path.exists(s_ca_cert_file):
+ continue
- for dirpath in [self.cfg.cadir, self.cfg.certroot, self.cfg.csrroot]:
- if not os.path.exists(dirpath):
- os.makedirs(dirpath)
+ try:
+ if not os.path.exists(s_cadir):
+ os.makedirs(s_cadir)
+ if not os.path.exists(s_ca_key_file) and not os.path.exists(s_ca_cert_file):
+ certs.create_ca(CN=mycn, ca_key_file=s_ca_key_file, ca_cert_file=s_ca_cert_file)
+ except (IOError, OSError), e:
+ print 'Cannot make certmaster certificate authority keys/certs for CA %s, aborting: %s' % (s_caname, e)
+ sys.exit(1)
+
+ # open up the cakey and cacert so we have them available
+ self.cakey[s_caname] = certs.retrieve_key_from_file(s_ca_key_file)
+ self.cacert[s_caname] = certs.retrieve_cert_from_file(s_ca_cert_file)
+
+ for dirpath in [a_ca['cadir'], a_ca['certroot'], a_ca['csrroot'], a_ca['csrroot']]:
+ if not os.path.exists(dirpath):
+ os.makedirs(dirpath)
# setup handlers
self.handlers = {
commonname = commonname.replace('\\', '')
return commonname
- def wait_for_cert(self, csrbuf, with_triggers=True):
+ def wait_for_cert(self, csrbuf, ca='', with_triggers=True):
"""
takes csr as a string
returns True, caller_cert, ca_cert
self.logger.info("%s requested signing of cert %s" % (requesting_host,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)
+ certfile = '%s/%s.cert' % (self.cfg.ca[ca]['certroot'], requesting_host)
+ csrfile = '%s/%s.csr' % (self.cfg.ca[ca]['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 we're autosign then sign it, write out the cert and return True, etc, etc
# else write out the csr
- if self.cfg.autosign:
+ if self.cfg.ca[ca]['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)
- self.logger.info("cert for %s was autosigned" % (requesting_host))
+ self.logger.info("cert for %s for ca %s was autosigned" % (requesting_host,ca))
if with_triggers:
self._run_triggers(None,'/var/lib/certmaster/triggers/request/post/*')
return True, cert_buf, cacert_buf
destfo.write(crypto.dump_certificate_request(crypto.FILETYPE_PEM, csrreq))
destfo.close()
del destfo
- self.logger.info("cert for %s created and ready to be signed" % (requesting_host))
+ self.logger.info("cert for %s for CA %s created and ready to be signed" % (requesting_host, ca))
if with_triggers:
self._run_triggers(None,'/var/lib/certmaster/triggers/request/post/*')
return False, '', ''
return False, '', ''
- def get_csrs_waiting(self):
+ def get_csrs_waiting(self, ca=''):
hosts = []
- csrglob = '%s/*.csr' % self.cfg.csrroot
+ csrglob = '%s/*.csr' % self.cfg.ca[ca]['csrroot']
csr_list = glob.glob(csrglob)
for f in csr_list:
hn = os.path.basename(f)
hosts.append(hn)
return hosts
- def remove_this_cert(self, hn, with_triggers=True):
+ def remove_this_cert(self, hn, with_triggers=True, ca=''):
""" removes cert for hostname using unlink """
cm = self
- csrglob = '%s/%s.csr' % (cm.cfg.csrroot, hn)
+ csrglob = '%s/%s.csr' % (cm.cfg.ca[ca]['csrroot'], hn)
csrs = glob.glob(csrglob)
- certglob = '%s/%s.cert' % (cm.cfg.certroot, hn)
+ certglob = '%s/%s.cert' % (cm.cfg.ca[ca]['certroot'], hn)
certs = glob.glob(certglob)
if not csrs and not certs:
# FIXME: should be an exception?
if with_triggers:
self._run_triggers(hn,'/var/lib/certmaster/triggers/remove/post/*')
- def sign_this_csr(self, csr, with_triggers=True):
+ def sign_this_csr(self, csr, with_triggers=True,ca=''):
"""returns the path to the signed cert file"""
csr_unlink_file = None
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))
+ elif os.path.exists('%s/%s' % (self.cfg.ca[ca]['csrroot'], csr)): # we have a partial path?
+ csrfo = open('%s/%s' % (self.cfg.ca[ca]['csrroot'], csr))
csr_buf = csrfo.read()
- csr_unlink_file = '%s/%s' % (self.cfg.csrroot, csr)
+ csr_unlink_file = '%s/%s' % (self.cfg.ca[ca]['csrroot'], csr)
# we have a string of some kind
else:
self._run_triggers(requesting_host,'/var/lib/certmaster/triggers/sign/pre/*')
- certfile = '%s/%s.cert' % (self.cfg.certroot, requesting_host)
+ certfile = '%s/%s.cert' % (self.cfg.ca[ca]['certroot'], requesting_host)
self.logger.info("Signing for csr %s requested" % certfile)
- thiscert = certs.create_slave_certificate(csrreq, self.cakey, self.cacert, self.cfg.cadir)
+ thiscert = certs.create_slave_certificate(csrreq, self.cakey, self.cacert, self.cfg.ca[ca]['cadir'])
destfo = open(certfile, 'w')
destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, thiscert))
return certfile
# return a list of already signed certs
- def get_signed_certs(self, hostglobs=None):
- certglob = "%s/*.cert" % (self.cfg.certroot)
+ def get_signed_certs(self, hostglobs=None, ca=''):
+ certglob = "%s/*.cert" % (self.cfg.ca[ca]['certroot'])
certs = []
globs = "*"
globs = hostglobs
for hostglob in globs:
- certglob = "%s/%s.cert" % (self.cfg.certroot, hostglob)
+ certglob = "%s/%s.cert" % (self.cfg.ca[ca]['certroot'], hostglob)
certs = certs + glob.glob(certglob)
signed_certs = []
return glob.glob(myglob)
# return a list of the cert hash string we use to identify systems
- def get_cert_hashes(self, hostglobs=None):
- certglob = "%s/*.cert" % (self.cfg.certroot)
+ def get_cert_hashes(self, hostglobs=None,ca=''):
+ certglob = "%s/*.cert" % (self.cfg.ca[ca]['certroot'])
certfiles = []
globs = "*"
globs = hostglobs
for hostglob in globs:
- certglob = "%s/%s.cert" % (self.cfg.certroot, hostglob)
+ certglob = "%s/%s.cert" % (self.cfg.ca[ca]['certroot'], hostglob)
certfiles = certfiles + glob.glob(certglob)
cert_hashes = []
# FIXME: move to requestor module and also create a verbose mode
# prints to the screen for usage by /usr/bin/certmaster-request
-def create_minion_keys(hostname=None):
+def create_minion_keys(hostname=None, ca=''):
log = logger.Logger().logger
# FIXME: paths should not be hard coded here, move to settings universally
config_file = '/etc/certmaster/minion.conf'
config = read_config(config_file, MinionConfig)
- cert_dir = config.cert_dir
+
+ cert_dir = config.ca[ca]['cert_dir']
+
master_uri = 'http://%s:%s/' % (config.certmaster, config.certmaster_port)
hn = hostname
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):
# print "DEBUG: err, no cert_file"
return
try:
# print "DEBUG: submitting CSR to certmaster: %s" % master_uri
log.debug("submitting CSR: %s to certmaster %s" % (csr_file, master_uri))
- result, cert_string, ca_cert_string = submit_csr_to_master(csr_file, master_uri)
+ result, cert_string, ca_cert_string = submit_csr_to_master(csr_file, master_uri, ca)
except socket.error, e:
log.warning("Could not locate certmaster at %s" % master_uri)
raise codes.CMException, "certmaster trigger failed: %(file)s returns %(code)d" % { "file" : file, "code" : rc }
-def submit_csr_to_master(csr_file, master_uri):
+def submit_csr_to_master(csr_file, master_uri, ca=''):
""""
gets us our cert back from the certmaster.wait_for_cert() method
takes csr_file as path location and master_uri
s = xmlrpclib.ServerProxy(master_uri)
# print "DEBUG: waiting for cert"
- return s.wait_for_cert(csr)
+ return s.wait_for_cert(csr,ca)
#!/usr/bin/python -tt
# sign/list keys
+# --ca ca sign/list certs for the 'ca'
# --sign hostname hostname hostname
# --list # lists all csrs needing to be signed
-# --list-all ?
+# --list-all ca list all certs for a given ca
# --clean? not sure what it will do
import sys
def parseargs(args):
usage = 'certmaster-ca <option> [args]'
parser = CertmasterCAOptionParser(usage=usage,version=True)
-
+
+ parser.add_option("", '--ca', default='', action="store", dest="ca", metavar="CA",
+ help="certificate authority used to sign/list certs")
parser.add_option('-l', '--list', default=False, action="store_true",
help='list signing requests remaining')
parser.add_option('-s', '--sign', default=False, action="store_true",
if opts.list:
- hns = cm.get_csrs_waiting()
+ hns = cm.get_csrs_waiting(opts.ca)
if hns:
for hn in sorted(hns):
print hn
return 1
for hn in args:
- csrglob = '%s/%s.csr' % (cm.cfg.csrroot, hn)
+ csrglob = '%s/%s.csr' % (cm.cfg.cas[opts.ca]['csrroot'], hn)
csrs = glob.glob(csrglob)
if not csrs:
errorprint('No match for %s to sign' % hn)
return 1
for fn in csrs:
- certfile = cm.sign_this_csr(fn)
+ certfile = cm.sign_this_csr(opts.ca,fn)
print '%s signed - cert located at %s' % (fn, certfile)
return 0
return 1
for hn in args:
- cm.remove_this_cert(hn)
+ cm.remove_this_cert(opts.ca,hn)
return 0
if args:
hostglobs = args
- signed_certs = cm.get_signed_certs(args)
+ signed_certs = cm.get_signed_certs(opts.ca, args)
for i in sorted(signed_certs):
print i
if args:
hostglobs = args
- cert_hashes = cm.get_cert_hashes(hostglobs)
+ cert_hashes = cm.get_cert_hashes(opts.ca, hostglobs)
for i in sorted(cert_hashes):
print i