Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
alternate-mdx
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Trust and Identity Incubator
alternate-mdx
Commits
83b52854
Commit
83b52854
authored
3 years ago
by
Martin van Es
Browse files
Options
Downloads
Patches
Plain Diff
Rename mdserver to mdsigner and (mdsiger to mdwriter)
parent
c3fd0f94
No related branches found
No related tags found
No related merge requests found
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
.gitignore
+1
-1
1 addition, 1 deletion
.gitignore
README.md
+4
-4
4 additions, 4 deletions
README.md
mdserver.py
+0
-76
0 additions, 76 deletions
mdserver.py
mdsigner.py
+69
-45
69 additions, 45 deletions
mdsigner.py
mdsigner.service
+3
-3
3 additions, 3 deletions
mdsigner.service
mdwriter.py
+52
-0
52 additions, 0 deletions
mdwriter.py
with
129 additions
and
129 deletions
.gitignore
+
1
−
1
View file @
83b52854
...
...
@@ -8,5 +8,5 @@ meta.key
hsm.crt
hsm.der
*.xml
mds
erv
er.yaml
mds
ign
er.yaml
mdproxy.yaml
This diff is collapsed.
Click to expand it.
README.md
+
4
−
4
View file @
83b52854
...
...
@@ -12,10 +12,10 @@ Alternate MDX research project
-
Download metadata file(s)
-
Run one or more of the tools below
## ```md
sign
er.py [mdfile] [mdfile] [mdfile] ...```
## ```md
writ
er.py [mdfile] [mdfile] [mdfile] ...```
Reads source metadata file(s) and outputs them signed to filesystem
## ```mds
erv
er.py```
## ```mds
ign
er.py```
Starts a metadata signer server.
Reads source metadata files(s) from mdsigner.yaml configuration, see example.
Reloads metadata on inotify CLOSE_WRITE of metadata file.
...
...
@@ -23,12 +23,12 @@ Serves and caches signed by realm signer from memory, on request
## ```mdproxy.py```
Reads config from mdproxy.yaml configuration, see example.
Caches signed and cached
```mds
erv
er.py```
metadata requests
Caches signed and cached
```mds
ign
er.py```
metadata requests
## Queries
MDQ Queries can then be pointed at
-
```http://mds
erv
er:5001/<realm>/entities/<entityid>```
-
```http://mds
ign
er:5001/<realm>/entities/<entityid>```
-
```http://mdproxy:5002/<realm>/entities/<entityid>```
## Bootstrap softHSM2
...
...
This diff is collapsed.
Click to expand it.
mdserver.py
deleted
100755 → 0
+
0
−
76
View file @
c3fd0f94
#!/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
)
This diff is collapsed.
Click to expand it.
mdsigner.py
+
69
−
45
View file @
83b52854
#!/usr/bin/env python
import
sys
import
copy
from
concurrent.futures
import
ThreadPoolExecutor
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
from
lxml
import
etree
as
ET
# import traceback
import
logging
log
=
logging
.
getLogger
(
'
werkzeug
'
)
log
.
setLevel
(
logging
.
ERROR
)
from
utils
import
hasher
from
signers
import
Signers
config
=
read_config
(
'
mdsigner.yaml
'
)
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
:
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
}
"
)
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
)
This diff is collapsed.
Click to expand it.
mds
erv
er.service
→
mds
ign
er.service
+
3
−
3
View file @
83b52854
[Unit]
Description
=
MDS
erv
er
Description
=
MDS
ign
er
After
=
syslog.target network.target
[Service]
Type
=
simple
WorkingDirectory
=
/opt/alternate-mdx
ExecStart
=
/opt/alternate-mdx/bin/python -u mds
erv
er.py
ExecStart
=
/opt/alternate-mdx/bin/python -u mds
ign
er.py
ExecReload
=
/bin/kill -HUP $MAINPID
Restart
=
on-failure
RestartSec
=
10
SyslogIdentifier
=
mds
erv
er
SyslogIdentifier
=
mds
ign
er
[Install]
WantedBy
=
multi-user.target
This diff is collapsed.
Click to expand it.
mdwriter.py
0 → 100755
+
52
−
0
View file @
83b52854
#!/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
}
"
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment