From: Robert Varga Date: Sun, 28 Jan 2024 20:48:32 +0000 (+0100) Subject: Refactor ClientFactoryManagerConfigurator X-Git-Tag: v7.0.0~36 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=64e0deaed38a06b0d1dc962726a94b3b1c4ab75a;p=netconf.git Refactor ClientFactoryManagerConfigurator Turn the interface into an abstract class, so that we can evolve -- most of the use cases boil down to authentication, it would seem. JIRA: NETCONF-1238 Change-Id: Ieef402a8879a86780bff65614397aae158903495 Signed-off-by: Robert Varga --- diff --git a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeSshServer.java b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeSshServer.java index 27286b8182..49eb4c0174 100644 --- a/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeSshServer.java +++ b/apps/callhome-provider/src/main/java/org/opendaylight/netconf/topology/callhome/CallHomeSshServer.java @@ -20,6 +20,7 @@ import java.util.concurrent.TimeoutException; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.netconf.api.TransportConstants; import org.opendaylight.netconf.client.NetconfClientSessionNegotiatorFactory; +import org.opendaylight.netconf.shaded.sshd.client.ClientFactoryManager; import org.opendaylight.netconf.shaded.sshd.client.auth.password.UserAuthPasswordFactory; import org.opendaylight.netconf.shaded.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; import org.opendaylight.netconf.shaded.sshd.client.session.ClientSession; @@ -68,11 +69,17 @@ public final class CallHomeSshServer implements AutoCloseable { // NB actual username will be assigned dynamically but predefined one is required for transport initialization final var sshClientParams = new SshClientParametersBuilder().setClientIdentity( new ClientIdentityBuilder().setUsername("ignored").build()).build(); - final ClientFactoryManagerConfigurator configurator = factoryMgr -> { - factoryMgr.setServerKeyVerifier(this::verifyServerKey); - factoryMgr.addSessionListener(createSessionListener()); - // supported auth factories - factoryMgr.setUserAuthFactories(List.of(new UserAuthPasswordFactory(), new UserAuthPublicKeyFactory())); + final var configurator = new ClientFactoryManagerConfigurator() { + @Override + protected void configureClientFactoryManager(final ClientFactoryManager factoryManager) { + factoryManager.setServerKeyVerifier((clientSession, remoteAddress, serverKey) + -> verifyServerKey(clientSession, remoteAddress, serverKey)); + factoryManager.addSessionListener(createSessionListener()); + // supported auth factories + factoryManager.setUserAuthFactories(List.of( + new UserAuthPasswordFactory(), + new UserAuthPublicKeyFactory())); + } }; try { client = transportStackFactory.listenClient(TransportConstants.SSH_SUBSYSTEM, transportChannelListener, diff --git a/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactoryImpl.java b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactoryImpl.java index 24dcad0f53..82fd1f9400 100644 --- a/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactoryImpl.java +++ b/apps/netconf-topology/src/main/java/org/opendaylight/netconf/topology/spi/NetconfClientConfigurationBuilderFactoryImpl.java @@ -19,8 +19,11 @@ import org.opendaylight.netconf.client.conf.NetconfClientConfiguration.NetconfCl import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder; import org.opendaylight.netconf.client.mdsal.api.CredentialProvider; import org.opendaylight.netconf.client.mdsal.api.SslContextFactoryProvider; +import org.opendaylight.netconf.shaded.sshd.client.ClientFactoryManager; import org.opendaylight.netconf.shaded.sshd.client.auth.pubkey.UserAuthPublicKeyFactory; import org.opendaylight.netconf.shaded.sshd.common.keyprovider.KeyIdentityProvider; +import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException; +import org.opendaylight.netconf.transport.ssh.ClientFactoryManagerConfigurator; import org.opendaylight.netconf.transport.tls.FixedSslHandlerFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.crypto.types.rev240208.password.grouping.password.type.CleartextPasswordBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.client.rev240208.netconf.client.initiate.stack.grouping.transport.ssh.ssh.SshClientParametersBuilder; @@ -115,16 +118,20 @@ public final class NetconfClientConfigurationBuilderFactoryImpl implements Netco } else if (credentials instanceof KeyAuth keyAuth) { final var keyBased = keyAuth.getKeyBased(); sshParamsBuilder.setClientIdentity(new ClientIdentityBuilder().setUsername(keyBased.getUsername()).build()); - confBuilder.withSshConfigurator(factoryMgr -> { - final var keyId = keyBased.getKeyId(); - final var keyPair = credentialProvider.credentialForId(keyId); - if (keyPair == null) { - throw new IllegalArgumentException("No keypair found with keyId=" + keyId); + confBuilder.withSshConfigurator(new ClientFactoryManagerConfigurator() { + @Override + protected void configureClientFactoryManager(final ClientFactoryManager factoryManager) + throws UnsupportedConfigurationException { + final var keyId = keyBased.getKeyId(); + final var keyPair = credentialProvider.credentialForId(keyId); + if (keyPair == null) { + throw new IllegalArgumentException("No keypair found with keyId=" + keyId); + } + factoryManager.setKeyIdentityProvider(KeyIdentityProvider.wrapKeyPairs(keyPair)); + final var factory = new UserAuthPublicKeyFactory(); + factory.setSignatureFactories(factoryManager.getSignatureFactories()); + factoryManager.setUserAuthFactories(List.of(factory)); } - factoryMgr.setKeyIdentityProvider(KeyIdentityProvider.wrapKeyPairs(keyPair)); - final var factory = new UserAuthPublicKeyFactory(); - factory.setSignatureFactories(factoryMgr.getSignatureFactories()); - factoryMgr.setUserAuthFactories(List.of(factory)); }); } else { throw new IllegalArgumentException("Unsupported credential type: " + credentials.getClass()); diff --git a/protocol/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientFactoryImplTest.java b/protocol/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientFactoryImplTest.java index 6fb783be5a..e349d774fe 100644 --- a/protocol/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientFactoryImplTest.java +++ b/protocol/netconf-client/src/test/java/org/opendaylight/netconf/client/NetconfClientFactoryImplTest.java @@ -47,6 +47,7 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.opendaylight.netconf.client.conf.NetconfClientConfiguration; import org.opendaylight.netconf.client.conf.NetconfClientConfigurationBuilder; import org.opendaylight.netconf.common.impl.DefaultNetconfTimer; +import org.opendaylight.netconf.shaded.sshd.client.ClientFactoryManager; import org.opendaylight.netconf.shaded.sshd.client.auth.password.PasswordIdentityProvider; import org.opendaylight.netconf.shaded.sshd.server.auth.password.UserAuthPasswordFactory; import org.opendaylight.netconf.shaded.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; @@ -281,10 +282,13 @@ class NetconfClientFactoryImplTest { (usr, psw, session) -> USERNAME.equals(usr) && PASSWORD.equals(psw)); factoryManager.setKeyPairProvider(new SimpleGeneratorHostKeyProvider()); }; - final ClientFactoryManagerConfigurator clientConfigurator = factoryManager -> { - factoryManager.setPasswordIdentityProvider(PasswordIdentityProvider.wrapPasswords(PASSWORD)); - factoryManager.setUserAuthFactories(List.of( - new org.opendaylight.netconf.shaded.sshd.client.auth.password.UserAuthPasswordFactory())); + final var clientConfigurator = new ClientFactoryManagerConfigurator() { + @Override + protected void configureClientFactoryManager(final ClientFactoryManager factoryManager) { + factoryManager.setPasswordIdentityProvider(PasswordIdentityProvider.wrapPasswords(PASSWORD)); + factoryManager.setUserAuthFactories(List.of( + new org.opendaylight.netconf.shaded.sshd.client.auth.password.UserAuthPasswordFactory())); + } }; final var server = SERVER_FACTORY.listenServer("netconf", serverTransportListener, tcpServerParams, diff --git a/transport/transport-ssh/src/main/java/org/opendaylight/netconf/transport/ssh/ClientFactoryManagerConfigurator.java b/transport/transport-ssh/src/main/java/org/opendaylight/netconf/transport/ssh/ClientFactoryManagerConfigurator.java index bdc2e98750..935106af91 100644 --- a/transport/transport-ssh/src/main/java/org/opendaylight/netconf/transport/ssh/ClientFactoryManagerConfigurator.java +++ b/transport/transport-ssh/src/main/java/org/opendaylight/netconf/transport/ssh/ClientFactoryManagerConfigurator.java @@ -15,14 +15,13 @@ import org.opendaylight.netconf.transport.api.UnsupportedConfigurationException; * Extension interface allowing one to customize {@link ClientFactoryManager} before it is used to create the * {@link SSHClient} instance. */ -@FunctionalInterface -public interface ClientFactoryManagerConfigurator { +public abstract class ClientFactoryManagerConfigurator { /** * Apply custom configuration. * * @param factoryManager client factory manager instance * @throws UnsupportedConfigurationException if the configuration is not acceptable */ - void configureClientFactoryManager(@NonNull ClientFactoryManager factoryManager) + protected abstract void configureClientFactoryManager(@NonNull ClientFactoryManager factoryManager) throws UnsupportedConfigurationException; } diff --git a/transport/transport-ssh/src/test/java/org/opendaylight/netconf/transport/ssh/SshClientServerTest.java b/transport/transport-ssh/src/test/java/org/opendaylight/netconf/transport/ssh/SshClientServerTest.java index 5c2feda4dd..2341a881d4 100644 --- a/transport/transport-ssh/src/test/java/org/opendaylight/netconf/transport/ssh/SshClientServerTest.java +++ b/transport/transport-ssh/src/test/java/org/opendaylight/netconf/transport/ssh/SshClientServerTest.java @@ -55,6 +55,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import org.opendaylight.netconf.shaded.sshd.client.ClientFactoryManager; import org.opendaylight.netconf.shaded.sshd.client.auth.password.PasswordIdentityProvider; import org.opendaylight.netconf.shaded.sshd.client.session.ClientSession; import org.opendaylight.netconf.shaded.sshd.common.session.Session; @@ -338,10 +339,14 @@ public class SshClientServerTest { } private static ClientFactoryManagerConfigurator clientConfigurator(final String username) { - return factoryManager -> { - factoryManager.setPasswordIdentityProvider(PasswordIdentityProvider.wrapPasswords(PASSWORD)); - factoryManager.setUserAuthFactories(List.of( - new org.opendaylight.netconf.shaded.sshd.client.auth.password.UserAuthPasswordFactory())); + return new ClientFactoryManagerConfigurator() { + @Override + protected void configureClientFactoryManager(final ClientFactoryManager factoryManager) + throws UnsupportedConfigurationException { + factoryManager.setPasswordIdentityProvider(PasswordIdentityProvider.wrapPasswords(PASSWORD)); + factoryManager.setUserAuthFactories(List.of( + new org.opendaylight.netconf.shaded.sshd.client.auth.password.UserAuthPasswordFactory())); + } }; }