Files
Personalpy/aws_google_saml/inspect_saml.py
2026-01-25 11:38:48 -05:00

82 lines
2.6 KiB
Python

#!/usr/bin/env python3
import sys, subprocess
from xml.etree import ElementTree as ET
fn = "saml-response.xml"
ns = {
'p': 'urn:oasis:names:tc:SAML:2.0:protocol',
's': 'urn:oasis:names:tc:SAML:2.0:assertion',
'ds': 'http://www.w3.org/2000/09/xmldsig#'
}
try:
root = ET.parse(fn).getroot()
except Exception as e:
print("ERROR: cannot parse saml-response.xml:", e)
sys.exit(1)
def find_text(path, default=""):
el = root.find(path, ns)
return el.text.strip() if el is not None and el.text else default
# Status (StatusCode Value attribute)
status_el = root.find('.//p:Status/p:StatusCode', ns)
status = status_el.get('Value') if status_el is not None else ""
print("Status: " + status)
# NameID
nameid = find_text('.//s:NameID')
print("Name: " + nameid)
# Audience
aud = find_text('.//s:Audience')
print("Audience: " + aud)
# Recipient (SubjectConfirmationData @Recipient)
rec_el = root.find('.//s:Subject/s:SubjectConfirmation/s:SubjectConfirmationData', ns)
recipient = rec_el.get('Recipient') if rec_el is not None else ""
print("Recipient: " + recipient)
# Extract cert and write PEM with proper line breaks
cert_el = root.find('.//ds:X509Certificate', ns)
if cert_el is None or not cert_el.text or not cert_el.text.strip():
print("no-cert-found")
sys.exit(0)
b64 = "".join(cert_el.text.split())
pem = "-----BEGIN CERTIFICATE-----\n"
# wrap at 64 chars per line
for i in range(0, len(b64), 64):
pem += b64[i:i+64] + "\n"
pem += "-----END CERTIFICATE-----\n"
with open("google_cert.pem", "w") as f:
f.write(pem)
# Try to print openssl fingerprint
try:
out = subprocess.check_output(['openssl','x509','-in','google_cert.pem','-noout','-fingerprint','-sha256'], stderr=subprocess.STDOUT)
print(out.decode().strip())
except Exception as e:
print("openssl-not-available-or-error")
# Print all Attribute values for AWS Role and RoleSessionName
role_attr = root.find('.//s:Attribute[@Name="https://aws.amazon.com/SAML/Attributes/Role"]', ns)
if role_attr is not None:
vals = [v.text.strip() for v in role_attr.findall('.//s:AttributeValue', ns) if v.text]
for v in vals:
print("ROLE_ATTRIBUTE_VALUE: " + v)
else:
print("ROLE_ATTRIBUTE_VALUE: not-present")
role_session_attr = root.find('.//s:Attribute[@Name="https://aws.amazon.com/SAML/Attributes/RoleSessionName"]', ns)
if role_session_attr is not None:
vals = [v.text.strip() for v in role_session_attr.findall('.//s:AttributeValue', ns) if v.text]
for v in vals:
print("ROLE_SESSION_NAME_VALUE: " + v)
else:
print("ROLE_SESSION_NAME_VALUE: not-present")