Index: conffiles/setup_saml_sp.py =================================================================== --- conffiles/setup_saml_sp.py (revision 80962) +++ conffiles/setup_saml_sp.py (working copy) @@ -36,6 +36,7 @@ from subprocess import call from time import sleep from urlparse import urlparse +from xml.etree import ElementTree workaround = set() @@ -49,14 +50,19 @@ workaround.add(True) cleanup() metadata_download_failed = [] + metadata_validation_failed = [] saml_idp = config_registry.get('umc/saml/idp-server') if saml_idp and not download_idp_metadata(saml_idp): metadata_download_failed.append(saml_idp) + elif not valid_metadata(saml_idp): + metadata_validation_failed.append(saml_idp) reload_webserver() if not rewrite_sasl_configuration(): raise SystemExit('Could not rewrite SASL configuration for UMC.') if metadata_download_failed: raise SystemExit('Could not download IDP metadata for %s' % (', '.join(metadata_download_failed),)) + if metadata_validation_failed: + raise SystemExit('IDP metadata not valid for %s' % (', '.join(metadata_validation_failed),)) def cleanup(): @@ -64,6 +70,17 @@ os.remove(metadata) +def valid_metadata(saml_idp): + idp = bytes(urlparse(saml_idp).netloc) + filename = '/usr/share/univention-management-console/saml/idp/%s.xml' % (idp,) + try: + ElementTree.parse(filename) + except ElementTree.ParseError: + os.remove(filename) + return False + return True + + def download_idp_metadata(metadata): idp = bytes(urlparse(metadata).netloc) filename = '/usr/share/univention-management-console/saml/idp/%s.xml' % (idp,) @@ -71,6 +88,7 @@ print 'Try to download idp metadata (%s/60)' % (i + 1) rc = call([ '/usr/bin/curl', + '--fail', '--cacert', '/etc/univention/ssl/ucsCA/CAcert.pem', '-o', filename, metadata, Index: univention-management-console-web-server =================================================================== --- univention-management-console-web-server (revision 80962) +++ univention-management-console-web-server (working copy) @@ -492,6 +492,10 @@ def _decorated(self, *args, **kwargs): message = func(self, *args, **kwargs) or () super(SamlError, self).__init__(status, message) + if "Passive authentication not supported." in message: + # This error just meens we need to do an active login. The frontend knows how to handle that and there is no need to log that. It still needs to be raised though. + return self + CORE.warn('SamlError: %s' % message) return self return _decorated if func is None: Index: usr/share/univention-management-console/saml/sp.py =================================================================== --- usr/share/univention-management-console/saml/sp.py (revision 80962) +++ usr/share/univention-management-console/saml/sp.py (working copy) @@ -8,6 +8,7 @@ from univention.config_registry.interfaces import Interfaces from univention.config_registry import ConfigRegistry +from univention.management.console.log import CORE ucr = ConfigRegistry() ucr.load() @@ -24,6 +25,9 @@ addresses.extend([y['address'] for x, y in i.all_interfaces if y and y.get('address')]) bases = ['%s://%s/univention/saml' % (scheme, addr) for addr in addresses for scheme in ('https', 'http')] +idp_configs = glob.glob('/usr/share/univention-management-console/saml/idp/*.xml') +if not idp_configs: + CORE.error('''SamlError: Can't find any idp. SAML won't work. Please check the ucr variable "umc/saml/idp-server".''') CONFIG = { "entityid": "https://%s/univention/saml/metadata" % (fqdn,), "name_form": NAME_FORMAT_URI, @@ -46,7 +50,7 @@ "cert_file": "/etc/univention/ssl/%s/cert.pem" % (fqdn,), "xmlsec_binary": "/usr/bin/xmlsec1", "metadata": { - "local": glob.glob('/usr/share/univention-management-console/saml/idp/*.xml'), + "local": idp_configs, }, # TODO: add contact_person? }