diff --git a/entities_security_contacts.py b/entities_security_contacts.py index 247cd0e89ebf1a5b3da6923dc61638da22ba2e51..404fed6aa8aa0463a0b9ddf769aa889e34efa0ff 100755 --- a/entities_security_contacts.py +++ b/entities_security_contacts.py @@ -34,7 +34,7 @@ entities = root.findall('./md:EntityDescriptor', ns) for entity in entities: sec_mails = set() - + entity_id = entity.attrib['entityID'].strip() registration_authority = '' registration_info = entity.find('./md:Extensions/mdrpi:RegistrationInfo', ns) if registration_info == None: @@ -70,7 +70,8 @@ for entity in entities: for mail in sec_mails: if (domain,mail) not in seen_doms_mails: seen_doms_mails.add((domain, mail)) - contacts.add('{},{},{},{}'.format(registration_authority, domain, mail, orgname)) + contacts.add('{},{},{},{},{}'.format(registration_authority, entity_id, domain, mail, orgname)) for contact in sorted(contacts): + print('RegistrationAuthority,entityID,scope,security-contact,OrganizationName') print(contact) diff --git a/entity_details.py b/entity_details.py new file mode 100755 index 0000000000000000000000000000000000000000..76bb783826885b6f748f171b7917bfa4721e5bfd --- /dev/null +++ b/entity_details.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 + +import sys +import argparse +import requests +from xml.etree import ElementTree as ET + + +# DEFINE SOME VARS + +entity_id = None +metadata_file = None +root = None +tec_contact = '' +sup_contact = '' +adm_contact = '' + + +# ARGPARSE + +parser = argparse.ArgumentParser(description='Show detailed information about an eduGAIN entity.', + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=''' +Examples + +- Retrieve details about a single entity using eduGAIN metadata:\n +./entity_details.py https://idp.dir.garr.it/idp/shibboleth\n\n + +- Retrieve details for a list of idps using a local metadata file:\n +./entity_details.py -e idp_list -f edugain-v2.xml +''') +group = parser.add_mutually_exclusive_group() +group.add_argument('ENTITYID', nargs='?', help='entityID of the entity to look up') +group.add_argument('-e', type=str, help='load entityIDs from file E') +parser.add_argument('-f', type=str, help='load metadata from file F') +parser.add_argument('-u', type=str, default='https://mds.edugain.org/edugain-v2.xml', + help='download metadata from url U (default to https://mds.edugain.org/edugain-v2.xml)') +args = parser.parse_args() + +# METHDO TO RETRIVE FED NAME + +feds_request = requests.get("https://technical.edugain.org/api.php?action=list_feds&format") +feds = feds_request.json() + +def get_fed_name(registration_authority): + for key in feds: + if feds[key]['reg_auth'] == registration_authority: + return feds[key]['name'] + return None + +# MAIN + +entities = [] + +if args.ENTITYID: + entities.append(args.ENTITYID) +elif args.e: + with open(args.e, 'r') as entitiesfile: + entities = entitiesfile.readlines() +else: + parser.parse_args(['-h']) + exit(1) + +if args.f: + tree = ET.parse(args.f) + root = tree.getroot() +else: + xml_req = requests.get(args.u) + root = ET.fromstring(xml_req.content) + +orgs = set() + +ns = { + 'md': 'urn:oasis:names:tc:SAML:2.0:metadata', + 'mdui': 'urn:oasis:names:tc:SAML:metadata:ui', + 'shibmd': 'urn:mace:shibboleth:metadata:1.0', + 'remd': 'http://refeds.org/metadata', + 'icmd': 'http://id.incommon.org/metadata', + 'mdrpi': 'urn:oasis:names:tc:SAML:metadata:rpi', +} + +print('entityID,FederationName,RegistrationAuthority,OrganizationName,TechnicalContact,SupportContact,AdministrativeContact') + +for entity_id in entities: + + entity = root.find(f'./md:EntityDescriptor[@entityID="{entity_id.strip()}"]', ns) + + if entity: + + registration_authority = None + registration_info = entity.find('./md:Extensions/mdrpi:RegistrationInfo', ns) + + if registration_info: + registration_authority = registration_info.attrib['registrationAuthority'].strip() + fed_name = get_fed_name(registration_authority) + + orgname = entity.find('./md:Organization/md:OrganizationDisplayName', ns).text.strip() + + tec_contact_el = entity.find('./md:ContactPerson[@contactType="technical"]/md:EmailAddress', ns) + if tec_contact_el is not None: + tec_contact = tec_contact_el.text.replace('mailto:', '') + sup_contact_el = entity.find('./md:ContactPerson[@contactType="support"]/md:EmailAddress', ns) + if sup_contact_el is not None: + sup_contact = sup_contact_el.text.replace('mailto:', '') + adm_contact_el = entity.find('./md:ContactPerson[@contactType="administrative"]/md:EmailAddress', ns) + if adm_contact_el is not None: + adm_contact = adm_contact_el.text.replace('mailto:', '') + + print('{},{},{},{},{},{}'.format(entity_id, fed_name, registration_authority, orgname, tec_contact, sup_contact, adm_contact)) + + else: + + print(f'No such entityID: {entity_id}')