NET-611 FTP does not validate command reply syntax fully
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/net/trunk@1782002 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 2a42c65..d745052 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -63,7 +63,30 @@
-->
<body>
- <release version="3.6" date="TBA" description="">
+ <release version="3.6" date="TBA" description="
+This is mainly a bug-fix release. See further details below.
+
+
+ This release is binary compatible with previous releases.
+ However it is not source compatible with releases before 3.4, as some methods were added to the interface NtpV3Packet in 3.4
+
+ The code now requires a minimum of Java 1.6.
+
+ Changes to functionality:
+ The FTP client now performs stricter checks on non-multiline command replies.
+ The 3 digit code must now be followed by a space and some text, as per RFC 959.
+ To suppress this stricter checking, call FTP#setStrictReplyParsing(false). This should not be needed with a well-behaved server.
+ Note also that if strict checking is disabled, some functions may unconditionally strip the next character after the code,
+without checking it if is a space.
+
+
+ Notable additions:
+ The POP3Mail examples can now get password from console, stdin or an environment variable.
+
+">
+ <action issue="NET-611" type="fix" dev="sebb">
+ FTP does not validate command reply syntax fully
+ </action>
<action issue="NET-609" type="fix" dev="sebb" due-to="Tqup3">
DefaultUnixFTPFileEntryParserFactory Issue (leading spaces removal configuration)
</action>
diff --git a/src/main/java/org/apache/commons/net/ftp/FTP.java b/src/main/java/org/apache/commons/net/ftp/FTP.java
index 0ded5a0..bac6d7d 100644
--- a/src/main/java/org/apache/commons/net/ftp/FTP.java
+++ b/src/main/java/org/apache/commons/net/ftp/FTP.java
@@ -236,6 +236,14 @@
protected boolean strictMultilineParsing = false;
/**
+ * If this is true, then non-multiline replies must have the format:
+ * 3 digit code <space> <text>
+ * If false, then the 3 digit code does not have to be followed by space
+ * See section 4.2 of RFC 959 for details.
+ */
+ private boolean strictReplyParsing = true;
+
+ /**
* Wraps SocketClient._input_ to facilitate the reading of text
* from the FTP control connection. Do not access the control
* connection via SocketClient._input_. This member starts
@@ -339,25 +347,37 @@
_replyLines.add(line);
- // Get extra lines if message continues.
- if (length > REPLY_CODE_LEN && line.charAt(REPLY_CODE_LEN) == '-')
- {
- do
- {
- line = _controlInput_.readLine();
+ // Check the server reply type
+ if (length > REPLY_CODE_LEN) {
+ char sep = line.charAt(REPLY_CODE_LEN);
+ // Get extra lines if message continues.
+ if (sep == '-') {
+ do
+ {
+ line = _controlInput_.readLine();
- if (line == null) {
- throw new FTPConnectionClosedException(
- "Connection closed without indication.");
+ if (line == null) {
+ throw new FTPConnectionClosedException(
+ "Connection closed without indication.");
+ }
+
+ _replyLines.add(line);
+
+ // The length() check handles problems that could arise from readLine()
+ // returning too soon after encountering a naked CR or some other
+ // anomaly.
}
+ while ( isStrictMultilineParsing() ? __strictCheck(line, code) : __lenientCheck(line));
- _replyLines.add(line);
-
- // The length() check handles problems that could arise from readLine()
- // returning too soon after encountering a naked CR or some other
- // anomaly.
+ } else if (isStrictReplyParsing()) {
+ if (length == REPLY_CODE_LEN + 1) { // expecting some text
+ throw new MalformedServerReplyException("Truncated server reply: '" + line +"'");
+ } else if (sep != ' ') {
+ throw new MalformedServerReplyException("Invalid server reply: '" + line +"'");
+ }
}
- while ( isStrictMultilineParsing() ? __strictCheck(line, code) : __lenientCheck(line));
+ } else if (isStrictReplyParsing()) {
+ throw new MalformedServerReplyException("Truncated server reply: '" + line +"'");
}
if (reportReply) {
@@ -1803,6 +1823,36 @@
}
/**
+ * Return whether strict non-multiline parsing is enabled, as per RFC 959, section 4.2.
+ * <p>
+ * The default is true, which requires the 3 digit code be followed by space and some text.
+ * <br>
+ * If false, only the 3 digit code is required (as was the case for versions up to 3.5)
+ * <br>
+ * @return True if strict (default), false if additional checks are not made
+ * @since 3.6
+ */
+ public boolean isStrictReplyParsing() {
+ return strictReplyParsing;
+ }
+
+ /**
+ * Set strict non-multiline parsing.
+ * <p>
+ * If true, it requires the 3 digit code be followed by space and some text.
+ * <br>
+ * If false, only the 3 digit code is required (as was the case for versions up to 3.5)
+ * <p>
+ * <b>This should not be required by a well-behaved FTP server</b>
+ * <br>
+ * @param strictReplyParsing the setting
+ * @since 3.6
+ */
+ public void setStrictReplyParsing(boolean strictReplyParsing) {
+ this.strictReplyParsing = strictReplyParsing;
+ }
+
+ /**
* Provide command support to super-class
*/
@Override