Skip to content

Commit 945d2e6

Browse files
committed
Report is fallback possible
1 parent 98231b3 commit 945d2e6

File tree

3 files changed

+58
-15
lines changed

3 files changed

+58
-15
lines changed

src/main/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcher.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,27 @@ public ValidationResponse validateConfiguration() {
212212
valid = true;
213213
report.computeIfAbsent(ValidationResponse.Level.INFO, k -> new ArrayList<>())
214214
.add("Default dispatcher " + defaultDispatcher + " configuration is valid");
215+
216+
Dispatcher legacy = dispatchers.get(LegacyDispatcher.NAME);
217+
if (legacy == null) {
218+
report.computeIfAbsent(ValidationResponse.Level.INFO, k -> new ArrayList<>())
219+
.add("Legacy dispatcher not present in system");
220+
} else {
221+
// legacy is just "informational" does not affect overall status; merely allows fallback
222+
report.computeIfAbsent(ValidationResponse.Level.INFO, k -> new ArrayList<>())
223+
.add("Legacy dispatcher present in system");
224+
ValidationResponse legacyResponse =
225+
legacy.validateConfiguration(prepareDispatcherConfig(LegacyDispatcher.NAME));
226+
subsystems.add(legacyResponse);
227+
if (!legacyResponse.isValid()) {
228+
report.computeIfAbsent(ValidationResponse.Level.WARNING, k -> new ArrayList<>())
229+
.add(
230+
"Legacy dispatcher not operational; transparent fallback not possible");
231+
} else {
232+
report.computeIfAbsent(ValidationResponse.Level.INFO, k -> new ArrayList<>())
233+
.add("Legacy dispatcher is operational; transparent fallback possible");
234+
}
235+
}
215236
}
216237
}
217238
}

src/main/java/org/codehaus/plexus/components/secdispatcher/internal/dispatchers/LegacyDispatcher.java

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
import java.security.InvalidKeyException;
3232
import java.security.MessageDigest;
3333
import java.security.NoSuchAlgorithmException;
34+
import java.util.ArrayList;
3435
import java.util.Base64;
3536
import java.util.Collection;
37+
import java.util.HashMap;
3638
import java.util.List;
3739
import java.util.Map;
3840

@@ -94,25 +96,42 @@ public EncryptPayload encrypt(String str, Map<String, String> attributes, Map<St
9496
public String decrypt(String str, Map<String, String> attributes, Map<String, String> config)
9597
throws SecDispatcherException {
9698
try {
97-
return legacyCipher.decrypt64(str, getMasterPassword());
99+
String masterPassword = getMasterPassword();
100+
if (masterPassword == null) {
101+
throw new SecDispatcherException("Master password could not be obtained");
102+
}
103+
return legacyCipher.decrypt64(str, masterPassword);
98104
} catch (PlexusCipherException e) {
99105
throw new SecDispatcherException("Decrypt failed", e);
100106
}
101107
}
102108

103109
@Override
104110
public SecDispatcher.ValidationResponse validateConfiguration(Map<String, String> config) {
105-
return new SecDispatcher.ValidationResponse(
106-
getClass().getSimpleName(),
107-
false,
108-
Map.of(
109-
SecDispatcher.ValidationResponse.Level.ERROR,
110-
List.of("This dispatcher cannot and must not be directly used via configuration")),
111-
List.of());
111+
HashMap<SecDispatcher.ValidationResponse.Level, List<String>> report = new HashMap<>();
112+
boolean valid = false;
113+
try {
114+
String mp = getMasterPassword();
115+
if (mp == null) {
116+
report.computeIfAbsent(SecDispatcher.ValidationResponse.Level.ERROR, k -> new ArrayList<>())
117+
.add("Master Password not found");
118+
} else {
119+
report.computeIfAbsent(SecDispatcher.ValidationResponse.Level.INFO, k -> new ArrayList<>())
120+
.add("Master Password found and decrypted");
121+
valid = true;
122+
}
123+
} catch (PlexusCipherException e) {
124+
report.computeIfAbsent(SecDispatcher.ValidationResponse.Level.ERROR, k -> new ArrayList<>())
125+
.add("Master Password could not be decrypted");
126+
}
127+
return new SecDispatcher.ValidationResponse(getClass().getSimpleName(), valid, report, List.of());
112128
}
113129

114130
private String getMasterPassword() throws SecDispatcherException {
115131
String encryptedMasterPassword = getMasterMasterPasswordFromSettingsSecurityXml();
132+
if (encryptedMasterPassword == null) {
133+
return null;
134+
}
116135
return legacyCipher.decrypt64(plexusCipher.unDecorate(encryptedMasterPassword), MASTER_MASTER_PASSWORD);
117136
}
118137

@@ -133,7 +152,7 @@ private String getMasterMasterPasswordFromSettingsSecurityXml() {
133152
// just ignore whatever it is
134153
}
135154
}
136-
throw new SecDispatcherException("Could not locate legacy master password: " + xml);
155+
return null;
137156
}
138157

139158
private static final class LegacyCipher {

src/test/java/org/codehaus/plexus/components/secdispatcher/internal/DefaultSecDispatcherTest.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.codehaus.plexus.components.cipher.internal.AESGCMNoPadding;
2424
import org.codehaus.plexus.components.cipher.internal.DefaultPlexusCipher;
2525
import org.codehaus.plexus.components.secdispatcher.SecDispatcher;
26+
import org.codehaus.plexus.components.secdispatcher.internal.dispatchers.LegacyDispatcher;
2627
import org.codehaus.plexus.components.secdispatcher.internal.dispatchers.MasterDispatcher;
2728
import org.codehaus.plexus.components.secdispatcher.internal.sources.EnvMasterSource;
2829
import org.codehaus.plexus.components.secdispatcher.internal.sources.GpgAgentMasterSource;
@@ -84,11 +85,11 @@ void validate() throws Exception {
8485
SecDispatcher.ValidationResponse response = secDispatcher.validateConfiguration();
8586
assertTrue(response.isValid());
8687
// secDispatcher
87-
assertTrue(response.getReport().size() == 1);
88-
assertTrue(response.getSubsystems().size() == 1);
88+
assertEquals(1, response.getReport().size());
89+
assertEquals(2, response.getSubsystems().size());
8990
// master dispatcher
90-
assertTrue(response.getSubsystems().get(0).getReport().size() == 1);
91-
assertTrue(response.getSubsystems().get(0).getSubsystems().size() == 1);
91+
assertEquals(1, response.getSubsystems().get(0).getReport().size());
92+
assertEquals(1, response.getSubsystems().get(0).getSubsystems().size());
9293
// master source
9394
assertTrue(response.getSubsystems()
9495
.get(0)
@@ -109,7 +110,7 @@ void validate() throws Exception {
109110
protected void roundtrip() throws Exception {
110111
DefaultSecDispatcher sd = construct();
111112

112-
assertEquals(1, sd.availableDispatchers().size());
113+
assertEquals(2, sd.availableDispatchers().size());
113114
String encrypted = sd.encrypt("supersecret", Map.of(SecDispatcher.DISPATCHER_NAME_ATTR, "master", "a", "b"));
114115
// example:
115116
// {[name=master,cipher=AES/GCM/NoPadding,a=b]vvq66pZ7rkvzSPStGTI9q4QDnsmuDwo+LtjraRel2b0XpcGJFdXcYAHAS75HUA6GLpcVtEkmyQ==}
@@ -136,7 +137,9 @@ protected DefaultSecDispatcher construct() {
136137
SystemPropertyMasterSource.NAME,
137138
new SystemPropertyMasterSource(),
138139
GpgAgentMasterSource.NAME,
139-
new GpgAgentMasterSource()))),
140+
new GpgAgentMasterSource())),
141+
"legacy",
142+
new LegacyDispatcher(dpc)),
140143
CONFIG_PATH);
141144
}
142145
}

0 commit comments

Comments
 (0)