Package org.dru.clay.respository.transport.ssh

Source Code of org.dru.clay.respository.transport.ssh.SshTransport

package org.dru.clay.respository.transport.ssh;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.common.Buffer.BufferException;
import net.schmizz.sshj.common.IOUtils;
import net.schmizz.sshj.connection.channel.direct.Session;
import net.schmizz.sshj.connection.channel.direct.Session.Command;
import net.schmizz.sshj.userauth.method.AuthMethod;
import net.schmizz.sshj.xfer.InMemoryDestFile;

import org.dru.clay.respository.transport.FileInfo;
import org.dru.clay.respository.transport.Transport;

import com.jcraft.jsch.agentproxy.AgentProxy;
import com.jcraft.jsch.agentproxy.Connector;
import com.jcraft.jsch.agentproxy.ConnectorFactory;
import com.jcraft.jsch.agentproxy.Identity;
import com.jcraft.jsch.agentproxy.sshj.AuthAgent;

public class SshTransport implements Transport {
  private final SSHClient ssh;

  public SshTransport(SshConfig config) {
    this.ssh = new SSHClient();
   
    try {
      this.ssh.loadKnownHosts();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Override
  public FileInfo get(URI file) {
    Session session = null;
    try {
      session = getSession(file);
      final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      final InMemoryDestFile destination = new InMemoryDestFile() {
       
        @Override
        public OutputStream getOutputStream() throws IOException {
          return outputStream;
        }
      };
      ssh.newSCPFileTransfer().download(file.getPath(), destination);
     
      final byte[] content = outputStream.toByteArray();
      final long length = content.length;
      final long lastModified = System.currentTimeMillis(); // TODO: not good
      return new FileInfo(length, lastModified, content);
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      close(session);
    }
  }

  @Override
  public void get(URI file, File destination) {
    Session session = null;
    try {
      session = getSession(file);
      ssh.newSCPFileTransfer().download(file.getPath(), destination.getAbsolutePath());
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      close(session);
    }
  }

  @Override
  public void getIfNewer(URI file, File destination) {
    // TODO: implements this if it's possible
    get(file, destination);
  }

  @Override
  public void put(File source, URI destination) {
    Session session = null;
    try {
      session = getSession(destination);
      ssh.newSCPFileTransfer().upload(source.getAbsolutePath(), destination.getPath());
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      close(session);
    }
  }

  @Override
  public List<URI> list(URI directory) {
    Session session = null;
    try {
      session = getSession(directory);
      final List<URI> uris = new ArrayList<URI>();
      final Command command = session.exec("ls -p1 --group-directories-first /" + directory.getPath());
      final String result = IOUtils.readFully(command.getInputStream()).toString();
     
      for (String line : result.split("[\n\r]+")) {
        if (line.endsWith("/")) {
          final String dir = line.substring(0, line.length() - 2);
          uris.add(new URI(directory + "/" + dir));
        }
      }
      return uris;
    } catch (Exception e) {
      throw new RuntimeException(e);
    } finally {
      close(session);
    }
  }

  private void close(Session session) {
    if (session != null && session.isOpen()) {
      try {
        session.close();
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
  }

  @Override
  public void cleanup() {
    if (ssh.isConnected()) {
      try {
        ssh.close();
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }
  }
 
  private synchronized Session getSession(URI directory) {
    try {     
      if (!ssh.isConnected()) {
        final int port = directory.getPort() < 0 ? 22 : directory.getPort();
        final String hostname = directory.getHost();

        ssh.connect(hostname, port);
      }
     
      if (!ssh.isAuthenticated()) {
        final Connector connector = ConnectorFactory.getDefault().createConnector();
        final String username = (directory.getUserInfo() == null) ?  System.getProperty("user.name") : directory.getUserInfo();
       
        if (connector == null) {
          ssh.authPublickey(username);
         
          // TODO: find other ways to authenticate the user
          throw new UnsupportedOperationException("No SSH agent found");         
        } else {
          final AgentProxy proxy = new AgentProxy(connector);         
          ssh.auth(username, getAuthMethods(proxy));
        }     
      }

      // TODO: Check if the connection is against the correct server
      // if (ssh.getRemoteHostname())
     
      return ssh.startSession();
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }


  private static List<AuthMethod> getAuthMethods(AgentProxy agent) throws BufferException  {
    Identity[] identities = agent.getIdentities();
    List<AuthMethod> result = new ArrayList<AuthMethod>();
    for (Identity identity : identities) {
      result.add(new AuthAgent(agent, identity));
    }
    return result;
 
}
TOP

Related Classes of org.dru.clay.respository.transport.ssh.SshTransport

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.