diff options
author | Michael Valenta | 2005-04-04 19:36:45 +0000 |
---|---|---|
committer | Michael Valenta | 2005-04-04 19:36:45 +0000 |
commit | 5f74fe5b171576e56e6473400bf579294b55cda3 (patch) | |
tree | 426c426f6c4834d1a7472fdedc8838a0ccce50aa /bundles | |
parent | 276590a63db8412635cd408a9dc494c598ac6f47 (diff) | |
download | eclipse.platform.team-5f74fe5b171576e56e6473400bf579294b55cda3.tar.gz eclipse.platform.team-5f74fe5b171576e56e6473400bf579294b55cda3.tar.xz eclipse.platform.team-5f74fe5b171576e56e6473400bf579294b55cda3.zip |
Bug 89275 [SSH2] Prompted many times when server key changes
Diffstat (limited to 'bundles')
7 files changed, 80 insertions, 16 deletions
diff --git a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/IUserAuthenticator.java b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/IUserAuthenticator.java index 941c13a77..354f76c36 100644 --- a/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/IUserAuthenticator.java +++ b/bundles/org.eclipse.team.cvs.core/src/org/eclipse/team/internal/ccvs/core/IUserAuthenticator.java @@ -123,4 +123,11 @@ public interface IUserAuthenticator { * @since 3.0 */ public int prompt(ICVSRepositoryLocation location, int promptType, String title, String message, int[] promptResponses, int defaultResponseIndex); + + /** + * The host key for the given location has changed. + * @param location + * @return true if new host key should be accepted + */ + public boolean promptForHostKeyChange(ICVSRepositoryLocation location); } diff --git a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2PreferencePage.java b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2PreferencePage.java index 52613c651..49c713141 100644 --- a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2PreferencePage.java +++ b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2PreferencePage.java @@ -974,7 +974,7 @@ public class CVSSSH2PreferencePage extends PreferencePage */ IProgressMonitor pm=new org.eclipse.core.runtime.NullProgressMonitor(); - Session session=JSchSession.getSession(null, user, "", host, port, new JSchSession.ResponsiveSocketFacory(pm)).getSession(); //$NON-NLS-1$ + Session session=JSchSession.getSession(null, user, "", host, port, pm).getSession(); //$NON-NLS-1$ if(session.getServerVersion().indexOf("OpenSSH")==-1){ //$NON-NLS-1$ setErrorMessage(Policy.bind("CVSSSH2PreferencePage.110")); //$NON-NLS-1$ return; diff --git a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2ServerConnection.java b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2ServerConnection.java index 3cd815521..324a79e3c 100644 --- a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2ServerConnection.java +++ b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/CVSSSH2ServerConnection.java @@ -104,7 +104,7 @@ public class CVSSSH2ServerConnection implements IServerConnection { boolean tryAgain = false; while (firstTime || tryAgain) { tryAgain = false; // reset the try again flag - session = JSchSession.getSession(location, location.getUsername(), password, location.getHost(), location.getPort(), new JSchSession.ResponsiveSocketFacory(monitor)); + session = JSchSession.getSession(location, location.getUsername(), password, location.getHost(), location.getPort(), monitor); channel = session.getSession().openChannel("exec"); //$NON-NLS-1$ ((ChannelExec) channel).setCommand(COMMAND); channel_out = channel.getOutputStream(); diff --git a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/JSchSession.java b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/JSchSession.java index a2be90032..73e4ad78e 100644 --- a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/JSchSession.java +++ b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/JSchSession.java @@ -181,6 +181,7 @@ class JSchSession { private IUserAuthenticator authenticator; private int attemptCount; private boolean passwordChanged; + private boolean purgeHostKey; MyUserInfo(String username, String password, ICVSRepositoryLocation location) { this.location = location; @@ -266,16 +267,26 @@ class JSchSession { } } public void showMessage(String message) { - authenticator.prompt( - location, - IUserAuthenticator.INFORMATION, - Policy.bind("JSchSession.5"), //$NON-NLS-1$ - message, - new int[] {IUserAuthenticator.OK_ID}, - IUserAuthenticator.OK_ID - ); + if (isHostKeyChangeWarning(message)) { + handleHostKeyChange(); + } else { + authenticator.prompt( + location, + IUserAuthenticator.INFORMATION, + Policy.bind("JSchSession.5"), //$NON-NLS-1$ + message, + new int[] {IUserAuthenticator.OK_ID}, + IUserAuthenticator.OK_ID + ); + } } - public String[] promptKeyboardInteractive(String destination, + private void handleHostKeyChange() { + purgeHostKey = authenticator.promptForHostKeyChange(location); + } + private boolean isHostKeyChangeWarning(String message) { + return message.indexOf("WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED") != -1; //$NON-NLS-1$ + } + public String[] promptKeyboardInteractive(String destination, String name, String instruction, String[] prompt, @@ -329,6 +340,9 @@ class JSchSession { // We were prompted for and returned a password so record it with the location location.setPassword(password); } + } + public boolean isPurgeHostKey() { + return purgeHostKey; } } @@ -336,7 +350,7 @@ class JSchSession { return ee.getMessage().equals("Auth fail"); //$NON-NLS-1$ } - static JSchSession getSession(ICVSRepositoryLocation location, String username, String password, String hostname, int port, SocketFactory socketFactory) throws JSchException { + static JSchSession getSession(ICVSRepositoryLocation location, String username, String password, String hostname, int port, IProgressMonitor monitor) throws JSchException { if (port == ICVSRepositoryLocation.USE_DEFAULT_PORT) port = getPort(location); @@ -416,11 +430,23 @@ class JSchSession { Session session = null; try { - session = createSession(username, password, hostname, port, socketFactory, proxy, wrapperUI); + session = createSession(username, password, hostname, port, new JSchSession.ResponsiveSocketFacory(monitor), proxy, wrapperUI); } catch (JSchException e) { if (isAuthenticationFailure(e) && wrapperUI.hasPromptExceededTimeout()) { // Try again since the previous prompt may have obtained the proper credentials from the user - session = createSession(username, password, hostname, port, socketFactory, proxy, wrapperUI); + session = createSession(username, password, hostname, port, new JSchSession.ResponsiveSocketFacory(monitor), proxy, wrapperUI); + } else if (isHostKeyChangeError(e) && ui.isPurgeHostKey()) { + // Remove the host keys + HostKeyRepository hkr =JSchSession.getJSch().getHostKeyRepository(); + HostKey[] keys = hkr.getHostKey(); + for (int i = 0; i < keys.length; i++) { + HostKey hostKey = keys[i]; + if (hostKey.getHost().equals(hostname)) { + hkr.remove(hostKey.getHost(), hostKey.getType()); + } + } + // Retry the connection + session = createSession(username, password, hostname, port, new JSchSession.ResponsiveSocketFacory(monitor), proxy, wrapperUI); } else { throw e; } @@ -441,6 +467,15 @@ class JSchSession { } } + private static boolean isHostKeyPurged(String hostname) { + // TODO Auto-generated method stub + return false; + } + + private static boolean isHostKeyChangeError(JSchException e) { + return e.getMessage().equals("HostKey has been changed"); //$NON-NLS-1$ + } + private static Session createSession(String username, String password, String hostname, int port, SocketFactory socketFactory, Proxy proxy, UserInfo wrapperUI) throws JSchException { Session session = jsch.getSession(username, hostname, port); if (proxy != null) { @@ -450,7 +485,13 @@ class JSchSession { session.setUserInfo(wrapperUI); session.setSocketFactory(socketFactory); // This is where the server is contacted and authentication occurs - session.connect(); + try { + session.connect(); + } catch (JSchException e) { + if (session.isConnected()) + session.disconnect(); + throw e; + } return session; } diff --git a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/PServerSSH2ServerConnection.java b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/PServerSSH2ServerConnection.java index f003fdea5..6ac08bb3a 100644 --- a/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/PServerSSH2ServerConnection.java +++ b/bundles/org.eclipse.team.cvs.ssh2/src/org/eclipse/team/internal/ccvs/ssh2/PServerSSH2ServerConnection.java @@ -87,7 +87,7 @@ public class PServerSSH2ServerConnection implements IServerConnection { int retry = 1; while (true) { try { - session = JSchSession.getSession(location, ssh_user, "", ssh_host, ssh_port, new JSchSession.ResponsiveSocketFacory(monitor)).getSession(); //$NON-NLS-1$ + session = JSchSession.getSession(location, ssh_user, "", ssh_host, ssh_port, monitor).getSession(); //$NON-NLS-1$ String[] list = session.getPortForwardingL(); String name = ":" + rhost + ":" + rport; //$NON-NLS-1$ //$NON-NLS-2$ boolean done = false; diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkbenchUserAuthenticator.java b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkbenchUserAuthenticator.java index a1041e8fa..ec40c0efe 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkbenchUserAuthenticator.java +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/WorkbenchUserAuthenticator.java @@ -242,4 +242,18 @@ public class WorkbenchUserAuthenticator implements IUserAuthenticator { }); return retval[0]; } + + public boolean promptForHostKeyChange(final ICVSRepositoryLocation location) { + final boolean[] openConfirm = new boolean[] { false }; + final Display display = CVSUIPlugin.getStandardDisplay(); + display.syncExec(new Runnable() { + public void run() { + openConfirm[0] = MessageDialog.openConfirm(null, Policy.bind("WorkbenchUserAuthenticator.1"), Policy.bind("WorkbenchUserAuthenticator.2", location.getHost())); //$NON-NLS-1$ //$NON-NLS-2$ + } + }); + if (!openConfirm[0]) { + throw new OperationCanceledException(); + } + return openConfirm[0]; + } } diff --git a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties index 2677346f3..63d5c1029 100644 --- a/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties +++ b/bundles/org.eclipse.team.cvs.ui/src/org/eclipse/team/internal/ccvs/ui/messages.properties @@ -761,6 +761,8 @@ VersionsElement.versions=Versions WorkbenchUserAuthenticator.cancelled=Operation cancelled because login cancelled WorkbenchUserAuthenticator.0=An attempt to prompt for user authentication information has failed. +WorkbenchUserAuthenticator.1=Host Key Change +WorkbenchUserAuthenticator.2=The host key for {0} has changed. It is possible that this was intentional but there is also a chance that you are the target of an attack of some kind. If you know that the host key has changed, click OK and existing host key will be purged. Otherwise, click Cancel and consult with your system administrator WorkbenchUserAuthenticator.errorFlushing=Error occurred while flushing password for {0} WorkbenchUserAuthenticator.errorSaving=Error occurred while saving password for {0} |