From c935ede6937c85e6258a4f8223dfd749684adc61 Mon Sep 17 00:00:00 2001 From: Tamas Cservenak Date: Mon, 9 Dec 2024 13:25:28 +0100 Subject: [PATCH] Legacy passwords may have leading or trailing comment. (#83) * Legacy passwords may have leading or trailing comment. Fixes #81 --- .../internal/DefaultSecDispatcher.java | 40 ++++++++++++++----- .../internal/DefaultSecDispatcherTest.java | 19 +++++++++ 2 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcher.java b/src/main/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcher.java index b0b692b..2a6fd18 100644 --- a/src/main/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcher.java +++ b/src/main/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcher.java @@ -133,11 +133,17 @@ public String encrypt(String str, Map attr) throws SecDispatcher @Override public String decrypt(String str) throws SecDispatcherException, IOException { - if (!isAnyEncryptedString(str)) return str; - String bare = unDecorate(str); - Map attr = requireNonNull(stripAttributes(bare)); + String bare; + Map attr; if (isLegacyEncryptedString(str)) { + bare = unDecorateLegacy(str); + attr = new HashMap<>(); attr.put(DISPATCHER_NAME_ATTR, LegacyDispatcher.NAME); + } else if (isEncryptedString(str)) { + bare = unDecorate(str); + attr = requireNonNull(stripAttributes(bare)); + } else { + return str; } String name = attr.get(DISPATCHER_NAME_ATTR); Dispatcher dispatcher = dispatchers.get(name); @@ -172,14 +178,20 @@ public boolean isEncryptedString(String str) { */ @Override public boolean isLegacyEncryptedString(String str) { - boolean looksLike = str != null - && !str.isBlank() - && str.startsWith(SHIELD_BEGIN) - && str.endsWith(SHIELD_END) - && !unDecorate(str).contains(SHIELD_BEGIN) - && !unDecorate(str).contains(SHIELD_END); - if (looksLike) { - return stripAttributes(unDecorate(str)).isEmpty(); + if (str != null && str.contains(SHIELD_BEGIN)) { + str = str.substring(str.indexOf(SHIELD_BEGIN)); + if (str.contains(SHIELD_END)) { + str = str.substring(0, str.indexOf(SHIELD_END) + 1); + String undecorated = unDecorate(str); + boolean looksLike = !str.isBlank() + && str.startsWith(SHIELD_BEGIN) + && str.endsWith(SHIELD_END) + && !undecorated.contains(SHIELD_BEGIN) + && !undecorated.contains(SHIELD_END); + if (looksLike) { + return stripAttributes(undecorated).isEmpty(); + } + } } return false; } @@ -309,4 +321,10 @@ protected Map stripAttributes(String str) { protected String unDecorate(String str) { return str.substring(SHIELD_BEGIN.length(), str.length() - SHIELD_END.length()); } + + protected String unDecorateLegacy(String str) { + str = str.substring(str.indexOf(SHIELD_BEGIN)); + str = str.substring(0, str.indexOf(SHIELD_END) + 1); + return unDecorate(str); + } } diff --git a/src/test/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcherTest.java b/src/test/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcherTest.java index 8e27148..352e01e 100644 --- a/src/test/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcherTest.java +++ b/src/test/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcherTest.java @@ -122,16 +122,29 @@ void detection() { assertFalse(secDispatcher.isEncryptedString("{foo}")); assertTrue(secDispatcher.isLegacyEncryptedString("{foo}")); + assertFalse(secDispatcher.isEncryptedString("Oleg was here {foo}")); + assertTrue(secDispatcher.isLegacyEncryptedString("Oleg was here {foo}")); + assertTrue(secDispatcher.isLegacyEncryptedString("Oleg {foo} was here")); assertFalse(secDispatcher.isEncryptedString("{12345678901234567890123456789012345678901234567890}")); assertTrue(secDispatcher.isLegacyEncryptedString("{12345678901234567890123456789012345678901234567890}")); + assertFalse( + secDispatcher.isEncryptedString("Oleg was here {12345678901234567890123456789012345678901234567890}")); + assertTrue(secDispatcher.isLegacyEncryptedString( + "{12345678901234567890123456789012345678901234567890} Oleg was here")); + assertTrue(secDispatcher.isLegacyEncryptedString( + "Oleg {12345678901234567890123456789012345678901234567890} was here")); // contains {} in the middle assertFalse(secDispatcher.isEncryptedString("{KDvsYOFLlX{}gH4LU8tvpzAGg5otiosZXvfdQq0yO86LU=}")); assertFalse(secDispatcher.isLegacyEncryptedString("{KDvsYOFLlX{}gH4LU8tvpzAGg5otiosZXvfdQq0yO86LU=}")); + assertFalse(secDispatcher.isLegacyEncryptedString( + "Oleg was here {KDvsYOFLlX{}gH4LU8tvpzAGg5otiosZXvfdQq0yO86LU=}")); assertFalse(secDispatcher.isEncryptedString("{KDvsYOFLlXgH4LU8tvpzAGg5otiosZXvfdQq0yO86LU=}")); assertTrue(secDispatcher.isLegacyEncryptedString("{KDvsYOFLlXgH4LU8tvpzAGg5otiosZXvfdQq0yO86LU=}")); + assertTrue( + secDispatcher.isLegacyEncryptedString("Oleg was here {KDvsYOFLlXgH4LU8tvpzAGg5otiosZXvfdQq0yO86LU=}")); assertTrue( secDispatcher.isEncryptedString( @@ -192,5 +205,11 @@ void legacy(String xml) throws Exception { SecDispatcher secDispatcher = construct(); String cleartext = secDispatcher.decrypt("{L6L/HbmrY+cH+sNkphnq3fguYepTpM04WlIXb8nB1pk=}"); assertEquals("password", cleartext); + + cleartext = secDispatcher.decrypt("Oleg was here {L6L/HbmrY+cH+sNkphnq3fguYepTpM04WlIXb8nB1pk=}"); + assertEquals("password", cleartext); + + cleartext = secDispatcher.decrypt("Oleg {L6L/HbmrY+cH+sNkphnq3fguYepTpM04WlIXb8nB1pk=} was here"); + assertEquals("password", cleartext); } }