summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@mdehaan.rdu.redhat.com>2007-09-26 16:35:41 -0400
committerMichael DeHaan <mdehaan@mdehaan.rdu.redhat.com>2007-09-26 16:35:41 -0400
commit484c9dba767b8a9b1e907d5e4179951ca3f1f2f7 (patch)
treeab8f91bcda34e11d6cba9840ee5326118aa6839e
parent62b705f2ef608e212229a234b9e53cf60f9dd83f (diff)
parent05034f278190ecaccdf61655d9b7c9bc97d52e79 (diff)
downloadfunc-484c9dba767b8a9b1e907d5e4179951ca3f1f2f7.tar.gz
func-484c9dba767b8a9b1e907d5e4179951ca3f1f2f7.tar.xz
func-484c9dba767b8a9b1e907d5e4179951ca3f1f2f7.zip
Merge branch 'master' of ssh://git.fedoraproject.org/git/hosted/func
-rw-r--r--func.spec1
-rwxr-xr-xfunc/certmaster.py74
-rwxr-xr-xminion/server.py1
-rwxr-xr-xscripts/certmaster-ca70
-rw-r--r--setup.py2
-rw-r--r--version2
6 files changed, 135 insertions, 15 deletions
diff --git a/func.spec b/func.spec
index a81f207..ed67a05 100644
--- a/func.spec
+++ b/func.spec
@@ -38,6 +38,7 @@ rm -fr $RPM_BUILD_ROOT
%{_bindir}/funcd
%{_bindir}/func
%{_bindir}/certmaster
+%{_bindir}/certmaster-ca
/etc/init.d/funcd
/etc/init.d/certmaster
%config(noreplace) /etc/func/minion.conf
diff --git a/func/certmaster.py b/func/certmaster.py
index 89b68a0..58840bb 100755
--- a/func/certmaster.py
+++ b/func/certmaster.py
@@ -1,5 +1,9 @@
#!/usr/bin/python
+# FIXME: Perms checked and okayed on all csr, certs and keys, everywhere
+# FIXME: picky about bogus CN names ../ ../ ./ etc, etc to avoid stupid attacks
+# FIXME: more intelligent fault raises
+
"""
cert master listener
@@ -24,6 +28,7 @@ import os.path
import traceback
from OpenSSL import crypto
import sha
+import glob
#from func.server import codes
import func
@@ -95,8 +100,7 @@ class CertMaster(object):
if method in self.handlers.keys():
return self.handlers[method](*params)
else:
- pass
- #raise codes.InvalidMethodException
+ raise func.codes.InvalidMethodException
def wait_for_cert(self, csrbuf):
@@ -113,7 +117,7 @@ class CertMaster(object):
return False, '', ''
requesting_host = csrreq.get_subject().CN
- certfile = '%s/%s.pem' % (self.cfg.certroot, requesting_host)
+ certfile = '%s/%s.cert' % (self.cfg.certroot, requesting_host)
csrfile = '%s/%s.csr' % (self.cfg.csrroot, requesting_host)
# check for old csr on disk
@@ -134,8 +138,7 @@ class CertMaster(object):
# look for a cert:
# if we have it, then return True, etc, etc
if os.path.exists(certfile):
- slavecert = crypto.load_certificate(crypto.FILETYPE_PEM, certfile)
-
+ slavecert = func.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
@@ -145,14 +148,9 @@ class CertMaster(object):
# else write out the csr
if self.cfg.autosign:
- slavecert = func.certs.create_slave_certificate(csrreq,
- self.cakey, self.cacert, self.cfg.cadir)
-
- destfo = open(certfile, 'w')
- destfo.write(crypto.dump_certificate(crypto.FILETYPE_PEM, slavecert))
- destfo.close()
- del destfo
- cert_buf = crypto.dump_certificate(crypto.FILETYPE_PEM, slavecert)
+ cert_fn = self.sign_this_csr(csrreq)
+ cert = func.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
@@ -166,6 +164,56 @@ class CertMaster(object):
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 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:
+ print 'Bad CSR: %s' % csr
+
+ else: # assume we got a bare csr req
+ csrreq = csr
+ requesting_host = csrreq.get_subject().CN
+ certfile = '%s/%s.cert' % (self.cfg.certroot, requesting_host)
+ thiscert = func.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
diff --git a/minion/server.py b/minion/server.py
index a047c53..0208f46 100755
--- a/minion/server.py
+++ b/minion/server.py
@@ -29,6 +29,7 @@ import codes
import config_data
import logger
import module_loader
+import utils
class XmlRpcInterface(object):
diff --git a/scripts/certmaster-ca b/scripts/certmaster-ca
new file mode 100755
index 0000000..14f7c2f
--- /dev/null
+++ b/scripts/certmaster-ca
@@ -0,0 +1,70 @@
+#!/usr/bin/python -tt
+# sign/list keys
+# --sign hostname hostname hostname
+# --list # lists all csrs needing to be signed
+# --list-all ?
+# --clean? not sure what it will do
+
+import sys
+
+import func
+import func.certs
+import func.certmaster
+
+
+
+from optparse import OptionParser
+defaults = { 'listen_addr': 'localhost',
+ 'listen_port': '51235',
+ 'cadir': '/etc/pki/func/ca',
+ 'certroot': '/var/lib/func/certmaster/certs',
+ 'csrroot': '/var/lib/func/certmaster/csrs',
+ 'autosign': 'false'
+ }
+
+def errorprint(stuff):
+ print >> sys.stderr, stuff
+
+
+def parseargs(args):
+ usage = 'certmaster-ca [options]'
+ parser = OptionParser(usage=usage)
+
+ 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",
+ help='sign requests of hosts specified')
+
+ (opts, args) = parser.parse_args()
+ # XXX FIXME check for obviously impossible things and exit, etc
+
+ return (opts, args)
+
+def main(args):
+ cm = func.certmaster.CertMaster('/etc/func/certmaster.conf', defaults)
+
+ (opts, args) = parseargs(args)
+ if opts.list:
+ hns = cm.get_csrs_waiting()
+ if hns:
+ for hn in cm.get_csrs_waiting():
+ print hn
+ else:
+ print 'No certificates to sign'
+
+ return 0
+
+ if opts.sign:
+ if not args:
+ errorprint('Need hostnames to sign')
+ return 1
+
+ for hn in args:
+ csrfile = '%s/%s.csr' % (cm.cfg.csrroot, hn)
+ certfile = cm.sign_this_csr(csrfile)
+ print '%s signed - cert located at %s' % (hn, certfile)
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/setup.py b/setup.py
index 51b3c49..be7e9cb 100644
--- a/setup.py
+++ b/setup.py
@@ -27,7 +27,7 @@ if __name__ == "__main__":
author_email = "func-list@redhat.com",
url = "https://hosted.fedoraproject.org/projects/func/",
license = "GPL",
- scripts = ["scripts/funcd", "scripts/func", "scripts/certmaster"],
+ scripts = ["scripts/funcd", "scripts/func", "scripts/certmaster", "scripts/certmaster-ca"],
# package_data = { '' : ['*.*'] },
package_dir = {"%s" % NAME: "%s" % NAME,
"%s/minion" % NAME: "minion/",
diff --git a/version b/version
index 6cd8779..5376242 100644
--- a/version
+++ b/version
@@ -1 +1 @@
-0.11 5
+0.11 6