diff options
Diffstat (limited to 'ipalib')
-rw-r--r-- | ipalib/constants.py | 4 | ||||
-rw-r--r-- | ipalib/plugins/cert.py | 53 | ||||
-rw-r--r-- | ipalib/plugins/service.py | 21 |
3 files changed, 67 insertions, 11 deletions
diff --git a/ipalib/constants.py b/ipalib/constants.py index ed396de0a..9aff5e269 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -112,7 +112,8 @@ DEFAULT_CONFIG = ( # CA plugin: ('ca_host', object), # Set in Env._finalize_core() ('ca_port', 9180), - ('ca_ssl_port', 9443), + ('ca_agent_port', 9443), + ('ca_ee_port', 9444), # Special CLI: ('prompt_all', False), @@ -120,6 +121,7 @@ DEFAULT_CONFIG = ( # Enable certain optional plugins: ('enable_ra', False), + ('ra_plugin', 'selfsign'), # ******************************************************** # The remaining keys are never set from the values here! diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py index e38ec1812..1681a22f6 100644 --- a/ipalib/plugins/cert.py +++ b/ipalib/plugins/cert.py @@ -30,6 +30,24 @@ from ipalib import Command, Str, Int, Bytes, Flag from ipalib import errors from ipalib.plugins.virtual import * import base64 +from OpenSSL import crypto + +def get_serial(certificate): + """ + Given a certificate, return the serial number in that cert + + In theory there should be only one cert per object so even if we get + passed in a list/tuple only return the first one. + """ + if type(certificate) in (list, tuple): + certificate = certificate[0] + try: + x509 = crypto.load_certificate(crypto.FILETYPE_ASN1, certificate) + serial = str(x509.get_serial_number()) + except crypto.Error: + raise errors.GenericError(format='Unable to decode certificate in entry') + + return serial def validate_csr(ugettext, csr): """ @@ -76,14 +94,14 @@ class cert_request(VirtualCommand): # See if the service exists and punt if it doesn't and we aren't # going to add it try: - service = api.Command['service_show'](principal, **skw) - if service.get('usercertificate'): + (dn, service) = api.Command['service_show'](principal, **skw) + if 'usercertificate' in service: # FIXME, what to do here? Do we revoke the old cert? - raise errors.GenericError(format='entry already has a certificate') + raise errors.GenericError(format='entry already has a certificate, serial number %s' % get_serial(service['usercertificate'])) except errors.NotFound, e: if not add: - raise e + raise errors.NotFound(reason="The service principal for this request doesn't exist.") # Request the certificate result = self.Backend.ra.request_certificate(csr, **kw) @@ -104,6 +122,33 @@ class cert_request(VirtualCommand): else: textui.print_plain('Failed to submit a certificate request.') + def run(self, *args, **options): + """ + Dispatch to forward() and execute() to do work locally and on the + server. + """ + if self.env.in_server: + return self.execute(*args, **options) + + # Client-side code + csr = args[0] + if csr[:7] == "file://": + file = csr[7:] + try: + f = open(file, "r") + csr = f.readlines() + f.close() + except IOError, err: + raise errors.ValidationError(name='csr', error=err[1]) + csr = "".join(csr) + # We just want the CSR bits, make sure there is nothing else + s = csr.find("-----BEGIN NEW CERTIFICATE REQUEST-----") + e = csr.find("-----END NEW CERTIFICATE REQUEST-----") + if s >= 0: + csr = csr[s+40:e] + csr = csr.decode('UTF-8') + return self.forward(csr, **options) + api.register(cert_request) diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py index 8e9554282..70812579d 100644 --- a/ipalib/plugins/service.py +++ b/ipalib/plugins/service.py @@ -33,6 +33,17 @@ from ipalib import uuid _container_dn = api.env.container_service _default_attributes = ['krbprincipalname', 'usercertificate'] +def get_serial(certificate): + """ + Given a certificate, return the serial number in that cert + """ + try: + x509 = crypto.load_certificate(crypto.FILETYPE_ASN1, certificate) + serial = str(x509.get_serial_number()) + except crypto.Error: + raise errors.GenericError(format='Unable to decode certificate in entry') + + return serial def split_principal(principal): service = hostname = realm = None @@ -194,10 +205,8 @@ class service_del(crud.Delete): 'krbprincipalname', principal, 'ipaservice' ) - if 'usercerfificate' in entry_attrs: - cert = entry_attrs['usercertificate'] - x509 = crypto.load_certificate(crypto.FILETYPE_ASN1, cert) - serial = str(x509.get_serial_number()) + if 'usercertificate' in entry_attrs: + serial = get_serial(entry_attrs['usercertificate']) api.Command['cert_revoke'](unicode(serial), revocation_reason=5) ldap.delete_entry(dn) @@ -226,9 +235,9 @@ class service_mod(crud.Update): dn = ldap.make_dn_from_attr('krbprincipalname', principal, _container_dn) (dn, old_entry_attrs) = ldap.get_entry(dn) - if 'usercertificate' in old_entry_attrs and 'usercerficate' in options: + if 'usercertificate' in old_entry_attrs and 'usercertificate' in options: # FIXME, what to do here? Do we revoke the old cert? - raise errors.GenericError(format='entry already has a certificate') + raise errors.GenericError(format='entry already has a certificate, serial number %s' % get_serial(old_entry_attrs['usercertificate'])) try: ldap.update_entry(dn, entry_attrs) |