diff options
author | Michael Valenta | 2007-02-20 19:43:35 +0000 |
---|---|---|
committer | Michael Valenta | 2007-02-20 19:43:35 +0000 |
commit | 8e76681c55535ccabcc7604886b1747e6355ec6e (patch) | |
tree | 006de1a68dfb0a5889cc854ed1310d348c124ff3 /bundles | |
parent | 423fe0799ce654759ffd1c449d1521d542b34f54 (diff) | |
download | eclipse.platform.team-8e76681c55535ccabcc7604886b1747e6355ec6e.tar.gz eclipse.platform.team-8e76681c55535ccabcc7604886b1747e6355ec6e.tar.xz eclipse.platform.team-8e76681c55535ccabcc7604886b1747e6355ec6e.zip |
Bug 170883 [SSH2] jsch connection preferences should be made public below "Internet" category
Diffstat (limited to 'bundles')
9 files changed, 915 insertions, 25 deletions
diff --git a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java index a470af97d..5c68f6e78 100644 --- a/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java +++ b/bundles/org.eclipse.jsch.core/src/org/eclipse/jsch/internal/core/Utils.java @@ -143,7 +143,7 @@ public class Utils{ } private static String getProxyType(IProxyData data){ - if (data.getType().equals(IProxyData.HTTP_PROXY_TYPE) || data.getType().equals(IProxyData.HTTPS_PROXY_TYPE)) + if (data.getType().equals(IProxyData.HTTPS_PROXY_TYPE)) return IConstants.PROXY_TYPE_HTTP; if (data.getType().equals(IProxyData.SOCKS_PROXY_TYPE)) return IConstants.PROXY_TYPE_SOCKS5; diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/IHelpContextIds.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/IHelpContextIds.java new file mode 100644 index 000000000..fa8fa8a21 --- /dev/null +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/IHelpContextIds.java @@ -0,0 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2007 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jsch.internal.ui; + +public interface IHelpContextIds{ + + public final String USER_VALIDATION_DIALOG=null; + public final String KEYBOARD_INTERACTIVE_DIALOG=null; + +} diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/JSchUIPlugin.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/JSchUIPlugin.java index bb3e781f1..4865d38b1 100644 --- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/JSchUIPlugin.java +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/JSchUIPlugin.java @@ -157,4 +157,8 @@ public class JSchUIPlugin extends AbstractUIPlugin{ } + public URL getImageUrl(String relative){ + return FileLocator.find(Platform.getBundle(ID), new Path(IUIConstants.ICON_PATH + relative), null); + } + } diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/KeyboardInteractiveDialog.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/KeyboardInteractiveDialog.java new file mode 100644 index 000000000..b07b98741 --- /dev/null +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/KeyboardInteractiveDialog.java @@ -0,0 +1,331 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 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 org.eclipse.jsch.internal.ui; + +import org.eclipse.jface.dialogs.*; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.window.Window; +import org.eclipse.osgi.util.NLS; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.ui.PlatformUI; + +/** + * A dialog for keyboard-interactive authentication for the ssh2 connection. + */ +public class KeyboardInteractiveDialog extends TrayDialog { + // widgets + private Text[] texts; + protected Image keyLockImage; + protected Button allowCachingButton; + protected Text usernameField; + + protected String userName; + protected String domain; + protected String destination; + protected String name; + protected String instruction; + protected String lang; + protected String[] prompt; + protected boolean[] echo; + private String message; + private String[] result; + protected boolean allowCaching=false; + + private boolean isPasswordAuth=false; + + + /** + * Creates a new KeyboardInteractiveDialog. + * + * @param parentShell the parent shell + * @param location + * @param destination + * @param name the name + * @param userName + * @param instruction the instruction + * @param prompt the titles for text fields + * @param echo '*' should be used or not + */ + public KeyboardInteractiveDialog(Shell parentShell, + String location, + String destination, + String name, + String userName, + String instruction, + String[] prompt, + boolean[] echo){ + super(parentShell); + this.domain=location; + this.destination=destination; + this.name=name; + this.userName=userName; + this.instruction=instruction; + this.prompt=prompt; + this.echo=echo; + if (name!=null && name.length()>0) { + this.message=NLS.bind(Messages.KeyboardInteractiveDialog_0, new String[] { destination, name }); + } else { + this.message=NLS.bind(Messages.KeyboardInteractiveDialog_1, destination); + } + + if(KeyboardInteractiveDialog.isPasswordAuth(prompt)){ + isPasswordAuth=true; + } + } + /** + * @see Window#configureShell + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + if (isPasswordAuth) { + newShell.setText(Messages.KeyboardInteractiveDialog_2); + } else { + newShell.setText(message); + } + + // set F1 help + PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, + IHelpContextIds.KEYBOARD_INTERACTIVE_DIALOG); + } + /** + * @see Window#create + */ + public void create() { + super.create(); + + if (isPasswordAuth && usernameField != null && userName != null) { + usernameField.setText(userName); + usernameField.setEditable(false); + } + + if (texts.length > 0) { + texts[0].setFocus(); + } + } + /** + * @see Dialog#createDialogArea + */ + protected Control createDialogArea(Composite parent) { + Composite top = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + + top.setLayout(layout); + top.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Composite imageComposite = new Composite(top, SWT.NONE); + layout = new GridLayout(); + imageComposite.setLayout(layout); + imageComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + + Composite main = new Composite(top, SWT.NONE); + layout = new GridLayout(); + layout.numColumns = 3; + main.setLayout(layout); + main.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label imageLabel = new Label(imageComposite, SWT.NONE); + keyLockImage = ImageDescriptor.createFromURL(JSchUIPlugin.getPlugin().getImageUrl(IUIConstants.IMG_KEY_LOCK)).createImage(); + imageLabel.setImage(keyLockImage); + GridData data = new GridData(GridData.FILL_HORIZONTAL + | GridData.GRAB_HORIZONTAL); + imageLabel.setLayoutData(data); + + if (message != null) { + Label messageLabel = new Label(main, SWT.WRAP); + messageLabel.setText(message); + data = new GridData(GridData.FILL_HORIZONTAL + | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 3; + data.widthHint = 300; + messageLabel.setLayoutData(data); + } + + if (domain != null) { + Label d = new Label(main, SWT.WRAP); + d.setText(Messages.KeyboardInteractiveDialog_3); + data = new GridData(); + d.setLayoutData(data); + Label label = new Label(main, SWT.WRAP); + + label.setText(domain); + + data = new GridData(GridData.FILL_HORIZONTAL + | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 2; + data.widthHint = 300; + label.setLayoutData(data); + } + + if (instruction != null && instruction.length() > 0) { + Label label = new Label(main, SWT.WRAP); + label.setText(instruction); + data = new GridData(GridData.FILL_HORIZONTAL + | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 3; + data.widthHint = 300; + label.setLayoutData(data); + } + + if (isPasswordAuth) { + createUsernameFields(main); + } + + createPasswordFields(main); + + if (isPasswordAuth & domain != null) { + allowCachingButton = new Button(main, SWT.CHECK); + allowCachingButton.setText(Messages.KeyboardInteractiveDialog_4); + data = new GridData(GridData.FILL_HORIZONTAL + | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 3; + allowCachingButton.setLayoutData(data); + allowCachingButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + allowCaching = allowCachingButton.getSelection(); + } + }); + Composite warningComposite = new Composite(main, SWT.NONE); + layout = new GridLayout(); + layout.numColumns = 2; + layout.marginHeight = 0; + layout.marginHeight = 0; + warningComposite.setLayout(layout); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalSpan = 3; + warningComposite.setLayoutData(data); + Label warningLabel = new Label(warningComposite, SWT.NONE); + warningLabel.setImage(getImage(DLG_IMG_MESSAGE_WARNING)); + warningLabel.setLayoutData(new GridData( + GridData.VERTICAL_ALIGN_BEGINNING + | GridData.HORIZONTAL_ALIGN_BEGINNING)); + Label warningText = new Label(warningComposite, SWT.WRAP); + warningText.setText(Messages.KeyboardInteractiveDialog_5); + data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = 300; + warningText.setLayoutData(data); + } + + Dialog.applyDialogFont(parent); + return main; + } + + /** + * Creates the three widgets that represent the user name entry area. + * + * @param parent the parent of the widgets + */ + protected void createUsernameFields(Composite parent){ + new Label(parent, SWT.NONE).setText(Messages.KeyboardInteractiveDialog_6); + + usernameField=new Text(parent, SWT.BORDER); + GridData data=new GridData(GridData.FILL_HORIZONTAL); + data.horizontalSpan=2; + data.widthHint=convertHorizontalDLUsToPixels(IDialogConstants.ENTRY_FIELD_WIDTH); + usernameField.setLayoutData(data); + } + + /** + * Creates the widgets that represent the entry area. + * + * @param parent + * the parent of the widgets + */ + protected void createPasswordFields(Composite parent) { + texts=new Text[prompt.length]; + + for(int i=0; i<prompt.length; i++){ + new Label(parent, SWT.NONE).setText(prompt[i]); + texts[i]=new Text(parent, SWT.BORDER|SWT.PASSWORD); + GridData data=new GridData(GridData.FILL_HORIZONTAL); + data.horizontalSpan=2; + data.widthHint=convertHorizontalDLUsToPixels(IDialogConstants.ENTRY_FIELD_WIDTH); + texts[i].setLayoutData(data); + if(!echo[i]){ + texts[i].setEchoChar('*'); + } + } + } + /** + * Returns the entered values, or null + * if the user canceled. + * + * @return the entered values + */ + public String[] getResult() { + return result; + } + + /** + * Returns <code>true</code> if the save password checkbox was selected. + * @return <code>true</code> if the save password checkbox was selected and <code>false</code> + * otherwise. + */ + public boolean getAllowCaching(){ + return allowCaching; + } + + /** + * Notifies that the ok button of this dialog has been pressed. + * <p> + * The default implementation of this framework method sets + * this dialog's return code to <code>Window.OK</code> + * and closes the dialog. Subclasses may override. + * </p> + */ + protected void okPressed() { + result=new String[prompt.length]; + for(int i=0; i<texts.length; i++){ + result[i]=texts[i].getText(); + } + super.okPressed(); + } + /** + * Notifies that the cancel button of this dialog has been pressed. + * <p> + * The default implementation of this framework method sets + * this dialog's return code to <code>Window.CANCEL</code> + * and closes the dialog. Subclasses may override. + * </p> + */ + protected void cancelPressed() { + result=null; + super.cancelPressed(); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#close() + */ + public boolean close(){ + if(keyLockImage!=null){ + keyLockImage.dispose(); + } + return super.close(); + } + + /** + * Guesses if this dialog is used for password authentication. + * @param prompt prompts for keyboard-interactive authentication method. + * @return <code>true</code> if this dialog is used for password authentication. + */ + static boolean isPasswordAuth(String[] prompt) { + return prompt != null && prompt.length == 1 + && prompt[0].trim().equalsIgnoreCase("password:"); //$NON-NLS-1$ + } +} diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java index c040aca99..54594ee37 100644 --- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/Messages.java @@ -83,4 +83,19 @@ public class Messages extends NLS{ public static String CVSSSH2PreferencePage_136; public static String CVSSSH2PreferencePage_138; public static String CVSSSH2PreferencePage_139; + public static String KeyboardInteractiveDialog_0; + public static String KeyboardInteractiveDialog_1; + public static String KeyboardInteractiveDialog_2; + public static String KeyboardInteractiveDialog_3; + public static String KeyboardInteractiveDialog_4; + public static String KeyboardInteractiveDialog_5; + public static String KeyboardInteractiveDialog_6; + public static String UserInfoPrompter_0; + public static String UserInfoPrompter_1; + public static String UserValidationDialog_0; + public static String UserValidationDialog_1; + public static String UserValidationDialog_2; + public static String UserValidationDialog_3; + public static String UserValidationDialog_4; + public static String UserValidationDialog_5; } diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/UserValidationDialog.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/UserValidationDialog.java new file mode 100644 index 000000000..6391065dc --- /dev/null +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/UserValidationDialog.java @@ -0,0 +1,274 @@ +/******************************************************************************* + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jsch.internal.ui; + + +import org.eclipse.jface.dialogs.*; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.ui.PlatformUI; + +/** + * A dialog for prompting for a user name and password + */ +public class UserValidationDialog extends TrayDialog { + // widgets + protected Text usernameField; + protected Text passwordField; + protected Button allowCachingButton; + + protected String domain; + protected String defaultUsername; + protected String password = null; + protected boolean allowCaching = false; + protected Image keyLockImage; + + // whether or not the user name can be changed + protected boolean isUsernameMutable = true; + protected String username = null; + protected String message = null; + + /** + * Creates a new UserValidationDialog. + * + * @param parentShell the parent shell + * @param location the location + * @param defaultName the default user name + * @param message a message to display to the user + */ + public UserValidationDialog(Shell parentShell, String location, String defaultName, String message) { + super(parentShell); + setShellStyle(getShellStyle() | SWT.RESIZE); + this.defaultUsername = defaultName; + this.domain = location; + this.message = message; + } + /** + * @see Window#configureShell + */ + protected void configureShell(Shell newShell) { + super.configureShell(newShell); + newShell.setText(Messages.UserValidationDialog_0); + // set F1 help + PlatformUI.getWorkbench().getHelpSystem().setHelp(newShell, IHelpContextIds.USER_VALIDATION_DIALOG); + } + /** + * @see Window#create + */ + public void create() { + super.create(); + // add some default values + usernameField.setText(defaultUsername); + + if (isUsernameMutable) { + // give focus to user name field + usernameField.selectAll(); + usernameField.setFocus(); + } else { + usernameField.setEditable(false); + passwordField.setFocus(); + } + } + + /** + * @see Dialog#createDialogArea + */ + protected Control createDialogArea(Composite parent) { + Composite top = new Composite(parent, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.numColumns = 2; + + top.setLayout(layout); + top.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Composite imageComposite = new Composite(top, SWT.NONE); + layout = new GridLayout(); + imageComposite.setLayout(layout); + imageComposite.setLayoutData(new GridData(GridData.FILL_VERTICAL)); + + Composite main = new Composite(top, SWT.NONE); + layout = new GridLayout(); + layout.numColumns = 3; + main.setLayout(layout); + main.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + Label imageLabel = new Label(imageComposite, SWT.NONE); + keyLockImage = ImageDescriptor.createFromURL(JSchUIPlugin.getPlugin().getImageUrl(IUIConstants.IMG_KEY_LOCK)).createImage(); + imageLabel.setImage(keyLockImage); + GridData data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL); + imageLabel.setLayoutData(data); + + if (message != null) { + Label messageLabel = new Label(main, SWT.WRAP); + messageLabel.setText(message); + data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 3; + data.widthHint = 300; + messageLabel.setLayoutData(data); + } + if (domain != null) { + Label d = new Label(main, SWT.WRAP); + d.setText(Messages.UserValidationDialog_1); + data = new GridData(); + d.setLayoutData(data); + Label label = new Label(main, SWT.WRAP); + label.setText(domain); + data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 2; + data.widthHint = 300; + label.setLayoutData(data); + } + createUsernameFields(main); + createPasswordFields(main); + + if(domain != null) { + allowCachingButton = new Button(main, SWT.CHECK); + allowCachingButton.setText(Messages.UserValidationDialog_2); + data = new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL); + data.horizontalSpan = 3; + allowCachingButton.setLayoutData(data); + allowCachingButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + allowCaching = allowCachingButton.getSelection(); + } + }); + Composite warningComposite = new Composite(main, SWT.NONE); + layout = new GridLayout(); + layout.numColumns = 2; + layout.marginHeight = 0; + layout.marginHeight = 0; + warningComposite.setLayout(layout); + data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalSpan = 3; + warningComposite.setLayoutData(data); + Label warningLabel = new Label(warningComposite, SWT.NONE); + warningLabel.setImage(getImage(DLG_IMG_MESSAGE_WARNING)); + warningLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_BEGINNING)); + Label warningText = new Label(warningComposite, SWT.WRAP); + warningText.setText(Messages.UserValidationDialog_3); + data = new GridData(GridData.FILL_HORIZONTAL); + data.widthHint = 300; + warningText.setLayoutData(data); + } + + Dialog.applyDialogFont(parent); + + return main; + } + + /** + * Creates the three widgets that represent the password entry area. + * + * @param parent the parent of the widgets + */ + protected void createPasswordFields(Composite parent) { + new Label(parent, SWT.NONE).setText(Messages.UserValidationDialog_4); + + passwordField = new Text(parent, SWT.BORDER | SWT.PASSWORD); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalSpan = 2; + data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.ENTRY_FIELD_WIDTH); + passwordField.setLayoutData(data); + } + /** + * Creates the three widgets that represent the user name entry area. + * + * @param parent the parent of the widgets + */ + protected void createUsernameFields(Composite parent) { + new Label(parent, SWT.NONE).setText(Messages.UserValidationDialog_5); + + usernameField = new Text(parent, SWT.BORDER); + GridData data = new GridData(GridData.FILL_HORIZONTAL); + data.horizontalSpan = 2; + data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.ENTRY_FIELD_WIDTH); + usernameField.setLayoutData(data); + } + + /** + * Returns the password entered by the user, or null + * if the user canceled. + * + * @return the entered password + */ + public String getPassword() { + return password; + } + + /** + * Returns the user name entered by the user, or null + * if the user canceled. + * + * @return the entered user name + */ + public String getUsername() { + return username; + } + + /** + * Returns <code>true</code> if the save password checkbox was selected. + * @return <code>true</code> if the save password checkbox was selected and <code>false</code> + * otherwise. + */ + public boolean getAllowCaching() { + return allowCaching; + } + + /** + * Notifies that the ok button of this dialog has been pressed. + * <p> + * The default implementation of this framework method sets + * this dialog's return code to <code>Window.OK</code> + * and closes the dialog. Subclasses may override. + * </p> + */ + protected void okPressed() { + password = passwordField.getText(); + username = usernameField.getText(); + + super.okPressed(); + } + + protected void cancelPressed(){ + password = null; + username = null; + super.cancelPressed(); + } + + /** + * Sets whether or not the user name field should be mutable. + * This method must be called before create(), otherwise it + * will be ignored. + * + * @param value whether the user name is mutable + */ + public void setUsernameMutable(boolean value) { + isUsernameMutable = value; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.Dialog#close() + */ + public boolean close() { + if(keyLockImage != null) { + keyLockImage.dispose(); + } + return super.close(); + } +} diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties index c68a6a0f9..a4035b36b 100644 --- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/messages.properties @@ -73,3 +73,18 @@ CVSSSH2PreferencePage_135=Type CVSSSH2PreferencePage_136=Fingerprint CVSSSH2PreferencePage_138=&Remove CVSSSH2PreferencePage_139=Keys of known hosts: +UserInfoPrompter_0=SSH2 Message +UserInfoPrompter_1=SSH2 Message +KeyboardInteractiveDialog_0=Keyboard Interactive authentication for {0}: {1} +KeyboardInteractiveDialog_1=Keyboard Interactive authentication for {0} +KeyboardInteractiveDialog_2=Password Required +KeyboardInteractiveDialog_3=Domain: +KeyboardInteractiveDialog_4=&Save password +KeyboardInteractiveDialog_5=Saved passwords are stored on your computer in a file that is difficult, but not impossible, for an intruder to read. +KeyboardInteractiveDialog_6=&User name: +UserValidationDialog_0=Password Required +UserValidationDialog_1=Domain: +UserValidationDialog_2=&Save password +UserValidationDialog_3=Saved passwords are stored on your computer in a file that is difficult, but not impossible, for an intruder to read. +UserValidationDialog_4=&Password: +UserValidationDialog_5=&User name: diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java index 8987b2a33..f515233db 100644 --- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/internal/ui/preference/PreferencePage.java @@ -868,7 +868,7 @@ public class PreferencePage extends org.eclipse.jface.preference.PreferencePage int timeout = 60000; Session session = JSchProvider.createSession(host, port, user); - session.setUserInfo(new UserInfoPrompter()); + new UserInfoPrompter(session); session.setTimeout(timeout); try { JSchProvider.connect(session, timeout, new NullProgressMonitor()); diff --git a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/ui/UserInfoPrompter.java b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/ui/UserInfoPrompter.java index 5f3f527d6..495039568 100644 --- a/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/ui/UserInfoPrompter.java +++ b/bundles/org.eclipse.jsch.ui/src/org/eclipse/jsch/ui/UserInfoPrompter.java @@ -10,56 +10,289 @@ *******************************************************************************/ package org.eclipse.jsch.ui; -import com.jcraft.jsch.UserInfo; +import org.eclipse.core.runtime.OperationCanceledException; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jsch.core.JSchProvider; +import org.eclipse.jsch.internal.ui.*; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Shell; -public class UserInfoPrompter implements UserInfo{ +import com.jcraft.jsch.*; - /* (non-Javadoc) +/** + * A {@link UserInfo} prompter implementation that can be used when connecting a + * {@link Session}. + * <p> + * Clients may instantiate or subclass this class. + * + * @since 1.0 + * @see JSchProvider#createSession(String, int, String) + * @see JSchProvider#connect(Session, int, + * org.eclipse.core.runtime.IProgressMonitor) + */ +public class UserInfoPrompter implements UserInfo, UIKeyboardInteractive{ + + private String passphrase; + private String password; + private final Session session; + private int attemptCount; + + /** + * Create a prompter for the given session. This constructor will associate + * this prompter with the session using {@link Session#setUserInfo(UserInfo)}. + * + * @param session + * the session + */ + public UserInfoPrompter(Session session){ + super(); + this.session=session; + session.setUserInfo(this); + } + + /** + * Return the session to which this prompter is assigned. + * + * @return the session to which this prompter is assigned + */ + public Session getSession(){ + return session; + } + + /* + * (non-Javadoc) + * * @see com.jcraft.jsch.UserInfo#getPassphrase() */ public String getPassphrase(){ - // XXX Auto-generated method stub - return null; + return passphrase; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.jcraft.jsch.UserInfo#getPassword() */ public String getPassword(){ - // XXX Auto-generated method stub - return null; + return password; } - /* (non-Javadoc) + /** + * Set the pass phrase to be used when connecting the session. Return + * <code>null</code> if the pass phrase is not known. + * + * @param passphrase + * the pass phrase to be used when connecting the session or + * <code>null</code> + */ + public void setPassphrase(String passphrase){ + this.passphrase=passphrase; + } + + /** + * Set the password to be used when connecting the session. Return + * <code>null</code> if the password is not known. + * + * @param password + * the password to be used when connecting the session or + * <code>null</code> + */ + public void setPassword(String password){ + this.password=password; + } + + /* + * (non-Javadoc) + * * @see com.jcraft.jsch.UserInfo#promptPassphrase(java.lang.String) */ - public boolean promptPassphrase(String arg0){ - // XXX Auto-generated method stub - return false; + public boolean promptPassphrase(String message){ + String _passphrase=promptSecret(message); + if(_passphrase!=null){ + setPassphrase(_passphrase); + } + return _passphrase!=null; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.jcraft.jsch.UserInfo#promptPassword(java.lang.String) */ - public boolean promptPassword(String arg0){ - // XXX Auto-generated method stub - return false; + public boolean promptPassword(String message){ + String _password=promptSecret(message); + if(_password!=null){ + setPassword(_password); + } + return _password!=null; + } + + private String promptSecret(final String message){ + // ask the user for a password + final String[] result=new String[1]; + Display display=Display.getCurrent(); + if(display!=null){ + result[0]=promptForPassword(message); + } + else{ + // sync exec in default thread + Display.getDefault().syncExec(new Runnable(){ + public void run(){ + result[0]=promptForPassword(message); + } + }); + } + + if(result[0]==null){ + throw new OperationCanceledException(); + } + return result[0]; + } + + /* package */String promptForPassword(final String message){ + String username=getSession().getUserName(); + UserValidationDialog dialog=new UserValidationDialog(null, null, + (username==null) ? "" : username, message); //$NON-NLS-1$ + dialog.setUsernameMutable(false); + dialog.open(); + return dialog.getPassword(); + } + + /* + * (non-Javadoc) + * + * @see com.jcraft.jsch.UIKeyboardInteractive#promptKeyboardInteractive(java.lang.String, + * java.lang.String, java.lang.String, java.lang.String[], boolean[]) + */ + 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=iromptForKeyboradInteractiveInUI(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]; + } + attemptCount++; + return result; + } + catch(OperationCanceledException e){ + return null; + } } - /* (non-Javadoc) + private String[] iromptForKeyboradInteractiveInUI(final String destination, + final String name, final String instruction, final String[] prompt, + final boolean[] echo){ + final String[][] result=new String[1][]; + Display display=Display.getCurrent(); + if(display!=null){ + result[0]=internalPromptForUserInteractive(destination, name, + instruction, prompt, echo); + } + else{ + // sync exec in default thread + Display.getDefault().syncExec(new Runnable(){ + public void run(){ + result[0]=internalPromptForUserInteractive(destination, name, + instruction, prompt, echo); + } + }); + } + return result[0]; + } + + /* package */ String[] internalPromptForUserInteractive(String destination, + String name, String instruction, String[] prompt, boolean[] echo){ + String domain=null; + String userName=getSession().getUserName(); + KeyboardInteractiveDialog dialog=new KeyboardInteractiveDialog(null, + domain, destination, name, userName, instruction, prompt, echo); + dialog.open(); + String[] _result=dialog.getResult(); + return _result; + } + + /* + * (non-Javadoc) + * * @see com.jcraft.jsch.UserInfo#promptYesNo(java.lang.String) */ - public boolean promptYesNo(String arg0){ - // XXX Auto-generated method stub - return false; + public boolean promptYesNo(String question){ + int prompt=prompt(MessageDialog.QUESTION, Messages.UserInfoPrompter_0, + question, new int[] {IDialogConstants.YES_ID, IDialogConstants.NO_ID}, + 0 // yes + // the + // default + ); + return prompt==0; } - /* (non-Javadoc) + /* + * (non-Javadoc) + * * @see com.jcraft.jsch.UserInfo#showMessage(java.lang.String) */ - public void showMessage(String arg0){ - // XXX Auto-generated method stub + public void showMessage(String message){ + prompt(MessageDialog.INFORMATION, Messages.UserInfoPrompter_1, message, + new int[] {IDialogConstants.OK_ID}, 0); + } + + private int prompt(final int promptType, final String title, + final String message, final int[] promptResponses, + final int defaultResponse){ + final Display display=getStandardDisplay(); + final int[] retval=new int[1]; + final String[] buttons=new String[promptResponses.length]; + for(int i=0; i<promptResponses.length; i++){ + int prompt=promptResponses[i]; + switch(prompt){ + case IDialogConstants.OK_ID: + buttons[i]=IDialogConstants.OK_LABEL; + break; + case IDialogConstants.CANCEL_ID: + buttons[i]=IDialogConstants.CANCEL_LABEL; + break; + case IDialogConstants.NO_ID: + buttons[i]=IDialogConstants.NO_LABEL; + break; + case IDialogConstants.YES_ID: + buttons[i]=IDialogConstants.YES_LABEL; + break; + } + } + + display.syncExec(new Runnable(){ + public void run(){ + final MessageDialog dialog=new MessageDialog(new Shell(display), title, + null /* title image */, message, promptType, buttons, + defaultResponse); + retval[0]=dialog.open(); + } + }); + return retval[0]; + } + private Display getStandardDisplay(){ + Display display=Display.getCurrent(); + if(display==null){ + display=Display.getDefault(); + } + return display; } } |