blob: fcc4a0bd09d4110bb9a7fe2fde6198bc0eb07b3c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2019 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.jsch.internal.core;
import java.io.FileNotFoundException;
import java.util.Hashtable;
import java.util.ArrayList;
import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.runtime.*;
import org.eclipse.jsch.core.AbstractIdentityRepositoryFactory;
import org.eclipse.jsch.core.IJSchService;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.osgi.util.tracker.ServiceTracker;
import com.jcraft.jsch.IdentityRepository;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
public class JSchCorePlugin extends Plugin{
public static String ID="org.eclipse.jsch.core"; //$NON-NLS-1$
// communication timeout with the server
public static final int DEFAULT_TIMEOUT=60;
private int communicationsTimeout=DEFAULT_TIMEOUT;
private boolean needToLoadKnownHosts=true;
private boolean needToLoadKeys=true;
private JSch jsch;
private String current_pkeys=""; //$NON-NLS-1$
public static final String PT_AUTHENTICATOR="authenticator"; //$NON-NLS-1$
public static final String PT_IDENTITYREPOSITORY="identityrepository"; //$NON-NLS-1$
private static JSchCorePlugin plugin;
private ServiceTracker<?, ?> tracker;
private ServiceRegistration<?> jschService;
public JSchCorePlugin(){
plugin=this;
}
public static JSchCorePlugin getPlugin(){
return plugin;
}
/**
* Convenience method for logging CoreExceptions to the plugin log
*
* @param e
* the exception
*/
public static void log(CoreException e){
log(e.getStatus().getSeverity(), e.getMessage(), e);
}
/**
* Log the given status. Do not use this method for the IStatus from a
* CoreException. Use<code>log(CoreException)</code> instead so the stack
* trace is not lost.
*
* @param status
* the status
*/
public static void log(IStatus status){
getPlugin().getLog().log(status);
}
public static void log(int severity, String message, Throwable e){
log(new Status(severity, ID, 0, message, e));
}
/**
* Get the communications timeout value in seconds
*
* @return the timeout value in seconds
*/
public int getTimeout(){
return communicationsTimeout;
}
/**
* Set the timeout value for communications to a value in seconds. The value
* must be greater than or equal 0. If is it 0, there is no timeout.
*
* @param timeout
* the timeout value in seconds
*/
public void setTimeout(int timeout){
this.communicationsTimeout=Math.max(0, timeout);
}
public synchronized JSch getJSch(){
if(jsch==null){
jsch=new JSch();
setIdentityRepository();
}
return jsch;
}
public synchronized void setIdentityRepository(){
IdentityRepository[] repositories = getPluggedInIdentityRepositries();
String[] selected = Utils.getSelectedSSHAgent().split(","); //$NON-NLS-1$
IdentityRepository irepo = null;
for(int i=0; i<selected.length; i++){
for(int j=0; j<repositories.length; j++){
IdentityRepository _irepo = repositories[j];
if(selected[i].equals(_irepo.getName()) &&
_irepo.getStatus()==IdentityRepository.RUNNING){
irepo = _irepo;
break;
}
}
if(irepo!=null)
break;
}
if(irepo!=null){
jsch.setIdentityRepository(irepo);
}
else{
// set the internal default IdentityRepository
jsch.setIdentityRepository(null);
}
}
public IdentityRepository[] getPluggedInIdentityRepositries(){
IExtension[] extensions=Platform.getExtensionRegistry().getExtensionPoint(
JSchCorePlugin.ID, JSchCorePlugin.PT_IDENTITYREPOSITORY).getExtensions();
if(extensions.length==0)
return new IdentityRepository[0];
ArrayList<IdentityRepository> tmp = new ArrayList<>();
for(int i=0; i<extensions.length; i++){
IExtension extension=extensions[i];
IConfigurationElement[] configs=extension.getConfigurationElements();
if(configs.length==0){
JSchCorePlugin
.log(
IStatus.ERROR,
NLS
.bind(
"IdentityRepository {0} is missing required fields", (new Object[] {extension.getUniqueIdentifier()})), null);//$NON-NLS-1$
continue;
}
try{
IConfigurationElement config=configs[0];
AbstractIdentityRepositoryFactory iirf =
(AbstractIdentityRepositoryFactory)config.createExecutableExtension("run");//$NON-NLS-1$
tmp.add(iirf.create());
}
catch(CoreException ex){
JSchCorePlugin
.log(
IStatus.ERROR,
NLS
.bind(
"Unable to instantiate identity repository {0}", (new Object[] {extension.getUniqueIdentifier()})), ex);//$NON-NLS-1$
}
}
IdentityRepository[] repositories = new IdentityRepository[tmp.size()];
for(int i=0; i<tmp.size(); i++){
repositories[i]=tmp.get(i);
}
return repositories;
}
public void loadKnownHosts(){
Preferences preferences=JSchCorePlugin.getPlugin().getPluginPreferences();
String ssh_home=preferences.getString(IConstants.KEY_SSH2HOME);
if(ssh_home.length()==0)
ssh_home=PreferenceInitializer.SSH_HOME_DEFAULT;
java.io.File file=new java.io.File(ssh_home, "known_hosts"); //$NON-NLS-1$
try{
getJSch().setKnownHosts(file.getPath());
}
catch(JSchException e){
if (!(e.getCause() instanceof FileNotFoundException)) {
JSchCorePlugin.log(IStatus.ERROR, NLS.bind(
"An error occurred while loading the know hosts file {0}", file //$NON-NLS-1$
.getAbsolutePath()), e);
}
}
needToLoadKnownHosts=false;
}
public boolean isNeedToLoadKnownHosts(){
return needToLoadKnownHosts;
}
public void setNeedToLoadKnownHosts(boolean needToLoadKnownHosts){
this.needToLoadKnownHosts=needToLoadKnownHosts;
}
public boolean isNeedToLoadKeys(){
return needToLoadKeys;
}
public void setNeedToLoadKeys(boolean needToLoadKeys){
this.needToLoadKeys=needToLoadKeys;
}
public void loadPrivateKeys(){
current_pkeys=Utils.loadPrivateKeys(getJSch(), current_pkeys);
setNeedToLoadKeys(false);
}
/**
* Return the {@link IProxyService} or <code>null</code> if the service is
* not available.
*
* @return the {@link IProxyService} or <code>null</code>
*/
public IProxyService getProxyService(){
return (IProxyService)tracker.getService();
}
@Override
public void start(BundleContext context) throws Exception{
super.start(context);
tracker=new ServiceTracker<Object, Object>(getBundle().getBundleContext(),
IProxyService.class.getName(), null);
tracker.open();
jschService=getBundle().getBundleContext().registerService(
IJSchService.class.getName(), JSchProvider.getInstance(),
new Hashtable<String, Object>());
}
@Override
public void stop(BundleContext context) throws Exception{
super.stop(context);
tracker.close();
jschService.unregister();
}
}