📄 jschsession.java
字号:
/*******************************************************************************
* 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 + -