⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jschsession.java

📁 SFTP Plug-in for Eclipse will add the SFTP support to Eclipse
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Atsuhiko Yamanaka, JCraft,Inc. - initial API and implementation.
 *     IBM Corporation - ongoing maintenance
 *******************************************************************************/
package com.jcraft.eclipse.sftp.internal;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Enumeration;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.team.internal.ccvs.core.*;
import org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation;
//import org.eclipse.team.internal.ccvs.core.util.Util;
import org.eclipse.team.internal.ccvs.ssh2.*;
//import org.eclipse.ui.plugin.AbstractUIPlugin;

import com.jcraft.jsch.*;

class JSchSession{
  private static final int SSH_DEFAULT_PORT=22;
  private static JSch jsch=new JSch();
  private static java.util.Hashtable pool=new java.util.Hashtable();
  
  static final int DEFAULT_TIMEOUT = 60;
  
  static String KEY_SSH2HOME="CVSSSH2PreferencePage.SSH2HOME"; //$NON-NLS-1$
  static String KEY_PRIVATEKEY="CVSSSH2PreferencePage.PRIVATEKEY"; //$NON-NLS-1$
  
  static String SOCKS5="SOCKS5"; //$NON-NLS-1$
  static String HTTP="HTTP"; //$NON-NLS-1$
  static String HTTP_DEFAULT_PORT="80"; //$NON-NLS-1$
  static String SOCKS5_DEFAULT_PORT="1080"; //$NON-NLS-1$
  static String PRIVATE_KEYS_DEFAULT="id_dsa,id_rsa"; //$NON-NLS-1$

  static String DSA="DSA"; //$NON-NLS-1$
  static String RSA="RSA"; //$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;
    }
    else{

    }
  }

  private static String current_ssh_home=null;
  private static String current_pkeys=""; //$NON-NLS-1$
  private final Session session;
  private final UserInfo prompter;
  private final ICVSRepositoryLocation location;

  protected static int getTimeoutInMillis(){
    //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 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=JSchSession.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(getTimeoutInMillis());
      return socket;
    }
  }

  /**
   * UserInfo wrapper class that will time how long each prompt takes
   */
  private static class UserInfoTimer implements UserInfo, UIKeyboardInteractive{

    private UserInfo wrappedInfo;
    private long startTime;
    private long endTime;
    private boolean prompting;

    public UserInfoTimer(UserInfo wrappedInfo){
      this.wrappedInfo=wrappedInfo;
    }

    private synchronized void startTimer(){
      prompting=true;
      startTime=System.currentTimeMillis();
    }

    private synchronized void endTimer(){
      prompting=false;
      endTime=System.currentTimeMillis();
    }

    public long getLastDuration(){
      return Math.max(0, endTime-startTime);
    }

    public boolean hasPromptExceededTimeout(){
      if(!isPrompting()){
        return getLastDuration()>getTimeoutInMillis();
      }
      return false;
    }

    public String getPassphrase(){
      return wrappedInfo.getPassphrase();
    }

    public String getPassword(){
      return wrappedInfo.getPassword();
    }

    public boolean promptPassword(String arg0){
      try{
        startTimer();
        return wrappedInfo.promptPassword(arg0);
      }
      finally{
        endTimer();
      }
    }

    public boolean promptPassphrase(String arg0){
      try{
        startTimer();
        return wrappedInfo.promptPassphrase(arg0);
      }
      finally{
        endTimer();
      }
    }

    public boolean promptYesNo(String arg0){
      try{
        startTimer();
        return wrappedInfo.promptYesNo(arg0);
      }
      finally{
        endTimer();
      }
    }

    public void showMessage(String arg0){
      if(arg0.length()!=0){
        try{
          startTimer();
          wrappedInfo.showMessage(arg0);
        }
        finally{
          endTimer();
        }
      }
    }

    public String[] promptKeyboardInteractive(String arg0, String arg1,
        String arg2, String[] arg3, boolean[] arg4){
      try{
        startTimer();
        return ((UIKeyboardInteractive)wrappedInfo).promptKeyboardInteractive(
            arg0, arg1, arg2, arg3, arg4);
      }
      finally{
        endTimer();
      }
    }

    public boolean isPrompting(){
      return prompting;
    }
  }

  /**
   * User information delegates to the IUserAuthenticator. This allows
   * headless access to the connection method.
   */
  private static class MyUserInfo implements UserInfo, UIKeyboardInteractive{
    private String username;
    private String password;
    private String passphrase;
    private ICVSRepositoryLocation location;
    private IUserAuthenticator authenticator;
    private int attemptCount;
    private boolean passwordChanged;

    MyUserInfo(String username, String password, ICVSRepositoryLocation location){
      this.location=location;
      this.username=username;
      this.password=password;
      ICVSRepositoryLocation _location=location;
      if(_location==null){
        String dummy=":extssh:dummy@dummy:/"; //$NON-NLS-1$
        try{
          _location=CVSRepositoryLocation.fromString(dummy);
        }
        catch(CVSException e){
        }
      }
      authenticator=_location.getUserAuthenticator();

    }

    public String getPassword(){
      return password;
    }

    public String getPassphrase(){
      return passphrase;
    }

    public boolean promptYesNo(String str){
      int prompt=authenticator.prompt(location, IUserAuthenticator.QUESTION,
          CVSSSH2Messages.JSchSession_5, str, new int[] {
              IUserAuthenticator.YES_ID, IUserAuthenticator.NO_ID}, 0 //yes the default
          );
      return prompt==0;
    }

    private String promptSecret(String message, boolean includeLocation)
        throws CVSException{
      final String[] _password=new String[1];
      IUserInfo info=new IUserInfo(){
        public String getUsername(){
          return username;
        }

        public boolean isUsernameMutable(){
          return false;
        }

        public void setPassword(String password){
          _password[0]=password;
        }

        public void setUsername(String username){
        }
      };
      try{
        authenticator.promptForUserInfo(includeLocation ? location : null,
            info, message);
      }
      catch(OperationCanceledException e){
        _password[0]=null;
      }
      return _password[0];
    }

    public boolean promptPassphrase(String message){
      try{
        String _passphrase=promptSecret(message, false);
        if(_passphrase!=null){
          passphrase=_passphrase;
        }
        return _passphrase!=null;
      }
      catch(CVSException e){
        return false;
      }
    }

    public boolean promptPassword(String message){
      try{
        String _password=promptSecret(message, true);
        if(_password!=null){
          password=_password;
          // Cache the password with the repository location on the memory.
          if(location!=null)
            ((CVSRepositoryLocation)location).setPassword(password);
        }
        return _password!=null;
      }
      catch(CVSException e){
        return false;
      }
    }

    public void showMessage(String message){
      authenticator.prompt(location, IUserAuthenticator.INFORMATION,
          CVSSSH2Messages.JSchSession_5, message,
          new int[] {IUserAuthenticator.OK_ID}, IUserAuthenticator.OK_ID);

    }

    public String[] promptKeyboardInteractive(String destination, String name,
        String instruction, String[] prompt, boolean[] echo){
      if(prompt.length==0){
        // No need to prompt, just return an empty String array
        return new String[0];
      }
      try{
        if(attemptCount==0&&password!=null&&prompt.length==1
            &&prompt[0].trim().equalsIgnoreCase("password:")){ //$NON-NLS-1$
          // Return the provided password the first time but always prompt on subsequent tries
          attemptCount++;
          return new String[] {password};
        }
        String[] result=authenticator.promptForKeyboradInteractive(location,
            destination, name, instruction, prompt, echo);
        if(result==null)
          return null; // canceled
        if(result.length==1&&prompt.length==1
            &&prompt[0].trim().equalsIgnoreCase("password:")){ //$NON-NLS-1$
          password=result[0];
          passwordChanged=true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -