TryAuthenticate calls itself to pass the next authentication method to the server, but the list of authentication methods it passes in doesn't exclude the authentication methods already completed. As such, the same authentication method is tried over and over again without ever moving to the next authentication method.
Taking a specific example, suppose that password and privateKey methods are used. Password passes the initial Authenticate call and the result is PartialSuccess. TryAuthenticate is called, and the new list of authenticated methods is still { password, privateKey }. Password is verified again with a result of PartialSuccess. This continues until stack overflow.
Duped with ServU SFTP Server and SSH.NET Changeset 35920
__Recommended solution__: Filter the passed authentication methods down exclude those which have already passed. This needs to be done by authentication method type to ensure that, for example, for a given password authentication returning partial success that we do not attempt any other password authentications but we do attempt all non-failed private keys.
If we want to be able to try different username/auth method combinations then we'd also have to track the difference between failedAuthenticationMethods at the top level and failedAuthenticationMethods found during a PartialSuccess state since I believe it may be possible to fail authentication during PartialSuccess state but succeed from the root level. Not sure how SFTP or SSH.NET responds to switching user names after a PartialSuccess though. Maybe multiple usernames with a single ConnectionInfo is just a weird case that we don't need/want to support.
I've attached a suggested change for the basic fix based on ConnectionInfo.cs Changeset 35920
Comments: ** Comment from web user: drieseng **
I was able to reproduce the issue, but still need to look into a solution.[0A]The fix you proposed will introduce a regression as we'll no longer be able to use the same authentication method twice.[0A][0A]For example:[0A]You'd no longer be able to authenticate against a server that wants the password to be entered twice.[0A][0A]Note that I don't think it's as easy as checking whether the allowed authentication methods remain the same upon a partial success to determine if we want move on to the next configured authentication method.[0A][0A]Suppose a OpenSSH which supports two authentication lists:[0A]"publickey,password password,password"[0A][0A]This would offer the following allowed authentications on the first attempt:[0A]publickey,password[0A][0A]where "publickey" is the first authentication method of the first list, and "password" is the first authentication method of the second list.[0A][0A]Upon the first partial success using "password" authentication, it would still provide the same allowed authentications. In which case "publickey" is still the first authentication method of the first list, but "password" would be the second authentication method of the second list.[0A]