blob: 3a7b051d9a10c3a02112c3d34b9d238c9c14b4cb [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Atsuhiko Yamanaka, JCraft,Inc. - initial API and implementation.
* IBM Corporation - ongoing maintenance
*******************************************************************************/
package org.eclipse.team.internal.ccvs.ssh2;
import java.util.Enumeration;
import java.util.Hashtable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.jsch.core.IJSchService;
import org.eclipse.jsch.core.IJSchLocation;
import org.eclipse.jsch.core.IPasswordStore;
import org.eclipse.osgi.util.NLS;
import org.eclipse.team.internal.ccvs.core.*;
import com.jcraft.jsch.*;
class JSchSession {
private static final int SSH_DEFAULT_PORT = 22;
private static Hashtable<String, JSchSession> pool = new Hashtable<>();
private final Session session;
private final ICVSRepositoryLocation location;
protected static int getCVSTimeoutInMillis() {
//return CVSProviderPlugin.getPlugin().getTimeout() * 1000;
// TODO Hard-code the timeout for now since JSch doesn't respect CVS timeout
// See bug 92887
return 60000;
}
public static boolean isAuthenticationFailure(JSchException ee) {
return ee.getMessage().equals("Auth fail"); //$NON-NLS-1$
}
static JSchSession getSession(final ICVSRepositoryLocation location, String username, String password, String hostname, int port, IProgressMonitor monitor) throws JSchException {
int actualPort = port;
if (actualPort == ICVSRepositoryLocation.USE_DEFAULT_PORT)
actualPort = getPort(location);
String key = getPoolKey(username, hostname, actualPort);
try {
JSchSession jschSession = pool.get(key);
if (jschSession != null && !jschSession.getSession().isConnected()) {
pool.remove(key);
jschSession = null;
}
if (jschSession == null) {
IJSchService service = getJSchService();
IJSchLocation jlocation=service.getLocation(username, hostname, actualPort);
// As for the connection method "pserverssh2",
// there is not a place to save the given password for ssh2.
if (!location.getMethod().getName().equals("pserverssh2")) { //$NON-NLS-1$
IPasswordStore pstore = new IPasswordStore() {
public void clear(IJSchLocation l) {
location.flushUserInfo();
}
public boolean isCached(IJSchLocation l) {
return location.getUserInfoCached();
}
public void update(IJSchLocation l) {
location.setPassword(l.getPassword());
location.setAllowCaching(true);
}
};
jlocation.setPasswordStore(pstore);
}
jlocation.setComment(NLS.bind(CVSSSH2Messages.JSchSession_3, new String[] {location.toString()}));
Session session = null;
try {
session = createSession(service, jlocation, password, monitor);
} catch (JSchException e) {
throw e;
}
if (session == null)
throw new JSchException(CVSSSH2Messages.JSchSession_4);
if (session.getTimeout() != location.getTimeout() * 1000)
session.setTimeout(location.getTimeout() * 1000);
JSchSession schSession = new JSchSession(session, location);
pool.put(key, schSession);
return schSession;
}
return jschSession;
} catch (JSchException e) {
pool.remove(key);
if(e.toString().indexOf("Auth cancel")!=-1){ //$NON-NLS-1$
throw new OperationCanceledException();
}
throw e;
}
}
private static Session createSession(IJSchService service, IJSchLocation location, String password, IProgressMonitor monitor) throws JSchException {
if (password != null)
location.setPassword(password);
Session session = service.createSession(location, null);
session.setTimeout(getCVSTimeoutInMillis());
if (password != null)
session.setPassword(password);
service.connect(session, getCVSTimeoutInMillis(), monitor);
return session;
}
private static IJSchService getJSchService(){
return CVSSSH2Plugin.getDefault().getJSchService();
}
private static String getPoolKey(String username, String hostname, int port) {
return username + "@" + hostname + ":" + port; //$NON-NLS-1$ //$NON-NLS-2$
}
private static String getPoolKey(ICVSRepositoryLocation location){
return location.getUsername() + "@" + location.getHost() + ":" + getPort(location); //$NON-NLS-1$ //$NON-NLS-2$
}
private static int getPort(ICVSRepositoryLocation location) {
int port = location.getPort();
if (port == ICVSRepositoryLocation.USE_DEFAULT_PORT)
port = SSH_DEFAULT_PORT;
return port;
}
static void shutdown() {
if (getJSch() != null && pool.size() > 0) {
for (Enumeration e = pool.elements(); e.hasMoreElements();) {
JSchSession session = (JSchSession) (e.nextElement());
try {
session.getSession().disconnect();
} catch (Exception ee) {
// Ignore
}
}
pool.clear();
}
}
static JSch getJSch() {
return getJSchService().getJSch();
}
private JSchSession(Session session, ICVSRepositoryLocation location) {
this.session = session;
this.location = location;
}
public Session getSession() {
return session;
}
public void dispose() {
if (session.isConnected()) {
session.disconnect();
}
pool.remove(getPoolKey(location));
}
}