1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.net.ftp;
19
20 import static org.junit.jupiter.api.Assertions.assertEquals;
21 import static org.junit.jupiter.api.Assertions.assertNotNull;
22 import static org.junit.jupiter.api.Assertions.assertTrue;
23
24 import java.io.File;
25 import java.io.IOException;
26 import java.net.SocketException;
27 import java.net.URL;
28 import java.time.Duration;
29
30 import org.apache.commons.io.FileUtils;
31 import org.apache.commons.io.output.NullOutputStream;
32 import org.apache.commons.lang3.ThreadUtils;
33 import org.apache.commons.net.PrintCommandListener;
34 import org.apache.ftpserver.FtpServer;
35 import org.apache.ftpserver.FtpServerFactory;
36 import org.apache.ftpserver.ftplet.FtpException;
37 import org.apache.ftpserver.ftplet.UserManager;
38 import org.apache.ftpserver.listener.ListenerFactory;
39 import org.apache.ftpserver.ssl.SslConfiguration;
40 import org.apache.ftpserver.ssl.SslConfigurationFactory;
41 import org.apache.ftpserver.usermanager.Md5PasswordEncryptor;
42 import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
43 import org.apache.ftpserver.usermanager.impl.BaseUser;
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 public abstract class AbstractFtpsTest {
59
60 private static int SocketPort;
61 private static FtpServer EmbeddedFtpServer;
62 protected static final boolean IMPLICIT = false;
63 protected static final long TEST_TIMEOUT = 10000;
64 private static final boolean TRACE_CALLS = Boolean.parseBoolean(System.getenv("TRACE_CALLS"));
65 private static final boolean ADD_LISTENER = Boolean.parseBoolean(System.getenv("ADD_LISTENER"));
66 private static final long startTime = System.nanoTime();
67
68
69
70
71
72
73 protected static String getTestHomeDirectory(final String defaultHome) {
74 return System.getProperty("test.basedir", defaultHome);
75 }
76
77
78
79
80
81
82
83
84
85
86 protected static synchronized void setupServer(final boolean implicit, final String userPropertiesResource, final String serverJksResourceResource,
87 final String defaultHome) throws FtpException {
88 if (EmbeddedFtpServer != null) {
89 return;
90 }
91
92 SocketPort = 0;
93 final FtpServerFactory serverFactory = new FtpServerFactory();
94 final PropertiesUserManagerFactory propertiesUserManagerFactory = new PropertiesUserManagerFactory();
95
96 propertiesUserManagerFactory.setPasswordEncryptor(new Md5PasswordEncryptor());
97 final URL userPropsResource = ClassLoader.getSystemClassLoader().getResource(userPropertiesResource);
98 assertNotNull(userPropsResource, userPropertiesResource);
99 propertiesUserManagerFactory.setUrl(userPropsResource);
100 final UserManager userManager = propertiesUserManagerFactory.createUserManager();
101 final BaseUser user = (BaseUser) userManager.getUserByName("test");
102
103
104 user.setHomeDirectory(getTestHomeDirectory(defaultHome));
105 serverFactory.setUserManager(userManager);
106 final ListenerFactory factory = new ListenerFactory();
107 factory.setPort(SocketPort);
108
109
110 final URL serverJksResource = ClassLoader.getSystemClassLoader().getResource(serverJksResourceResource);
111 assertNotNull(serverJksResource, serverJksResourceResource);
112
113 final SslConfigurationFactory sllConfigFactory = new SslConfigurationFactory();
114 final File keyStoreFile = FileUtils.toFile(serverJksResource);
115 assertTrue(keyStoreFile.exists(), keyStoreFile.toString());
116 sllConfigFactory.setKeystoreFile(keyStoreFile);
117 sllConfigFactory.setKeystorePassword("password");
118
119
120 final SslConfiguration sslConfiguration = sllConfigFactory.createSslConfiguration();
121 final NoProtocolSslConfigurationProxy noProtocolSslConfigurationProxy = new NoProtocolSslConfigurationProxy(sslConfiguration);
122 factory.setSslConfiguration(noProtocolSslConfigurationProxy);
123 factory.setImplicitSsl(implicit);
124
125
126 serverFactory.addListener("default", factory.createListener());
127
128
129 EmbeddedFtpServer = serverFactory.createServer();
130 EmbeddedFtpServer.start();
131 SocketPort = ((org.apache.ftpserver.impl.DefaultFtpServer) EmbeddedFtpServer).getListener("default").getPort();
132
133 trace("Server started");
134 }
135
136 protected static void trace(final String msg) {
137 if (TRACE_CALLS) {
138 System.err.println(msg + " " + (System.nanoTime() - startTime));
139 }
140 }
141
142 private boolean endpointCheckingEnabled;
143
144 protected void assertClientCode(final FTPSClient client) {
145 final int replyCode = client.getReplyCode();
146 assertTrue(FTPReply.isPositiveCompletion(replyCode));
147 }
148
149 protected FTPSClient loginClient() throws SocketException, IOException {
150 trace(">>loginClient");
151 final FTPSClient client = new FTPSClient(IMPLICIT);
152 if (ADD_LISTENER) {
153 client.addProtocolCommandListener(new PrintCommandListener(System.err));
154 }
155
156 client.setControlKeepAliveReplyTimeout(null);
157 assertEquals(0, client.getControlKeepAliveReplyTimeoutDuration().getSeconds());
158 client.setControlKeepAliveReplyTimeout(Duration.ofSeconds(60));
159 assertEquals(60, client.getControlKeepAliveReplyTimeoutDuration().getSeconds());
160
161 client.setControlKeepAliveTimeout(null);
162 assertEquals(0, client.getControlKeepAliveTimeoutDuration().getSeconds());
163 client.setControlKeepAliveTimeout(Duration.ofSeconds(61));
164 assertEquals(61, client.getControlKeepAliveTimeoutDuration().getSeconds());
165
166 client.setDataTimeout(null);
167 assertEquals(0, client.getDataTimeout().getSeconds());
168 client.setDataTimeout(Duration.ofSeconds(62));
169 assertEquals(62, client.getDataTimeout().getSeconds());
170
171 client.setEndpointCheckingEnabled(endpointCheckingEnabled);
172 client.connect("localhost", SocketPort);
173
174 assertClientCode(client);
175 assertEquals(SocketPort, client.getRemotePort());
176
177
178
179 ThreadUtils.sleepQuietly(Duration.ofMillis(200));
180 assertTrue(client.login("test", "test"));
181 assertClientCode(client);
182
183 client.setFileType(FTP.BINARY_FILE_TYPE);
184 assertClientCode(client);
185
186 client.execPBSZ(0);
187 assertClientCode(client);
188
189 client.execPROT("P");
190 assertClientCode(client);
191 trace("<<loginClient");
192 return client;
193 }
194
195 protected void retrieveFile(final String pathname) throws SocketException, IOException {
196 final FTPSClient client = loginClient();
197 try {
198
199
200 assertTrue(client.retrieveFile(pathname, NullOutputStream.INSTANCE), pathname);
201 assertTrue(client.retrieveFile(pathname, NullOutputStream.INSTANCE), pathname);
202 } finally {
203 client.disconnect();
204 }
205 }
206
207 public void setEndpointCheckingEnabled(final boolean value) {
208 this.endpointCheckingEnabled = value;
209 }
210 }