+++ /dev/null
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.netconf.ssh.threads;
-
-
-import ch.ethz.ssh2.AuthenticationResult;
-import ch.ethz.ssh2.PtySettings;
-import ch.ethz.ssh2.ServerAuthenticationCallback;
-import ch.ethz.ssh2.ServerConnection;
-import ch.ethz.ssh2.ServerConnectionCallback;
-import ch.ethz.ssh2.ServerSession;
-import ch.ethz.ssh2.ServerSessionCallback;
-import ch.ethz.ssh2.SimpleServerSessionCallback;
-import org.opendaylight.controller.netconf.ssh.authentication.AuthProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.annotation.concurrent.ThreadSafe;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-
-@ThreadSafe
-public class SocketThread implements Runnable, ServerAuthenticationCallback, ServerConnectionCallback {
- private static final Logger logger = LoggerFactory.getLogger(SocketThread.class);
-
- private final Socket socket;
- private final InetSocketAddress clientAddress;
- private ServerConnection conn = null;
- private final long sessionId;
- private String currentUser;
- private final String remoteAddressWithPort;
- private final AuthProvider authProvider;
-
-
- public static void start(Socket socket,
- InetSocketAddress clientAddress,
- long sessionId,
- AuthProvider authProvider) throws IOException {
- Thread netconf_ssh_socket_thread = new Thread(new SocketThread(socket, clientAddress, sessionId, authProvider));
- netconf_ssh_socket_thread.setDaemon(true);
- netconf_ssh_socket_thread.start();
- }
-
- private SocketThread(Socket socket,
- InetSocketAddress clientAddress,
- long sessionId,
- AuthProvider authProvider) throws IOException {
-
- this.socket = socket;
- this.clientAddress = clientAddress;
- this.sessionId = sessionId;
- this.remoteAddressWithPort = socket.getRemoteSocketAddress().toString().replaceFirst("/", "");
- this.authProvider = authProvider;
-
- }
-
- @Override
- public void run() {
- conn = new ServerConnection(socket);
- try {
- conn.setPEMHostKey(authProvider.getPEMAsCharArray(), "netconf");
- } catch (Exception e) {
- logger.warn("Server authentication setup failed.", e);
- }
- conn.setAuthenticationCallback(this);
- conn.setServerConnectionCallback(this);
- try {
- conn.connect();
- } catch (IOException e) {
- logger.error("SocketThread error ", e);
- }
- }
-
- @Override
- public ServerSessionCallback acceptSession(final ServerSession session) {
- SimpleServerSessionCallback cb = new SimpleServerSessionCallback() {
- @Override
- public Runnable requestSubsystem(final ServerSession ss, final String subsystem) throws IOException {
- return new Runnable() {
- @Override
- public void run() {
- if (subsystem.equals("netconf")) {
- IOThread netconf_ssh_input = null;
- IOThread netconf_ssh_output = null;
- try {
- String hostName = clientAddress.getHostName();
- int portNumber = clientAddress.getPort();
- final Socket echoSocket = new Socket(hostName, portNumber);
- logger.trace("echo socket created");
-
- logger.trace("starting netconf_ssh_input thread");
- netconf_ssh_input = new IOThread(echoSocket.getInputStream(), ss.getStdin(), "input_thread_" + sessionId, ss, conn);
- netconf_ssh_input.setDaemon(false);
- netconf_ssh_input.start();
-
- logger.trace("starting netconf_ssh_output thread");
- final String customHeader = "[" + currentUser + ";" + remoteAddressWithPort + ";ssh;;;;;;]\n";
- netconf_ssh_output = new IOThread(ss.getStdout(), echoSocket.getOutputStream(), "output_thread_" + sessionId, ss, conn, customHeader);
- netconf_ssh_output.setDaemon(false);
- netconf_ssh_output.start();
-
- } catch (Exception t) {
- logger.error("SSH bridge could not create echo socket: {}", t.getMessage(), t);
-
- try {
- if (netconf_ssh_input != null) {
- netconf_ssh_input.join();
- }
- } catch (InterruptedException e1) {
- Thread.currentThread().interrupt();
- logger.error("netconf_ssh_input join error ", e1);
- }
-
- try {
- if (netconf_ssh_output != null) {
- netconf_ssh_output.join();
- }
- } catch (InterruptedException e2) {
- Thread.currentThread().interrupt();
- logger.error("netconf_ssh_output join error ", e2);
- }
- }
- } else {
- String reason = "Only netconf subsystem is supported, requested:" + subsystem;
- closeSession(ss, reason);
- }
- }
- };
- }
-
- public void closeSession(ServerSession ss, String reason) {
- logger.trace("Closing session - {}", reason);
- try {
- ss.getStdin().write(reason.getBytes());
- } catch (IOException e) {
- logger.debug("Exception while closing session", e);
- }
- ss.close();
- }
-
- @Override
- public Runnable requestPtyReq(final ServerSession ss, final PtySettings pty) throws IOException {
- return new Runnable() {
- @Override
- public void run() {
- closeSession(ss, "PTY request not supported");
- }
- };
- }
-
- @Override
- public Runnable requestShell(final ServerSession ss) throws IOException {
- return new Runnable() {
- @Override
- public void run() {
- closeSession(ss, "Shell not supported");
- }
- };
- }
- };
-
- return cb;
- }
-
- @Override
- public String initAuthentication(ServerConnection sc) {
- logger.trace("Established connection with host {}", remoteAddressWithPort);
- return "Established connection with host " + remoteAddressWithPort + "\r\n";
- }
-
- @Override
- public String[] getRemainingAuthMethods(ServerConnection sc) {
- return new String[]{ServerAuthenticationCallback.METHOD_PASSWORD};
- }
-
- @Override
- public AuthenticationResult authenticateWithNone(ServerConnection sc, String username) {
- return AuthenticationResult.FAILURE;
- }
-
- @Override
- public AuthenticationResult authenticateWithPassword(ServerConnection sc, String username, String password) {
-
- try {
- if (authProvider.authenticated(username, password)) {
- currentUser = username;
- logger.trace("user {}@{} authenticated", currentUser, remoteAddressWithPort);
- return AuthenticationResult.SUCCESS;
- }
- } catch (Exception e) {
- logger.warn("Authentication failed due to :" + e.getLocalizedMessage());
- }
- return AuthenticationResult.FAILURE;
- }
-
- @Override
- public AuthenticationResult authenticateWithPublicKey(ServerConnection sc, String username, String algorithm,
- byte[] publickey, byte[] signature) {
- return AuthenticationResult.FAILURE;
- }
-
-}