/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.sshd.client.simple; import java.io.IOException; import java.security.KeyPair; import java.util.Objects; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.sshd.client.session.ClientSession; import org.apache.sshd.common.config.keys.KeyUtils; import org.apache.sshd.common.session.Session; import org.apache.sshd.common.session.SessionListener; import org.apache.sshd.server.auth.password.PasswordAuthenticator; import org.apache.sshd.server.auth.password.RejectAllPasswordAuthenticator; import org.apache.sshd.server.auth.pubkey.RejectAllPublickeyAuthenticator; import org.apache.sshd.util.test.Utils; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; /** * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a> */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class SimpleSessionClientTest extends BaseSimpleClientTestSupport { public SimpleSessionClientTest() { super(); } @Test public void testLoginSessionWithPassword() throws Exception { // make sure authentication occurs only for passwords sshd.setPublickeyAuthenticator(RejectAllPublickeyAuthenticator.INSTANCE); client.start(); try (ClientSession session = simple.sessionLogin(TEST_LOCALHOST, port, getCurrentTestName(), getCurrentTestName())) { assertEquals("Mismatched session username", getCurrentTestName(), session.getUsername()); } } @Test public void testLoginSessionWithIdentity() throws Exception { final KeyPair identity = Utils.getFirstKeyPair(createTestHostKeyProvider()); final AtomicBoolean identityQueried = new AtomicBoolean(false); sshd.setPublickeyAuthenticator((username, key, session) -> { if (username.equals(getCurrentTestName())) { identityQueried.set(true); return KeyUtils.compareKeys(identity.getPublic(), key); } return false; }); // make sure authentication occurs only with public keys sshd.setPasswordAuthenticator(RejectAllPasswordAuthenticator.INSTANCE); client.start(); try (ClientSession session = simple.sessionLogin(TEST_LOCALHOST, port, getCurrentTestName(), identity)) { assertEquals("Mismatched session username", getCurrentTestName(), session.getUsername()); assertTrue("User identity not queried", identityQueried.get()); } } @Test public void testConnectionTimeout() throws Exception { client.addSessionListener(new SessionListener() { @Override public void sessionCreated(Session session) { try { Thread.sleep(CONNECT_TIMEOUT + 150L); } catch (InterruptedException e) { // ignored } } }); client.start(); long nanoStart = System.nanoTime(); try (ClientSession session = simple.sessionLogin(TEST_LOCALHOST, port, getCurrentTestName(), getCurrentTestName())) { fail("Unexpected connection success"); } catch (IOException e) { long nanoEnd = System.nanoTime(); long nanoDuration = nanoEnd - nanoStart; long nanoTimeout = TimeUnit.MILLISECONDS.toNanos(CONNECT_TIMEOUT); // we allow the timeout to be shorter than the connect timeout, but no more than 3 times its value assertTrue("Expired time (" + nanoDuration + ") too long", nanoDuration < (nanoTimeout * 3L)); } } @Test public void testAuthenticationTimeout() throws Exception { // make sure authentication occurs only for passwords sshd.setPublickeyAuthenticator(RejectAllPublickeyAuthenticator.INSTANCE); PasswordAuthenticator delegate = Objects.requireNonNull(sshd.getPasswordAuthenticator(), "No password authenticator"); sshd.setPasswordAuthenticator((username, password, session) -> { try { Thread.sleep(AUTH_TIMEOUT + 150L); } catch (InterruptedException e) { // ignored } return delegate.authenticate(username, password, session); }); client.start(); long nanoStart = System.nanoTime(); try (ClientSession session = simple.sessionLogin(TEST_LOCALHOST, port, getCurrentTestName(), getCurrentTestName())) { fail("Unexpected connection success"); } catch (IOException e) { long nanoEnd = System.nanoTime(); long nanoDuration = nanoEnd - nanoStart; long nanoTimeout = TimeUnit.MILLISECONDS.toNanos(AUTH_TIMEOUT); // we allow the timeout to be shorter than the connect timeout, but no more than 3 times its value assertTrue("Expired time (" + nanoDuration + ") too long", nanoDuration < (nanoTimeout * 3L)); } } }