Dne 26.9.2014 v 19:54 Jan Cholasta napsal(a):
Dne 26.9.2014 v 17:13 Rob Crittenden napsal(a):
Jan Cholasta wrote:
Dne 23.9.2014 v 20:39 Rob Crittenden napsal(a):
Jan Cholasta wrote:
Hi,
the attached patches fix various bugs and shortcomings in the CA
management and renewal code. Related tickets:
<https://fedorahosted.org/freeipa/ticket/4416>,
<https://fedorahosted.org/freeipa/ticket/4460>.
(Patch 319 was originally posted at
<http://www.redhat.com/archives/freeipa-devel/2014-September/msg00132.html>.)
Only two of the patches includes what ticket(s) they address. Most have
the tersest of commit messages. If got more and more difficult to see
why the changes were needed at all, as you'll see.
Sorry, fixed (hopefully).
Note that most of these patches fix stuff I didn't have time to fix
before I posted the original CA management patches, hence the missing
tickets.
Well, the policy is that every commit should have a ticket. So I guess
re-open the old tickets or open new ones. This will help someone in the
future know the "why" of a patch. I've certainly been guilty
OK, I will reopen the related tickets.
Here is a new set of reviews as trying to intermingle was making my eyes
cross:
319:
I guess I still don't understand why you can't pull the certs out of
LDAP when creating this database. When this code runs, we know that the
client is configured, so we have access to authentication. Why can't
create_ipa_nssdb pull the certs directly? It seems more robust to me,
and the code is already written in ipa-client-install to do this.
Well, I don't understand why do you want them to be updated so much, as
nothing will break if they are not. Also try to imagine what would
happen if, say, 10k clients were updated at the same moment...
When adding the CA certificates to the temporary database it will report
that a failure occurred, but not the exception:
+ except CalledProcessError, e:
+ root_logger.info("Failed to add CA to temporary NSS
database.")
+ return CLIENT_INSTALL_ERROR
Granted, NSS errors are often obtuse, but should it at least DEBUG log
it?
It is already logged in ipautil.run. The exception only says that the
command failed, there's no point in logging it.
324, 325, 326: ACK
327:
So the idea is to just mirror the certs and us the new db to know what
was added?
Exactly.
What if someone has the same nickname, different cert in the
two databases? Is that too much of a corner case?
IMO it is too much of a corner case, but I plan on adding a better
diff/patch algorithm in the future if it turns out to be a problem.
328, 329, 330, 331: ACK
As an aside, do you know why the global certs are seen by mod_nss?
libnssckbi.so is symlinked into the directory (certutil -L -d
/etc/httpd/alias -h all will show all the certs).
I'm not sure why it is this way, but the module is linked to the NSS
database:
$ sudo modutil -list -dbdir /etc/httpd/alias
Listing of PKCS #11 Modules
-----------------------------------------------------------
1. NSS Internal PKCS #11 Module
slots: 2 slots attached
status: loaded
slot: NSS Internal Cryptographic Services
token: NSS Generic Crypto Services
slot: NSS User Private Key and Certificate Services
token: NSS Certificate DB
2. Root Certs
library name: /etc/httpd/alias/libnssckbi.so
slots: 2 slots attached
status: loaded
slot: /etc/pki/ca-trust/source
token: System Trust
slot: /usr/share/pki/ca-trust-source
token: Default Trust
-----------------------------------------------------------
332-335
I think the naming and/or comments can be improved. For example, there
are now 3 *retrieve_cert commands, all of which do slightly different
things. All have external handlers (via the oddly named profile), but
some are called internally as well.
I have spent quite some time trying to come up with good names for them,
but I was not able to do so. Suggestions are welcome.
This is rather complex code: a command passes a call onto certmonger
which then exuecutes the IPA CA helper... More documentation would
definitely help a newcomer figure out how renewal, CA retrieval, etc.
works.
OK, I'll try to add some.
Not to be too pedantic but there is a lot of this in
dogtag-ipa-ca-renew-agent-submit:
if variable: OR if not variable:
Where variable defaults to None. Shouldn't the test be:
if variable is [not] None:
This doesn't catch empty strings, which may occur in some of these checks.
340: ACK
Through some combination of ipa-certupdate and ipa-cacert-manage I seem
to have hosed things up:
ipa: DEBUG: certmonger request is in state
dbus.String(u'CA_UNREACHABLE', variant_level=1)
ipa.ipaserver.install.ipa_cacert_manage.CACertManage: DEBUG: File
"/usr/lib/python2.7/site-packages/ipapython/admintool.py", line 171, in
execute
return_value = self.run()
File
"/usr/lib/python2.7/site-packages/ipaserver/install/ipa_cacert_manage.py",
line 118, in run
rc = self.renew()
File
"/usr/lib/python2.7/site-packages/ipaserver/install/ipa_cacert_manage.py",
line 181, in renew
return self.renew_self_signed(ca)
File
"/usr/lib/python2.7/site-packages/ipaserver/install/ipa_cacert_manage.py",
line 193, in renew_self_signed
self.resubmit_request(ca, 'caCACert')
File
"/usr/lib/python2.7/site-packages/ipaserver/install/ipa_cacert_manage.py",
line 315, in resubmit_request
"please check the request manually" % self.request_id)
ipa.ipaserver.install.ipa_cacert_manage.CACertManage: DEBUG: The
ipa-cacert-manage command failed, exception: ScriptError: Error
resubmitting certmonger request '20140909142830', please check the
request manually
ipa.ipaserver.install.ipa_cacert_manage.CACertManage: ERROR: Error
resubmitting certmonger request '20140909142830', please check the
request manually
Incidentally, IMHO it should include the command to execute to check the
request manually.
Will add.
The CA is actually unreachable. Restarting it fixed things. I'll chalk
this up to cosmic rays.
OK.
Re-running ipa-cacert-manage renew was successful.
Good.
I confirmed that the CA signing cert was updated in the dogtag database.
I then ran ipa-certupdate to distribute this new CA cert around and none
of the databases got the updated CA cert, nor did /etc/ipa/ca.crt.
Can you see the new CA cert in cn=certificates,cn=ipa,cn=etc,$SUFFIX?
Still doing some functional testing.
Unrelated to this:
9:freeipa-python-4.0.0GITf6875d4-0.#################################
[100%]
Update failed: Operations error:
Seems to be related to this:
2014-09-25T19:28:22Z DEBUG ---------------------------------------------
2014-09-25T19:28:22Z DEBUG Final value after applying updates
2014-09-25T19:28:22Z DEBUG dn: cn=referential integrity
postoperation,cn=plugins,cn=config
2014-09-25T19:28:22Z DEBUG cn:
2014-09-25T19:28:22Z DEBUG referential integrity postoperation
2014-09-25T19:28:22Z DEBUG objectClass:
2014-09-25T19:28:22Z DEBUG top
2014-09-25T19:28:22Z DEBUG nsSlapdPlugin
2014-09-25T19:28:22Z DEBUG extensibleObject
2014-09-25T19:28:22Z DEBUG nsslapd-pluginprecedence:
2014-09-25T19:28:22Z DEBUG 40
2014-09-25T19:28:22Z DEBUG nsslapd-pluginPath:
2014-09-25T19:28:22Z DEBUG libreferint-plugin
2014-09-25T19:28:22Z DEBUG nsslapd-pluginVersion:
2014-09-25T19:28:22Z DEBUG 1.3.3.2
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg5:
2014-09-25T19:28:22Z DEBUG owner
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg4:
2014-09-25T19:28:22Z DEBUG uniquemember
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg7:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg6:
2014-09-25T19:28:22Z DEBUG seeAlso
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg1:
2014-09-25T19:28:22Z DEBUG
/var/log/dirsrv/slapd-GREYOAK-COM/referint
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg0:
2014-09-25T19:28:22Z DEBUG 0
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg3:
2014-09-25T19:28:22Z DEBUG member
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg2:
2014-09-25T19:28:22Z DEBUG 0
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg9:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg8:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginInitfunc:
2014-09-25T19:28:22Z DEBUG referint_postop_init
2014-09-25T19:28:22Z DEBUG nsslapd-pluginexcludeentryscope:
2014-09-25T19:28:22Z DEBUG cn=provisioning,dc=greyoak,dc=com
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg11:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg10:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg13:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg12:
2014-09-25T19:28:22Z DEBUG nsslapd-plugin-depends-on-type:
2014-09-25T19:28:22Z DEBUG database
2014-09-25T19:28:22Z DEBUG nsslapd-pluginVendor:
2014-09-25T19:28:22Z DEBUG 389 Project
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg17:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg16:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg18:
2014-09-25T19:28:22Z DEBUG nsslapd-pluginType:
2014-09-25T19:28:22Z DEBUG betxnpostoperation
2014-09-25T19:28:22Z DEBUG nsslapd-pluginDescription:
2014-09-25T19:28:22Z DEBUG referential integrity plugin
2014-09-25T19:28:22Z DEBUG nsslapd-pluginentryscope:
2014-09-25T19:28:22Z DEBUG dc=greyoak,dc=com
2014-09-25T19:28:22Z DEBUG nsslapd-pluginEnabled:
2014-09-25T19:28:22Z DEBUG on
2014-09-25T19:28:22Z DEBUG nsslapd-pluginId:
2014-09-25T19:28:22Z DEBUG referint
2014-09-25T19:28:22Z DEBUG nsslapd-plugincontainerscope:
2014-09-25T19:28:22Z DEBUG dc=greyoak,dc=com
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg15:
2014-09-25T19:28:22Z DEBUG referint-membership-attr:
2014-09-25T19:28:22Z DEBUG manager
2014-09-25T19:28:22Z DEBUG secretary
2014-09-25T19:28:22Z DEBUG memberuser
2014-09-25T19:28:22Z DEBUG memberhost
2014-09-25T19:28:22Z DEBUG sourcehost
2014-09-25T19:28:22Z DEBUG memberservice
2014-09-25T19:28:22Z DEBUG managedby
2014-09-25T19:28:22Z DEBUG memberallowcmd
2014-09-25T19:28:22Z DEBUG memberdenycmd
2014-09-25T19:28:22Z DEBUG ipasudorunas
2014-09-25T19:28:22Z DEBUG ipasudorunasgroup
2014-09-25T19:28:22Z DEBUG ipatokenradiusconfiglink
2014-09-25T19:28:22Z DEBUG nsslapd-pluginarg14:
2014-09-25T19:28:22Z DEBUG [(1, u'nsslapd-pluginarg16', None), (1,
u'nsslapd-pluginarg7', None), (1, u'nsslapd-pluginarg9', None), (1,
u'nsslapd-pluginarg8', None), (1, u'nsslapd-pluginarg11', None), (1,
u'nsslapd-pluginarg10', None), (1, u'nsslapd-pluginarg13', None), (1,
u'nsslapd-pluginarg12', None), (1, u'nsslapd-pluginarg17', None), (1,
u'nsslapd-pluginarg18', None), (1, u'nsslapd-pluginarg15', None), (2,
u'referint-membership-attr', ['sourcehost', 'memberallowcmd',
'memberdenycmd', 'memberuser', 'managedby', 'manager', 'memberservice',
'ipasudorunas', 'ipasudorunasgroup', 'secretary', 'memberhost',
'ipatokenradiusconfiglink']), (1, u'nsslapd-pluginarg14', None)]
2014-09-25T19:28:22Z DEBUG Live 1, updated 1
2014-09-25T19:28:22Z DEBUG Unhandled LDAPError: OPERATIONS_ERROR:
{'desc': 'Operations error'}
2014-09-25T19:28:22Z ERROR Update failed: Operations error:
Updated rebased patches attached, now with ticket URLs.
I have decided to drop 332-335 for now, since I won't be able to finish
them before the release. We can continue with them later.
--
Jan Cholasta
>From 4233abd78f9aa835ca511ed67c52bb79b049b24a Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 18 Sep 2014 16:28:59 +0200
Subject: [PATCH 01/10] Introduce NSS database /etc/ipa/nssdb
This is the new default NSS database for IPA.
/etc/pki/nssdb is still maintained for backward compatibility.
https://fedorahosted.org/freeipa/ticket/3259
---
freeipa.spec.in | 17 ++++
ipa-client/ipa-install/ipa-client-install | 159 ++++++++++++++++++------------
ipa-client/ipaclient/ipa_certupdate.py | 9 ++
ipalib/rpc.py | 2 +-
ipaplatform/base/paths.py | 2 +-
ipapython/certdb.py | 28 ++++++
6 files changed, 153 insertions(+), 64 deletions(-)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 9171c82..d16a865 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -423,6 +423,7 @@ mkdir -p %{buildroot}/%{_localstatedir}/lib/ipa/backup
mkdir -p %{buildroot}%{_sysconfdir}/ipa/
/bin/touch %{buildroot}%{_sysconfdir}/ipa/default.conf
/bin/touch %{buildroot}%{_sysconfdir}/ipa/ca.crt
+mkdir -p %{buildroot}%{_sysconfdir}/ipa/nssdb
mkdir -p %{buildroot}/%{_localstatedir}/lib/ipa-client/sysrestore
mkdir -p %{buildroot}%{_sysconfdir}/bash_completion.d
install -pm 644 contrib/completion/ipa.bash_completion %{buildroot}%{_sysconfdir}/bash_completion.d/ipa
@@ -537,6 +538,17 @@ if [ $1 -gt 1 ] ; then
/bin/systemctl condrestart ntpd.service 2>&1 || :
fi
fi
+
+ if [ ! -f '/etc/ipa/nssdb/cert8.db' -a $restore -ge 2 ]; then
+ python2 -c 'from ipapython.certdb import create_ipa_nssdb; create_ipa_nssdb()' >/dev/null 2>&1
+ tempfile=$(mktemp)
+ if certutil -L -d /etc/pki/nssdb -n 'IPA CA' -a >"$tempfile" 2>/var/log/ipaupgrade.log; then
+ certutil -A -d /etc/ipa/nssdb -n 'IPA CA' -t CT,C,C -a -i "$tempfile" >/var/log/ipaupgrade.log 2>&1
+ elif certutil -L -d /etc/pki/nssdb -n 'External CA cert' -a >"$tempfile" 2>/var/log/ipaupgrade.log; then
+ certutil -A -d /etc/ipa/nssdb -n 'External CA cert' -t C,, -a -i "$tempfile" >/var/log/ipaupgrade.log 2>&1
+ fi
+ rm -f "$tempfile"
+ fi
fi
%triggerin -n freeipa-client -- openssh-server
@@ -795,6 +807,11 @@ fi
%dir %attr(0755,root,root) %{_sysconfdir}/ipa/
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/default.conf
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt
+%dir %attr(0755,root,root) %{_sysconfdir}/ipa/nssdb
+%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/cert8.db
+%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/key3.db
+%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/secmod.db
+%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/pwdfile.txt
%if ! %{ONLY_CLIENT}
%files tests -f tests-python.list
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 45e8022..ab40cd8 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -46,7 +46,7 @@ try:
from ipaplatform import services
from ipaplatform.paths import paths
from ipapython import ipautil, sysrestore, version, certmonger, ipaldap
- from ipapython import kernel_keyring
+ from ipapython import kernel_keyring, certdb
from ipapython.config import IPAOptionParser
from ipalib import api, errors
from ipalib import x509, certstore
@@ -550,6 +550,15 @@ def uninstall(options, env):
cmonger.service_name, str(e))
# Remove our host cert and CA cert
+ for filename in (os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'),
+ os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'),
+ os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'),
+ os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')):
+ try:
+ os.remove(filename)
+ except OSError, e:
+ root_logger.error("Failed to remove %s: %s", filename, e)
+
purge_ipa_certs({client_nss_nickname, 'IPA CA', 'External CA cert'})
try:
@@ -2524,62 +2533,69 @@ def install(options, env, fstore, statestore):
except ValueError:
pass
- # Add CA certs to a temporary NSS database
+ tmp_nss_dir = tempfile.mkdtemp()
try:
- os.mkdir(paths.IPA_NSSDB_DIR)
- pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
- run([paths.CERTUTIL, '-N',
- '-d', paths.IPA_NSSDB_DIR,
- '-f', pwd_file.name])
-
- ca_certs = x509.load_certificate_list_from_file(CACERT)
- ca_certs = [cert.der_data for cert in ca_certs]
- for i, cert in enumerate(ca_certs):
- run([paths.CERTUTIL, '-A',
- '-d', paths.IPA_NSSDB_DIR,
- '-n', 'CA certificate %d' % (i + 1),
- '-t', 'C,,'],
- stdin=cert)
- except CalledProcessError, e:
- root_logger.info("Failed to add CA to temporary NSS database.")
- return CLIENT_INSTALL_ERROR
+ # Add CA certs to a temporary NSS database
+ try:
+ pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
+ run([paths.CERTUTIL, '-N',
+ '-d', tmp_nss_dir,
+ '-f', pwd_file.name])
- # Now, let's try to connect to the server's XML-RPC interface
- connected = False
- try:
- api.Backend.rpcclient.connect(nss_dir=paths.IPA_NSSDB_DIR)
- connected = True
- root_logger.debug('Try RPC connection')
- api.Backend.rpcclient.forward('ping')
- except errors.KerberosError, e:
- if connected:
- api.Backend.rpcclient.disconnect()
- root_logger.info('Cannot connect to the server due to ' +
- 'Kerberos error: %s. Trying with delegate=True', str(e))
+ ca_certs = x509.load_certificate_list_from_file(CACERT)
+ ca_certs = [cert.der_data for cert in ca_certs]
+ for i, cert in enumerate(ca_certs):
+ run([paths.CERTUTIL, '-A',
+ '-d', tmp_nss_dir,
+ '-n', 'CA certificate %d' % (i + 1),
+ '-t', 'C,,'],
+ stdin=cert)
+ except CalledProcessError, e:
+ root_logger.info("Failed to add CA to temporary NSS database.")
+ return CLIENT_INSTALL_ERROR
+
+ # Now, let's try to connect to the server's RPC interface
+ connected = False
try:
- api.Backend.rpcclient.connect(delegate=True, nss_dir=paths.IPA_NSSDB_DIR)
- root_logger.debug('Try RPC connection')
+ api.Backend.rpcclient.connect(nss_dir=tmp_nss_dir)
+ connected = True
+ root_logger.debug("Try RPC connection")
api.Backend.rpcclient.forward('ping')
+ except errors.KerberosError, e:
+ if connected:
+ api.Backend.rpcclient.disconnect()
+ root_logger.info(
+ "Cannot connect to the server due to Kerberos error: %s. "
+ "Trying with delegate=True", e)
+ try:
+ api.Backend.rpcclient.connect(delegate=True,
+ nss_dir=tmp_nss_dir)
+ root_logger.debug("Try RPC connection")
+ api.Backend.rpcclient.forward('ping')
- root_logger.info('Connection with delegate=True successful')
+ root_logger.info("Connection with delegate=True successful")
- # The remote server is not capable of Kerberos S4U2Proxy delegation
- # This features is implemented in IPA server version 2.2 and higher
- root_logger.warning("Target IPA server has a lower version than " +
- "the enrolled client")
- root_logger.warning("Some capabilities including the ipa " +
- "command capability may not be available")
- except errors.PublicError, e2:
- root_logger.warning(
- 'Second connect with delegate=True also failed: %s', str(e2))
+ # The remote server is not capable of Kerberos S4U2Proxy
+ # delegation. This features is implemented in IPA server
+ # version 2.2 and higher
+ root_logger.warning(
+ "Target IPA server has a lower version than the enrolled "
+ "client")
+ root_logger.warning(
+ "Some capabilities including the ipa command capability "
+ "may not be available")
+ except errors.PublicError, e2:
+ root_logger.warning(
+ "Second connect with delegate=True also failed: %s", e2)
+ root_logger.error(
+ "Cannot connect to the IPA server RPC interface: %s", e2)
+ return CLIENT_INSTALL_ERROR
+ except errors.PublicError, e:
root_logger.error(
- "Cannot connect to the IPA server XML-RPC interface: %s",
- str(e2))
+ "Cannot connect to the server due to generic error: %s", e)
return CLIENT_INSTALL_ERROR
- except errors.PublicError, e:
- root_logger.error(
- 'Cannot connect to the server due to generic error: %s', str(e))
- return CLIENT_INSTALL_ERROR
+ finally:
+ shutil.rmtree(tmp_nss_dir)
# Use the RPC directly so older servers are supported
result = api.Backend.rpcclient.forward(
@@ -2591,14 +2607,38 @@ def install(options, env, fstore, statestore):
if not remote_env['enable_ra']:
disable_ra()
+ # Create IPA NSS database
+ try:
+ certdb.create_ipa_nssdb()
+ except ipautil.CalledProcessError, e:
+ root_logger.error("Failed to create IPA NSS database: %s", e)
+ return CLIENT_INSTALL_ERROR
+
# Get CA certificates from the certificate store
ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm,
remote_env['enable_ra'])
+ ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u))
+ for (c, n, t, u) in ca_certs]
- # Add the CA to the platform-dependant systemwide CA store
+ # Add the CA certificates to the IPA NSS database
+ root_logger.debug("Adding CA certificates to the IPA NSS database.")
+ for cert, nickname, trust_flags in ca_certs_trust:
+ try:
+ run([paths.CERTUTIL,
+ "-A",
+ "-d", paths.IPA_NSSDB_DIR,
+ "-n", nickname,
+ "-t", trust_flags],
+ stdin=cert)
+ except CalledProcessError, e:
+ root_logger.error(
+ "Failed to add %s to the IPA NSS database.", nickname)
+ return CLIENT_INSTALL_ERROR
+
+ # Add the CA certificates to the platform-dependant systemwide CA store
tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)
- # Add the CA to the default NSS database and trust it
+ # Add the CA certificates to the default NSS database
if not purge_ipa_certs():
root_logger.info(
"Failed to remove old IPA certificates from the default NSS "
@@ -2611,12 +2651,10 @@ def install(options, env, fstore, statestore):
root_logger.error("Failed to open /etc/pki/nssdb/ipa.txt: %s", e)
return CLIENT_INSTALL_ERROR
- for cert, nickname, trusted, ext_key_usage in ca_certs:
+ root_logger.debug(
+ "Attempting to add CA certificates to the default NSS database.")
+ for cert, nickname, trust_flags in ca_certs_trust:
try:
- root_logger.debug("Attempting to add CA directly to the "
- "default NSS database.")
- trust_flags = certstore.key_policy_to_trust_flags(
- trusted, True, ext_key_usage)
run([paths.CERTUTIL,
"-A",
"-d", paths.NSS_DB_DIR,
@@ -2624,12 +2662,13 @@ def install(options, env, fstore, statestore):
"-t", trust_flags],
stdin=cert)
except CalledProcessError, e:
- root_logger.info("Failed to add CA to the default NSS database.")
+ root_logger.error(
+ "Failed to add %s to the default NSS database.", nickname)
list_file.close()
return CLIENT_INSTALL_ERROR
else:
- root_logger.info('Added the CA to the default NSS database.')
list_file.write(nickname + '\n')
+ root_logger.info("Added CA certificates to the default NSS database.")
list_file.close()
@@ -2855,7 +2894,3 @@ finally:
os.remove(CCACHE_FILE)
except Exception:
pass
- try:
- shutil.rmtree(paths.IPA_NSSDB_DIR)
- except Exception:
- pass
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index 8e7fe04..57dbf20 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -70,6 +70,15 @@ class CertUpdate(admintool.AdminTool):
def update_client(self, certs):
self.update_file(paths.IPA_CA_CRT, certs)
+ self.update_db(paths.IPA_NSSDB_DIR, certs)
+
+ for nickname in ('IPA CA', 'External CA cert'):
+ try:
+ ipautil.run([paths.CERTUTIL, '-D',
+ '-d', paths.NSS_DB_DIR,
+ '-n', nickname])
+ except ipautil.CalledProcessError, e:
+ pass
self.update_db(paths.NSS_DB_DIR, certs)
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index e7e60f4..5934f0c 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -483,7 +483,7 @@ class SSLTransport(LanguageAwareTransport):
if self._connection and host == self._connection[0]:
return self._connection[1]
- dbdir = getattr(context, 'nss_dir', paths.NSS_DB_DIR)
+ dbdir = getattr(context, 'nss_dir', paths.IPA_NSSDB_DIR)
no_init = self.__nss_initialized(dbdir)
if sys.version_info < (2, 7):
conn = NSSHTTPS(host, 443, dbdir=dbdir, no_init=no_init)
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 6f2a29e..1493918 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -63,7 +63,7 @@ class BasePathNamespace(object):
IPA_DNS_UPDATE_TXT = "/etc/ipa/.dns_update.txt"
IPA_CA_CRT = "/etc/ipa/ca.crt"
IPA_DEFAULT_CONF = "/etc/ipa/default.conf"
- IPA_NSSDB_DIR = "/etc/ipa/.nssdb"
+ IPA_NSSDB_DIR = "/etc/ipa/nssdb"
KRB5_CONF = "/etc/krb5.conf"
KRB5_KEYTAB = "/etc/krb5.keytab"
LDAP_CONF = "/etc/ldap.conf"
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index a858313..426c809 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -17,6 +17,34 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
+import os
+
+from ipaplatform.paths import paths
+from ipapython import ipautil
+
CA_NICKNAME_FMT = "%s IPA CA"
+
+
def get_ca_nickname(realm, format=CA_NICKNAME_FMT):
return format % realm
+
+
+def create_ipa_nssdb():
+ pwdfile = os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')
+
+ ipautil.backup_file(pwdfile)
+ ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'))
+ ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'))
+ ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'))
+
+ with open(pwdfile, 'w') as f:
+ f.write(ipautil.ipa_generate_password(pwd_len=40))
+ os.chmod(pwdfile, 0600)
+
+ ipautil.run([paths.CERTUTIL,
+ "-N",
+ "-d", paths.IPA_NSSDB_DIR,
+ "-f", pwdfile])
+ os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'), 0644)
+ os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'), 0644)
+ os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'), 0644)
--
1.9.3
>From eb9f5135eb6594527696fcbc84a58249f6dc5d33 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 18 Sep 2014 11:19:46 +0200
Subject: [PATCH 02/10] Move NSSDatabase from ipaserver.certs to
ipapython.certdb
https://fedorahosted.org/freeipa/ticket/4416
---
ipapython/certdb.py | 256 +++++++++++++++++++++++++++++++++++++++++++++
ipaserver/install/certs.py | 254 +-------------------------------------------
2 files changed, 257 insertions(+), 253 deletions(-)
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index 426c809..9c1dfc4 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -18,8 +18,14 @@
#
import os
+import re
+import tempfile
+import shutil
+from nss import nss
+from nss.error import NSPRError
from ipaplatform.paths import paths
+from ipapython.ipa_log_manager import root_logger
from ipapython import ipautil
CA_NICKNAME_FMT = "%s IPA CA"
@@ -48,3 +54,253 @@ def create_ipa_nssdb():
os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'), 0644)
os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'), 0644)
os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'), 0644)
+
+
+def find_cert_from_txt(cert, start=0):
+ """
+ Given a cert blob (str) which may or may not contian leading and
+ trailing text, pull out just the certificate part. This will return
+ the FIRST cert in a stream of data.
+
+ Returns a tuple (certificate, last position in cert)
+ """
+ s = cert.find('-----BEGIN CERTIFICATE-----', start)
+ e = cert.find('-----END CERTIFICATE-----', s)
+ if e > 0:
+ e = e + 25
+
+ if s < 0 or e < 0:
+ raise RuntimeError("Unable to find certificate")
+
+ cert = cert[s:e]
+ return (cert, e)
+
+
+class NSSDatabase(object):
+ """A general-purpose wrapper around a NSS cert database
+
+ For permanent NSS databases, pass the cert DB directory to __init__
+
+ For temporary databases, do not pass nssdir, and call close() when done
+ to remove the DB. Alternatively, a NSSDatabase can be used as a
+ context manager that calls close() automatically.
+ """
+ # Traditionally, we used CertDB for our NSS DB operations, but that class
+ # got too tied to IPA server details, killing reusability.
+ # BaseCertDB is a class that knows nothing about IPA.
+ # Generic NSS DB code should be moved here.
+ def __init__(self, nssdir=None):
+ if nssdir is None:
+ self.secdir = tempfile.mkdtemp()
+ self._is_temporary = True
+ else:
+ self.secdir = nssdir
+ self._is_temporary = False
+
+ def close(self):
+ if self._is_temporary:
+ shutil.rmtree(self.secdir)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, tb):
+ self.close()
+
+ def run_certutil(self, args, stdin=None):
+ new_args = [paths.CERTUTIL, "-d", self.secdir]
+ new_args = new_args + args
+ return ipautil.run(new_args, stdin)
+
+ def create_db(self, password_filename):
+ """Create cert DB
+
+ :param password_filename: Name of file containing the database password
+ """
+ self.run_certutil(["-N", "-f", password_filename])
+
+ def list_certs(self):
+ """Return nicknames and cert flags for all certs in the database
+
+ :return: List of (name, trust_flags) tuples
+ """
+ certs, stderr, returncode = self.run_certutil(["-L"])
+ certs = certs.splitlines()
+
+ # FIXME, this relies on NSS never changing the formatting of certutil
+ certlist = []
+ for cert in certs:
+ match = re.match(r'^(.+?)\s+(\w*,\w*,\w*)\s*$', cert)
+ if match:
+ certlist.append(match.groups())
+
+ return tuple(certlist)
+
+ def find_server_certs(self):
+ """Return nicknames and cert flags for server certs in the database
+
+ Server certs have an "u" character in the trust flags.
+
+ :return: List of (name, trust_flags) tuples
+ """
+ server_certs = []
+ for name, flags in self.list_certs():
+ if 'u' in flags:
+ server_certs.append((name, flags))
+
+ return server_certs
+
+ def get_trust_chain(self, nickname):
+ """Return names of certs in a given cert's trust chain
+
+ :param nickname: Name of the cert
+ :return: List of certificate names
+ """
+ root_nicknames = []
+ chain, stderr, returncode = self.run_certutil([
+ "-O", "-n", nickname])
+ chain = chain.splitlines()
+
+ for c in chain:
+ m = re.match('\s*"(.*)" \[.*', c)
+ if m:
+ root_nicknames.append(m.groups()[0])
+
+ return root_nicknames
+
+ def import_pkcs12(self, pkcs12_filename, db_password_filename,
+ pkcs12_passwd=None):
+ args = [paths.PK12UTIL, "-d", self.secdir,
+ "-i", pkcs12_filename,
+ "-k", db_password_filename, '-v']
+ if pkcs12_passwd is not None:
+ pkcs12_passwd = pkcs12_passwd + '\n'
+ args = args + ["-w", paths.DEV_STDIN]
+ try:
+ ipautil.run(args, stdin=pkcs12_passwd)
+ except ipautil.CalledProcessError, e:
+ if e.returncode == 17:
+ raise RuntimeError("incorrect password for pkcs#12 file %s" %
+ pkcs12_filename)
+ elif e.returncode == 10:
+ raise RuntimeError("Failed to open %s" % pkcs12_filename)
+ else:
+ raise RuntimeError("unknown error import pkcs#12 file %s" %
+ pkcs12_filename)
+
+ def trust_root_cert(self, root_nickname, trust_flags=None):
+ if root_nickname[:7] == "Builtin":
+ root_logger.debug(
+ "No need to add trust for built-in root CAs, skipping %s" %
+ root_nickname)
+ else:
+ if trust_flags is None:
+ trust_flags = 'C,,'
+ try:
+ self.run_certutil(["-M", "-n", root_nickname,
+ "-t", trust_flags])
+ except ipautil.CalledProcessError, e:
+ raise RuntimeError(
+ "Setting trust on %s failed" % root_nickname)
+
+ def get_cert(self, nickname, pem=False):
+ args = ['-L', '-n', nickname]
+ if pem:
+ args.append('-a')
+ else:
+ args.append('-r')
+ try:
+ cert, err, returncode = self.run_certutil(args)
+ except ipautil.CalledProcessError:
+ raise RuntimeError("Failed to get %s" % nickname)
+ return cert
+
+ def export_pem_cert(self, nickname, location):
+ """Export the given cert to PEM file in the given location"""
+ cert = self.get_cert(nickname)
+ with open(location, "w+") as fd:
+ fd.write(cert)
+ os.chmod(location, 0444)
+
+ def import_pem_cert(self, nickname, flags, location):
+ """Import a cert form the given PEM file.
+
+ The file must contain exactly one certificate.
+ """
+ try:
+ with open(location) as fd:
+ certs = fd.read()
+ except IOError as e:
+ raise RuntimeError(
+ "Failed to open %s: %s" % (location, e.strerror)
+ )
+
+ cert, st = find_cert_from_txt(certs)
+ self.add_cert(cert, nickname, flags, pem=True)
+
+ try:
+ find_cert_from_txt(certs, st)
+ except RuntimeError:
+ pass
+ else:
+ raise ValueError('%s contains more than one certificate' %
+ location)
+
+ def add_cert(self, cert, nick, flags, pem=False):
+ args = ["-A", "-n", nick, "-t", flags]
+ if pem:
+ args.append("-a")
+ self.run_certutil(args, stdin=cert)
+
+ def delete_cert(self, nick):
+ self.run_certutil(["-D", "-n", nick])
+
+ def verify_server_cert_validity(self, nickname, hostname):
+ """Verify a certificate is valid for a SSL server with given hostname
+
+ Raises a ValueError if the certificate is invalid.
+ """
+ certdb = cert = None
+ if nss.nss_is_initialized():
+ nss.nss_shutdown()
+ nss.nss_init(self.secdir)
+ try:
+ certdb = nss.get_default_certdb()
+ cert = nss.find_cert_from_nickname(nickname)
+ intended_usage = nss.certificateUsageSSLServer
+ try:
+ approved_usage = cert.verify_now(certdb, True, intended_usage)
+ except NSPRError, e:
+ if e.errno != -8102:
+ raise ValueError(e.strerror)
+ approved_usage = 0
+ if not approved_usage & intended_usage:
+ raise ValueError('invalid for a SSL server')
+ if not cert.verify_hostname(hostname):
+ raise ValueError('invalid for server %s' % hostname)
+ finally:
+ del certdb, cert
+ nss.nss_shutdown()
+
+ return None
+
+ def verify_ca_cert_validity(self, nickname):
+ certdb = cert = None
+ if nss.nss_is_initialized():
+ nss.nss_shutdown()
+ nss.nss_init(self.secdir)
+ try:
+ certdb = nss.get_default_certdb()
+ cert = nss.find_cert_from_nickname(nickname)
+ intended_usage = nss.certificateUsageSSLCA
+ try:
+ approved_usage = cert.verify_now(certdb, True, intended_usage)
+ except NSPRError, e:
+ if e.errno != -8102: # SEC_ERROR_INADEQUATE_KEY_USAGE
+ raise ValueError(e.strerror)
+ approved_usage = 0
+ if approved_usage & intended_usage != intended_usage:
+ raise ValueError('invalid for a CA')
+ finally:
+ del certdb, cert
+ nss.nss_shutdown()
diff --git a/ipaserver/install/certs.py b/ipaserver/install/certs.py
index 4d508cd..c2ab59e 100644
--- a/ipaserver/install/certs.py
+++ b/ipaserver/install/certs.py
@@ -19,7 +19,6 @@
import os
import stat
-import re
import sys
import tempfile
import shutil
@@ -28,15 +27,12 @@ import pwd
import base64
from hashlib import sha1
-from nss import nss
-from nss.error import NSPRError
-
from ipapython.ipa_log_manager import root_logger
from ipapython import dogtag
from ipapython import sysrestore
from ipapython import ipautil
from ipapython import certmonger
-from ipapython.certdb import get_ca_nickname
+from ipapython.certdb import get_ca_nickname, find_cert_from_txt, NSSDatabase
from ipapython.dn import DN
from ipalib import pkcs10, x509, api
from ipalib.errors import CertificateOperationError
@@ -48,24 +44,6 @@ from ipaplatform.paths import paths
# where apache can reach
NSS_DIR = paths.HTTPD_ALIAS_DIR
-def find_cert_from_txt(cert, start=0):
- """
- Given a cert blob (str) which may or may not contian leading and
- trailing text, pull out just the certificate part. This will return
- the FIRST cert in a stream of data.
-
- Returns a tuple (certificate, last position in cert)
- """
- s = cert.find('-----BEGIN CERTIFICATE-----', start)
- e = cert.find('-----END CERTIFICATE-----', s)
- if e > 0: e = e + 25
-
- if s < 0 or e < 0:
- raise RuntimeError("Unable to find certificate")
-
- cert = cert[s:e]
- return (cert, e)
-
def get_cert_nickname(cert):
"""
Using the subject from cert come up with a nickname suitable
@@ -83,236 +61,6 @@ def get_cert_nickname(cert):
return (str(dn[0]), dn)
-class NSSDatabase(object):
- """A general-purpose wrapper around a NSS cert database
-
- For permanent NSS databases, pass the cert DB directory to __init__
-
- For temporary databases, do not pass nssdir, and call close() when done
- to remove the DB. Alternatively, a NSSDatabase can be used as a
- context manager that calls close() automatically.
- """
- # Traditionally, we used CertDB for our NSS DB operations, but that class
- # got too tied to IPA server details, killing reusability.
- # BaseCertDB is a class that knows nothing about IPA.
- # Generic NSS DB code should be moved here.
- def __init__(self, nssdir=None):
- if nssdir is None:
- self.secdir = tempfile.mkdtemp()
- self._is_temporary = True
- else:
- self.secdir = nssdir
- self._is_temporary = False
-
- def close(self):
- if self._is_temporary:
- shutil.rmtree(self.secdir)
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, tb):
- self.close()
-
- def run_certutil(self, args, stdin=None):
- new_args = [paths.CERTUTIL, "-d", self.secdir]
- new_args = new_args + args
- return ipautil.run(new_args, stdin)
-
- def create_db(self, password_filename):
- """Create cert DB
-
- :param password_filename: Name of file containing the database password
- """
- self.run_certutil(["-N", "-f", password_filename])
-
- def list_certs(self):
- """Return nicknames and cert flags for all certs in the database
-
- :return: List of (name, trust_flags) tuples
- """
- certs, stderr, returncode = self.run_certutil(["-L"])
- certs = certs.splitlines()
-
- # FIXME, this relies on NSS never changing the formatting of certutil
- certlist = []
- for cert in certs:
- match = re.match(r'^(.+?)\s+(\w*,\w*,\w*)\s*$', cert)
- if match:
- certlist.append(match.groups())
-
- return tuple(certlist)
-
- def find_server_certs(self):
- """Return nicknames and cert flags for server certs in the database
-
- Server certs have an "u" character in the trust flags.
-
- :return: List of (name, trust_flags) tuples
- """
- server_certs = []
- for name, flags in self.list_certs():
- if 'u' in flags:
- server_certs.append((name, flags))
-
- return server_certs
-
- def get_trust_chain(self, nickname):
- """Return names of certs in a given cert's trust chain
-
- :param nickname: Name of the cert
- :return: List of certificate names
- """
- root_nicknames = []
- chain, stderr, returncode = self.run_certutil([
- "-O", "-n", nickname])
- chain = chain.splitlines()
-
- for c in chain:
- m = re.match('\s*"(.*)" \[.*', c)
- if m:
- root_nicknames.append(m.groups()[0])
-
- return root_nicknames
-
- def import_pkcs12(self, pkcs12_filename, db_password_filename,
- pkcs12_passwd=None):
- args = [paths.PK12UTIL, "-d", self.secdir,
- "-i", pkcs12_filename,
- "-k", db_password_filename, '-v']
- if pkcs12_passwd is not None:
- pkcs12_passwd = pkcs12_passwd + '\n'
- args = args + ["-w", paths.DEV_STDIN]
- try:
- ipautil.run(args, stdin=pkcs12_passwd)
- except ipautil.CalledProcessError, e:
- if e.returncode == 17:
- raise RuntimeError("incorrect password for pkcs#12 file %s" %
- pkcs12_filename)
- elif e.returncode == 10:
- raise RuntimeError("Failed to open %s" % pkcs12_filename)
- else:
- raise RuntimeError("unknown error import pkcs#12 file %s" %
- pkcs12_filename)
-
- def trust_root_cert(self, root_nickname, trust_flags=None):
- if root_nickname[:7] == "Builtin":
- root_logger.debug(
- "No need to add trust for built-in root CAs, skipping %s" %
- root_nickname)
- else:
- if trust_flags is None:
- trust_flags = 'C,,'
- try:
- self.run_certutil(["-M", "-n", root_nickname,
- "-t", trust_flags])
- except ipautil.CalledProcessError, e:
- raise RuntimeError(
- "Setting trust on %s failed" % root_nickname)
-
- def get_cert(self, nickname, pem=False):
- args = ['-L', '-n', nickname]
- if pem:
- args.append('-a')
- else:
- args.append('-r')
- try:
- cert, err, returncode = self.run_certutil(args)
- except ipautil.CalledProcessError:
- raise RuntimeError("Failed to get %s" % nickname)
- return cert
-
- def export_pem_cert(self, nickname, location):
- """Export the given cert to PEM file in the given location"""
- cert = self.get_cert(nickname)
- with open(location, "w+") as fd:
- fd.write(cert)
- os.chmod(location, 0444)
-
- def import_pem_cert(self, nickname, flags, location):
- """Import a cert form the given PEM file.
-
- The file must contain exactly one certificate.
- """
- try:
- with open(location) as fd:
- certs = fd.read()
- except IOError as e:
- raise RuntimeError(
- "Failed to open %s: %s" % (location, e.strerror)
- )
-
- cert, st = find_cert_from_txt(certs)
- self.add_cert(cert, nickname, flags, pem=True)
-
- try:
- find_cert_from_txt(certs, st)
- except RuntimeError:
- pass
- else:
- raise ValueError('%s contains more than one certificate' %
- location)
-
- def add_cert(self, cert, nick, flags, pem=False):
- args = ["-A", "-n", nick, "-t", flags]
- if pem:
- args.append("-a")
- self.run_certutil(args, stdin=cert)
-
- def delete_cert(self, nick):
- self.run_certutil(["-D", "-n", nick])
-
- def verify_server_cert_validity(self, nickname, hostname):
- """Verify a certificate is valid for a SSL server with given hostname
-
- Raises a ValueError if the certificate is invalid.
- """
- certdb = cert = None
- if nss.nss_is_initialized():
- nss.nss_shutdown()
- nss.nss_init(self.secdir)
- try:
- certdb = nss.get_default_certdb()
- cert = nss.find_cert_from_nickname(nickname)
- intended_usage = nss.certificateUsageSSLServer
- try:
- approved_usage = cert.verify_now(certdb, True, intended_usage)
- except NSPRError, e:
- if e.errno != -8102:
- raise ValueError(e.strerror)
- approved_usage = 0
- if not approved_usage & intended_usage:
- raise ValueError('invalid for a SSL server')
- if not cert.verify_hostname(hostname):
- raise ValueError('invalid for server %s' % hostname)
- finally:
- del certdb, cert
- nss.nss_shutdown()
-
- return None
-
- def verify_ca_cert_validity(self, nickname):
- certdb = cert = None
- if nss.nss_is_initialized():
- nss.nss_shutdown()
- nss.nss_init(self.secdir)
- try:
- certdb = nss.get_default_certdb()
- cert = nss.find_cert_from_nickname(nickname)
- intended_usage = nss.certificateUsageSSLCA
- try:
- approved_usage = cert.verify_now(certdb, True, intended_usage)
- except NSPRError, e:
- if e.errno != -8102: # SEC_ERROR_INADEQUATE_KEY_USAGE
- raise ValueError(e.strerror)
- approved_usage = 0
- if approved_usage & intended_usage != intended_usage:
- raise ValueError('invalid for a CA')
- finally:
- del certdb, cert
- nss.nss_shutdown()
-
-
class CertDB(object):
"""An IPA-server-specific wrapper around NSS
--
1.9.3
>From 4a6c9d1ba218099e0cc7aaf7d1cda64e576845d2 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 18 Sep 2014 11:42:14 +0200
Subject: [PATCH 03/10] Add NSSDatabase.has_nickname for checking nickname
presence in a NSS DB
https://fedorahosted.org/freeipa/ticket/4416
---
ipapython/certdb.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index 9c1dfc4..a6f00d3 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -215,6 +215,15 @@ class NSSDatabase(object):
raise RuntimeError("Failed to get %s" % nickname)
return cert
+ def has_nickname(self, nickname):
+ try:
+ self.get_cert(nickname)
+ except RuntimeError:
+ # This might be error other than "nickname not found". Beware.
+ return False
+ else:
+ return True
+
def export_pem_cert(self, nickname, location):
"""Export the given cert to PEM file in the given location"""
cert = self.get_cert(nickname)
--
1.9.3
>From fee7267b21e5ca571c546aed98b4c1a1a614c105 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 18 Sep 2014 12:00:15 +0200
Subject: [PATCH 04/10] Use NSSDatabase instead of direct certutil calls in
client code
https://fedorahosted.org/freeipa/ticket/4416
---
ipa-client/ipa-install/ipa-client-install | 50 ++++++++-----------------------
ipa-client/ipaclient/ipa_certupdate.py | 14 ++++-----
ipapython/certdb.py | 20 ++++++-------
3 files changed, 26 insertions(+), 58 deletions(-)
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index ab40cd8..22085ec 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -226,14 +226,6 @@ def logging_setup(options):
def log_service_error(name, action, error):
root_logger.error("%s failed to %s: %s", name, action, str(error))
-def nickname_exists(nickname):
- (sout, serr, returncode) = run([paths.CERTUTIL, "-L", "-d", paths.NSS_DB_DIR, "-n", nickname], raiseonerr=False)
-
- if returncode == 0:
- return True
- else:
- return False
-
def purge_ipa_certs(additional=[]):
filename = paths.NSSDB_IPA_TXT
if file_exists(filename):
@@ -258,12 +250,11 @@ def purge_ipa_certs(additional=[]):
if nickname:
nicknames.add(nickname)
+ sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
for nickname in nicknames:
- while nickname_exists(nickname):
+ while sys_db.has_nickname(nickname):
try:
- run([paths.CERTUTIL, "-D",
- "-d", paths.NSS_DB_DIR,
- "-n", nickname])
+ sys_db.delete_cert(nickname)
except Exception, e:
root_logger.error(
"Failed to remove %s from /etc/pki/nssdb: %s", nickname, e)
@@ -2533,23 +2524,16 @@ def install(options, env, fstore, statestore):
except ValueError:
pass
- tmp_nss_dir = tempfile.mkdtemp()
- try:
+ with certdb.NSSDatabase() as tmp_db:
# Add CA certs to a temporary NSS database
try:
pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
- run([paths.CERTUTIL, '-N',
- '-d', tmp_nss_dir,
- '-f', pwd_file.name])
+ tmp_db.create_db(pwd_file.name)
ca_certs = x509.load_certificate_list_from_file(CACERT)
ca_certs = [cert.der_data for cert in ca_certs]
for i, cert in enumerate(ca_certs):
- run([paths.CERTUTIL, '-A',
- '-d', tmp_nss_dir,
- '-n', 'CA certificate %d' % (i + 1),
- '-t', 'C,,'],
- stdin=cert)
+ tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), 'C,,')
except CalledProcessError, e:
root_logger.info("Failed to add CA to temporary NSS database.")
return CLIENT_INSTALL_ERROR
@@ -2557,7 +2541,7 @@ def install(options, env, fstore, statestore):
# Now, let's try to connect to the server's RPC interface
connected = False
try:
- api.Backend.rpcclient.connect(nss_dir=tmp_nss_dir)
+ api.Backend.rpcclient.connect(nss_dir=tmp_db.secdir)
connected = True
root_logger.debug("Try RPC connection")
api.Backend.rpcclient.forward('ping')
@@ -2569,7 +2553,7 @@ def install(options, env, fstore, statestore):
"Trying with delegate=True", e)
try:
api.Backend.rpcclient.connect(delegate=True,
- nss_dir=tmp_nss_dir)
+ nss_dir=tmp_db.secdir)
root_logger.debug("Try RPC connection")
api.Backend.rpcclient.forward('ping')
@@ -2594,8 +2578,6 @@ def install(options, env, fstore, statestore):
root_logger.error(
"Cannot connect to the server due to generic error: %s", e)
return CLIENT_INSTALL_ERROR
- finally:
- shutil.rmtree(tmp_nss_dir)
# Use the RPC directly so older servers are supported
result = api.Backend.rpcclient.forward(
@@ -2622,14 +2604,10 @@ def install(options, env, fstore, statestore):
# Add the CA certificates to the IPA NSS database
root_logger.debug("Adding CA certificates to the IPA NSS database.")
+ ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
for cert, nickname, trust_flags in ca_certs_trust:
try:
- run([paths.CERTUTIL,
- "-A",
- "-d", paths.IPA_NSSDB_DIR,
- "-n", nickname,
- "-t", trust_flags],
- stdin=cert)
+ ipa_db.add_cert(cert, nickname, trust_flags)
except CalledProcessError, e:
root_logger.error(
"Failed to add %s to the IPA NSS database.", nickname)
@@ -2653,14 +2631,10 @@ def install(options, env, fstore, statestore):
root_logger.debug(
"Attempting to add CA certificates to the default NSS database.")
+ sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
for cert, nickname, trust_flags in ca_certs_trust:
try:
- run([paths.CERTUTIL,
- "-A",
- "-d", paths.NSS_DB_DIR,
- "-n", nickname,
- "-t", trust_flags],
- stdin=cert)
+ sys_db.add_cert(cert, nickname, trust_flags)
except CalledProcessError, e:
root_logger.error(
"Failed to add %s to the default NSS database.", nickname)
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index 57dbf20..f7b0e29 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -22,7 +22,7 @@ import tempfile
import shutil
from ipapython import (admintool, ipautil, ipaldap, sysrestore, dogtag,
- certmonger)
+ certmonger, certdb)
from ipaplatform import services
from ipaplatform.paths import paths
from ipaplatform.tasks import tasks
@@ -72,11 +72,10 @@ class CertUpdate(admintool.AdminTool):
self.update_file(paths.IPA_CA_CRT, certs)
self.update_db(paths.IPA_NSSDB_DIR, certs)
+ sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
for nickname in ('IPA CA', 'External CA cert'):
try:
- ipautil.run([paths.CERTUTIL, '-D',
- '-d', paths.NSS_DB_DIR,
- '-n', nickname])
+ sys_db.delete_cert(nickname)
except ipautil.CalledProcessError, e:
pass
@@ -165,15 +164,12 @@ class CertUpdate(admintool.AdminTool):
self.log.error("failed to update %s: %s", filename, e)
def update_db(self, path, certs):
+ db = certdb.NSSDatabase(path)
for cert, nickname, trusted, eku in certs:
trust_flags = certstore.key_policy_to_trust_flags(
trusted, True, eku)
try:
- ipautil.run([paths.CERTUTIL, '-A',
- '-d', path,
- '-n', nickname,
- '-t', trust_flags],
- stdin=cert)
+ db.add_cert(cert, nickname, trust_flags)
except ipautil.CalledProcessError, e:
self.log.error(
"failed to update %s in %s: %s", nickname, path, e)
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index a6f00d3..56cbe36 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -36,24 +36,22 @@ def get_ca_nickname(realm, format=CA_NICKNAME_FMT):
def create_ipa_nssdb():
- pwdfile = os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')
+ db = NSSDatabase(paths.IPA_NSSDB_DIR)
+ pwdfile = os.path.join(db.secdir, 'pwdfile.txt')
ipautil.backup_file(pwdfile)
- ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'))
- ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'))
- ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'))
+ ipautil.backup_file(os.path.join(db.secdir, 'cert8.db'))
+ ipautil.backup_file(os.path.join(db.secdir, 'key3.db'))
+ ipautil.backup_file(os.path.join(db.secdir, 'secmod.db'))
with open(pwdfile, 'w') as f:
f.write(ipautil.ipa_generate_password(pwd_len=40))
os.chmod(pwdfile, 0600)
- ipautil.run([paths.CERTUTIL,
- "-N",
- "-d", paths.IPA_NSSDB_DIR,
- "-f", pwdfile])
- os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'), 0644)
- os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'), 0644)
- os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'), 0644)
+ db.create_db(pwdfile)
+ os.chmod(os.path.join(db.secdir, 'cert8.db'), 0644)
+ os.chmod(os.path.join(db.secdir, 'key3.db'), 0644)
+ os.chmod(os.path.join(db.secdir, 'secmod.db'), 0644)
def find_cert_from_txt(cert, start=0):
--
1.9.3
>From ad4e508520c83a2d201b2454f538dc25e6fc94de Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Mon, 22 Sep 2014 11:13:15 +0200
Subject: [PATCH 05/10] Use /etc/ipa/nssdb to get nicknames of IPA certs
installed in /etc/pki/nssdb
Previously a list of nicknames was kept in /etc/pki/nssdb/ipa.txt. The file
is removed now.
https://fedorahosted.org/freeipa/ticket/3259
---
ipa-client/ipa-install/ipa-client-install | 78 +++++++++----------------------
ipa-client/ipaclient/ipa_certupdate.py | 59 +++++++++--------------
ipaplatform/base/paths.py | 1 -
3 files changed, 42 insertions(+), 96 deletions(-)
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 22085ec..2e59df9 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -226,41 +226,6 @@ def logging_setup(options):
def log_service_error(name, action, error):
root_logger.error("%s failed to %s: %s", name, action, str(error))
-def purge_ipa_certs(additional=[]):
- filename = paths.NSSDB_IPA_TXT
- if file_exists(filename):
- try:
- with open(filename, 'r') as f:
- lines = f.readlines()
- except IOError, e:
- root_logger.error("Failed to open %s: %s", filename, e)
- return False
- finally:
- try:
- os.unlink(filename)
- except OSError, e:
- root_logger.error("Failed to remove %s: %s", filename, e)
- return False
- else:
- lines = []
-
- nicknames = set(additional)
- for line in lines:
- nickname = line.strip()
- if nickname:
- nicknames.add(nickname)
-
- sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
- for nickname in nicknames:
- while sys_db.has_nickname(nickname):
- try:
- sys_db.delete_cert(nickname)
- except Exception, e:
- root_logger.error(
- "Failed to remove %s from /etc/pki/nssdb: %s", nickname, e)
-
- return True
-
def cert_summary(msg, certs, indent=' '):
if msg:
s = '%s\n' % msg
@@ -541,16 +506,32 @@ def uninstall(options, env):
cmonger.service_name, str(e))
# Remove our host cert and CA cert
- for filename in (os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'),
- os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'),
- os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'),
- os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')):
+ ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
+ try:
+ ipa_certs = ipa_db.list_certs()
+ except CalledProcessError, e:
+ root_logger.error(
+ "Failed to list certificates in %s: %s", ipa_db.secdir, e)
+ ipa_certs = []
+
+ for filename in (os.path.join(ipa_db.secdir, 'cert8.db'),
+ os.path.join(ipa_db.secdir, 'key3.db'),
+ os.path.join(ipa_db.secdir, 'secmod.db'),
+ os.path.join(ipa_db.secdir, 'pwdfile.txt')):
try:
os.remove(filename)
except OSError, e:
root_logger.error("Failed to remove %s: %s", filename, e)
- purge_ipa_certs({client_nss_nickname, 'IPA CA', 'External CA cert'})
+ sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
+ for nickname, trust_flags in ipa_certs:
+ while sys_db.has_nickname(nickname):
+ try:
+ sys_db.delete_cert(nickname)
+ except Exception, e:
+ root_logger.error("Failed to remove %s from %s: %s",
+ nickname, sys_db.secdir, e)
+ break
try:
cmonger.stop()
@@ -2617,18 +2598,6 @@ def install(options, env, fstore, statestore):
tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)
# Add the CA certificates to the default NSS database
- if not purge_ipa_certs():
- root_logger.info(
- "Failed to remove old IPA certificates from the default NSS "
- "database.")
- return CLIENT_INSTALL_ERROR
-
- try:
- list_file = open(paths.NSSDB_IPA_TXT, 'w')
- except IOError, e:
- root_logger.error("Failed to open /etc/pki/nssdb/ipa.txt: %s", e)
- return CLIENT_INSTALL_ERROR
-
root_logger.debug(
"Attempting to add CA certificates to the default NSS database.")
sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
@@ -2638,14 +2607,9 @@ def install(options, env, fstore, statestore):
except CalledProcessError, e:
root_logger.error(
"Failed to add %s to the default NSS database.", nickname)
- list_file.close()
return CLIENT_INSTALL_ERROR
- else:
- list_file.write(nickname + '\n')
root_logger.info("Added CA certificates to the default NSS database.")
- list_file.close()
-
if not options.on_master:
client_dns(cli_server[0], hostname, options.dns_updates)
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index f7b0e29..8259755 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -70,49 +70,32 @@ class CertUpdate(admintool.AdminTool):
def update_client(self, certs):
self.update_file(paths.IPA_CA_CRT, certs)
- self.update_db(paths.IPA_NSSDB_DIR, certs)
+ ipa_db = certdb.NSSDatabase(paths.IPA_NSSDB_DIR)
sys_db = certdb.NSSDatabase(paths.NSS_DB_DIR)
- for nickname in ('IPA CA', 'External CA cert'):
- try:
- sys_db.delete_cert(nickname)
- except ipautil.CalledProcessError, e:
- pass
-
- self.update_db(paths.NSS_DB_DIR, certs)
- new_nicknames = set(c[1] for c in certs)
- old_nicknames = set()
- if ipautil.file_exists(paths.NSSDB_IPA_TXT):
- try:
- list_file = open(paths.NSSDB_IPA_TXT, 'r')
- except IOError, e:
- self.log.error("failed to open %s: %s", paths.NSSDB_IPA_TXT, e)
- else:
+ # Remove IPA certs from /etc/pki/nssdb
+ for nickname, trust_flags in ipa_db.list_certs():
+ while sys_db.has_nickname(nickname):
try:
- lines = list_file.readlines()
- except IOError, e:
- self.log.error(
- "failed to read %s: %s", paths.NSSDB_IPA_TXT, e)
- else:
- for line in lines:
- nickname = line.strip()
- if nickname:
- old_nicknames.add(nickname)
- list_file.close()
- if new_nicknames != old_nicknames:
- try:
- list_file = open(paths.NSSDB_IPA_TXT, 'w')
- except IOError, e:
- self.log.error("failed to open %s: %s", paths.NSSDB_IPA_TXT, e)
- else:
+ sys_db.delete_cert(nickname)
+ except ipautil.CalledProcessError, e:
+ self.log.error("Failed to remove %s from %s: %s",
+ nickname, sys_db.secdir, e)
+ break
+
+ # Remove old IPA certs from /etc/ipa/nssdb
+ for nickname in ('IPA CA', 'External CA cert'):
+ while ipa_db.has_nickname(nickname):
try:
- for nickname in new_nicknames:
- list_file.write(nickname + '\n')
- except IOError, e:
- self.log.error(
- "failed to write %s: %s", paths.NSSDB_IPA_TXT, e)
- list_file.close()
+ ipa_db.delete_cert(nickname)
+ except ipautil.CalledProcessError, e:
+ self.log.error("Failed to remove %s from %s: %s",
+ nickname, ipa_db.secdir, e)
+ break
+
+ self.update_db(ipa_db.secdir, certs)
+ self.update_db(sys_db.secdir, certs)
tasks.remove_ca_certs_from_systemwide_ca_store()
tasks.insert_ca_certs_into_systemwide_ca_store(certs)
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 1493918..5f73d85 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -85,7 +85,6 @@ class BasePathNamespace(object):
NSSDB_CERT8_DB = "/etc/pki/nssdb/cert8.db"
NSSDB_KEY3_DB = "/etc/pki/nssdb/key3.db"
NSSDB_SECMOD_DB = "/etc/pki/nssdb/secmod.db"
- NSSDB_IPA_TXT = "/etc/pki/nssdb/ipa.txt"
PKI_TOMCAT = "/etc/pki/pki-tomcat"
PKI_TOMCAT_ALIAS_DIR = "/etc/pki/pki-tomcat/alias/"
PKI_TOMCAT_PASSWORD_CONF = "/etc/pki/pki-tomcat/password.conf"
--
1.9.3
>From 9aaeaa84fb140ea6bd5ecc21cec25fdb346b5142 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 18 Sep 2014 10:52:56 +0200
Subject: [PATCH 06/10] Check if IPA client is configured in ipa-certupdate
https://fedorahosted.org/freeipa/ticket/4460
---
ipa-client/ipaclient/ipa_certupdate.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index 8259755..c25dcae 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -41,6 +41,12 @@ class CertUpdate(admintool.AdminTool):
super(CertUpdate, self).validate_options(needs_root=True)
def run(self):
+ fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
+ if (not fstore.has_files() and
+ not os.path.exists(paths.IPA_DEFAULT_CONF)):
+ raise admintool.ScriptError(
+ "IPA client is not configured on this system.")
+
api.bootstrap(context='cli_installer')
api.finalize()
--
1.9.3
>From d88e4ec5a8fa291e95d108c309a83c1f19ab9e1a Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Thu, 18 Sep 2014 11:15:49 +0200
Subject: [PATCH 07/10] Get server hostname from jsonrpc_uri in ipa-certupdate
https://fedorahosted.org/freeipa/ticket/3259
---
ipa-client/ipaclient/ipa_certupdate.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index c25dcae..fd6c80d 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -20,6 +20,7 @@
import os
import tempfile
import shutil
+import urlparse
from ipapython import (admintool, ipautil, ipaldap, sysrestore, dogtag,
certmonger, certdb)
@@ -50,10 +51,7 @@ class CertUpdate(admintool.AdminTool):
api.bootstrap(context='cli_installer')
api.finalize()
- try:
- server = api.env.server
- except AttributeError:
- server = api.env.host
+ server = urlparse.urlsplit(api.env.jsonrpc_uri).hostname
ldap = ipaldap.IPAdmin(server)
tmpdir = tempfile.mkdtemp(prefix="tmp-")
--
1.9.3
>From 29bc4238d022b69a3272060c4cb5f2cb60d408d1 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 17 Sep 2014 15:04:11 +0200
Subject: [PATCH 08/10] Remove ipa-ca.crt from systemwide CA store on client
uninstall and cert update
The file was used by previous versions of IPA to provide the IPA CA certificate
to p11-kit and has since been obsoleted by ipa.p11-kit, a file which contains
all the CA certificates and associated trust policy from the LDAP certificate
store.
Since p11-kit is hooked into /etc/httpd/alias, ipa-ca.crt must be removed to
prevent certificate import failures in installer code.
Also add ipa.p11-kit to the files owned by the freeipa-python package.
https://fedorahosted.org/freeipa/ticket/3259
---
freeipa.spec.in | 1 +
ipaplatform/base/paths.py | 1 +
ipaplatform/fedora/tasks.py | 38 ++++++++++++++++++++++++++++----------
3 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/freeipa.spec.in b/freeipa.spec.in
index d16a865..99cd6df 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -812,6 +812,7 @@ fi
%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/key3.db
%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/secmod.db
%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/pwdfile.txt
+%ghost %config(noreplace) %{_sysconfdir}/pki/ca-trust/source/ipa.p11-kit
%if ! %{ONLY_CLIENT}
%files tests -f tests-python.list
diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py
index 5f73d85..baaa109 100644
--- a/ipaplatform/base/paths.py
+++ b/ipaplatform/base/paths.py
@@ -80,6 +80,7 @@ class BasePathNamespace(object):
PAM_LDAP_CONF = "/etc/pam_ldap.conf"
PASSWD = "/etc/passwd"
ETC_PKI_CA_DIR = "/etc/pki-ca"
+ SYSTEMWIDE_CA_STORE = "/etc/pki/ca-trust/source/anchors/"
IPA_P11_KIT = "/etc/pki/ca-trust/source/ipa.p11-kit"
NSS_DB_DIR = "/etc/pki/nssdb"
NSSDB_CERT8_DB = "/etc/pki/nssdb/cert8.db"
diff --git a/ipaplatform/fedora/tasks.py b/ipaplatform/fedora/tasks.py
index 9f4a76b..351f523 100644
--- a/ipaplatform/fedora/tasks.py
+++ b/ipaplatform/fedora/tasks.py
@@ -158,6 +158,16 @@ class FedoraTaskNamespace(BaseTaskNamespace):
auth_config.execute()
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
+ new_cacert_path = os.path.join(paths.SYSTEMWIDE_CA_STORE, 'ipa-ca.crt')
+
+ if os.path.exists(new_cacert_path):
+ try:
+ os.remove(new_cacert_path)
+ except OSError, e:
+ root_logger.error(
+ "Could not remove %s: %s", new_cacert_path, e)
+ return False
+
new_cacert_path = paths.IPA_P11_KIT
try:
@@ -250,25 +260,33 @@ class FedoraTaskNamespace(BaseTaskNamespace):
return False
def remove_ca_certs_from_systemwide_ca_store(self):
- new_cacert_path = paths.IPA_P11_KIT
+ ipa_ca_crt = os.path.join(paths.SYSTEMWIDE_CA_STORE, 'ipa-ca.crt')
+ update = False
# Remove CA cert from systemwide store
- if os.path.exists(new_cacert_path):
+ for new_cacert_path in (paths.IPA_P11_KIT, ipa_ca_crt):
+ if not os.path.exists(new_cacert_path):
+ continue
try:
os.remove(new_cacert_path)
- ipautil.run([paths.UPDATE_CA_TRUST])
except OSError, e:
- root_logger.error('Could not remove: %s, %s'
- % (new_cacert_path, str(e)))
- return False
+ root_logger.error(
+ "Could not remove %s: %s", new_cacert_path, e)
+ else:
+ update = True
+
+ if update:
+ try:
+ ipautil.run([paths.UPDATE_CA_TRUST])
except CalledProcessError, e:
- root_logger.error('Could not update systemwide CA trust '
- 'database: %s' % str(e))
+ root_logger.error(
+ "Could not update systemwide CA trust database: %s", e)
return False
else:
- root_logger.info('Systemwide CA database updated.')
+ root_logger.info("Systemwide CA database updated.")
+ return True
- return True
+ return False
def backup_and_replace_hostname(self, fstore, statestore, hostname):
old_hostname = socket.gethostname()
--
1.9.3
>From f9338db90b45ff751b8c61ce8be4964f8245b1f9 Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Tue, 16 Sep 2014 10:34:57 +0200
Subject: [PATCH 09/10] Fix certmonger.wait_for_request
https://fedorahosted.org/freeipa/ticket/4558
---
ipapython/certmonger.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ipapython/certmonger.py b/ipapython/certmonger.py
index 85b0e9a..bcfafda 100644
--- a/ipapython/certmonger.py
+++ b/ipapython/certmonger.py
@@ -474,7 +474,7 @@ def check_state(dirs):
def wait_for_request(request_id, timeout=120):
for i in range(0, timeout, 5):
- state = get_request_value(request_id, 'state').strip()
+ state = get_request_value(request_id, 'status')
root_logger.debug("certmonger request is in state %r", state)
if state in ('CA_REJECTED', 'CA_UNREACHABLE', 'CA_UNCONFIGURED',
'NEED_GUIDANCE', 'NEED_CA', 'MONITORING'):
--
1.9.3
>From 04a207885e7bd98204a9e316ee8c6205662b6cac Mon Sep 17 00:00:00 2001
From: Jan Cholasta <jchol...@redhat.com>
Date: Wed, 24 Sep 2014 19:22:59 +0200
Subject: [PATCH 10/10] Fix certmonger search for the CA cert in ipa-certupdate
and ipa-cacert-manage
The search criteria did not include the CA agent name.
https://fedorahosted.org/freeipa/ticket/3259
---
ipa-client/ipaclient/ipa_certupdate.py | 1 +
ipaserver/install/ipa_cacert_manage.py | 7 +++++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/ipa-client/ipaclient/ipa_certupdate.py b/ipa-client/ipaclient/ipa_certupdate.py
index fd6c80d..ff16b9b 100644
--- a/ipa-client/ipaclient/ipa_certupdate.py
+++ b/ipa-client/ipaclient/ipa_certupdate.py
@@ -120,6 +120,7 @@ class CertUpdate(admintool.AdminTool):
criteria = {
'cert-database': dogtag_constants.ALIAS_DIR,
'cert-nickname': nickname,
+ 'ca-name': 'dogtag-ipa-ca-renew-agent',
}
request_id = certmonger.get_request_id(criteria)
if request_id is not None:
diff --git a/ipaserver/install/ipa_cacert_manage.py b/ipaserver/install/ipa_cacert_manage.py
index c681261..155aa00 100644
--- a/ipaserver/install/ipa_cacert_manage.py
+++ b/ipaserver/install/ipa_cacert_manage.py
@@ -153,8 +153,11 @@ class CACertManage(admintool.AdminTool):
raise admintool.ScriptError("CA is not configured on this system")
nss_dir = ca.dogtag_constants.ALIAS_DIR
- criteria = {'cert-database': nss_dir,
- 'cert-nickname': self.cert_nickname}
+ criteria = {
+ 'cert-database': nss_dir,
+ 'cert-nickname': self.cert_nickname,
+ 'ca-name': 'dogtag-ipa-ca-renew-agent',
+ }
self.request_id = certmonger.get_request_id(criteria)
if self.request_id is None:
raise admintool.ScriptError(
--
1.9.3
_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel