diff --git a/rse/features/org.eclipse.rse.ssh-feature/feature.xml b/rse/features/org.eclipse.rse.ssh-feature/feature.xml index 5fe0b097577..3ef36a30c8b 100644 --- a/rse/features/org.eclipse.rse.ssh-feature/feature.xml +++ b/rse/features/org.eclipse.rse.ssh-feature/feature.xml @@ -25,24 +25,17 @@ + + - - - - --> - - - - - + //--------------------------------------------------------------------------- + public void start(BundleContext context) throws Exception { super.start(context); + tracker = new ServiceTracker(getBundle().getBundleContext(), IJSchService.class.getName(), null); + tracker.open(); } - /* - * (non-Javadoc) - * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext) - */ public void stop(BundleContext context) throws Exception { - plugin = null; - super.stop(context); + try { + SshConnectorService.shutdown(); + tracker.close(); + } finally { + plugin = null; + super.stop(context); + } } + /** + * Returns an instance of IJSchService from the OSGi Registry. + * @return An instance of IJSchService, or null if no + * IJschService service is available. + */ + public IJSchService getJSchService() { + return (IJSchService)tracker.getService(); + } + + //--------------------------------------------------------------------------- + // + //--------------------------------------------------------------------------- + /** * Returns the shared instance * diff --git a/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/ISshConstants.java b/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/ISshConstants.java index 1af76bfcafc..464c21c37fa 100644 --- a/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/ISshConstants.java +++ b/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/ISshConstants.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Martin Oberhuber (Wind River) - extracted from various team.cvs plugins + * Martin Oberhuber (Wind River) - [175686] Adapted to new IJSchService API *******************************************************************************/ package org.eclipse.rse.internal.connectorservice.ssh; @@ -17,23 +18,6 @@ package org.eclipse.rse.internal.connectorservice.ssh; */ public interface ISshConstants { - // These are from ISSHContants - public static final String KEY_SSH2HOME="CVSSSH2PreferencePage.SSH2HOME"; //$NON-NLS-1$ - public static final String KEY_PRIVATEKEY="CVSSSH2PreferencePage.PRIVATEKEY"; //$NON-NLS-1$ - - // These are from ICVSUIConstants - public static final String PREF_USE_PROXY = "proxyEnabled"; //$NON-NLS-1$ - public static final String PREF_PROXY_TYPE = "proxyType"; //$NON-NLS-1$ - public static final String PREF_PROXY_HOST = "proxyHost"; //$NON-NLS-1$ - public static final String PREF_PROXY_PORT = "proxyPort"; //$NON-NLS-1$ - public static final String PREF_PROXY_AUTH = "proxyAuth"; //$NON-NLS-1$ - - // These are from CVSProviderPlugin - public static final String PROXY_TYPE_HTTP = "HTTP"; //$NON-NLS-1$ - public static final String PROXY_TYPE_SOCKS5 = "SOCKS5"; //$NON-NLS-1$ - public static final String HTTP_DEFAULT_PORT="80"; //$NON-NLS-1$ - public static final String SOCKS5_DEFAULT_PORT="1080"; //$NON-NLS-1$ - // These are from cvs.ui.IHelpContextIds public static final String CVSUIPREFIX = "org.eclipse.team.cvs.ui."; //$NON-NLS-1$ public static final String HELP_USER_VALIDATION_DIALOG = CVSUIPREFIX + "user_validation_dialog_context"; //$NON-NLS-1$ diff --git a/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java b/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java index d52de98a5d4..dd366926cb5 100644 --- a/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java +++ b/rse/plugins/org.eclipse.rse.connectorservice.ssh/src/org/eclipse/rse/internal/connectorservice/ssh/SshConnectorService.java @@ -8,45 +8,29 @@ * Contributors: * Martin Oberhuber (Wind River) - initial API and implementation * David Dykstal (IBM) - 168977: refactoring IConnectorService and ServerLauncher hierarchies + * Martin Oberhuber (Wind River) - [175686] Adapted to new IJSchService API + * - copied code from org.eclipse.team.cvs.ssh2/JSchSession (Copyright IBM) *******************************************************************************/ package org.eclipse.rse.internal.connectorservice.ssh; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.lang.reflect.InvocationTargetException; -import java.net.MalformedURLException; -import java.net.Socket; -import java.net.URL; -import java.net.UnknownHostException; -import java.util.Collections; -import java.util.Map; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.operation.IRunnableContext; import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.window.Window; +import org.eclipse.jsch.core.IJSchService; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.preferences.ScopedPreferenceStore; -import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; -import com.jcraft.jsch.Proxy; -import com.jcraft.jsch.ProxyHTTP; -import com.jcraft.jsch.ProxySOCKS5; import com.jcraft.jsch.Session; -import com.jcraft.jsch.SocketFactory; import com.jcraft.jsch.UIKeyboardInteractive; import com.jcraft.jsch.UserInfo; @@ -58,7 +42,6 @@ import org.eclipse.rse.core.subsystems.CommunicationsEvent; import org.eclipse.rse.core.subsystems.IConnectorService; import org.eclipse.rse.core.subsystems.SubSystemConfiguration; import org.eclipse.rse.internal.services.ssh.ISshSessionProvider; -import org.eclipse.rse.services.RemoteUtil; import org.eclipse.rse.services.clientserver.messages.SystemMessage; import org.eclipse.rse.ui.ISystemMessages; import org.eclipse.rse.ui.RSEUIPlugin; @@ -72,7 +55,6 @@ public class SshConnectorService extends StandardConnectorService implements ISs { private static final int SSH_DEFAULT_PORT = 22; private static final int CONNECT_DEFAULT_TIMEOUT = 60; //seconds - private static JSch jsch=new JSch(); private Session session; private SessionLostHandler fSessionLostHandler; @@ -86,227 +68,53 @@ public class SshConnectorService extends StandardConnectorService implements ISs } //---------------------------------------------------------------------- - // + // //---------------------------------------------------------------------- - private static String current_ssh_home = null; - private static String current_pkeys = ""; //$NON-NLS-1$ - static String SSH_HOME_DEFAULT = null; - static { - String ssh_dir_name = ".ssh"; //$NON-NLS-1$ - - // Windows doesn't like files or directories starting with a dot. - if (Platform.getOS().equals(Platform.OS_WIN32)) { - ssh_dir_name = "ssh"; //$NON-NLS-1$ - } - SSH_HOME_DEFAULT = System.getProperty("user.home"); //$NON-NLS-1$ - if (SSH_HOME_DEFAULT != null) { - SSH_HOME_DEFAULT = SSH_HOME_DEFAULT + java.io.File.separator + ssh_dir_name; - } - } - private static IPreferenceStore fCvsSsh2PreferenceStore; - static IPreferenceStore getCvsSsh2PreferenceStore() { - if (fCvsSsh2PreferenceStore == null) { - fCvsSsh2PreferenceStore = new ScopedPreferenceStore(new InstanceScope(),"org.eclipse.team.cvs.ssh2"); //$NON-NLS-1$ - } - return fCvsSsh2PreferenceStore; + private static Session createSession(String username, String password, String hostname, int port, UserInfo wrapperUI, IProgressMonitor monitor) throws JSchException { + IJSchService service = Activator.getDefault().getJSchService(); + if (service == null) + return null; + Session session = service.createSession(hostname, port, username); + //session.setTimeout(getSshTimeoutInMillis()); + session.setTimeout(0); //never time out on the session + if (password != null) + session.setPassword(password); + session.setUserInfo(wrapperUI); + return session; } - private static IPreferenceStore fCvsUIPreferenceStore; - static IPreferenceStore getCvsUIPreferenceStore() { - if (fCvsUIPreferenceStore == null) { - fCvsUIPreferenceStore = new ScopedPreferenceStore(new InstanceScope(),"org.eclipse.team.cvs.ui"); //$NON-NLS-1$ - } - return fCvsUIPreferenceStore; - } - - // Load ssh prefs from Team/CVS for now. - // TODO do our own preference page. - static void loadSshPrefs(JSch jsch) - { - IPreferenceStore store = getCvsSsh2PreferenceStore(); - String ssh_home = store.getString(ISshConstants.KEY_SSH2HOME); - String pkeys = store.getString(ISshConstants.KEY_PRIVATEKEY); - - try { - if (ssh_home.length() == 0) - ssh_home = SSH_HOME_DEFAULT; - - if (current_ssh_home == null || !current_ssh_home.equals(ssh_home)) { - loadKnownHosts(jsch, ssh_home); - current_ssh_home = ssh_home; - current_pkeys = ""; //$NON-NLS-1$ - } - - if (!current_pkeys.equals(pkeys)) { - java.io.File file; - String[] pkey = pkeys.split(","); //$NON-NLS-1$ - String[] _pkey = current_pkeys.split(","); //$NON-NLS-1$ - current_pkeys = ""; //$NON-NLS-1$ - for (int i = 0; i < pkey.length; i++) { - file = new java.io.File(pkey[i]); - if (!file.isAbsolute()) { - file = new java.io.File(ssh_home, pkey[i]); - } - if (file.exists()) { - boolean notyet = true; - for (int j = 0; j < _pkey.length; j++) { - if (pkey[i].equals(_pkey[j])) { - notyet = false; - break; - } - } - if (notyet) - jsch.addIdentity(file.getPath()); - if (current_pkeys.length() == 0) { - current_pkeys = pkey[i]; - } else { - current_pkeys += ("," + pkey[i]); //$NON-NLS-1$ - } - } - } - } - } catch (Exception e) { - } - - } - - static void loadKnownHosts(JSch jsch, String ssh_home){ - try { - java.io.File file; - file=new java.io.File(ssh_home, "known_hosts"); //$NON-NLS-1$ - jsch.setKnownHosts(file.getPath()); - } catch (Exception e) { - } - } - - private static final String INFO_PROXY_USER = "org.eclipse.team.cvs.core.proxy.user"; //$NON-NLS-1$ - private static final String INFO_PROXY_PASS = "org.eclipse.team.cvs.core.proxy.pass"; //$NON-NLS-1$ - - static Proxy loadSshProxyPrefs() { - //TODO Use official Platform prefs when bug 154100 is fixed - IPreferenceStore store = getCvsUIPreferenceStore(); - boolean useProxy = store.getBoolean(ISshConstants.PREF_USE_PROXY); - Proxy proxy = null; - if (useProxy) { - String _type = store.getString(ISshConstants.PREF_PROXY_TYPE); - String _host = store.getString(ISshConstants.PREF_PROXY_HOST); - String _port = store.getString(ISshConstants.PREF_PROXY_PORT); - - boolean useAuth = store.getBoolean(ISshConstants.PREF_PROXY_AUTH); - String _user = ""; //$NON-NLS-1$ - String _pass = ""; //$NON-NLS-1$ - - // Retrieve username and password from keyring. - if(useAuth){ - Map authInfo = null; - try { - URL FAKE_URL = new URL("http://org.eclipse.team.cvs.proxy.auth");//$NON-NLS-1$ - authInfo = Platform.getAuthorizationInfo(FAKE_URL, "proxy", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } catch(MalformedURLException e) { - //should never happen - } - if (authInfo==null) authInfo=Collections.EMPTY_MAP; - _user=(String)authInfo.get(INFO_PROXY_USER); - _pass=(String)authInfo.get(INFO_PROXY_PASS); - if (_user==null) _user=""; //$NON-NLS-1$ - if (_pass==null) _pass=""; //$NON-NLS-1$ - } - - String proxyhost = _host + ":" + _port; //$NON-NLS-1$ - if (_type.equals(ISshConstants.PROXY_TYPE_HTTP)) { - proxy = new ProxyHTTP(proxyhost); - if (useAuth) { - ((ProxyHTTP) proxy).setUserPasswd(_user, _pass); - } - } else if (_type.equals(ISshConstants.PROXY_TYPE_SOCKS5)) { - proxy = new ProxySOCKS5(proxyhost); - if (useAuth) { - ((ProxySOCKS5) proxy).setUserPasswd(_user, _pass); - } - } - } - return proxy; - } - - public static class SimpleSocketFactory implements SocketFactory { - InputStream in = null; - OutputStream out = null; - public Socket createSocket(String host, int port) throws IOException, UnknownHostException { - Socket socket = null; - socket = new Socket(host, port); - return socket; - } - public InputStream getInputStream(Socket socket) throws IOException { - if (in == null) - in = socket.getInputStream(); - return in; - } - public OutputStream getOutputStream(Socket socket) throws IOException { - if (out == null) - out = socket.getOutputStream(); - return out; - } - } - - public static class ResponsiveSocketFactory extends SimpleSocketFactory { - private IProgressMonitor monitor; - public ResponsiveSocketFactory(IProgressMonitor monitor) { - this.monitor = monitor; - } - public Socket createSocket(String host, int port) throws IOException, UnknownHostException { - Socket socket = null; - //Allows to cancel the socket creation operation if necessary. - //Waits for the timeout specified in CVS Preferences, maximum. - socket = RemoteUtil.createSocket(host, port, CONNECT_DEFAULT_TIMEOUT, monitor); - // Null out the monitor so we don't hold onto anything - // (i.e. the SSH2 session will keep a handle to the socket factory around - monitor = new NullProgressMonitor(); - // Set the socket timeout - //socket.setSoTimeout(getSshTimeoutInMillis()); - // We want blocking read() calls in ssh to never terminate - socket.setSoTimeout(0); - return socket; - } + static void shutdown() { + //TODO: Store all Jsch sessions in a pool and disconnect them on shutdown } //---------------------------------------------------------------------- - // + // //---------------------------------------------------------------------- + protected void internalConnect(IProgressMonitor monitor) throws Exception { - //We could share the preferences from ssh2, or use RSE - //ConnectorService Properties / Server Launcher Properties - - //jsch.setKnownHosts("/home/foo/.ssh/known_hosts"); - loadSshPrefs(jsch); String host = getHostName(); String user = getUserId(); - - Proxy proxy = loadSshProxyPrefs(); - session=jsch.getSession(user, host, SSH_DEFAULT_PORT); - if (proxy != null) { - session.setProxy(proxy); - } - //session.setTimeout(getSshTimeoutInMillis()); - session.setTimeout(0); //never time out on the session String password=""; //$NON-NLS-1$ SystemSignonInformation ssi = getSignonInformation(); if (ssi!=null) { password = getSignonInformation().getPassword(); } - session.setPassword(password); MyUserInfo userInfo = new MyUserInfo(user, password); - session.setUserInfo(userInfo); - session.setSocketFactory(new ResponsiveSocketFactory(monitor)); - - //java.util.Hashtable config=new java.util.Hashtable(); - //config.put("StrictHostKeyChecking", "no"); - //session.setConfig(config); userInfo.aboutToConnect(); + try { - Activator.trace("SshConnectorService.connecting..."); //$NON-NLS-1$ + session = createSession(user, password, host, SSH_DEFAULT_PORT, + userInfo, monitor); + + //java.util.Hashtable config=new java.util.Hashtable(); + //config.put("StrictHostKeyChecking", "no"); + //session.setConfig(config); + userInfo.aboutToConnect(); + + Activator.trace("SshConnectorService.connecting..."); //$NON-NLS-1$ //wait for 60 sec maximum during connect session.connect(CONNECT_DEFAULT_TIMEOUT * 1000); Activator.trace("SshConnectorService.connected"); //$NON-NLS-1$ @@ -314,6 +122,9 @@ public class SshConnectorService extends StandardConnectorService implements ISs Activator.trace("SshConnectorService.connect failed: "+e.toString()); //$NON-NLS-1$ if (session.isConnected()) session.disconnect(); + if(e.toString().indexOf("Auth cancel")>=0) { //$NON-NLS-1$ + throw new OperationCanceledException(); + } throw e; } userInfo.connectionMade(); diff --git a/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF index 74948fb1321..db79aa6a603 100644 --- a/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF +++ b/rse/plugins/org.eclipse.rse.services.ssh/META-INF/MANIFEST.MF @@ -8,7 +8,7 @@ Bundle-Vendor: %providerName Bundle-Localization: plugin Require-Bundle: org.eclipse.core.runtime, org.eclipse.rse.services, - com.jcraft.jsch;bundle-version="[0.1.28,2.0.0)" + com.jcraft.jsch;bundle-version="[0.1.28,1.0.0)" Eclipse-LazyStart: true Export-Package: org.eclipse.rse.internal.services.ssh;x-friends:="org.eclipse.rse.connectorservice.ssh,org.eclipse.rse.subsystems.files.ssh,org.eclipse.rse.subsystems.shells.ssh", org.eclipse.rse.internal.services.ssh.files;x-friends:="org.eclipse.rse.connectorservice.ssh,org.eclipse.rse.subsystems.files.ssh,org.eclipse.rse.subsystems.shells.ssh", diff --git a/terminal/org.eclipse.tm.terminal.ssh-feature/feature.xml b/terminal/org.eclipse.tm.terminal.ssh-feature/feature.xml index 86fbe13a10b..3040d1ba5ae 100644 --- a/terminal/org.eclipse.tm.terminal.ssh-feature/feature.xml +++ b/terminal/org.eclipse.tm.terminal.ssh-feature/feature.xml @@ -2,8 +2,8 @@ + version="1.0.0.qualifier" + provider-name="%providerName"> %description @@ -25,11 +25,8 @@ - + + + //--------------------------------------------------------------------------- + + public void start(BundleContext context) throws Exception { + super.start(context); + tracker = new ServiceTracker(getBundle().getBundleContext(), IJSchService.class.getName(), null); + tracker.open(); + } + + public void stop(BundleContext context) throws Exception { + try { + SshConnection.shutdown(); + tracker.close(); + } finally { + plugin = null; + super.stop(context); + } + } + + /** + * Returns an instance of IJSchService from the OSGi Registry. + * @return An instance of IJSchService, or null if no + * IJschService service is available. + */ + public IJSchService getJSchService() { + return (IJSchService)tracker.getService(); + } + + //--------------------------------------------------------------------------- + // + //--------------------------------------------------------------------------- + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static Activator getDefault() { + return plugin; + } + + /** + * Returns an image descriptor for the image file at the given + * plug-in relative path. + * + * @param path the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path); + } + +} diff --git a/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/ISshConstants.java b/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/ISshConstants.java index 2ac687d6404..0638da25c9c 100644 --- a/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/ISshConstants.java +++ b/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/ISshConstants.java @@ -8,6 +8,7 @@ * Contributors: * IBM Corporation - initial API and implementation * Martin Oberhuber (Wind River) - extracted from various team.cvs plugins + * Martin Oberhuber (Wind River) - [175686] Adapted to new IJSchService API *******************************************************************************/ package org.eclipse.tm.internal.terminal.ssh; @@ -17,23 +18,6 @@ package org.eclipse.tm.internal.terminal.ssh; */ public interface ISshConstants { - // These are from ISSHContants - public static final String KEY_SSH2HOME="CVSSSH2PreferencePage.SSH2HOME"; //$NON-NLS-1$ - public static final String KEY_PRIVATEKEY="CVSSSH2PreferencePage.PRIVATEKEY"; //$NON-NLS-1$ - - // These are from ICVSUIConstants - public static final String PREF_USE_PROXY = "proxyEnabled"; //$NON-NLS-1$ - public static final String PREF_PROXY_TYPE = "proxyType"; //$NON-NLS-1$ - public static final String PREF_PROXY_HOST = "proxyHost"; //$NON-NLS-1$ - public static final String PREF_PROXY_PORT = "proxyPort"; //$NON-NLS-1$ - public static final String PREF_PROXY_AUTH = "proxyAuth"; //$NON-NLS-1$ - - // These are from CVSProviderPlugin - public static final String PROXY_TYPE_HTTP = "HTTP"; //$NON-NLS-1$ - public static final String PROXY_TYPE_SOCKS5 = "SOCKS5"; //$NON-NLS-1$ - public static final String HTTP_DEFAULT_PORT="80"; //$NON-NLS-1$ - public static final String SOCKS5_DEFAULT_PORT="1080"; //$NON-NLS-1$ - // These are from cvs.ui.IHelpContextIds public static final String CVSUIPREFIX = "org.eclipse.team.cvs.ui."; //$NON-NLS-1$ public static final String HELP_USER_VALIDATION_DIALOG = CVSUIPREFIX + "user_validation_dialog_context"; //$NON-NLS-1$ diff --git a/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnection.java b/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnection.java index ab537ac7022..968007d39c3 100644 --- a/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnection.java +++ b/terminal/org.eclipse.tm.terminal.ssh/src/org/eclipse/tm/internal/terminal/ssh/SshConnection.java @@ -8,36 +8,29 @@ * Contributors: * Michael Scharf (Wind River) - initial API and implementation * Martin Oberhuber (Wind River) - fixed copyright headers and beautified + * Martin Oberhuber (Wind River) - [175686] Adapted to new IJSchService API + * - copied code from org.eclipse.team.cvs.ssh2/JSchSession (Copyright IBM) *******************************************************************************/ package org.eclipse.tm.internal.terminal.ssh; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Collections; -import java.util.Map; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.window.Window; +import org.eclipse.jsch.core.IJSchService; import org.eclipse.swt.widgets.Display; import org.eclipse.tm.terminal.ITerminalControl; import org.eclipse.tm.terminal.Logger; import org.eclipse.tm.terminal.TerminalState; -import org.eclipse.ui.preferences.ScopedPreferenceStore; import com.jcraft.jsch.Channel; import com.jcraft.jsch.ChannelShell; -import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; -import com.jcraft.jsch.Proxy; -import com.jcraft.jsch.ProxyHTTP; -import com.jcraft.jsch.ProxySOCKS5; import com.jcraft.jsch.Session; import com.jcraft.jsch.UserInfo; @@ -54,151 +47,28 @@ class SshConnection extends Thread { } //---------------------------------------------------------------------- - // + // //---------------------------------------------------------------------- - private static String current_ssh_home = null; - private static String current_pkeys = ""; //$NON-NLS-1$ - static String SSH_HOME_DEFAULT = null; - static { - String ssh_dir_name = ".ssh"; //$NON-NLS-1$ - - // Windows doesn't like files or directories starting with a dot. - if (Platform.getOS().equals(Platform.OS_WIN32)) { - ssh_dir_name = "ssh"; //$NON-NLS-1$ - } - SSH_HOME_DEFAULT = System.getProperty("user.home"); //$NON-NLS-1$ - if (SSH_HOME_DEFAULT != null) { - SSH_HOME_DEFAULT = SSH_HOME_DEFAULT + java.io.File.separator + ssh_dir_name; - } - } - private static IPreferenceStore fCvsSsh2PreferenceStore; - static IPreferenceStore getCvsSsh2PreferenceStore() { - if (fCvsSsh2PreferenceStore == null) { - fCvsSsh2PreferenceStore = new ScopedPreferenceStore(new InstanceScope(),"org.eclipse.team.cvs.ssh2"); //$NON-NLS-1$ - } - return fCvsSsh2PreferenceStore; + private static Session createSession(String username, String password, String hostname, int port, UserInfo wrapperUI, IProgressMonitor monitor) throws JSchException { + IJSchService service = Activator.getDefault().getJSchService(); + if (service == null) + return null; + Session session = service.createSession(hostname, port, username); + //session.setTimeout(getSshTimeoutInMillis()); + session.setTimeout(0); //never time out on the session + if (password != null) + session.setPassword(password); + session.setUserInfo(wrapperUI); + return session; } - private static IPreferenceStore fCvsUIPreferenceStore; - static IPreferenceStore getCvsUIPreferenceStore() { - if (fCvsUIPreferenceStore == null) { - fCvsUIPreferenceStore = new ScopedPreferenceStore(new InstanceScope(),"org.eclipse.team.cvs.ui"); //$NON-NLS-1$ - } - return fCvsUIPreferenceStore; - } - - // Load ssh prefs from Team/CVS for now. - // TODO do our own preference page. - static void loadSshPrefs(JSch jsch) - { - IPreferenceStore store = getCvsSsh2PreferenceStore(); - String ssh_home = store.getString(ISshConstants.KEY_SSH2HOME); - String pkeys = store.getString(ISshConstants.KEY_PRIVATEKEY); - - try { - if (ssh_home.length() == 0) - ssh_home = SSH_HOME_DEFAULT; - - if (current_ssh_home == null || !current_ssh_home.equals(ssh_home)) { - loadKnownHosts(jsch, ssh_home); - current_ssh_home = ssh_home; - current_pkeys = ""; //$NON-NLS-1$ - } - - if (!current_pkeys.equals(pkeys)) { - java.io.File file; - String[] pkey = pkeys.split(","); //$NON-NLS-1$ - String[] _pkey = current_pkeys.split(","); //$NON-NLS-1$ - current_pkeys = ""; //$NON-NLS-1$ - for (int i = 0; i < pkey.length; i++) { - file = new java.io.File(pkey[i]); - if (!file.isAbsolute()) { - file = new java.io.File(ssh_home, pkey[i]); - } - if (file.exists()) { - boolean notyet = true; - for (int j = 0; j < _pkey.length; j++) { - if (pkey[i].equals(_pkey[j])) { - notyet = false; - break; - } - } - if (notyet) - jsch.addIdentity(file.getPath()); - if (current_pkeys.length() == 0) { - current_pkeys = pkey[i]; - } else { - current_pkeys += ("," + pkey[i]); //$NON-NLS-1$ - } - } - } - } - } catch (Exception e) { - } - + static void shutdown() { + //TODO: Store all Jsch sessions in a pool and disconnect them on shutdown } - static void loadKnownHosts(JSch jsch, String ssh_home){ - try { - java.io.File file; - file=new java.io.File(ssh_home, "known_hosts"); //$NON-NLS-1$ - jsch.setKnownHosts(file.getPath()); - } catch (Exception e) { - } - } - - private static final String INFO_PROXY_USER = "org.eclipse.team.cvs.core.proxy.user"; //$NON-NLS-1$ - private static final String INFO_PROXY_PASS = "org.eclipse.team.cvs.core.proxy.pass"; //$NON-NLS-1$ - - static Proxy loadSshProxyPrefs() { - //TODO Use official Platform prefs when bug 154100 is fixed - IPreferenceStore store = getCvsUIPreferenceStore(); - boolean useProxy = store.getBoolean(ISshConstants.PREF_USE_PROXY); - Proxy proxy = null; - if (useProxy) { - String _type = store.getString(ISshConstants.PREF_PROXY_TYPE); - String _host = store.getString(ISshConstants.PREF_PROXY_HOST); - String _port = store.getString(ISshConstants.PREF_PROXY_PORT); - - boolean useAuth = store.getBoolean(ISshConstants.PREF_PROXY_AUTH); - String _user = ""; //$NON-NLS-1$ - String _pass = ""; //$NON-NLS-1$ - - // Retrieve username and password from keyring. - if(useAuth){ - Map authInfo = null; - try { - URL FAKE_URL = new URL("http://org.eclipse.team.cvs.proxy.auth");//$NON-NLS-1$ - authInfo = Platform.getAuthorizationInfo(FAKE_URL, "proxy", ""); //$NON-NLS-1$ //$NON-NLS-2$ - } catch(MalformedURLException e) { - //should never happen - } - if (authInfo==null) authInfo=Collections.EMPTY_MAP; - _user=(String)authInfo.get(INFO_PROXY_USER); - _pass=(String)authInfo.get(INFO_PROXY_PASS); - if (_user==null) _user=""; //$NON-NLS-1$ - if (_pass==null) _pass=""; //$NON-NLS-1$ - } - - String proxyhost = _host + ":" + _port; //$NON-NLS-1$ - if (_type.equals(ISshConstants.PROXY_TYPE_HTTP)) { - proxy = new ProxyHTTP(proxyhost); - if (useAuth) { - ((ProxyHTTP) proxy).setUserPasswd(_user, _pass); - } - } else if (_type.equals(ISshConstants.PROXY_TYPE_SOCKS5)) { - proxy = new ProxySOCKS5(proxyhost); - if (useAuth) { - ((ProxySOCKS5) proxy).setUserPasswd(_user, _pass); - } - } - } - return proxy; - } - //---------------------------------------------------------------------- - // + // //---------------------------------------------------------------------- public void run() { @@ -209,15 +79,6 @@ class SshConnection extends Thread { String password = fConn.getTelnetSettings().getPassword(); int port=fConn.getTelnetSettings().getPort(); - loadSshPrefs(fConn.getJsch()); - Proxy proxy = loadSshProxyPrefs(); - Session session=fConn.getJsch().getSession(user, host, port); - if (proxy != null) { - session.setProxy(proxy); - } - session.setTimeout(0); //never time out once connected - - session.setPassword(password); ////Giving a connectionId could be the index into a local ////Store where passwords are stored //String connectionId = host; @@ -226,13 +87,14 @@ class SshConnection extends Thread { //} //UserInfo ui=new MyUserInfo(connectionId, user, password); UserInfo ui=new MyUserInfo(null, user, password); - session.setUserInfo(ui); -// java.util.Hashtable config=new java.util.Hashtable(); -// config.put("StrictHostKeyChecking", "no"); -// session.setConfig(config); + Session session = createSession(user, password, host, port, + ui, new NullProgressMonitor()); - //session.connect(); + //java.util.Hashtable config=new java.util.Hashtable(); + //config.put("StrictHostKeyChecking", "no"); + //session.setConfig(config); + //ui.aboutToConnect(); session.connect(nTimeout); // making connection with timeout. ChannelShell channel=(ChannelShell) session.openChannel("shell"); //$NON-NLS-1$ @@ -250,7 +112,10 @@ class SshConnection extends Thread { // when reading is done, we set the state to closed fControl.setState(TerminalState.CLOSED); } catch (JSchException e) { - connectFailed(e.getMessage(),e.getMessage()); + if(e.toString().indexOf("Auth cancel")<0) { //$NON-NLS-1$ + //no error if user pressed cancel + connectFailed(e.getMessage(),e.getMessage()); + } } catch (IOException e) { connectFailed(e.getMessage(),e.getMessage()); } finally {