import socket
import exceptions
-#from func.server import codes
import certs
import codes
import utils
+
+import logger
+
from config import read_config
from commonconfig import CMConfig
CERTMASTER_LISTEN_PORT = 51235
-CERTMASTER_CONFIG = "/etc/func/certmaster.conf"
+CERTMASTER_CONFIG = "/etc/certmaster/certmaster.conf"
class CertMaster(object):
def __init__(self, conf_file=CERTMASTER_CONFIG):
self.cfg = read_config(conf_file, CMConfig)
- usename = utils.get_hostname()
+ usename = utils.get_hostname(talk_to_certmaster=False)
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
+ 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()
+
try:
if not os.path.exists(self.cfg.cadir):
os.makedirs(self.cfg.cadir)
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:
+ self.logger.info("Unhandled method call for method: %s " % method)
raise codes.InvalidMethodException
def _sanitize_cn(self, commonname):
commonname = commonname.replace('\\', '')
return commonname
- def wait_for_cert(self, csrbuf):
+ def wait_for_cert(self, csrbuf, with_triggers=True):
"""
takes csr as a string
returns True, caller_cert, ca_cert
return False, '', ''
requesting_host = self._sanitize_cn(csrreq.get_subject().CN)
-
+
+ if with_triggers:
+ self._run_triggers(None, '/var/lib/certmaster/triggers/request/pre/*')
+
+ 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)
# check for old csr on disk
# if we have it - compare the two - if they are not the same - raise a fault
+ self.logger.debug("csrfile: %s certfile: %s" % (csrfile, certfile))
+
if os.path.exists(csrfile):
oldfo = open(csrfile)
oldcsrbuf = oldfo.read()
newsha.update(csrbuf)
newdig = newsha.hexdigest()
if not newdig == olddig:
+ self.logger.info("A cert for %s already exists and does not match the requesting cert" % (requesting_host))
# XXX raise a proper fault
- return False, '', ''
+ return False, '', ''
+
# look for a cert:
# if we have it, then return True, etc, etc
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)
+ if with_triggers:
+ self._run_triggers(None,'/var/lib/certmaster/triggers/request/post/*')
return True, cert_buf, cacert_buf
# if we don't have a cert then:
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))
+ if with_triggers:
+ self._run_triggers(None,'/var/lib/certmaster/triggers/request/post/*')
return True, cert_buf, cacert_buf
else:
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))
+ if with_triggers:
+ self._run_triggers(None,'/var/lib/certmaster/triggers/request/post/*')
return False, '', ''
return False, '', ''
hosts.append(hn)
return hosts
- def remove_this_cert(self, hn):
+ def remove_this_cert(self, hn, with_triggers=True):
""" removes cert for hostname using unlink """
cm = self
csrglob = '%s/%s.csr' % (cm.cfg.csrroot, hn)
# FIXME: should be an exception?
print 'No match for %s to clean up' % hn
return
+ if with_triggers:
+ self._run_triggers(None,'/var/lib/certmaster/triggers/remove/pre/*')
for fn in csrs + certs:
print 'Cleaning out %s for host matching %s' % (fn, hn)
- os.unlink(fn)
+ self.logger.info('Cleaning out %s for host matching %s' % (fn, hn))
+ os.unlink(fn)
+ if with_triggers:
+ self._run_triggers(None,'/var/lib/certmaster/triggers/remove/post/*')
- def sign_this_csr(self, csr):
+ def sign_this_csr(self, csr, with_triggers=True):
"""returns the path to the signed cert file"""
csr_unlink_file = None
try:
csrreq = crypto.load_certificate_request(crypto.FILETYPE_PEM, csr_buf)
except crypto.Error, e:
+ self.logger.info("Unable to sign %s: Bad CSR" % (csr))
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)
-
+
+ if with_triggers:
+ self._run_triggers(None,'/var/lib/certmaster/triggers/sign/pre/*')
+
+
+ requesting_host = self._sanitize_cn(csrreq.get_subject().CN)
certfile = '%s/%s.cert' % (self.cfg.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)
+
destfo = open(certfile, 'w')
destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, thiscert))
destfo.close()
del destfo
+
+
+ self.logger.info("csr %s signed" % (certfile))
+ if with_triggers:
+ self._run_triggers(None,'/var/lib/certmaster/triggers/sign/post/*')
+
+
if csr_unlink_file and os.path.exists(csr_unlink_file):
os.unlink(csr_unlink_file)
return certfile
+ def _run_triggers(self, ref, globber):
+ return utils.run_triggers(ref, globber)
+
class CertmasterXMLRPCServer(SimpleXMLRPCServer.SimpleXMLRPCServer):
- def __init__(self, args):
+ def __init__(self, addr):
self.allow_reuse_address = True
- SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, args)
+ SimpleXMLRPCServer.SimpleXMLRPCServer.__init__(self, addr)
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)
+ xmlrpcinstance.logger.info("certmaster started")
+ xmlrpcinstance.audit_logger.logger.info("certmaster started")
server.serve_forever()
def main(argv):
- cm = CertMaster('/etc/func/certmaster.conf')
+ cm = CertMaster('/etc/certmaster/certmaster.conf')
if "daemon" in argv or "--daemon" in argv:
utils.daemonize("/var/run/certmaster.pid")