From cd446e3d08f8adb0b3541442c3f7a32c16c8385f Mon Sep 17 00:00:00 2001 From: Andreas Richter Date: Mon, 5 Jan 2015 09:22:56 -0500 Subject: [PATCH 1/9] Fix error when response has no cert but outstanding_certs is defined. --- src/saml2/entity.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/saml2/entity.py b/src/saml2/entity.py index f9d290e..eed8233 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -872,9 +872,13 @@ class Entity(HTTPBase): if response: if outstanding_certs: - _, key_file = make_temp( - "%s" % outstanding_certs[ - response.in_response_to]["key"], decode=False) + cert = outstanding_certs[ + response.in_response_to] + if cert: + _, key_file = make_temp( + "%s" % cert["key"], decode=False) + else: + key_file = "" else: key_file = "" response = response.verify(key_file) From 25e535e3b8eff5c0dbe8850ff310bbf207f45364 Mon Sep 17 00:00:00 2001 From: Steven Das Date: Tue, 27 Jan 2015 21:58:02 -0600 Subject: [PATCH 2/9] Fixed typo in title --- doc/examples/sp.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/examples/sp.rst b/doc/examples/sp.rst index fdbacda..32f8b4b 100644 --- a/doc/examples/sp.rst +++ b/doc/examples/sp.rst @@ -1,6 +1,6 @@ .. _example_sp: -An extremly simple example of a SAML2 service provider. +An extremely simple example of a SAML2 service provider. ======================================================= How it works From a51eee702ad1c584187bba3ee456e29eed987743 Mon Sep 17 00:00:00 2001 From: Andrea Biancini Date: Fri, 27 Feb 2015 13:52:55 +0100 Subject: [PATCH 3/9] Fixed problem with metadata extensions With this small modification, I fixed I problem I was experiencing while trying to add RequestInitiator extension to a SP metadata. The problem here is that the XML attributes are called Binding and Location while the python instance attributes are called binding and location respectively. Se the instruction "elif key in _inst.c_attributes:" needs to have key with the capital letter while the setattr needs the lowercase name of the field. To be more generic I imagined it was better to retrieve the field name from the tuple associated to the field in c_attributes. --- src/saml2/s_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/saml2/s_utils.py b/src/saml2/s_utils.py index e17c2b5..16d031f 100644 --- a/src/saml2/s_utils.py +++ b/src/saml2/s_utils.py @@ -469,7 +469,7 @@ def rec_factory(cls, **kwargs): except Exception: continue else: - setattr(_inst, key, val) + setattr(_inst, _inst.c_attributes[key][0], val) elif key in _inst.c_child_order: for tag, _cls in _inst.c_children.values(): if tag == key: From a17cf103b019dbb445728777e909b54cd242b8ed Mon Sep 17 00:00:00 2001 From: Ludwig Kraatz Date: Wed, 4 Mar 2015 23:17:18 +0100 Subject: [PATCH 4/9] bugfix in make_metadata tool entities_descriptor returns tuple --- tools/make_metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/make_metadata.py b/tools/make_metadata.py index eff71d2..d9aea50 100755 --- a/tools/make_metadata.py +++ b/tools/make_metadata.py @@ -66,7 +66,7 @@ conf.xmlsec_binary = args.xmlsec secc = security_context(conf) if args.id: - desc = entities_descriptor(eds, valid_for, args.name, args.id, + desc, xmldoc = entities_descriptor(eds, valid_for, args.name, args.id, args.sign, secc) valid_instance(desc) print desc.to_string(nspair) From 3af76d1d8c501718dfc7c65bec1fe0dd79d19376 Mon Sep 17 00:00:00 2001 From: tpazderka Date: Fri, 6 Mar 2015 09:50:17 +0100 Subject: [PATCH 5/9] Fixed sid called with arguments --- src/saml2/entity.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/saml2/entity.py b/src/saml2/entity.py index 8779b19..be5977f 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -151,7 +151,6 @@ class Entity(HTTPBase): self.metadata = self.config.metadata self.config.setup_logger() self.debug = self.config.debug - self.seed = rndstr(32) self.sec = security_context(self.config) @@ -285,7 +284,7 @@ class Entity(HTTPBase): def message_args(self, message_id=0): if not message_id: - message_id = sid(self.seed) + message_id = sid() return {"id": message_id, "version": VERSION, "issue_instant": instant(), "issuer": self._issuer()} @@ -438,7 +437,7 @@ class Entity(HTTPBase): request_cls """ if not message_id: - message_id = sid(self.seed) + message_id = sid() for key, val in self.message_args(message_id).items(): if key not in kwargs: From a4af98d8434c9aada0c8b3a117e3879c6aa5eb99 Mon Sep 17 00:00:00 2001 From: Rebecka Gulliksson Date: Mon, 9 Mar 2015 14:18:50 +0100 Subject: [PATCH 6/9] Improved support for forceAuthn: clear cookie (if any) in case of forceAuthn="true". --- example/idp2/idp.py | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/example/idp2/idp.py b/example/idp2/idp.py index 90339c8..08c0e0c 100755 --- a/example/idp2/idp.py +++ b/example/idp2/idp.py @@ -143,7 +143,7 @@ class Service(object): saml_msg["RelayState"], encrypt_cert=_encrypt_cert, **kwargs) except KeyError: - # Can live with no relay state # TODO or can we, for inacademia? + # Can live with no relay state return self.do(saml_msg["SAMLRequest"], binding, saml_msg["RelayState"], **kwargs) @@ -211,10 +211,13 @@ class Service(object): def not_authn(self, key, requested_authn_context): ruri = geturl(self.environ, query=False) - return do_authentication(self.environ, self.start_response, - authn_context=requested_authn_context, - key=key, redirect_uri=ruri) + kwargs = dict(authn_context=requested_authn_context, key=key, redirect_uri=ruri) + # Clear cookie, if it already exists + kaka = delete_cookie(self.environ, "idpauthn") + if kaka: + kwargs["headers"] = [kaka] + return do_authentication(self.environ, self.start_response, **kwargs) # ----------------------------------------------------------------------------- @@ -422,7 +425,8 @@ class SSO(Service): saml_msg["SAMLRequest"], BINDING_HTTP_POST) _req = self.req_info.message if self.user: - if _req.force_authn: + if _req.force_authn is not None and \ + _req.force_authn.lower() == 'true': saml_msg["req_info"] = self.req_info key = self._store_request(saml_msg) return self.not_authn(key, _req.requested_authn_context) @@ -486,7 +490,7 @@ class SSO(Service): def do_authentication(environ, start_response, authn_context, key, - redirect_uri): + redirect_uri, headers=None): """ Display the login form """ @@ -496,7 +500,7 @@ def do_authentication(environ, start_response, authn_context, key, if len(auth_info): method, reference = auth_info[0] logger.debug("Authn chosen: %s (ref=%s)" % (method, reference)) - return method(environ, start_response, reference, key, redirect_uri) + return method(environ, start_response, reference, key, redirect_uri, headers) else: resp = Unauthorized("No usable authentication method") return resp(environ, start_response) @@ -513,15 +517,17 @@ PASSWD = { def username_password_authn(environ, start_response, reference, key, - redirect_uri): + redirect_uri, headers=None): """ Display the login form """ logger.info("The login page") - headers = [] - resp = Response(mako_template="login.mako", template_lookup=LOOKUP, - headers=headers) + kwargs = dict(mako_template="login.mako", template_lookup=LOOKUP) + if headers: + kwargs["headers"] = headers + + resp = Response(**kwargs) argv = { "action": "/verify", From 65399af7db4968949a3ca4f2b7c23c19bdb7c946 Mon Sep 17 00:00:00 2001 From: Rebecka Gulliksson Date: Mon, 9 Mar 2015 14:19:11 +0100 Subject: [PATCH 7/9] Autofocus on username input. --- example/idp2/htdocs/login.mako | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/idp2/htdocs/login.mako b/example/idp2/htdocs/login.mako index 6f23673..7555deb 100644 --- a/example/idp2/htdocs/login.mako +++ b/example/idp2/htdocs/login.mako @@ -14,7 +14,7 @@
-
+
From 13ff5e8899300c9b359fa1bdfdb3d412be0d7356 Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Wed, 11 Mar 2015 09:58:42 +0100 Subject: [PATCH 8/9] Slightly better handling of outstanding_certs. --- src/saml2/entity.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/saml2/entity.py b/src/saml2/entity.py index 82c932f..eadeb10 100644 --- a/src/saml2/entity.py +++ b/src/saml2/entity.py @@ -1,5 +1,5 @@ import base64 -from binascii import hexlify +#from binascii import hexlify import logging from hashlib import sha1 from Crypto.PublicKey import RSA @@ -937,13 +937,13 @@ class Entity(HTTPBase): if response: if outstanding_certs: - cert = outstanding_certs[ - response.in_response_to] - if cert: - _, key_file = make_temp( - "%s" % cert["key"], decode=False) - else: + try: + cert = outstanding_certs[response.in_response_to] + except KeyError: key_file = "" + else: + _, key_file = make_temp("%s" % cert["key"], + decode=False) else: key_file = "" response = response.verify(key_file) From 1d2d767cc9567843dcdc6f505fded30d9ad760b7 Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Wed, 11 Mar 2015 10:03:39 +0100 Subject: [PATCH 9/9] Release version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4e1aa41..616779e 100755 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ if sys.version_info < (2, 7): setup( name='pysaml2', - version='2.4.0beta', + version='2.4.0', description='Python implementation of SAML Version 2', # long_description = read("README"), author='Roland Hedberg',