You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2020/08/07 14:52:42 UTC
[mina-sshd] 04/04: [SSHD-1050] Make first error before first auth
attempt sticky
This is an automated email from the ASF dual-hosted git repository.
lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git
commit a966070d8b793a00f0e479d984f2e431fcee229c
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Thu Aug 6 18:33:54 2020 +0300
[SSHD-1050] Make first error before first auth attempt sticky
---
.../sshd/client/session/ClientSessionImpl.java | 13 ++++++++-
.../sshd/client/session/ClientSessionTest.java | 32 ++++++++++++++++------
2 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
index a7c07c9..72c41ae 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
@@ -59,6 +59,7 @@ public class ClientSessionImpl extends AbstractClientSession {
*/
private volatile AuthFuture authFuture;
+ private final AtomicReference<Throwable> beforeAuthErrorHolder = new AtomicReference<>();
/** Also guards setting an earlyError and the authFuture together. */
private final AtomicReference<Throwable> authErrorHolder = new AtomicReference<>();
@@ -136,7 +137,13 @@ public class ClientSessionImpl extends AbstractClientSession {
synchronized (authErrorHolder) {
future = ValidateUtils.checkNotNull(
authService.auth(serviceName), "No auth future generated by service=%s", serviceName);
- earlyError = authErrorHolder.getAndSet(null);
+ // If have an error before the 1st auth then make it "sticky"
+ Throwable beforeAuthError = beforeAuthErrorHolder.get();
+ if (authFuture != null) {
+ earlyError = authErrorHolder.getAndSet(beforeAuthError);
+ } else {
+ earlyError = beforeAuthError;
+ }
authFuture = future;
}
@@ -180,6 +187,10 @@ public class ClientSessionImpl extends AbstractClientSession {
// save only the 1st newly signaled exception
firstError = authErrorHolder.compareAndSet(null, t);
future = authFuture;
+ // save in special location errors before the 1st auth attempt
+ if (future == null) {
+ beforeAuthErrorHolder.compareAndSet(null, t);
+ }
}
}
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
index d9e022f..d6c4cf2 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionTest.java
@@ -252,7 +252,16 @@ public class ClientSessionTest extends BaseTestSupport {
}
@Test // SSHD-1050
- public void testAuthGetsNotifiedOnLongPreamble() throws Exception {
+ public void testAuthGetsNotifiedIfErrorBeforeFirstAuth() throws Exception {
+ testEarlyErrorAuthAttempts(1);
+ }
+
+ @Test // SSHD-1050
+ public void testSecondAuthNotifiedAfterEarlyError() throws Exception {
+ testEarlyErrorAuthAttempts(3);
+ }
+
+ private void testEarlyErrorAuthAttempts(int maxAttempts) throws Exception {
int limit = CoreModuleProperties.MAX_IDENTIFICATION_SIZE.getRequired(sshd);
String line = getClass().getCanonicalName() + "#" + getCurrentTestName();
StringBuilder sb = new StringBuilder(limit + line.length());
@@ -271,15 +280,20 @@ public class ClientSessionTest extends BaseTestSupport {
// Give time to the client to signal the overflow in server identification
Thread.sleep(AUTH_TIMEOUT.toMillis() / 2L);
- AuthFuture future = session.auth();
- assertTrue("Auth not completed on time", future.await(AUTH_TIMEOUT));
- assertTrue("No auth result", future.isDone());
- assertFalse("Unexpected auth success", future.isSuccess());
- assertTrue("Auth not marked as failed", future.isFailure());
+ for (int index = 1; index <= maxAttempts; index++) {
+ String authId = "Auth " + index + "/" + maxAttempts;
+ outputDebugMessage("%s(%s)", getCurrentTestName(), authId);
+
+ AuthFuture future = session.auth();
+ assertTrue(authId + " not completed on time", future.await(AUTH_TIMEOUT));
+ assertTrue(authId + " has no result", future.isDone());
+ assertFalse(authId + " unexpected success", future.isSuccess());
+ assertTrue(authId + " not marked as failed", future.isFailure());
- Throwable exception = future.getException();
- String message = exception.getLocalizedMessage();
- assertTrue("Invalid exception message: " + message, message.contains("too many header lines"));
+ Throwable exception = future.getException();
+ String message = exception.getMessage();
+ assertTrue(authId + " invalid exception message: " + message, message.contains("too many header lines"));
+ }
} finally {
CoreModuleProperties.SERVER_EXTRA_IDENTIFICATION_LINES.set(sshd, null);
}