diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | ipatests/test_xmlrpc/test_host_plugin.py | 22 | ||||
-rw-r--r-- | ipatests/test_xmlrpc/test_service_plugin.py | 24 | ||||
-rw-r--r-- | ipatests/test_xmlrpc/testcert.py | 103 | ||||
-rwxr-xr-x | make-testcert | 136 |
6 files changed, 121 insertions, 166 deletions
diff --git a/.gitignore b/.gitignore index 6ff372b37..04eb68371 100644 --- a/.gitignore +++ b/.gitignore @@ -64,7 +64,6 @@ freeipa2-dev-doc /ipa-client/ipa-join /ipa-client/ipa-rmkeytab -/ipatests/test_xmlrpc/service.crt /ipatests/setup.py /ipapython/setup.py @@ -113,7 +113,6 @@ lint: bootstrap-autogen test: - ./make-testcert ./make-test release-update: diff --git a/ipatests/test_xmlrpc/test_host_plugin.py b/ipatests/test_xmlrpc/test_host_plugin.py index 300e1c25e..af42ee54d 100644 --- a/ipatests/test_xmlrpc/test_host_plugin.py +++ b/ipatests/test_xmlrpc/test_host_plugin.py @@ -28,11 +28,12 @@ from ipapython import ipautil from ipalib import api, errors, x509 from ipapython.dn import DN from nose.tools import raises, assert_raises -from nose.plugins.skip import Skip, SkipTest +from nose.plugins.skip import SkipTest from ipatests.test_xmlrpc.xmlrpc_test import (Declarative, XMLRPC_test, fuzzy_uuid, fuzzy_digits, fuzzy_hash, fuzzy_date, fuzzy_issuer, fuzzy_hex) from ipatests.test_xmlrpc import objectclasses +from ipatests.test_xmlrpc.testcert import get_testcert import base64 @@ -55,13 +56,6 @@ dn4 = DN(('fqdn',fqdn4),('cn','computers'),('cn','accounts'), api.env.basedn) invalidfqdn1 = u'foo_bar.lab.%s' % api.env.domain -# We can use the same cert we generated for the service tests -fd = open('ipatests/test_xmlrpc/service.crt', 'r') -servercert = fd.readlines() -servercert = ''.join(servercert) -servercert = x509.strip_header(servercert) -fd.close() - sshpubkey = u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGAX3xAeLeaJggwTqMjxNwa6XHBUAikXPGMzEpVrlLDCZtv00djsFTBi38PkgxBJVkgRWMrcBsr/35lq7P6w8KGIwA8GI48Z0qBS2NBMJ2u9WQ2hjLN6GdMlo77O0uJY3251p12pCVIS/bHRSq8kHO2No8g7KA9fGGcagPfQH+ee3t7HUkpbQkFTmbPPN++r3V8oVUk5LxbryB3UIIVzNmcSIn3JrXynlvui4MixvrtX6zx+O/bBo68o8/eZD26QrahVbA09fivrn/4h3TM019Eu/c2jOdckfU3cHUV/3Tno5d6JicibyaoDDK7S/yjdn5jhaz8MSEayQvFkZkiF0L public key test' sshpubkeyfp = u'13:67:6B:BF:4E:A2:05:8E:AE:25:8B:A1:31:DE:6F:1B public key test (ssh-rsa)' @@ -254,7 +248,7 @@ class test_host(Declarative): dict( desc='Update %r' % fqdn1, command=('host_mod', [fqdn1], dict(description=u'Updated host 1', - usercertificate=servercert)), + usercertificate=get_testcert())), expected=dict( value=fqdn1, summary=u'Modified host "%s"' % fqdn1, @@ -264,7 +258,7 @@ class test_host(Declarative): l=[u'Undisclosed location 1'], krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], valid_not_before=fuzzy_date, valid_not_after=fuzzy_date, subject=DN(('CN',api.env.host),x509.subject_base()), @@ -295,7 +289,7 @@ class test_host(Declarative): has_keytab=False, has_password=False, managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], valid_not_before=fuzzy_date, valid_not_after=fuzzy_date, subject=DN(('CN',api.env.host),x509.subject_base()), @@ -493,7 +487,7 @@ class test_host(Declarative): l=[u'Undisclosed location 1'], krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], valid_not_before=fuzzy_date, valid_not_after=fuzzy_date, subject=DN(('CN',api.env.host),x509.subject_base()), @@ -522,7 +516,7 @@ class test_host(Declarative): l=[u'Undisclosed location 1'], krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], valid_not_before=fuzzy_date, valid_not_after=fuzzy_date, subject=DN(('CN',api.env.host),x509.subject_base()), @@ -560,7 +554,7 @@ class test_host(Declarative): l=[u'Undisclosed location 1'], krbprincipalname=[u'host/%s@%s' % (fqdn1, api.env.realm)], managedby_host=[u'%s' % fqdn1], - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], valid_not_before=fuzzy_date, valid_not_after=fuzzy_date, subject=DN(('CN',api.env.host),x509.subject_base()), diff --git a/ipatests/test_xmlrpc/test_service_plugin.py b/ipatests/test_xmlrpc/test_service_plugin.py index f51954eb3..c11612e6b 100644 --- a/ipatests/test_xmlrpc/test_service_plugin.py +++ b/ipatests/test_xmlrpc/test_service_plugin.py @@ -26,6 +26,7 @@ from ipatests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_hash from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_digits, fuzzy_date, fuzzy_issuer from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_hex from ipatests.test_xmlrpc import objectclasses +from ipatests.test_xmlrpc.testcert import get_testcert import base64 from ipapython.dn import DN @@ -39,11 +40,6 @@ host1dn = DN(('fqdn',fqdn1),('cn','computers'),('cn','accounts'),api.env.basedn) host2dn = DN(('fqdn',fqdn2),('cn','computers'),('cn','accounts'),api.env.basedn) host3dn = DN(('fqdn',fqdn3),('cn','computers'),('cn','accounts'),api.env.basedn) -fd = open('ipatests/test_xmlrpc/service.crt', 'r') -servercert = fd.readlines() -servercert = ''.join(servercert) -servercert = x509.strip_header(servercert) -fd.close() badservercert = 'MIICbzCCAdigAwIBAgICA/4wDQYJKoZIhvcNAQEFBQAwKTEnMCUGA1UEAxMeSVBBIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDgwOTE1MDIyN1oXDTIwMDgwOTE1MDIyN1owKTEMMAoGA1UEChMDSVBBMRkwFwYDVQQDExBwdW1hLmdyZXlvYWsuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwYbfEOQPgGenPn9vt1JFKvWm/Je3y2tawGWA3LXDuqfFJyYtZ8ib3TcBUOnLk9WK5g2qCwHaNlei7bj8ggIfr5hegAVe10cun+wYErjnYo7hsHYd+57VZezeipWrXu+7NoNd4+c4A5lk4A/xJay9j3bYx2oOM8BEox4xWYoWge1ljPrc5JK46f0X7AGW4F2VhnKPnf8rwSuzI1U8VGjutyM9TWNy3m9KMWeScjyG/ggIpOjUDMV7HkJL0Di61lznR9jXubpiEC7gWGbTp84eGl/Nn9bgK1AwHfJ2lHwfoY4uiL7ge1gyP6EvuUlHoBzdb7pekiX28iePjW3iEG9IawIDAQABoyIwIDARBglghkgBhvhCAQEEBAMCBkAwCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBBQUAA4GBACRESLemRV9BPxfEgbALuxH5oE8jQm8WZ3pm2pALbpDlAd9wQc3yVf6RtkfVthyDnM18bg7IhxKpd77/p3H8eCnS8w5MLVRda6ktUC6tGhFTS4QKAf0WyDGTcIgkXbeDw0OPAoNHivoXbIXIIRxlw/XgaSaMzJQDBG8iROsN4kCv' @@ -68,7 +64,7 @@ class test_service(Declarative): dict( desc='Try to update non-existent %r' % service1, - command=('service_mod', [service1], dict(usercertificate=servercert)), + command=('service_mod', [service1], dict(usercertificate=get_testcert())), expected=errors.NotFound( reason=u'%s: service not found' % service1), ), @@ -380,12 +376,12 @@ class test_service(Declarative): dict( desc='Update %r' % service1, - command=('service_mod', [service1], dict(usercertificate=servercert)), + command=('service_mod', [service1], dict(usercertificate=get_testcert())), expected=dict( value=service1, summary=u'Modified service "%s"' % service1, result=dict( - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], krbprincipalname=[service1], managedby_host=[fqdn1], valid_not_before=fuzzy_date, @@ -420,7 +416,7 @@ class test_service(Declarative): value=service1, summary=u'Modified service "%s"' % service1, result=dict( - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], krbprincipalname=[service1], managedby_host=[fqdn1], ipakrbauthzdata=[u'MS-PAC'], @@ -445,7 +441,7 @@ class test_service(Declarative): summary=None, result=dict( dn=service1dn, - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], krbprincipalname=[service1], has_keytab=False, managedby_host=[fqdn1], @@ -472,7 +468,7 @@ class test_service(Declarative): value=service1, summary=u'Modified service "%s"' % service1, result=dict( - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], krbprincipalname=[service1], managedby_host=[fqdn1], ipakrbauthzdata=[u'MS-PAC'], @@ -499,7 +495,7 @@ class test_service(Declarative): value=service1, summary=u'Modified service "%s"' % service1, result=dict( - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], krbprincipalname=[service1], managedby_host=[fqdn1], ipakrbauthzdata=[u'MS-PAC'], @@ -524,7 +520,7 @@ class test_service(Declarative): value=service1, summary=u'Modified service "%s"' % service1, result=dict( - usercertificate=[base64.b64decode(servercert)], + usercertificate=[base64.b64decode(get_testcert())], krbprincipalname=[service1], managedby_host=[fqdn1], ipakrbauthzdata=[u'MS-PAC'], @@ -564,7 +560,7 @@ class test_service(Declarative): dict( desc='Try to update non-existent %r' % service1, - command=('service_mod', [service1], dict(usercertificate=servercert)), + command=('service_mod', [service1], dict(usercertificate=get_testcert())), expected=errors.NotFound( reason=u'%s: service not found' % service1), ), diff --git a/ipatests/test_xmlrpc/testcert.py b/ipatests/test_xmlrpc/testcert.py new file mode 100644 index 000000000..ead6ee7f5 --- /dev/null +++ b/ipatests/test_xmlrpc/testcert.py @@ -0,0 +1,103 @@ +# +# Authors: +# Rob Crittenden <rcritten@redhat.com> +# +# 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 <http://www.gnu.org/licenses/>. + +""" +Provide a custom certificate used in the service tests. + +The certificate in cached in a global variable so it only has to be created +once per test run. +""" + +import os +import tempfile +import shutil +from ipalib import api, x509 +from ipaserver.plugins import rabase +from ipapython import ipautil +from ipapython.dn import DN + +_testcert = None + + +def get_testcert(): + """Get the certificate, creating it if it doesn't exist""" + global _testcert + if _testcert is None: + reqdir = tempfile.mkdtemp(prefix="tmp-") + try: + _testcert = makecert(reqdir) + finally: + shutil.rmtree(reqdir) + return x509.strip_header(_testcert) + + +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 generate_csr(reqdir, pwname, subject): + """ + Create a CSR for the given subject. + """ + req_path = os.path.join(reqdir, 'req') + run_certutil(reqdir, ["-R", "-s", subject, + "-o", req_path, + "-z", "/etc/group", + "-f", pwname, + "-a"]) + with open(req_path, "r") as fp: + return fp.read() + + +def makecert(reqdir): + """ + Generate a service certificate that can be used during unit testing. + """ + + ra = rabase.rabase() + if (not os.path.exists(ra.sec_dir) and + api.env.xmlrpc_uri == 'http://localhost:8888/ipa/xml'): + raise AssertionError('The self-signed CA is not configured, ' + 'see ipatests/test_xmlrpc/test_cert.py') + + pwname = os.path.join(reqdir, "pwd") + + # Create an empty password file + with open(pwname, "w") as fp: + fp.write("\n") + + # Generate NSS cert database to store the private key for our CSR + run_certutil(reqdir, ["-N", "-f", pwname]) + + res = api.Command['config_show']() + subject_base = res['result']['ipacertificatesubjectbase'][0] + + cert = None + subject = DN(('CN', api.env.host), subject_base) + princ = 'unittest/%s@%s' % (api.env.host, api.env.realm) + csr = unicode(generate_csr(reqdir, pwname, str(subject))) + + res = api.Command['cert_request'](csr, principal=princ, add=True) + return x509.make_pem(res['result']['certificate']) diff --git a/make-testcert b/make-testcert deleted file mode 100755 index ff25b399c..000000000 --- a/make-testcert +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/python2 -# -# Authors: -# Rob Crittenden <rcritten@redhat.com> -# -# 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 <http://www.gnu.org/licenses/>. - -""" -Generate a custom certificate used in the service unit tests. The certificate -will be created in ipatests/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 -from ipapython.dn import DN - -CERTPATH = 'ipatests/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 ipatests/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]) - - res = api.Backend.client.run('config_show') - subject_base = res['result']['ipacertificatesubjectbase'][0] - - cert = None - subject = DN(('CN', api.env.host), subject_base) - princ = 'unittest/%s@%s' % (api.env.host, api.env.realm) - csr = unicode(generateCSR(reqdir, pwname, str(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) |