88import java .io .InputStream ;
99import java .nio .file .Path ;
1010import java .nio .file .Paths ;
11+ import java .security .GeneralSecurityException ;
12+ import java .security .KeyStore ;
13+
14+ import javax .net .ssl .X509TrustManager ;
1115
1216import org .apache .commons .net .ftp .FTP ;
1317import org .apache .commons .net .ftp .FTPReply ;
1418import org .apache .commons .net .ftp .FTPSClient ;
19+ import org .apache .commons .net .util .TrustManagerUtils ;
1520
1621import com .genexus .commons .ftps .FtpsClientObject ;
1722import com .genexus .ftps .utils .FtpConnectionMode ;
23+ import com .genexus .securityapicommons .utils .ExtensionsWhiteList ;
1824import com .genexus .securityapicommons .utils .SecurityUtils ;
1925
2026public class FtpsClient extends FtpsClientObject {
2127
2228 private FTPSClient client ;
2329 private String pwd ;
30+ private ExtensionsWhiteList whiteList ;
2431
2532 public FtpsClient () {
2633 super ();
2734 this .client = null ;
35+ this .whiteList = null ;
2836 }
2937
3038 /******** EXTERNAL OBJECT PUBLIC METHODS - BEGIN ********/
@@ -38,8 +46,14 @@ public boolean connect(FtpsOptions options) {
3846 this .error .setError ("FS001" , "Empty connection data" );
3947 return false ;
4048 }
41-
49+
4250 setProtocol (options );
51+
52+ if (!SecurityUtils .compareStrings ("" , options .getTrustStorePath ())) {
53+ if (!setCertificateValidation (options )) {
54+ return false ;
55+ }
56+ }
4357 try {
4458 this .client .connect (options .getHost (), options .getPort ());
4559 if (options .getForceEncryption ()) {
@@ -51,9 +65,8 @@ public boolean connect(FtpsOptions options) {
5165 return false ;
5266 }
5367 boolean login = this .client .login (options .getUser (), options .getPassword ());
54- if (!login )
55- {
56- this .error .setError ("FS0016" , "Login error" );
68+ if (!login ) {
69+ this .error .setError ("FS0016" , "Login error" );
5770 return false ;
5871 }
5972 setEncoding (options );
@@ -68,11 +81,18 @@ public boolean connect(FtpsOptions options) {
6881 this .error .setError ("FS009" , "Connection error" );
6982 return false ;
7083 }
71-
84+ this . whiteList = options . getWhiteList ();
7285 return true ;
7386 }
7487
7588 public boolean put (String localPath , String remoteDir ) {
89+ if (this .whiteList != null ) {
90+ if (!this .whiteList .isValid (localPath )) {
91+ this .error .setError ("WL001" , "Invalid file extension" );
92+ return false ;
93+ }
94+ }
95+
7696 if (this .client == null || !this .client .isConnected ()
7797 || !FTPReply .isPositiveCompletion (this .client .getReplyCode ())) {
7898 this .error .setError ("FS003" , "The connection is invalid, reconect" );
@@ -118,6 +138,12 @@ public boolean put(String localPath, String remoteDir) {
118138 }
119139
120140 public boolean get (String remoteFilePath , String localDir ) {
141+ if (this .whiteList != null ) {
142+ if (!this .whiteList .isValid (remoteFilePath )) {
143+ this .error .setError ("WL002" , "Invalid file extension" );
144+ return false ;
145+ }
146+ }
121147 if (this .client == null || !this .client .isConnected ()) {
122148 this .error .setError ("FS010" , "The connection is invalid, reconect" );
123149 return false ;
@@ -184,8 +210,7 @@ public String getWorkingDirectory() {
184210 this .error .setError ("FS006" , "Could not obtain working directory, try reconnect" );
185211 return "" ;
186212 }
187- if (pwd == null )
188- {
213+ if (pwd == null ) {
189214 return this .pwd ;
190215 }
191216 return pwd ;
@@ -247,24 +272,21 @@ private static void copyInputStreamToFile(InputStream inputStream, File file) th
247272 }
248273
249274 }
250-
251- private void setEncoding (FtpsOptions options ) throws IOException
252- {
253- switch (options .getFtpEncoding ())
254- {
275+
276+ private void setEncoding (FtpsOptions options ) throws IOException {
277+ switch (options .getFtpEncoding ()) {
255278 case BINARY :
256279 this .client .setFileType (FTP .BINARY_FILE_TYPE );
257280 break ;
258281 case ASCII :
259282 this .client .sendCommand (FTP .ASCII_FILE_TYPE );
260283 break ;
261- default :
262- this .client .setFileType (FTP .BINARY_FILE_TYPE );
284+ default :
285+ this .client .setFileType (FTP .BINARY_FILE_TYPE );
263286 }
264287 }
265-
266- private void setConnectionMode (FtpsOptions options )
267- {
288+
289+ private void setConnectionMode (FtpsOptions options ) {
268290 FtpConnectionMode mode = options .getFtpConnectionMode ();
269291 switch (mode ) {
270292 case ACTIVE :
@@ -273,15 +295,13 @@ private void setConnectionMode(FtpsOptions options)
273295 case PASSIVE :
274296 this .client .enterLocalPassiveMode ();
275297 break ;
276- default :
277- this .client .enterLocalPassiveMode ();
298+ default :
299+ this .client .enterLocalPassiveMode ();
278300 }
279301 }
280-
281- private void setProtocol (FtpsOptions options )
282- {
283- switch (options .getFtpsProtocol ())
284- {
302+
303+ private void setProtocol (FtpsOptions options ) {
304+ switch (options .getFtpsProtocol ()) {
285305 case TLS1_0 :
286306 this .client = new FTPSClient ("TLS" , isImplicit (options ));
287307 break ;
@@ -301,18 +321,37 @@ private void setProtocol(FtpsOptions options)
301321 this .client = new FTPSClient ("TLS" , isImplicit (options ));
302322 }
303323 }
304-
305- private boolean isImplicit (FtpsOptions options )
306- {
307- switch (options .getFtpEncryptionMode ())
308- {
324+
325+ private boolean isImplicit (FtpsOptions options ) {
326+ switch (options .getFtpEncryptionMode ()) {
309327 case EXPLICIT :
310328 return false ;
311329 case IMPLICIT :
312330 return true ;
313- default :
314- return false ;
331+ default :
332+ return false ;
315333 }
316334 }
317335
336+ private boolean setCertificateValidation (FtpsOptions options ) {
337+ X509TrustManager trustManager = null ;
338+ KeyStore keyStore = null ;
339+ InputStream in = null ;
340+ try {
341+ in = SecurityUtils .inputFileToStream (options .getTrustStorePath ());
342+ keyStore = KeyStore .getInstance ("PKCS12" );
343+ keyStore .load (in , options .getTrustStorePassword ().toCharArray ());
344+ trustManager = TrustManagerUtils .getDefaultTrustManager (keyStore );
345+ } catch (IOException | GeneralSecurityException e ) {
346+ this .error .setError ("FS017" , "Could not load trust store" );
347+ return false ;
348+ }
349+ if (trustManager == null ) {
350+ this .error .setError ("FS018" , "Could not load trust store" );
351+ return false ;
352+ }
353+ client .setTrustManager (trustManager );
354+ return true ;
355+ }
356+
318357}
0 commit comments