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
8 package org.opendaylight.netconf.ssh;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
14 import com.google.common.base.Stopwatch;
15 import io.netty.bootstrap.Bootstrap;
16 import io.netty.channel.ChannelInitializer;
17 import io.netty.channel.EventLoopGroup;
18 import io.netty.channel.local.LocalAddress;
19 import io.netty.channel.nio.NioEventLoopGroup;
20 import io.netty.channel.socket.nio.NioSocketChannel;
21 import io.netty.util.HashedWheelTimer;
23 import java.net.InetSocketAddress;
24 import java.nio.file.Files;
25 import java.util.concurrent.ExecutorService;
26 import java.util.concurrent.Executors;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.TimeUnit;
29 import org.junit.AfterClass;
30 import org.junit.BeforeClass;
31 import org.junit.Test;
32 import org.opendaylight.netconf.nettyutil.handler.ssh.authentication.LoginPasswordHandler;
33 import org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandler;
34 import org.opendaylight.netconf.shaded.sshd.common.util.security.SecurityUtils;
35 import org.opendaylight.netconf.ssh.EchoClientHandler.State;
37 public class SSHTest {
38 public static final String AHOJ = "ahoj\n";
40 private static EventLoopGroup nettyGroup;
41 private static HashedWheelTimer hashedWheelTimer;
42 private static ExecutorService nioExec;
43 private static ScheduledExecutorService minaTimerEx;
46 public static void setUp() throws Exception {
47 hashedWheelTimer = new HashedWheelTimer();
48 nettyGroup = new NioEventLoopGroup();
49 nioExec = Executors.newFixedThreadPool(1);
50 minaTimerEx = Executors.newScheduledThreadPool(1);
54 public static void tearDown() throws Exception {
55 hashedWheelTimer.stop();
56 nettyGroup.shutdownGracefully().await(5, TimeUnit.SECONDS);
57 minaTimerEx.shutdownNow();
58 nioExec.shutdownNow();
62 public void test() throws Exception {
63 File sshKeyPair = Files.createTempFile("sshKeyPair", ".pem").toFile();
64 sshKeyPair.deleteOnExit();
65 new Thread(new EchoServer(), "EchoServer").start();
67 final InetSocketAddress addr = new InetSocketAddress("127.0.0.1", 10831);
68 try (var sshProxyServer = new SshProxyServer(minaTimerEx, nettyGroup, nioExec)) {
69 sshProxyServer.bind(new SshProxyServerConfigurationBuilder()
70 .setBindingAddress(addr).setLocalAddress(new LocalAddress("netconf"))
71 .setAuthenticator((username, password) -> true)
72 .setKeyPairProvider(SecurityUtils.createGeneratorHostKeyProvider(sshKeyPair.toPath()))
73 .setIdleTimeout(Integer.MAX_VALUE).createSshProxyServerConfiguration());
75 final EchoClientHandler echoClientHandler = connectClient(addr);
77 Stopwatch stopwatch = Stopwatch.createStarted();
78 while (echoClientHandler.isConnected() == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
81 assertTrue(echoClientHandler.isConnected());
82 echoClientHandler.write(AHOJ);
84 // check that server sent back the same string
85 stopwatch = stopwatch.reset().start();
86 while (echoClientHandler.read().endsWith(AHOJ) == false && stopwatch.elapsed(TimeUnit.SECONDS) < 30) {
90 final String read = echoClientHandler.read();
91 assertTrue(read + " should end with " + AHOJ, read.endsWith(AHOJ));
95 public EchoClientHandler connectClient(final InetSocketAddress address) {
96 final EchoClientHandler echoClientHandler = new EchoClientHandler();
97 final ChannelInitializer<NioSocketChannel> channelInitializer = new ChannelInitializer<>() {
99 public void initChannel(final NioSocketChannel ch) throws Exception {
100 ch.pipeline().addFirst(AsyncSshHandler.createForNetconfSubsystem(new LoginPasswordHandler("a", "a")));
101 ch.pipeline().addLast(echoClientHandler);
104 final Bootstrap b = new Bootstrap();
107 .channel(NioSocketChannel.class)
108 .handler(channelInitializer);
111 b.connect(address).addListener(echoClientHandler);
112 return echoClientHandler;
116 public void testClientWithoutServer() throws Exception {
117 final InetSocketAddress address = new InetSocketAddress(12345);
118 final EchoClientHandler echoClientHandler = connectClient(address);
119 final Stopwatch stopwatch = Stopwatch.createStarted();
120 while (echoClientHandler.getState() == State.CONNECTING && stopwatch.elapsed(TimeUnit.SECONDS) < 5) {
123 assertFalse(echoClientHandler.isConnected());
124 assertEquals(State.FAILED_TO_CONNECT, echoClientHandler.getState());