Desenvolvendo terminal SSH

Galera primeiramente desculpa meio que “reabrir” o tópico…

Eu estou querendo fazer um “terminal” cliente SSH com java web usando jsf, primefaces e ajax.

Depois de muita pesquisa eu encontrei este tópico e consegui fazer uma parte funcionar: http://www.guj.com.br/java/102651-java-como-cliente-ssh

No tópico acima tem uma classe chamada “SSHConector” com alguns métodos…

Eu criei um bean gerenciavel e consegui fazer um método que deleta um arquivo do servidor quando eu clico em um botão na página jsf…
new SSHConector.execCommand(“rm arquivo.txt”);
na verdad foi só um teste… e funcionou!!!

Bom eu tentei fazer “sozinho” (com muita pesquisa) e não consegui fazer o “terminal” cliente SSH.

Eu preciso agora usar os métodos de read e write para enviar comandos e receber a resposta… na verdade write e execCommand axo que seria a mesma coisa…

Enfim… alguém estaria disposto a ajudar?

No final do “projeto” eu pretendo criar um tutorial de como fazer do zero e postar aqui no guj o pdf e o projeto inteiro com a lib, etc…

Cara, tenta usar o jcraft. Eh bem facil, ja usei pra implementar sftp.
se tiver com tempo te mando exemplo, mas nao deve dar mto trabalho fazer um ssh web.
agora nao existe pronto? Precisa fazer mesmo?
boa sorte
abs

Olá amigo.

Obrigado pela sua opinião, vou dar uma pesquisada a respeito…

… Sobre achar pronto, eu procurei na internet e não consegui achar nada :frowning:
o que achei foi essa classe de conexão com o ssh que está no outro tópico…

Se você conseguir um exemplo pra min ficarei muito grato.

Obrigado.

Amigo,

Neste link tem varios exemplos:
http://www.jcraft.com/jsch/examples/

Vi a lib de ssh que tava no outro link mas não gostei mto. Na epoca que precisei, acabei usando o jcraft para SFTP pois a implementação dele é usada em diversos aplicativos:
Conforme o site:
We have recognized that the following applications have used JSch.

* Ant(1.6 or later).
  JSch has been used for Ant's sshexec and scp tasks.
* Eclipse(3.0).
  Our Eclipse-CVSSSH2 plug-in has been included in Eclipse SDK 3.0. This plug-in will allow you to get ssh2 accesses to remote CVS repository by JSch.
* NetBeans 5.0(and later)
* Jakarta Commons VFS
* Maven Wagon
* Rational Application Devloper for WebSphere Software
* HP Storage Essentials
* JIRA
* Trac WikiOutputStreamPlugin

E aqui comigo o SFTP via Jcraft tem funcionado muito bem.
Segue fonte que montei (tive de remover algumas coisas do fonte por questões de segurança, portanto precisa de um pequeno ajuste para rodar).
O fonte serve somente para transmitir arquivos via SFTP (processo de sincronização de arquivos gerados por um app java)

[code]import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;
import com.jcraft.jsch.SftpProgressMonitor;

/**

  • Classe para conexão com um servidor SFTP
  • Pode ser utilizada para troca de arquivos entre uma maquina local e um servidor SFTP.
  • Exemplo de implementação:
  •  ConexaoSFTP conexaoSFTP = new ConexaoSFTP();
    
  •  conexaoSFTP.setArquivoChaveConexao("C:/temp/Chaves/id_rsa");
    
  •  conexaoSFTP.setTimeout(60);
    
  •  conexaoSFTP.setUsuario("xxx");
    
  •  conexaoSFTP.setServidor("xxxserv");
    
  •  conexaoSFTP.conectar();
    
  •  conexaoSFTP.mudarDiretorio("/aaa/bbb");
    
  •  conexaoSFTP.enviarArquivo("c:/temp/", "xxx.xxx");
    
  •  conexaoSFTP.desconectar();
    
  • @author joao.menezes

*/
public class ConexaoSFTP {

private static final int BUFFER_SIZE = 1024;

private byte[] chaveConexao = null;
private byte[] chavePublica = null;
private String arquivoChaveConexao = null;
private String usuario = null;	
private String senha = null;
private String servidor = null;
private int porta = 22;
private int timeout = 30;
private boolean validarServidor = false;
private String arquivoServidoresValidos = null;
private JSch jsch = null;
private Session jsession = null;
private ChannelSftp cSftp = null;
private SftpProgressMonitor monitor = null;

/**
 * Cria um objeto de conexão com um SFTP
 */
public ConexaoSFTP() {
	jsch = new JSch();
	JSch.setConfig("StrictHostKeyChecking", "no");
}	

public byte[] getChavePublica() {
	return chavePublica;
}

public void setChavePublica(byte[] chavePublica) {
	this.chavePublica = chavePublica;
}

public int getPorta() {
	return porta;
}

public void setPorta(int porta) {
	this.porta = porta;
}

public int getTimeout() {
	return timeout;
}

public void setTimeout(int timeout) {
	this.timeout = timeout;
}

public byte[] getChaveConexao() {
	return chaveConexao;
}

public void setChaveConexao(byte[] chaveConexao) {
	this.chaveConexao = chaveConexao;
}

public String getArquivoChaveConexao() {
	return arquivoChaveConexao;
}

/**
 * Define que a comunicação será feita utilizando uma chave através de um arquivo.
 * 
 * @param arquivoChaveConexao Arquivo de chave de conexão.
 * @throws IOException Em caso de erros de io.
 */
public void setArquivoChaveConexao(String arquivoChaveConexao) throws IOException {
	this.arquivoChaveConexao = arquivoChaveConexao;

	// Carregar a chave
	setChaveConexao(carregarChaveConexao(getArquivoChaveConexao()));
}

private byte[] carregarChaveConexao(String arquivoChave) throws IOException {
	BufferedInputStream bis = null;
	try {
		File keyFile = new File(arquivoChave);
		bis = new BufferedInputStream(new FileInputStream(keyFile));
		byte[] buffer = new byte[BUFFER_SIZE];

		byte[] ret = new byte[bis.available()];
		int bytesRead = 0;
		int cont = 0;
		while ((bytesRead = bis.read(buffer)) != -1) {
			System.arraycopy(buffer, 0, ret, cont * BUFFER_SIZE, bytesRead);
			cont++;
		}
		return ret;
	} catch (IOException ioex) {
		throw ioex;
	} finally {
		if (bis != null) {
			bis.close();
		}			
	}		
}

public String getUsuario() {
	return usuario;
}

public void setUsuario(String usuario) {
	this.usuario = usuario;
}

public String getSenha() {
	return senha;
}

public void setSenha(String senha) {
	this.senha = senha;
}

public String getServidor() {
	return servidor;
}

public void setServidor(String servidor) {
	this.servidor = servidor;
}

public boolean isValidarServidor() {
	return validarServidor;
}

public void setValidarServidor(boolean validarServidor) {
	this.validarServidor = validarServidor;
	if (this.validarServidor) {
		JSch.setConfig("StrictHostKeyChecking", "yes");
	} else {
		JSch.setConfig("StrictHostKeyChecking", "no");
	}
}

public String getArquivoServidoresValidos() {
	return arquivoServidoresValidos;
}

public void setArquivoServidoresValidos(String arquivoServidoresValidos) {
	this.arquivoServidoresValidos = arquivoServidoresValidos;
}

public SftpProgressMonitor getMonitor() {
	return monitor;
}

/**
 * Conecta ao servidor com as propriedades definidas.
 * 
 * @throws CoreException Em caso de erros.
 */
public void conectar() throws CoreException {
	if (getUsuario() == null) {
		throw new CoreException("Usuário não fornecido");
	}
	byte[] prvKey = new byte[0];
	byte[] passPhrase = new byte[0];		
	if (getChaveConexao() != null) {
		prvKey = getChaveConexao();			
	}
	if (getSenha() != null) {
		passPhrase = getSenha().getBytes();
	}
	
	try {
	    // Validação de servidores
		if (getArquivoServidoresValidos() != null) {
	    	this.jsch.setKnownHosts(getArquivoServidoresValidos());
	    }

	    // Efetua configuração do JSCH (JCraft)
		if (getChaveConexao() != null) {
			this.jsch.addIdentity(
					getUsuario(), // Usuário
					prvKey,       // byte[] chavePrivada 
					getChavePublica(),         // byte[] chavePublica
					passPhrase    // byte[] senha
					);
		}
		
		
		this.jsession = jsch.getSession(getUsuario(), getServidor(), getPorta());
		this.jsession.setTimeout(1000 * getTimeout());

		// Em caso de uso de senha
		if (getSenha() != null) {
			this.jsession.setPassword(passPhrase);
		}
		
		// Efetiva a conexão
		this.jsession.connect();
		
		Channel channel = this.jsession.openChannel("sftp");
		channel.connect();
		cSftp = (ChannelSftp) channel;
		
	} catch (JSchException jsce) {
		throw new CoreException("Erro inesperado em jsch.", jsce);
	}
	
}

/**
 * Desconecta do servidor
 * 
 * @throws CoreException Em caso de erros.
 */
public void desconectar() throws CoreException {
	try {
		if (this.cSftp != null) {
			this.cSftp.quit();
		}
		if (this.jsession != null) {
			this.jsession.disconnect();
		}
	}  catch (Exception ex) {
		throw new CoreException("Erro ao desconectar.", ex);
	}
}

/**
 * Muda de diretório.
 * 
 * @param diretorioDestino Diretório destino.
 * @throws CoreException Em caso de erros.
 */
public void mudarDiretorio(String diretorioDestino) throws CoreException {
	try {
		this.cSftp.cd(diretorioDestino);	
	} catch (SftpException sfex) {
		throw new CoreException("Erro ao mudar diretório: " + diretorioDestino, sfex);
	}
			
}

/**
 * Envia um arquivo para o servidor conectado.
 * 
 * @param diretorioOrigem Diretório de origem.
 * @param arquivoOrigem Arquivo de origem.
 * @throws CoreException Em caso de erros.
 */
public void enviarArquivo(String diretorioOrigem, String arquivoOrigem) throws CoreException {
	try {
		// Muda diretório
		this.cSftp.lcd(diretorioOrigem);
		
		// Envia arquivo
		monitor = new ProgressoSFTP();
		int mode = ChannelSftp.OVERWRITE;
		this.cSftp.put(arquivoOrigem, ".", monitor, mode); 
	} catch (SftpException sfex) {
		throw new CoreException("Erro ao enviarArquivo: " + arquivoOrigem, sfex);
	}
}

[/code]
Nesse site do Jcraft tem o que você precisa:
http://www.jcraft.com/jsch/examples/Shell.java

Boa sorte

Galera seguinte, eu estou tentando criar um terminal para connectar com meu servidor linux.
Pelo programa PUTTY eu consigo connectar normalmente…

Estou usando ese dialog:
http://www.primefaces.org/showcase/ui/terminalDialog.jsf

Está aparecendo o seguinte erro

prime $ ssh root@localhost
stdin: is not a tty
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
[-D [bind_address:]port] [-e escape_char] [-F configfile]
[-i identity_file] [-L [bind_address:]port:host:hostport]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-R [bind_address:]port:host:hostport] [-S ctl_path]
[-w local_tun[:remote_tun]] [user@]hostname [command]

Eu tenho 2 classes no meu código.

Uma delas eh a SSHConnector:

[code]package com.java.ssh;
//imports omitidos
public class SSHConector {
private Connection sshConnection;
private Session sshSession;
private String user;
private String password;
private InputStream stdout;
private InputStream stderr;
private OutputStream stdin;
private int state = 0; //0=stopped, 1=started

public SSHConector(String host, String user, String password) {
	sshConnection = new Connection(host);
	this.user = user;
	this.password = password;
	this.state = 0;
}

public void start() {
	try {
		sshConnection.connect();
		boolean isAuthenticated = sshConnection.authenticateWithPassword(user, password);
		
		if (isAuthenticated == false)
			throw new IOException("Authentication failed.");
		
		sshSession = sshConnection.openSession();			
		sshSession.startShell();
		
		stdout = new StreamGobbler(sshSession.getStdout());
		stderr = new StreamGobbler(sshSession.getStderr());
		stdin = sshSession.getStdin();

		read(); //consume login message
		
		this.state = 1;
		
	} catch (IOException e) {
		// TODO Auto-generated catch block
		this.state = 0;
		e.printStackTrace();
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		this.state = 0;
		e.printStackTrace();
	}
}

public String read() throws IOException, InterruptedException{
	BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
	StringBuffer sb = new StringBuffer();
	sshSession.waitForCondition(ChannelCondition.EOF, 5000);
	while (br.ready())
	{
		String line = br.readLine();
		sb.append(line + "<BR>");
	}		
	return sb.toString();
}

public String readError() throws IOException, InterruptedException{
	BufferedReader br = new BufferedReader(new InputStreamReader(stderr));
	StringBuffer sb = new StringBuffer();
	sshSession.waitForCondition(ChannelCondition.EOF, 5000);
	while (br.ready())
	{
		String line = br.readLine();
		sb.append(line + "<BR>");
	}		
	return sb.toString();
}

public void write(String message){
	PrintStream ps = new PrintStream(stdin);		
	ps.println(message);
	ps.flush();
}

public void stop() {
	sshSession.close();
	this.state = 0;
}

public String execCommand(String command){
	String msg = "NO_ANSWER";
	
	if (state == 0)
		start();	
	
	try {
		write(command);
		msg = read();
		
		if (msg.length() <= 0)
			msg = readError();
		
	} catch (IOException e) {
		e.printStackTrace();
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
	
	return msg;
	
}

}
[/code]

A outra eh a SshBean que faz a comunicação com a visão:

[code]package com.java.ssh;

//omitido os imports

@ManagedBean
public class SshBean {

//1- host, 2- login, 3- senha...

// na verdade nao eh local, mais obviamente nao vou por host, user e pass aki ^^
private SSHConector sshc = new SSHConector(“localhost”, “root”, “root”);

public SshBean() {
}

public String handleCommand(String command, String[] params) {
    return sshc.execCommand(command);
}

}
[/code]

E na minha visão eu tenho o seguinte:

<p:dialog widgetVar="terminal" height="400" width="850" header="Terminal" resizable="false" modal="true"> <p:terminal widgetVar="term" commandHandler="#{sshBean.handleCommand}" width="800px" welcomeMessage="Welcome to PrimeFaces Terminal, how are you today?"/> </p:dialog>

http://www.google.com.br/url?sa=t&rct=j&q=ssh+web&source=web&cd=1&ved=0CCQQFjAA&url=http%3A%2F%2Fwww.serfish.com%2Fconsole%2F&ei=6e8zT6SaFIrftgfem7jAAg&usg=AFQjCNGBrQunDQN6ohO3XqXm3uh1rF-Nxg&cad=rja

esse ai eh pra min usar na internet
a intenção aki eh FAZER um! ^^

ate hj num consegui faze rsrs ta tenso
só consigo enviar os comandos… + nao retorna a resposta do comando… por exemplo se eu envio um “rm arquivo” ele deleta… blz ai nao tem resposta… mais se eu envio um “ls” ele nao me mostra a lista de arquivos…

Num wrapper que eu fiz da lib j2ssh eu consigo pegar a resposta dos comandos.
Segue exemplo e fonte no github:

https://github.com/leandronsp/ftp-communication