You are viewing a plain text version of this content. The canonical link for it is here.
Posted to ftpserver-commits@incubator.apache.org by ng...@apache.org on 2007/06/23 20:32:54 UTC
svn commit: r550099 - in /incubator/ftpserver/trunk/core/src:
java/org/apache/ftpserver/command/ java/org/apache/ftpserver/util/
test/org/apache/ftpserver/util/
Author: ngn
Date: Sat Jun 23 13:32:53 2007
New Revision: 550099
URL: http://svn.apache.org/viewvc?view=rev&rev=550099
Log:
Refactored IP+port encoding/decoding into seperate class
Added:
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalInetAddressException.java (with props)
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalPortException.java (with props)
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/SocketAddressEncoder.java (with props)
incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/SocketAddressEncoderTest.java (with props)
Modified:
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PASV.java
incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PORT.java
Modified: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PASV.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PASV.java?view=diff&rev=550099&r1=550098&r2=550099
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PASV.java (original)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PASV.java Sat Jun 23 13:32:53 2007
@@ -32,6 +32,7 @@
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.listener.Connection;
import org.apache.ftpserver.util.FtpReplyUtil;
+import org.apache.ftpserver.util.SocketAddressEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -67,6 +68,7 @@
try {
InetSocketAddress dataConAddress = dataCon.initPassiveDataConnection();
+
// get connection info
InetAddress servAddr;
if(externalPassiveAddress != null) {
@@ -74,10 +76,11 @@
} else {
servAddr = dataConAddress.getAddress();
}
- int servPort = dataConAddress.getPort();
// send connection info to client
- String addrStr = servAddr.getHostAddress().replace( '.', ',' ) + ',' + (servPort>>8) + ',' + (servPort&0xFF);
+ InetSocketAddress externalDataConAddress = new InetSocketAddress(servAddr, dataConAddress.getPort());
+
+ String addrStr = SocketAddressEncoder.encode(externalDataConAddress);
out.write(FtpReplyUtil.translate(session, FtpReply.REPLY_227_ENTERING_PASSIVE_MODE, "PASV", addrStr));
} catch(DataConnectionException e) {
LOG.warn("Failed to open passive data connection", e);
Modified: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PORT.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PORT.java?view=diff&rev=550099&r1=550098&r2=550099
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PORT.java (original)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/command/PORT.java Sat Jun 23 13:32:53 2007
@@ -23,7 +23,6 @@
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
-import java.util.StringTokenizer;
import org.apache.ftpserver.FtpSessionImpl;
import org.apache.ftpserver.ftplet.FtpReply;
@@ -32,6 +31,9 @@
import org.apache.ftpserver.interfaces.DataConnectionConfig;
import org.apache.ftpserver.listener.Connection;
import org.apache.ftpserver.util.FtpReplyUtil;
+import org.apache.ftpserver.util.IllegalInetAddressException;
+import org.apache.ftpserver.util.IllegalPortException;
+import org.apache.ftpserver.util.SocketAddressEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -74,13 +76,7 @@
out.write(FtpReplyUtil.translate(session, FtpReply.REPLY_501_SYNTAX_ERROR_IN_PARAMETERS_OR_ARGUMENTS, "PORT", null));
return;
}
-
- StringTokenizer st = new StringTokenizer(request.getArgument(), ",");
- if(st.countTokens() != 6) {
- out.write(FtpReplyUtil.translate(session, 510, "PORT", null));
- return;
- }
-
+
// is port enabled
DataConnectionConfig dataCfg = session.getListener().getDataConnectionConfig();
if(!dataCfg.isActiveEnabled()) {
@@ -88,15 +84,18 @@
return;
}
- // get data server
- String dataSrvName = st.nextToken() + '.' + st.nextToken() + '.' +
- st.nextToken() + '.' + st.nextToken();
- InetAddress dataAddr = null;
+ InetSocketAddress address;
try {
- dataAddr = InetAddress.getByName(dataSrvName);
- }
- catch(UnknownHostException ex) {
- LOG.debug("Unknown host: " + dataSrvName, ex);
+ address = SocketAddressEncoder.decode(request.getArgument());
+ } catch(IllegalInetAddressException e) {
+ out.write(FtpReplyUtil.translate(session, 510, "PORT", null));
+ return;
+ } catch(IllegalPortException e) {
+ LOG.debug("Invalid data port: " + request.getArgument(), e);
+ out.write(FtpReplyUtil.translate(session, FtpReply.REPLY_552_REQUESTED_FILE_ACTION_ABORTED_EXCEEDED_STORAGE, "PORT.invalid", null));
+ return;
+ } catch(UnknownHostException e) {
+ LOG.debug("Unknown host", e);
out.write(FtpReplyUtil.translate(session, FtpReply.REPLY_553_REQUESTED_ACTION_NOT_TAKEN_FILE_NAME_NOT_ALLOWED, "PORT.host", null));
return;
}
@@ -104,26 +103,13 @@
// check IP
if(dataCfg.isActiveIpCheck()) {
InetAddress clientAddr = session.getClientAddress();
- if(!dataAddr.equals(clientAddr)) {
+ if(!address.getAddress().equals(clientAddr)) {
out.write(FtpReplyUtil.translate(session, 510, "PORT.mismatch", null));
return;
}
}
- // get data server port
- int dataPort = 0;
- try {
- int hi = Integer.parseInt(st.nextToken());
- int lo = Integer.parseInt(st.nextToken());
- dataPort = (hi << 8) | lo;
- }
- catch(NumberFormatException ex) {
- LOG.debug("Invalid data port: " + request.getArgument(), ex);
- out.write(FtpReplyUtil.translate(session, FtpReply.REPLY_552_REQUESTED_FILE_ACTION_ABORTED_EXCEEDED_STORAGE, "PORT.invalid", null));
- return;
- }
-
- session.getServerDataConnection().initActiveDataConnection(new InetSocketAddress(dataAddr, dataPort));
+ session.getServerDataConnection().initActiveDataConnection(address);
out.write(FtpReplyUtil.translate(session, FtpReply.REPLY_200_COMMAND_OKAY, "PORT", null));
}
Added: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalInetAddressException.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalInetAddressException.java?view=auto&rev=550099
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalInetAddressException.java (added)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalInetAddressException.java Sat Jun 23 13:32:53 2007
@@ -0,0 +1,46 @@
+/*
+ * 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.util;
+
+/**
+ * Thrown if the provided string representation does not match a valid IP address
+ */
+public class IllegalInetAddressException extends IllegalArgumentException {
+
+ private static final long serialVersionUID = -7771719692741419933L;
+
+ public IllegalInetAddressException() {
+ super();
+ }
+
+ public IllegalInetAddressException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public IllegalInetAddressException(String s) {
+ super(s);
+ }
+
+ public IllegalInetAddressException(Throwable cause) {
+ super(cause);
+ }
+
+
+}
Propchange: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalInetAddressException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalPortException.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalPortException.java?view=auto&rev=550099
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalPortException.java (added)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalPortException.java Sat Jun 23 13:32:53 2007
@@ -0,0 +1,46 @@
+/*
+ * 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.util;
+
+/**
+ * Thrown if the provided string representation does not match a valid IP port
+ */
+public class IllegalPortException extends IllegalArgumentException {
+
+ private static final long serialVersionUID = -7771719692741419931L;
+
+ public IllegalPortException() {
+ super();
+ }
+
+ public IllegalPortException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public IllegalPortException(String s) {
+ super(s);
+ }
+
+ public IllegalPortException(Throwable cause) {
+ super(cause);
+ }
+
+
+}
Propchange: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/IllegalPortException.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/SocketAddressEncoder.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/SocketAddressEncoder.java?view=auto&rev=550099
==============================================================================
--- incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/SocketAddressEncoder.java (added)
+++ incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/SocketAddressEncoder.java Sat Jun 23 13:32:53 2007
@@ -0,0 +1,86 @@
+/*
+ * 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.util;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+import java.util.StringTokenizer;
+
+/**
+ * Encodes and decodes socket addresses (IP and port) from and to the format
+ * used with for example the PORT and PASV command
+ */
+public class SocketAddressEncoder {
+
+ private static int convertAndValidateNumber(String s) {
+ int i = Integer.parseInt(s);
+ if(i < 0) {
+ throw new IllegalArgumentException("Token can not be less than 0");
+ } else if(i > 255) {
+ throw new IllegalArgumentException("Token can not be larger than 255");
+ }
+
+ return i;
+ }
+
+ public static InetSocketAddress decode(String str) throws UnknownHostException {
+ StringTokenizer st = new StringTokenizer(str, ",");
+ if(st.countTokens() != 6) {
+ throw new IllegalInetAddressException("Illegal amount of tokens");
+ }
+
+ StringBuffer sb = new StringBuffer();
+ try {
+ sb.append(convertAndValidateNumber(st.nextToken()));
+ sb.append('.');
+ sb.append(convertAndValidateNumber(st.nextToken()));
+ sb.append('.');
+ sb.append(convertAndValidateNumber(st.nextToken()));
+ sb.append('.');
+ sb.append(convertAndValidateNumber(st.nextToken()));
+ } catch(IllegalArgumentException e) {
+ throw new IllegalInetAddressException(e);
+ }
+
+ InetAddress dataAddr = InetAddress.getByName(sb.toString());
+
+
+ // get data server port
+ int dataPort = 0;
+ try {
+ int hi = convertAndValidateNumber(st.nextToken());
+ int lo = convertAndValidateNumber(st.nextToken());
+ dataPort = (hi << 8) | lo;
+ }
+ catch(IllegalArgumentException ex) {
+ throw new IllegalPortException("Invalid data port: " + str, ex);
+ }
+
+ return new InetSocketAddress(dataAddr, dataPort);
+ }
+
+ public static String encode(InetSocketAddress address) {
+ InetAddress servAddr = address.getAddress();
+ int servPort = address.getPort();
+ return servAddr.getHostAddress().replace( '.', ',' ) + ',' + (servPort>>8) + ',' + (servPort&0xFF);
+ }
+
+}
Propchange: incubator/ftpserver/trunk/core/src/java/org/apache/ftpserver/util/SocketAddressEncoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/SocketAddressEncoderTest.java
URL: http://svn.apache.org/viewvc/incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/SocketAddressEncoderTest.java?view=auto&rev=550099
==============================================================================
--- incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/SocketAddressEncoderTest.java (added)
+++ incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/SocketAddressEncoderTest.java Sat Jun 23 13:32:53 2007
@@ -0,0 +1,112 @@
+/*
+ * 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.util;
+
+import java.net.InetSocketAddress;
+
+import junit.framework.TestCase;
+
+public class SocketAddressEncoderTest extends TestCase {
+
+ public void testEncodeLowPort() {
+ InetSocketAddress address = new InetSocketAddress("localhost", 21);
+
+ assertEquals("127,0,0,1,0,21", SocketAddressEncoder.encode(address));
+ }
+
+ public void testEncodeHighPort() {
+ InetSocketAddress address = new InetSocketAddress("localhost", 21123);
+
+ assertEquals("127,0,0,1,82,131", SocketAddressEncoder.encode(address));
+ }
+
+ public void testEncodeIpNumber() {
+ InetSocketAddress address = new InetSocketAddress("1.2.3.4", 21);
+
+ assertEquals("1,2,3,4,0,21", SocketAddressEncoder.encode(address));
+ }
+
+ public void testDecodeLowPort() throws Exception {
+ InetSocketAddress address = new InetSocketAddress("1.2.3.4", 21);
+
+ assertEquals(address, SocketAddressEncoder.decode("1,2,3,4,0,21"));
+ }
+
+ public void testDecodeHighPort() throws Exception {
+ InetSocketAddress address = new InetSocketAddress("1.2.3.4", 21123);
+
+ assertEquals(address, SocketAddressEncoder.decode("1,2,3,4,82,131"));
+ }
+
+ public void testDecodeTooFewTokens() throws Exception {
+ try {
+ SocketAddressEncoder.decode("1,2,3,4,82");
+ fail("Must throw IllegalInetAddressException");
+ } catch(IllegalInetAddressException e) {
+ // OK
+ } catch(Exception e) {
+ fail("Must throw IllegalInetAddressException");
+ }
+ }
+
+ public void testDecodeTooManyTokens() throws Exception {
+ try {
+ SocketAddressEncoder.decode("1,2,3,4,82,1,2");
+ fail("Must throw IllegalInetAddressException");
+ } catch(IllegalInetAddressException e) {
+ // OK
+ } catch(Exception e) {
+ fail("Must throw IllegalInetAddressException");
+ }
+ }
+
+ public void testDecodeToHighPort() {
+ try {
+ SocketAddressEncoder.decode("1,2,3,4,820,2");
+ fail("Must throw IllegalPortException");
+ } catch(IllegalPortException e) {
+ // OK
+ } catch(Exception e) {
+ fail("Must throw IllegalPortException");
+ }
+ }
+
+ public void testDecodeIPTokenNotANumber() {
+ try {
+ SocketAddressEncoder.decode("foo,2,3,4,5,6");
+ fail("Must throw IllegalInetAddressException");
+ } catch(IllegalInetAddressException e) {
+ // OK
+ } catch(Exception e) {
+ fail("Must throw IllegalInetAddressException");
+ }
+ }
+
+ public void testDecodePortTokenNotANumber() {
+ try {
+ SocketAddressEncoder.decode("1,2,3,4,foo,6");
+ fail("Must throw IllegalPortException");
+ } catch(IllegalPortException e) {
+ // OK
+ } catch(Exception e) {
+ fail("Must throw IllegalPortException");
+ }
+ }
+}
\ No newline at end of file
Propchange: incubator/ftpserver/trunk/core/src/test/org/apache/ftpserver/util/SocketAddressEncoderTest.java
------------------------------------------------------------------------------
svn:eol-style = native