You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by ng...@apache.org on 2009/05/30 23:39:06 UTC
svn commit: r780332 - in /mina/ftpserver/trunk/core/src:
main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
test/java/org/apache/ftpserver/clienttests/DecoderTest.java
Author: ngn
Date: Sat May 30 21:39:05 2009
New Revision: 780332
URL: http://svn.apache.org/viewvc?rev=780332&view=rev
Log:
Return an error reply rather than close the session if we get a decoding problem (FTPSERVER-309)
Added:
mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DecoderTest.java
Modified:
mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
Modified: mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java?rev=780332&r1=780331&r2=780332&view=diff
==============================================================================
--- mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java (original)
+++ mina/ftpserver/trunk/core/src/main/java/org/apache/ftpserver/impl/DefaultFtpHandler.java Sat May 30 21:39:05 2009
@@ -20,11 +20,13 @@
package org.apache.ftpserver.impl;
import java.io.IOException;
+import java.nio.charset.MalformedInputException;
import org.apache.ftpserver.command.Command;
import org.apache.ftpserver.command.CommandFactory;
import org.apache.ftpserver.ftplet.DataConnection;
import org.apache.ftpserver.ftplet.DataConnectionFactory;
+import org.apache.ftpserver.ftplet.DefaultFtpReply;
import org.apache.ftpserver.ftplet.FileSystemView;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
@@ -33,6 +35,7 @@
import org.apache.ftpserver.listener.Listener;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.write.WriteToClosedSessionException;
+import org.apache.mina.filter.codec.ProtocolDecoderException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -135,18 +138,29 @@
public void exceptionCaught(final FtpIoSession session,
final Throwable cause) throws Exception {
- if (cause instanceof WriteToClosedSessionException) {
+
+ if(cause instanceof ProtocolDecoderException &&
+ cause.getCause() instanceof MalformedInputException) {
+ // client probably sent something which is not UTF-8 and we failed to
+ // decode it
+
+ LOG.warn(
+ "Client sent command that could not be decoded: {}",
+ ((ProtocolDecoderException)cause).getHexdump());
+ session.write(new DefaultFtpReply(FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "Invalid character in command"));
+ } else if (cause instanceof WriteToClosedSessionException) {
WriteToClosedSessionException writeToClosedSessionException =
(WriteToClosedSessionException) cause;
LOG.warn(
"Client closed connection before all replies could be sent, last reply was {}",
writeToClosedSessionException.getRequest());
-
+ session.close(false).awaitUninterruptibly(10000);
} else {
LOG.error("Exception caught, closing session", cause);
+ session.close(false).awaitUninterruptibly(10000);
}
- session.close(false).awaitUninterruptibly(10000);
+
}
private boolean isCommandOkWithoutAuthentication(String command) {
Added: mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DecoderTest.java
URL: http://svn.apache.org/viewvc/mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DecoderTest.java?rev=780332&view=auto
==============================================================================
--- mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DecoderTest.java (added)
+++ mina/ftpserver/trunk/core/src/test/java/org/apache/ftpserver/clienttests/DecoderTest.java Sat May 30 21:39:05 2009
@@ -0,0 +1,82 @@
+/*
+ * 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.ftpserver.clienttests;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.MalformedInputException;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.commons.net.ftp.FTPClient;
+
+
+/**
+*
+* @author The Apache MINA Project (dev@mina.apache.org)*
+*/
+public class DecoderTest extends ClientTestTemplate {
+ private String dump = "4C 49 53 54 20 61 62 63 64 AE 2E 0D 0A".replace(" ", "");
+
+ byte[] b;
+
+ public DecoderTest() throws DecoderException {
+ b = Hex.decodeHex(dump.toCharArray());
+ }
+
+ public void testDecodeError() throws CharacterCodingException {
+ CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder();
+ ByteBuffer buffer = ByteBuffer.wrap(b);
+
+ try {
+ decoder.decode(buffer);
+ fail("Must throw MalformedInputException");
+ } catch (MalformedInputException e) {
+ // OK
+ }
+ }
+
+ private static class MyFTPClient extends FTPClient {
+ public void sendRawCommand(byte[] b) throws IOException {
+ OutputStream out =_socket_.getOutputStream();
+ out.write(b);
+ }
+ }
+
+ protected FTPClient createFTPClient() throws Exception {
+ FTPClient client = new MyFTPClient();
+ client.setDefaultTimeout(10000);
+ return client;
+ }
+
+ public void testInvalidCharacter() throws Exception {
+ client.login(ADMIN_USERNAME, ADMIN_PASSWORD);
+
+ ((MyFTPClient)client).sendRawCommand(b);
+ client.completePendingCommand();
+
+ assertEquals(501, client.getReplyCode());
+ }
+
+}