2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.netconf.ssh;
11 import com.google.common.collect.Lists;
12 import io.netty.channel.EventLoopGroup;
13 import io.netty.channel.local.LocalAddress;
14 import java.io.IOException;
15 import java.net.InetSocketAddress;
16 import java.nio.channels.AsynchronousChannelGroup;
17 import java.util.concurrent.ExecutorService;
18 import java.util.concurrent.ScheduledExecutorService;
19 import java.util.concurrent.TimeUnit;
20 import org.apache.sshd.SshServer;
21 import org.apache.sshd.common.FactoryManager;
22 import org.apache.sshd.common.KeyPairProvider;
23 import org.apache.sshd.common.NamedFactory;
24 import org.apache.sshd.common.RuntimeSshException;
25 import org.apache.sshd.common.io.IoAcceptor;
26 import org.apache.sshd.common.io.IoConnector;
27 import org.apache.sshd.common.io.IoHandler;
28 import org.apache.sshd.common.io.IoServiceFactory;
29 import org.apache.sshd.common.io.IoServiceFactoryFactory;
30 import org.apache.sshd.common.io.nio2.Nio2Acceptor;
31 import org.apache.sshd.common.io.nio2.Nio2Connector;
32 import org.apache.sshd.common.io.nio2.Nio2ServiceFactoryFactory;
33 import org.apache.sshd.common.util.CloseableUtils;
34 import org.apache.sshd.server.Command;
35 import org.apache.sshd.server.PasswordAuthenticator;
38 * Proxy SSH server that just delegates decrypted content to a delegate server within same VM.
39 * Implemented using Apache Mina SSH lib.
41 public class SshProxyServer implements AutoCloseable {
43 private final SshServer sshServer;
44 private final ScheduledExecutorService minaTimerExecutor;
45 private final EventLoopGroup clientGroup;
46 private final IoServiceFactoryFactory nioServiceWithPoolFactoryFactory;
48 public SshProxyServer(final ScheduledExecutorService minaTimerExecutor, final EventLoopGroup clientGroup, final ExecutorService nioExecutor) {
49 this.minaTimerExecutor = minaTimerExecutor;
50 this.clientGroup = clientGroup;
51 this.nioServiceWithPoolFactoryFactory = new NioServiceWithPoolFactory.NioServiceWithPoolFactoryFactory(nioExecutor);
52 this.sshServer = SshServer.setUpDefaultServer();
55 public void bind(final InetSocketAddress bindingAddress, final LocalAddress localAddress, final PasswordAuthenticator authenticator, final KeyPairProvider keyPairProvider) throws IOException {
56 sshServer.setHost(bindingAddress.getHostString());
57 sshServer.setPort(bindingAddress.getPort());
59 sshServer.setPasswordAuthenticator(authenticator);
60 sshServer.setKeyPairProvider(keyPairProvider);
62 sshServer.setIoServiceFactoryFactory(nioServiceWithPoolFactoryFactory);
63 sshServer.setScheduledExecutorService(minaTimerExecutor);
65 final RemoteNetconfCommand.NetconfCommandFactory netconfCommandFactory =
66 new RemoteNetconfCommand.NetconfCommandFactory(clientGroup, localAddress);
67 sshServer.setSubsystemFactories(Lists.<NamedFactory<Command>>newArrayList(netconfCommandFactory));
75 } catch (final InterruptedException e) {
76 throw new RuntimeException("Interrupted while stopping sshServer", e);
78 sshServer.close(true);
83 * Based on Nio2ServiceFactory with one addition: injectable executor
85 private static final class NioServiceWithPoolFactory extends CloseableUtils.AbstractCloseable implements IoServiceFactory {
87 private final FactoryManager manager;
88 private final AsynchronousChannelGroup group;
90 public NioServiceWithPoolFactory(final FactoryManager manager, final ExecutorService executor) {
91 this.manager = manager;
93 group = AsynchronousChannelGroup.withThreadPool(executor);
94 } catch (final IOException e) {
95 throw new RuntimeSshException(e);
99 public IoConnector createConnector(final IoHandler handler) {
100 return new Nio2Connector(manager, handler, group);
103 public IoAcceptor createAcceptor(final IoHandler handler) {
104 return new Nio2Acceptor(manager, handler, group);
108 protected void doCloseImmediately() {
111 group.awaitTermination(5, TimeUnit.SECONDS);
112 } catch (final Exception e) {
113 log.debug("Exception caught while closing channel group", e);
115 super.doCloseImmediately();
119 private static final class NioServiceWithPoolFactoryFactory extends Nio2ServiceFactoryFactory {
121 private final ExecutorService nioExecutor;
123 private NioServiceWithPoolFactoryFactory(final ExecutorService nioExecutor) {
124 this.nioExecutor = nioExecutor;
128 public IoServiceFactory create(final FactoryManager manager) {
129 return new NioServiceWithPoolFactory(manager, nioExecutor);