1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 * <text indicating server is entering extended passive mode>
57 * (<d><d><d><tcp-port><d>)
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<space><net-prt>
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<space>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 }