Skip to content

Commit a9d0b7c

Browse files
author
Roland Hedberg
committed
Merge pull request #87 from HaToHo/master
Only validate certificate and set client certificate tp authn request.
2 parents b0c0cf8 + 7edc244 commit a9d0b7c

File tree

12 files changed

+63
-24
lines changed

12 files changed

+63
-24
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,9 @@ example/sp/sp_nocert2.xml
149149
example/sp/test.py
150150

151151
example/sp/sp_conf.py
152+
153+
example/sp/nocert_sp_conf/sp.xml
154+
155+
example/sp/nocert_sp_conf/sp_conf.py
156+
157+
example/sp/nocert_sp_conf/who.ini

example/sp/who.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ saml_conf = sp_conf
1717
remember_name = auth_tkt
1818
sid_store = outstanding
1919
idp_query_param = IdPEntityId
20+
discovery = http://130.239.201.5/role/idp.ds
2021

2122
[general]
2223
request_classifier = s2repoze.plugins.challenge_decider:my_request_classifier

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ def run_tests(self):
4444
'zope.interface',
4545
'repoze.who',
4646
'pycrypto', #'Crypto'
47+
'pytz'
4748
]
4849

4950
tests_require = [

src/saml2/cert.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1+
__author__ = 'haho0032'
2+
13
import base64
2-
import traceback
3-
from M2Crypto.util import passphrase_callback
44
import datetime
55
import dateutil.parser
66
import pytz
7-
8-
__author__ = 'haho0032'
97
from OpenSSL import crypto
108
from os.path import exists, join
119
from os import remove

src/saml2/client_base.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ def create_authn_request(self, destination, vorg="", scoping=None,
231231
:param kwargs: Extra key word arguments
232232
:return: <samlp:AuthnRequest> instance
233233
"""
234-
234+
client_crt = None
235+
if "client_crt" in kwargs:
236+
client_crt = kwargs["client_crt"]
235237
args = {}
236238
try:
237239
args["assertion_consumer_service_url"] = kwargs[
@@ -299,9 +301,11 @@ def create_authn_request(self, destination, vorg="", scoping=None,
299301
except KeyError:
300302
pass
301303

302-
if sign and self.sec.cert_handler.generate_cert():
304+
if (sign and self.sec.cert_handler.generate_cert()) or client_crt is not None:
303305
with self.lock:
304-
self.sec.cert_handler.update_cert(True)
306+
self.sec.cert_handler.update_cert(True, client_crt)
307+
if client_crt is not None:
308+
sign_prepare = True
305309
return self._message(AuthnRequest, destination, message_id, consent,
306310
extensions, sign, sign_prepare,
307311
protocol_binding=binding,

src/saml2/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
AA_IDP_ARGS = [
9393
"sign_assertion",
9494
"want_authn_requests_signed",
95+
"want_authn_requests_only_with_valid_cert",
9596
"provided_attributes",
9697
"subject_data",
9798
"sp",

src/saml2/entity.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,12 @@ def _parse_request(self, xmlstr, request_cls, service, binding):
546546
origdoc = xmlstr
547547
xmlstr = self.unravel(xmlstr, binding, request_cls.msgtype)
548548
must = self.config.getattr("want_authn_requests_signed", "idp")
549-
_request = _request.loads(xmlstr, binding, origdoc=origdoc, must=must)
549+
only_valid_cert = self.config.getattr("want_authn_requests_only_with_valid_cert", "idp")
550+
if only_valid_cert is None:
551+
only_valid_cert = False
552+
if only_valid_cert:
553+
must = True
554+
_request = _request.loads(xmlstr, binding, origdoc=origdoc, must=must, only_valid_cert=only_valid_cert)
550555

551556
_log_debug("Loaded request")
552557

src/saml2/md.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,6 +1041,8 @@ class IDPSSODescriptorType_(SSODescriptorType_):
10411041
c_cardinality['attribute'] = {"min": 0}
10421042
c_attributes['WantAuthnRequestsSigned'] = ('want_authn_requests_signed',
10431043
'boolean', False)
1044+
c_attributes['WantAuthnRequestsOnlyWithValidCert'] = ('want_authn_requests_only_with_valid_cert',
1045+
'boolean', False)
10441046
c_child_order.extend(['single_sign_on_service', 'name_id_mapping_service',
10451047
'assertion_id_request_service', 'attribute_profile',
10461048
'attribute'])
@@ -1069,6 +1071,7 @@ def __init__(self,
10691071
text=None,
10701072
extension_elements=None,
10711073
extension_attributes=None,
1074+
want_authn_requests_only_with_valid_cert=None,
10721075
):
10731076
SSODescriptorType_.__init__(self,
10741077
artifact_resolution_service=artifact_resolution_service,
@@ -1095,6 +1098,7 @@ def __init__(self,
10951098
self.attribute_profile = attribute_profile or []
10961099
self.attribute = attribute or []
10971100
self.want_authn_requests_signed = want_authn_requests_signed
1101+
self.want_authn_requests_only_with_valid_cert = want_authn_requests_only_with_valid_cert
10981102

10991103

11001104
def idpsso_descriptor_type__from_string(xml_string):
@@ -2012,3 +2016,5 @@ def entities_descriptor_from_string(xml_string):
20122016
def factory(tag, **kwargs):
20132017
return ELEMENT_BY_TAG[tag](**kwargs)
20142018

2019+
2020+

src/saml2/metadata.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"want_assertions_signed": "true",
3838
"authn_requests_signed": "false",
3939
"want_authn_requests_signed": "true",
40+
"want_authn_requests_only_with_valid_cert": "false",
4041
}
4142

4243
ORG_ATTR_TRANSL = {
@@ -407,6 +408,7 @@ def do_endpoints(conf, endpoints):
407408
"want_assertions_signed": "true",
408409
"authn_requests_signed": "false",
409410
"want_authn_requests_signed": "false",
411+
"want_authn_requests_only_with_valid_cert": "false",
410412
}
411413

412414

@@ -527,6 +529,16 @@ def do_idpsso_descriptor(conf, cert=None):
527529
except KeyError:
528530
setattr(idpsso, key, DEFAULTS[key])
529531

532+
for key in ["want_authn_requests_only_with_valid_cert"]:
533+
try:
534+
val = conf.getattr(key, "idp")
535+
if val is None:
536+
setattr(idpsso, key, DEFAULT["want_authn_requests_only_with_valid_cert"])
537+
else:
538+
setattr(idpsso, key, "%s" % val)
539+
except KeyError:
540+
setattr(idpsso, key, DEFAULTS[key])
541+
530542
return idpsso
531543

532544

src/saml2/request.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ def _clear(self):
3636
self.message = None
3737
self.not_on_or_after = 0
3838

39-
def _loads(self, xmldata, binding=None, origdoc=None, must=None):
39+
def _loads(self, xmldata, binding=None, origdoc=None, must=None, only_valid_cert=False):
4040
# own copy
4141
self.xmlstr = xmldata[:]
4242
logger.info("xmlstr: %s" % (self.xmlstr,))
4343
try:
44-
self.message = self.signature_check(xmldata, origdoc=origdoc, must=must)
44+
self.message = self.signature_check(xmldata, origdoc=origdoc, must=must, only_valid_cert=only_valid_cert)
4545
except TypeError:
4646
raise
4747
except Exception, excp:
@@ -84,8 +84,8 @@ def _verify(self):
8484
assert self.issue_instant_ok()
8585
return self
8686

87-
def loads(self, xmldata, binding, origdoc=None, must=None):
88-
return self._loads(xmldata, binding, origdoc, must)
87+
def loads(self, xmldata, binding, origdoc=None, must=None, only_valid_cert=False):
88+
return self._loads(xmldata, binding, origdoc, must, only_valid_cert=only_valid_cert)
8989

9090
def verify(self):
9191
try:

0 commit comments

Comments
 (0)