Skip to content

Commit 34c3b87

Browse files
authored
Merge branch 'master' into fix_sane_defaults
2 parents 7b5cb73 + 2326962 commit 34c3b87

File tree

6 files changed

+52
-27
lines changed

6 files changed

+52
-27
lines changed

src/saml2/attribute_converter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def get_local_name(acs, attr, name_format):
246246
for aconv in acs:
247247
#print(ac.format, name_format)
248248
if aconv.name_format == name_format:
249-
return aconv._fro[attr]
249+
return aconv._fro.get(attr)
250250

251251

252252
def d_to_local_name(acs, attr):

src/saml2/pack.py

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,35 @@
4040
import defusedxml.ElementTree
4141

4242
NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/"
43-
FORM_SPEC = """<form method="post" action="%s">
44-
<input type="hidden" name="%s" value="%s" />
45-
<input type="hidden" name="RelayState" value="%s" />
46-
<input type="submit" value="Submit" />
47-
</form>"""
4843

44+
FORM_SPEC = """\
45+
<!DOCTYPE html>
46+
<html>
47+
<head>
48+
<meta charset="utf-8" />
49+
</head>
50+
<body onload="document.forms[0].submit()">
51+
<noscript>
52+
<p>
53+
<strong>Note:</strong> Since your browser does not support JavaScript,
54+
you must press the Continue button once to proceed.
55+
</p>
56+
</noscript>
57+
58+
<form action="{action}" method="post">
59+
<div>
60+
<input type="hidden" name="RelayState" value="{relay_state}"/>
61+
62+
<input type="hidden" name="{saml_type}" value="{saml_response}"/>
63+
</div>
64+
<noscript>
65+
<div>
66+
<input type="submit" value="Continue"/>
67+
</div>
68+
</noscript>
69+
</form>
70+
</body>
71+
</html>"""
4972

5073
def http_form_post_message(message, location, relay_state="",
5174
typ="SAMLRequest", **kwargs):
@@ -58,8 +81,6 @@ def http_form_post_message(message, location, relay_state="",
5881
:param relay_state: for preserving and conveying state information
5982
:return: A tuple containing header information and a HTML message.
6083
"""
61-
response = ["<head>", """<title>SAML 2.0 POST</title>""", "</head><body>"]
62-
6384
if not isinstance(message, six.string_types):
6485
message = str(message)
6586
if not isinstance(message, six.binary_type):
@@ -71,17 +92,17 @@ def http_form_post_message(message, location, relay_state="",
7192
_msg = message
7293
_msg = _msg.decode('ascii')
7394

74-
response.append(FORM_SPEC % (location, typ, _msg, relay_state))
95+
args = {
96+
'action' : location,
97+
'saml_type' : typ,
98+
'relay_state' : relay_state,
99+
'saml_response' : _msg
100+
}
75101

76-
response.append("""<script type="text/javascript">""")
77-
response.append(" window.onload = function ()")
78-
response.append(" { document.forms[0].submit(); }")
79-
response.append("""</script>""")
80-
response.append("</body>")
102+
response = FORM_SPEC.format(**args)
81103

82104
return {"headers": [("Content-type", "text/html")], "data": response}
83105

84-
85106
def http_post_message(message, relay_state="", typ="SAMLRequest", **kwargs):
86107
"""
87108

src/saml2/validate.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import re
44
import struct
55
import base64
6+
import time
67

78
from saml2 import time_util
89

@@ -42,8 +43,8 @@ class ToEarly(Exception):
4243

4344
def valid_ncname(name):
4445
match = NCNAME.match(name)
45-
if not match:
46-
raise NotValid("NCName")
46+
#if not match: # hack for invalid authnRequest/ID from meteor saml lib
47+
# raise NotValid("NCName")
4748
return True
4849

4950

@@ -90,8 +91,10 @@ def validate_on_or_after(not_on_or_after, slack):
9091
now = time_util.utc_now()
9192
nooa = calendar.timegm(time_util.str_to_time(not_on_or_after))
9293
if now > nooa + slack:
94+
now_str=time.strftime('%Y-%M-%dT%H:%M:%SZ', time.gmtime(now))
9395
raise ResponseLifetimeExceed(
94-
"Can't use it, it's too old %d > %d" % (now - slack, nooa))
96+
"Can't use repsonse, too old (now=%s + slack=%d > " \
97+
"not_on_or_after=%s" % (now_str, slack, not_on_or_after))
9598
return nooa
9699
else:
97100
return False
@@ -102,8 +105,9 @@ def validate_before(not_before, slack):
102105
now = time_util.utc_now()
103106
nbefore = calendar.timegm(time_util.str_to_time(not_before))
104107
if nbefore > now + slack:
105-
raise ToEarly("Can't use it yet %d <= %d" % (now + slack, nbefore))
106-
108+
now_str = time.strftime('%Y-%M-%dT%H:%M:%SZ', time.gmtime(now))
109+
raise ToEarly("Can't use response yet: (now=%s + slack=%d) "
110+
"<= notbefore=%s" % (now_str, slack, not_before))
107111
return True
108112

109113

tests/test_51_client.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ def test_do_logout_post(self):
14041404
binding, info = resp[entity_ids[0]]
14051405
assert binding == BINDING_HTTP_POST
14061406

1407-
_dic = unpack_form(info["data"][3])
1407+
_dic = unpack_form(info["data"])
14081408
res = self.server.parse_logout_request(_dic["SAMLRequest"],
14091409
BINDING_HTTP_POST)
14101410
assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr
@@ -1434,7 +1434,7 @@ def test_do_logout_session_expired(self):
14341434
binding, info = resp[entity_ids[0]]
14351435
assert binding == BINDING_HTTP_POST
14361436

1437-
_dic = unpack_form(info["data"][3])
1437+
_dic = unpack_form(info["data"])
14381438
res = self.server.parse_logout_request(_dic["SAMLRequest"],
14391439
BINDING_HTTP_POST)
14401440
assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr
@@ -1531,7 +1531,7 @@ def test_post_sso(self):
15311531
sid, http_args = self.client.prepare_for_authenticate(
15321532
"urn:mace:example.com:saml:roland:idp", relay_state="really",
15331533
binding=binding, response_binding=response_binding)
1534-
_dic = unpack_form(http_args["data"][3])
1534+
_dic = unpack_form(http_args["data"])
15351535

15361536
req = self.server.parse_authn_request(_dic["SAMLRequest"], binding)
15371537
resp_args = self.server.response_args(req.message, [response_binding])
@@ -1566,7 +1566,7 @@ def test_negotiated_post_sso(self):
15661566
sid, auth_binding, http_args = self.client.prepare_for_negotiated_authenticate(
15671567
"urn:mace:example.com:saml:roland:idp", relay_state="really",
15681568
binding=binding, response_binding=response_binding)
1569-
_dic = unpack_form(http_args["data"][3])
1569+
_dic = unpack_form(http_args["data"])
15701570

15711571
assert binding == auth_binding
15721572

@@ -1586,7 +1586,7 @@ def test_negotiated_post_sso(self):
15861586

15871587
response = self.client.send(**http_args)
15881588
print(response.text)
1589-
_dic = unpack_form(response.text[3], "SAMLResponse")
1589+
_dic = unpack_form(response.text, "SAMLResponse")
15901590
resp = self.client.parse_authn_request_response(_dic["SAMLResponse"],
15911591
BINDING_HTTP_POST,
15921592
{sid: "/"})

tests/test_65_authn_query.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def get_msg(hinfo, binding):
2828
if binding == BINDING_SOAP:
2929
xmlstr = hinfo["data"]
3030
elif binding == BINDING_HTTP_POST:
31-
_inp = hinfo["data"][3]
31+
_inp = hinfo["data"]
3232
i = _inp.find(TAG1)
3333
i += len(TAG1) + 1
3434
j = _inp.find('"', i)

tests/test_68_assertion_id.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def get_msg(hinfo, binding, response=False):
2727
if binding == BINDING_SOAP:
2828
msg = hinfo["data"]
2929
elif binding == BINDING_HTTP_POST:
30-
_inp = hinfo["data"][3]
30+
_inp = hinfo["data"]
3131
i = _inp.find(TAG1)
3232
i += len(TAG1) + 1
3333
j = _inp.find('"', i)

0 commit comments

Comments
 (0)