#!/usr/bin/python # # Authors: # Rob Crittenden # # Copyright (C) 2011 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ Generate a custom certificate used in the service unit tests. The certificate will be created in tests/test_xmlrpc/service.crt """ import sys import os import tempfile import shutil import nss.nss as nss from ipalib import api, x509, backend, errors from ipaserver.plugins import rabase from ipapython import ipautil CERTPATH = 'tests/test_xmlrpc/service.crt' def run_certutil(reqdir, args, stdin=None): """ Run an NSS certutil command """ new_args = ["/usr/bin/certutil", "-d", reqdir] new_args = new_args + args return ipautil.run(new_args, stdin) def generateCSR(reqdir, pwname, subject): """ Create a CSR for the given subject. """ run_certutil(reqdir, ["-R", "-s", subject, "-o", '%s/req' % reqdir, "-z", "/etc/group", "-f", pwname, "-a", ]) fp = open('%s/req' % reqdir, "r") data = fp.read() fp.close() return data class client(backend.Executioner): """ A simple-minded IPA client that can execute remote commands. """ def run(self, method, *args, **options): self.create_context() result = self.execute(method, *args, **options) return result def makecert(reqdir): """ Generate a service certificate that can be used during unit testing. """ cfg = dict( context='cli', in_server=False, debug=False, verbose=0, ) api.bootstrap(**cfg) api.register(client) api.finalize() ra = rabase.rabase() if not os.path.exists(ra.sec_dir) and api.env.xmlrpc_uri == 'http://localhost:8888/ipa/xml': sys.exit('The in-tree self-signed CA is not configured, see tests/test_xmlrpc/test_cert.py') pwname = reqdir + "/pwd" # Create an empty password file fp = open(pwname, "w") fp.write("\n") fp.close() # Generate NSS cert database to store the private key for our CSR run_certutil(reqdir, ["-N", "-f", pwname]) cert = None subject = 'CN=%s,O=%s' % (api.env.host, api.env.realm) princ = 'unittest/%s@%s' % (api.env.host, api.env.realm) csr = unicode(generateCSR(reqdir, pwname, subject)) try: res = api.Backend.client.run('cert_request', csr, principal=princ, add=True) cert = x509.make_pem(res['result']['certificate']) fd = open(CERTPATH, 'w') fd.write(cert) fd.close() except errors.NotFound: return "certificate request failed" except errors.CommandError: return "You need to set enable_ra=True in ~/.ipa/default.conf" nss.nss_init_nodb() c = x509.load_certificate(cert, x509.PEM) print c return 0 reqdir = None if os.path.exists(CERTPATH): print "Test certificate %s exists, skipping." % CERTPATH sys.exit(0) try: reqdir = tempfile.mkdtemp(prefix = "tmp-") sys.exit(makecert(reqdir)) finally: shutil.rmtree(reqdir)