View Javadoc

1   /*
2    * ------------------------------------------------------------------------------
3    * Hermes FTP Server
4    * Copyright (c) 2005-2007 Lars Behnke
5    * ------------------------------------------------------------------------------
6    * 
7    * This file is part of Hermes FTP Server.
8    * 
9    * Hermes FTP Server is free software; you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as published by
11   * the Free Software Foundation; either version 2 of the License, or
12   * (at your option) any later version.
13   * 
14   * Hermes FTP Server is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public License
20   * along with Hermes FTP Server; if not, write to the Free Software
21   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22   * ------------------------------------------------------------------------------
23   */
24  
25  package net.sf.hermesftp.cmd.impl;
26  
27  import net.sf.hermesftp.cmd.AbstractFtpCmdPasv;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  /***
33   * <b>The EPSV Command (EPSV)</b>
34   * <p>
35   * The EPSV command requests that a server listen on a data port and wait for a connection. The EPSV
36   * command takes an optional argument. The response to this command includes only the TCP port
37   * number of the listening connection. The format of the response, however, is similar to the
38   * argument of the EPRT command. This allows the same parsing routines to be used for both commands.
39   * In addition, the format leaves a place holder for the network protocol and/or network address,
40   * which may be needed in the EPSV response in the future. The response code for entering passive
41   * mode using an extended address MUST be 229. The interpretation of this code, according to [PR85]
42   * is:
43   * </p>
44   * 
45   * <pre>
46   *   2yz Positive Completion
47   *   x2z Connections
48   *   xy9 Extended Passive Mode Entered
49   * </pre>
50   * 
51   * <p>
52   * The text returned in response to the EPSV command MUST be:
53   * </p>
54   * 
55   * <pre>
56   *   &lt;text indicating server is entering extended passive mode&gt; 
57   *   (&lt;d&gt;&lt;d&gt;&lt;d&gt;&lt;tcp-port&gt;&lt;d&gt;)
58   * </pre>
59   * 
60   * <p>
61   * The portion of the string enclosed in parentheses MUST be the exact string needed by the EPRT
62   * command to open the data connection, as specified above.
63   * </p>
64   * <p>
65   * The first two fields contained in the parenthesis MUST be blank. The third field MUST be the
66   * string representation of the TCP port number on which the server is listening for a data
67   * connection. The network protocol used by the data connection will be the same network protocol
68   * used by the control connection. In addition, the network address used to establish the data
69   * connection will be the same network address used for the control connection. An example response
70   * string follows:
71   * </p>
72   * 
73   * <pre>
74   *   Entering Extended Passive Mode (|||6446|)
75   * </pre>
76   * 
77   * <p>
78   * The standard negative error codes 500 and 501 are sufficient to handle all errors involving the
79   * EPSV command (e.g., syntax errors). When the EPSV command is issued with no argument, the server
80   * will choose the network protocol for the data connection based on the protocol used for the
81   * control connection. However, in the case of proxy FTP, this protocol might not be appropriate for
82   * communication between the two servers. Therefore, the client needs to be able to request a
83   * specific protocol. If the server returns a protocol that is not supported by the host that will
84   * be connecting to the port, the client MUST issue an ABOR (abort) command to allow the server to
85   * close down the listening connection. The client can then send an EPSV command requesting the use
86   * of a specific network protocol, as follows:
87   * </p>
88   * 
89   * <pre>
90   *   EPSV&lt;space&gt;&lt;net-prt&gt;
91   * </pre>
92   * 
93   * <p>
94   * If the requested protocol is supported by the server, it SHOULD use the protocol. If not, the
95   * server MUST return the 522 error messages as outlined in section 2.
96   * </p>
97   * <p>
98   * Finally, the EPSV command can be used with the argument "ALL" to inform Network Address
99   * Translators that the EPRT command (as well as other data commands) will no longer be used. An
100  * example of this command follows:
101  * </p>
102  * <p>
103  * EPSV&lt;space&gt;ALL
104  * </p>
105  * <p>
106  * Upon receipt of an EPSV ALL command, the server MUST reject all data connection setup commands
107  * other than EPSV (i.e., EPRT, PORT, PASV, et al.). This use of the EPSV command is further
108  * explained in section 4.
109  * </p>
110  * <p>
111  * <i>[Excerpt from RFC-2428, Allman]</i>
112  * </p>
113  */
114 public class FtpCmdEpsv extends AbstractFtpCmdPasv {
115 
116     private static Log log = LogFactory.getLog(FtpCmdEpsv.class);
117 
118     /***
119      * {@inheritDoc}
120      */
121     protected String createResponseMessage(int protocolIdx, String ip, int port) {
122         return msg(MSG229, new String[] {"" + port});
123     }
124 
125     /***
126      * {@inheritDoc}
127      */
128     public String getHelp() {
129         return "Activates the extended passive transfer mode";
130     }
131 
132     /***
133      * {@inheritDoc}
134      */
135     protected int getPreferredProtocol() {
136         int result = 0;
137         String args = getArguments();
138         if (args != null && args.length() > 0) {
139             try {
140                 result = Integer.parseInt(args.trim());
141             } catch (Exception e) {
142                 log.warn("Invalid argument for EPSV: " + getArguments());
143             }
144         }
145         return result;
146     }
147 
148 }