Merge branch 'fork/Tony-the-Tech/fix/12.0.x/SslContextFactory_use_credential' into jetty-12.0.x

Updated with call to check if old behaviour has been extended.
This commit is contained in:
gregw 2024-08-28 09:13:22 +10:00
commit 1bf074894a
3 changed files with 103 additions and 21 deletions

View File

@ -816,4 +816,25 @@ public class TypeUtil
int result = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(value - 1)); int result = 1 << (Integer.SIZE - Integer.numberOfLeadingZeros(value - 1));
return result > 0 ? result : Integer.MAX_VALUE; return result > 0 ? result : Integer.MAX_VALUE;
} }
/**
* Test is a method has been declared on the class of an instance
* @param object The object to check
* @param methodName The method name
* @param args The arguments to the method
* @return {@code true} iff {@link Class#getDeclaredMethod(String, Class[])} can be called on the
* {@link Class} of the object, without throwing {@link NoSuchMethodException}.
*/
public static boolean isDeclaredMethodOn(Object object, String methodName, Class<?>... args)
{
try
{
object.getClass().getDeclaredMethod(methodName, args);
return true;
}
catch (NoSuchMethodException e)
{
return false;
}
}
} }

View File

@ -77,6 +77,7 @@ import javax.net.ssl.X509ExtendedTrustManager;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import org.eclipse.jetty.util.StringUtil; import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.ContainerLifeCycle;
@ -86,6 +87,7 @@ import org.eclipse.jetty.util.resource.ResourceFactory;
import org.eclipse.jetty.util.resource.Resources; import org.eclipse.jetty.util.resource.Resources;
import org.eclipse.jetty.util.security.CertificateUtils; import org.eclipse.jetty.util.security.CertificateUtils;
import org.eclipse.jetty.util.security.CertificateValidator; import org.eclipse.jetty.util.security.CertificateValidator;
import org.eclipse.jetty.util.security.Credential;
import org.eclipse.jetty.util.security.Password; import org.eclipse.jetty.util.security.Password;
import org.eclipse.jetty.util.thread.AutoLock; import org.eclipse.jetty.util.thread.AutoLock;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -157,9 +159,9 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
private Resource _trustStoreResource; private Resource _trustStoreResource;
private String _trustStoreProvider; private String _trustStoreProvider;
private String _trustStoreType; private String _trustStoreType;
private Password _keyStorePassword; private Credential _keyStoreCredential;
private Password _keyManagerPassword; private Credential _keyManagerCredential;
private Password _trustStorePassword; private Credential _trustStoreCredential;
private String _sslProvider; private String _sslProvider;
private String _sslProtocol = "TLS"; private String _sslProtocol = "TLS";
private String _secureRandomAlgorithm; private String _secureRandomAlgorithm;
@ -811,46 +813,42 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
public String getKeyStorePassword() public String getKeyStorePassword()
{ {
return _keyStorePassword == null ? null : _keyStorePassword.toString(); return _keyStoreCredential == null ? null : _keyStoreCredential.toString();
} }
/** /**
* @param password The password for the key store. If null is passed and * @param password The password for the key store. If null is passed then
* a keystore is set, then * {@link #getCredential(String)} is used to obtain a password from
* the {@link #getPassword(String)} is used to * the {@value #PASSWORD_PROPERTY} system property.
* obtain a password either from the {@value #PASSWORD_PROPERTY}
* system property.
*/ */
public void setKeyStorePassword(String password) public void setKeyStorePassword(String password)
{ {
_keyStorePassword = password == null ? getPassword(PASSWORD_PROPERTY) : newPassword(password); _keyStoreCredential = password == null ? getCredential(PASSWORD_PROPERTY) : newCredential(password);
} }
public String getKeyManagerPassword() public String getKeyManagerPassword()
{ {
return _keyManagerPassword == null ? null : _keyManagerPassword.toString(); return _keyManagerCredential == null ? null : _keyManagerCredential.toString();
} }
/** /**
* @param password The password (if any) for the specific key within the key store. * @param password The password (if any) for the specific key within the key store.
* If null is passed and the {@value #KEYPASSWORD_PROPERTY} system property is set, * If null is passed then {@link #getCredential(String)} is used to
* then the {@link #getPassword(String)} is used to
* obtain a password from the {@value #KEYPASSWORD_PROPERTY} system property. * obtain a password from the {@value #KEYPASSWORD_PROPERTY} system property.
*/ */
public void setKeyManagerPassword(String password) public void setKeyManagerPassword(String password)
{ {
_keyManagerPassword = password == null ? getPassword(KEYPASSWORD_PROPERTY) : newPassword(password); _keyManagerCredential = password == null ? getCredential(KEYPASSWORD_PROPERTY) : newCredential(password);
} }
/** /**
* @param password The password for the truststore. If null is passed then * @param password The password for the truststore. If null is passed then
* the {@link #getPassword(String)} is used to * {@link #getCredential(String)} is used to obtain a password from the {@value #PASSWORD_PROPERTY}
* obtain a password from the {@value #PASSWORD_PROPERTY}
* system property. * system property.
*/ */
public void setTrustStorePassword(String password) public void setTrustStorePassword(String password)
{ {
_trustStorePassword = password == null ? getPassword(PASSWORD_PROPERTY) : newPassword(password); _trustStoreCredential = password == null ? getCredential(PASSWORD_PROPERTY) : newCredential(password);
} }
/** /**
@ -1133,7 +1131,7 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
*/ */
protected KeyStore loadKeyStore(Resource resource) throws Exception protected KeyStore loadKeyStore(Resource resource) throws Exception
{ {
String storePassword = Objects.toString(_keyStorePassword, null); String storePassword = Objects.toString(_keyStoreCredential, null);
return CertificateUtils.getKeyStore(resource, getKeyStoreType(), getKeyStoreProvider(), storePassword); return CertificateUtils.getKeyStore(resource, getKeyStoreType(), getKeyStoreProvider(), storePassword);
} }
@ -1148,12 +1146,12 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
{ {
String type = Objects.toString(getTrustStoreType(), getKeyStoreType()); String type = Objects.toString(getTrustStoreType(), getKeyStoreType());
String provider = Objects.toString(getTrustStoreProvider(), getKeyStoreProvider()); String provider = Objects.toString(getTrustStoreProvider(), getKeyStoreProvider());
Password passwd = _trustStorePassword; Credential passwd = _trustStoreCredential;
if (resource == null || resource.equals(_keyStoreResource)) if (resource == null || resource.equals(_keyStoreResource))
{ {
resource = _keyStoreResource; resource = _keyStoreResource;
if (passwd == null) if (passwd == null)
passwd = _keyStorePassword; passwd = _keyStoreCredential;
} }
return CertificateUtils.getKeyStore(resource, type, provider, Objects.toString(passwd, null)); return CertificateUtils.getKeyStore(resource, type, provider, Objects.toString(passwd, null));
} }
@ -1180,7 +1178,7 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
if (keyStore != null) if (keyStore != null)
{ {
KeyManagerFactory keyManagerFactory = getKeyManagerFactoryInstance(); KeyManagerFactory keyManagerFactory = getKeyManagerFactoryInstance();
keyManagerFactory.init(keyStore, _keyManagerPassword == null ? (_keyStorePassword == null ? null : _keyStorePassword.toString().toCharArray()) : _keyManagerPassword.toString().toCharArray()); keyManagerFactory.init(keyStore, _keyManagerCredential == null ? (_keyStoreCredential == null ? null : _keyStoreCredential.toString().toCharArray()) : _keyManagerCredential.toString().toCharArray());
managers = keyManagerFactory.getKeyManagers(); managers = keyManagerFactory.getKeyManagers();
if (managers != null) if (managers != null)
@ -1615,7 +1613,9 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
* *
* @param realm the realm * @param realm the realm
* @return the Password object * @return the Password object
* @deprecated use {#link getCredential} instead.
*/ */
@Deprecated(since = "12.0.13", forRemoval = true)
protected Password getPassword(String realm) protected Password getPassword(String realm)
{ {
String password = System.getProperty(realm); String password = System.getProperty(realm);
@ -1627,12 +1627,43 @@ public abstract class SslContextFactory extends ContainerLifeCycle implements Du
* *
* @param password the password string * @param password the password string
* @return the new Password object * @return the new Password object
* @deprecated use {#link newCredential} instead.
*/ */
@Deprecated(since = "12.0.13", forRemoval = true)
public Password newPassword(String password) public Password newPassword(String password)
{ {
return new Password(password); return new Password(password);
} }
/**
* Returns the credential object for the given realm.
*
* @param realm the realm
* @return the Credential object
*/
protected Credential getCredential(String realm)
{
if (TypeUtil.isDeclaredMethodOn(this, "getPassword", String.class))
return getPassword(realm);
String password = System.getProperty(realm);
return password == null ? null : newCredential(password);
}
/**
* Creates a new Credential object.
*
* @param password the password string
* @return the new Credential object
*/
public Credential newCredential(String password)
{
if (TypeUtil.isDeclaredMethodOn(this, "newPassword", String.class))
return newPassword(password);
return Credential.getCredential(password);
}
public SSLServerSocket newSslServerSocket(String host, int port, int backlog) throws IOException public SSLServerSocket newSslServerSocket(String host, int port, int backlog) throws IOException
{ {
checkIsStarted(); checkIsStarted();

View File

@ -267,4 +267,34 @@ public class TypeUtilTest
assertThat(TypeUtil.ceilToNextPowerOfTwo(5), is(8)); assertThat(TypeUtil.ceilToNextPowerOfTwo(5), is(8));
assertThat(TypeUtil.ceilToNextPowerOfTwo(Integer.MAX_VALUE - 1), is(Integer.MAX_VALUE)); assertThat(TypeUtil.ceilToNextPowerOfTwo(Integer.MAX_VALUE - 1), is(Integer.MAX_VALUE));
} }
public static class Base
{
protected String methodA(String arg)
{
return "a" + arg.length();
}
protected String methodB(String arg)
{
return "b" + arg.length();
}
}
public static class Example extends Base
{
@Override
protected String methodB(String arg)
{
return "B" + arg;
}
}
@Test
public void testIsMethodDeclaredOn()
{
Example example = new Example();
assertFalse(TypeUtil.isDeclaredMethodOn(example, "methodA", String.class));
assertTrue(TypeUtil.isDeclaredMethodOn(example, "methodB", String.class));
}
} }