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 2015/12/16 11:17:11 UTC

[1/5] mina-sshd git commit: [SSHD-479] Upgrade used Maven artifacts versions to more recent versions

Repository: mina-sshd
Updated Branches:
  refs/heads/master e329167e3 -> 68844229a


[SSHD-479] Upgrade used Maven artifacts versions to more recent versions

* Upgraded Maven assembly plugin


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

Branch: refs/heads/master
Commit: 1b6d41b57a0d923f5b95e918452f004b0424cb38
Parents: e329167
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Wed Dec 16 12:12:03 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Wed Dec 16 12:12:03 2015 +0200

----------------------------------------------------------------------
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1b6d41b5/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index d1fe10e..c1ce612 100644
--- a/pom.xml
+++ b/pom.xml
@@ -847,7 +847,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-assembly-plugin</artifactId>
-                <version>2.5.4</version>
+                <version>2.6</version>
                 <executions>
                     <execution>
                         <id>source-release-assembly</id>


[3/5] mina-sshd git commit: Define SessionHolder + update the various Client/Session

Posted by lg...@apache.org.
Define SessionHolder + update the various Client/Session


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

Branch: refs/heads/master
Commit: fa0af69af1ce04d13c7872c8435ff41948d901dc
Parents: 4c106fe
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Wed Dec 16 12:13:05 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Wed Dec 16 12:13:05 2015 +0200

----------------------------------------------------------------------
 .../auth/pubkey/AbstractKeyPairIterator.java    | 61 ++++++++++++++++++++
 .../auth/pubkey/SessionKeyPairIterator.java     | 26 +++------
 .../auth/pubkey/SshAgentPublicKeyIterator.java  | 22 +------
 .../auth/pubkey/UserAuthPublicKeyIterator.java  | 21 +------
 .../client/kex/AbstractDHClientKeyExchange.java | 12 +++-
 .../org/apache/sshd/client/kex/DHGClient.java   |  3 +-
 .../org/apache/sshd/client/kex/DHGEXClient.java |  3 +-
 .../client/session/ClientConnectionService.java | 16 +++--
 .../session/ClientConnectionServiceFactory.java |  4 +-
 .../sshd/client/session/ClientSessionImpl.java  | 15 ++---
 .../client/session/ClientUserAuthService.java   |  5 +-
 .../subsystem/AbstractSubsystemClient.java      | 37 ++++++++++++
 .../sshd/client/subsystem/SubsystemClient.java  |  4 +-
 .../subsystem/sftp/AbstractSftpClient.java      |  4 +-
 .../java/org/apache/sshd/common/Service.java    |  1 -
 .../org/apache/sshd/common/channel/Channel.java |  4 --
 .../org/apache/sshd/common/kex/KeyExchange.java |  4 +-
 .../common/kex/dh/AbstractDHKeyExchange.java    | 10 +++-
 .../session/AbstractConnectionService.java      | 12 ++--
 .../sshd/common/session/AbstractSession.java    |  8 ++-
 .../org/apache/sshd/common/session/Session.java |  2 +-
 .../sshd/common/session/SessionHolder.java      | 28 +++++++++
 .../server/kex/AbstractDHServerKeyExchange.java |  8 +--
 .../org/apache/sshd/server/kex/DHGEXServer.java |  4 +-
 .../org/apache/sshd/server/kex/DHGServer.java   |  4 +-
 .../org/apache/sshd/server/scp/ScpCommand.java  | 21 ++++++-
 .../server/session/ServerConnectionService.java | 16 ++---
 .../session/ServerConnectionServiceFactory.java |  4 +-
 .../server/session/ServerSessionHolder.java     |  3 +
 .../sshd/deprecated/AbstractUserAuth.java       | 10 +++-
 .../java/org/apache/sshd/server/ServerTest.java | 41 +++++++------
 .../server/command/ScpCommandFactoryTest.java   |  4 +-
 32 files changed, 274 insertions(+), 143 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/AbstractKeyPairIterator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/AbstractKeyPairIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/AbstractKeyPairIterator.java
new file mode 100644
index 0000000..cb33de9
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/AbstractKeyPairIterator.java
@@ -0,0 +1,61 @@
+/*
+ * 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.auth.pubkey;
+
+import java.util.Iterator;
+
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.client.session.ClientSessionHolder;
+import org.apache.sshd.common.session.SessionHolder;
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * @param <I> Type of {@link PublicKeyIdentity} being iterated
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractKeyPairIterator<I extends PublicKeyIdentity>
+        implements Iterator<I>, SessionHolder<ClientSession>, ClientSessionHolder {
+
+    private final ClientSession session;
+
+    protected AbstractKeyPairIterator(ClientSession session) {
+        this.session = ValidateUtils.checkNotNull(session, "No session");
+    }
+
+    @Override
+    public final ClientSession getClientSession() {
+        return session;
+    }
+
+    @Override
+    public final ClientSession getSession() {
+        return getClientSession();
+    }
+
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException("No removal allowed");
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + getClientSession() + "]";
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SessionKeyPairIterator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SessionKeyPairIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SessionKeyPairIterator.java
index 5ff50b4..09ad1e7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SessionKeyPairIterator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SessionKeyPairIterator.java
@@ -22,22 +22,24 @@ package org.apache.sshd.client.auth.pubkey;
 import java.security.KeyPair;
 import java.util.Iterator;
 
+import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.kex.KexFactoryManager;
-import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class SessionKeyPairIterator implements Iterator<KeyPairIdentity> {
-
-    private final KexFactoryManager manager;
+public class SessionKeyPairIterator extends AbstractKeyPairIterator<KeyPairIdentity> {
     private final Iterator<KeyPair> keys;
 
-    public SessionKeyPairIterator(KexFactoryManager manager, Iterator<KeyPair> keys) {
-        this.manager = ValidateUtils.checkNotNull(manager, "No KEX factory manager");
+    public SessionKeyPairIterator(ClientSession session, Iterator<KeyPair> keys) {
+        super(session);
         this.keys = keys;   // OK if null
     }
 
+    public KexFactoryManager getKexFactoryManager() {
+        return getClientSession();
+    }
+
     @Override
     public boolean hasNext() {
         return (keys != null) && keys.hasNext();
@@ -45,16 +47,6 @@ public class SessionKeyPairIterator implements Iterator<KeyPairIdentity> {
 
     @Override
     public KeyPairIdentity next() {
-        return new KeyPairIdentity(manager, keys.next());
-    }
-
-    @Override
-    public void remove() {
-        throw new UnsupportedOperationException("No removal allowed");
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[" + manager + "]";
+        return new KeyPairIdentity(getKexFactoryManager(), keys.next());
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SshAgentPublicKeyIterator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SshAgentPublicKeyIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SshAgentPublicKeyIterator.java
index 8becc4b..8bb18c9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SshAgentPublicKeyIterator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/SshAgentPublicKeyIterator.java
@@ -25,7 +25,6 @@ import java.util.Iterator;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.client.session.ClientSessionHolder;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.Pair;
 import org.apache.sshd.common.util.ValidateUtils;
@@ -33,23 +32,17 @@ import org.apache.sshd.common.util.ValidateUtils;
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class SshAgentPublicKeyIterator implements Iterator<KeyAgentIdentity>, ClientSessionHolder {
-    private final ClientSession clientSession;
+public class SshAgentPublicKeyIterator extends AbstractKeyPairIterator<KeyAgentIdentity> {
     private final SshAgent agent;
     private final Iterator<Pair<PublicKey, String>> keys;
 
     public SshAgentPublicKeyIterator(ClientSession session, SshAgent agent) throws IOException {
-        this.clientSession = ValidateUtils.checkNotNull(session, "No session");
+        super(session);
         this.agent = ValidateUtils.checkNotNull(agent, "No agent");
         keys = GenericUtils.iteratorOf(agent.getIdentities());
     }
 
     @Override
-    public ClientSession getClientSession() {
-        return clientSession;
-    }
-
-    @Override
     public boolean hasNext() {
         return (keys != null) && keys.hasNext();
     }
@@ -59,15 +52,4 @@ public class SshAgentPublicKeyIterator implements Iterator<KeyAgentIdentity>, Cl
         Pair<PublicKey, String> kp = keys.next();
         return new KeyAgentIdentity(agent, kp.getFirst(), kp.getSecond());
     }
-
-    @Override
-    public void remove() {
-        throw new UnsupportedOperationException("No removal allowed");
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[" + getClientSession() + "]";
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
index 83ed94c..e1e9b3e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/UserAuthPublicKeyIterator.java
@@ -30,7 +30,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
 import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.client.session.ClientSessionHolder;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.keyprovider.KeyIdentityProvider;
 import org.apache.sshd.common.util.GenericUtils;
@@ -39,16 +38,15 @@ import org.apache.sshd.common.util.ValidateUtils;
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class UserAuthPublicKeyIterator implements Iterator<PublicKeyIdentity>, ClientSessionHolder, Channel {
+public class UserAuthPublicKeyIterator extends AbstractKeyPairIterator<PublicKeyIdentity> implements Channel {
 
     private final AtomicBoolean open = new AtomicBoolean(true);
-    private final ClientSession clientSession;
     private final Iterator<Iterator<? extends PublicKeyIdentity>> iterators;
     private Iterator<? extends PublicKeyIdentity> current;
     private SshAgent agent;
 
     public UserAuthPublicKeyIterator(ClientSession session) throws Exception {
-        clientSession = ValidateUtils.checkNotNull(session, "No session");
+        super(session);
 
         Collection<Iterator<? extends PublicKeyIdentity>> identities = new LinkedList<>();
         identities.add(new SessionKeyPairIterator(session, KeyIdentityProvider.Utils.iteratorOf(session)));
@@ -75,11 +73,6 @@ public class UserAuthPublicKeyIterator implements Iterator<PublicKeyIdentity>, C
     }
 
     @Override
-    public ClientSession getClientSession() {
-        return clientSession;
-    }
-
-    @Override
     public boolean hasNext() {
         if (!isOpen()) {
             return false;
@@ -102,11 +95,6 @@ public class UserAuthPublicKeyIterator implements Iterator<PublicKeyIdentity>, C
     }
 
     @Override
-    public void remove() {
-        throw new UnsupportedOperationException("No removal allowed");
-    }
-
-    @Override
     public boolean isOpen() {
         return open.get();
     }
@@ -139,9 +127,4 @@ public class UserAuthPublicKeyIterator implements Iterator<PublicKeyIdentity>, C
 
         return null;
     }
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() + "[" + getClientSession() + "]";
-    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/kex/AbstractDHClientKeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/AbstractDHClientKeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/AbstractDHClientKeyExchange.java
index 9eacdfd..eef04e0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/AbstractDHClientKeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/AbstractDHClientKeyExchange.java
@@ -22,14 +22,15 @@ package org.apache.sshd.client.kex;
 import java.security.PublicKey;
 
 import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.client.session.ClientSessionHolder;
 import org.apache.sshd.common.kex.dh.AbstractDHKeyExchange;
-import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public abstract class AbstractDHClientKeyExchange extends AbstractDHKeyExchange {
+public abstract class AbstractDHClientKeyExchange extends AbstractDHKeyExchange implements ClientSessionHolder {
     protected PublicKey serverKey;
 
     protected AbstractDHClientKeyExchange() {
@@ -37,7 +38,12 @@ public abstract class AbstractDHClientKeyExchange extends AbstractDHKeyExchange
     }
 
     @Override
-    public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
+    public final ClientSession getClientSession() {
+        return (ClientSession) getSession();
+    }
+
+    @Override
+    public void init(Session s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
         super.init(s, v_s, v_c, i_s, i_c);
         ValidateUtils.checkTrue(s instanceof ClientSession, "Using a client side KeyExchange on a server");
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
index 1d16973..dc736f9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
@@ -26,7 +26,6 @@ import org.apache.sshd.common.kex.AbstractDH;
 import org.apache.sshd.common.kex.DHFactory;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.kex.KeyExchangeFactory;
-import org.apache.sshd.common.session.AbstractSession;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.signature.Signature;
 import org.apache.sshd.common.util.GenericUtils;
@@ -77,7 +76,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
     }
 
     @Override
-    public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
+    public void init(Session s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
         super.init(s, v_s, v_c, i_s, i_c);
         dh = getDH();
         hash = dh.getHash();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
index 36feac4..4f7748d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
@@ -29,7 +29,6 @@ import org.apache.sshd.common.kex.AbstractDH;
 import org.apache.sshd.common.kex.DHFactory;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.kex.KeyExchangeFactory;
-import org.apache.sshd.common.session.AbstractSession;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.signature.Signature;
 import org.apache.sshd.common.util.GenericUtils;
@@ -87,7 +86,7 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
     }
 
     @Override
-    public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
+    public void init(Session s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
         super.init(s, v_s, v_c, i_s, i_c);
         if (log.isDebugEnabled()) {
             log.debug("init({}) Send SSH_MSG_KEX_DH_GEX_REQUEST", s);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
index 356efbf..85ddb97 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
@@ -28,8 +28,6 @@ import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.session.AbstractConnectionService;
-import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
@@ -37,22 +35,27 @@ import org.apache.sshd.common.util.buffer.Buffer;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class ClientConnectionService extends AbstractConnectionService {
-    public ClientConnectionService(Session s) throws SshException {
+public class ClientConnectionService extends AbstractConnectionService<AbstractClientSession> implements ClientSessionHolder {
+    public ClientConnectionService(AbstractClientSession s) throws SshException {
         super(s);
+    }
 
-        ValidateUtils.checkTrue(s instanceof ClientSession, "Client side service used on server side");
+    @Override
+    public final ClientSession getClientSession() {
+        return getSession();
     }
 
     @Override
     public void start() {
-        if (!((ClientSession) session).isAuthenticated()) {
+        ClientSession session = getClientSession();
+        if (!session.isAuthenticated()) {
             throw new IllegalStateException("Session is not authenticated");
         }
         startHeartBeat();
     }
 
     protected void startHeartBeat() {
+        ClientSession session = getClientSession();
         long interval = PropertyResolverUtils.getLongProperty(session, ClientFactoryManager.HEARTBEAT_INTERVAL, ClientFactoryManager.DEFAULT_HEARTBEAT_INTERVAL);
         if (interval > 0L) {
             FactoryManager manager = session.getFactoryManager();
@@ -70,6 +73,7 @@ public class ClientConnectionService extends AbstractConnectionService {
     }
 
     protected void sendHeartBeat() {
+        ClientSession session = getClientSession();
         String request = PropertyResolverUtils.getStringProperty(session, ClientFactoryManager.HEARTBEAT_REQUEST, ClientFactoryManager.DEFAULT_KEEP_ALIVE_HEARTBEAT_STRING);
         try {
             Buffer buf = session.createBuffer(SshConstants.SSH_MSG_GLOBAL_REQUEST, request.length() + Byte.SIZE);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionServiceFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionServiceFactory.java
index ba331e1..2efe7b7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionServiceFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionServiceFactory.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import org.apache.sshd.common.Service;
 import org.apache.sshd.common.ServiceFactory;
 import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -41,6 +42,7 @@ public class ClientConnectionServiceFactory implements ServiceFactory {
 
     @Override
     public Service create(Session session) throws IOException {
-        return new ClientConnectionService(session);
+        ValidateUtils.checkTrue(session instanceof AbstractClientSession, "Not a client sesssion: %s", session);
+        return new ClientConnectionService((AbstractClientSession) session);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
----------------------------------------------------------------------
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 8166f2b..44c6e9c 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
@@ -20,6 +20,7 @@ package org.apache.sshd.client.session;
 
 import java.io.IOException;
 import java.net.SocketAddress;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumMap;
@@ -106,16 +107,12 @@ public class ClientSessionImpl extends AbstractClientSession {
     }
 
     @Override
-    protected Service[] getServices() {
-        Service[] services;
+    protected List<Service> getServices() {
         if (nextService != null) {
-            services = new Service[]{currentService, nextService};
-        } else if (currentService != null) {
-            services = new Service[]{currentService};
+            return Arrays.asList(currentService, nextService);
         } else {
-            services = new Service[0];
+            return super.getServices();
         }
-        return services;
     }
 
     @Override
@@ -175,8 +172,8 @@ public class ClientSessionImpl extends AbstractClientSession {
 
     @Override
     public KeyExchangeFuture switchToNoneCipher() throws IOException {
-        if (!(currentService instanceof AbstractConnectionService)
-                || !((AbstractConnectionService) currentService).getChannels().isEmpty()) {
+        if (!(currentService instanceof AbstractConnectionService<?>)
+                || !GenericUtils.isEmpty(((AbstractConnectionService<?>) currentService).getChannels())) {
             throw new IllegalStateException("The switch to the none cipher must be done immediately after authentication");
         }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/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 23c1b4b..521da96 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
@@ -37,6 +37,7 @@ import org.apache.sshd.common.Service;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionHolder;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -47,7 +48,9 @@ import org.apache.sshd.common.util.closeable.AbstractCloseable;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class ClientUserAuthService extends AbstractCloseable implements Service, ClientSessionHolder {
+public class ClientUserAuthService
+        extends AbstractCloseable
+        implements Service, SessionHolder<ClientSession>, ClientSessionHolder {
 
     /**
      * The AuthFuture that is being used by the current auth request.  This encodes the state.

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/AbstractSubsystemClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/AbstractSubsystemClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/AbstractSubsystemClient.java
new file mode 100644
index 0000000..6bd32c1
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/AbstractSubsystemClient.java
@@ -0,0 +1,37 @@
+/*
+ * 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.subsystem;
+
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractSubsystemClient extends AbstractLoggingBean implements SubsystemClient {
+    protected AbstractSubsystemClient() {
+        super();
+    }
+
+    @Override
+    public final ClientSession getSession() {
+        return getClientSession();
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/SubsystemClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/SubsystemClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/SubsystemClient.java
index 5f2a7fd..dca1b38 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/SubsystemClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/SubsystemClient.java
@@ -22,13 +22,15 @@ package org.apache.sshd.client.subsystem;
 import java.nio.channels.Channel;
 
 import org.apache.sshd.client.channel.ClientChannel;
+import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.client.session.ClientSessionHolder;
 import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.session.SessionHolder;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface SubsystemClient extends ClientSessionHolder, NamedResource, Channel {
+public interface SubsystemClient extends SessionHolder<ClientSession>, ClientSessionHolder, NamedResource, Channel {
     /**
      * @return The underlying {@link ClientChannel} used
      */

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
index 6f061ac..56dcf80 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
@@ -30,6 +30,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
 
+import org.apache.sshd.client.subsystem.AbstractSubsystemClient;
 import org.apache.sshd.client.subsystem.sftp.extensions.BuiltinSftpClientExtensions;
 import org.apache.sshd.client.subsystem.sftp.extensions.SftpClientExtension;
 import org.apache.sshd.client.subsystem.sftp.extensions.SftpClientExtensionFactory;
@@ -42,13 +43,12 @@ import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
 
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public abstract class AbstractSftpClient extends AbstractLoggingBean implements SftpClient, RawSftpClient {
+public abstract class AbstractSftpClient extends AbstractSubsystemClient implements SftpClient, RawSftpClient {
 
     private final AtomicReference<Map<String, Object>> parsedExtensionsHolder = new AtomicReference<>(null);
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/Service.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/Service.java b/sshd-core/src/main/java/org/apache/sshd/common/Service.java
index ee13a22..35bc7c0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/Service.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/Service.java
@@ -28,7 +28,6 @@ import org.apache.sshd.common.util.buffer.Buffer;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public interface Service extends Closeable {
-
     Session getSession();
 
     // TODO: this is specific to clients

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
index 20436c8..d023fed 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
@@ -23,7 +23,6 @@ import java.io.IOException;
 import org.apache.sshd.client.future.OpenFuture;
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.PropertyResolver;
-import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -69,9 +68,6 @@ public interface Channel extends ChannelListenerManager, PropertyResolver, Close
 
     void handleFailure() throws IOException;
 
-    @Override
-    CloseFuture close(boolean immediately);
-
     void init(ConnectionService service, Session session, int id) throws IOException;
 
     /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/kex/KeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/KeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/KeyExchange.java
index a3364a9..bd5f7ed 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/KeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/KeyExchange.java
@@ -24,7 +24,7 @@ import java.util.Map;
 import org.apache.sshd.common.NamedResource;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.digest.Digest;
-import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.logging.LoggingUtils;
@@ -46,7 +46,7 @@ public interface KeyExchange extends NamedResource {
      * @param i_c     the client key init packet
      * @throws Exception if an error occurs
      */
-    void init(AbstractSession session, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception;
+    void init(Session session, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception;
 
     /**
      * Process the next packet

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
index 666e2b7..a92a5bc 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
@@ -22,13 +22,15 @@ package org.apache.sshd.common.kex.dh;
 import org.apache.sshd.common.digest.Digest;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionHolder;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.logging.AbstractLoggingBean;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public abstract class AbstractDHKeyExchange extends AbstractLoggingBean implements KeyExchange {
+public abstract class AbstractDHKeyExchange extends AbstractLoggingBean implements KeyExchange, SessionHolder<AbstractSession> {
 
     protected byte[] v_s;
     protected byte[] v_c;
@@ -47,14 +49,16 @@ public abstract class AbstractDHKeyExchange extends AbstractLoggingBean implemen
     }
 
     @Override
-    public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
-        this.session = ValidateUtils.checkNotNull(s, "No session");
+    public void init(Session s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
+        ValidateUtils.checkTrue(s instanceof AbstractSession, "Not an abstract session: %s", s);
+        this.session = (AbstractSession) s;
         this.v_s = ValidateUtils.checkNotNullAndNotEmpty(v_s, "No v_s value");
         this.v_c = ValidateUtils.checkNotNullAndNotEmpty(v_c, "No v_c value");
         this.i_s = ValidateUtils.checkNotNullAndNotEmpty(i_s, "No i_s value");
         this.i_c = ValidateUtils.checkNotNullAndNotEmpty(i_c, "No i_c value");
     }
 
+    @Override
     public AbstractSession getSession() {
         return session;
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
index b00d8a8..179d67c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
@@ -53,9 +53,10 @@ import org.apache.sshd.server.x11.X11ForwardSupport;
 /**
  * Base implementation of ConnectionService.
  *
+ * @param <S> Type of {@link AbstractSession} being used
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public abstract class AbstractConnectionService extends AbstractInnerCloseable implements ConnectionService {
+public abstract class AbstractConnectionService<S extends AbstractSession> extends AbstractInnerCloseable implements ConnectionService {
     /**
      * Property that can be used to configure max. allowed concurrent active channels
      *
@@ -78,7 +79,7 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
      */
     protected final AtomicInteger nextChannelId = new AtomicInteger(0);
 
-    protected final AbstractSession session;
+    private final S session;
 
     /**
      * The tcpip forwarder
@@ -88,9 +89,8 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
     protected final X11ForwardSupport x11Forward;
     private final AtomicBoolean allowMoreSessions = new AtomicBoolean(true);
 
-    protected AbstractConnectionService(Session session) {
-        ValidateUtils.checkTrue(session instanceof AbstractSession, "Not an AbstractSession");
-        this.session = (AbstractSession) session;
+    protected AbstractConnectionService(S session) {
+        this.session = session;
         FactoryManager manager = session.getFactoryManager();
         agentForward = new AgentForwardSupport(this);
         x11Forward = new X11ForwardSupport(this);
@@ -107,7 +107,7 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
     }
 
     @Override
-    public AbstractSession getSession() {
+    public S getSession() {
         return session;
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
index bfe9592..95edc26 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
@@ -22,9 +22,11 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.nio.charset.StandardCharsets;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Date;
 import java.util.EnumMap;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentHashMap;
@@ -752,8 +754,10 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
         super.preClose();
     }
 
-    protected Service[] getServices() {
-        return currentService != null ? new Service[]{currentService} : new Service[0];
+    protected List<Service> getServices() {
+        return (currentService != null)
+              ? Collections.singletonList(currentService)
+              : Collections.<Service>emptyList();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
index 142835b..1832002 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
@@ -234,7 +234,7 @@ public interface Session
      * If the service is not of the specified class,
      * an IllegalStateException will be thrown.
      *
-     * @param <T>   The generic service type
+     * @param <T>   The generic {@link Service} type
      * @param clazz The service class
      * @return The service instance
      * @throws IllegalStateException If failed to find a matching service

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionHolder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionHolder.java b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionHolder.java
new file mode 100644
index 0000000..1f7a204
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionHolder.java
@@ -0,0 +1,28 @@
+/*
+ * 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.common.session;
+
+/**
+ * @param <S> Type of {@link Session} being held
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface SessionHolder<S extends Session> {
+    S getSession();
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
index 03ccda6..589d702 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
@@ -22,7 +22,7 @@ package org.apache.sshd.server.kex;
 import java.security.PublicKey;
 
 import org.apache.sshd.common.kex.dh.AbstractDHKeyExchange;
-import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.server.session.ServerSession;
 import org.apache.sshd.server.session.ServerSessionHolder;
@@ -37,12 +37,12 @@ public abstract class AbstractDHServerKeyExchange extends AbstractDHKeyExchange
     }
 
     @Override
-    public ServerSession getServerSession() {
-        return (ServerSession) super.getSession();
+    public final ServerSession getServerSession() {
+        return (ServerSession) getSession();
     }
 
     @Override
-    public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
+    public void init(Session s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
         super.init(s, v_s, v_c, i_s, i_c);
         ValidateUtils.checkTrue(s instanceof ServerSession, "Using a server side KeyExchange on a client");
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
index b427c08..c2e0742 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
@@ -40,7 +40,7 @@ import org.apache.sshd.common.kex.KexProposalOption;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.kex.KeyExchangeFactory;
 import org.apache.sshd.common.random.Random;
-import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.signature.Signature;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.SecurityUtils;
@@ -95,7 +95,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
     }
 
     @Override
-    public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
+    public void init(Session s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
         super.init(s, v_s, v_c, i_s, i_c);
         expected = SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST;
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
index e6a9ef2..3cdcd17 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
@@ -28,7 +28,7 @@ import org.apache.sshd.common.kex.DHFactory;
 import org.apache.sshd.common.kex.KexProposalOption;
 import org.apache.sshd.common.kex.KeyExchange;
 import org.apache.sshd.common.kex.KeyExchangeFactory;
-import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.signature.Signature;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -75,7 +75,7 @@ public class DHGServer extends AbstractDHServerKeyExchange {
     }
 
     @Override
-    public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
+    public void init(Session s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
         super.init(s, v_s, v_c, i_s, i_c);
         dh = factory.create();
         hash = dh.getHash();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
index 78458a1..fc6f492 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
@@ -37,6 +37,9 @@ import org.apache.sshd.common.util.threads.ThreadUtils;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.Environment;
 import org.apache.sshd.server.ExitCallback;
+import org.apache.sshd.server.SessionAware;
+import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.server.session.ServerSessionHolder;
 
 /**
  * This commands provide SCP support on both server and client side.
@@ -45,7 +48,10 @@ import org.apache.sshd.server.ExitCallback;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class ScpCommand extends AbstractLoggingBean implements Command, Runnable, FileSystemAware {
+public class ScpCommand
+        extends AbstractLoggingBean
+        implements Command, Runnable, FileSystemAware, SessionAware, ServerSessionHolder {
+
     protected String name;
     protected boolean optR;
     protected boolean optT;
@@ -65,6 +71,7 @@ public class ScpCommand extends AbstractLoggingBean implements Command, Runnable
     protected int sendBufferSize;
     protected int receiveBufferSize;
     protected ScpTransferEventListener listener;
+    protected ServerSession serverSession;
 
     /**
      * @param command         The command to be executed
@@ -154,6 +161,16 @@ public class ScpCommand extends AbstractLoggingBean implements Command, Runnable
     }
 
     @Override
+    public ServerSession getServerSession() {
+        return serverSession;
+    }
+
+    @Override
+    public void setSession(ServerSession session) {
+        serverSession = session;
+    }
+
+    @Override
     public void setInputStream(InputStream in) {
         this.in = in;
     }
@@ -227,7 +244,7 @@ public class ScpCommand extends AbstractLoggingBean implements Command, Runnable
     public void run() {
         int exitValue = ScpHelper.OK;
         String exitMessage = null;
-        ScpHelper helper = new ScpHelper(in, out, fileSystem, listener);
+        ScpHelper helper = new ScpHelper(getServerSession(), in, out, fileSystem, listener);
         try {
             if (optT) {
                 helper.receive(helper.resolveLocalPath(path), optR, optD, optP, receiveBufferSize);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
index a36d38b..97e96b8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
@@ -22,27 +22,27 @@ import java.io.IOException;
 
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.session.AbstractConnectionService;
-import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * Server side <code>ssh-connection</code> service.
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class ServerConnectionService extends AbstractConnectionService {
-
-    protected ServerConnectionService(Session s) throws SshException {
+public class ServerConnectionService extends AbstractConnectionService<AbstractServerSession> implements ServerSessionHolder {
+    protected ServerConnectionService(AbstractServerSession s) throws SshException {
         super(s);
 
-        ValidateUtils.checkTrue(s instanceof ServerSession, "Server side service used on client side");
-
-        if (!session.isAuthenticated()) {
+        if (!s.isAuthenticated()) {
             throw new SshException("Session is not authenticated");
         }
     }
 
     @Override
+    public final ServerSession getServerSession() {
+        return getSession();
+    }
+
+    @Override
     public String initAgentForward() throws IOException {
         return agentForward.initialize();
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionServiceFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionServiceFactory.java
index fb0ede1..1607e32 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionServiceFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionServiceFactory.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import org.apache.sshd.common.Service;
 import org.apache.sshd.common.ServiceFactory;
 import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -41,6 +42,7 @@ public class ServerConnectionServiceFactory implements ServiceFactory {
 
     @Override
     public Service create(Session session) throws IOException {
-        return new ServerConnectionService(session);
+        ValidateUtils.checkTrue(session instanceof AbstractServerSession, "Not a server session: %s", session);
+        return new ServerConnectionService((AbstractServerSession) session);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionHolder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionHolder.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionHolder.java
index cf4aca4..6b4ff38 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionHolder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionHolder.java
@@ -23,5 +23,8 @@ package org.apache.sshd.server.session;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public interface ServerSessionHolder {
+    /**
+     * @return The underlying {@link ServerSession} used
+     */
     ServerSession getServerSession();
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/test/java/org/apache/sshd/deprecated/AbstractUserAuth.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/AbstractUserAuth.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/AbstractUserAuth.java
index bcaac59..1b891e7 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/AbstractUserAuth.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/AbstractUserAuth.java
@@ -20,12 +20,15 @@ package org.apache.sshd.deprecated;
 
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.client.session.ClientSessionHolder;
+import org.apache.sshd.common.session.SessionHolder;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.logging.AbstractLoggingBean;
 
 /**
  */
-public abstract class AbstractUserAuth extends AbstractLoggingBean implements UserAuth, ClientSessionHolder {
+public abstract class AbstractUserAuth
+        extends AbstractLoggingBean
+        implements UserAuth, SessionHolder<ClientSession>, ClientSessionHolder {
     private final ClientSession session;
     private final String service;
 
@@ -39,6 +42,11 @@ public abstract class AbstractUserAuth extends AbstractLoggingBean implements Us
         return session;
     }
 
+    @Override
+    public final ClientSession getSession() {
+        return getClientSession();
+    }
+
     public String getService() {
         return service;
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
index e9ba550..f21e070 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
@@ -310,27 +310,30 @@ public class ServerTest extends BaseTestSupport {
             assertTrue("No changes in open channels", channelListener.waitForModification(3L, TimeUnit.SECONDS));
             assertTrue("No open server side channels", GenericUtils.size(channelListener.getOpenChannels()) > 0);
 
-            try (AbstractSession serverSession = sshd.getActiveSessions().iterator().next();
-                 Channel channel = serverSession.getService(AbstractConnectionService.class).getChannels().iterator().next()) {
-
-                final long MAX_TIMEOUT_VALUE = IDLE_TIMEOUT_VALUE + DISCONNECT_TIMEOUT_VALUE + TimeUnit.SECONDS.toMillis(3L);
-                for (long totalNanoTime = 0L; channel.getRemoteWindow().getSize() > 0; ) {
-                    long nanoStart = System.nanoTime();
-                    Thread.sleep(1L);
-                    long nanoEnd = System.nanoTime();
-                    long nanoDuration = nanoEnd - nanoStart;
-
-                    totalNanoTime += nanoDuration;
-                    assertTrue("Waiting for too long on remote window size to reach zero", totalNanoTime < TimeUnit.MILLISECONDS.toNanos(MAX_TIMEOUT_VALUE));
-                }
+            try (AbstractSession serverSession = sshd.getActiveSessions().iterator().next()) {
+                AbstractConnectionService<?> service = serverSession.getService(AbstractConnectionService.class);
+                Collection<? extends Channel> channels = service.getChannels();
+
+                try (Channel channel = channels.iterator().next()) {
+                    final long MAX_TIMEOUT_VALUE = IDLE_TIMEOUT_VALUE + DISCONNECT_TIMEOUT_VALUE + TimeUnit.SECONDS.toMillis(3L);
+                    for (long totalNanoTime = 0L; channel.getRemoteWindow().getSize() > 0; ) {
+                        long nanoStart = System.nanoTime();
+                        Thread.sleep(1L);
+                        long nanoEnd = System.nanoTime();
+                        long nanoDuration = nanoEnd - nanoStart;
+
+                        totalNanoTime += nanoDuration;
+                        assertTrue("Waiting for too long on remote window size to reach zero", totalNanoTime < TimeUnit.MILLISECONDS.toNanos(MAX_TIMEOUT_VALUE));
+                    }
 
-                LoggerFactory.getLogger(getClass()).info("Waiting for session idle timeouts");
+                    LoggerFactory.getLogger(getClass()).info("Waiting for session idle timeouts");
 
-                long t0 = System.currentTimeMillis();
-                latch.await(1, TimeUnit.MINUTES);
-                long t1 = System.currentTimeMillis(), diff = t1 - t0;
-                assertTrue("Wait time too low: " + diff, diff > IDLE_TIMEOUT_VALUE);
-                assertTrue("Wait time too high: " + diff, diff < MAX_TIMEOUT_VALUE);
+                    long t0 = System.currentTimeMillis();
+                    latch.await(1, TimeUnit.MINUTES);
+                    long t1 = System.currentTimeMillis(), diff = t1 - t0;
+                    assertTrue("Wait time too low: " + diff, diff > IDLE_TIMEOUT_VALUE);
+                    assertTrue("Wait time too high: " + diff, diff < MAX_TIMEOUT_VALUE);
+                }
             }
         } finally {
             client.stop();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fa0af69a/sshd-core/src/test/java/org/apache/sshd/server/command/ScpCommandFactoryTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/command/ScpCommandFactoryTest.java b/sshd-core/src/test/java/org/apache/sshd/server/command/ScpCommandFactoryTest.java
index 916576b..5bcc437 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/command/ScpCommandFactoryTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/command/ScpCommandFactoryTest.java
@@ -79,12 +79,12 @@ public class ScpCommandFactoryTest extends BaseTestSupport {
      * <UL>
      * <LI>
      * Make sure the builder returns new instances on every call to
-     * {@link ScpCommandFactory.Builder#build()} method
+     * {@link org.apache.sshd.server.scp.ScpCommandFactory.Builder#build()} method
      * </LI>
      *
      * <LI>
      * Make sure values are preserved between successive invocations
-     * of the {@link ScpCommandFactory.Builder#build()} method
+     * of the {@link org.apache.sshd.server.scp.ScpCommandFactory.Builder#build()} method
      * </LI>
      * </UL
      */


[4/5] mina-sshd git commit: Added -E option to log the output of the 'ssh', 'scp', 'sftp' commands to a file or STDOUT instead of STDERR (default)

Posted by lg...@apache.org.
Added -E option to log the output of the 'ssh', 'scp', 'sftp' commands to a file or STDOUT instead of STDERR (default)


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

Branch: refs/heads/master
Commit: 914b570370c669e723becba932cb43518e26c30b
Parents: fa0af69
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Wed Dec 16 12:14:10 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Wed Dec 16 12:14:10 2015 +0200

----------------------------------------------------------------------
 assembly/src/main/distribution/bin/scp.bat      |   2 +-
 assembly/src/main/distribution/bin/scp.sh       |   2 +-
 .../java/org/apache/sshd/client/SshClient.java  | 112 ++++++++++++++-----
 .../sshd/client/scp/DefaultScpClient.java       |  45 ++++++--
 .../sshd/client/subsystem/sftp/SftpCommand.java |  15 ++-
 5 files changed, 132 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/914b5703/assembly/src/main/distribution/bin/scp.bat
----------------------------------------------------------------------
diff --git a/assembly/src/main/distribution/bin/scp.bat b/assembly/src/main/distribution/bin/scp.bat
index 6a30289..ce86067 100644
--- a/assembly/src/main/distribution/bin/scp.bat
+++ b/assembly/src/main/distribution/bin/scp.bat
@@ -47,7 +47,7 @@ if not exist "%SSHD_HOME%" (
 )
 
 set DEFAULT_JAVA_OPTS=-server -Xmx512M -Dcom.sun.management.jmxremote
-set DEFAULT_JAVA_DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005
+set DEFAULT_JAVA_DEBUG_OPTS=-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
 
 rem Support for loading native libraries
 set PATH=%PATH%;%SSHD_HOME%\lib

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/914b5703/assembly/src/main/distribution/bin/scp.sh
----------------------------------------------------------------------
diff --git a/assembly/src/main/distribution/bin/scp.sh b/assembly/src/main/distribution/bin/scp.sh
index fa894d5..55d26b8 100644
--- a/assembly/src/main/distribution/bin/scp.sh
+++ b/assembly/src/main/distribution/bin/scp.sh
@@ -213,7 +213,7 @@ setupDefaults() {
             CLASSPATH="$CLASSPATH:$file"
         fi
     done
-    DEFAULT_JAVA_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
+    DEFAULT_JAVA_DEBUG_OPTS="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"
 
     ##
     ## TODO: Move to conf/profiler/yourkit.{sh|cmd}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/914b5703/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index b60ebd2..e8da138 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -23,13 +23,17 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StreamCorruptedException;
 import java.io.StringWriter;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
+import java.nio.file.Files;
 import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.security.GeneralSecurityException;
 import java.security.KeyPair;
 import java.util.ArrayList;
@@ -733,11 +737,19 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
           Main class implementation
      *=================================*/
 
-    private static boolean showError(PrintStream stderr, String message) {
+    public static boolean showError(PrintStream stderr, String message) {
         stderr.println(message);
         return true;
     }
 
+    public static boolean isArgumentedOption(String portOption, String argName) {
+        return portOption.equals(argName)
+             || "-i".equals(argName)
+             || "-o".equals(argName)
+             || "-l".equals(argName)
+             || "-E".equals(argName);
+    }
+
     // NOTE: ClientSession#getFactoryManager is the SshClient
     public static ClientSession setupClientSession(
             String portOption, final BufferedReader stdin, final PrintStream stdout, final PrintStream stderr, String... args)
@@ -752,35 +764,31 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         int numArgs = GenericUtils.length(args);
         for (int i = 0; (!error) && (i < numArgs); i++) {
             String argName = args[i];
-            if (portOption.equals(argName)) {
-                if (i + 1 >= numArgs) {
+            String argVal = null;
+            if (isArgumentedOption(portOption, argName)) {
+                if ((i + 1) >= numArgs) {
                     error = showError(stderr, "option requires an argument: " + argName);
                     break;
                 }
 
+                argVal = args[++i];
+            }
+
+            if (portOption.equals(argName)) {
                 if (port > 0) {
                     error = showError(stderr, argName + " option value re-specified: " + port);
                     break;
                 }
 
-                port = Integer.parseInt(args[++i]);
+                port = Integer.parseInt(argVal);
                 if (port <= 0) {
                     error = showError(stderr, "Bad option value for " + argName + ": " + port);
                     break;
                 }
             } else if ("-i".equals(argName)) {
-                if (i + 1 >= numArgs) {
-                    error = showError(stderr, "option requires an argument: " + argName);
-                    break;
-                }
-
-                identities.add(new File(args[++i]));
+                identities.add(new File(argVal));
             } else if ("-o".equals(argName)) {
-                if (i + 1 >= numArgs) {
-                    error = showError(stderr, "option requires an argument: " + argName);
-                    break;
-                }
-                String opt = args[++i];
+                String opt = argVal;
                 int idx = opt.indexOf('=');
                 if (idx <= 0) {
                     error = showError(stderr, "bad syntax for option: " + opt);
@@ -788,17 +796,12 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                 }
                 options.put(opt.substring(0, idx), opt.substring(idx + 1));
             } else if ("-l".equals(argName)) {
-                if (i + 1 >= numArgs) {
-                    error = showError(stderr, "option requires an argument: " + argName);
-                    break;
-                }
-
                 if (login != null) {
                     error = showError(stderr, argName + " option value re-specified: " + port);
                     break;
                 }
 
-                login = args[++i];
+                login = argVal;
             } else if (argName.charAt(0) != '-') {
                 if (host != null) { // assume part of a command following it
                     break;
@@ -929,8 +932,52 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         return Level.WARNING;
     }
 
-    public static Handler setupLogging(Level level) {
-        Handler fh = new ConsoleHandler();
+    public static OutputStream resolveLoggingTargetStream(PrintStream stdout, PrintStream stderr, String ... args) {
+        return resolveLoggingTargetStream(stdout, stderr, args, GenericUtils.length(args));
+    }
+
+    public static OutputStream resolveLoggingTargetStream(PrintStream stdout, PrintStream stderr, String[] args, int maxIndex) {
+        for (int index = 0; index < maxIndex; index++) {
+            String argName = args[index];
+            if ("-E".equals(argName)) {
+                if ((index + 1) >= maxIndex) {
+                    showError(stderr, "Missing " + argName + " option argument");
+                    return null;
+                }
+
+                String argVal = args[index + 1];
+                if ("--".equals(argVal)) {
+                    return stdout;
+                }
+
+                try {
+                    Path path = Paths.get(argVal).normalize().toAbsolutePath();
+                    return Files.newOutputStream(path);
+                } catch (IOException e) {
+                    showError(stderr, "Failed (" + e.getClass().getSimpleName() + ") to open " + argVal + ": " + e.getMessage());
+                    return null;
+                }
+            }
+        }
+
+        return stderr;
+    }
+
+    public static Handler setupLogging(Level level, final PrintStream stdout, final PrintStream stderr, final OutputStream outputStream) {
+        Handler fh = new ConsoleHandler() {
+            {
+                setOutputStream(outputStream); // override the default (stderr)
+            }
+
+            @Override
+            protected synchronized void setOutputStream(OutputStream out) throws SecurityException {
+                if ((out == stdout) || (out == stderr)) {
+                    super.setOutputStream(new NoCloseOutputStream(out));
+                } else {
+                    super.setOutputStream(out);
+                }
+            }
+        };
         fh.setLevel(Level.FINEST);
         fh.setFormatter(new Formatter() {
             @Override
@@ -950,6 +997,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                         record.getLoggerName(), message, throwable);
             }
         });
+
         Logger root = Logger.getLogger("");
         for (Handler handler : root.getHandlers()) {
             root.removeHandler(handler);
@@ -971,10 +1019,11 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         boolean error = false;
         String target = null;
         Level level = Level.WARNING;
+        OutputStream logStream = stderr;
         for (int i = 0; i < numArgs; i++) {
             String argName = args[i];
             // handled by 'setupClientSession'
-            if ((command == null) && ("-i".equals(argName) || "-p".equals(argName) || "-o".equals(argName) || "-l".equals(argName))) {
+            if ((command == null) && isArgumentedOption("-p", argName)) {
                 if ((i + 1) >= numArgs) {
                     error = showError(stderr, "option requires an argument: " + argName);
                     break;
@@ -1009,6 +1058,11 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                 agentForward = false;
             } else {
                 level = resolveLoggingVerbosity(args, i);
+                logStream = resolveLoggingTargetStream(stdout, stderr, args, i);
+                if (logStream == null) {
+                    error = true;
+                    break;
+                }
                 if ((command == null) && target == null) {
                     target = argName;
                 } else {
@@ -1020,11 +1074,11 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             }
         }
 
-        setupLogging(level);
-
         ClientSession session = null;
         try (BufferedReader stdin = new BufferedReader(new InputStreamReader(new NoCloseInputStream(System.in)))) {
             if (!error) {
+                setupLogging(level, stdout, stderr, logStream);
+
                 session = setupClientSession("-p", stdin, stdout, stderr, args);
                 if (session == null) {
                     error = true;
@@ -1032,7 +1086,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             }
 
             if (error) {
-                System.err.println("usage: ssh [-A|-a] [-v[v][v]] [-D socksPort] [-l login] [-p port] [-o option=value] hostname/user@host [command]");
+                System.err.println("usage: ssh [-A|-a] [-v[v][v]] [-E logoutput] [-D socksPort] [-l login] [-p port] [-o option=value] hostname/user@host [command]");
                 System.exit(-1);
                 return;
             }
@@ -1088,6 +1142,10 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             } finally {
                 session.close();
             }
+        } finally {
+            if ((logStream != stdout) && (logStream != stderr)) {
+                logStream.close();
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/914b5703/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
index 7913ac9..6176c91 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
@@ -33,6 +33,8 @@ import java.util.Collections;
 import java.util.EnumSet;
 import java.util.List;
 import java.util.Set;
+import java.util.logging.Level;
+
 import org.apache.sshd.client.SshClient;
 import org.apache.sshd.client.channel.ChannelExec;
 import org.apache.sshd.client.session.ClientSession;
@@ -73,10 +75,11 @@ public class DefaultScpClient extends AbstractScpClient {
     @Override
     public void download(String remote, OutputStream local) throws IOException {
         String cmd = createReceiveCommand(remote, Collections.<Option>emptyList());
-        ChannelExec channel = openCommandChannel(getClientSession(), cmd);
+        ClientSession session = getClientSession();
+        ChannelExec channel = openCommandChannel(session, cmd);
         try {
             // NOTE: we use a mock file system since we expect no invocations for it
-            ScpHelper helper = new ScpHelper(channel.getInvertedOut(), channel.getInvertedIn(), new MockFileSystem(remote), listener);
+            ScpHelper helper = new ScpHelper(session, channel.getInvertedOut(), channel.getInvertedIn(), new MockFileSystem(remote), listener);
             helper.receiveFileStream(local, ScpHelper.DEFAULT_RECEIVE_BUFFER_SIZE);
         } finally {
             channel.close(false);
@@ -86,9 +89,10 @@ public class DefaultScpClient extends AbstractScpClient {
     @Override
     protected void download(String remote, FileSystem fs, Path local, Collection<Option> options) throws IOException {
         String cmd = createReceiveCommand(remote, options);
-        ChannelExec channel = openCommandChannel(getClientSession(), cmd);
+        ClientSession session = getClientSession();
+        ChannelExec channel = openCommandChannel(session, cmd);
         try {
-            ScpHelper helper = new ScpHelper(channel.getInvertedOut(), channel.getInvertedIn(), fs, listener);
+            ScpHelper helper = new ScpHelper(session, channel.getInvertedOut(), channel.getInvertedIn(), fs, listener);
             helper.receive(local,
                     options.contains(Option.Recursive),
                     options.contains(Option.TargetIsDirectory),
@@ -106,9 +110,10 @@ public class DefaultScpClient extends AbstractScpClient {
                 ? remote
                 : ValidateUtils.checkNotNullAndNotEmpty(remote.substring(namePos + 1), "No name value in remote=%s", remote);
         final String cmd = createSendCommand(remote, (time != null) ? EnumSet.of(Option.PreserveAttributes) : Collections.<Option>emptySet());
-        ChannelExec channel = openCommandChannel(clientSession, cmd);
+        ClientSession session = getClientSession();
+        ChannelExec channel = openCommandChannel(session, cmd);
         try {
-            ScpHelper helper = new ScpHelper(channel.getInvertedOut(), channel.getInvertedIn(), new MockFileSystem(remote), listener);
+            ScpHelper helper = new ScpHelper(session, channel.getInvertedOut(), channel.getInvertedIn(), new MockFileSystem(remote), listener);
             final Path mockPath = new MockPath(remote);
             helper.sendStream(new DefaultScpStreamResolver(name, mockPath, perms, time, size, local, cmd),
                               time != null, ScpHelper.DEFAULT_SEND_BUFFER_SIZE);
@@ -133,7 +138,7 @@ public class DefaultScpClient extends AbstractScpClient {
             FileSystemFactory factory = manager.getFileSystemFactory();
             FileSystem fs = factory.createFileSystem(session);
             try {
-                ScpHelper helper = new ScpHelper(channel.getInvertedOut(), channel.getInvertedIn(), fs, listener);
+                ScpHelper helper = new ScpHelper(session, channel.getInvertedOut(), channel.getInvertedIn(), fs, listener);
                 executor.execute(helper, local, options);
             } finally {
                 try {
@@ -164,7 +169,8 @@ public class DefaultScpClient extends AbstractScpClient {
         boolean error = false;
         for (int index = 0; (index < numArgs) && (!error); index++) {
             String argName = args[index];
-            if ("-i".equals(argName) || "-P".equals(argName) || "-o".equals(argName)) {
+            // handled by 'setupClientSession'
+            if (SshClient.isArgumentedOption("-P", argName)) {
                 if ((index + 1) >= numArgs) {
                     error = showError(stderr, "option requires an argument: " + argName);
                     break;
@@ -172,7 +178,8 @@ public class DefaultScpClient extends AbstractScpClient {
 
                 effective.add(argName);
                 effective.add(args[++index]);
-            } else if ("-r".equals(argName) || "-p".equals(argName) || "-q".equals(argName)) {
+            } else if ("-r".equals(argName) || "-p".equals(argName) || "-q".equals(argName)
+                    || "-v".equals(argName) || "-vv".equals(argName) || "-vvv".equals(argName)) {
                 effective.add(argName);
             } else if (argName.charAt(0) == '-') {
                 error = showError(stderr, "Unknown option: " + argName);
@@ -213,12 +220,23 @@ public class DefaultScpClient extends AbstractScpClient {
     public static void main(String[] args) throws Exception {
         final PrintStream stdout = System.out;
         final PrintStream stderr = System.err;
+        OutputStream logStream = stdout;
         try (BufferedReader stdin = new BufferedReader(new InputStreamReader(new NoCloseInputStream(System.in)))) {
             args = normalizeCommandArguments(stdout, stderr, args);
+            int numArgs = GenericUtils.length(args);
+            // see the way normalizeCommandArguments works...
+            if (numArgs >= 2) {
+                Level level = SshClient.resolveLoggingVerbosity(args, numArgs - 2);
+                logStream = SshClient.resolveLoggingTargetStream(stdout, stderr, args, numArgs - 2);
+                if (logStream != null) {
+                    SshClient.setupLogging(level, stdout, stderr, logStream);
+                }
+            }
 
-            ClientSession session = GenericUtils.isEmpty(args) ? null : SshClient.setupClientSession("-P", stdin, stdout, stderr, args);
+            ClientSession session = (logStream == null) || GenericUtils.isEmpty(args)
+                    ? null : SshClient.setupClientSession("-P", stdin, stdout, stderr, args);
             if (session == null) {
-                stderr.println("usage: scp [-P port] [-i identity] [-r] [-p] [-q] [-o option=value] <source> <target>");
+                stderr.println("usage: scp [-P port] [-i identity] [-v[v][v]] [-E logoutput] [-r] [-p] [-q] [-o option=value] <source> <target>");
                 stderr.println();
                 stderr.println("Where <source> or <target> are either 'user@host:file' or a local file path");
                 stderr.println("NOTE: exactly ONE of the source or target must be remote and the other one local");
@@ -228,7 +246,6 @@ public class DefaultScpClient extends AbstractScpClient {
 
             try {
                 // see the way normalizeCommandArguments works...
-                int numArgs = GenericUtils.length(args);
                 Collection<Option> options = EnumSet.noneOf(Option.class);
                 boolean quiet = false;
                 for (int index = 0; index < numArgs; index++) {
@@ -291,6 +308,10 @@ public class DefaultScpClient extends AbstractScpClient {
             } finally {
                 session.close();
             }
+        } finally {
+            if ((logStream != stdout) && (logStream != stderr)) {
+                logStream.close();
+            }
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/914b5703/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
index 1fc041e..59b7622 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
@@ -22,6 +22,7 @@ package org.apache.sshd.client.subsystem.sftp;
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
 import java.io.PrintStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
@@ -188,13 +189,17 @@ public class SftpCommand implements Channel {
     public static void main(String[] args) throws Exception {
         PrintStream stdout = System.out;
         PrintStream stderr = System.err;
+        OutputStream logStream = stderr;
         try (BufferedReader stdin = new BufferedReader(new InputStreamReader(new NoCloseInputStream(System.in)))) {
             Level level = SshClient.resolveLoggingVerbosity(args);
-            SshClient.setupLogging(level);
+            logStream = SshClient.resolveLoggingTargetStream(stdout, stderr, args);
+            if (logStream != null) {
+                SshClient.setupLogging(level, stdout, stderr, logStream);
+            }
 
-            ClientSession session = SshClient.setupClientSession("-P", stdin, stdout, stderr, args);
+            ClientSession session = (logStream == null) ? null : SshClient.setupClientSession("-P", stdin, stdout, stderr, args);
             if (session == null) {
-                System.err.println("usage: sftp [-v[v][v]] [-i identity] [-l login] [-P port] [-o option=value] hostname/user@host");
+                System.err.println("usage: sftp [-v[v][v]] [-E logoutput] [-i identity] [-l login] [-P port] [-o option=value] hostname/user@host");
                 System.exit(-1);
                 return;
             }
@@ -206,6 +211,10 @@ public class SftpCommand implements Channel {
             } finally {
                 session.close();
             }
+        } finally {
+            if ((logStream != stdout) && (logStream != stderr)) {
+                logStream.close();
+            }
         }
     }
 


[5/5] mina-sshd git commit: Added some more SessionHolder markings to existing entities

Posted by lg...@apache.org.
Added some more SessionHolder markings to existing entities


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

Branch: refs/heads/master
Commit: 68844229a070ac3899a8f7df114677ef49011109
Parents: 914b570
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Wed Dec 16 12:16:51 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Wed Dec 16 12:16:51 2015 +0200

----------------------------------------------------------------------
 .../sshd/client/scp/AbstractScpClient.java      |   5 +
 .../org/apache/sshd/client/scp/ScpClient.java   |   4 +-
 .../common/forward/TcpipForwarderFactory.java   |  10 +-
 .../org/apache/sshd/common/scp/ScpHelper.java   | 199 ++++++++++++++-----
 .../session/AbstractConnectionService.java      |  56 +++---
 5 files changed, 188 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/68844229/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
index 40030b6..c96b02c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
@@ -56,6 +56,11 @@ public abstract class AbstractScpClient extends AbstractLoggingBean implements S
     }
 
     @Override
+    public final ClientSession getSession() {
+        return getClientSession();
+    }
+
+    @Override
     public void download(String remote, String local, Option... options) throws IOException {
         download(remote, local, GenericUtils.isEmpty(options) ? Collections.<Option>emptySet() : GenericUtils.of(options));
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/68844229/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java
index 20ca54e..579f30f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/scp/ScpClient.java
@@ -26,12 +26,14 @@ import java.nio.file.attribute.PosixFilePermission;
 import java.util.Collection;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.client.session.ClientSessionHolder;
 import org.apache.sshd.common.scp.ScpTimestamp;
+import org.apache.sshd.common.session.SessionHolder;
 
 /**
  */
-public interface ScpClient extends ClientSessionHolder {
+public interface ScpClient extends SessionHolder<ClientSession>, ClientSessionHolder {
 
     enum Option {
         Recursive,

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/68844229/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipForwarderFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipForwarderFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipForwarderFactory.java
index 4b19b89..beb64cd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipForwarderFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipForwarderFactory.java
@@ -21,16 +21,16 @@ package org.apache.sshd.common.forward;
 import org.apache.sshd.common.session.ConnectionService;
 
 /**
- * A factory for creating TcpipForwarder objects for client Port forwarding
+ * A factory for creating forwarder objects for client port forwarding
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public interface TcpipForwarderFactory {
 
     /**
-     * Creates the TcpipForwarder to be used for TCP/IP port forwards for
-     * this ClientSession.
+     * Creates the forwarder to be used for TCP/IP port forwards for this session.
      *
-     * @param service the service the connections are forwarded through
-     * @return the TcpipForwarder that will listen for connections and set up forwarding
+     * @param service the {@link ConnectionService} the connections are forwarded through
+     * @return the {@link TcpipForwarder} that will listen for connections and set up forwarding
      */
     TcpipForwarder create(ConnectionService service);
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/68844229/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
index 988ef32..d665eec 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
@@ -45,8 +45,11 @@ import java.util.concurrent.TimeUnit;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.file.util.MockPath;
 import org.apache.sshd.common.scp.ScpTransferEventListener.FileOperation;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionHolder;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.SelectorUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.io.DirectoryScanner;
 import org.apache.sshd.common.util.io.IoUtils;
 import org.apache.sshd.common.util.io.LimitInputStream;
@@ -55,7 +58,7 @@ import org.apache.sshd.common.util.logging.AbstractLoggingBean;
 /**
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class ScpHelper extends AbstractLoggingBean {
+public class ScpHelper extends AbstractLoggingBean implements SessionHolder<Session> {
     /**
      * Command prefix used to identify SCP commands
      */
@@ -94,13 +97,21 @@ public class ScpHelper extends AbstractLoggingBean {
     protected final OutputStream out;
     protected final ScpTransferEventListener listener;
 
-    public ScpHelper(InputStream in, OutputStream out, FileSystem fileSystem, ScpTransferEventListener eventListener) {
-        this.in = in;
-        this.out = out;
+    private final Session session;
+
+    public ScpHelper(Session session, InputStream in, OutputStream out, FileSystem fileSystem, ScpTransferEventListener eventListener) {
+        this.session = ValidateUtils.checkNotNull(session, "No session");
+        this.in = ValidateUtils.checkNotNull(in, "No input stream");
+        this.out = ValidateUtils.checkNotNull(out, "No output stream");
         this.fileSystem = fileSystem;
         this.listener = (eventListener == null) ? ScpTransferEventListener.EMPTY : eventListener;
     }
 
+    @Override
+    public Session getSession() {
+        return session;
+    }
+
     public void receiveFileStream(final OutputStream local, final int bufferSize) throws IOException {
         receive(new ScpReceiveLineHandler() {
             @Override
@@ -115,7 +126,8 @@ public class ScpHelper extends AbstractLoggingBean {
                     @Override
                     public OutputStream resolveTargetStream(String name, long length, Set<PosixFilePermission> perms) throws IOException {
                         if (log.isDebugEnabled()) {
-                            log.debug("resolveTargetStream(" + name + ")[" + perms + "][len=" + length + "] started local stream download");
+                            log.debug("resolveTargetStream({}) name={}, perms={}, len={} - started local stream download",
+                                      ScpHelper.this, name, perms, length);
                         }
                         return local;
                     }
@@ -129,7 +141,8 @@ public class ScpHelper extends AbstractLoggingBean {
                     @SuppressWarnings("synthetic-access")
                     public void postProcessReceivedData(String name, boolean preserve, Set<PosixFilePermission> perms, ScpTimestamp time) throws IOException {
                         if (log.isDebugEnabled()) {
-                            log.debug("postProcessReceivedData(" + name + ")[" + perms + "][time=" + time + "] ended local stream download");
+                            log.debug("postProcessReceivedData({}) name={}, perms={}, preserve={} time={}",
+                                      ScpHelper.this, name, perms, preserve, time);
                         }
                     }
 
@@ -142,7 +155,8 @@ public class ScpHelper extends AbstractLoggingBean {
         });
     }
 
-    public void receive(final Path path, final boolean recursive, boolean shouldBeDir, final boolean preserve, final int bufferSize) throws IOException {
+    public void receive(Path local, final boolean recursive, boolean shouldBeDir, final boolean preserve, final int bufferSize) throws IOException {
+        final Path path = ValidateUtils.checkNotNull(local, "No local path").normalize().toAbsolutePath();
         if (shouldBeDir) {
             LinkOption[] options = IoUtils.getLinkOptions(false);
             Boolean status = IoUtils.checkFileExists(path, options);
@@ -182,21 +196,29 @@ public class ScpHelper extends AbstractLoggingBean {
                 case 'D':
                     isDir = true;
                     line = String.valueOf((char) c) + readLine();
-                    log.debug("Received header: " + line);
+                    if (log.isDebugEnabled()) {
+                        log.debug("receive({}) - Received 'D' header: {}", this, line);
+                    }
                     break;
                 case 'C':
                     line = String.valueOf((char) c) + readLine();
-                    log.debug("Received header: " + line);
+                    if (log.isDebugEnabled()) {
+                        log.debug("receive({}) - Received 'C' header: {}", this, line);
+                    }
                     break;
                 case 'T':
                     line = String.valueOf((char) c) + readLine();
-                    log.debug("Received header: " + line);
+                    if (log.isDebugEnabled()) {
+                        log.debug("receive({}) - Received 'T' header: {}", this, line);
+                    }
                     time = ScpTimestamp.parseTime(line);
                     ack();
                     continue;
                 case 'E':
                     line = String.valueOf((char) c) + readLine();
-                    log.debug("Received header: " + line);
+                    if (log.isDebugEnabled()) {
+                        log.debug("receive({}) - Received 'E' header: {}", this, line);
+                    }
                     ack();
                     return;
                 default:
@@ -212,12 +234,14 @@ public class ScpHelper extends AbstractLoggingBean {
         }
     }
 
-    public void receiveDir(String header, Path path, ScpTimestamp time, boolean preserve, int bufferSize) throws IOException {
+    public void receiveDir(String header, Path local, ScpTimestamp time, boolean preserve, int bufferSize) throws IOException {
+        Path path = ValidateUtils.checkNotNull(local, "No local path").normalize().toAbsolutePath();
         if (log.isDebugEnabled()) {
-            log.debug("Receiving directory {}", path);
+            log.debug("receiveDir({})[{}] Receiving directory {} - preserve={}, time={}, buffer-size={}",
+                      this, header, path, preserve, time, bufferSize);
         }
         if (!header.startsWith("D")) {
-            throw new IOException("Expected a D message but got '" + header + "'");
+            throw new IOException("Expected a 'D; message but got '" + header + "'");
         }
 
         Set<PosixFilePermission> perms = parseOctalPermissions(header.substring(1, 5));
@@ -276,7 +300,7 @@ public class ScpHelper extends AbstractLoggingBean {
             for (;;) {
                 header = readLine();
                 if (log.isDebugEnabled()) {
-                    log.debug("Received header: " + header);
+                    log.debug("receiveDir({})[{}] Received header: {}", this, file, header);
                 }
                 if (header.startsWith("C")) {
                     receiveFile(header, file, time, preserve, bufferSize);
@@ -300,9 +324,11 @@ public class ScpHelper extends AbstractLoggingBean {
         }
     }
 
-    public void receiveFile(String header, Path path, ScpTimestamp time, boolean preserve, int bufferSize) throws IOException {
+    public void receiveFile(String header, Path local, ScpTimestamp time, boolean preserve, int bufferSize) throws IOException {
+        Path path = ValidateUtils.checkNotNull(local, "No local path").normalize().toAbsolutePath();
         if (log.isDebugEnabled()) {
-            log.debug("Receiving file {}", path);
+            log.debug("receiveFile({})[{}] Receiving file {} - preserve={}, time={}, buffer-size={}",
+                      this, header, path, preserve, time, bufferSize);
         }
 
         receiveStream(header, new LocalFileScpTargetStreamResolver(path), time, preserve, bufferSize);
@@ -321,14 +347,15 @@ public class ScpHelper extends AbstractLoggingBean {
         final long length = Long.parseLong(header.substring(6, header.indexOf(' ', 6)));
         String name = header.substring(header.indexOf(' ', 6) + 1);
         if (length < 0L) { // TODO consider throwing an exception...
-            log.warn("receiveStream(" + resolver + ") bad length in header: " + header);
+            log.warn("receiveStream({})[{}] bad length in header: {}", this, resolver, header);
         }
 
         // if file size is less than buffer size allocate only expected file size
         int bufSize;
         if (length == 0L) {
             if (log.isDebugEnabled()) {
-                log.debug("receiveStream(" + resolver + ") zero file size (perhaps special file) using copy buffer size=" + MIN_RECEIVE_BUFFER_SIZE);
+                log.debug("receiveStream({})[{}] zero file size (perhaps special file) using copy buffer size={}",
+                          this, resolver, MIN_RECEIVE_BUFFER_SIZE);
             }
             bufSize = MIN_RECEIVE_BUFFER_SIZE;
         } else {
@@ -336,7 +363,8 @@ public class ScpHelper extends AbstractLoggingBean {
         }
 
         if (bufSize < 0) { // TODO consider throwing an exception
-            log.warn("receiveFile(" + resolver + ") bad buffer size (" + bufSize + ") using default (" + MIN_RECEIVE_BUFFER_SIZE + ")");
+            log.warn("receiveStream({})[{}] bad buffer size ({}) using default ({})",
+                     this, resolver, bufSize, MIN_RECEIVE_BUFFER_SIZE);
             bufSize = MIN_RECEIVE_BUFFER_SIZE;
         }
 
@@ -361,12 +389,11 @@ public class ScpHelper extends AbstractLoggingBean {
 
         ack();
         readAck(false);
-
     }
 
     protected void updateFileProperties(Path file, Set<PosixFilePermission> perms, ScpTimestamp time) throws IOException {
         if (log.isTraceEnabled()) {
-            log.trace("updateFileProperties(" + file + ") permissions: " + perms);
+            log.trace("updateFileProperties({}) {} permissions={}, time={}", this, file, perms, time);
         }
         IoUtils.setPermissions(file, perms);
 
@@ -375,7 +402,7 @@ public class ScpHelper extends AbstractLoggingBean {
             FileTime lastModified = FileTime.from(time.getLastModifiedTime(), TimeUnit.MILLISECONDS);
             FileTime lastAccess = FileTime.from(time.getLastAccessTime(), TimeUnit.MILLISECONDS);
             if (log.isTraceEnabled()) {
-                log.trace("updateFileProperties(" + file + ") last-modified=" + lastModified + ", last-access=" + lastAccess);
+                log.trace("updateFileProperties({}) {} last-modified={}, last-access={}", this, file, lastModified, lastAccess);
             }
             view.setTimes(lastModified, lastAccess, null);
         }
@@ -386,18 +413,19 @@ public class ScpHelper extends AbstractLoggingBean {
     }
 
     public String readLine(boolean canEof) throws IOException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        for (;;) {
-            int c = in.read();
-            if (c == '\n') {
-                return baos.toString();
-            } else if (c == -1) {
-                if (!canEof) {
-                    throw new EOFException("EOF while await end of line");
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(Byte.MAX_VALUE)) {
+            for (;;) {
+                int c = in.read();
+                if (c == '\n') {
+                    return baos.toString(StandardCharsets.UTF_8.name());
+                } else if (c == -1) {
+                    if (!canEof) {
+                        throw new EOFException("EOF while await end of line");
+                    }
+                    return null;
+                } else {
+                    baos.write(c);
                 }
-                return null;
-            } else {
-                baos.write(c);
             }
         }
     }
@@ -426,12 +454,18 @@ public class ScpHelper extends AbstractLoggingBean {
                         sendFile(file, preserve, bufferSize);
                     } else if (Files.isDirectory(file, options)) {
                         if (!recursive) {
+                            if (log.isDebugEnabled()) {
+                                log.debug("send({}) {}: not a regular file", this, path);
+                            }
                             out.write(ScpHelper.WARNING);
                             out.write((path.replace(File.separatorChar, '/') + " not a regular file\n").getBytes(StandardCharsets.UTF_8));
                         } else {
                             sendDir(file, preserve, bufferSize);
                         }
                     } else {
+                        if (log.isDebugEnabled()) {
+                            log.debug("send({}) {}: unknown file type", this, path);
+                        }
                         out.write(ScpHelper.WARNING);
                         out.write((path.replace(File.separatorChar, '/') + " unknown file type\n").getBytes(StandardCharsets.UTF_8));
                     }
@@ -451,7 +485,8 @@ public class ScpHelper extends AbstractLoggingBean {
         }
     }
 
-    protected void send(Path file, boolean recursive, boolean preserve, int bufferSize, LinkOption... options) throws IOException {
+    protected void send(Path local, boolean recursive, boolean preserve, int bufferSize, LinkOption... options) throws IOException {
+        Path file = ValidateUtils.checkNotNull(local, "No local path").normalize().toAbsolutePath();
         Boolean status = IoUtils.checkFileExists(file, options);
         if (status == null) {
             throw new AccessDeniedException("Send file existence status cannot be determined: " + file);
@@ -493,15 +528,16 @@ public class ScpHelper extends AbstractLoggingBean {
         Path abs = lcl.isAbsolute() ? lcl : lcl.toAbsolutePath();
         Path p = abs.normalize();
         if (log.isTraceEnabled()) {
-            log.trace("resolveLocalPath({}) {}", commandPath, p);
+            log.trace("resolveLocalPath({}) {}: {}", this, commandPath, p);
         }
-        
+
         return p;
     }
 
-    public void sendFile(Path path, boolean preserve, int bufferSize) throws IOException {
+    public void sendFile(Path local, boolean preserve, int bufferSize) throws IOException {
+        Path path = ValidateUtils.checkNotNull(local, "No local path").normalize().toAbsolutePath();
         if (log.isDebugEnabled()) {
-            log.debug("Sending file {}", path);
+            log.debug("sendFile({})[preserve={},buffer-size={}] Sending file {}", this, preserve, bufferSize, path);
         }
 
         sendStream(new LocalFileScpSourceStreamResolver(path), preserve, bufferSize);
@@ -517,7 +553,8 @@ public class ScpHelper extends AbstractLoggingBean {
         int bufSize;
         if (fileSize <= 0L) {
             if (log.isDebugEnabled()) {
-                log.debug("sendStream(" + resolver + ") unknown file size (" + fileSize + ")  perhaps special file - using copy buffer size=" + MIN_SEND_BUFFER_SIZE);
+                log.debug("sendStream({})[{}] unknown file size ({}) perhaps special file - using copy buffer size={}",
+                          this, resolver, fileSize, MIN_SEND_BUFFER_SIZE);
             }
             bufSize = MIN_SEND_BUFFER_SIZE;
         } else {
@@ -525,15 +562,20 @@ public class ScpHelper extends AbstractLoggingBean {
         }
 
         if (bufSize < 0) { // TODO consider throwing an exception
-            log.warn("sendStream(" + resolver + ") bad buffer size (" + bufSize + ") using default (" + MIN_SEND_BUFFER_SIZE + ")");
+            log.warn("sendStream({})[{}] bad buffer size ({}) using default ({})",
+                     this, resolver, bufSize, MIN_SEND_BUFFER_SIZE);
             bufSize = MIN_SEND_BUFFER_SIZE;
         }
 
         ScpTimestamp time = resolver.getTimestamp();
         if (preserve && (time != null)) {
             String cmd = "T" + TimeUnit.MILLISECONDS.toSeconds(time.getLastModifiedTime())
-                    + ' ' + '0' + ' ' + TimeUnit.MILLISECONDS.toSeconds(time.getLastAccessTime())
-                    + ' ' + '0' + '\n';
+                    + " " + "0" + " " + TimeUnit.MILLISECONDS.toSeconds(time.getLastAccessTime())
+                    + " " + "0" + "\n";
+            if (log.isDebugEnabled()) {
+                log.debug("sendStream({})[{}] send timestamp={} command: {}",
+                          this, resolver, time, cmd.substring(0, cmd.length() - 1));
+            }
             out.write(cmd.getBytes(StandardCharsets.UTF_8));
             out.flush();
             readAck(false);
@@ -542,7 +584,11 @@ public class ScpHelper extends AbstractLoggingBean {
         Set<PosixFilePermission> perms = EnumSet.copyOf(resolver.getPermissions());
         String octalPerms = preserve ? getOctalPermissions(perms) : "0644";
         String fileName = resolver.getFileName();
-        String cmd = "C" + octalPerms + ' ' + fileSize + ' ' + fileName + '\n';
+        String cmd = "C" + octalPerms + " " + fileSize + " " + fileName + "\n";
+        if (log.isDebugEnabled()) {
+            log.debug("sendStream({})[{}] send 'C' command: {}",
+                      this, resolver, cmd.substring(0, cmd.length() - 1));
+        }
         out.write(cmd.getBytes(StandardCharsets.UTF_8));
         out.flush();
         readAck(false);
@@ -562,24 +608,39 @@ public class ScpHelper extends AbstractLoggingBean {
         readAck(false);
     }
 
-    public void sendDir(Path path, boolean preserve, int bufferSize) throws IOException {
+    public void sendDir(Path local, boolean preserve, int bufferSize) throws IOException {
+        Path path = ValidateUtils.checkNotNull(local, "No local path").normalize().toAbsolutePath();
         if (log.isDebugEnabled()) {
-            log.debug("Sending directory {}", path);
+            log.debug("sendDir({}) Sending directory {} - preserve={}, buffer-size={}",
+                      this, path, preserve, bufferSize);
         }
 
         BasicFileAttributes basic = Files.getFileAttributeView(path, BasicFileAttributeView.class).readAttributes();
         if (preserve) {
-            out.write(("T" + basic.lastModifiedTime().to(TimeUnit.SECONDS) + " "
-                    + "0" + " " + basic.lastAccessTime().to(TimeUnit.SECONDS) + " "
-                    + "0" + "\n").getBytes(StandardCharsets.UTF_8));
+            FileTime lastModified = basic.lastModifiedTime();
+            FileTime lastAccess = basic.lastAccessTime();
+            String cmd = "T" + lastModified.to(TimeUnit.SECONDS) + " "
+                    + "0" + " " + lastAccess.to(TimeUnit.SECONDS) + " "
+                    + "0" + "\n";
+            if (log.isDebugEnabled()) {
+                log.debug("sendDir({})[{}] send last-modified={}, last-access={} command: {}",
+                          this, path, lastModified,  lastAccess, cmd.substring(0, cmd.length() - 1));
+            }
+
+            out.write(cmd.getBytes(StandardCharsets.UTF_8));
             out.flush();
             readAck(false);
         }
 
         LinkOption[] options = IoUtils.getLinkOptions(false);
         Set<PosixFilePermission> perms = IoUtils.getPermissions(path, options);
-        out.write(("D" + (preserve ? getOctalPermissions(perms) : "0755") + " "
-                + "0" + " " + path.getFileName().toString() + "\n").getBytes(StandardCharsets.UTF_8));
+        String cmd = "D" + (preserve ? getOctalPermissions(perms) : "0755") + " "
+                + "0" + " " + path.getFileName().toString() + "\n";
+        if (log.isDebugEnabled()) {
+            log.debug("sendDir({})[{}] send 'D' command: {}",
+                      this, path, cmd.substring(0, cmd.length() - 1));
+        }
+        out.write(cmd.getBytes(StandardCharsets.UTF_8));
         out.flush();
         readAck(false);
 
@@ -602,6 +663,9 @@ public class ScpHelper extends AbstractLoggingBean {
             }
         }
 
+        if (log.isDebugEnabled()) {
+            log.debug("sendDir({})[{}] send 'E' command", this, path);
+        }
         out.write("E\n".getBytes(StandardCharsets.UTF_8));
         out.flush();
         readAck(false);
@@ -699,20 +763,45 @@ public class ScpHelper extends AbstractLoggingBean {
         int c = in.read();
         switch (c) {
             case -1:
+                if (log.isDebugEnabled()) {
+                    log.debug("readAck({})[EOF={}] received EOF", this, canEof);
+                }
                 if (!canEof) {
                     throw new EOFException("readAck - EOF before ACK");
                 }
                 break;
             case OK:
+                if (log.isDebugEnabled()) {
+                    log.debug("readAck({})[EOF={}] read OK", this, canEof);
+                }
                 break;
-            case WARNING:
-                log.warn("Received warning: " + readLine());
+            case WARNING: {
+                if (log.isDebugEnabled()) {
+                    log.debug("readAck({})[EOF={}] read warning message", this, canEof);
+                }
+
+                String line = readLine();
+                log.warn("readAck({})[EOF={}] - Received warning: {}", this, canEof, line);
                 break;
-            case ERROR:
-                throw new IOException("Received nack: " + readLine());
+            }
+            case ERROR: {
+                if (log.isDebugEnabled()) {
+                    log.debug("readAck({})[EOF={}] read error message", this, canEof);
+                }
+                String line = readLine();
+                if (log.isDebugEnabled()) {
+                    log.debug("readAck({})[EOF={}] received error: {}", this, canEof, line);
+                }
+                throw new IOException("Received nack: " + line);
+            }
             default:
                 break;
         }
         return c;
     }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + getSession() + "]";
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/68844229/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
index 179d67c..176c867 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
@@ -79,8 +79,6 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
      */
     protected final AtomicInteger nextChannelId = new AtomicInteger(0);
 
-    private final S session;
-
     /**
      * The tcpip forwarder
      */
@@ -89,17 +87,18 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
     protected final X11ForwardSupport x11Forward;
     private final AtomicBoolean allowMoreSessions = new AtomicBoolean(true);
 
+    private final S sessionInstance;
+
     protected AbstractConnectionService(S session) {
-        this.session = session;
-        FactoryManager manager = session.getFactoryManager();
+        sessionInstance = ValidateUtils.checkNotNull(session, "No session");
         agentForward = new AgentForwardSupport(this);
         x11Forward = new X11ForwardSupport(this);
 
-        TcpipForwarderFactory factory = ValidateUtils.checkNotNull(
-                manager.getTcpipForwarderFactory(),
-                "No forwarder factory",
-                GenericUtils.EMPTY_OBJECT_ARRAY);
-        tcpipForwarder = factory.create(this);
+        FactoryManager manager =
+                ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
+        TcpipForwarderFactory factory =
+                ValidateUtils.checkNotNull(manager.getTcpipForwarderFactory(), "No forwarder factory");
+        tcpipForwarder = ValidateUtils.checkNotNull(factory.create(this), "No forwarder created for %s", session);
     }
 
     public Collection<Channel> getChannels() {
@@ -108,7 +107,7 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
 
     @Override
     public S getSession() {
-        return session;
+        return sessionInstance;
     }
 
     @Override
@@ -124,7 +123,7 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
     @Override
     protected Closeable getInnerCloseable() {
         return builder()
-                .sequential(tcpipForwarder, agentForward, x11Forward)
+                .sequential(getTcpipForwarder(), agentForward, x11Forward)
                 .parallel(channels.values())
                 .build();
     }
@@ -135,6 +134,7 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
 
     @Override
     public int registerChannel(Channel channel) throws IOException {
+        final Session session = getSession();
         int maxChannels = PropertyResolverUtils.getIntProperty(session, MAX_CONCURRENT_CHANNELS_PROP, DEFAULT_MAX_CHANNELS);
         int curSize = channels.size();
         if (curSize > maxChannels) {
@@ -152,7 +152,7 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
         }
 
         if (log.isDebugEnabled()) {
-            log.debug("registerChannel(id={}) {}", Integer.valueOf(channelId), channel);
+            log.debug("registerChannel({})[id={}] {}", this, channelId, channel);
         }
         return channelId;
     }
@@ -386,6 +386,7 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
             return;
         }
 
+        final Session session = getSession();
         FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
         final Channel channel = NamedFactory.Utils.create(manager.getChannelFactories(), type);
         if (channel == null) {
@@ -444,6 +445,7 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
                       this, sender, SshConstants.getOpenErrorCodeName(reasonCode), lang, message);
         }
 
+        final Session session = getSession();
         Buffer buf = session.prepareBuffer(SshConstants.SSH_MSG_CHANNEL_OPEN_FAILURE, BufferUtils.clear(buffer));
         buf.putInt(sender);
         buf.putInt(reasonCode);
@@ -462,20 +464,24 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
         String req = buffer.getString();
         boolean wantReply = buffer.getBoolean();
         if (log.isDebugEnabled()) {
-            log.debug("Received SSH_MSG_GLOBAL_REQUEST {} want-reply={}", req, Boolean.valueOf(wantReply));
+            log.debug("globalRequest({}) received SSH_MSG_GLOBAL_REQUEST {} want-reply={}",
+                      this, req, Boolean.valueOf(wantReply));
         }
 
-        List<RequestHandler<ConnectionService>> handlers = session.getFactoryManager().getGlobalRequestHandlers();
+        Session session = getSession();
+        FactoryManager manager =
+                ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
+        List<RequestHandler<ConnectionService>> handlers = manager.getGlobalRequestHandlers();
         if (GenericUtils.size(handlers) > 0) {
             for (RequestHandler<ConnectionService> handler : handlers) {
                 RequestHandler.Result result;
                 try {
                     result = handler.process(this, req, wantReply, buffer);
                 } catch (Exception e) {
-                    log.warn("globalRequest({})[want-reply={}] failed ({}) to process: {}",
-                             req, wantReply, e.getClass().getSimpleName(), e.getMessage());
+                    log.warn("globalRequest({})[{}, want-reply={}] failed ({}) to process: {}",
+                             this, req, wantReply, e.getClass().getSimpleName(), e.getMessage());
                     if (log.isDebugEnabled()) {
-                        log.debug("globalRequest(" + req + ")[want-reply=" + wantReply + "] failure details", e);
+                        log.debug("globalRequest(" + this + ")[" + req + ", want-reply=" + wantReply + "] failure details", e);
                     }
                     result = RequestHandler.Result.ReplyFailure;
                 }
@@ -483,8 +489,8 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
                 // if Unsupported then check the next handler in line
                 if (RequestHandler.Result.Unsupported.equals(result)) {
                     if (log.isTraceEnabled()) {
-                        log.trace("{}#process({})[want-reply={}] : {}",
-                                  handler.getClass().getSimpleName(), req, wantReply, result);
+                        log.trace("globalRequest({}) {}#process({})[want-reply={}] : {}",
+                                  this, handler.getClass().getSimpleName(), req, wantReply, result);
                     }
                 } else {
                     sendResponse(buffer, req, result, wantReply);
@@ -493,13 +499,13 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
             }
         }
 
-        log.warn("Unknown global request: {}", req);
+        log.warn("globalRequest({}) unknown global request: {}", this, req);
         sendResponse(buffer, req, RequestHandler.Result.Unsupported, wantReply);
     }
 
     protected void sendResponse(Buffer buffer, String req, RequestHandler.Result result, boolean wantReply) throws IOException {
         if (log.isDebugEnabled()) {
-            log.debug("sendResponse({}) result={}, want-reply={}", req, result, Boolean.valueOf(wantReply));
+            log.debug("sendResponse({})[{}] result={}, want-reply={}", this, req, result, Boolean.valueOf(wantReply));
         }
 
         if (RequestHandler.Result.Replied.equals(result) || (!wantReply)) {
@@ -515,20 +521,20 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
         buffer.rpos(5);
         buffer.wpos(5);
         buffer.putByte(cmd);
-        session.writePacket(buffer);
+        getSession().writePacket(buffer);
     }
 
     protected void requestSuccess(Buffer buffer) throws Exception {
-        session.requestSuccess(buffer);
+        getSession().requestSuccess(buffer);
     }
 
     protected void requestFailure(Buffer buffer) throws Exception {
-        session.requestFailure(buffer);
+        getSession().requestFailure(buffer);
     }
 
     @Override
     public String toString() {
-        return getClass().getSimpleName() + "[" + session + "]";
+        return getClass().getSimpleName() + "[" + getSession() + "]";
     }
 
 }


[2/5] mina-sshd git commit: Using a common verbosity arguments parsing method for 'ssh', 'scp', 'sftp' commands

Posted by lg...@apache.org.
Using a common verbosity arguments parsing method for 'ssh', 'scp', 'sftp' commands


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

Branch: refs/heads/master
Commit: 4c106febdc0bfd0d95d5e755b11fd86278bea192
Parents: 1b6d41b
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Wed Dec 16 12:12:38 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Wed Dec 16 12:12:38 2015 +0200

----------------------------------------------------------------------
 .../java/org/apache/sshd/client/SshClient.java  | 80 +++++++++++++-------
 .../sshd/client/subsystem/sftp/SftpCommand.java |  6 +-
 2 files changed, 56 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4c106feb/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index 5fce328..b60ebd2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -910,9 +910,26 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         }
     }
 
-    //////////////////////////////////////////////////////////////////////////
+    public static Level resolveLoggingVerbosity(String ... args) {
+        return resolveLoggingVerbosity(args, GenericUtils.length(args));
+    }
 
-    public static void main(String[] args) throws Exception {
+    public static Level resolveLoggingVerbosity(String[] args, int maxIndex) {
+        for (int index = 0; index < maxIndex; index++) {
+            String argName = args[index];
+            if ("-v".equals(argName)) {
+                return Level.INFO;
+            } else if ("-vv".equals(argName)) {
+                return Level.FINE;
+            } else if ("-vvv".equals(argName)) {
+                return Level.FINEST;
+            }
+        }
+
+        return Level.WARNING;
+    }
+
+    public static Handler setupLogging(Level level) {
         Handler fh = new ConsoleHandler();
         fh.setLevel(Level.FINEST);
         fh.setFormatter(new Formatter() {
@@ -938,48 +955,61 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             root.removeHandler(handler);
         }
         root.addHandler(fh);
+        root.setLevel(level);
+        return fh;
+    }
+
+    //////////////////////////////////////////////////////////////////////////
 
+    public static void main(String[] args) throws Exception {
         PrintStream stdout = System.out;
         PrintStream stderr = System.err;
         boolean agentForward = false;
         List<String> command = null;
-        int logLevel = 0;
         int socksPort = -1;
         int numArgs = GenericUtils.length(args);
         boolean error = false;
         String target = null;
+        Level level = Level.WARNING;
         for (int i = 0; i < numArgs; i++) {
             String argName = args[i];
-            if (command == null && "-D".equals(argName)) {
-                if (i + 1 >= numArgs) {
-                    System.err.println("option requires an argument: " + argName);
-                    error = true;
+            // handled by 'setupClientSession'
+            if ((command == null) && ("-i".equals(argName) || "-p".equals(argName) || "-o".equals(argName) || "-l".equals(argName))) {
+                if ((i + 1) >= numArgs) {
+                    error = showError(stderr, "option requires an argument: " + argName);
+                    break;
+                }
+
+                continue;
+            }
+
+            // verbosity handled separately
+            if ((command == null) && ("-v".equals(argName) || "-vv".equals(argName) || "-vvv".equals(argName))) {
+                continue;
+            }
+
+            if ((command == null) && "-D".equals(argName)) {
+                if ((i + 1) >= numArgs) {
+                    error = showError(stderr, "option requires an argument: " + argName);
                     break;
                 }
                 if (socksPort > 0) {
-                    stderr.println(argName + " option value re-specified: " + socksPort);
-                    error = true;
+                    error = showError(stderr, argName + " option value re-specified: " + socksPort);
                     break;
                 }
 
                 socksPort = Integer.parseInt(args[++i]);
                 if (socksPort <= 0) {
-                    stderr.println("Bad option value for " + argName + ": " + socksPort);
-                    error = true;
+                    error = showError(stderr, "Bad option value for " + argName + ": " + socksPort);
                     break;
                 }
-            } else if (command == null && "-v".equals(argName)) {
-                logLevel += 1;
-            } else if (command == null && "-vv".equals(argName)) {
-                logLevel += 2;
-            } else if (command == null && "-vvv".equals(argName)) {
-                logLevel += 3;
-            } else if (command == null && "-A".equals(argName)) {
+            } else if ((command == null) && "-A".equals(argName)) {
                 agentForward = true;
-            } else if (command == null && "-a".equals(argName)) {
+            } else if ((command == null) && "-a".equals(argName)) {
                 agentForward = false;
             } else {
-                if (command == null && target == null) {
+                level = resolveLoggingVerbosity(args, i);
+                if ((command == null) && target == null) {
                     target = argName;
                 } else {
                     if (command == null) {
@@ -990,15 +1020,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
             }
         }
 
-        if (logLevel <= 0) {
-            root.setLevel(Level.WARNING);
-        } else if (logLevel == 1) {
-            root.setLevel(Level.INFO);
-        } else if (logLevel == 2) {
-            root.setLevel(Level.FINE);
-        } else {
-            root.setLevel(Level.FINEST);
-        }
+        setupLogging(level);
 
         ClientSession session = null;
         try (BufferedReader stdin = new BufferedReader(new InputStreamReader(new NoCloseInputStream(System.in)))) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/4c106feb/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
index eaf6f46..1fc041e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
@@ -30,6 +30,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Map;
 import java.util.TreeMap;
+import java.util.logging.Level;
 
 import org.apache.sshd.client.SshClient;
 import org.apache.sshd.client.session.ClientSession;
@@ -188,9 +189,12 @@ public class SftpCommand implements Channel {
         PrintStream stdout = System.out;
         PrintStream stderr = System.err;
         try (BufferedReader stdin = new BufferedReader(new InputStreamReader(new NoCloseInputStream(System.in)))) {
+            Level level = SshClient.resolveLoggingVerbosity(args);
+            SshClient.setupLogging(level);
+
             ClientSession session = SshClient.setupClientSession("-P", stdin, stdout, stderr, args);
             if (session == null) {
-                System.err.println("usage: sftp [-l login] [-P port] [-o option=value] hostname/user@host");
+                System.err.println("usage: sftp [-v[v][v]] [-i identity] [-l login] [-P port] [-o option=value] hostname/user@host");
                 System.exit(-1);
                 return;
             }