Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 92887

Summary: [SSH2] Prompted for server password after being prompted for keyring password
Product: [Eclipse Project] Platform Reporter: Dani Megert <daniel_megert>
Component: CVSAssignee: platform-cvs-inbox <platform-cvs-inbox>
Status: RESOLVED DUPLICATE QA Contact:
Severity: normal    
Priority: P3 CC: ymnk
Version: 3.1   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Fix none

Description Dani Megert CLA 2005-04-27 05:01:07 EDT
I20050426-1700

Prompted for server password after being prompted for keyring password. This
does not happen all the time but from time to time (see also comments in bug
66885 and bug 90766).

1. open an editor on a file that is shared
2. ensure that the CVS Quick Diff reference provider is used
3. ensure to used ssh2 with a password protected keyring
4. ensure another window is open with Team perspective
5. exit
6. start
7. switch to another application for several minutes
8. switch back to eclipse
   ==> password for keyring gets asked
9. enter keyring password
==>

Bug 1: server password gets asked
Bug 2: select the "Save Password" checkbox and repeat 5. - 9. ==> server
password is queried even though I checked to save it.


!ENTRY org.eclipse.team.cvs.core 4 2 2005-04-27 09:50:02.140
!MESSAGE Authentication error: An undetermined authentication failure has occurred
!STACK 0
com.jcraft.jsch.JSchException: Auth fail
	at com.jcraft.jsch.Session.connect(Unknown Source)
	at com.jcraft.jsch.Session.connect(Unknown Source)
	at
org.eclipse.team.internal.ccvs.ssh2.JSchSession.createSession(JSchSession.java:484)
	at org.eclipse.team.internal.ccvs.ssh2.JSchSession.getSession(JSchSession.java:433)
	at
org.eclipse.team.internal.ccvs.ssh2.CVSSSH2ServerConnection.internalOpen(CVSSSH2ServerConnection.java:108)
	at
org.eclipse.team.internal.ccvs.ssh2.CVSSSH2ServerConnection.open(CVSSSH2ServerConnection.java:93)
	at
org.eclipse.team.internal.ccvs.core.connection.Connection.open(Connection.java:128)
	at
org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation.createConnection(CVSRepositoryLocation.java:493)
	at
org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation.openConnection(CVSRepositoryLocation.java:733)
	at org.eclipse.team.internal.ccvs.core.client.Session.open(Session.java:149)
	at
org.eclipse.team.internal.ccvs.core.resources.RemoteFile.internalFetchContents(RemoteFile.java:199)
	at
org.eclipse.team.internal.ccvs.core.resources.RemoteFile.fetchContents(RemoteFile.java:177)
	at
org.eclipse.team.core.variants.CachedResourceVariant.ensureContentsCached(CachedResourceVariant.java:111)
	at
org.eclipse.team.core.variants.CachedResourceVariant.getStorage(CachedResourceVariant.java:101)
	at
org.eclipse.team.internal.ccvs.core.resources.RemoteFile.getContents(RemoteFile.java:168)
	at
org.eclipse.team.internal.ccvs.ui.RemoteRevisionQuickDiffProvider.readDocument(RemoteRevisionQuickDiffProvider.java:254)
	at
org.eclipse.team.internal.ccvs.ui.RemoteRevisionQuickDiffProvider.getReference(RemoteRevisionQuickDiffProvider.java:131)
	at
org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer$1.run(DocumentLineDiffer.java:447)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:67)
Comment 1 Michael Valenta CLA 2005-05-02 10:01:31 EDT
I've tried your steps a couple of times and cannot reproduce the failure. 
There's not much I can do without being able to reproduce it. I'll leave this 
open. Please add any additonal information if you see this again.
Comment 2 Dani Megert CLA 2005-05-19 03:00:33 EDT
Here's an updated .log from this morning using latest N20050519-0010. I'll retry
the attached stpes from comment 0 to see what I forgot to provide since I really
like this bug being fixed.

!SESSION 2005-05-19 08:36:26.135 -----------------------------------------------
eclipse.buildId=N20050519-0010
java.version=1.5.0_03
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=win32, ARCH=x86, WS=win32, NL=de_CH
Framework arguments:  -update -keyring c:\eclipse\.keyring -application
org.eclipse.ui.ide.workbench -showlocation
Command-line arguments:  -update -keyring c:\eclipse\.keyring -application
org.eclipse.ui.ide.workbench -showlocation -data
c:\eclipse\workspaces\Development_2_2\plugins

!ENTRY org.eclipse.team.cvs.core 4 2 2005-05-19 08:41:25.615
!MESSAGE Authentication error: An undetermined authentication failure has occurred
!STACK 0
com.jcraft.jsch.JSchException: Auth fail
	at com.jcraft.jsch.Session.connect(Unknown Source)
	at com.jcraft.jsch.Session.connect(Unknown Source)
	at
org.eclipse.team.internal.ccvs.ssh2.JSchSession.createSession(JSchSession.java:486)
	at org.eclipse.team.internal.ccvs.ssh2.JSchSession.getSession(JSchSession.java:435)
	at
org.eclipse.team.internal.ccvs.ssh2.CVSSSH2ServerConnection.internalOpen(CVSSSH2ServerConnection.java:122)
	at
org.eclipse.team.internal.ccvs.ssh2.CVSSSH2ServerConnection.open(CVSSSH2ServerConnection.java:107)
	at
org.eclipse.team.internal.ccvs.core.connection.Connection.open(Connection.java:128)
	at
org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation.createConnection(CVSRepositoryLocation.java:494)
	at
org.eclipse.team.internal.ccvs.core.connection.CVSRepositoryLocation.openConnection(CVSRepositoryLocation.java:734)
	at org.eclipse.team.internal.ccvs.core.client.Session.open(Session.java:149)
	at
org.eclipse.team.internal.ccvs.core.resources.RemoteFile.internalFetchContents(RemoteFile.java:199)
	at
org.eclipse.team.internal.ccvs.core.resources.RemoteFile.fetchContents(RemoteFile.java:177)
	at
org.eclipse.team.core.variants.CachedResourceVariant.ensureContentsCached(CachedResourceVariant.java:111)
	at
org.eclipse.team.core.variants.CachedResourceVariant.getStorage(CachedResourceVariant.java:101)
	at
org.eclipse.team.internal.ccvs.core.resources.RemoteFile.getContents(RemoteFile.java:168)
	at
org.eclipse.team.internal.ccvs.ui.RemoteRevisionQuickDiffProvider.readDocument(RemoteRevisionQuickDiffProvider.java:254)
	at
org.eclipse.team.internal.ccvs.ui.RemoteRevisionQuickDiffProvider.getReference(RemoteRevisionQuickDiffProvider.java:131)
	at
org.eclipse.ui.internal.texteditor.quickdiff.DocumentLineDiffer$1.run(DocumentLineDiffer.java:448)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:67)
Comment 3 Dani Megert CLA 2005-06-24 07:10:41 EDT
I can also not reproduce this with a fresh workspace and a single connection but
it happens from time to time (at least once a week) in my large development
workspace where I have many different repository connection. Same machine.

Is there some debug/trace that I could enable to better track this down?
Comment 4 Michael Valenta CLA 2005-06-24 09:48:20 EDT
There is no tracing but we should add some in 3.2.
Comment 5 Dani Megert CLA 2005-12-15 12:24:49 EST
This drives me nuts at least twice a weak. I'll try to hunt it down now.
Comment 6 Dani Megert CLA 2005-12-15 13:24:06 EST
Setting a high connection timeout (60000 in my case) is the cause for this problem.
Comment 7 Dani Megert CLA 2005-12-15 16:57:13 EST
Found the bug:

ICVSRepositoryLocation.getTimeout() is defined as:
 	/**
	 * Return the conection timeout value in milliseconds.
	 * A value of 0 means there is no timeout value.
	 */
	public int getTimeout();

However, CVSRepositoryLocation.getTimeout() is implemented like this:

	public int getTimeout() {
		return CVSProviderPlugin.getPlugin().getTimeout();
	}

where CVSProviderPlugin.getPlugin().getTimeout() is in seconds!

The fix is to change CVSRepositoryLocation.getTimeout() to:
	public int getTimeout() {
		return CVSProviderPlugin.getPlugin().getTimeout() * 1000;
	}

I've checked occurrences and it looks good i.e. callers of ICVSRepositoryLocation.getTimeout() are indeed expecting ms.

Michael, the attached patch also contains a fix for the preference page: it clarifies the dimension of the connection timeout. I'd appreciate if you could release this soon.
Comment 8 Dani Megert CLA 2005-12-15 16:57:40 EST
Created attachment 31836 [details]
Fix
Comment 9 Michael Valenta CLA 2005-12-15 17:22:04 EST
I don't think this will fix your problem. I checked and all the users of the method are expected seconds. I've updated the javadoc of ICVSRepositoryLocation to indicate that the timeout is in seconds.

Are you saying that you enter 60000 as the timeout and that caused your problem? I can release the text change if that is the case.
Comment 10 Dani Megert CLA 2005-12-16 02:19:24 EST
OK, I see that ms is not correct, it's used as retries with connections that use 1000ms as timeout. Point taken. Forgot to take a coffee last night ;-)

I can now constantly reproduce and debug the problem when setting connection timeout to 60000:
If the connection timeout is high (like in my case 60000s) a JSchException is thrown even if the correct passphrase is entered. It looks as if JSch has some internal timeout which is not connected to the socket timeout (I tried to set the session's timeout using Session.setTimeout(...) but that did not help). So, JSch throws the exception even it the passphrase has been entered correctly. 

The exception is handled in JSchSession.getSession(...) line 439:
    if (isAuthenticationFailure(e) && wrapperUI.hasPromptExceededTimeout()) {

isAuthenticationFailure(e) is true in our case. Now if wrapperUI.hasPromptExceededTimeout() is true, another attempt is made, assuming the correct information might have been recorded. I think the test should be:
  isAuthenticationFailure(e) && !wrapperUI.hasPromptExceededTimeout()
i.e. if the timeout is not yet reached the information might have been successfully entered but aborted by internal JSch timeout.

In fact using the timeout here is questionable since it's not really relevant whether the connection timed out or not but whether the user has entered the correct credentials. We could even want to remove that test and simply try a second time. The current code then throws the exception should it fails again.

>Are you saying that you enter 60000 as the timeout and that caused your
>problem? I can release the text change if that is the case.
Yes, exactly that I'm saying but I do this *on purpose* because
- we often have a very slow network that often resulted in a timeout, hence I've
  set a very high time out
- due to the lack of information on the preference page I went into the code
  to check whether seconds or milliseconds are used and I explicitly set 60000
==> even though I now know the dimension I think it's worth improving the preference page ;-)
Comment 11 Michael Valenta CLA 2005-12-16 09:53:38 EST
This logic was put in to fix bug 66885. The logic is correct but the problem is that we use the CVS timeout as the test instead of the timeout used by Jsch. The other part of the problem is that Jsch doesn't provide a distinction between a real authentication failure and a timeout during authentication.

We'll need to find a proper solution but for the time being, I've hardcoded the timeout used for the re-prompt case to 60 seconds. Let me know if this helps in your case.
Comment 12 Dani Megert CLA 2005-12-16 10:05:30 EST
Thanks, the workaround works for me.

In bug you wrote:
>I have modified the SSH2 client to retry if a connection failure occurs after 
>a prompt has been open for longer than the CVS timeout (option 2 above)
So, why not simply always try a second time?

>instead of the timeout used by Jsch.
I'm not sure you can access this. There's a getter on Session but it does not seem to be the same timeout that causes this (I tried setting via setter without luck).

Comment 13 Michael Valenta CLA 2005-12-16 10:17:34 EST
In general, reprompting is handled by Jsch (though a callback). We only want to reprompt in the case were there was a timeout while our prompt was up. It would probably be better if this was also handled by Jsch but currently it is not. 

With regard to the timeout used by Jsch, I wasn't implying it would be possible given the current API. We may need to work with the provider of Jsch to resolve the issue properly.
Comment 14 Michael Valenta CLA 2006-04-12 08:45:42 EDT
The proper solution ot this problem would require that Jsch throw an exception with a different message when authentication fails. In general, it wuld be nice if Jsch used exception return codes to indicate the type of failure. We won't have time to address this in 3.2 but perhaps it is something we can look at in 3.3.
Comment 15 Michael Valenta CLA 2007-04-18 21:32:32 EDT
We didn't have time to address this in 3.3.
Comment 16 Atsuhiko Yamanaka CLA 2007-04-18 21:59:39 EDT
I think that the essential problem is that the password is not correctly
cached.  

Even if the reconnections happens, the prompt will not be appeared 
if the correct password is passed from cvs.core.

I have read the similar problem on the other bug entry,
where the keyring will be broken or a given password is not correctly 
saved into the keyring in some timing on Eclipse 3.2.  
Michael, do you remember about that?  That reporter had used cvs plug-in 
and Mylar simultaneously.
Comment 17 Atsuhiko Yamanaka CLA 2007-04-18 22:26:53 EDT
(In reply to comment #16)
> I have read the similar problem on the other bug entry,
> where the keyring will be broken or a given password is not correctly 
> saved into the keyring in some timing on Eclipse 3.2.  
> Michael, do you remember about that?  That reporter had used cvs plug-in 
> and Mylar simultaneously.

I found it.  Please refer to Bug 130582 Comment 27.
It seems that keyring broken problem has been fixed at Bug 170722.
So, Dainiel, may I ask you to try Eclipse SDK 3.3M6?  I hope you will not
encounter such irritate prompts any more.

Comment 18 Dani Megert CLA 2007-04-19 03:09:53 EDT
I cannot verify this because as far as I know the workaround that Michael put in for me (see comment 11) is still in place and hence I no longer run into the problem.
Comment 19 Michael Valenta CLA 2007-04-19 08:17:49 EDT
Yes, the cause of bug 170722 may be the problem here as well. Given that the fix mentioned in comment 11 is also in, I'm closing this.

*** This bug has been marked as a duplicate of bug 170722 ***