From 9345b2b376d09d014c6f6d002a2078001db01a65 Mon Sep 17 00:00:00 2001 From: Roland Hedberg Date: Mon, 29 Mar 2010 11:06:04 +0200 Subject: [PATCH] Clean up --- src/saml2/authnresponse.py | 73 ++++++++++++++++++++++++++------------ src/saml2/client.py | 11 +++--- src/saml2/server.py | 7 ++-- 3 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/saml2/authnresponse.py b/src/saml2/authnresponse.py index 3a45b51..5f74f99 100644 --- a/src/saml2/authnresponse.py +++ b/src/saml2/authnresponse.py @@ -29,19 +29,23 @@ from saml2.attribute_converter import to_local def _use_on_or_after(condition, slack): now = time.mktime(time.gmtime()) + #print "NOW: %d" % now not_on_or_after = time.mktime(str_to_time(condition.not_on_or_after)) + #print "not_on_or_after: %d" % not_on_or_after # slack is +- high = not_on_or_after+slack if now > high: # To old ignore - print "(%d > %d)" % (now,high) + #print "(%d > %d)" % (now,high) raise Exception("To old can't use it!") return not_on_or_after def _use_before(condition, slack): - not_before = time.mktime(str_to_time(condition.not_before)) now = time.mktime(time.gmtime()) - + #print "NOW: %s" % now + not_before = time.mktime(str_to_time(condition.not_before)) + #print "not_before: %d" % not_before + if not_before > now + slack: # Can't use it yet raise Exception("Can't use it yet %s <= %s" % (not_before, now)) @@ -54,8 +58,11 @@ def for_me(condition, myself ): if audience.text.strip() == myself: return True else: - print "%s != %s" % (audience.text.strip(), myself) - + #print "Not for me: %s != %s" % (audience.text.strip(), myself) + pass + + return False + # --------------------------------------------------------------------------- class IncorrectlySigned(Exception): @@ -64,7 +71,7 @@ class IncorrectlySigned(Exception): # --------------------------------------------------------------------------- def authn_response(conf, requestor, outstanding_queries=None, log=None, - timeslack=0): + timeslack=0, debug=0): sec = security_context(conf) if not timeslack: try: @@ -73,7 +80,7 @@ def authn_response(conf, requestor, outstanding_queries=None, log=None, pass return AuthnResponse(sec, conf.attribute_converters, requestor, - outstanding_queries, log, timeslack) + outstanding_queries, log, timeslack, debug) class AuthnResponse(object): @@ -95,6 +102,8 @@ class AuthnResponse(object): self.clear() def loads(self, xmldata, decode=True): + if self.debug: + self.log.info("--- Loads AuthnResponse ---") if decode: decoded_xml = base64.b64decode(xmldata) else: @@ -102,7 +111,13 @@ class AuthnResponse(object): # own copy self.xmlstr = decoded_xml[:] - self.response = self.sc.correctly_signed_response(decoded_xml) + if self.debug: + self.log.info("xmlstr: %s" % (self.xmlstr,)) + try: + self.response = self.sc.correctly_signed_response(decoded_xml) + except Exception, excp: + self.log.info("EXCEPTION: %s", excp) + raise if not self.response: if self.log: @@ -111,7 +126,7 @@ class AuthnResponse(object): raise IncorrectlySigned() if self.debug: - self.log.debug("response: %s" % (response,)) + self.log.info("response: %s" % (self.response,)) return self @@ -127,6 +142,7 @@ class AuthnResponse(object): def status_ok(self): if self.response.status: status = self.response.status + self.log.info("status: %s" % (status,)) if status.status_code.value != samlp.STATUS_SUCCESS: if self.log: self.log.info("Not successfull operation: %s" % status) @@ -151,7 +167,8 @@ class AuthnResponse(object): try: self.not_on_or_after = _use_on_or_after(condition, self.timeslack) _use_before(condition, self.timeslack) - except Exception: + except Exception,excp: + self.log.error("Exception on condition: %s" % (excp,)) if not lax: raise else: @@ -166,9 +183,14 @@ class AuthnResponse(object): def get_identity(self): # The assertion can contain zero or one attributeStatements if not self.assertion.attribute_statement: + self.log.error("Missing Attribute Statement") ava = {} else: assert len(self.assertion.attribute_statement) == 1 + self.log.info("Attribute Statement: %s" % ( + self.assertion.attribute_statement[0],)) + for ac in self.attribute_converters(): + self.log.info("Converts name format: %s" % (ac.format,)) ava = to_local(self.attribute_converters(), self.assertion.attribute_statement[0]) return ava @@ -179,11 +201,11 @@ class AuthnResponse(object): subject = self.assertion.subject for subject_confirmation in subject.subject_confirmation: data = subject_confirmation.subject_confirmation_data - if data.in_response_to in self.outstanding: - self.came_from = self.outstanding[data.in_response_to] - del self.outstanding[data.in_response_to] + if data.in_response_to in self.outstanding_queries: + self.came_from = self.outstanding_queries[data.in_response_to] + del self.outstanding_queries[data.in_response_to] else: - print data.in_response_to, self.outstanding.keys() + print data.in_response_to, self.outstanding_queries.keys() raise Exception( "Combination of session id and requestURI I don't recall") @@ -195,9 +217,10 @@ class AuthnResponse(object): self.assertion = assertion if self.debug: - self.log.info("assertion context: %s" % (context,)) + self.log.info("assertion context: %s" % (self.context,)) self.log.info("assertion keys: %s" % (assertion.keyswv())) - self.log.info("outstanding: %s" % (outstanding)) + self.log.info("outstanding_queries: %s" % ( + self.outstanding_queries)) if self.context == "AuthNReq": self.authn_statement_ok() @@ -205,10 +228,13 @@ class AuthnResponse(object): if not self.condition_ok(): return None + if self.debug: + self.log.info("--- Getting Identity ---") + self.ava = self.get_identity() if self.debug: - self.log.debug("AVA: %s" % (self.ava,)) + self.log.info("--- AVA: %s" % (self.ava,)) self.get_subject() @@ -218,18 +244,18 @@ class AuthnResponse(object): decrypt_xml = self.sc.decrypt(self.xmlstr) if self.debug: - self.log.debug("Decryption successfull") + self.log.info("Decryption successfull") self.response = samlp.response_from_string(decrypt_xml) if self.debug: - self.log.debug("Parsed decrypted assertion successfull") + self.log.info("Parsed decrypted assertion successfull") enc = self.response.encrypted_assertion[0].extension_elements[0] assertion = extension_element_to_element(enc, saml.ELEMENT_FROM_STRING, namespace=saml.NAMESPACE) if self.debug: - self.log.debug("Decrypted Assertion: %s" % assertion) + self.log.info("Decrypted Assertion: %s" % assertion) return self._assertion(assertion) def parse_assertion(self): @@ -240,11 +266,12 @@ class AuthnResponse(object): raise Exception("No assertion part") if self.response.assertion: - self.debug and self.log.debug("***Unencrypted response***") + self.debug and self.log.info("***Unencrypted response***") return self._assertion(self.response.assertion[0]) else: self.debug and self.log.info("***Encrypted response***") - return self._encrypted_assertion(outstanding) + return self._encrypted_assertion( + self.response.encrypted_assertion[0]) return True @@ -266,7 +293,7 @@ class AuthnResponse(object): return self.response.id def session_info(self): - return { "ava": self.ava, "name_id": name_id, + return { "ava": self.ava, "name_id": self.name_id, "came_from": self.came_from, "issuer": self.issuer(), "not_on_or_after": self.not_on_or_after } diff --git a/src/saml2/client.py b/src/saml2/client.py index ae877eb..b79c822 100644 --- a/src/saml2/client.py +++ b/src/saml2/client.py @@ -51,7 +51,7 @@ LAX = False class Saml2Client(object): """ The basic pySAML2 service provider class """ - def __init__(self, environ, config=None): + def __init__(self, environ, config=None, debug=0): """ :param environ: :param config: A saml2.config.Config instance @@ -62,7 +62,9 @@ class Saml2Client(object): if "metadata" in config: self.metadata = config["metadata"] self.sc = security_context(config) - + + self.debug = debug + def _init_request(self, request, destination): #request.id = sid() request.version = VERSION @@ -112,7 +114,8 @@ class Saml2Client(object): if post.has_key("SAMLResponse"): saml_response = post['SAMLResponse'].value if saml_response: - ar = authn_response(self.conf, requestor, outstanding, log) + ar = authn_response(self.config, requestor, outstanding, log, + debug=self.debug) ar.loads(saml_response) return ar.verify() @@ -324,7 +327,7 @@ class Saml2Client(object): if response: log and log.info("Verifying response") - ar = authn_response(self.conf, issuer, {session_id:""}, log) + ar = authn_response(self.config, issuer, {session_id:""}, log) session_info = ar.loads(response).verify().session_info() log and log.info("session: %s" % session_info) diff --git a/src/saml2/server.py b/src/saml2/server.py index d699184..50c78c6 100644 --- a/src/saml2/server.py +++ b/src/saml2/server.py @@ -200,7 +200,7 @@ class Server(object): try: request = self.sc.correctly_signed_authn_request(request_xml) if self.log and self.debug: - self.log.error("Request was correctly signed") + self.log.info("Request was correctly signed") except Exception: if self.log: self.log.error("Request was not correctly signed") @@ -238,7 +238,7 @@ class Server(object): response["consumer_url"] = consumer_url response["request"] = request - self.log and self.log.info("AuthNRequest: %s" % request) + return response def wants(self, sp_entity_id): @@ -407,8 +407,7 @@ class Server(object): in_response_to, # in_response_to sp_entity_id, # sp_entity_id identity, # identity as dictionary - name_id, - userid + name_id ) except MissingValue, exc: response = self.error_response(destination, in_response_to,