/****************************************************************************** * Copyright (c) 2008 g-Eclipse consortium * 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 * * Initial development of the original code was made for * project g-Eclipse founded by European Union * project number: FP6-IST-034327 http://www.geclipse.eu/ * * Contributor(s): * UCY (http://www.cs.ucy.ac.cy) * - Harald Gjermundrod (harald@cs.ucy.ac.cy) * *****************************************************************************/ package eu.geclipse.batch; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; import org.eclipse.jsch.core.IJSchService; import com.jcraft.jsch.ChannelShell; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.Session; import eu.geclipse.batch.internal.Activator; import eu.geclipse.core.IBidirectionalConnection; import eu.geclipse.core.ICoreProblems; import eu.geclipse.core.ICoreSolutions; import eu.geclipse.core.portforward.ForwardType; import eu.geclipse.core.portforward.IForward; import eu.geclipse.core.reporting.IProblem; import eu.geclipse.core.reporting.ISolution; import eu.geclipse.core.reporting.ProblemException; import eu.geclipse.core.reporting.ReportingPlugin; /** * Class used to establish a persistant ssh connection to a remote server. */ public class SSHPersistantConnection implements IBidirectionalConnection { private Session session = null; private ISSHConnectionInfo userInfo; // private ChannelDirectTCPIP channel; private ChannelShell channel; /** * Creates a new SSH session using the specified ssh connection * information. * @param sshConnectionInfo the connection information describing the ssh * session. * @param forwards list of port forwards to create. * @throws ProblemException If the ssh connection cannot be established */ public void createSession( final ISSHConnectionInfo sshConnectionInfo, final List<IForward> forwards ) throws ProblemException { try { IJSchService service = Activator.getDefault().getJSchService(); if ( service == null ) { IProblem problem; problem = ReportingPlugin.getReportingService() .getProblem( IBatchProblems.GET_SSH_SERVICE_FAILED, null, null, Activator.PLUGIN_ID ); throw new ProblemException( problem ); } this.userInfo = sshConnectionInfo; this.session = service.createSession( this.userInfo.getHostname(), this.userInfo.getPort(), this.userInfo.getUsername() ); this.session.setUserInfo( this.userInfo ); if ( null != forwards ) { for ( IForward forward : forwards ) { if ( ForwardType.LOCAL == forward.getType() ) { this.session.setPortForwardingL( forward.getBindPort(), forward.getHostname(), forward.getPort() ); } else { this.session.setPortForwardingR( forward.getBindPort(), forward.getHostname(), forward.getPort() ); } } } this.session.connect(); } catch ( JSchException exception ) { // The user wanted to cancel, so ignore the exception if ( !sshConnectionInfo.getCanceledPWValue() ) { IProblem problem; problem = ReportingPlugin.getReportingService() .getProblem( IBatchProblems.LOGIN_FAILED, null, exception, Activator.PLUGIN_ID ); ISolution solution; solution = ReportingPlugin.getReportingService() .getSolution( IBatchSolutions.CHECK_USERNAME_AND_PASSWORD, null ); problem.addSolution( solution ); solution = ReportingPlugin.getReportingService().getSolution( IBatchSolutions.CHECK_SSH_SERVER_CONFIG, null ); problem.addSolution( solution ); throw new ProblemException( problem ); } } catch( Exception exception ){ Activator.logException( exception ); } } /** * Test if the session to the server is established. * * @return Returns <code>true</code> if the session is established, * <code>false</code> otherwise. */ public boolean isSessionActive() { boolean status = false; if ( null != this.session ) { status = this.session.isConnected(); } return status; } /** * Tears down the established SSH session . */ public void close() { if ( null != this.session ) this.session.disconnect(); } public InputStream getInputStream() throws IOException { InputStream ret = null; if ( null != this.channel ) ret = this.channel.getInputStream(); return ret; } public OutputStream getOutputStream() throws IOException { OutputStream ret = null; if ( null != this.channel ) ret = this.channel.getOutputStream(); return ret; } /** * Returns the error stream for this tunnel * @return Returns the error stream. * @throws IOException */ public InputStream getErrorStream() throws IOException { InputStream ret = null; if ( null != this.channel ) ret = this.channel.getExtInputStream(); return ret; } /** * Creates a SSH tunnel to the remote host. * * @param inStream The input stream for the tunnel * @param outStream The output stream for the tunnel * @param errStream The error stream for the tunnel * @throws ProblemException If the tunnel could not successfully be established */ public void connect( /*final InputStream inStream, final OutputStream outStream, final OutputStream errStream*/ ) throws ProblemException { // We throw exception if we don't have a session if ( ! this.isSessionActive() ) { IProblem problem; problem = ReportingPlugin.getReportingService() .getProblem( ICoreProblems.NET_CONNECTION_FAILED, null, null, Activator.PLUGIN_ID ); ISolution solution; solution = ReportingPlugin.getReportingService() .getSolution( ICoreSolutions.NET_CHECK_INTERNET_CONNECTION, null ); problem.addSolution( solution ); throw new ProblemException( problem ); } try { // this.channel = ( ChannelDirectTCPIP )this.session.openChannel( "direct-tcpip" ); //$NON-NLS-1$ this.channel = ( ChannelShell )this.session.openChannel( "shell" ); //$NON-NLS-1$ // this.channel.setInputStream( inStream ); // this.channel.setExtOutputStream( errStream ); // this.channel.setOutputStream( outStream ); this.channel.connect(); } catch( JSchException jschExc ) { IProblem problem; problem = ReportingPlugin.getReportingService() .getProblem( ICoreProblems.NET_CONNECTION_FAILED, null, jschExc, Activator.PLUGIN_ID ); ISolution solution; solution = ReportingPlugin.getReportingService() .getSolution( ICoreSolutions.NET_CHECK_INTERNET_CONNECTION, null ); problem.addSolution( solution ); solution = ReportingPlugin.getReportingService().getSolution( IBatchSolutions.CHECK_USERNAME_AND_PASSWORD, null ); problem.addSolution( solution ); solution = ReportingPlugin.getReportingService() .getSolution( ICoreSolutions.NET_CHECK_FIREWALL, null ); problem.addSolution( solution ); throw new ProblemException( problem ); } } }