X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Fproviders%2Fsaml2idp.py;h=a1247d5da3193442aea651708c622f2c2ac0b607;hp=c70b96a929dd44e95a3a9cee8e580a97b67f71b0;hb=62cdf30afac58855d9895dfe32a58332315e50c4;hpb=5a6c713fda1a4052051566984c0b489e286aa502 diff --git a/ipsilon/providers/saml2idp.py b/ipsilon/providers/saml2idp.py index c70b96a..a1247d5 100755 --- a/ipsilon/providers/saml2idp.py +++ b/ipsilon/providers/saml2idp.py @@ -21,13 +21,14 @@ from ipsilon.providers.common import ProviderBase, ProviderPageBase from ipsilon.providers.common import FACILITY from ipsilon.providers.saml2.auth import AuthenticateRequest from ipsilon.providers.saml2.admin import AdminPage -from ipsilon.providers.saml2.certs import Certificate -from ipsilon.providers.saml2 import metadata +from ipsilon.providers.saml2.provider import IdentityProvider +from ipsilon.tools.certs import Certificate +from ipsilon.tools import saml2metadata as metadata +from ipsilon.tools import files from ipsilon.util.user import UserSession from ipsilon.util.plugin import PluginObject import cherrypy import lasso -import pwd import os @@ -76,7 +77,7 @@ class Continue(AuthenticateRequest): raise cherrypy.HTTPError(400) try: - login = lasso.Login.newFromDump(self.cfg.idp, dump) + login = self.cfg.idp.get_login_handler(dump) except Exception, e: # pylint: disable=broad-except self._debug('Failed to load status from dump: %r' % e) @@ -97,39 +98,41 @@ class SSO(ProviderPageBase): self.Continue = Continue(*args, **kwargs) +class Metadata(ProviderPageBase): + def GET(self, *args, **kwargs): + with open(self.cfg.idp_metadata_file) as m: + body = m.read() + cherrypy.response.headers["Content-Type"] = "text/xml" + cherrypy.response.headers["Content-Disposition"] = \ + 'attachment; filename="metadata.xml"' + return body + + class SAML2(ProviderPageBase): def __init__(self, *args, **kwargs): super(SAML2, self).__init__(*args, **kwargs) + self.metadata = Metadata(*args, **kwargs) # Init IDP data try: - self.cfg.idp = lasso.Server(self.cfg.idp_metadata_file, - self.cfg.idp_key_file, - None, - self.cfg.idp_certificate_file) - self.cfg.idp.role = lasso.PROVIDER_ROLE_IDP + self.cfg.idp = IdentityProvider(self.cfg) except Exception, e: # pylint: disable=broad-except - self._debug('Failed to enable SAML2 provider: %r' % e) + self._debug('Failed to init SAML2 provider: %r' % e) return # Import all known applications data = self.cfg.get_data() for idval in data: - if 'type' not in data[idval] or data[idval]['type'] != 'SP': - continue - path = os.path.join(self.cfg.idp_storage_path, str(idval)) sp = data[idval] - if 'name' in sp: - name = sp['name'] - else: - name = str(idval) + if 'type' not in sp or sp['type'] != 'SP': + continue + if 'name' not in sp or 'metadata' not in sp: + continue try: - meta = os.path.join(path, 'metadata.xml') - self.cfg.idp.addProvider(lasso.PROVIDER_ROLE_SP, meta) - self._debug('Added SP %s' % name) + self.cfg.idp.add_provider(sp) except Exception, e: # pylint: disable=broad-except - self._debug('Failed to add SP %s: %r' % (name, e)) + self._debug('Failed to add SP %s: %r' % (sp['name'], e)) self.SSO = SSO(*args, **kwargs) @@ -138,7 +141,9 @@ class IdpProvider(ProviderBase): def __init__(self): super(IdpProvider, self).__init__('saml2', 'saml2') + self.admin = None self.page = None + self.idp = None self.description = """ Provides SAML 2.0 authentication infrastructure. """ @@ -184,6 +189,13 @@ Provides SAML 2.0 authentication infrastructure. """ 'example.com' ] } + if cherrypy.config.get('debug', False): + import logging + import sys + logger = logging.getLogger('lasso') + lh = logging.StreamHandler(sys.stderr) + logger.addHandler(lh) + logger.setLevel(logging.DEBUG) @property def allow_self_registration(self): @@ -235,16 +247,13 @@ class Installer(object): def install_args(self, group): group.add_argument('--saml2', choices=['yes', 'no'], default='yes', help='Configure SAML2 Provider') - group.add_argument('--saml2-storage', - default='/var/lib/ipsilon/saml2', - help='SAML2 Provider storage area') def configure(self, opts): if opts['saml2'] != 'yes': return # Check storage path is present or create it - path = opts['saml2_storage'] + path = os.path.join(opts['data_dir'], 'saml2') if not os.path.exists(path): os.makedirs(path, 0700) @@ -253,16 +262,17 @@ class Installer(object): cert.generate('idp', opts['hostname']) # Generate Idp Metadata - url = 'https://' + opts['hostname'] + '/idp/saml2' + proto = 'https' + if opts['secure'].lower() == 'no': + proto = 'http' + url = '%s://%s/%s/saml2' % (proto, opts['hostname'], opts['instance']) meta = metadata.Metadata(metadata.IDP_ROLE) meta.set_entity_id(url + '/metadata') meta.add_certs(cert, cert) - meta.add_service(metadata.SSO_SERVICE, - lasso.SAML2_METADATA_BINDING_POST, - url + '/POST') - meta.add_service(metadata.SSO_SERVICE, - lasso.SAML2_METADATA_BINDING_REDIRECT, - url + '/Redirect') + meta.add_service(metadata.SAML2_SERVICE_MAP['sso-post'], + url + '/SSO/POST') + meta.add_service(metadata.SAML2_SERVICE_MAP['sso-redirect'], + url + '/SSO/Redirect') meta.add_allowed_name_format( lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT) @@ -285,18 +295,10 @@ class Installer(object): config = {'idp storage path': path, 'idp metadata file': 'metadata.xml', 'idp certificate file': cert.cert, - 'idp key file': cert.key} + 'idp key file': cert.key, + 'enabled': '1'} po.set_config(config) po.save_plugin_config(FACILITY) # Fixup permissions so only the ipsilon user can read these files - pw = pwd.getpwnam(opts['system_user']) - for root, dirs, files in os.walk(path): - for name in dirs: - target = os.path.join(root, name) - os.chown(target, pw.pw_uid, pw.pw_gid) - os.chmod(target, 0700) - for name in files: - target = os.path.join(root, name) - os.chown(target, pw.pw_uid, pw.pw_gid) - os.chmod(target, 0600) + files.fix_user_dirs(path, opts['system_user'])