1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 06:05:24 +02:00

Increase ssh default timeout, support ssh proxy options and add tracing support

This commit is contained in:
Martin Oberhuber 2006-05-19 16:08:48 +00:00
parent 57a32aa51a
commit 5e65fc8836
4 changed files with 159 additions and 34 deletions

View file

@ -10,6 +10,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.rse.services.ssh,
org.eclipse.rse.services,
org.eclipse.rse.ui,
org.eclipse.team.cvs.core;bundle-version="[3.2.0,4.0.0)",
org.eclipse.team.cvs.ssh2;bundle-version="[3.2.0,4.0.0)",
org.eclipse.team.cvs.ui;bundle-version="[3.2.0,4.0.0)",
org.eclipse.ui,

View file

@ -1,5 +1,10 @@
package org.eclipse.rse.connectorservice.ssh;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
@ -48,6 +53,37 @@ public class Activator extends AbstractUIPlugin {
return plugin;
}
private static Boolean fTracingOn = null;
public static boolean isTracingOn() {
if (fTracingOn==null) {
String id = plugin.getBundle().getSymbolicName();
String val = Platform.getDebugOption(id + "/debug"); //$NON-NLS-1$
if ("true".equals(val)) {
fTracingOn = Boolean.TRUE;
} else {
fTracingOn = Boolean.FALSE;
}
}
return fTracingOn.booleanValue();
}
public static String getTimestamp() {
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); //$NON-NLS-1$
return formatter.format(new Date());
} catch (Exception e) {
// If there were problems writing out the date, ignore and
// continue since that shouldn't stop us from logging the rest
// of the information
}
return Long.toString(System.currentTimeMillis());
}
public static void trace(String msg) {
if (isTracingOn()) {
String fullMsg = getTimestamp() + " | " + Thread.currentThread().getName() + " | " + msg;
System.out.println(fullMsg);
}
}
/**
* Returns an image descriptor for the image file at the given
* plug-in relative path.

View file

@ -11,7 +11,14 @@
package org.eclipse.rse.connectorservice.ssh;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.IPreferenceStore;
@ -19,12 +26,19 @@ import org.eclipse.rse.core.subsystems.AbstractConnectorService;
import org.eclipse.rse.model.IHost;
import org.eclipse.rse.services.ssh.ISshSessionProvider;
import org.eclipse.swt.widgets.Display;
import org.eclipse.team.internal.ccvs.core.CVSProviderPlugin;
import org.eclipse.team.internal.ccvs.core.util.Util;
import org.eclipse.team.internal.ccvs.ssh2.CVSSSH2Plugin;
import org.eclipse.team.internal.ccvs.ssh2.ISSHContants;
import org.eclipse.team.internal.ccvs.ui.UserValidationDialog;
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.UserInfo;
/**
@ -35,7 +49,6 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
private static final int SSH_DEFAULT_PORT = 22;
private static JSch jsch=new JSch();
private Session session;
// protected SftpFileService _sftpFileService;
public SshConnectorService(IHost host) {
//TODO the port parameter doesnt really make sense here since
@ -43,7 +56,6 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
//setPort() on our base class -- I assume the port is meant to
//be a local port.
super("SSH Connector Service", "SSH Connector Service Description", host, 0);
// _sftpFileService = new SftpFileService(this);
}
//----------------------------------------------------------------------
@ -51,6 +63,13 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
//----------------------------------------------------------------------
private static String current_ssh_home = null;
private static String current_pkeys = ""; //$NON-NLS-1$
protected static int getSshTimeoutInMillis() {
//return CVSProviderPlugin.getPlugin().getTimeout() * 1000;
// TODO Hard-code the timeout for now since Jsch doesn't respect CVS timeout
// See bug 92887
return 60000;
}
static String SSH_HOME_DEFAULT = null;
static {
@ -66,6 +85,8 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
}
}
// Load ssh prefs from Team/CVS for now.
// TODO do our own preference page.
static void loadSshPrefs()
{
IPreferenceStore store = CVSSSH2Plugin.getDefault().getPreferenceStore();
@ -123,6 +144,79 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
}
}
static Proxy loadSshProxyPrefs() {
boolean useProxy = CVSProviderPlugin.getPlugin().isUseProxy();
Proxy proxy = null;
if (useProxy) {
String _type = CVSProviderPlugin.getPlugin().getProxyType();
String _host = CVSProviderPlugin.getPlugin().getProxyHost();
String _port = CVSProviderPlugin.getPlugin().getProxyPort();
boolean useAuth = CVSProviderPlugin.getPlugin().isUseProxyAuth();
String _user = ""; //$NON-NLS-1$
String _pass = ""; //$NON-NLS-1$
// Retrieve username and password from keyring.
if(useAuth){
_user=CVSProviderPlugin.getPlugin().getProxyUser();
_pass=CVSProviderPlugin.getPlugin().getProxyPassword();
}
String proxyhost = _host + ":" + _port; //$NON-NLS-1$
if (_type.equals(CVSProviderPlugin.PROXY_TYPE_HTTP)) {
proxy = new ProxyHTTP(proxyhost);
if (useAuth) {
((ProxyHTTP) proxy).setUserPasswd(_user, _pass);
}
} else if (_type.equals(CVSProviderPlugin.PROXY_TYPE_SOCKS5)) {
proxy = new ProxySOCKS5(proxyhost);
if (useAuth) {
((ProxySOCKS5) proxy).setUserPasswd(_user, _pass);
}
} else {
proxy = null;
}
}
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 ResponsiveSocketFacory extends SimpleSocketFactory {
private IProgressMonitor monitor;
public ResponsiveSocketFacory(IProgressMonitor monitor) {
this.monitor = monitor;
}
public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
Socket socket = null;
socket = Util.createSocket(host, port, 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());
return socket;
}
}
//----------------------------------------------------------------------
// </copied from org.eclipse.team.cvs.ssh2>
//----------------------------------------------------------------------
@ -138,32 +232,29 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
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.setPassword(getPasswordInformation().getPassword());
//session.setPassword("your password");
// username and password will be given via UserInfo interface.
UserInfo ui=new MyUserInfo(user);
session.setUserInfo(ui);
session.setUserInfo(new MyUserInfo(user));
session.setSocketFactory(new ResponsiveSocketFacory(monitor));
//java.util.Hashtable config=new java.util.Hashtable();
//config.put("StrictHostKeyChecking", "no");
//session.setConfig(config);
session.connect(3000); // making connection with timeout.
//now also connect the sftpFileService. It's not very nice to force
//the connector service know about the file service, and connect it
//so early -- lazy connect inside the sftpFileService would be better.
//But the FileServiceSubsystem only calls internalConnect() on the
//connector service, and doesn't try to connect the file service
//individually.
//TODO: From the API point of view, it might be better if the file
//service had a connect() method and could decide itself if and how
//it wants to use the connector service.
//Or could we ensure that the FileService is instanciated only once
//it needs to be connected? - Currently this is not the case (it is
//instanciated very early by the subsystem).
// _sftpFileService.connect();
try {
Activator.trace("connecting..."); //$NON-NLS-1$
session.connect();
Activator.trace("connected"); //$NON-NLS-1$
} catch (JSchException e) {
Activator.trace("connect failed: "+e.toString()); //$NON-NLS-1$
if (session.isConnected())
session.disconnect();
throw e;
}
}
public void internalDisconnect(IProgressMonitor monitor)
@ -171,7 +262,8 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
//TODO: Check, Is disconnect being called because the network (connection) went down?
//TODO: Fire communication event (aboutToDisconnect) -- see DStoreConnectorService.internalDisconnect()
//TODO: Wrap exception in an InvocationTargetException -- see DStoreConnectorService.internalDisconnect()
// _sftpFileService.disconnect();
//Will services like the sftp service be disconnected too? Or notified?
Activator.trace("disconnect"); //$NON-NLS-1$
session.disconnect();
}
@ -182,11 +274,6 @@ public class SshConnectorService extends AbstractConnectorService implements ISs
public Session getSession() {
return session;
}
/*
public IFileService getFileService() {
return _sftpFileService;
}
*/
private static Display getStandardDisplay() {
Display display = Display.getCurrent();

View file

@ -71,7 +71,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
fUserHome = fChannelSftp.pwd();
Activator.trace("SftpFileService.connected"); //$NON-NLS-1$
} catch(Exception e) {
Activator.trace("SftpFileService.connecting failed: "+e.toString());
Activator.trace("SftpFileService.connecting failed: "+e.toString()); //$NON-NLS-1$
throw e;
}
}
@ -79,7 +79,7 @@ public class SftpFileService extends AbstractFileService implements IFileService
protected ChannelSftp getChannel(String task) {
Activator.trace(task);
if (fChannelSftp==null || !fChannelSftp.isConnected()) {
Activator.trace(task + ": channel not connected: "+fChannelSftp);
Activator.trace(task + ": channel not connected: "+fChannelSftp); //$NON-NLS-1$
}
return fChannelSftp;
}
@ -98,9 +98,9 @@ public class SftpFileService extends AbstractFileService implements IFileService
SftpATTRS attrs = null;
try {
attrs = getChannel("SftpFileService.getFile").stat(remoteParent+'/'+fileName); //$NON-NLS-1$
Activator.trace("SftpFileService.getFile done");
Activator.trace("SftpFileService.getFile done"); //$NON-NLS-1$
} catch(Exception e) {
Activator.trace("SftpFileService.getFile failed: "+e.toString());
Activator.trace("SftpFileService.getFile failed: "+e.toString()); //$NON-NLS-1$
}
if (attrs!=null) {
node = makeHostFile(remoteParent, fileName, attrs);
@ -141,13 +141,14 @@ public class SftpFileService extends AbstractFileService implements IFileService
}
}
}
Activator.trace("SftpFileService.internalFetch ok"); //$NON-NLS-1$
} catch(Exception e) {
//TODO throw new SystemMessageException.
//We get a "2: No such file" exception when we try to get contents
//of a symbolic link that turns out to point to a file rather than
//a directory. In this case, the result is probably expected.
//We should try to classify symbolic links as "file" or "dir" correctly.
Activator.trace("SftpFileService.internalFetch failed: "+e.toString());
Activator.trace("SftpFileService.internalFetch failed: "+e.toString()); //$NON-NLS-1$
e.printStackTrace();
}
return (IHostFile[])results.toArray(new IHostFile[results.size()]);