package net.sourceforge.javautil.network.ssh;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import net.sourceforge.javautil.common.ByteUtil;
import net.sourceforge.javautil.common.ShutdownUtil.ShutdownHook;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.VirtualPath;
import net.sourceforge.javautil.common.io.remote.RemoteDirectory;
import net.sourceforge.javautil.common.io.remote.RemoteFile;
import net.sourceforge.javautil.common.io.remote.RemoteLocation;
import net.sourceforge.javautil.common.io.remote.RemoteLocationFactory;
import net.sourceforge.javautil.common.io.remote.impl.RemoteDirectoryAbstract;
import net.sourceforge.javautil.common.password.Password;
/**
* Utilizing the JSCH library, this is a high level SSH API, integrating with the {@link RemoteLocation} framwork.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: SecureShell.java 540 2009-08-12 23:46:37Z ponderator $
*/
public class SecureShell implements RemoteLocationFactory, ShutdownHook {
protected JSch ssh = new JSch();
protected Map<String, SecureShellSession> sessions = new LinkedHashMap<String, SecureShellSession>();
/**
* Timeout in milliseconds for connection related operations
*/
protected int timeout;
/**
* @param user The user for the shell
* @param host The host for the shell
* @param port The port for the shell
* @param input The {@link SecureShellSession#input} stream
* @param output The {@link SecureShellSession#output} stream
*
* @return The session that is a result of the parameters, failure will cause an exception
*/
public SecureShellSession createSession (String host, int port, String user, Password password) {
try {
String shellId = host + ":" + port + ":" + user;
if (this.sessions.containsKey(shellId) && !this.sessions.get(shellId).session.isConnected())
this.sessions.remove(shellId);
if (!this.sessions.containsKey(shellId)) {
Session session = ssh.getSession(user, host, port);
session.setPassword(password.getPassword());
session.setConfig("StrictHostKeyChecking", "no");
session.connect(timeout);
this.sessions.put(shellId, new SecureShellSession(this, shellId, session, password, timeout));
} else {
if (!ByteUtil.equals(this.sessions.get(shellId).password.getPassword(), password.getPassword()))
throw new IllegalArgumentException("Invalid password");
}
return this.sessions.get(shellId);
} catch (JSchException e) {
throw ThrowableManagerRegistry.caught(e);
}
}
public RemoteLocation createLocation(String host, int port, String username, Password password, String path) {
SecureShellSession session = this.createSession(host, port, username, password);
return session.createFTPConnection(path);
}
public void shutdown() {
for (SecureShellSession session : this.sessions.values()) {
try { session.close(); } catch (Exception e) { e.printStackTrace(); }
}
}
}