Imported Upstream version 4.8.10
This commit is contained in:
@@ -17,39 +17,117 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from ipaserver.install.plugins import MIDDLE
|
||||
from ipaserver.install.plugins.baseupdate import PostUpdate
|
||||
from ipaserver.install.dsinstance import realm_to_serverid, config_dirname
|
||||
from ipaserver.install import certs
|
||||
from ipalib import api
|
||||
from ipapython.dn import DN
|
||||
import base64
|
||||
import logging
|
||||
|
||||
class update_upload_cacrt(PostUpdate):
|
||||
from ipalib.install import certstore
|
||||
from ipaserver.install import certs, dsinstance
|
||||
from ipapython.ipaldap import realm_to_serverid
|
||||
from ipalib import Registry, errors
|
||||
from ipalib import Updater
|
||||
from ipapython import certdb
|
||||
from ipapython.dn import DN
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
register = Registry()
|
||||
|
||||
|
||||
@register()
|
||||
class update_upload_cacrt(Updater):
|
||||
"""
|
||||
Upload public CA certificate to LDAP
|
||||
"""
|
||||
order=MIDDLE
|
||||
|
||||
def execute(self, **options):
|
||||
ldap = self.obj.backend
|
||||
ipa_config = ldap.get_ipa_config()
|
||||
subject_base = ipa_config.get('ipacertificatesubjectbase', [None])[0]
|
||||
dirname = config_dirname(realm_to_serverid(api.env.realm))
|
||||
certdb = certs.CertDB(api.env.realm, nssdir=dirname, subject_base=subject_base)
|
||||
serverid = realm_to_serverid(self.api.env.realm)
|
||||
db = certs.CertDB(self.api.env.realm,
|
||||
nssdir=dsinstance.config_dirname(serverid))
|
||||
ca_cert = None
|
||||
|
||||
dercert = certdb.get_cert_from_db(certdb.cacert_name, pem=False)
|
||||
ca_enabled = self.api.Command.ca_is_enabled()['result']
|
||||
if ca_enabled:
|
||||
ca_nickname = certdb.get_ca_nickname(self.api.env.realm)
|
||||
ca_subject = certstore.get_ca_subject(
|
||||
self.api.Backend.ldap2,
|
||||
self.api.env.container_ca,
|
||||
self.api.env.basedn)
|
||||
else:
|
||||
ca_nickname = None
|
||||
server_certs = db.find_server_certs()
|
||||
if server_certs:
|
||||
ca_chain = db.find_root_cert(server_certs[0][0])[:-1]
|
||||
if ca_chain:
|
||||
ca_nickname = ca_chain[-1]
|
||||
|
||||
updates = {}
|
||||
dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'), api.env.basedn)
|
||||
ldap = self.api.Backend.ldap2
|
||||
|
||||
cacrt_entry = ['objectclass:nsContainer',
|
||||
'objectclass:pkiCA',
|
||||
'cn:CAcert',
|
||||
'cACertificate;binary:%s' % dercert,
|
||||
]
|
||||
updates[dn] = {'dn': dn, 'default': cacrt_entry}
|
||||
for nickname, trust_flags in db.list_certs():
|
||||
if trust_flags.has_key:
|
||||
continue
|
||||
cert = db.get_cert_from_db(nickname)
|
||||
subject = cert.subject
|
||||
if ca_enabled and subject == ca_subject:
|
||||
# When ca is enabled, we can have the IPA CA cert stored
|
||||
# in the nss db with a different nickname (for instance
|
||||
# when the server was installed with --subject to
|
||||
# customize the CA cert subject), but it must always be
|
||||
# stored in LDAP with the DN cn=$DOMAIN IPA CA
|
||||
# This is why we check the subject instead of the nickname here
|
||||
nickname = ca_nickname
|
||||
trust_flags = certdb.IPA_CA_TRUST_FLAGS
|
||||
trust, _ca, eku = certstore.trust_flags_to_key_policy(trust_flags)
|
||||
|
||||
return (False, True, [updates])
|
||||
dn = DN(('cn', nickname), ('cn', 'certificates'), ('cn', 'ipa'),
|
||||
('cn','etc'), self.api.env.basedn)
|
||||
entry = ldap.make_entry(dn)
|
||||
|
||||
api.register(update_upload_cacrt)
|
||||
try:
|
||||
certstore.init_ca_entry(entry, cert, nickname, trust, eku)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to create entry for %s: %s",
|
||||
nickname, e)
|
||||
continue
|
||||
if nickname == ca_nickname:
|
||||
ca_cert = cert
|
||||
config = entry.setdefault('ipaConfigString', [])
|
||||
if ca_enabled:
|
||||
config.append('ipaCa')
|
||||
config.append('compatCA')
|
||||
|
||||
try:
|
||||
ldap.add_entry(entry)
|
||||
except errors.DuplicateEntry:
|
||||
if nickname == ca_nickname and ca_enabled:
|
||||
try:
|
||||
ldap.update_entry(entry)
|
||||
except errors.EmptyModlist:
|
||||
pass
|
||||
|
||||
if ca_cert:
|
||||
dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'),
|
||||
self.api.env.basedn)
|
||||
try:
|
||||
entry = ldap.get_entry(dn)
|
||||
except errors.NotFound:
|
||||
entry = ldap.make_entry(dn)
|
||||
entry['objectclass'] = ['nsContainer', 'pkiCA']
|
||||
entry.single_value['cn'] = 'CAcert'
|
||||
entry.single_value['cACertificate;binary'] = ca_cert
|
||||
ldap.add_entry(entry)
|
||||
else:
|
||||
force_write = False
|
||||
try:
|
||||
_cert_bin = entry['cACertificate;binary']
|
||||
except ValueError:
|
||||
# BZ 1644874
|
||||
# sometimes the cert is badly stored, twice encoded
|
||||
# force write to fix the value
|
||||
logger.debug('Fixing the value of cACertificate;binary '
|
||||
'in entry %s', entry.dn)
|
||||
force_write = True
|
||||
|
||||
if force_write or b'' in entry['cACertificate;binary']:
|
||||
entry.single_value['cACertificate;binary'] = ca_cert
|
||||
ldap.update_entry(entry)
|
||||
|
||||
return False, []
|
||||
|
||||
Reference in New Issue
Block a user