Allow for using AA or ECP
authorrohe0002 <roland.hedberg@adm.umu.se>
Tue, 25 Oct 2011 11:27:00 +0000 (13:27 +0200)
committerrohe0002 <roland.hedberg@adm.umu.se>
Tue, 25 Oct 2011 11:27:00 +0000 (13:27 +0200)
12 files changed:
README
etc/aa_config.py [new file with mode: 0644]
etc/config.py
etc/ecp_config.py
etc/pysaml_config.py
freeradius_aa.py [moved from freeradius_pysaml2.py with 100% similarity]
freeradius_ecp.py
setup.py
template/modules_python
template/modules_python_aa [new file with mode: 0644]
template/modules_python_ecp [new file with mode: 0644]
template/sites-available_inner-tunnel [moved from template/sites-available_inner-tunnel.dont_use with 100% similarity]

diff --git a/README b/README
index 97e4b6f..8fc935d 100644 (file)
--- a/README
+++ b/README
@@ -1,52 +1,56 @@
 moonshot
 ========
 A python module usable in a Moonshot environment to allow a freeradius server
-to fetch information about a user from a SAML2 Attribute Authority.
+to fetch information about a user from a SAML2 Attribute Authority (AA) or
+Identity Provider (IdP).
+There are some things you have to do disregarding how you want the SP to
+talk to the IdP/AA. So I take those first.
 
-Installing
+Basic Installing
 ----------
 
-sudo python setup.py install
-
-eventually also
-
-sudo easy_install moonshot
-
-When the python module is installed a couple of changes to the freeradius
-configuration are necessary.
+A couple of changes to the freeradius configuration are necessary.
+This is one way of doing it. How you chose to do it depends on your local
+preferences.
 
 1) create raddb/modules/python
 
-You can use the provided '/usr/local/etc/moonshot/template/modules_python' file
-as is.
+You can use one of the provided 'template/modules_python_aa' or
+'template/modules_python_ecp' files as they are. Which one depends of your
+choice of using ECP or AA. Rename of copy the one you want to use to
+'template/modules_python' and copy it to raddb/modules.
+
+Regarding the configuration of outer/inner tunnel this is still a bit
+undecided. The extension module can be use in either.
 
 2) Edit raddb/sites-available/default
 To the 'post-auth' section add one line referencing the python module.
 You can see how it can be done in
-'/usr/local/etc/moonshot/template/sites-available_default".
+'template/sites-available_default".
 
 3) Edit raddb/sites-available/inner-tunnel.
 To the 'post-auth' section add one line referencing the python module.
 You can see how it can be done in
-'/usr/local/etc/moonshot/template/sites-available_inner-tunnel".
+'template/sites-available_inner-tunnel".
 
 
-Now, you should have the basic setup.
+Now, you should have the basic freeradius setup.
 To get it working you have to do a couple of more things:
 
 
-I) Get the SAML2 metadata for the Attribute Authority (AA) you want to use.
-
-Place it in the '/usr/local/etc/moonshot/' directory
+I) Get the SAML2 metadata for the AA or IDP you want to use. Rename it to
+metadata.xml and place it in the 'etc' directory.
 
 
-II) Change the configuration in /usr/local/etc/moonshot/config.py
+II) Chose one of the configuration files for the extension you want to use.
+There are two choices (etc/aa_config.py and etc/ecp_config.py).
+Rename (or copy) the one you want to use to config.py and edit it.
 
-You must change the value of ATTRIBUTE_AUTHORITY so it is the identifier of the
-SAML2 AA you want to use.
+You must change the value of ATTRIBUTE_AUTHORITY/IDP_ENTITYID so it is the
+identifier (entityID) of the SAML2 AA/IdP you want to use.
 
 
-III) Change the configuration '/usr/local/etc/moonshot/pysaml_config.py'.
+III) Change the pysaml2 configuration file 'etc/pysaml_config.py'.
 A couple of things:
 
 BASE : This is the identifier of the SP (=this module) you are running.
@@ -56,6 +60,8 @@ organization: Information about the organization running this service
 contact_person: Information about a person people can contact to ask about
     this service
 
+xmlsec_binary: where the xmlsec1 binaries are located. This is only needed if
+these binaries are somewhere outside the normal PATH.
 
 IV) Create your own key pair.
 
@@ -64,14 +70,28 @@ $ openssl genrsa 1024 > ssl.key
 $ openssl req -new -x509 -nodes -sha1 -days 365 -key ssl.key > ssl.cert
 $ sudo mv ssl.key ssl.cert /usr/local/etc/moonshot/pki
 
-If you chose other names for you key and cert you have to change accordingly
-in pysaml_config.py .
+If you chose other names for you key and cert you have to change
+pysaml_config.py accordingly.
+
+
+V)
+
+Now you can install the package:
+
+python setup.py install
+
+should place everything in it's place.
+One thing that might happen is that a new directory is created.
+/usr/local/etc/moonshot
+You may have to change the premissions on this directory to make it possible
+for the freeradius extension to access the information in the directory.
 
+VI) Create the metadata file for your SP.
 
-V) Create the metadata file for your SP.
+$ cd etc
+$ make_metadata.py pysaml_config.py > sp.xml
 
-$ make_metadata.py /usr/local/etc/moonshot/pysaml_config.py > sp.xml
-This file you have to give to the person/organization that runs the AA you
+This file you have to give to the person/organization that runs the AA/IdP you
 want to get information from.
 
 !!! That should be it !!!
diff --git a/etc/aa_config.py b/etc/aa_config.py
new file mode 100644 (file)
index 0000000..d180bce
--- /dev/null
@@ -0,0 +1,27 @@
+# You shouldn't change these three lines unless you know what you are doing
+CONFIG = 'pysaml_config'                # PySAML2 Configuration file name
+IDENTITY_CACHE = "identity_cache"
+STATE_CACHE = "state_cache"
+METADATA_FILE=metadata.xml
+
+DEBUG=0
+
+# Should the SP sign the request
+SIGN=False
+
+# This depends on the AA configuration
+SP_NAME_QUALIFIER=""
+NAME_QUALIFIER="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
+NAMEID_FORMAT="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
+
+# This is necessary to pick information about the right AA from the metadata
+# file. This must be the entity ID of the AA not the endpoint
+ATTRIBUTE_AUTHORITY = "http://localhost:8088/"
+
+# Attribute filters per service@hostname
+# the key are GSS-Acceptor-Service-Name+':'+GSS-Acceptor-Host-Name
+# and the attribute names are the so called friendly-names
+
+ATTRIBUTE_FILTER = {
+    "ldap:example.com" : ["email", "givenName", "surname"],
+}
\ No newline at end of file
index d180bce..94806f1 100644 (file)
@@ -1,27 +1,17 @@
-# You shouldn't change these three lines unless you know what you are doing
+# You shouldn't change this line unless you know what you are doing
 CONFIG = 'pysaml_config'                # PySAML2 Configuration file name
-IDENTITY_CACHE = "identity_cache"
-STATE_CACHE = "state_cache"
-METADATA_FILE=metadata.xml
+
+METADATA_FILE="/usr/local/etc/moonshot/metadata.xml"
 
 DEBUG=0
 
-# Should the SP sign the request
+# Should the SP sign the request ?
 SIGN=False
 
-# This depends on the AA configuration
-SP_NAME_QUALIFIER=""
-NAME_QUALIFIER="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
-NAMEID_FORMAT="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
-
-# This is necessary to pick information about the right AA from the metadata
-# file. This must be the entity ID of the AA not the endpoint
-ATTRIBUTE_AUTHORITY = "http://localhost:8088/"
-
-# Attribute filters per service@hostname
-# the key are GSS-Acceptor-Service-Name+':'+GSS-Acceptor-Host-Name
-# and the attribute names are the so called friendly-names
+# This is needed in order to pick information about the right IdP from the
+# metadata file. This must be the entity ID of the IdP not an endpoint
+IDP_ENTITYID = "http://localhost:8087/idp"
 
-ATTRIBUTE_FILTER = {
-    "ldap:example.com" : ["email", "givenName", "surname"],
-}
\ No newline at end of file
+# The password that should be used when authenticating with the IdP
+# This password will be used disregarding which user it is.
+PASSWD = "foobar"
\ No newline at end of file
index e67803f..933e1ee 100644 (file)
@@ -1,9 +1,7 @@
 # You shouldn't change this line unless you know what you are doing
 CONFIG = 'pysaml_config'                # PySAML2 Configuration file name
-#IDENTITY_CACHE = "identity_cache"
-#STATE_CACHE = "state_cache"
 
-METADATA_FILE="../idp/idp.xml"
+METADATA_FILE="metadata.xml"
 
 DEBUG=0
 
@@ -14,10 +12,6 @@ SIGN=False
 # metadata file. This must be the entity ID of the IdP not an endpoint
 IDP_ENTITYID = "http://example.com/idp"
 
-# Attribute filters per service@hostname
-# the key are GSS-Acceptor-Service-Name+':'+GSS-Acceptor-Host-Name
-# and the attribute names are the so called friendly-names
-
-ATTRIBUTE_FILTER = {
-    "ldap:example.com" : ["email", "givenName", "surname"],
-}
\ No newline at end of file
+# The password that should be used when authenticating with the IdP
+# This password will be used disregarding which user it is.
+PASSWD = "foobar"
\ No newline at end of file
index 46c4742..2370cf9 100644 (file)
@@ -4,7 +4,7 @@ from saml2 import BINDING_PAOS
 # *** Change this line ***
 BASE= "http://localhost:8088/"
 
-# Don't change this line
+# Don't change this line unless you know exactly what you are doing
 BASEDIR = "/usr/local/etc/moonshot/"
 
 CONFIG = {
similarity index 100%
rename from freeradius_pysaml2.py
rename to freeradius_aa.py
index a1ac9d8..913289f 100644 (file)
@@ -5,6 +5,7 @@
 # The freeradius extension using ECP
 #
 __author__ = 'rolandh'
+__version__ = "0.0.5a"
 
 import radiusd
 import saml2
@@ -19,11 +20,11 @@ from saml2.response import authn_response
 from saml2.ecp_client import Client
 
 # Where's the configuration file is
-#CONFIG_DIR = "/usr/local/etc/moonshot"
-CONFIG_DIR = "../etc"
+CONFIG_DIR = "/usr/local/etc/moonshot"
+#CONFIG_DIR = "../etc"
 sys.path.insert(0, CONFIG_DIR)
 
-import ecp_config
+import config
 
 # Globals
 CLIENT = None
@@ -68,7 +69,7 @@ def instantiate(p):
     # Use IdP info retrieved from the SP when metadata is missing
 
     try:
-        CLIENT = Saml2Client(ecp_config.DEBUG, config_file=ecp_config.CONFIG)
+        CLIENT = Saml2Client(config.DEBUG, config_file=config.CONFIG)
 
     except Exception, e:
         # Report the error and return -1 for failure.
@@ -77,7 +78,8 @@ def instantiate(p):
         return -1
 
     try:
-        ECP = Client("", "", None, metadata_file=ecp_config.METADATA_FILE)
+        ECP = Client("", config.PASSWD, None,
+                     metadata_file=config.METADATA_FILE)
     except Exception, err:
         log(radiusd.L_ERR, str(err))
         return -1
@@ -107,8 +109,13 @@ def authentication_request(cls, ecp, idp_entity_id, destination,
         log = cls.logger
 
     session_id = sid()
-    acsu = cls.config.endpoint('assertion_consumer_service',
-                               saml2.BINDING_PAOS)[0]
+    acsus = cls.config.endpoint('assertion_consumer_service',
+                                saml2.BINDING_PAOS)
+    if not acsus:
+        if log:
+            log.error("Couldn't find own PAOS endpoint for")
+    acsu = acsus[0]
+
     spentityid = cls.config.entityid
 
     # create the request
@@ -187,12 +194,12 @@ def post_auth(authData):
 
     global CLIENT
     global HTTP
+    global ECP
 
     # Extract the data we need.
     userName = None
     serviceName = ""
     hostName = ""
-    #userPasswd = None
 
     for t in authData:
         if t[0] == 'User-Name':
@@ -207,17 +214,28 @@ def post_auth(authData):
 
 
     # Find the endpoint to use
-    attribute_service = CLIENT.config.attribute_services(ecp_config.IDP_ENTITYID)
-    location = attribute_service[0].location
+    sso_service = CLIENT.config.single_sign_on_services(config.IDP_ENTITYID,
+                                                        saml2.BINDING_PAOS)
+    if not sso_service:
+        log(radiusd.L_DBG,
+            "Couldn't find an single sign on endpoint for: %s" % (
+                config.IDP_ENTITYID,))
+        return radiusd.RLM_MODULE_FAIL
+
+    location = sso_service[0]
 
     log(radiusd.L_DBG, "location: %s" % location)
 
+    ECP.http.clear_credentials()
+    ECP.user = userName
+    log(radiusd.L_DBG, "Login using user:%s password:'%s'" % (ECP.user,
+                                                             ECP.passwd))
 
     _assertion = authentication_request(CLIENT, ECP,
-                                        ecp_config.IDP_ENTITYID,
+                                        config.IDP_ENTITYID,
                                         location,
                                         log=LOG(),
-                                        sign=ecp_config.SIGN)
+                                        sign=config.SIGN)
 
     if _assertion is None:
         return radiusd.RLM_MODULE_FAIL
@@ -228,12 +246,6 @@ def post_auth(authData):
 
     # remove the subject confirmation if there is one
     _assertion.subject.subject_confirmation = []
-    # Only allow attributes that the service should have
-    try:
-        _assertion = only_allowed_attributes(CLIENT, _assertion,
-                                             ecp_config.ATTRIBUTE_FILTER[_srv])
-    except KeyError:
-        pass
 
     log(radiusd.L_DBG, "Assertion: %s" % _assertion)
 
index c75840b..29e93e7 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -2,8 +2,10 @@
 
 import os
 
-"""Setup script for the pyparsing module distribution."""
-from distutils.core import setup
+try:
+    from setuptools import setup
+except ImportError:
+    from distutils.core import setup
 
 __author__ = 'rolandh'
 
@@ -12,12 +14,12 @@ def read(fname):
 
 setup(# Distribution meta-data
     name = "freeradius_pysaml2",
-    version = "0.0.4",
-    description = "FreeRadius python module to be used in Moonshot",
+    version = "0.0.5",
+    description = "FreeRadius python modules to be used in Moonshot",
     author = "Roland Hedberg",
     author_email = "roland.hedberg@adm.umu.se",
     license = "MIT License",
-    py_modules = ['freeradius_pysaml2','radiusd', "freeradius_ecp"],
+    py_modules = ['freeradius_aa','radiusd', "freeradius_ecp"],
     classifiers=[
         'Development Status :: 4 - Beta',
         'Intended Audience :: Developers',
@@ -35,12 +37,9 @@ setup(# Distribution meta-data
                              'attributemaps/saml_uri.py',
                              'attributemaps/shibboleth_uri.py']),
                 ('/usr/local/etc/moonshot/pki',
-                            ['pki/ssl.cert', 'pki/ssl.key']),
-                ('/usr/local/etc/moonshot/template',
-                            ['template/modules_python',
-                             'template/sites-available_default',
-                             'template/sites-available_inner-tunnel'])],
-    install_requires=[
-        'pysaml2'
-    ]
+                            ['pki/ssl.cert', 'pki/ssl.key'])],
+    zip_safe=False,
+#    install_requires=[
+#        'pysaml2'
+#    ]
     )
index c30cc0c..0062df5 100644 (file)
@@ -5,8 +5,8 @@
 #  Persistent, embedded Python interpreter.
 #
 python {
-    mod_instantiate = "freeradius-pysaml2"
+    mod_instantiate = "freeradius_ecp"
     func_instantiate = "instantiate"
-    mod_post_auth= "freeradius-pysaml2"
+    mod_post_auth= "freeradius_ecp"
     func_post_auth= "post_auth"
 }
diff --git a/template/modules_python_aa b/template/modules_python_aa
new file mode 100644 (file)
index 0000000..3740673
--- /dev/null
@@ -0,0 +1,12 @@
+# -*- text -*-
+#
+#  $Id$
+
+#  Persistent, embedded Python interpreter.
+#
+python {
+    mod_instantiate = "freeradius_pysaml2"
+    func_instantiate = "instantiate"
+    mod_post_auth= "freeradius_pysaml2"
+    func_post_auth= "post_auth"
+}
diff --git a/template/modules_python_ecp b/template/modules_python_ecp
new file mode 100644 (file)
index 0000000..0062df5
--- /dev/null
@@ -0,0 +1,12 @@
+# -*- text -*-
+#
+#  $Id$
+
+#  Persistent, embedded Python interpreter.
+#
+python {
+    mod_instantiate = "freeradius_ecp"
+    func_instantiate = "instantiate"
+    mod_post_auth= "freeradius_ecp"
+    func_post_auth= "post_auth"
+}