Работает!
Написал свой SSH1ServiceActivator
с блэкджеком ... для SSH v1 с использованием библиотеки
mindterm:
Код:
package ru.dsi.bgbilling.modules.inet.dyn.device.terminal;
import com.mindbright.jca.security.interfaces.RSAPublicKey;
import com.mindbright.ssh.*;
import com.mindbright.sshcommon.TimeoutException;
import org.apache.log4j.Logger;
import ru.bitel.bgbilling.modules.inet.access.sa.ServiceActivator;
import ru.bitel.bgbilling.modules.inet.access.sa.ServiceActivatorEvent;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetConnection;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDevice;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetDeviceType;
import ru.bitel.bgbilling.modules.inet.api.common.bean.InetServ;
import ru.bitel.bgbilling.modules.inet.dyn.device.terminal.AbstractTerminalServiceActivator;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.ParameterMap;
import ru.bitel.common.Utils;
import java.io.*;
import java.net.Socket;
import java.util.Properties;
import java.util.Set;
/**
* {@inheritDoc}
* @see ru.bitel.bgbilling.modules.inet.dyn.device.terminal.AbstractTerminalServiceActivator
*/
public class SSH1ServiceActivator
extends AbstractTerminalServiceActivator
implements ServiceActivator
{
private static final Logger logger = Logger.getLogger( SSH1ServiceActivator.class );
protected String endSequence;
protected SSH1Cisco ssh;
@Override
public Object init( Setup setup, int moduleId, InetDevice device, InetDeviceType deviceType, ParameterMap config )
throws Exception
{
super.init( setup, moduleId, device, deviceType, config );
if( this.port <= 0 )
{
this.port = 22;
}
this.endSequence = config.get( "sa.endSequence", null );
return null;
}
@Override
public Object destroy()
throws Exception
{
return super.destroy();
}
@Override
public Object connect()
throws Exception
{
ssh = new SSH1Cisco(host, port, username, password);
//TODO найти способ задать таймаут (хотя, похоже, это невозможно)
//ssh.setTimeout(timeout);
if( Utils.notBlankString( endSequence ) )
{
ssh.setEndSequence(endSequence);
}
logger.info( "Connected" );
return super.connect();
}
@Override
public Object disconnect()
throws Exception
{
super.disconnect();
logger.info(ssh.doCommand(this.exitCommand));
ssh.close();
logger.debug( "Disconnected" );
return null;
}
@Override
protected void executeCommand( String command )
throws Exception
{
logger.info( "execute: " + command );
logger.info( ssh.doCommand( command ) );
}
@Override
protected Object getValue( ServiceActivatorEvent e, InetServ serv, InetConnection connection, Set<Integer> options, String macros, Object[] args, Object[] globalArgs )
throws Exception
{
if( "setEndSequence".equals( macros ) )
{
if( args.length > 0 )
{
String endSequence = (String)args[0];
if( Utils.notEmptyString( endSequence ) )
{
ssh.setEndSequence((String)args[0]);
return "";
}
}
ssh.setEndSequence(this.endSequence);
return "";
}
else
{
return super.getValue( e, serv, connection, options, macros, args, globalArgs );
}
}
class SSH1Cisco extends SSHInteractorAdapter
implements SSHAuthenticator, SSHClientUser
{
private Properties props = new Properties();
private SSHConsoleClient client;
private String endSequence;
public SSH1Cisco(String host, int port, String user, String pass)
throws IOException
{
this.props.put("server", host);
this.props.put("port", String.valueOf(port));
this.props.put("username", user);
this.props.put("password", pass);
this.props.put("auth-method", "password");
this.endSequence = "#"; //default
this.client = new SSHConsoleClient(getSrvHost(), getSrvPort(), this, this);
if (!this.client.shell()) {
this.client = null;
throw new IOException("SSHConsoleClient returns null");
}
}
public String doCommand(String command)
throws IOException, TimeoutException {
OutputStream os = this.client.getStdIn();
os.write((command + "\n").getBytes());
os.flush();
StringBuilder result = new StringBuilder();
BufferedReader in = new BufferedReader(new InputStreamReader(this.client.getStdOut()));
String line;
do
{
line = in.readLine();
if (line == null) break;
result.append(line).append("\n");
}
while (!line.contains(this.endSequence));
return result.toString();
}
public void close()
{
this.client.close();
}
private String getProp(String key)
{
return (String)this.props.get(key);
}
public String getEndSequence(){
return this.endSequence;
}
public void setEndSequence(String endSequence){
this.endSequence = endSequence;
}
public String getUsername(SSHClientUser origin)
throws IOException
{
return getProp("username");
}
public String getPassword(SSHClientUser origin)
throws IOException
{
return getProp("password");
}
public String getChallengeResponse(SSHClientUser origin, String challenge)
throws IOException
{
return null;
}
public int[] getAuthTypes(SSHClientUser origin)
{
return SSH.getAuthTypes(getProp("auth-method"));
}
/**
* Get desired encryption algorithm
*/
public int getCipher(SSHClientUser origin) {
return SSH.CIPHER_3DES;
}
/**
* Return name of file containing private key for pubkey authentication
*/
public SSHRSAKeyFile getIdentityFile(SSHClientUser origin)
throws IOException
{
String idfile = System.getProperty("user.home") + File.separatorChar + ".ssh" +
File.separatorChar + "identity";
return new SSHRSAKeyFile(idfile);
}
/**
* Return password protecting identify file
*/
public String getIdentityPassword(SSHClientUser origin)
throws IOException
{
// If you have a password set on the private key file,
// return it here
return null;
}
/**
* Verify the fingerprint of the remote host.
*
* @param hostPub public key of remote host
*
* @return true if the public key verifies
*/
public boolean verifyKnownHosts(RSAPublicKey hostPub) throws IOException {
// This is insecure, and vulnerable to man in the middle
// attacks. At least we should remember the fingerprint after
// the first session and compare against that.
return true;
}
public String getSrvHost()
throws IOException
{
return getProp("server");
}
public int getSrvPort()
{
return Integer.parseInt(getProp("port"));
}
/**
* Return a connection to the server. This can be used to connect
* through proxies etc.
*/
public Socket getProxyConnection()
throws IOException
{
return null;
}
/**
* Get the display for X11 forwardings
*/
public String getDisplay()
{
return null;
}
/**
* get maximum packet size (0 = no limit)
*/
public int getMaxPacketSz()
{
return 0;
}
/**
* Get alive interval (0 = do not send keepalive packets)
*/
public int getAliveInterval()
{
return 0;
}
/**
* Get desired level of compression
*/
public int getCompressionLevel()
{
return 0;
}
/**
* Return true if X11 forwarding is desired
*/
public boolean wantX11Forward()
{
return false;
}
/**
* Return true if we need a PTY on the server
*/
public boolean wantPTY()
{
return false;
}
/**
* Get interactor which should handle the authentication phase
*/
public SSHInteractor getInteractor()
{
return this;
}
}
}
Конфиг типа устрйства:
Код:
#ru.dsi.bgbilling.modules.inet.dyn.device.terminal.SSH1ServiceActivator
#sa.endSequence=#
#
#ru.bitel.bgbilling.modules.inet.dyn.device.terminal.AbstractTerminalServiceActivator
#sa.command.timeout=60000 (default)
#sa.command.exit=exit (default)
#sa.command.connect=
sa.command.connect.1=term length 0
sa.command.connect.2=term width 0
sa.command.connect.3=conf term
#sa.command.disconnect=
sa.command.disconnect.1=end
#sa.command.serv.enable=
sa.command.serv.enable.1=interface $ifaceTitle
sa.command.serv.enable.2=no shutdown
#sa.command.serv.disable=
sa.command.serv.disable.1=interface $ifaceTitle
sa.command.serv.disable.2=shutdown
#sa.command.serv.create=<sa.command.serv.enable> (default)
#sa.command.serv.cancel=<sa.command.serv.disable> (default)
#sa.command.inetOption.<id>.enable=<список команд чрез запятую или через subIndexed>
#sa.command.inetOption.<id>.disable=<список команд чрез запятую или через subIndexed>
#sa.inetOption.root=