Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions src/satosa/metadata_creation/saml_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@


def _create_entity_descriptor(entity_config):
cnf = Config().load(copy.deepcopy(entity_config))
cnf = entity_config if isinstance(entity_config, Config) else Config().load(copy.deepcopy(entity_config))
return entity_descriptor(cnf)


Expand All @@ -28,7 +28,7 @@ def _create_backend_metadata(backend_modules):
if isinstance(plugin_module, SAMLBackend):
logline = "Generating SAML backend '{}' metadata".format(plugin_module.name)
logger.info(logline)
backend_metadata[plugin_module.name] = [_create_entity_descriptor(plugin_module.config["sp_config"])]
backend_metadata[plugin_module.name] = [_create_entity_descriptor(plugin_module.sp.config)]

return backend_metadata

Expand Down Expand Up @@ -154,3 +154,18 @@ def create_signed_entity_descriptor(entity_descriptor, security_context, valid_f
raise ValueError("Could not construct valid EntityDescriptor tag")

return xmldoc


def create_entity_descriptor_metadata(entity_descriptor, valid_for=None):
"""
:param entity_descriptor: the entity descriptor to create metadata for
:param valid_for: number of hours the metadata should be valid
:return: the EntityDescriptor metadata

:type entity_descriptor: saml2.md.EntityDescriptor]
:type valid_for: Optional[int]
"""
if valid_for:
entity_descriptor.valid_until = in_a_while(hours=valid_for)

return str(entity_descriptor)
45 changes: 31 additions & 14 deletions src/satosa/scripts/satosa_saml_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from saml2.sigver import security_context

from ..metadata_creation.saml_metadata import create_entity_descriptors
from ..metadata_creation.saml_metadata import create_entity_descriptor_metadata
from ..metadata_creation.saml_metadata import create_signed_entity_descriptor
from ..satosa_config import SATOSAConfig

Expand All @@ -16,44 +17,58 @@ def _get_security_context(key, cert):
return security_context(conf)


def _create_split_entity_descriptors(entities, secc, valid):
def _create_split_entity_descriptors(entities, secc, valid, sign=True):
output = []
for module_name, eds in entities.items():
for i, ed in enumerate(eds):
output.append((create_signed_entity_descriptor(ed, secc, valid), "{}_{}.xml".format(module_name, i)))
ed_str = (
create_signed_entity_descriptor(ed, secc, valid)
if sign
else create_entity_descriptor_metadata(ed, valid)
)
output.append((ed_str, "{}_{}.xml".format(module_name, i)))

return output


def _create_merged_entities_descriptors(entities, secc, valid, name):
def _create_merged_entities_descriptors(entities, secc, valid, name, sign=True):
output = []
frontend_entity_descriptors = [e for sublist in entities.values() for e in sublist]
for frontend in frontend_entity_descriptors:
output.append((create_signed_entity_descriptor(frontend, secc, valid), name))
ed_str = (
create_signed_entity_descriptor(frontend, secc, valid)
if sign
else create_entity_descriptor_metadata(frontend, valid)
)
output.append((ed_str, name))

return output


def create_and_write_saml_metadata(proxy_conf, key, cert, dir, valid, split_frontend_metadata=False,
split_backend_metadata=False):
split_backend_metadata=False, sign=True):
"""
Generates SAML metadata for the given PROXY_CONF, signed with the given KEY and associated CERT.
"""
satosa_config = SATOSAConfig(proxy_conf)
secc = _get_security_context(key, cert)

if sign and (not key or not cert):
raise ValueError("Key and cert are required when signing")
secc = _get_security_context(key, cert) if sign else None

frontend_entities, backend_entities = create_entity_descriptors(satosa_config)

output = []
if frontend_entities:
if split_frontend_metadata:
output.extend(_create_split_entity_descriptors(frontend_entities, secc, valid))
output.extend(_create_split_entity_descriptors(frontend_entities, secc, valid, sign))
else:
output.extend(_create_merged_entities_descriptors(frontend_entities, secc, valid, "frontend.xml"))
output.extend(_create_merged_entities_descriptors(frontend_entities, secc, valid, "frontend.xml", sign))
if backend_entities:
if split_backend_metadata:
output.extend(_create_split_entity_descriptors(backend_entities, secc, valid))
output.extend(_create_split_entity_descriptors(backend_entities, secc, valid, sign))
else:
output.extend(_create_merged_entities_descriptors(backend_entities, secc, valid, "backend.xml"))
output.extend(_create_merged_entities_descriptors(backend_entities, secc, valid, "backend.xml", sign))

for metadata, filename in output:
path = os.path.join(dir, filename)
Expand All @@ -64,8 +79,8 @@ def create_and_write_saml_metadata(proxy_conf, key, cert, dir, valid, split_fron

@click.command()
@click.argument("proxy_conf")
@click.argument("key")
@click.argument("cert")
@click.argument("key", required=False)
@click.argument("cert", required=False)
@click.option("--dir",
type=click.Path(exists=True, file_okay=False, dir_okay=True, writable=True, readable=False,
resolve_path=False),
Expand All @@ -75,5 +90,7 @@ def create_and_write_saml_metadata(proxy_conf, key, cert, dir, valid, split_fron
help="Create one entity descriptor per file for the frontend metadata")
@click.option("--split-backend", is_flag=True, type=click.BOOL, default=False,
help="Create one entity descriptor per file for the backend metadata")
def construct_saml_metadata(proxy_conf, key, cert, dir, valid, split_frontend, split_backend):
create_and_write_saml_metadata(proxy_conf, key, cert, dir, valid, split_frontend, split_backend)
@click.option("--sign/--no-sign", is_flag=True, type=click.BOOL, default=True,
help="Sign the generated metadata")
def construct_saml_metadata(proxy_conf, key, cert, dir, valid, split_frontend, split_backend, sign):
create_and_write_saml_metadata(proxy_conf, key, cert, dir, valid, split_frontend, split_backend, sign)