summaryrefslogtreecommitdiffstats
path: root/ipalib
diff options
context:
space:
mode:
Diffstat (limited to 'ipalib')
-rw-r--r--ipalib/constants.py4
-rw-r--r--ipalib/plugins/cert.py53
-rw-r--r--ipalib/plugins/service.py21
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)