diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java index d976dcd8f8c..d671c8f95fc 100644 --- a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslContextFactory.java @@ -72,6 +72,8 @@ import javax.net.ssl.X509TrustManager; import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; @@ -85,7 +87,7 @@ import org.eclipse.jetty.util.security.Password; * creates SSL context based on these parameters to be * used by the SSL connectors. */ -public class SslContextFactory extends AbstractLifeCycle +public class SslContextFactory extends AbstractLifeCycle implements Dumpable { public final static TrustManager[] TRUST_ALL_CERTS = new X509TrustManager[]{new X509TrustManager() { @@ -327,7 +329,39 @@ public class SslContextFactory extends AbstractLifeCycle LOG.debug("Selected Ciphers {} of {}", Arrays.asList(_selectedCipherSuites), Arrays.asList(supported.getCipherSuites())); } } - + + @Override + public String dump() + { + return ContainerLifeCycle.dump(this); + } + + @Override + public void dump(Appendable out, String indent) throws IOException + { + out.append(String.valueOf(this)).append(" trustAll=").append(Boolean.toString(_trustAll)).append(System.lineSeparator()); + + SSLEngine sslEngine = newSSLEngine(); + + List selections = new ArrayList<>(); + + // protocols + selections.add(new SslSelectionDump("Protocol", + sslEngine.getSupportedProtocols(), + sslEngine.getEnabledProtocols(), + getExcludeProtocols(), + getIncludeProtocols())); + + // ciphers + selections.add(new SslSelectionDump("Cipher Suite", + sslEngine.getSupportedCipherSuites(), + sslEngine.getEnabledCipherSuites(), + getExcludeCipherSuites(), + getIncludeCipherSuites())); + + ContainerLifeCycle.dump(out, indent, selections); + } + @Override protected void doStop() throws Exception { diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslSelectionDump.java b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslSelectionDump.java new file mode 100644 index 00000000000..125be3a8b4f --- /dev/null +++ b/jetty-util/src/main/java/org/eclipse/jetty/util/ssl/SslSelectionDump.java @@ -0,0 +1,156 @@ +package org.eclipse.jetty.util.ssl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.eclipse.jetty.util.component.ContainerLifeCycle; +import org.eclipse.jetty.util.component.Dumpable; + +public class SslSelectionDump extends ContainerLifeCycle implements Dumpable +{ + private static class CaptionedList extends ArrayList implements Dumpable + { + private final String caption; + + public CaptionedList(String caption) + { + this.caption = caption; + } + + @Override + public String dump() + { + return ContainerLifeCycle.dump(SslSelectionDump.CaptionedList.this); + } + + @Override + public void dump(Appendable out, String indent) throws IOException + { + out.append(caption); + out.append(" (size=").append(Integer.toString(size())).append(")"); + out.append(System.lineSeparator()); + ContainerLifeCycle.dump(out, indent, this); + } + } + + private final String type; + private SslSelectionDump.CaptionedList enabled = new SslSelectionDump.CaptionedList("Enabled"); + private SslSelectionDump.CaptionedList disabled = new SslSelectionDump.CaptionedList("Disabled"); + + public SslSelectionDump(String type, + String[] supportedByJVM, + String[] enabledByJVM, + String[] excludedByConfig, + String[] includedByConfig) + { + this.type = type; + addBean(enabled); + addBean(disabled); + + List jvmEnabled = Arrays.asList(enabledByJVM); + List excludedPatterns = Arrays.stream(excludedByConfig) + .map((entry) -> Pattern.compile(entry)) + .collect(Collectors.toList()); + List includedPatterns = Arrays.stream(includedByConfig) + .map((entry) -> Pattern.compile(entry)) + .collect(Collectors.toList()); + + Arrays.stream(supportedByJVM) + .sorted(Comparator.naturalOrder()) + .forEach((entry) -> + { + boolean isPresent = true; + + StringBuilder s = new StringBuilder(); + s.append(entry); + if (!jvmEnabled.contains(entry)) + { + if (isPresent) + { + s.append(" -"); + isPresent = false; + } + s.append(" JreDisabled:java.security"); + } + + for (Pattern pattern : excludedPatterns) + { + Matcher m = pattern.matcher(entry); + if (m.matches()) + { + if (isPresent) + { + s.append(" -"); + isPresent = false; + } + else + { + s.append(","); + } + s.append(" ConfigExcluded:'").append(pattern.pattern()).append('\''); + } + } + + if (!includedPatterns.isEmpty()) + { + boolean isIncluded = false; + for (Pattern pattern : includedPatterns) + { + Matcher m = pattern.matcher(entry); + if (m.matches()) + { + isIncluded = true; + break; + } + } + + if (!isIncluded) + { + if (isPresent) + { + s.append(" -"); + isPresent = false; + } + else + { + s.append(","); + } + s.append(" ConfigIncluded:NotSpecified"); + } + } + + if (isPresent) + { + enabled.add(s.toString()); + } + else + { + disabled.add(s.toString()); + } + }); + } + + @Override + public String dump() + { + return ContainerLifeCycle.dump(this); + } + + @Override + public void dump(Appendable out, String indent) throws IOException + { + dumpBeans(out, indent); + } + + @Override + protected void dumpThis(Appendable out) throws IOException + { + out.append(type).append(" Selections").append(System.lineSeparator()); + } +} diff --git a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java index fedf95e8532..f49bfaa8000 100644 --- a/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java +++ b/jetty-util/src/test/java/org/eclipse/jetty/util/ssl/SslContextFactoryTest.java @@ -29,7 +29,6 @@ import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; -import java.util.Arrays; import javax.net.ssl.SSLEngine; @@ -62,11 +61,8 @@ public class SslContextFactoryTest cf.setKeyManagerPassword("keypwd"); cf.start(); - - System.err.println(Arrays.asList(cf.getSelectedProtocols())); - for (String cipher : cf.getSelectedCipherSuites()) - System.err.println(cipher); - + + cf.dump(System.out, ""); } @Test