Skip to content
Snippets Groups Projects
Commit 83b52854 authored by Martin van Es's avatar Martin van Es
Browse files

Rename mdserver to mdsigner and (mdsiger to mdwriter)

parent c3fd0f94
Branches
No related tags found
No related merge requests found
...@@ -8,5 +8,5 @@ meta.key ...@@ -8,5 +8,5 @@ meta.key
hsm.crt hsm.crt
hsm.der hsm.der
*.xml *.xml
mdserver.yaml mdsigner.yaml
mdproxy.yaml mdproxy.yaml
...@@ -12,10 +12,10 @@ Alternate MDX research project ...@@ -12,10 +12,10 @@ Alternate MDX research project
- Download metadata file(s) - Download metadata file(s)
- Run one or more of the tools below - Run one or more of the tools below
## ```mdsigner.py [mdfile] [mdfile] [mdfile] ...``` ## ```mdwriter.py [mdfile] [mdfile] [mdfile] ...```
Reads source metadata file(s) and outputs them signed to filesystem Reads source metadata file(s) and outputs them signed to filesystem
## ```mdserver.py``` ## ```mdsigner.py```
Starts a metadata signer server. Starts a metadata signer server.
Reads source metadata files(s) from mdsigner.yaml configuration, see example. Reads source metadata files(s) from mdsigner.yaml configuration, see example.
Reloads metadata on inotify CLOSE_WRITE of metadata file. Reloads metadata on inotify CLOSE_WRITE of metadata file.
...@@ -23,12 +23,12 @@ Serves and caches signed by realm signer from memory, on request ...@@ -23,12 +23,12 @@ Serves and caches signed by realm signer from memory, on request
## ```mdproxy.py``` ## ```mdproxy.py```
Reads config from mdproxy.yaml configuration, see example. Reads config from mdproxy.yaml configuration, see example.
Caches signed and cached ```mdserver.py``` metadata requests Caches signed and cached ```mdsigner.py``` metadata requests
## Queries ## Queries
MDQ Queries can then be pointed at MDQ Queries can then be pointed at
- ```http://mdserver:5001/<realm>/entities/<entityid>``` - ```http://mdsigner:5001/<realm>/entities/<entityid>```
- ```http://mdproxy:5002/<realm>/entities/<entityid>``` - ```http://mdproxy:5002/<realm>/entities/<entityid>```
## Bootstrap softHSM2 ## Bootstrap softHSM2
......
#!/usr/bin/env python
from utils import read_config, Realm, Server
from flask import Flask, Response
from datetime import datetime
from dateutil import tz
from email.utils import formatdate
from time import mktime
import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
config = read_config('mdserver.yaml')
app = Flask(__name__)
server = Server()
@app.route('/<realm>/entities',
strict_slashes=False,
methods=['GET'])
def serve_all(realm):
print(f"all in {realm}")
response = Response()
response.headers['Content-Type'] = "application/samlmetadata+xml"
response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
data = server[realm].all_entities()
response.data = data.md
max_age = int((data.valid_until -
datetime.now(tz.tzutc())).total_seconds())
response.headers['Cache-Control'] = f"max-age={max_age}"
response.headers['Last-Modified'] = formatdate(
timeval=mktime(data.last_modified.timetuple()),
localtime=False,
usegmt=True)
return response
@app.route('/<realm>/entities/<path:entity_id>',
strict_slashes=False,
methods=['GET'])
def serve_one(realm, entity_id):
print(f"entity_id: {entity_id}")
response = Response()
response.headers['Content-Type'] = "application/samlmetadata+xml"
response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
try:
data = server[realm][entity_id]
response.data = data.md
max_age = data.max_age
last_modified = data.last_modified
except Exception:
response.data = "No valid metadata\n"
response.headers['Content-type'] = "text/html"
response.status = 404
max_age = 60
last_modified = datetime.now(tz.tzutc())
response.headers['Cache-Control'] = f"max-age={max_age}"
response.headers['Last-Modified'] = formatdate(
timeval=mktime(last_modified.timetuple()),
localtime=False,
usegmt=True)
return response
for realm, values in config.items():
print(f"realm: {realm}")
location = values['metadir']
signer = values['signer']
server[realm] = Realm(location, signer)
if __name__ == "__main__":
app.run(host='127.0.0.1', port=5001, debug=False)
#!/usr/bin/env python #!/usr/bin/env python
import sys from utils import read_config, Realm, Server
import copy from flask import Flask, Response
from concurrent.futures import ThreadPoolExecutor from datetime import datetime
from dateutil import tz
from email.utils import formatdate
from time import mktime
from lxml import etree as ET import logging
# import traceback log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
from utils import hasher config = read_config('mdsigner.yaml')
from signers import Signers app = Flask(__name__)
server = Server()
# Find all IdP's in edugain metadata
idps = []
success = 0
failed = 0
maxthreads = 8
signer = Signers('normal_signer')
@app.route('/<realm>/entities',
strict_slashes=False,
methods=['GET'])
def serve_all(realm):
print(f"all in {realm}")
response = Response()
response.headers['Content-Type'] = "application/samlmetadata+xml"
response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
data = server[realm].all_entities()
response.data = data.md
max_age = int((data.valid_until -
datetime.now(tz.tzutc())).total_seconds())
response.headers['Cache-Control'] = f"max-age={max_age}"
response.headers['Last-Modified'] = formatdate(
timeval=mktime(data.last_modified.timetuple()),
localtime=False,
usegmt=True)
return response
@app.route('/<realm>/entities/<path:entity_id>',
strict_slashes=False,
methods=['GET'])
def serve_one(realm, entity_id):
print(f"entity_id: {entity_id}")
response = Response()
response.headers['Content-Type'] = "application/samlmetadata+xml"
response.headers['Content-Disposition'] = "filename = \"metadata.xml\""
def sign(xml, name):
global success, failed, cert, key
# print("Signer")
try: try:
sha1 = hasher(name) data = server[realm][entity_id]
signed = signer(xml) response.data = data.md
out = ET.tostring(signed, pretty_print=True).decode() max_age = data.max_age
# XMLVerifier().verify(out, x509_cert=cert) last_modified = data.last_modified
with open(f'output/{sha1}.xml', 'w') as f: except Exception:
f.write(out) response.data = "No valid metadata\n"
success += 1 response.headers['Content-type'] = "text/html"
except Exception as e: response.status = 404
print(name) max_age = 60
print(f" {e}") last_modified = datetime.now(tz.tzutc())
# traceback.print_exc()
failed += 1 response.headers['Cache-Control'] = f"max-age={max_age}"
response.headers['Last-Modified'] = formatdate(
timeval=mktime(last_modified.timetuple()),
with ThreadPoolExecutor(max_workers=maxthreads) as executor: localtime=False,
for mdfile in sys.argv[1:]: usegmt=True)
tree = ET.ElementTree(file=mdfile) return response
root = tree.getroot()
ns = copy.deepcopy(root.nsmap)
ns['xml'] = 'http://www.w3.org/XML/1998/namespace' for realm, values in config.items():
print(f"realm: {realm}")
for idp in root.findall('md:EntityDescriptor', ns): location = values['metadir']
entityID = idp.attrib.get('entityID', 'none') signer = values['signer']
if entityID not in idps: server[realm] = Realm(location, signer)
idps.append(entityID)
executor.submit(sign, idp, entityID) if __name__ == "__main__":
app.run(host='127.0.0.1', port=5001, debug=False)
print(f"Succeeded: {success}")
print(f"Failed: {failed}")
[Unit] [Unit]
Description=MDServer Description=MDSigner
After=syslog.target network.target After=syslog.target network.target
[Service] [Service]
Type=simple Type=simple
WorkingDirectory=/opt/alternate-mdx WorkingDirectory=/opt/alternate-mdx
ExecStart=/opt/alternate-mdx/bin/python -u mdserver.py ExecStart=/opt/alternate-mdx/bin/python -u mdsigner.py
ExecReload=/bin/kill -HUP $MAINPID ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure Restart=on-failure
RestartSec=10 RestartSec=10
SyslogIdentifier=mdserver SyslogIdentifier=mdsigner
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
#!/usr/bin/env python
import sys
import copy
from concurrent.futures import ThreadPoolExecutor
from lxml import etree as ET
# import traceback
from utils import hasher
from signers import Signers
# Find all IdP's in edugain metadata
idps = []
success = 0
failed = 0
maxthreads = 8
signer = Signers('normal_signer')
def sign(xml, name):
global success, failed, cert, key
# print("Signer")
try:
sha1 = hasher(name)
signed = signer(xml)
out = ET.tostring(signed, pretty_print=True).decode()
# XMLVerifier().verify(out, x509_cert=cert)
with open(f'output/{sha1}.xml', 'w') as f:
f.write(out)
success += 1
except Exception as e:
print(name)
print(f" {e}")
# traceback.print_exc()
failed += 1
with ThreadPoolExecutor(max_workers=maxthreads) as executor:
for mdfile in sys.argv[1:]:
tree = ET.ElementTree(file=mdfile)
root = tree.getroot()
ns = copy.deepcopy(root.nsmap)
ns['xml'] = 'http://www.w3.org/XML/1998/namespace'
for idp in root.findall('md:EntityDescriptor', ns):
entityID = idp.attrib.get('entityID', 'none')
if entityID not in idps:
idps.append(entityID)
executor.submit(sign, idp, entityID)
print(f"Succeeded: {success}")
print(f"Failed: {failed}")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment