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 2016/09/16 15:25:29 UTC

[1/4] mina-sshd git commit: [SSHD-698] Added some generics definitions though not strictly required due to Eclipse shortcomings

Repository: mina-sshd
Updated Branches:
  refs/heads/master 241551793 -> fad77cd31


[SSHD-698] Added some generics definitions though not strictly required due to Eclipse shortcomings


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

Branch: refs/heads/master
Commit: f560959af5e928d083da7603ab84b21ff796f46a
Parents: 2415517
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Fri Sep 16 18:15:33 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Fri Sep 16 18:15:33 2016 +0300

----------------------------------------------------------------------
 .../sshd/client/auth/password/PasswordIdentityProvider.java     | 5 ++++-
 .../org/apache/sshd/common/keyprovider/KeyIdentityProvider.java | 5 ++++-
 .../src/main/java/org/apache/sshd/common/util/GenericUtils.java | 2 +-
 3 files changed, 9 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f560959a/sshd-core/src/main/java/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java
index 268779c..3c428cb 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/password/PasswordIdentityProvider.java
@@ -22,6 +22,7 @@ package org.apache.sshd.client.auth.password;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.function.Supplier;
 
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.util.GenericUtils;
@@ -205,7 +206,9 @@ public interface PasswordIdentityProvider {
      * @return The wrapping iterable
      */
     static Iterable<String> iterableOf(Collection<? extends PasswordIdentityProvider> providers) {
-        return GenericUtils.multiIterableSuppliers(GenericUtils.wrapIterable(providers, p -> p::loadPasswords));
+        Iterable<Supplier<Iterable<String>>> passwordSuppliers =
+                GenericUtils.<PasswordIdentityProvider, Supplier<Iterable<String>>>wrapIterable(providers, p -> p::loadPasswords);
+        return GenericUtils.multiIterableSuppliers(passwordSuppliers);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f560959a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
index b696acf..0e809f9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyIdentityProvider.java
@@ -23,6 +23,7 @@ import java.security.KeyPair;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.function.Supplier;
 
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.util.GenericUtils;
@@ -209,7 +210,9 @@ public interface KeyIdentityProvider {
      * @return The wrapping iterable
      */
     static Iterable<KeyPair> iterableOf(Collection<? extends KeyIdentityProvider> providers) {
-        return GenericUtils.multiIterableSuppliers(GenericUtils.wrapIterable(providers, p -> p::loadKeys));
+        Iterable<Supplier<Iterable<KeyPair>>> keysSuppliers =
+                GenericUtils.<KeyIdentityProvider, Supplier<Iterable<KeyPair>>>wrapIterable(providers, p -> p::loadKeys);
+        return GenericUtils.multiIterableSuppliers(keysSuppliers);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f560959a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
index b8a04d1..07928ae 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
@@ -696,7 +696,7 @@ public final class GenericUtils {
      * @param providers The providers - ignored if {@code null} (i.e., return an empty iterable instance)
      * @return The wrapping instance
      */
-    public static <T> Iterable<T> multiIterableSuppliers(final Iterable<? extends Supplier<? extends Iterable<? extends T>>> providers) {
+    public static <T> Iterable<T> multiIterableSuppliers(Iterable<? extends Supplier<? extends Iterable<? extends T>>> providers) {
         return (providers == null) ? Collections.emptyList() : () -> new Iterator<T>() {
             private final Iterator<? extends Supplier<? extends Iterable<? extends T>>> iter = iteratorOf(providers);
             private Iterator<? extends T> current = nextIterator();


[4/4] mina-sshd git commit: [SSHD-699] Ignore also malformed SSH_MSG_UNIMPLEMENTED messages

Posted by lg...@apache.org.
[SSHD-699] Ignore also malformed SSH_MSG_UNIMPLEMENTED messages


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

Branch: refs/heads/master
Commit: fad77cd31063f880a1a4a273d429df05ccf217ce
Parents: 9e56da0
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Fri Sep 16 18:27:20 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Fri Sep 16 18:27:20 2016 +0300

----------------------------------------------------------------------
 .../session/ReservedSessionMessagesHandler.java   | 12 ++++++++++++
 .../common/session/helpers/AbstractSession.java   | 18 ++++++++----------
 .../ReservedSessionMessagesHandlerAdapter.java    | 11 +++++++++++
 .../session/helpers/AbstractSessionTest.java      | 18 +++++++++++++++++-
 4 files changed, 48 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fad77cd3/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
index 6138ae8..08292ea 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
@@ -52,4 +52,16 @@ public interface ReservedSessionMessagesHandler extends SshdEventListener {
     default void handleDebugMessage(Session session, Buffer buffer) throws Exception {
         // ignored
     }
+
+    /**
+     * Invoked when an {@code SSH_MSG_UNIMPLEMENTED} packet is received
+     *
+     * @param session The {@code Session} through which the message was received
+     * @param buffer The {@code Buffer} containing the data
+     * @throws Exception If failed to handle the message
+     * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-11.4">RFC 4253 - section 11.4</A>
+     */
+    default void handleUnimplementedMessage(Session session, Buffer buffer) throws Exception {
+        // ignored
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fad77cd3/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
index d101e37..1377a0e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
@@ -609,7 +609,7 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
         // malformed ignore message - ignore (even though we don't have to, but we can be tolerant in this case)
         if (!buffer.isValidMessageStructure(byte[].class)) {
             if (log.isTraceEnabled()) {
-                log.trace("handleDebug({}) ignore malformed message", this);
+                log.trace("handleIgnore({}) ignore malformed message", this);
             }
             return;
         }
@@ -619,17 +619,15 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
     }
 
     protected void handleUnimplemented(Buffer buffer) throws Exception {
-        handleUnimplemented(buffer.getInt(), buffer);
-    }
-
-    protected void handleUnimplemented(int seqNo, Buffer buffer) throws Exception {
-        if (log.isDebugEnabled()) {
-            log.debug("handleUnimplented({}) SSH_MSG_UNIMPLEMENTED #{}", this, seqNo);
+        if (!buffer.isValidMessageStructure(int.class)) {
+            if (log.isTraceEnabled()) {
+                log.trace("handleUnimplemented({}) ignore malformed message", this);
+            }
+            return;
         }
 
-        if (log.isTraceEnabled()) {
-            log.trace("handleUnimplemented({}) data: {}", this, buffer.toHex());
-        }
+        ReservedSessionMessagesHandler handler = resolveReservedSessionMessagesHandler();
+        handler.handleUnimplementedMessage(this, buffer);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fad77cd3/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java
index 0e62bb0..bcc0a5f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/ReservedSessionMessagesHandlerAdapter.java
@@ -66,4 +66,15 @@ public class ReservedSessionMessagesHandlerAdapter
                       session, display, lang, msg);
         }
     }
+
+    @Override
+    public void handleUnimplementedMessage(Session session, Buffer buffer) throws Exception {
+        handleUnimplementedMessage(session, buffer, buffer.getUInt());
+    }
+
+    public void handleUnimplementedMessage(Session session, Buffer buffer, long seqNo) throws Exception {
+        if (log.isDebugEnabled()) {
+            log.debug("handleUnimplementedMessage({}) SSH_MSG_UNIMPLEMENTED - seqNo={}", session, seqNo);
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fad77cd3/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java b/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
index ced4eb9..dbb4051 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
@@ -194,6 +194,22 @@ public class AbstractSessionTest extends BaseTestSupport {
     }
 
     @Test   // see SSHD-699
+    public void testMalformedUnimplementedMessage() throws Exception {
+        session.setReservedSessionMessagesHandler(new ReservedSessionMessagesHandler() {
+            @Override
+            public void handleUnimplementedMessage(Session session, Buffer buffer) throws Exception {
+                fail("Unexpected invocation: available=" + buffer.available());
+            }
+        });
+
+        Buffer buffer = new ByteArrayBuffer(Long.SIZE);
+        for (int index = 0; index < (Integer.BYTES - 1); index++) {
+            buffer.putByte((byte) index);
+            session.handleUnimplemented(buffer);
+        }
+    }
+
+    @Test   // see SSHD-699
     public void testMalformedIgnoreMessageBadLength() throws Exception {
         session.setReservedSessionMessagesHandler(new ReservedSessionMessagesHandler() {
             @Override
@@ -203,7 +219,7 @@ public class AbstractSessionTest extends BaseTestSupport {
         });
 
         Buffer buffer = new ByteArrayBuffer(Long.SIZE);
-        for (int index = 0; index < Integer.BYTES; index++) {
+        for (int index = 0; index < (Integer.BYTES - 1); index++) {
             buffer.putByte((byte) index);
             session.handleIgnore(buffer);
         }


[3/4] mina-sshd git commit: [SSHD-698] Default all methods in ReservedSessionMessagesHandler as default

Posted by lg...@apache.org.
[SSHD-698] Default all methods in ReservedSessionMessagesHandler as 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/9e56da0f
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/9e56da0f
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/9e56da0f

Branch: refs/heads/master
Commit: 9e56da0f19967aa39eda4336a53f53f81bbce321
Parents: 110ee57
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Fri Sep 16 18:16:51 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Fri Sep 16 18:16:51 2016 +0300

----------------------------------------------------------------------
 .../sshd/common/session/ReservedSessionMessagesHandler.java  | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9e56da0f/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
index 6c525f7..6138ae8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/ReservedSessionMessagesHandler.java
@@ -37,7 +37,9 @@ public interface ReservedSessionMessagesHandler extends SshdEventListener {
      * @throws Exception If failed to handle the message
      * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-11.2">RFC 4253 - section 11.2</A>
      */
-    void handleIgnoreMessage(Session session, Buffer buffer) throws Exception;
+    default void handleIgnoreMessage(Session session, Buffer buffer) throws Exception {
+        // ignored
+    }
 
     /**
      * Invoked when an {@code SSH_MSG_DEBUG} packet is received
@@ -47,5 +49,7 @@ public interface ReservedSessionMessagesHandler extends SshdEventListener {
      * @throws Exception If failed to handle the message
      * @see <A HREF="https://tools.ietf.org/html/rfc4253#section-11.3">RFC 4253 - section 11.3</A>
      */
-    void handleDebugMessage(Session session, Buffer buffer) throws Exception;
+    default void handleDebugMessage(Session session, Buffer buffer) throws Exception {
+        // ignored
+    }
 }


[2/4] mina-sshd git commit: [SSHD-699] Ignore malformed SSH_MSG_IGNORE/DEBUG messages

Posted by lg...@apache.org.
[SSHD-699] Ignore malformed SSH_MSG_IGNORE/DEBUG messages


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

Branch: refs/heads/master
Commit: 110ee5702ac352331938f7bdf899ea3c7f369917
Parents: f560959
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Fri Sep 16 18:16:26 2016 +0300
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Fri Sep 16 18:16:26 2016 +0300

----------------------------------------------------------------------
 .../common/session/helpers/AbstractSession.java | 18 ++++-
 .../apache/sshd/common/util/buffer/Buffer.java  | 66 +++++++++++++++++
 .../common/util/buffer/ByteArrayBuffer.java     |  7 +-
 .../session/helpers/AbstractSessionTest.java    | 77 ++++++++++++++++++++
 4 files changed, 166 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/110ee570/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
index 290ce96..d101e37 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
@@ -606,6 +606,14 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
     }
 
     protected void handleIgnore(Buffer buffer) throws Exception {
+        // malformed ignore message - ignore (even though we don't have to, but we can be tolerant in this case)
+        if (!buffer.isValidMessageStructure(byte[].class)) {
+            if (log.isTraceEnabled()) {
+                log.trace("handleDebug({}) ignore malformed message", this);
+            }
+            return;
+        }
+
         ReservedSessionMessagesHandler handler = resolveReservedSessionMessagesHandler();
         handler.handleIgnoreMessage(this, buffer);
     }
@@ -626,7 +634,7 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
 
     @Override
     public IoWriteFuture sendDebugMessage(boolean display, Object msg, String lang) throws IOException {
-        String text = Objects.toString(msg);
+        String text = Objects.toString(msg, "");
         lang = (lang == null) ? "" : lang;
 
         Buffer buffer = createBuffer(SshConstants.SSH_MSG_DEBUG,
@@ -638,6 +646,14 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
     }
 
     protected void handleDebug(Buffer buffer) throws Exception {
+        // malformed ignore message - ignore (even though we don't have to, but we can be tolerant in this case)
+        if (!buffer.isValidMessageStructure(boolean.class, String.class, String.class)) {
+            if (log.isTraceEnabled()) {
+                log.trace("handleDebug({}) ignore malformed message", this);
+            }
+            return;
+        }
+
         ReservedSessionMessagesHandler handler = resolveReservedSessionMessagesHandler();
         handler.handleDebugMessage(this, buffer);
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/110ee570/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
index 5da403c..16a0368 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
@@ -44,6 +44,7 @@ import java.security.spec.InvalidKeySpecException;
 import java.security.spec.RSAPrivateCrtKeySpec;
 import java.security.spec.RSAPublicKeySpec;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -108,6 +109,71 @@ public abstract class Buffer implements Readable {
 
     public abstract void clear();
 
+    public boolean isValidMessageStructure(Class<?>... fieldTypes) {
+        return isValidMessageStructure(GenericUtils.isEmpty(fieldTypes) ? Collections.emptyList() : Arrays.asList(fieldTypes));
+    }
+
+    public boolean isValidMessageStructure(Collection<Class<?>> fieldTypes) {
+        if (GenericUtils.isEmpty(fieldTypes)) {
+            return true;
+        }
+
+        int remainLen = available();
+        int readOffset = 0;
+        for (Class<?> ft : fieldTypes) {
+            if ((ft == boolean.class) || (ft == Boolean.class)
+                    || (ft == byte.class) || (ft == Byte.class)) {
+                if (remainLen < Byte.BYTES) {
+                    return false;
+                }
+
+                remainLen -= Byte.BYTES;
+                readOffset += Byte.BYTES;
+            } else if ((ft == short.class) || (ft == Short.class)) {
+                if (remainLen < Short.BYTES) {
+                    return false;
+                }
+
+                remainLen -= Short.BYTES;
+                readOffset += Short.BYTES;
+            } else if ((ft == int.class) || (ft == Integer.class)) {
+                if (remainLen < Integer.BYTES) {
+                    return false;
+                }
+
+                remainLen -= Integer.BYTES;
+                readOffset += Integer.BYTES;
+            } else if ((ft == long.class) || (ft == Long.class)) {
+                if (remainLen < Long.BYTES) {
+                    return false;
+                }
+
+                remainLen -= Long.BYTES;
+                readOffset += Long.BYTES;
+            } else if ((ft == byte[].class) || (ft == String.class)) {
+                if (remainLen < Integer.BYTES) {
+                    return false;
+                }
+
+                copyRawBytes(readOffset, workBuf, 0, Integer.BYTES);
+                remainLen -= Integer.BYTES;
+                readOffset += Integer.BYTES;
+
+                long length = BufferUtils.getUInt(workBuf, 0, Integer.BYTES);
+                if (length > remainLen) {
+                    return false;
+                }
+
+                remainLen -= (int) length;
+                readOffset += (int) length;
+            }
+        }
+
+        return true;
+    }
+
+    protected abstract void copyRawBytes(int offset, byte[] buf, int pos, int len);
+
     public String toHex() {
         return BufferUtils.toHex(array(), rpos(), available());
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/110ee570/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
index 8d29494..8e64647 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
@@ -168,11 +168,16 @@ public class ByteArrayBuffer extends Buffer {
     @Override
     public void getRawBytes(byte[] buf, int off, int len) {
         ensureAvailable(len);
-        System.arraycopy(data, rpos, buf, off, len);
+        copyRawBytes(0, buf, off, len);
         rpos += len;
     }
 
     @Override
+    protected void copyRawBytes(int offset, byte[] buf, int pos, int len) {
+        System.arraycopy(data, rpos + offset, buf, pos, len);
+    }
+
+    @Override
     public void ensureCapacity(int capacity, Int2IntFunction growthFactor) {
         ValidateUtils.checkTrue(capacity >= 0, "Negative capacity requested: %d", capacity);
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/110ee570/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java b/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
index b0f4a89..ced4eb9 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/session/helpers/AbstractSessionTest.java
@@ -39,6 +39,7 @@ import org.apache.sshd.common.io.IoService;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.io.IoWriteFuture;
 import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.common.session.ReservedSessionMessagesHandler;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -192,6 +193,82 @@ public class AbstractSessionTest extends BaseTestSupport {
         assertEquals("Close listener not called", 1, closeCount.get());
     }
 
+    @Test   // see SSHD-699
+    public void testMalformedIgnoreMessageBadLength() throws Exception {
+        session.setReservedSessionMessagesHandler(new ReservedSessionMessagesHandler() {
+            @Override
+            public void handleIgnoreMessage(Session session, Buffer buffer) throws Exception {
+                fail("Unexpected invocation: available=" + buffer.available());
+            }
+        });
+
+        Buffer buffer = new ByteArrayBuffer(Long.SIZE);
+        for (int index = 0; index < Integer.BYTES; index++) {
+            buffer.putByte((byte) index);
+            session.handleIgnore(buffer);
+        }
+    }
+
+    @Test   // see SSHD-699
+    public void testMalformedIgnoreMessageCorruptedData() throws Exception {
+        session.setReservedSessionMessagesHandler(new ReservedSessionMessagesHandler() {
+            @Override
+            public void handleIgnoreMessage(Session session, Buffer buffer) throws Exception {
+                fail("Unexpected invocation: available=" + buffer.available());
+            }
+        });
+
+        Buffer buffer = new ByteArrayBuffer(Long.SIZE + Byte.MAX_VALUE);
+        buffer.putInt(Byte.MAX_VALUE + 1);  // bad message length
+        for (int index = 0; index < Byte.MAX_VALUE; index++) {
+            buffer.putByte((byte) index);
+            session.handleIgnore(buffer);
+        }
+    }
+
+    @Test
+    public void testMalformedDebugMessageContent() throws Exception {
+        session.setReservedSessionMessagesHandler(new ReservedSessionMessagesHandler() {
+            @Override
+            public void handleDebugMessage(Session session, Buffer buffer) throws Exception {
+                fail("Unexpected invocation: available=" + buffer.available());
+            }
+        });
+
+        Buffer buffer = new ByteArrayBuffer(Long.SIZE + Byte.MAX_VALUE);
+        session.handleDebug(buffer);    // no boolean field
+
+        buffer.putBoolean(true);
+        session.handleDebug(buffer);    // no message field
+
+        buffer.putInt(Byte.MAX_VALUE + 1);  // bad message field length
+        for (int index = 0; index < Byte.MAX_VALUE; index++) {
+            buffer.putByte((byte) index);
+            session.handleDebug(buffer);
+        }
+    }
+
+    @Test
+    public void testMalformedDebugMessageLanguage() throws Exception {
+        session.setReservedSessionMessagesHandler(new ReservedSessionMessagesHandler() {
+            @Override
+            public void handleDebugMessage(Session session, Buffer buffer) throws Exception {
+                fail("Unexpected invocation: available=" + buffer.available());
+            }
+        });
+
+        Buffer buffer = new ByteArrayBuffer(Long.SIZE);
+        buffer.putBoolean(true);
+        buffer.putString(getCurrentTestName());
+        session.handleDebug(buffer);    // no language tag
+
+        buffer.putInt(Byte.SIZE + 1);   // bad language tag length
+        for (int index = 0; index < Byte.SIZE; index++) {
+            buffer.putByte((byte) index);
+            session.handleDebug(buffer);
+        }
+    }
+
     private static String readIdentification(MySession session, Buffer buf) {
         List<String> lines = session.doReadIdentification(buf);
         return GenericUtils.isEmpty(lines) ? null : lines.get(lines.size() - 1);