[Freeipa-devel] [PATCH] 0097 Add options to write lightweight CA cert or chain to file
Fraser Tweedale
ftweedal at redhat.com
Mon Aug 8 04:34:24 UTC 2016
Please review the attached patch with adds --certificate-out and
--certificate-chain-out options to `ca-show' command.
Note that --certificate-chain-out currently writes a bogus file due
to a bug in Dogtag that will be fixed in this week's build.
https://fedorahosted.org/freeipa/ticket/6178
Thanks,
Fraser
-------------- next part --------------
From 6d3a153a954ab09022af6073ae9ea68668716618 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal at redhat.com>
Date: Mon, 8 Aug 2016 14:27:20 +1000
Subject: [PATCH] Add options to write lightweight CA cert or chain to file
Administrators need a way to retrieve the certificate or certificate
chain of an IPA-managed lightweight CA. Add --certificate-out and
--certificate-chain-out options to the `ca-show` command.
Fixes: https://fedorahosted.org/freeipa/ticket/6178
---
API.txt | 4 +++-
VERSION | 4 ++--
ipaclient/plugins/ca.py | 40 ++++++++++++++++++++++++++++++++++++++++
ipaserver/plugins/ca.py | 23 +++++++++++++++++++++--
ipaserver/plugins/dogtag.py | 12 ++++++++++++
5 files changed, 78 insertions(+), 5 deletions(-)
create mode 100644 ipaclient/plugins/ca.py
diff --git a/API.txt b/API.txt
index 535d8ec9a4990395207e2455a09a8c1bdef5529a..6ed8c5348876aa6ce1ab5d11e14dbcb1e7cee768 100644
--- a/API.txt
+++ b/API.txt
@@ -505,9 +505,11 @@ output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: ca_show/1
-args: 1,4,3
+args: 1,6,3
arg: Str('cn', cli_name='name')
option: Flag('all', autofill=True, cli_name='all', default=False)
+option: Str('certificate_chain_out?')
+option: Str('certificate_out?')
option: Flag('raw', autofill=True, cli_name='raw', default=False)
option: Flag('rights', autofill=True, default=False)
option: Str('version?')
diff --git a/VERSION b/VERSION
index ca489965050f32d2d8987dfd251ec2b2a0ba1768..3cdb27b806013be2cb0b8b2132c99302865e6358 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=211
-# Last change: mbabinsk: allow 'value' output param in commands without primary key
+IPA_API_VERSION_MINOR=212
+# Last change: ftweedal: ca: add options to write cert or cert chain to file
diff --git a/ipaclient/plugins/ca.py b/ipaclient/plugins/ca.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f4a7c6074b5eb139e01ba2963bf46399ce6d645
--- /dev/null
+++ b/ipaclient/plugins/ca.py
@@ -0,0 +1,40 @@
+#
+# Copyright (C) 2016 FreeIPA Contributors see COPYING for license
+#
+
+from ipaclient.frontend import MethodOverride
+from ipalib import util
+from ipalib.plugable import Registry
+from ipalib.text import _
+
+register = Registry()
+
+
+ at register(override=True, no_fail=True)
+class ca_show(MethodOverride):
+ def forward(self, *keys, **options):
+ if 'certificate_out' in options:
+ util.check_writable_file(options['certificate_out'])
+ if 'certificate_chain_out' in options:
+ util.check_writable_file(options['certificate_chain_out'])
+
+ result = super(ca_show, self).forward(*keys, **options)
+ summaries = []
+ if 'certificate_out' in options and 'certificate' in result['result']:
+ with open(options['certificate_out'], 'wb') as f:
+ f.write(result['result'].pop('certificate'))
+ summaries.append (
+ _("Certificate written to file '%(file)s'")
+ % dict(file=options['certificate_out'])
+ )
+ if 'certificate_chain_out' in options and 'chain' in result['result']:
+ with open(options['certificate_chain_out'], 'wb') as f:
+ f.write(result['result'].pop('chain'))
+ summaries.append (
+ _("Certificate chain written to file '%(file)s'")
+ % dict(file=options['certificate_chain_out'])
+ )
+ if len(summaries) > 0:
+ result['summary'] = '\n'.join(summaries)
+
+ return result
diff --git a/ipaserver/plugins/ca.py b/ipaserver/plugins/ca.py
index 966ae2b1bdb4bb0207dfa58f0e9c951bc930f766..70aaca19dbece452c8e679a58ce3754ea75666c5 100644
--- a/ipaserver/plugins/ca.py
+++ b/ipaserver/plugins/ca.py
@@ -140,9 +140,28 @@ class ca_find(LDAPSearch):
class ca_show(LDAPRetrieve):
__doc__ = _("Display the properties of a CA.")
- def execute(self, *args, **kwargs):
+ takes_options = LDAPRetrieve.takes_options + (
+ Str('certificate_out?',
+ doc=_('Write certificate to file'),
+ ),
+ Str('certificate_chain_out?',
+ doc=_('Write PKCS #7 certificate chain to file'),
+ ),
+ )
+
+ def execute(self, *keys, **options):
ca_enabled_check()
- return super(ca_show, self).execute(*args, **kwargs)
+ result = super(ca_show, self).execute(*keys, **options)
+
+ ca_id = result['result']['ipacaid'][0]
+ if 'certificate_out' in options:
+ with self.api.Backend.ra_lightweight_ca as ca_api:
+ result['result']['certificate'] = ca_api.read_ca_cert(ca_id)
+ if 'certificate_chain_out' in options:
+ with self.api.Backend.ra_lightweight_ca as ca_api:
+ result['result']['chain'] = ca_api.read_ca_chain(ca_id)
+
+ return result
@register()
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
index aef1e888eb1b6c273c1fd12cbf4912407f8f8132..ea78f4ee93d3bd16a2088cf82618e72a9dcf9268 100644
--- a/ipaserver/plugins/dogtag.py
+++ b/ipaserver/plugins/dogtag.py
@@ -2205,6 +2205,18 @@ class ra_lightweight_ca(RestClient):
except:
raise errors.RemoteRetrieveError(reason=_("Response from CA was not valid JSON"))
+ def read_ca_cert(self, ca_id):
+ status, resp_headers, resp_body = self._ssldo(
+ 'GET', '{}/cert'.format(ca_id),
+ headers={'Accept': 'application/x-pem-file'})
+ return resp_body
+
+ def read_ca_chain(self, ca_id):
+ status, resp_headers, resp_body = self._ssldo(
+ 'GET', '{}/chain'.format(ca_id),
+ headers={'Accept': 'application/x-pem-file'})
+ return resp_body
+
def disable_ca(self, ca_id):
self._ssldo(
'POST', ca_id + '/disable',
--
2.5.5
More information about the Freeipa-devel
mailing list