|
@@ -6,29 +6,25 @@ using Renci.SshNet.Common;
|
|
|
namespace Renci.SshNet.Tests.Classes
|
|
namespace Renci.SshNet.Tests.Classes
|
|
|
{
|
|
{
|
|
|
/// <summary>
|
|
/// <summary>
|
|
|
- /// ConnectionInfo provides 'keyboard-interactive', 'password', 'publickey' and authentication methods, and partial
|
|
|
|
|
- /// success limit is set to 2.
|
|
|
|
|
- ///
|
|
|
|
|
- /// Authentication proceeds as follows:
|
|
|
|
|
- ///
|
|
|
|
|
- /// 1 x * Client performs 'none' authentication attempt.
|
|
|
|
|
- /// * Server responds with 'failure', and 'password' allowed authentication method.
|
|
|
|
|
- ///
|
|
|
|
|
- /// 1 x * Client performs 'password' authentication attempt.
|
|
|
|
|
- /// * Server responds with 'partial success', and 'password' & 'publickey' allowed authentication methods.
|
|
|
|
|
- ///
|
|
|
|
|
- /// 1 x * Client performs 'publickey' authentication attempt.
|
|
|
|
|
- /// * Server responds with 'failure'.
|
|
|
|
|
- ///
|
|
|
|
|
- /// 1 x * Client performs 'password' authentication attempt.
|
|
|
|
|
- /// * Server responds with 'partial success', and 'keyboard-interactive' allowed authentication methods.
|
|
|
|
|
- ///
|
|
|
|
|
- /// 1 x * Client performs 'keyboard-interactive' authentication attempt.
|
|
|
|
|
- /// * Server responds with 'failure'.
|
|
|
|
|
- ///
|
|
|
|
|
- /// Since the server only ever allowed the 'password' authentication method, there are no
|
|
|
|
|
- /// authentication methods left to try after reaching the partial success limit for 'password'
|
|
|
|
|
- /// and as such authentication fails.
|
|
|
|
|
|
|
+ /// * ConnectionInfo provides the following authentication methods (in order):
|
|
|
|
|
+ /// o keyboard-interactive
|
|
|
|
|
+ /// o password
|
|
|
|
|
+ /// o publickey
|
|
|
|
|
+ /// * Partial success limit is 2
|
|
|
|
|
+ /// * Scenario:
|
|
|
|
|
+ /// none
|
|
|
|
|
+ /// (1=FAIL)
|
|
|
|
|
+ /// |
|
|
|
|
|
+ /// password
|
|
|
|
|
+ /// (2=PARTIAL)
|
|
|
|
|
+ /// |
|
|
|
|
|
+ /// +------------------------------+
|
|
|
|
|
+ /// | |
|
|
|
|
|
+ /// password publickey
|
|
|
|
|
+ /// (4=PARTIAL) (3=FAILURE)
|
|
|
|
|
+ /// |
|
|
|
|
|
+ /// keyboard-interactive
|
|
|
|
|
+ /// (5=FAILURE)
|
|
|
/// </summary>
|
|
/// </summary>
|
|
|
[TestClass]
|
|
[TestClass]
|
|
|
public class ClientAuthenticationTest_Success_MultiList_PartialSuccessLimitReachedFollowedByFailureInSameBranch : ClientAuthenticationTestBase
|
|
public class ClientAuthenticationTest_Success_MultiList_PartialSuccessLimitReachedFollowedByFailureInSameBranch : ClientAuthenticationTestBase
|
|
@@ -53,6 +49,8 @@ namespace Renci.SshNet.Tests.Classes
|
|
|
ConnectionInfoMock.InSequence(seq).Setup(p => p.CreateNoneAuthenticationMethod())
|
|
ConnectionInfoMock.InSequence(seq).Setup(p => p.CreateNoneAuthenticationMethod())
|
|
|
.Returns(NoneAuthenticationMethodMock.Object);
|
|
.Returns(NoneAuthenticationMethodMock.Object);
|
|
|
|
|
|
|
|
|
|
+ /* 1 */
|
|
|
|
|
+
|
|
|
NoneAuthenticationMethodMock.InSequence(seq).Setup(p => p.Authenticate(SessionMock.Object))
|
|
NoneAuthenticationMethodMock.InSequence(seq).Setup(p => p.Authenticate(SessionMock.Object))
|
|
|
.Returns(AuthenticationResult.Failure);
|
|
.Returns(AuthenticationResult.Failure);
|
|
|
ConnectionInfoMock.InSequence(seq)
|
|
ConnectionInfoMock.InSequence(seq)
|
|
@@ -67,9 +65,14 @@ namespace Renci.SshNet.Tests.Classes
|
|
|
.Setup(p => p.AllowedAuthentications)
|
|
.Setup(p => p.AllowedAuthentications)
|
|
|
.Returns(new[] {"password"});
|
|
.Returns(new[] {"password"});
|
|
|
|
|
|
|
|
|
|
+ /* Enumerate supported authentication methods */
|
|
|
|
|
+
|
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("keyboard-interactive");
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("keyboard-interactive");
|
|
|
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
|
|
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
|
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("publickey");
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("publickey");
|
|
|
|
|
+
|
|
|
|
|
+ /* 2 */
|
|
|
|
|
+
|
|
|
PasswordAuthenticationMethodMock.InSequence(seq)
|
|
PasswordAuthenticationMethodMock.InSequence(seq)
|
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
|
.Returns(AuthenticationResult.PartialSuccess);
|
|
.Returns(AuthenticationResult.PartialSuccess);
|
|
@@ -77,9 +80,14 @@ namespace Renci.SshNet.Tests.Classes
|
|
|
.Setup(p => p.AllowedAuthentications)
|
|
.Setup(p => p.AllowedAuthentications)
|
|
|
.Returns(new[] {"password", "publickey"});
|
|
.Returns(new[] {"password", "publickey"});
|
|
|
|
|
|
|
|
|
|
+ /* Enumerate supported authentication methods */
|
|
|
|
|
+
|
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("keyboard-interactive");
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("keyboard-interactive");
|
|
|
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
|
|
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
|
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("publickey");
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("publickey");
|
|
|
|
|
+
|
|
|
|
|
+ /* 3 */
|
|
|
|
|
+
|
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq)
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq)
|
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
|
.Returns(AuthenticationResult.Failure);
|
|
.Returns(AuthenticationResult.Failure);
|
|
@@ -87,6 +95,8 @@ namespace Renci.SshNet.Tests.Classes
|
|
|
.Setup(p => p.Name)
|
|
.Setup(p => p.Name)
|
|
|
.Returns("publickey-failure");
|
|
.Returns("publickey-failure");
|
|
|
|
|
|
|
|
|
|
+ /* 4 */
|
|
|
|
|
+
|
|
|
PasswordAuthenticationMethodMock.InSequence(seq)
|
|
PasswordAuthenticationMethodMock.InSequence(seq)
|
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
|
.Returns(AuthenticationResult.PartialSuccess);
|
|
.Returns(AuthenticationResult.PartialSuccess);
|
|
@@ -94,9 +104,14 @@ namespace Renci.SshNet.Tests.Classes
|
|
|
.Setup(p => p.AllowedAuthentications)
|
|
.Setup(p => p.AllowedAuthentications)
|
|
|
.Returns(new[] {"keyboard-interactive"});
|
|
.Returns(new[] {"keyboard-interactive"});
|
|
|
|
|
|
|
|
|
|
+ /* Enumerate supported authentication methods */
|
|
|
|
|
+
|
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("keyboard-interactive");
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("keyboard-interactive");
|
|
|
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
|
|
PasswordAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("password");
|
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("publickey");
|
|
PublicKeyAuthenticationMethodMock.InSequence(seq).Setup(p => p.Name).Returns("publickey");
|
|
|
|
|
+
|
|
|
|
|
+ /* 5 */
|
|
|
|
|
+
|
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq)
|
|
KeyboardInteractiveAuthenticationMethodMock.InSequence(seq)
|
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
.Setup(p => p.Authenticate(SessionMock.Object))
|
|
|
.Returns(AuthenticationResult.Failure);
|
|
.Returns(AuthenticationResult.Failure);
|