summaryrefslogtreecommitdiff
path: root/src/saml2/mdstore.py
diff options
context:
space:
mode:
authorRoland Hedberg <roland.hedberg@adm.umu.se>2015-05-27 11:43:07 +0200
committerRoland Hedberg <roland.hedberg@adm.umu.se>2015-05-27 11:43:07 +0200
commite9b472108e66ee3885beb6eae396ec35bd436e92 (patch)
tree9563df77cc186649ae0dd531932d92928453412e /src/saml2/mdstore.py
parent3e6b4c988e2f75019d3b18ff81ff55e1971a706f (diff)
downloadpysaml2-e9b472108e66ee3885beb6eae396ec35bd436e92.tar.gz
Providing a certificate when the metadata is not signed should not result in an error. Refactored the code so there is less duplication.
Diffstat (limited to 'src/saml2/mdstore.py')
-rw-r--r--src/saml2/mdstore.py105
1 files changed, 61 insertions, 44 deletions
diff --git a/src/saml2/mdstore.py b/src/saml2/mdstore.py
index 4cd8bdf3..9169213c 100644
--- a/src/saml2/mdstore.py
+++ b/src/saml2/mdstore.py
@@ -119,6 +119,8 @@ class MetaData(object):
self.onts = onts
self.attrc = attrc
self.metadata = metadata
+ self.entity = None
+ self.cert = None
def items(self):
'''
@@ -324,6 +326,10 @@ class InMemoryMetaData(MetaData):
self.entities_descr = None
self.entity_descr = None
self.check_validity = check_validity
+ try:
+ self.filter = kwargs["filter"]
+ except KeyError:
+ self.filter = None
def items(self):
return self.entity.items()
@@ -391,6 +397,11 @@ class InMemoryMetaData(MetaData):
else:
flag += 1
+ if self.filter:
+ _ent = self.filter(_ent)
+ if not _ent:
+ flag = 0
+
if flag:
self.entity[entity_descr.entity_id] = _ent
@@ -536,6 +547,34 @@ class InMemoryMetaData(MetaData):
res.append(dat["x509_certificate"]["text"])
return res
+ def signed(self):
+ if self.entities_descr and self.entities_descr.signature:
+ return True
+
+ if self.entity_descr and self.entity_descr.signature:
+ return True
+ else:
+ return False
+
+ def parse_and_check_signature(self, txt):
+ self.parse(txt)
+
+ if self.cert:
+ if not self.signed():
+ return True
+
+ node_name = self.node_name \
+ or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
+ md.EntitiesDescriptor.c_tag)
+
+ if self.security.verify_signature(
+ txt, node_name=node_name, cert_file=self.cert):
+ return True
+ else:
+ return False
+ else:
+ return True
+
class MetaDataFile(InMemoryMetaData):
"""
@@ -554,19 +593,7 @@ class MetaDataFile(InMemoryMetaData):
def load(self):
_txt = self.get_metadata_content()
- if self.cert:
- node_name = self.node_name \
- or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
- md.EntitiesDescriptor.c_tag)
-
- if self.security.verify_signature(_txt,
- node_name=node_name,
- cert_file=self.cert):
- self.parse(_txt)
- return True
- else:
- self.parse(_txt)
- return True
+ return self.parse_and_check_signature(_txt)
class MetaDataLoader(MetaDataFile):
@@ -633,10 +660,9 @@ class MetaDataExtern(InMemoryMetaData):
raise SAMLError('URL not specified.')
else:
self.url = url
- if not cert:
- raise SAMLError('No certificate specified.')
- else:
- self.cert = cert
+
+ # No cert is only an error if the metadata is unsigned
+ self.cert = cert
self.security = security
self.http = http
@@ -648,20 +674,8 @@ class MetaDataExtern(InMemoryMetaData):
"""
response = self.http.send(self.url)
if response.status_code == 200:
- node_name = self.node_name \
- or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
- md.EntitiesDescriptor.c_tag)
-
_txt = response.text.encode("utf-8")
- if self.cert:
- if self.security.verify_signature(_txt,
- node_name=node_name,
- cert_file=self.cert):
- self.parse(_txt)
- return True
- else:
- self.parse(_txt)
- return True
+ return self.parse_and_check_signature(_txt)
else:
logger.info("Response status: %s" % response.status_code)
return False
@@ -724,14 +738,7 @@ class MetaDataMDX(InMemoryMetaData):
_txt = response.text.encode("utf-8")
- if self.cert:
- if self.security.verify_signature(_txt,
- node_name=node_name,
- cert_file=self.cert):
- self.parse(_txt)
- return self.entity[item]
- else:
- self.parse(_txt)
+ if self.parse_and_check_signature(_txt):
return self.entity[item]
else:
logger.info("Response status: %s" % response.status_code)
@@ -741,7 +748,8 @@ class MetaDataMDX(InMemoryMetaData):
class MetadataStore(object):
def __init__(self, onts, attrc, config, ca_certs=None,
check_validity=True,
- disable_ssl_certificate_validation=False):
+ disable_ssl_certificate_validation=False,
+ filter=None):
"""
:params onts:
:params attrc:
@@ -761,8 +769,14 @@ class MetadataStore(object):
self.ii = 0
self.metadata = {}
self.check_validity = check_validity
+ self.filter = filter
def load(self, typ, *args, **kwargs):
+ if self.filter:
+ _args = {"filter": self.filter}
+ else:
+ _args = {}
+
if typ == "local":
key = args[0]
# if library read every file in the library
@@ -770,20 +784,20 @@ class MetadataStore(object):
files = [f for f in os.listdir(key) if isfile(join(key, f))]
for fil in files:
_fil = join(key, fil)
- _md = MetaDataFile(self.onts, self.attrc, _fil)
+ _md = MetaDataFile(self.onts, self.attrc, _fil, **_args)
_md.load()
self.metadata[_fil] = _md
return
else:
# else it's just a plain old file so read it
- _md = MetaDataFile(self.onts, self.attrc, key)
+ _md = MetaDataFile(self.onts, self.attrc, key, **_args)
elif typ == "inline":
self.ii += 1
key = self.ii
+ kwargs.update(_args)
_md = MetaData(self.onts, self.attrc, args[0], **kwargs)
elif typ == "remote":
key = kwargs["url"]
- _args = {}
for _key in ["node_name", "check_validity"]:
try:
_args[_key] = kwargs[_key]
@@ -794,10 +808,10 @@ class MetadataStore(object):
kwargs["cert"], self.http, **_args)
elif typ == "mdfile":
key = args[0]
- _md = MetaDataMD(self.onts, self.attrc, args[0])
+ _md = MetaDataMD(self.onts, self.attrc, args[0], **_args)
elif typ == "loader":
key = args[0]
- _md = MetaDataLoader(self.onts, self.attrc, args[0])
+ _md = MetaDataLoader(self.onts, self.attrc, args[0], **_args)
else:
raise SAMLError("Unknown metadata type '%s'" % typ)
_md.load()
@@ -837,6 +851,9 @@ class MetadataStore(object):
else:
kwargs = {}
+ if self.filter:
+ kwargs["filter"] = self.filter
+
for key in item['metadata']:
# Separately handle MetaDataFile and directory
if MDloader == MetaDataFile and os.path.isdir(key[0]):