Skip to content

Commit 257a415

Browse files
authored
Merge pull request SAML-Toolkits#356 from mauromol/add-assertion-version-check
Validate assertion version as well in SAML response validation
2 parents 820f581 + 25fab2e commit 257a415

File tree

4 files changed

+59
-4
lines changed

4 files changed

+59
-4
lines changed

core/src/main/java/com/onelogin/saml2/authn/SamlResponse.java

+9-2
Original file line numberDiff line numberDiff line change
@@ -191,9 +191,9 @@ public boolean isValid(String requestId) {
191191
Element rootElement = samlResponseDocument.getDocumentElement();
192192
rootElement.normalize();
193193

194-
// Check SAML version
194+
// Check SAML version on the response
195195
if (!"2.0".equals(rootElement.getAttribute("Version"))) {
196-
throw new ValidationError("Unsupported SAML Version.", ValidationError.UNSUPPORTED_SAML_VERSION);
196+
throw new ValidationError("Unsupported SAML Version on Response.", ValidationError.UNSUPPORTED_SAML_VERSION);
197197
}
198198

199199
// Check ID in the response
@@ -241,6 +241,13 @@ public boolean isValid(String requestId) {
241241
+ ", does not match the ID of the AuthNRequest sent by the SP: " + requestId, ValidationError.WRONG_INRESPONSETO);
242242
}
243243

244+
// Check SAML version on the assertion
245+
NodeList assertions = queryAssertion("");
246+
Node versionAttribute = assertions.item(0).getAttributes().getNamedItem("Version");
247+
if (versionAttribute == null || !"2.0".equals(versionAttribute.getNodeValue())) {
248+
throw new ValidationError("Unsupported SAML Version on Assertion.", ValidationError.UNSUPPORTED_SAML_VERSION);
249+
}
250+
244251
if (!this.encrypted && settings.getWantAssertionsEncrypted()) {
245252
throw new ValidationError("The assertion of the Response is not encrypted and the SP requires it", ValidationError.NO_ENCRYPTED_ASSERTION);
246253
}

core/src/test/java/com/onelogin/saml2/test/authn/AuthnResponseTest.java

+48-2
Original file line numberDiff line numberDiff line change
@@ -1637,7 +1637,7 @@ public void testNoCurrentURL() throws IOException, Error, XPathExpressionExcepti
16371637

16381638
/**
16391639
* Tests the isValid method of SamlResponse
1640-
* Case: invalid version
1640+
* Case: invalid version (the response is not SAML 2.0)
16411641
*
16421642
* @throws IOException
16431643
* @throws Error
@@ -1655,7 +1655,53 @@ public void testValidateVersion() throws IOException, Error, XPathExpressionExce
16551655
String samlResponseEncoded = Util.getFileAsString("data/responses/invalids/no_saml2.xml.base64");
16561656
SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
16571657
assertFalse(samlResponse.isValid());
1658-
assertEquals("Unsupported SAML Version.", samlResponse.getError());
1658+
assertTrue(samlResponse.getError().startsWith("Unsupported SAML Version"));
1659+
}
1660+
1661+
/**
1662+
* Tests the isValid method of SamlResponse
1663+
* Case: invalid response version (although the response may otherwise be valid SAML 2.0)
1664+
*
1665+
* @throws IOException
1666+
* @throws Error
1667+
* @throws ValidationError
1668+
* @throws SettingsException
1669+
* @throws SAXException
1670+
* @throws ParserConfigurationException
1671+
* @throws XPathExpressionException
1672+
*
1673+
* @see com.onelogin.saml2.authn.SamlResponse#isValid
1674+
*/
1675+
@Test
1676+
public void testValidateResponseVersion() throws IOException, Error, XPathExpressionException, ParserConfigurationException, SAXException, SettingsException, ValidationError {
1677+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
1678+
String samlResponseEncoded = Util.getFileAsString("data/responses/invalids/invalid_response_version.xml.base64");
1679+
SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
1680+
assertFalse(samlResponse.isValid());
1681+
assertEquals("Unsupported SAML Version on Response.", samlResponse.getError());
1682+
}
1683+
1684+
/**
1685+
* Tests the isValid method of SamlResponse
1686+
* Case: invalid assertion version (although the response may otherwise be valid SAML 2.0)
1687+
*
1688+
* @throws IOException
1689+
* @throws Error
1690+
* @throws ValidationError
1691+
* @throws SettingsException
1692+
* @throws SAXException
1693+
* @throws ParserConfigurationException
1694+
* @throws XPathExpressionException
1695+
*
1696+
* @see com.onelogin.saml2.authn.SamlResponse#isValid
1697+
*/
1698+
@Test
1699+
public void testValidateAssertionVersion() throws IOException, Error, XPathExpressionException, ParserConfigurationException, SAXException, SettingsException, ValidationError {
1700+
Saml2Settings settings = new SettingsBuilder().fromFile("config/config.min.properties").build();
1701+
String samlResponseEncoded = Util.getFileAsString("data/responses/invalids/invalid_assertion_version.xml.base64");
1702+
SamlResponse samlResponse = new SamlResponse(settings, newHttpRequest(samlResponseEncoded));
1703+
assertFalse(samlResponse.isValid());
1704+
assertEquals("Unsupported SAML Version on Assertion.", samlResponse.getError());
16591705
}
16601706

16611707
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CjxzYW1scDpSZXNwb25zZSB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJRD0iR09TQU1MUjEyOTAxMTc0NTcxNzk0IiBWZXJzaW9uPSIyLjAiIElzc3VlSW5zdGFudD0iMjAxMC0xMS0xOFQyMTo1NzozN1oiIERlc3RpbmF0aW9uPSJ7cmVjaXBpZW50fSI+CiAgPHNhbWxwOlN0YXR1cz4KICAgIDxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz48L3NhbWxwOlN0YXR1cz4KICA8c2FtbDpBc3NlcnRpb24geG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiBWZXJzaW9uPSIxLjAiIElEPSJwZnhhNDY1NzRkZi1iM2IwLWEwNmEtMjNjOC02MzY0MTMxOTg3NzIiIElzc3VlSW5zdGFudD0iMjAxMC0xMS0xOFQyMTo1NzozN1oiPgogICAgPHNhbWw6SXNzdWVyPmh0dHBzOi8vYXBwLm9uZWxvZ2luLmNvbS9zYW1sL21ldGFkYXRhLzEzNTkwPC9zYW1sOklzc3Vlcj4KICAgIDxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPgogICAgICA8ZHM6U2lnbmVkSW5mbz4KICAgICAgICA8ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAgICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4KICAgICAgICA8ZHM6UmVmZXJlbmNlIFVSST0iI3BmeGE0NjU3NGRmLWIzYjAtYTA2YS0yM2M4LTYzNjQxMzE5ODc3MiI+CiAgICAgICAgICA8ZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgICAgPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+CiAgICAgICAgICAgIDxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4KICAgICAgICAgIDwvZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgIDxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPgogICAgICAgICAgPGRzOkRpZ2VzdFZhbHVlPnBKUTdNUy9lazRLUlJXR212L0g0M1JlSFlNcz08L2RzOkRpZ2VzdFZhbHVlPgogICAgICAgIDwvZHM6UmVmZXJlbmNlPgogICAgICA8L2RzOlNpZ25lZEluZm8+CiAgICAgIDxkczpTaWduYXR1cmVWYWx1ZT55aXZlS2NQZERwdUROajZzaHJRM0FCd3IvY0EzQ3J5RDJwaEcveExac3pLV3hVNS9tbGFLdDhld2JaT2RLS3Z0T3MycEhCeTVEdWEzazk0QUYrenhHeWVsNWdPb3dtb3lYSnIrQU9yK2tQTzB2bGkxVjhvM2hQUFVad1JnU1g2UTlwUzFDcVFnaEtpRWFzUnl5bHFxSlVhUFl6bU96T0U4L1hsTWt3aVdtTzA9PC9kczpTaWduYXR1cmVWYWx1ZT4KICAgICAgPGRzOktleUluZm8+CiAgICAgICAgPGRzOlg1MDlEYXRhPgogICAgICAgICAgPGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlCclRDQ0FhR2dBd0lCQWdJQkFUQURCZ0VBTUdjeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJVd0V3WURWUVFIREF4VFlXNTBZU0JOYjI1cFkyRXhFVEFQQmdOVkJBb01DRTl1WlV4dloybHVNUmt3RndZRFZRUUREQkJoY0hBdWIyNWxiRzluYVc0dVkyOXRNQjRYRFRFd01ETXdPVEE1TlRnME5Wb1hEVEUxTURNd09UQTVOVGcwTlZvd1p6RUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2tOaGJHbG1iM0p1YVdFeEZUQVRCZ05WQkFjTURGTmhiblJoSUUxdmJtbGpZVEVSTUE4R0ExVUVDZ3dJVDI1bFRHOW5hVzR4R1RBWEJnTlZCQU1NRUdGd2NDNXZibVZzYjJkcGJpNWpiMjB3Z1o4d0RRWUpLb1pJaHZjTkFRRUJCUUFEZ1kwQU1JR0pBb0dCQU9qU3UxZmpQeThkNXc0UXlMMSt6ZDRoSXcxTWtrZmY0V1kvVExHOE9aa1U1WVRTV21tSFBENWt2WUg1dW9YUy82cVE4MXFYcFIyd1Y4Q1Rvd1pKVUxnMDlkZFJkUm44UXNxajFGeU9DNXNsRTN5MmJaMm9GdWE3Mm9mLzQ5ZnB1am5GVDZLblE2MUNCTXFsRG9UUXFPVDYydkdKOG5QNk1aV3ZBNnN4cXVkNUFnTUJBQUV3QXdZQkFBTUJBQT09PC9kczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgPC9kczpYNTA5RGF0YT4KICAgICAgPC9kczpLZXlJbmZvPgogICAgPC9kczpTaWduYXR1cmU+CiAgICA8c2FtbDpTdWJqZWN0PgogICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDplbWFpbEFkZHJlc3MiPnN1cHBvcnRAb25lbG9naW4uY29tPC9zYW1sOk5hbWVJRD4KICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPgogICAgICAgIDxzYW1sOlN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAxMC0xMS0xOFQyMjowMjozN1oiIFJlY2lwaWVudD0ie3JlY2lwaWVudH0iLz48L3NhbWw6U3ViamVjdENvbmZpcm1hdGlvbj4KICAgIDwvc2FtbDpTdWJqZWN0PgogICAgPHNhbWw6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMTAtMTEtMThUMjE6NTI6MzdaIiBOb3RPbk9yQWZ0ZXI9IjIwMTAtMTEtMThUMjI6MDI6MzdaIj4KICAgICAgPHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4KICAgICAgICA8c2FtbDpBdWRpZW5jZT57YXVkaWVuY2V9PC9zYW1sOkF1ZGllbmNlPgogICAgICA8L3NhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4KICAgIDwvc2FtbDpDb25kaXRpb25zPgogICAgPHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDEwLTExLTE4VDIxOjU3OjM3WiIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAxMC0xMS0xOVQyMTo1NzozN1oiIFNlc3Npb25JbmRleD0iXzUzMWMzMmQyODNiZGZmN2UwNGU0ODdiY2RiYzRkZDhkIj4KICAgICAgPHNhbWw6QXV0aG5Db250ZXh0PgogICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkPC9zYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPgogICAgICA8L3NhbWw6QXV0aG5Db250ZXh0PgogICAgPC9zYW1sOkF1dGhuU3RhdGVtZW50PgogICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50PgogICAgICA8c2FtbDpBdHRyaWJ1dGUgTmFtZT0idWlkIj4KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmRlbW88L3NhbWw6QXR0cmlidXRlVmFsdWU+CiAgICAgIDwvc2FtbDpBdHRyaWJ1dGU+CiAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJhbm90aGVyX3ZhbHVlIj4KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnZhbHVlPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPgogICAgICA8L3NhbWw6QXR0cmlidXRlPgogICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4KICA8L3NhbWw6QXNzZXJ0aW9uPgo8L3NhbWxwOlJlc3BvbnNlPgo=
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CjxzYW1scDpSZXNwb25zZSB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiBJRD0iR09TQU1MUjEyOTAxMTc0NTcxNzk0IiBWZXJzaW9uPSIxLjAiIElzc3VlSW5zdGFudD0iMjAxMC0xMS0xOFQyMTo1NzozN1oiIERlc3RpbmF0aW9uPSJ7cmVjaXBpZW50fSI+CiAgPHNhbWxwOlN0YXR1cz4KICAgIDxzYW1scDpTdGF0dXNDb2RlIFZhbHVlPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6c3RhdHVzOlN1Y2Nlc3MiLz48L3NhbWxwOlN0YXR1cz4KICA8c2FtbDpBc3NlcnRpb24geG1sbnM6eHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiBWZXJzaW9uPSIyLjAiIElEPSJwZnhhNDY1NzRkZi1iM2IwLWEwNmEtMjNjOC02MzY0MTMxOTg3NzIiIElzc3VlSW5zdGFudD0iMjAxMC0xMS0xOFQyMTo1NzozN1oiPgogICAgPHNhbWw6SXNzdWVyPmh0dHBzOi8vYXBwLm9uZWxvZ2luLmNvbS9zYW1sL21ldGFkYXRhLzEzNTkwPC9zYW1sOklzc3Vlcj4KICAgIDxkczpTaWduYXR1cmUgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiPgogICAgICA8ZHM6U2lnbmVkSW5mbz4KICAgICAgICA8ZHM6Q2Fub25pY2FsaXphdGlvbk1ldGhvZCBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvMTAveG1sLWV4Yy1jMTRuIyIvPgogICAgICAgIDxkczpTaWduYXR1cmVNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjcnNhLXNoYTEiLz4KICAgICAgICA8ZHM6UmVmZXJlbmNlIFVSST0iI3BmeGE0NjU3NGRmLWIzYjAtYTA2YS0yM2M4LTYzNjQxMzE5ODc3MiI+CiAgICAgICAgICA8ZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgICAgPGRzOlRyYW5zZm9ybSBBbGdvcml0aG09Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyNlbnZlbG9wZWQtc2lnbmF0dXJlIi8+CiAgICAgICAgICAgIDxkczpUcmFuc2Zvcm0gQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz4KICAgICAgICAgIDwvZHM6VHJhbnNmb3Jtcz4KICAgICAgICAgIDxkczpEaWdlc3RNZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwLzA5L3htbGRzaWcjc2hhMSIvPgogICAgICAgICAgPGRzOkRpZ2VzdFZhbHVlPnBKUTdNUy9lazRLUlJXR212L0g0M1JlSFlNcz08L2RzOkRpZ2VzdFZhbHVlPgogICAgICAgIDwvZHM6UmVmZXJlbmNlPgogICAgICA8L2RzOlNpZ25lZEluZm8+CiAgICAgIDxkczpTaWduYXR1cmVWYWx1ZT55aXZlS2NQZERwdUROajZzaHJRM0FCd3IvY0EzQ3J5RDJwaEcveExac3pLV3hVNS9tbGFLdDhld2JaT2RLS3Z0T3MycEhCeTVEdWEzazk0QUYrenhHeWVsNWdPb3dtb3lYSnIrQU9yK2tQTzB2bGkxVjhvM2hQUFVad1JnU1g2UTlwUzFDcVFnaEtpRWFzUnl5bHFxSlVhUFl6bU96T0U4L1hsTWt3aVdtTzA9PC9kczpTaWduYXR1cmVWYWx1ZT4KICAgICAgPGRzOktleUluZm8+CiAgICAgICAgPGRzOlg1MDlEYXRhPgogICAgICAgICAgPGRzOlg1MDlDZXJ0aWZpY2F0ZT5NSUlCclRDQ0FhR2dBd0lCQWdJQkFUQURCZ0VBTUdjeEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJVd0V3WURWUVFIREF4VFlXNTBZU0JOYjI1cFkyRXhFVEFQQmdOVkJBb01DRTl1WlV4dloybHVNUmt3RndZRFZRUUREQkJoY0hBdWIyNWxiRzluYVc0dVkyOXRNQjRYRFRFd01ETXdPVEE1TlRnME5Wb1hEVEUxTURNd09UQTVOVGcwTlZvd1p6RUxNQWtHQTFVRUJoTUNWVk14RXpBUkJnTlZCQWdNQ2tOaGJHbG1iM0p1YVdFeEZUQVRCZ05WQkFjTURGTmhiblJoSUUxdmJtbGpZVEVSTUE4R0ExVUVDZ3dJVDI1bFRHOW5hVzR4R1RBWEJnTlZCQU1NRUdGd2NDNXZibVZzYjJkcGJpNWpiMjB3Z1o4d0RRWUpLb1pJaHZjTkFRRUJCUUFEZ1kwQU1JR0pBb0dCQU9qU3UxZmpQeThkNXc0UXlMMSt6ZDRoSXcxTWtrZmY0V1kvVExHOE9aa1U1WVRTV21tSFBENWt2WUg1dW9YUy82cVE4MXFYcFIyd1Y4Q1Rvd1pKVUxnMDlkZFJkUm44UXNxajFGeU9DNXNsRTN5MmJaMm9GdWE3Mm9mLzQ5ZnB1am5GVDZLblE2MUNCTXFsRG9UUXFPVDYydkdKOG5QNk1aV3ZBNnN4cXVkNUFnTUJBQUV3QXdZQkFBTUJBQT09PC9kczpYNTA5Q2VydGlmaWNhdGU+CiAgICAgICAgPC9kczpYNTA5RGF0YT4KICAgICAgPC9kczpLZXlJbmZvPgogICAgPC9kczpTaWduYXR1cmU+CiAgICA8c2FtbDpTdWJqZWN0PgogICAgICA8c2FtbDpOYW1lSUQgRm9ybWF0PSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoxLjE6bmFtZWlkLWZvcm1hdDplbWFpbEFkZHJlc3MiPnN1cHBvcnRAb25lbG9naW4uY29tPC9zYW1sOk5hbWVJRD4KICAgICAgPHNhbWw6U3ViamVjdENvbmZpcm1hdGlvbiBNZXRob2Q9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpjbTpiZWFyZXIiPgogICAgICAgIDxzYW1sOlN1YmplY3RDb25maXJtYXRpb25EYXRhIE5vdE9uT3JBZnRlcj0iMjAxMC0xMS0xOFQyMjowMjozN1oiIFJlY2lwaWVudD0ie3JlY2lwaWVudH0iLz48L3NhbWw6U3ViamVjdENvbmZpcm1hdGlvbj4KICAgIDwvc2FtbDpTdWJqZWN0PgogICAgPHNhbWw6Q29uZGl0aW9ucyBOb3RCZWZvcmU9IjIwMTAtMTEtMThUMjE6NTI6MzdaIiBOb3RPbk9yQWZ0ZXI9IjIwMTAtMTEtMThUMjI6MDI6MzdaIj4KICAgICAgPHNhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4KICAgICAgICA8c2FtbDpBdWRpZW5jZT57YXVkaWVuY2V9PC9zYW1sOkF1ZGllbmNlPgogICAgICA8L3NhbWw6QXVkaWVuY2VSZXN0cmljdGlvbj4KICAgIDwvc2FtbDpDb25kaXRpb25zPgogICAgPHNhbWw6QXV0aG5TdGF0ZW1lbnQgQXV0aG5JbnN0YW50PSIyMDEwLTExLTE4VDIxOjU3OjM3WiIgU2Vzc2lvbk5vdE9uT3JBZnRlcj0iMjAxMC0xMS0xOVQyMTo1NzozN1oiIFNlc3Npb25JbmRleD0iXzUzMWMzMmQyODNiZGZmN2UwNGU0ODdiY2RiYzRkZDhkIj4KICAgICAgPHNhbWw6QXV0aG5Db250ZXh0PgogICAgICAgIDxzYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPnVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphYzpjbGFzc2VzOlBhc3N3b3JkPC9zYW1sOkF1dGhuQ29udGV4dENsYXNzUmVmPgogICAgICA8L3NhbWw6QXV0aG5Db250ZXh0PgogICAgPC9zYW1sOkF1dGhuU3RhdGVtZW50PgogICAgPHNhbWw6QXR0cmlidXRlU3RhdGVtZW50PgogICAgICA8c2FtbDpBdHRyaWJ1dGUgTmFtZT0idWlkIj4KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPmRlbW88L3NhbWw6QXR0cmlidXRlVmFsdWU+CiAgICAgIDwvc2FtbDpBdHRyaWJ1dGU+CiAgICAgIDxzYW1sOkF0dHJpYnV0ZSBOYW1lPSJhbm90aGVyX3ZhbHVlIj4KICAgICAgICA8c2FtbDpBdHRyaWJ1dGVWYWx1ZSB4bWxuczp4cz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiIHhzaTp0eXBlPSJ4czpzdHJpbmciPnZhbHVlPC9zYW1sOkF0dHJpYnV0ZVZhbHVlPgogICAgICA8L3NhbWw6QXR0cmlidXRlPgogICAgPC9zYW1sOkF0dHJpYnV0ZVN0YXRlbWVudD4KICA8L3NhbWw6QXNzZXJ0aW9uPgo8L3NhbWxwOlJlc3BvbnNlPgo=

0 commit comments

Comments
 (0)