X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-ssh%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fssh%2Fosgi%2FNetconfSSHActivator.java;h=a26843fae17a97621b48221a932eb9b823a6ce83;hb=16fcdf1a2169bcee3c0c8c0966deab134713036f;hp=d74308cfadbae8e658e58f9b189d93baaea83c2e;hpb=0552aa7d15d9482a9c24062786a743adca4ab74a;p=controller.git diff --git a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java index d74308cfad..a26843fae1 100644 --- a/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java +++ b/opendaylight/netconf/netconf-ssh/src/main/java/org/opendaylight/controller/netconf/ssh/osgi/NetconfSSHActivator.java @@ -7,24 +7,24 @@ */ package org.opendaylight.controller.netconf.ssh.osgi; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import com.google.common.base.Optional; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.local.LocalAddress; +import io.netty.channel.nio.NioEventLoopGroup; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.opendaylight.controller.netconf.ssh.NetconfSSHServer; import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider; import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator; import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil; -import org.opendaylight.controller.usermanager.IUserManager; +import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil.InfixProp; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.ServiceTracker; -import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,112 +32,56 @@ import org.slf4j.LoggerFactory; * Activator for netconf SSH bundle which creates SSH bridge between netconf client and netconf server. Activator * starts SSH Server in its own thread. This thread is closed when activator calls stop() method. Server opens socket * and listens for client connections. Each client connection creation is handled in separate - * {@link org.opendaylight.controller.netconf.ssh.threads.SocketThread} thread. + * {@link org.opendaylight.controller.netconf.ssh.threads.Handshaker} thread. * This thread creates two additional threads {@link org.opendaylight.controller.netconf.ssh.threads.IOThread} * forwarding data from/to client.IOThread closes servers session and server connection when it gets -1 on input stream. * {@link org.opendaylight.controller.netconf.ssh.threads.IOThread}'s run method waits for -1 on input stream to finish. * All threads are daemons. - **/ -public class NetconfSSHActivator implements BundleActivator{ + */ +public class NetconfSSHActivator implements BundleActivator { + private static final Logger logger = LoggerFactory.getLogger(NetconfSSHActivator.class); private NetconfSSHServer server; - private static final Logger logger = LoggerFactory.getLogger(NetconfSSHActivator.class); - private IUserManager iUserManager; - private BundleContext context = null; - - private ServiceTrackerCustomizer customizer = new ServiceTrackerCustomizer(){ - @Override - public IUserManager addingService(final ServiceReference reference) { - logger.trace("Service {} added, let there be SSH bridge.", reference); - iUserManager = context.getService(reference); - try { - onUserManagerFound(iUserManager); - } catch (final Exception e) { - logger.trace("Can't start SSH server due to {}",e); - } - return iUserManager; - } - @Override - public void modifiedService(final ServiceReference reference, final IUserManager service) { - logger.trace("Replacing modified service {} in netconf SSH.", reference); - server.addUserManagerService(service); - } - @Override - public void removedService(final ServiceReference reference, final IUserManager service) { - logger.trace("Removing service {} from netconf SSH. " + - "SSH won't authenticate users until IUserManager service will be started.", reference); - removeUserManagerService(); - } - }; - @Override - public void start(final BundleContext context) { - this.context = context; - listenForManagerService(); + public void start(final BundleContext bundleContext) throws IOException { + server = startSSHServer(bundleContext); } @Override public void stop(BundleContext context) throws IOException { - if (server != null){ - server.stop(); - logger.trace("Netconf SSH bridge is down ..."); + if (server != null) { + server.close(); } } - private void startSSHServer() throws IOException { - checkNotNull(this.iUserManager, "No user manager service available."); - logger.trace("Starting netconf SSH bridge."); - final InetSocketAddress sshSocketAddress = NetconfConfigUtil.extractSSHNetconfAddress(context, - NetconfConfigUtil.DEFAULT_NETCONF_SSH_ADDRESS); - final InetSocketAddress tcpSocketAddress = NetconfConfigUtil.extractTCPNetconfClientAddress(context, - NetconfConfigUtil.DEFAULT_NETCONF_TCP_ADDRESS); - String path = FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(context)); + private static NetconfSSHServer startSSHServer(BundleContext bundleContext) throws IOException { + Optional maybeSshSocketAddress = NetconfConfigUtil.extractNetconfServerAddress(bundleContext, + InfixProp.ssh); - if (path.isEmpty()) { - throw new IllegalStateException("Missing netconf.ssh.pk.path key in configuration file."); + if (maybeSshSocketAddress.isPresent() == false) { + logger.trace("SSH bridge not configured"); + return null; } + InetSocketAddress sshSocketAddress = maybeSshSocketAddress.get(); + logger.trace("Starting netconf SSH bridge at {}", sshSocketAddress); - final File privateKeyFile = new File(path); - final String privateKeyPEMString; - if (privateKeyFile.exists() == false) { - // generate & save to file - try { - privateKeyPEMString = PEMGenerator.generateTo(privateKeyFile); - } catch (Exception e) { - logger.error("Exception occurred while generating PEM string {}", e); - throw new IllegalStateException("Error generating RSA key from file " + path); - } - } else { - // read from file - try (FileInputStream fis = new FileInputStream(path)) { - privateKeyPEMString = IOUtils.toString(fis); - } catch (final IOException e) { - logger.error("Error reading RSA key from file '{}'", path); - throw new IOException("Error reading RSA key from file " + path, e); - } - } - final AuthProvider authProvider = new AuthProvider(iUserManager, privateKeyPEMString); - this.server = NetconfSSHServer.start(sshSocketAddress.getPort(), tcpSocketAddress, authProvider); + LocalAddress localAddress = NetconfConfigUtil.getNetconfLocalAddress(); + + String path = FilenameUtils.separatorsToSystem(NetconfConfigUtil.getPrivateKeyPath(bundleContext)); + checkState(StringUtils.isNotBlank(path), "Path to ssh private key is blank. Reconfigure %s", NetconfConfigUtil.getPrivateKeyKey()); + String privateKeyPEMString = PEMGenerator.readOrGeneratePK(new File(path)); + + final AuthProvider authProvider = new AuthProvider(privateKeyPEMString, bundleContext); + EventLoopGroup bossGroup = new NioEventLoopGroup(); + NetconfSSHServer server = NetconfSSHServer.start(sshSocketAddress.getPort(), localAddress, authProvider, bossGroup); final Thread serverThread = new Thread(server, "netconf SSH server thread"); serverThread.setDaemon(true); serverThread.start(); logger.trace("Netconf SSH bridge up and running."); + return server; } - private void onUserManagerFound(final IUserManager userManager) throws Exception{ - if (server!=null && server.isUp()){ - server.addUserManagerService(userManager); - } else { - startSSHServer(); - } - } - private void removeUserManagerService(){ - this.server.removeUserManagerService(); - } - private void listenForManagerService(){ - final ServiceTracker listenerTracker = new ServiceTracker<>(context, IUserManager.class,customizer); - listenerTracker.open(); - } + }