Repository: mina-sshd
Updated Branches:
  refs/heads/master c351ff6be -> 994ad4763


[SSHD=695] Client - support receiving of banner prior to auth()


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/994ad476
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/994ad476
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/994ad476

Branch: refs/heads/master
Commit: 994ad47631e70c4d3269610320aa92cb0efba760
Parents: c351ff6
Author: Matthew Pitts <[email protected]>
Authored: Tue Aug 30 21:09:02 2016 +0300
Committer: Lyor Goldstein <[email protected]>
Committed: Tue Aug 30 21:09:02 2016 +0300

----------------------------------------------------------------------
 .../client/session/ClientUserAuthService.java   |  10 +-
 .../sshd/server/auth/WelcomeBannerTest.java     | 121 +++++++++++++------
 2 files changed, 88 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/994ad476/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
 
b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
index 7d98a61..e0e52d2 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
@@ -164,15 +164,17 @@ public class ClientUserAuthService
     @Override
     public void process(int cmd, Buffer buffer) throws Exception {
         ClientSession session = getClientSession();
-        AuthFuture authFuture = 
ValidateUtils.checkNotNull(authFutureHolder.get(), "No current future");
-        if (authFuture.isSuccess()) {
+        AuthFuture authFuture = authFutureHolder.get();
+        if ((authFuture != null) && authFuture.isSuccess()) {
+            log.error("process({}) unexpected authenticated client command: 
{}",
+                      session, SshConstants.getCommandMessageName(cmd));
             throw new IllegalStateException("UserAuth message delivered to 
authenticated client");
-        } else if (authFuture.isDone()) {
+        } else if ((authFuture != null) && authFuture.isDone()) {
+            // ignore for now; TODO: random packets
             if (log.isDebugEnabled()) {
                 log.debug("process({}) Ignoring random message - cmd={}",
                           session, SshConstants.getCommandMessageName(cmd));
             }
-            // ignore for now; TODO: random packets
         } else if (cmd == SshConstants.SSH_MSG_USERAUTH_BANNER) {
             String welcome = buffer.getString();
             String lang = buffer.getString();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/994ad476/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java 
b/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java
index 2f16af7..7676d7d 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java
@@ -23,6 +23,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.Semaphore;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Function;
@@ -141,6 +142,44 @@ public class WelcomeBannerTest extends BaseTestSupport {
         testBanner(null);
     }
 
+    @Test   // see SSHD-695
+    public void testWelcomeBannerBeforeAuthBegins() throws Exception {
+        UserInteraction ui = client.getUserInteraction();
+        try {
+            Semaphore sigSem = new Semaphore(0);
+            client.setUserInteraction(new UserInteraction() {
+                @Override
+                public void welcome(ClientSession session, String banner, 
String lang) {
+                    sigSem.release();
+                }
+
+                @Override
+                public boolean isInteractionAllowed(ClientSession session) {
+                    return true;
+                }
+
+                @Override
+                public String[] interactive(ClientSession session, String 
name, String instruction, String lang, String[] prompt, boolean[] echo) {
+                    throw new UnsupportedOperationException("Unexpected 
interactive call");
+                }
+
+                @Override
+                public String getUpdatedPassword(ClientSession session, String 
prompt, String lang) {
+                    throw new UnsupportedOperationException("Unexpected 
password update call");
+                }
+            });
+            PropertyResolverUtils.updateProperty(sshd, 
ServerAuthenticationManager.WELCOME_BANNER, getCurrentTestName());
+            try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+                assertTrue("Welcome not signalled on time", 
sigSem.tryAcquire(11L, TimeUnit.SECONDS));
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+            }
+
+        } finally {
+            client.setUserInteraction(ui);
+        }
+    }
+
     private void testFileContentBanner(Function<? super Path, ?> 
configValueExtractor) throws Exception {
         Path dir = getTempTargetRelativeFile(getClass().getSimpleName());
         Path file = 
assertHierarchyTargetFolderExists(dir).resolve(getCurrentTestName() + ".txt");
@@ -153,54 +192,58 @@ public class WelcomeBannerTest extends BaseTestSupport {
     }
 
     private void testBanner(String expectedWelcome) throws Exception {
+        UserInteraction ui = client.getUserInteraction();
         AtomicReference<String> welcomeHolder = new AtomicReference<>(null);
-        AtomicReference<ClientSession> sessionHolder = new 
AtomicReference<>(null);
-        client.setUserInteraction(new UserInteraction() {
-            @Override
-            public boolean isInteractionAllowed(ClientSession session) {
-                return true;
-            }
+        try {
+            AtomicReference<ClientSession> sessionHolder = new 
AtomicReference<>(null);
+            client.setUserInteraction(new UserInteraction() {
+                @Override
+                public boolean isInteractionAllowed(ClientSession session) {
+                    return true;
+                }
 
-            @Override
-            public void serverVersionInfo(ClientSession session, List<String> 
lines) {
-                validateSession("serverVersionInfo", session);
-            }
+                @Override
+                public void serverVersionInfo(ClientSession session, 
List<String> lines) {
+                    validateSession("serverVersionInfo", session);
+                }
 
-            @Override
-            public void welcome(ClientSession session, String banner, String 
lang) {
-                validateSession("welcome", session);
-                assertNull("Multiple banner invocations", 
welcomeHolder.getAndSet(banner));
-            }
+                @Override
+                public void welcome(ClientSession session, String banner, 
String lang) {
+                    validateSession("welcome", session);
+                    assertNull("Multiple banner invocations", 
welcomeHolder.getAndSet(banner));
+                }
 
-            @Override
-            public String[] interactive(ClientSession session, String name, 
String instruction, String lang, String[] prompt, boolean[] echo) {
-                validateSession("interactive", session);
-                return null;
-            }
+                @Override
+                public String[] interactive(ClientSession session, String 
name, String instruction, String lang, String[] prompt, boolean[] echo) {
+                    validateSession("interactive", session);
+                    return null;
+                }
 
-            @Override
-            public String getUpdatedPassword(ClientSession clientSession, 
String prompt, String lang) {
-                throw new UnsupportedOperationException("Unexpected call");
-            }
+                @Override
+                public String getUpdatedPassword(ClientSession clientSession, 
String prompt, String lang) {
+                    throw new UnsupportedOperationException("Unexpected call");
+                }
 
-            private void validateSession(String phase, ClientSession session) {
-                ClientSession prev = sessionHolder.getAndSet(session);
-                if (prev != null) {
-                    assertSame("Mismatched " + phase + " client session", 
prev, session);
+                private void validateSession(String phase, ClientSession 
session) {
+                    ClientSession prev = sessionHolder.getAndSet(session);
+                    if (prev != null) {
+                        assertSame("Mismatched " + phase + " client session", 
prev, session);
+                    }
+                }
+            });
+
+            try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+                if (expectedWelcome != null) {
+                    assertSame("Mismatched sessions", session, 
sessionHolder.get());
+                } else {
+                    assertNull("Unexpected session", sessionHolder.get());
                 }
             }
-        });
-
-        try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
-            session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
-            if (expectedWelcome != null) {
-                assertSame("Mismatched sessions", session, 
sessionHolder.get());
-            } else {
-                assertNull("Unexpected session", sessionHolder.get());
-            }
+        } finally {
+            client.setUserInteraction(ui);
         }
-
         assertEquals("Mismatched banner", expectedWelcome, 
welcomeHolder.get());
     }
 }

Reply via email to