From a86682d585e74c73c764b40e2df80fc0f4fe0a57 Mon Sep 17 00:00:00 2001 From: IevaVasiljeva Date: Fri, 18 Aug 2023 17:15:09 +0100 Subject: [PATCH 1/3] change how the list of namespaces that apply to an element is constructed --- service_provider.go | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/service_provider.go b/service_provider.go index a63bdfe1..c36ff56d 100644 --- a/service_provider.go +++ b/service_provider.go @@ -1656,18 +1656,25 @@ func findChild(parentEl *etree.Element, childNS string, childTag string) (*etree } func elementToBytes(el *etree.Element) ([]byte, error) { + // Retrieve namespaces from the element itself and its parents namespaces := map[string]string{} - for _, childEl := range el.FindElements("//*") { - ns := childEl.NamespaceURI() - if ns != "" { - namespaces[childEl.Space] = ns + currentElement := el + for currentElement != nil { + for _, attr := range currentElement.Attr { + if attr.Space == "xmlns" || attr.Key == "xmlns" { + fmt.Println("namespace, fuckers") + if _, prefixExists := namespaces[attr.FullKey()]; !prefixExists { + namespaces[attr.FullKey()] = attr.Value + } + } } + currentElement = currentElement.Parent() } doc := etree.NewDocument() doc.SetRoot(el.Copy()) - for space, uri := range namespaces { - doc.Root().CreateAttr("xmlns:"+space, uri) + for prefix, uri := range namespaces { + doc.Root().CreateAttr(prefix, uri) } return doc.WriteToBytes() From beee70d9e487062b1a2c827b0e51cef35a203d3f Mon Sep 17 00:00:00 2001 From: IevaVasiljeva Date: Fri, 18 Aug 2023 17:21:11 +0100 Subject: [PATCH 2/3] remove a comment --- service_provider.go | 1 - 1 file changed, 1 deletion(-) diff --git a/service_provider.go b/service_provider.go index c36ff56d..3855971d 100644 --- a/service_provider.go +++ b/service_provider.go @@ -1662,7 +1662,6 @@ func elementToBytes(el *etree.Element) ([]byte, error) { for currentElement != nil { for _, attr := range currentElement.Attr { if attr.Space == "xmlns" || attr.Key == "xmlns" { - fmt.Println("namespace, fuckers") if _, prefixExists := namespaces[attr.FullKey()]; !prefixExists { namespaces[attr.FullKey()] = attr.Value } From df6f988a0c6bd576dc6ff1a97d1a46fc69741c7c Mon Sep 17 00:00:00 2001 From: IevaVasiljeva Date: Wed, 23 Aug 2023 16:15:58 +0100 Subject: [PATCH 3/3] add comments and a test --- service_provider.go | 5 +++- service_provider_test.go | 25 +++++++++++++++++++ testdata/TestSPWithDefaultNamespace | 1 + .../TestSPWithDefaultNamespace_idp_metadata | 1 + 4 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 testdata/TestSPWithDefaultNamespace create mode 100644 testdata/TestSPWithDefaultNamespace_idp_metadata diff --git a/service_provider.go b/service_provider.go index 3855971d..23eec556 100644 --- a/service_provider.go +++ b/service_provider.go @@ -1656,12 +1656,15 @@ func findChild(parentEl *etree.Element, childNS string, childTag string) (*etree } func elementToBytes(el *etree.Element) ([]byte, error) { - // Retrieve namespaces from the element itself and its parents namespaces := map[string]string{} currentElement := el + // Retrieve namespaces from the element itself and its parents for currentElement != nil { + // Iterate over the attributes of the element, if an attribute is a namespace declaration, add it to the list of namespaces for _, attr := range currentElement.Attr { + // "xmlns" is either the space or the key of the attribute, depending on whether it is a default namespace declaration or not if attr.Space == "xmlns" || attr.Key == "xmlns" { + // If the namespace is already preset in the list, it means that a child element has overriden it, so skip it if _, prefixExists := namespaces[attr.FullKey()]; !prefixExists { namespaces[attr.FullKey()] = attr.Value } diff --git a/service_provider_test.go b/service_provider_test.go index cdf5c723..1389c290 100644 --- a/service_provider_test.go +++ b/service_provider_test.go @@ -1851,3 +1851,28 @@ func TestMultipleAssertions(t *testing.T) { assert.Check(t, err) assert.Check(t, profile.Subject.NameID.Value != "admin@evil.com") } + +func TestResponseWithDefaultNamespace(t *testing.T) { + idpMetadata := golden.Get(t, "TestSPWithDefaultNamespace_idp_metadata") + respStr := golden.Get(t, "TestSPWithDefaultNamespace") + TimeNow = func() time.Time { + rv, _ := time.Parse("Mon Jan 2 15:04:05 MST 2006", "Fri Apr 21 13:12:51 UTC 2017") + return rv + } + Clock = dsig.NewFakeClockAt(TimeNow()) + s := ServiceProvider{ + Key: mustParsePrivateKey(golden.Get(t, "key_2017.pem")).(*rsa.PrivateKey), + Certificate: mustParseCertificate(golden.Get(t, "cert_2017.pem")), + MetadataURL: mustParseURL("https://sp.example.com/saml2/metadata"), + AcsURL: mustParseURL("https://sp.example.com/saml2/acs"), + IDPMetadata: &EntityDescriptor{}, + } + err := xml.Unmarshal(idpMetadata, &s.IDPMetadata) + assert.NilError(t, err) + + req := http.Request{PostForm: url.Values{}} + req.PostForm.Set("SAMLResponse", base64.StdEncoding.EncodeToString(respStr)) + _, err = s.ParseResponse(&req, []string{"id-00020406080a0c0e10121416181a1c1e"}) + + assert.NilError(t, err) +} diff --git a/testdata/TestSPWithDefaultNamespace b/testdata/TestSPWithDefaultNamespace new file mode 100644 index 00000000..ef5512a6 --- /dev/null +++ b/testdata/TestSPWithDefaultNamespace @@ -0,0 +1 @@ +https://idp.example.com/saml/metadatak/YYE7FN38le10KY8AOrpSN8HQc=KhB4vVN3JxVfjJnrIV12kzKawGgp7V9EkUPp4Pqak1R++rN7GluYy+okQHUKhmD71qokmhpxKbVTCt/IAS4pumd3yRZg/kT0xeG/U9qoNIzzqJECYev7mOjyKRxfJEahcTEu0QDuge0uNf5Uj21oQMqdcV4C4jCLwW2zWLYFLpf+IJPVjQjDL7cogffq7c5AD8fpS6ad7lt7tbWxjOLt1xyDoJRcEYbZrV2QrWpJ64V8R+Y0pzsMJ85r6gPtZpZRuqPeOtP3NOrR3XdT2w435SngGR0mqwvcGGOvgXuHz7xePrhKDxZCBc6Bx7VUOgLlMTXDlmmQf50W3aypMGEoNg==MIIDRTCCAi2gAwIBAgIJANke+OUVRk19MA0GCSqGSIb3DQEBBQUAMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTAeFw0xNzA0MTkxOTU2MTNaFw0xODA0MTkxOTU2MTNaMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ7tsAJqJ4rUZFT/5SjvoA1mpQBC+KidcehMsTFW/9l73cPnYNhtnNe+9S8n76eF2ASuEwAKN5xoXDP297y4ZOORnkouP8jiYZjqNHTckE9LevM8YOpTPVojhq+rq7hiQyMF6pJkBPgduolcsnBg188jn/oNmdmzIaS33QiNOZ6FGXLKt3/Fapscea0gq8a46wKhFFQmW8i+MGqdSSi255c05ZZL5H04plDNoGEvES5OsxSjbZ4+294K83nOXoGSEPfsO4XUTORlryis0p/f3aNUgooueeTphD9Go2pGHYvahjusx9ONbZ7egc07dJoIAVjgaMSv+UwqfpxjAU7018sCAwEAAaOBgTB/MB0GA1UdDgQWBBSYE9Nwp/eUqfRQ11rqwoowNFHNyTBQBgNVHSMESTBHgBSYE9Nwp/eUqfRQ11rqwoowNFHNyaEkpCIwIDEeMBwGA1UEAxMVbXlzZXJ2aWNlLmV4YW1wbGUuY29tggkA2R745RVGTX0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAVJmpMg1ZpDGweoCU4k66RVDpPzSuPJ+9H9L2jcaA38itDtXmG9IzdbOLpNF9fDbU60P421SgS0nF/s7zkxkYJWOoZaced/vUO6H9TdWEZay+uywAjvoZGwkZ9HxYMqKMVld4EwW/OwT67UVBdtgkSfI1O7ojqDOFx7U4+HJWxUEwGOc0pOPzNyLSYCsAkQt2CZU7dN72L96Ka8xxklNaVcUaUH+zOWF1JBamV9s6M2umcdBot8MO3m1zQTkXzBKM3f+Yvk+dRjO4TSW90h2oQqot8xrkPhy+DgOqJj3/lKmZXjqE5mAEhpQB0uVPekPvKN89hCnkPo2EvXKPf7VZgg==https://idp.example.com/saml/metadataunqkaATYuvJT2koFrke8ArX8K9s=Qzb+/IyJgHq2WLR4PyCXNX2pR87GYm0pDm0yBcKjcISo3i8S9Xm04yxqm+zxYb+4HuReB6ZJHId2Jhaz9Ny0aDmj0WMa2QDpeCugffhDdgEEhNiqCpZJVLfACK6QpgqLnsKccalM2VPexU96Q73INxz/zNQKw0Dltf/GBRCbEbJKcHNIX/Xg7CPJdV2sgAGPVlXbZ5vahW3Oy+7HUcGVajZTc6P5DrLEIQRSsZgHZLv4RSvbKBxQc/CvIzVagDWJDD5kJniqf9JGYVZ8j4MQeb8u0VtDlijvrq008Ia566OGom3qj7trdxYdz+Co0ZPJra4c9sKyDa3udXW428fqog==MIIDRTCCAi2gAwIBAgIJANke+OUVRk19MA0GCSqGSIb3DQEBBQUAMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTAeFw0xNzA0MTkxOTU2MTNaFw0xODA0MTkxOTU2MTNaMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ7tsAJqJ4rUZFT/5SjvoA1mpQBC+KidcehMsTFW/9l73cPnYNhtnNe+9S8n76eF2ASuEwAKN5xoXDP297y4ZOORnkouP8jiYZjqNHTckE9LevM8YOpTPVojhq+rq7hiQyMF6pJkBPgduolcsnBg188jn/oNmdmzIaS33QiNOZ6FGXLKt3/Fapscea0gq8a46wKhFFQmW8i+MGqdSSi255c05ZZL5H04plDNoGEvES5OsxSjbZ4+294K83nOXoGSEPfsO4XUTORlryis0p/f3aNUgooueeTphD9Go2pGHYvahjusx9ONbZ7egc07dJoIAVjgaMSv+UwqfpxjAU7018sCAwEAAaOBgTB/MB0GA1UdDgQWBBSYE9Nwp/eUqfRQ11rqwoowNFHNyTBQBgNVHSMESTBHgBSYE9Nwp/eUqfRQ11rqwoowNFHNyaEkpCIwIDEeMBwGA1UEAxMVbXlzZXJ2aWNlLmV4YW1wbGUuY29tggkA2R745RVGTX0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAVJmpMg1ZpDGweoCU4k66RVDpPzSuPJ+9H9L2jcaA38itDtXmG9IzdbOLpNF9fDbU60P421SgS0nF/s7zkxkYJWOoZaced/vUO6H9TdWEZay+uywAjvoZGwkZ9HxYMqKMVld4EwW/OwT67UVBdtgkSfI1O7ojqDOFx7U4+HJWxUEwGOc0pOPzNyLSYCsAkQt2CZU7dN72L96Ka8xxklNaVcUaUH+zOWF1JBamV9s6M2umcdBot8MO3m1zQTkXzBKM3f+Yvk+dRjO4TSW90h2oQqot8xrkPhy+DgOqJj3/lKmZXjqE5mAEhpQB0uVPekPvKN89hCnkPo2EvXKPf7VZgg==https://sp.example.com/saml2/metadataurn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransportalice diff --git a/testdata/TestSPWithDefaultNamespace_idp_metadata b/testdata/TestSPWithDefaultNamespace_idp_metadata new file mode 100644 index 00000000..faa6c89f --- /dev/null +++ b/testdata/TestSPWithDefaultNamespace_idp_metadata @@ -0,0 +1 @@ +MIIDRTCCAi2gAwIBAgIJANke+OUVRk19MA0GCSqGSIb3DQEBBQUAMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTAeFw0xNzA0MTkxOTU2MTNaFw0xODA0MTkxOTU2MTNaMCAxHjAcBgNVBAMTFW15c2VydmljZS5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ7tsAJqJ4rUZFT/5SjvoA1mpQBC+KidcehMsTFW/9l73cPnYNhtnNe+9S8n76eF2ASuEwAKN5xoXDP297y4ZOORnkouP8jiYZjqNHTckE9LevM8YOpTPVojhq+rq7hiQyMF6pJkBPgduolcsnBg188jn/oNmdmzIaS33QiNOZ6FGXLKt3/Fapscea0gq8a46wKhFFQmW8i+MGqdSSi255c05ZZL5H04plDNoGEvES5OsxSjbZ4+294K83nOXoGSEPfsO4XUTORlryis0p/f3aNUgooueeTphD9Go2pGHYvahjusx9ONbZ7egc07dJoIAVjgaMSv+UwqfpxjAU7018sCAwEAAaOBgTB/MB0GA1UdDgQWBBSYE9Nwp/eUqfRQ11rqwoowNFHNyTBQBgNVHSMESTBHgBSYE9Nwp/eUqfRQ11rqwoowNFHNyaEkpCIwIDEeMBwGA1UEAxMVbXlzZXJ2aWNlLmV4YW1wbGUuY29tggkA2R745RVGTX0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAVJmpMg1ZpDGweoCU4k66RVDpPzSuPJ+9H9L2jcaA38itDtXmG9IzdbOLpNF9fDbU60P421SgS0nF/s7zkxkYJWOoZaced/vUO6H9TdWEZay+uywAjvoZGwkZ9HxYMqKMVld4EwW/OwT67UVBdtgkSfI1O7ojqDOFx7U4+HJWxUEwGOc0pOPzNyLSYCsAkQt2CZU7dN72L96Ka8xxklNaVcUaUH+zOWF1JBamV9s6M2umcdBot8MO3m1zQTkXzBKM3f+Yvk+dRjO4TSW90h2oQqot8xrkPhy+DgOqJj3/lKmZXjqE5mAEhpQB0uVPekPvKN89hCnkPo2EvXKPf7VZgg==urn:oasis:names:tc:SAML:2.0:nameid-format:transient