1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.vfs2.provider.ftps;
18
19 import static org.apache.commons.vfs2.VfsTestUtils.getTestDirectory;
20
21 import java.io.File;
22 import java.net.URL;
23 import java.time.Duration;
24
25 import org.apache.commons.io.FileUtils;
26 import org.apache.commons.vfs2.AbstractProviderTestConfig;
27 import org.apache.commons.vfs2.FileObject;
28 import org.apache.commons.vfs2.FileSystemManager;
29 import org.apache.commons.vfs2.FileSystemOptions;
30 import org.apache.commons.vfs2.ProviderTestSuite;
31 import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
32 import org.apache.ftpserver.FtpServer;
33 import org.apache.ftpserver.FtpServerFactory;
34 import org.apache.ftpserver.ftplet.FtpException;
35 import org.apache.ftpserver.ftplet.UserManager;
36 import org.apache.ftpserver.listener.ListenerFactory;
37 import org.apache.ftpserver.ssl.SslConfiguration;
38 import org.apache.ftpserver.ssl.SslConfigurationFactory;
39 import org.apache.ftpserver.usermanager.Md5PasswordEncryptor;
40 import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
41 import org.apache.ftpserver.usermanager.impl.BaseUser;
42 import org.junit.jupiter.api.Assertions;
43
44
45
46
47 abstract class AbstractFtpsProviderTestCase extends AbstractProviderTestConfig {
48
49 static final class FtpProviderTestSuite extends ProviderTestSuite {
50
51 private final boolean implicit;
52
53 public FtpProviderTestSuite(final AbstractFtpsProviderTestCase providerConfig) throws Exception {
54 super(providerConfig);
55 implicit = providerConfig.isImplicit();
56 }
57
58 @Override
59 protected void setUp() throws Exception {
60 if (getSystemTestUriOverride() == null) {
61 setUpClass(implicit);
62 }
63 super.setUp();
64 }
65
66 @Override
67 protected void tearDown() throws Exception {
68 try {
69
70
71
72
73 super.tearDown();
74 } finally {
75 tearDownClass();
76 }
77 }
78 }
79
80 private static final String LISTENER_NAME = "default";
81
82 private static int socketPort;
83
84
85
86
87 private static String connectionUri;
88
89 private static FtpServer embeddedFtpServer;
90
91 private static final String TEST_URI = "test.ftps.uri";
92
93 private static final String USER_PROPS_RES = "org.apache.ftpsserver/users.properties";
94
95 private static final String SERVER_JKS_RES = "org.apache.ftpsserver/ftpserver.jks";
96
97 static String getConnectionUri() {
98 return connectionUri;
99 }
100
101 static int getSocketPort() {
102 return socketPort;
103 }
104
105 static String getSystemTestUriOverride() {
106 return System.getProperty(TEST_URI);
107 }
108
109
110
111
112
113
114
115 synchronized static void setUpClass(final boolean implicit) throws FtpException {
116 if (embeddedFtpServer != null) {
117 return;
118 }
119
120 socketPort = 0;
121 final FtpServerFactory serverFactory = new FtpServerFactory();
122 final PropertiesUserManagerFactory propertiesUserManagerFactory = new PropertiesUserManagerFactory();
123
124 propertiesUserManagerFactory.setPasswordEncryptor(new Md5PasswordEncryptor());
125 final URL userPropsResource = ClassLoader.getSystemClassLoader().getResource(USER_PROPS_RES);
126 Assertions.assertNotNull(userPropsResource, USER_PROPS_RES);
127 propertiesUserManagerFactory.setUrl(userPropsResource);
128 final UserManager userManager = propertiesUserManagerFactory.createUserManager();
129 final BaseUser user = (BaseUser) userManager.getUserByName("test");
130
131
132 user.setHomeDirectory(getTestDirectory());
133 serverFactory.setUserManager(userManager);
134 final ListenerFactory listenerFactory = new ListenerFactory();
135 listenerFactory.setPort(socketPort);
136
137
138 final URL serverJksResource = ClassLoader.getSystemClassLoader().getResource(SERVER_JKS_RES);
139 Assertions.assertNotNull(serverJksResource, SERVER_JKS_RES);
140
141 final SslConfigurationFactory sllConfigFactory = new SslConfigurationFactory();
142 final File keyStoreFile = FileUtils.toFile(serverJksResource);
143 Assertions.assertTrue(keyStoreFile.exists(), keyStoreFile.toString());
144 sllConfigFactory.setKeystoreFile(keyStoreFile);
145 sllConfigFactory.setKeystorePassword("password");
146
147
148 final SslConfiguration sslConfiguration = sllConfigFactory.createSslConfiguration();
149 final NoProtocolSslConfigurationProxy noProtocolSslConfigurationProxy = new NoProtocolSslConfigurationProxy(sslConfiguration);
150 listenerFactory.setSslConfiguration(noProtocolSslConfigurationProxy);
151 listenerFactory.setImplicitSsl(implicit);
152
153
154 serverFactory.addListener(LISTENER_NAME, listenerFactory.createListener());
155
156
157 embeddedFtpServer = serverFactory.createServer();
158 embeddedFtpServer.start();
159 Thread.yield();
160 if (embeddedFtpServer.isStopped() || embeddedFtpServer.isSuspended()) {
161 try {
162 Thread.sleep(200);
163 } catch (final InterruptedException e) {
164 e.printStackTrace();
165 }
166 }
167 socketPort = ((org.apache.ftpserver.impl.DefaultFtpServer) embeddedFtpServer).getListener(LISTENER_NAME).getPort();
168
169
170 connectionUri = "ftps://test:test@localhost:" + socketPort;
171 }
172
173
174
175
176 synchronized static void tearDownClass() {
177 if (embeddedFtpServer != null) {
178 embeddedFtpServer.suspend();
179 embeddedFtpServer.stop();
180 Thread.yield();
181 int count = 10;
182 while (count-- > 0 && !embeddedFtpServer.isStopped()) {
183 final int millis = 200;
184 System.out.println(String.format("Waiting %,d milliseconds for %s to stop", millis, embeddedFtpServer));
185 try {
186 Thread.sleep(millis);
187 } catch (final InterruptedException e) {
188 e.printStackTrace();
189 }
190 }
191 embeddedFtpServer = null;
192 }
193 }
194
195 protected FileSystemOptions fileSystemOptions;
196
197
198
199
200 @Override
201 public FileObject getBaseTestFolder(final FileSystemManager manager) throws Exception {
202 String uri = getSystemTestUriOverride();
203 if (uri == null) {
204 uri = connectionUri;
205 }
206 return manager.resolveFile(uri, getFileSystemOptions());
207 }
208
209 protected FileSystemOptions getFileSystemOptions() {
210 if (fileSystemOptions == null) {
211 fileSystemOptions = new FileSystemOptions();
212 setupOptions(FtpsFileSystemConfigBuilder.getInstance());
213 }
214 return fileSystemOptions;
215 }
216
217 protected abstract boolean isImplicit();
218
219
220
221
222 @Override
223 public void prepare(final DefaultFileSystemManager manager) throws Exception {
224 manager.addProvider("ftps", new FtpsFileProvider());
225 }
226
227 protected void setupOptions(final FtpsFileSystemConfigBuilder builder) {
228 builder.setConnectTimeout(fileSystemOptions, Duration.ofSeconds(10));
229 builder.setDataTimeout(fileSystemOptions, Duration.ofSeconds(10));
230 }
231
232 }