| /******************************************************************************* |
| * 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)); |
| } |
| |
| } |