Repository: mina-sshd
Updated Branches:
  refs/heads/master 7b8152d34 -> f5acda557


[SSHD-776] Do not throw an exception if SSH_MSG_CHANNEL_EOF received for 
non-existent channel


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

Branch: refs/heads/master
Commit: f5acda557a8e818321bfc1dd0c67afa9f9d1dcb6
Parents: 7b8152d
Author: Lyor Goldstein <lyor.goldst...@gmail.com>
Authored: Wed Oct 4 15:46:33 2017 +0300
Committer: Lyor Goldstein <lyor.goldst...@gmail.com>
Committed: Wed Oct 4 15:47:30 2017 +0300

----------------------------------------------------------------------
 .../common/channel/OpenChannelException.java    | 53 -------------------
 .../channel/exception/SshChannelException.java  | 48 +++++++++++++++++
 .../exception/SshChannelNotFoundException.java  | 39 ++++++++++++++
 .../exception/SshChannelOpenException.java      | 54 ++++++++++++++++++++
 .../helpers/AbstractConnectionService.java      | 22 +++++---
 .../sshd/server/forward/TcpipServerChannel.java |  6 +--
 6 files changed, 160 insertions(+), 62 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f5acda55/sshd-core/src/main/java/org/apache/sshd/common/channel/OpenChannelException.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/channel/OpenChannelException.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/channel/OpenChannelException.java
deleted file mode 100644
index 829858a..0000000
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/channel/OpenChannelException.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.channel;
-
-/**
- * Documents failure of a channel to open as expected.
- *
- * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
- */
-public class OpenChannelException extends Exception {
-    private static final long serialVersionUID = 3861183351970782341L;
-    private final int code;
-
-    public OpenChannelException(int code, String message) {
-        this(code, message, null);
-    }
-
-    public OpenChannelException(int code, String message, Throwable cause) {
-        super(message, cause);
-        this.code = code;
-    }
-
-    /**
-     * The reason code as specified by RFC 4254.
-     * <ul>
-     * <li>{@link 
org.apache.sshd.common.SshConstants#SSH_OPEN_ADMINISTRATIVELY_PROHIBITED}
-     * <li>{@link org.apache.sshd.common.SshConstants#SSH_OPEN_CONNECT_FAILED}
-     * <li>{@link 
org.apache.sshd.common.SshConstants#SSH_OPEN_UNKNOWN_CHANNEL_TYPE}
-     * <li>{@link 
org.apache.sshd.common.SshConstants#SSH_OPEN_RESOURCE_SHORTAGE}
-     * </ul>
-     *
-     * @return reason code; 0 if no standardized reason code is given.
-     */
-    public int getReasonCode() {
-        return code;
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f5acda55/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelException.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelException.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelException.java
new file mode 100644
index 0000000..57c9669
--- /dev/null
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelException.java
@@ -0,0 +1,48 @@
+/*
+ * 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.channel.exception;
+
+import java.io.IOException;
+
+/**
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+public class SshChannelException extends IOException {
+    private static final long serialVersionUID = 7355720478400167933L;
+
+    private final int channelId;
+
+    public SshChannelException(int channelId, String message) {
+        this(channelId, message, null);
+    }
+
+    public SshChannelException(int channelId, Throwable cause) {
+        this(channelId, cause.getMessage(), cause);
+    }
+
+    public SshChannelException(int channelId, String message, Throwable cause) 
{
+        super(message, cause);
+        this.channelId = channelId;
+    }
+
+    public int getChannelId() {
+        return channelId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f5acda55/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelNotFoundException.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelNotFoundException.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelNotFoundException.java
new file mode 100644
index 0000000..26fb9ab
--- /dev/null
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelNotFoundException.java
@@ -0,0 +1,39 @@
+/*
+ * 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.channel.exception;
+
+/**
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+public class SshChannelNotFoundException extends SshChannelException {
+    private static final long serialVersionUID = 6235323779982884257L;
+
+    public SshChannelNotFoundException(int channelId, String message) {
+        this(channelId, message, null);
+    }
+
+    public SshChannelNotFoundException(int channelId, Throwable cause) {
+        this(channelId, cause.getMessage(), cause);
+    }
+
+    public SshChannelNotFoundException(int channelId, String message, 
Throwable cause) {
+        super(channelId, message, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f5acda55/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelOpenException.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelOpenException.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelOpenException.java
new file mode 100644
index 0000000..e272d2b
--- /dev/null
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/channel/exception/SshChannelOpenException.java
@@ -0,0 +1,54 @@
+/*
+ * 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.channel.exception;
+
+/**
+ * Documents failure of a channel to open as expected.
+ *
+ * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
+ */
+public class SshChannelOpenException extends SshChannelException {
+    private static final long serialVersionUID = 3591321447714889771L;
+
+    private final int code;
+
+    public SshChannelOpenException(int channelId, int code, String message) {
+        this(channelId, code, message, null);
+    }
+
+    public SshChannelOpenException(int channelId, int code, String message, 
Throwable cause) {
+        super(channelId, message, cause);
+        this.code = code;
+    }
+
+    /**
+     * The reason code as specified by RFC 4254.
+     * <ul>
+     * <li>{@link 
org.apache.sshd.common.SshConstants#SSH_OPEN_ADMINISTRATIVELY_PROHIBITED}
+     * <li>{@link org.apache.sshd.common.SshConstants#SSH_OPEN_CONNECT_FAILED}
+     * <li>{@link 
org.apache.sshd.common.SshConstants#SSH_OPEN_UNKNOWN_CHANNEL_TYPE}
+     * <li>{@link 
org.apache.sshd.common.SshConstants#SSH_OPEN_RESOURCE_SHORTAGE}
+     * </ul>
+     *
+     * @return reason code; 0 if no standardized reason code is given.
+     */
+    public int getReasonCode() {
+        return code;
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f5acda55/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractConnectionService.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractConnectionService.java
 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractConnectionService.java
index 32d0920..1524196 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractConnectionService.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractConnectionService.java
@@ -42,9 +42,10 @@ import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.channel.AbstractChannel;
 import org.apache.sshd.common.channel.Channel;
-import org.apache.sshd.common.channel.OpenChannelException;
 import org.apache.sshd.common.channel.RequestHandler;
 import org.apache.sshd.common.channel.Window;
+import org.apache.sshd.common.channel.exception.SshChannelNotFoundException;
+import org.apache.sshd.common.channel.exception.SshChannelOpenException;
 import org.apache.sshd.common.forward.ForwardingFilter;
 import org.apache.sshd.common.forward.ForwardingFilterFactory;
 import org.apache.sshd.common.forward.PortForwardingEventListener;
@@ -451,8 +452,15 @@ public abstract class AbstractConnectionService<S extends 
AbstractSession>
      * @throws IOException if an error occurs
      */
     public void channelEof(Buffer buffer) throws IOException {
-        Channel channel = getChannel(buffer);
-        channel.handleEof();
+        // Do not use getChannel to avoid the session being closed
+        // if receiving the SSH_MSG_CHANNEL_EOF on an already closed channel
+        int recipient = buffer.getInt();
+        Channel channel = channels.get(recipient);
+        if (channel != null) {
+            channel.handleEof();
+        } else {
+            log.warn("Received SSH_MSG_CHANNEL_EOF on unknown channel " + 
recipient);
+        }
     }
 
     /**
@@ -523,7 +531,9 @@ public abstract class AbstractConnectionService<S extends 
AbstractSession>
             byte[] data = buffer.array();
             int curPos = buffer.rpos();
             int cmd = (curPos >= 5) ? (data[curPos - 5] & 0xFF) : -1;
-            throw new SshException("Received " + 
SshConstants.getCommandMessageName(cmd) + " on unknown channel " + recipient);
+            // Throw a special exception - SSHD-776
+            throw new SshChannelNotFoundException(recipient,
+                "Received " + SshConstants.getCommandMessageName(cmd) + " on 
unknown channel " + recipient);
         }
 
         return channel;
@@ -583,8 +593,8 @@ public abstract class AbstractConnectionService<S extends 
AbstractSession>
                     if (exception != null) {
                         String message = exception.getMessage();
                         int reasonCode = 0;
-                        if (exception instanceof OpenChannelException) {
-                            reasonCode = ((OpenChannelException) 
exception).getReasonCode();
+                        if (exception instanceof SshChannelOpenException) {
+                            reasonCode = ((SshChannelOpenException) 
exception).getReasonCode();
                         } else {
                             message = exception.getClass().getSimpleName() + " 
while opening channel: " + message;
                         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/f5acda55/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
 
b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
index cca2eb9..57a5699 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
@@ -33,8 +33,8 @@ import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.channel.ChannelFactory;
 import org.apache.sshd.common.channel.ChannelOutputStream;
-import org.apache.sshd.common.channel.OpenChannelException;
 import org.apache.sshd.common.channel.Window;
+import org.apache.sshd.common.channel.exception.SshChannelOpenException;
 import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.io.IoConnectFuture;
 import org.apache.sshd.common.io.IoConnector;
@@ -138,7 +138,7 @@ public class TcpipServerChannel extends 
AbstractServerChannel {
                     log.debug("doInit(" + this + ")[" + type + "][haveFilter=" 
+ (filter != null) + "] filtered out " + address);
                 }
                 super.close(true);
-                f.setException(new 
OpenChannelException(SshConstants.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, 
"Connection denied"));
+                f.setException(new SshChannelOpenException(getId(), 
SshConstants.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "Connection denied"));
                 return f;
             }
         } catch (Error e) {
@@ -235,7 +235,7 @@ public class TcpipServerChannel extends 
AbstractServerChannel {
         closeImmediately0();
 
         if (problem instanceof ConnectException) {
-            f.setException(new 
OpenChannelException(SshConstants.SSH_OPEN_CONNECT_FAILED, 
problem.getMessage(), problem));
+            f.setException(new SshChannelOpenException(getId(), 
SshConstants.SSH_OPEN_CONNECT_FAILED, problem.getMessage(), problem));
         } else {
             f.setException(problem);
         }

Reply via email to