View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  
21  package org.waarp.gateway.ftp.config;
22  
23  import io.netty.bootstrap.ServerBootstrap;
24  import io.netty.channel.ChannelFuture;
25  import io.netty.channel.EventLoopGroup;
26  import io.netty.channel.group.ChannelGroup;
27  import io.netty.channel.group.ChannelGroupFuture;
28  import io.netty.channel.group.ChannelGroupFutureListener;
29  import io.netty.channel.group.DefaultChannelGroup;
30  import io.netty.channel.nio.NioEventLoopGroup;
31  import io.netty.handler.traffic.AbstractTrafficShapingHandler;
32  import io.netty.util.concurrent.EventExecutorGroup;
33  import org.dom4j.Document;
34  import org.dom4j.DocumentException;
35  import org.waarp.common.crypto.Des;
36  import org.waarp.common.crypto.ssl.WaarpSecureKeyStore;
37  import org.waarp.common.crypto.ssl.WaarpSslContextFactory;
38  import org.waarp.common.database.DbAdmin;
39  import org.waarp.common.database.DbPreparedStatement;
40  import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
41  import org.waarp.common.database.exception.WaarpDatabaseSqlException;
42  import org.waarp.common.exception.CryptoException;
43  import org.waarp.common.exception.InvalidArgumentException;
44  import org.waarp.common.file.AbstractDir;
45  import org.waarp.common.file.DirInterface;
46  import org.waarp.common.file.FileParameterInterface;
47  import org.waarp.common.file.filesystembased.FilesystemBasedFileParameterImpl;
48  import org.waarp.common.file.filesystembased.specific.FilesystemBasedDirJdkAbstract;
49  import org.waarp.common.logging.WaarpLogger;
50  import org.waarp.common.logging.WaarpLoggerFactory;
51  import org.waarp.common.utility.WaarpNettyUtil;
52  import org.waarp.common.utility.WaarpStringUtils;
53  import org.waarp.common.utility.WaarpThreadFactory;
54  import org.waarp.common.xml.XmlDecl;
55  import org.waarp.common.xml.XmlHash;
56  import org.waarp.common.xml.XmlType;
57  import org.waarp.common.xml.XmlUtil;
58  import org.waarp.common.xml.XmlValue;
59  import org.waarp.ftp.core.config.FtpConfiguration;
60  import org.waarp.ftp.core.control.BusinessHandler;
61  import org.waarp.ftp.core.control.ftps.FtpsInitializer;
62  import org.waarp.ftp.core.data.handler.DataBusinessHandler;
63  import org.waarp.ftp.core.exception.FtpNoConnectionException;
64  import org.waarp.ftp.core.exception.FtpUnknownFieldException;
65  import org.waarp.gateway.ftp.adminssl.HttpSslInitializer;
66  import org.waarp.gateway.ftp.control.FtpConstraintLimitHandler;
67  import org.waarp.gateway.ftp.database.DbConstantFtp;
68  import org.waarp.gateway.ftp.database.data.DbTransferLog;
69  import org.waarp.gateway.ftp.database.model.DbModelFactoryFtp;
70  import org.waarp.gateway.ftp.exec.AbstractExecutor;
71  import org.waarp.gateway.ftp.exec.LocalExecClient;
72  import org.waarp.gateway.ftp.file.SimpleAuth;
73  import org.waarp.gateway.ftp.snmp.FtpMonitoring;
74  import org.waarp.gateway.ftp.snmp.FtpPrivateMib;
75  import org.waarp.gateway.ftp.snmp.FtpVariableFactory;
76  import org.waarp.snmp.SnmpConfiguration;
77  import org.waarp.snmp.WaarpMOFactory;
78  import org.waarp.snmp.WaarpSnmpAgent;
79  
80  import java.io.File;
81  import java.io.IOException;
82  import java.io.InvalidObjectException;
83  import java.net.InetAddress;
84  import java.net.InetSocketAddress;
85  import java.net.UnknownHostException;
86  import java.util.Arrays;
87  import java.util.Enumeration;
88  import java.util.List;
89  import java.util.concurrent.ConcurrentHashMap;
90  
91  /**
92   * FtpConfiguration based on a XML file
93   */
94  public class FileBasedConfiguration extends FtpConfiguration {
95    private static final String ERROR_DURING_WRITE_AUTHENTICATION_FILE =
96        "Error during Write Authentication file";
97  
98    private static final String UNABLE_TO_FIND_LOCAL_EXEC_ADDRESS_IN_CONFIG_FILE =
99        "Unable to find LocalExec Address in Config file";
100 
101   /**
102    * Internal Logger
103    */
104   private static final WaarpLogger logger =
105       WaarpLoggerFactory.getLogger(FileBasedConfiguration.class);
106 
107   /**
108    * SERVER HOSTID
109    */
110   private static final String XML_SERVER_HOSTID = "hostid";
111   /**
112    * Authentication
113    */
114   private static final String XML_AUTHENTIFICATION_FILE = "authentfile";
115   /**
116    * SERVER CRYPTO for Password
117    */
118   private static final String XML_PATH_CRYPTOKEY = "cryptokey";
119 
120   /**
121    * Structure of the Configuration file
122    */
123   private static final XmlDecl[] configIdentityDecls = {
124       // identity
125       new XmlDecl(XmlType.STRING, XML_SERVER_HOSTID),
126       new XmlDecl(XmlType.STRING, XML_PATH_CRYPTOKEY),
127       new XmlDecl(XmlType.STRING, XML_AUTHENTIFICATION_FILE)
128   };
129   /**
130    * Use HTTP compression for R66 HTTP connection
131    */
132   private static final String XML_USEHTTPCOMP = "usehttpcomp";
133   /**
134    * Use external Waarp Local Exec for ExecTask and ExecMoveTask
135    */
136   private static final String XML_USELOCALEXEC = "uselocalexec";
137 
138   /**
139    * Address of Waarp Local Exec for ExecTask and ExecMoveTask
140    */
141   private static final String XML_LEXECADDR = "lexecaddr";
142 
143   /**
144    * Port of Waarp Local Exec for ExecTask and ExecMoveTask
145    */
146   private static final String XML_LEXECPORT = "lexecport";
147   /**
148    * ADMINISTRATOR SERVER NAME (shutdown)
149    */
150   private static final String XML_SERVER_ADMIN = "serveradmin";
151   /**
152    * SERVER PASSWORD (shutdown)
153    */
154   private static final String XML_SERVER_PASSWD = "serverpasswd"; //NOSONAR
155   /**
156    * SERVER SSL STOREKEY PATH ADMIN
157    */
158   private static final String XML_PATH_ADMIN_KEYPATH = "admkeypath";
159 
160   /**
161    * SERVER SSL KEY PASS ADMIN
162    */
163   private static final String XML_PATH_ADMIN_KEYPASS = "admkeypass";
164 
165   /**
166    * SERVER SSL STOREKEY PASS ADMIN
167    */
168   private static final String XML_PATH_ADMIN_KEYSTOREPASS = "admkeystorepass";
169   /**
170    * HTTP Admin Directory
171    */
172   private static final String XML_HTTPADMINPATH = "httpadmin";
173   /**
174    * Monitoring: snmp configuration file (if empty, no snmp support)
175    */
176   private static final String XML_MONITOR_SNMP_CONFIG = "snmpconfig";
177 
178   /**
179    * Structure of the Configuration file
180    */
181   private static final XmlDecl[] configServerParamDecls = {
182       // server
183       new XmlDecl(XmlType.BOOLEAN, XML_USELOCALEXEC),
184       new XmlDecl(XmlType.STRING, XML_LEXECADDR),
185       new XmlDecl(XmlType.INTEGER, XML_LEXECPORT),
186       new XmlDecl(XmlType.STRING, XML_SERVER_ADMIN),
187       new XmlDecl(XmlType.STRING, XML_SERVER_PASSWD),
188       new XmlDecl(XmlType.BOOLEAN, XML_USEHTTPCOMP),
189       new XmlDecl(XmlType.STRING, XML_HTTPADMINPATH),
190       new XmlDecl(XmlType.STRING, XML_PATH_ADMIN_KEYPATH),
191       new XmlDecl(XmlType.STRING, XML_PATH_ADMIN_KEYSTOREPASS),
192       new XmlDecl(XmlType.STRING, XML_PATH_ADMIN_KEYPASS),
193       new XmlDecl(XmlType.STRING, XML_MONITOR_SNMP_CONFIG)
194   };
195   /**
196    * SERVER PORT
197    */
198   private static final String XML_SERVER_PORT = "serverport";
199   /**
200    * SERVER ADDRESS if any
201    */
202   private static final String XML_SERVER_ADDRESS = "serveraddress";
203   /**
204    * RANGE of PORT for Passive Mode
205    */
206   private static final String XML_RANGE_PORT_MIN = "portmin";
207 
208   /**
209    * RANGE of PORT for Passive Mode
210    */
211   private static final String XML_RANGE_PORT_MAX = "portmax";
212   /**
213    * SERVER HTTP PORT MONITORING
214    */
215   private static final String XML_SERVER_HTTP_PORT = "serverhttpport";
216   /**
217    * SERVER HTTPS PORT ADMINISTRATION
218    */
219   private static final String XML_SERVER_HTTPS_PORT = "serverhttpsport";
220 
221   /**
222    * Structure of the Configuration file
223    */
224   private static final XmlDecl[] configNetworkServerDecls = {
225       // network
226       new XmlDecl(XmlType.INTEGER, XML_SERVER_PORT),
227       new XmlDecl(XmlType.STRING, XML_SERVER_ADDRESS),
228       new XmlDecl(XmlType.INTEGER, XML_RANGE_PORT_MIN),
229       new XmlDecl(XmlType.INTEGER, XML_RANGE_PORT_MAX),
230       new XmlDecl(XmlType.INTEGER, XML_SERVER_HTTP_PORT),
231       new XmlDecl(XmlType.INTEGER, XML_SERVER_HTTPS_PORT)
232   };
233   /**
234    * Database Driver as of oracle, mysql, postgresql, h2
235    */
236   private static final String XML_DBDRIVER = "dbdriver";
237 
238   /**
239    * Database Server connection string as of jdbc:type://[host:port],[failoverhost:port]
240    * .../[database][?propertyName1][ =propertyValue1][&propertyName2][=propertyValue2]...
241    */
242   private static final String XML_DBSERVER = "dbserver";
243 
244   /**
245    * Database User
246    */
247   private static final String XML_DBUSER = "dbuser";
248 
249   /**
250    * Database Password
251    */
252   private static final String XML_DBPASSWD = "dbpasswd";//NOSONAR
253   /**
254    * Structure of the Configuration file
255    */
256   private static final XmlDecl[] configDbDecls = {
257       // db
258       new XmlDecl(XmlType.STRING, XML_DBDRIVER),
259       new XmlDecl(XmlType.STRING, XML_DBSERVER),
260       new XmlDecl(XmlType.STRING, XML_DBUSER),
261       new XmlDecl(XmlType.STRING, XML_DBPASSWD)
262   };
263   /**
264    * Allow PASSIVE = -1 / ACTIVE = 1 / Both = 0
265    */
266   private static final String XML_ACTIVE_OR_PASSIVE = "activepassive";
267   /**
268    * Should a file be deleted when a Store like command is aborted
269    */
270   private static final String XML_DELETEONABORT = "deleteonabort";
271   /**
272    * Default number of threads in pool for Server.
273    */
274   private static final String XML_SERVER_THREAD = "serverthread";
275 
276   /**
277    * Default number of threads in pool for Client.
278    */
279   private static final String XML_CLIENT_THREAD = "clientthread";
280   /**
281    * Memory Limit to use.
282    */
283   private static final String XML_MEMORY_LIMIT = "memorylimit";
284 
285   /**
286    * Limit for Session
287    */
288   private static final String XML_LIMITSESSION = "sessionlimit";
289 
290   /**
291    * Limit for Global
292    */
293   private static final String XML_LIMITGLOBAL = "globallimit";
294   /**
295    * Delay between two checks for Limit
296    */
297   private static final String XML_LIMITDELAY = "delaylimit";
298   /**
299    * Nb of milliseconds after connection is in timeout
300    */
301   private static final String XML_TIMEOUTCON = "timeoutcon";
302   /**
303    * Nb of milliseconds after data connection is in timeout
304    */
305   private static final String XML_DATA_TIMEOUTCON = "datatimeoutcon";
306   /**
307    * Size by default of block size for receive/sending files. Should be a
308    * multiple of 8192 (maximum = 64K due to
309    * block limitation to 2 bytes)
310    */
311   private static final String XML_BLOCKSIZE = "blocksize";
312   /**
313    * Should a file MD5 SHA1 be computed using NIO
314    */
315   private static final String XML_USENIO = "usenio";
316 
317   /**
318    * Should a file MD5 be computed using FastMD5
319    */
320   private static final String XML_USEFASTMD5 = "usefastmd5";
321 
322   /**
323    * If using Fast MD5, should we used the binary JNI library, empty meaning
324    * no
325    */
326   private static final String XML_FASTMD5 = "fastmd5";
327   /**
328    * Usage of CPU Limit
329    */
330   private static final String XML_CSTRT_USECPULIMIT = "usecpulimit";
331 
332   /**
333    * Usage of JDK CPU Limit (True) or SysMon CPU Limit
334    */
335   private static final String XML_CSTRT_USECPUJDKLIMIT = "usejdkcpulimit";
336 
337   /**
338    * CPU LIMIT between 0 and 1, where 1 stands for no limit
339    */
340   private static final String XML_CSTRT_CPULIMIT = "cpulimit";
341   /**
342    * Connection limit where 0 stands for no limit
343    */
344   private static final String XML_CSTRT_CONNLIMIT = "connlimit";
345   /**
346    * CPU LOW limit to apply increase of throttle
347    */
348   private static final String XML_CSTRT_LOWCPULIMIT = "lowcpulimit";
349   /**
350    * CPU HIGH limit to apply decrease of throttle, 0 meaning no throttle
351    * activated
352    */
353   private static final String XML_CSTRT_HIGHCPULIMIT = "highcpulimit";
354   /**
355    * PERCENTAGE DECREASE of Bandwidth
356    */
357   private static final String XML_CSTRT_PERCENTDECREASE = "percentdecrease";
358   /**
359    * Delay between 2 checks of throttle test
360    */
361   private static final String XML_CSTRT_DELAYTHROTTLE = "delaythrottle";
362   /**
363    * Bandwidth low limit to not got below
364    */
365   private static final String XML_CSTRT_LIMITLOWBANDWIDTH = "limitlowbandwidth";
366   /**
367    * Structure of the Configuration file
368    */
369   private static final XmlDecl[] configLimitDecls = {
370       // limit
371       new XmlDecl(XmlType.INTEGER, XML_ACTIVE_OR_PASSIVE),
372       new XmlDecl(XmlType.BOOLEAN, XML_DELETEONABORT),
373       new XmlDecl(XmlType.LONG, XML_LIMITSESSION),
374       new XmlDecl(XmlType.LONG, XML_LIMITGLOBAL),
375       new XmlDecl(XmlType.LONG, XML_LIMITDELAY),
376       new XmlDecl(XmlType.INTEGER, XML_SERVER_THREAD),
377       new XmlDecl(XmlType.INTEGER, XML_CLIENT_THREAD),
378       new XmlDecl(XmlType.LONG, XML_MEMORY_LIMIT),
379       new XmlDecl(XmlType.BOOLEAN, XML_CSTRT_USECPULIMIT),
380       new XmlDecl(XmlType.BOOLEAN, XML_CSTRT_USECPUJDKLIMIT),
381       new XmlDecl(XmlType.DOUBLE, XML_CSTRT_CPULIMIT),
382       new XmlDecl(XmlType.INTEGER, XML_CSTRT_CONNLIMIT),
383       new XmlDecl(XmlType.DOUBLE, XML_CSTRT_LOWCPULIMIT),
384       new XmlDecl(XmlType.DOUBLE, XML_CSTRT_HIGHCPULIMIT),
385       new XmlDecl(XmlType.DOUBLE, XML_CSTRT_PERCENTDECREASE),
386       new XmlDecl(XmlType.LONG, XML_CSTRT_LIMITLOWBANDWIDTH),
387       new XmlDecl(XmlType.LONG, XML_CSTRT_DELAYTHROTTLE),
388       new XmlDecl(XmlType.LONG, XML_TIMEOUTCON),
389       new XmlDecl(XmlType.LONG, XML_DATA_TIMEOUTCON),
390       new XmlDecl(XmlType.BOOLEAN, XML_USENIO),
391       new XmlDecl(XmlType.BOOLEAN, XML_USEFASTMD5),
392       new XmlDecl(XmlType.STRING, XML_FASTMD5),
393       new XmlDecl(XmlType.INTEGER, XML_BLOCKSIZE)
394   };
395 
396   /**
397    * RETRIEVE COMMAND
398    */
399   public static final String XML_RETRIEVE_COMMAND = "retrievecmd";
400 
401   /**
402    * STORE COMMAND
403    */
404   public static final String XML_STORE_COMMAND = "storecmd";
405 
406   /**
407    * DELAY RETRIEVE COMMAND
408    */
409   public static final String XML_DELAYRETRIEVE_COMMAND = "retrievedelay";
410 
411   /**
412    * DELAY STORE COMMAND
413    */
414   public static final String XML_DELAYSTORE_COMMAND = "storedelay";
415   /**
416    * Structure of the Configuration file
417    */
418   private static final XmlDecl[] configExecDecls = {
419       // Exec
420       new XmlDecl(XmlType.STRING, XML_RETRIEVE_COMMAND),
421       new XmlDecl(XmlType.LONG, XML_DELAYRETRIEVE_COMMAND),
422       new XmlDecl(XmlType.STRING, XML_STORE_COMMAND),
423       new XmlDecl(XmlType.LONG, XML_DELAYSTORE_COMMAND)
424   };
425   /**
426    * Base Directory
427    */
428   private static final String XML_SERVER_HOME = "serverhome";
429   /**
430    * Structure of the Configuration file
431    */
432   private static final XmlDecl[] configDirectoryDecls = {
433       // directory
434       new XmlDecl(XmlType.STRING, XML_SERVER_HOME)
435   };
436   /**
437    * SERVER SSL STOREKEY PATH
438    */
439   private static final String XML_PATH_KEYPATH = "keypath";
440 
441   /**
442    * SERVER SSL KEY PASS
443    */
444   private static final String XML_PATH_KEYPASS = "keypass";
445 
446   /**
447    * SERVER SSL STOREKEY PASS
448    */
449   private static final String XML_PATH_KEYSTOREPASS = "keystorepass";
450 
451   /**
452    * SERVER SSL TRUSTSTOREKEY PATH
453    */
454   private static final String XML_PATH_TRUSTKEYPATH = "trustkeypath";
455 
456   /**
457    * SERVER SSL TRUSTSTOREKEY PASS
458    */
459   private static final String XML_PATH_TRUSTKEYSTOREPASS = "trustkeystorepass";
460 
461   /**
462    * SERVER SSL Use TrustStore for Client Authentication
463    */
464   private static final String XML_USECLIENT_AUTHENT =
465       "trustuseclientauthenticate";
466   /**
467    * SERVER SSL Use Implicit FTPS
468    */
469   private static final String XML_IMPLICIT_FTPS = "useimplicitftps";
470   /**
471    * SERVER SSL Use Explicit FTPS
472    */
473   private static final String XML_EXPLICIT_FTPS = "useexplicitftps";
474 
475   /**
476    * Structure of the Configuration file
477    */
478   private static final XmlDecl[] configSslDecls = {
479       // ssl
480       new XmlDecl(XmlType.STRING, XML_PATH_KEYPATH),
481       new XmlDecl(XmlType.STRING, XML_PATH_KEYSTOREPASS),
482       new XmlDecl(XmlType.STRING, XML_PATH_KEYPASS),
483       new XmlDecl(XmlType.STRING, XML_PATH_TRUSTKEYPATH),
484       new XmlDecl(XmlType.STRING, XML_PATH_TRUSTKEYSTOREPASS),
485       new XmlDecl(XmlType.BOOLEAN, XML_USECLIENT_AUTHENT),
486       new XmlDecl(XmlType.BOOLEAN, XML_IMPLICIT_FTPS),
487       new XmlDecl(XmlType.BOOLEAN, XML_EXPLICIT_FTPS)
488   };
489   /**
490    * Overall structure of the Configuration file
491    */
492   private static final String XML_ROOT = "/config/";
493   private static final String XML_IDENTITY = "identity";
494   private static final String XML_SERVER = "server";
495   private static final String XML_DIRECTORY = "directory";
496   private static final String XML_LIMIT = "limit";
497   private static final String XML_NETWORK = "network";
498   private static final String XML_EXEC = "exec";
499   private static final String XML_DB = "db";
500   private static final String XML_SSL = "ssl";
501   /**
502    * Global Structure for Server Configuration
503    */
504   private static final XmlDecl[] configServer = {
505       new XmlDecl(XML_IDENTITY, XmlType.XVAL, XML_ROOT + XML_IDENTITY,
506                   configIdentityDecls, false),
507       new XmlDecl(XML_SERVER, XmlType.XVAL, XML_ROOT + XML_SERVER,
508                   configServerParamDecls, false),
509       new XmlDecl(XML_NETWORK, XmlType.XVAL, XML_ROOT + XML_NETWORK,
510                   configNetworkServerDecls, false),
511       new XmlDecl(XML_EXEC, XmlType.XVAL, XML_ROOT + XML_EXEC, configExecDecls,
512                   false),
513       new XmlDecl(XML_DIRECTORY, XmlType.XVAL, XML_ROOT + XML_DIRECTORY,
514                   configDirectoryDecls, false),
515       new XmlDecl(XML_LIMIT, XmlType.XVAL, XML_ROOT + XML_LIMIT,
516                   configLimitDecls, false),
517       new XmlDecl(XML_DB, XmlType.XVAL, XML_ROOT + XML_DB, configDbDecls,
518                   false),
519       new XmlDecl(XML_SSL, XmlType.XVAL, XML_ROOT + XML_SSL, configSslDecls,
520                   false)
521   };
522 
523   /**
524    * Authentication Fields
525    */
526   private static final String XML_AUTHENTIFICATION_ROOT = "authent";
527   /**
528    * Authentication Fields
529    */
530   private static final String XML_AUTHENTIFICATION_ENTRY = "entry";
531   /**
532    * Authentication Fields
533    */
534   private static final String XML_AUTHENTIFICATION_BASED =
535       '/' + XML_AUTHENTIFICATION_ROOT + '/' + XML_AUTHENTIFICATION_ENTRY;
536 
537   /**
538    * Authentication Fields
539    */
540   private static final String XML_AUTHENTICATION_USER = "user";
541 
542   /**
543    * Authentication Fields
544    */
545   private static final String XML_AUTHENTICATION_PASSWD = "passwd";//NOSONAR
546   /**
547    * Authentication Fields
548    */
549   private static final String XML_AUTHENTICATION_PASSWDFILE = //NOSONAR
550       "passwdfile";//NOSONAR
551 
552   /**
553    * Authentication Fields
554    */
555   private static final String XML_AUTHENTICATION_ACCOUNT = "account";
556 
557   /**
558    * Authentication Fields
559    */
560   private static final String XML_AUTHENTICATION_ADMIN = "admin";
561   /**
562    * Structure of the Configuration file
563    */
564   private static final XmlDecl[] configAuthenticationDecls = {
565       // identity
566       new XmlDecl(XmlType.STRING, XML_AUTHENTICATION_USER),
567       new XmlDecl(XmlType.STRING, XML_AUTHENTICATION_PASSWDFILE),
568       new XmlDecl(XmlType.STRING, XML_AUTHENTICATION_PASSWD),
569       new XmlDecl(XML_AUTHENTICATION_ACCOUNT, XmlType.STRING,
570                   XML_AUTHENTICATION_ACCOUNT, true),
571       new XmlDecl(XmlType.BOOLEAN, XML_AUTHENTICATION_ADMIN),
572       // Exec
573       new XmlDecl(XmlType.STRING, XML_RETRIEVE_COMMAND),
574       new XmlDecl(XmlType.LONG, XML_DELAYRETRIEVE_COMMAND),
575       new XmlDecl(XmlType.STRING, XML_STORE_COMMAND),
576       new XmlDecl(XmlType.LONG, XML_DELAYSTORE_COMMAND)
577   };
578   /**
579    * Global Structure for Server Configuration
580    */
581   private static final XmlDecl[] authentElements = {
582       new XmlDecl(XML_AUTHENTIFICATION_ENTRY, XmlType.XVAL,
583                   XML_AUTHENTIFICATION_BASED, configAuthenticationDecls, true)
584   };
585 
586   /**
587    * RANGE of PORT for Passive Mode
588    */
589   private static final String RANGE_PORT = "FTP_RANGE_PORT";
590   /**
591    * Use to access directly the configuration
592    */
593   public static FileBasedConfiguration fileBasedConfiguration;
594   /**
595    * All authentications
596    */
597   private final ConcurrentHashMap<String, SimpleAuth> authentications =
598       new ConcurrentHashMap<String, SimpleAuth>();
599 
600   /**
601    * File containing the authentications
602    */
603   private String authenticationFile;
604 
605   /**
606    * Default HTTP server port
607    */
608   private int serverHttpsPort = 8067;
609   /**
610    * Http Admin base
611    */
612   private String httpBasePath = "src/main/admin/";
613   /**
614    * Does this server will try to compress HTTP connections
615    */
616   private boolean useHttpCompression;
617 
618   /**
619    * Does this server will use Waarp LocalExec Daemon for Execute
620    */
621   private boolean useLocalExec;
622 
623   /**
624    * Crypto Key
625    */
626   private Des cryptoKey;
627   /**
628    * Server Administration Key
629    */
630   private byte[] serverAdminKey;
631   /**
632    * FTP server ID
633    */
634   private String hostId = "noId";
635   /**
636    * Admin name Id
637    */
638   private String adminName = "noAdmin";
639   /**
640    * Limit on CPU and Connection
641    */
642   private FtpConstraintLimitHandler constraintLimitHandler;
643 
644   /**
645    * List of all Http Channels to enable the close call on them using Netty
646    * ChannelGroup
647    */
648   private ChannelGroup httpChannelGroup;
649 
650   /**
651    * Server Group for HTTP
652    */
653   private EventLoopGroup serverGroup;
654 
655   /**
656    * Worker Group for HTTP
657    */
658   private EventLoopGroup workerGroup;
659 
660   /**
661    * ThreadPoolExecutor for Http and Https Server
662    */
663   private EventExecutorGroup httpExecutor;
664   /**
665    * Monitoring: snmp configuration file (empty means no snmp support)
666    */
667   private String snmpConfig;
668   /**
669    * SNMP Agent (if any)
670    */
671   private WaarpSnmpAgent agentSnmp;
672   /**
673    * Associated MIB
674    */
675   private FtpPrivateMib ftpMib;
676   /**
677    * Monitoring object
678    */
679   private FtpMonitoring monitoring;
680 
681   /**
682    * @param classtype
683    * @param businessHandler class that will be used for
684    *     BusinessHandler
685    * @param dataBusinessHandler class that will be used for
686    *     DataBusinessHandler
687    * @param fileParameter the FileParameter to use
688    */
689   public FileBasedConfiguration(final Class<?> classtype,
690                                 final Class<? extends BusinessHandler> businessHandler,
691                                 final Class<? extends DataBusinessHandler> dataBusinessHandler,
692                                 final FileParameterInterface fileParameter) {
693     super(classtype, businessHandler, dataBusinessHandler, fileParameter);
694     computeNbThreads();
695   }
696 
697   private static XmlHash hashConfig;
698 
699   private boolean loadIdentity() {
700     final XmlValue value = hashConfig.get(XML_SERVER_HOSTID);
701     if (value != null && !value.isEmpty()) {
702       setHostId(value.getString());
703     } else {
704       logger.error("Unable to find Host ID in Config file");
705       return false;
706     }
707     return setCryptoKey();
708   }
709 
710   private boolean loadAuthentication() {
711     // if no database, must load authentication from file
712     final XmlValue value = hashConfig.get(XML_AUTHENTIFICATION_FILE);
713     if (value != null && !value.isEmpty()) {
714       setAuthenticationFile(value.getString());
715       return initializeAuthent(getAuthenticationFile(), false);
716     } else {
717       logger.warn("Unable to find Authentication file in Config file");
718       return false;
719     }
720   }
721 
722   private boolean loadServerParam() {
723     XmlValue value = hashConfig.get(XML_USEHTTPCOMP);
724     if (value != null && !value.isEmpty()) {
725       setUseHttpCompression(value.getBoolean());
726     }
727     value = hashConfig.get(XML_USELOCALEXEC);
728     if (value != null && !value.isEmpty()) {
729       setUseLocalExec(value.getBoolean());
730       if (isUseLocalExec()) {
731         value = hashConfig.get(XML_LEXECADDR);
732         final String saddr;
733         final InetAddress addr;
734         if (value != null && !value.isEmpty()) {
735           saddr = value.getString();
736           try {
737             addr = InetAddress.getByName(saddr);
738           } catch (final UnknownHostException e) {
739             logger.error(UNABLE_TO_FIND_LOCAL_EXEC_ADDRESS_IN_CONFIG_FILE);
740             return false;
741           }
742         } else {
743           logger.warn(UNABLE_TO_FIND_LOCAL_EXEC_ADDRESS_IN_CONFIG_FILE);
744           try {
745             addr = InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 });
746           } catch (final UnknownHostException e) {
747             logger.error(UNABLE_TO_FIND_LOCAL_EXEC_ADDRESS_IN_CONFIG_FILE);
748             return false;
749           }
750         }
751         value = hashConfig.get(XML_LEXECPORT);
752         final int port;
753         if (value != null && !value.isEmpty()) {
754           port = value.getInteger();
755         } else {
756           port = 9999;
757         }
758         LocalExecClient.setAddress(new InetSocketAddress(addr, port));
759       }
760     }
761     value = hashConfig.get(XML_SERVER_ADMIN);
762     if (value != null && !value.isEmpty()) {
763       setAdminName(value.getString());
764     } else {
765       logger.error("Unable to find Administrator name in Config file");
766       return false;
767     }
768     if (getCryptoKey() == null && !setCryptoKey()) {
769       logger.error("Unable to find Crypto Key in Config file");
770       return false;
771     }
772     final String passwd;
773     value = hashConfig.get(XML_SERVER_PASSWD);
774     if (value != null && !value.isEmpty()) {
775       passwd = value.getString();
776     } else {
777       logger.error("Unable to find Password in Config file");
778       return false;
779     }
780     final byte[] decodedByteKeys;
781     try {
782       decodedByteKeys = getCryptoKey().decryptHexInBytes(passwd);
783     } catch (final Exception e) {
784       logger.error(
785           "Unable to Decrypt Server Password in Config file from: " + passwd,
786           e);
787       return false;
788     }
789     setSERVERKEY(decodedByteKeys);
790     value = hashConfig.get(XML_HTTPADMINPATH);
791     if (value == null || value.isEmpty()) {
792       logger.error("Unable to find Http Admin Base in Config file");
793       return false;
794     }
795     final String path = value.getString();
796     if (path == null || path.length() == 0) {
797       logger.warn(
798           "Unable to set correct Http Admin Base in Config file. No HTTPS support will be used.");
799       setHttpBasePath(null);
800     } else {
801       final File file = new File(path);
802       if (!file.isDirectory()) {
803         logger.error("Http Admin is not a directory in Config file");
804         return false;
805       }
806       try {
807         setHttpBasePath(AbstractDir.normalizePath(file.getCanonicalPath()) +
808                         DirInterface.SEPARATOR);
809       } catch (final IOException e1) {
810         logger.error("Unable to set Http Admin Path in Config file");
811         return false;
812       }
813     }
814     if (getHttpBasePath() != null) {
815       // Key for HTTPS
816       value = hashConfig.get(XML_PATH_ADMIN_KEYPATH);
817       if (value != null && !value.isEmpty()) {
818         final String keypath = value.getString();
819         if (keypath == null || keypath.length() == 0) {
820           logger.error("Bad Key Path");
821           return false;
822         }
823         value = hashConfig.get(XML_PATH_ADMIN_KEYSTOREPASS);
824         if (value == null || value.isEmpty()) {
825           logger.error("Unable to find KeyStore Passwd");
826           return false;
827         }
828         final String keystorepass = value.getString();
829         if (keystorepass == null || keystorepass.length() == 0) {
830           logger.error("Bad KeyStore Passwd");
831           return false;
832         }
833         value = hashConfig.get(XML_PATH_ADMIN_KEYPASS);
834         if (value == null || value.isEmpty()) {
835           logger.error("Unable to find Key Passwd");
836           return false;
837         }
838         final String keypass = value.getString();
839         if (keypass == null || keypass.length() == 0) {
840           logger.error("Bad Key Passwd");
841           return false;
842         }
843         try {
844           HttpSslInitializer.waarpSecureKeyStore =
845               new WaarpSecureKeyStore(keypath, keystorepass, keypass);
846         } catch (final CryptoException e) {
847           logger.error("Bad SecureKeyStore construction for AdminSsl");
848           return false;
849         }
850         // No client authentication
851         HttpSslInitializer.waarpSecureKeyStore.initEmptyTrustStore();
852         HttpSslInitializer.waarpSslContextFactory =
853             new WaarpSslContextFactory(HttpSslInitializer.waarpSecureKeyStore,
854                                        true);
855       }
856     }
857     value = hashConfig.get(XML_MONITOR_SNMP_CONFIG);
858     if (value != null && !value.isEmpty()) {
859       setSnmpConfig(value.getString());
860       logger.warn("SNMP configuration file: " + getSnmpConfig());
861       final File snmpfile = new File(getSnmpConfig());
862       if (snmpfile.canRead()) {
863         if (!SnmpConfiguration.setConfigurationFromXml(snmpfile)) {
864           logger.warn("Bad SNMP configuration file: " + getSnmpConfig());
865           setSnmpConfig(null);
866         }
867       } else {
868         logger.warn("Cannot read SNMP configuration file: " + getSnmpConfig());
869         setSnmpConfig(null);
870       }
871     } else {
872       logger.warn("NO SNMP configuration file");
873     }
874     return true;
875   }
876 
877   private boolean loadDirectory() {
878     final XmlValue value = hashConfig.get(XML_SERVER_HOME);
879     if (value == null || value.isEmpty()) {
880       logger.error("Unable to find Home in Config file");
881       return false;
882     }
883     final String path = value.getString();
884     final File file = new File(path);
885     if (!file.isDirectory()) {
886       logger.error("Home is not a directory in Config file");
887       return false;
888     }
889     try {
890       setBaseDirectory(AbstractDir.normalizePath(file.getCanonicalPath()));
891     } catch (final IOException e1) {
892       logger.error("Unable to set Home in Config file: " + path);
893       return false;
894     }
895     return true;
896   }
897 
898   private boolean loadLimit() {
899     XmlValue value = hashConfig.get(XML_LIMITGLOBAL);
900     if (value != null && !value.isEmpty()) {
901       serverGlobalReadLimit = value.getLong();
902       if (serverGlobalReadLimit <= 0) {
903         serverGlobalReadLimit = 0;
904       }
905       serverGlobalWriteLimit = serverGlobalReadLimit;
906       logger.info("Global Limit: {}", serverGlobalReadLimit);
907     }
908     value = hashConfig.get(XML_LIMITSESSION);
909     if (value != null && !value.isEmpty()) {
910       serverChannelReadLimit = value.getLong();
911       if (serverChannelReadLimit <= 0) {
912         serverChannelReadLimit = 0;
913       }
914       serverChannelWriteLimit = serverChannelReadLimit;
915       logger.info("SessionInterface Limit: {}", serverChannelReadLimit);
916     }
917     delayLimit = AbstractTrafficShapingHandler.DEFAULT_CHECK_INTERVAL;
918     value = hashConfig.get(XML_LIMITDELAY);
919     if (value != null && !value.isEmpty()) {
920       delayLimit = (value.getLong() / 10) * 10;
921       if (delayLimit <= 0) {
922         delayLimit = 0;
923       }
924       logger.info("Delay Limit: {}", delayLimit);
925     }
926     boolean useCpuLimit = false;
927     boolean useCpuLimitJDK = false;
928     double cpulimit = 1.0;
929     value = hashConfig.get(XML_CSTRT_USECPULIMIT);
930     if (value != null && !value.isEmpty()) {
931       useCpuLimit = value.getBoolean();
932       value = hashConfig.get(XML_CSTRT_USECPUJDKLIMIT);
933       if (value != null && !value.isEmpty()) {
934         useCpuLimitJDK = value.getBoolean();
935       }
936       value = hashConfig.get(XML_CSTRT_CPULIMIT);
937       if (value != null && !value.isEmpty()) {
938         cpulimit = value.getDouble();
939       }
940     }
941     int connlimit = 0;
942     value = hashConfig.get(XML_CSTRT_CONNLIMIT);
943     if (value != null && !value.isEmpty()) {
944       connlimit = value.getInteger();
945     }
946     double lowcpuLimit = 0;
947     double highcpuLimit = 0;
948     double percentageDecrease = 0;
949     long delay = 1000000;
950     long limitLowBandwidth = 4096;
951     value = hashConfig.get(XML_CSTRT_LOWCPULIMIT);
952     if (value != null && !value.isEmpty()) {
953       lowcpuLimit = value.getDouble();
954     }
955     value = hashConfig.get(XML_CSTRT_HIGHCPULIMIT);
956     if (value != null && !value.isEmpty()) {
957       highcpuLimit = value.getDouble();
958     }
959     value = hashConfig.get(XML_CSTRT_PERCENTDECREASE);
960     if (value != null && !value.isEmpty()) {
961       percentageDecrease = value.getDouble();
962     }
963     value = hashConfig.get(XML_CSTRT_DELAYTHROTTLE);
964     if (value != null && !value.isEmpty()) {
965       delay = (value.getLong() / 10) * 10;
966     }
967     value = hashConfig.get(XML_CSTRT_LIMITLOWBANDWIDTH);
968     if (value != null && !value.isEmpty()) {
969       limitLowBandwidth = value.getLong();
970     }
971     value = hashConfig.get(XML_TIMEOUTCON);
972     if (value != null && !value.isEmpty()) {
973       setTimeoutCon((value.getLong() / 10) * 10);
974       value = hashConfig.get(XML_DATA_TIMEOUTCON);
975       if (value != null && !value.isEmpty()) {
976         setDataTimeoutCon((value.getLong() / 10) * 10);
977       } else {
978         setDataTimeoutCon(getTimeoutCon());
979       }
980     } else {
981       value = hashConfig.get(XML_DATA_TIMEOUTCON);
982       if (value != null && !value.isEmpty()) {
983         setDataTimeoutCon((value.getLong() / 10) * 10);
984       }
985     }
986     if (highcpuLimit > 0) {
987       setConstraintLimitHandler(
988           new FtpConstraintLimitHandler(getTimeoutCon(), useCpuLimit,
989                                         useCpuLimitJDK, cpulimit, connlimit,
990                                         lowcpuLimit, highcpuLimit,
991                                         percentageDecrease, null, delay,
992                                         limitLowBandwidth));
993     } else {
994       setConstraintLimitHandler(
995           new FtpConstraintLimitHandler(getTimeoutCon(), useCpuLimit,
996                                         useCpuLimitJDK, cpulimit, connlimit));
997     }
998     value = hashConfig.get(XML_SERVER_THREAD);
999     if (value != null && !value.isEmpty()) {
1000       setServerThread(value.getInteger());
1001     }
1002     value = hashConfig.get(XML_CLIENT_THREAD);
1003     if (value != null && !value.isEmpty()) {
1004       setClientThread(value.getInteger());
1005     }
1006     if (getServerThread() == 0 || getClientThread() == 0) {
1007       computeNbThreads();
1008     }
1009     value = hashConfig.get(XML_MEMORY_LIMIT);
1010     if (value != null && !value.isEmpty()) {
1011       long lvalue = value.getLong();
1012       if (lvalue > Integer.MAX_VALUE) {
1013         lvalue = Integer.MAX_VALUE;
1014       }
1015       setMaxGlobalMemory((int) lvalue);
1016     }
1017     ((FilesystemBasedFileParameterImpl) getFileParameter()).deleteOnAbort =
1018         false;
1019     value = hashConfig.get(XML_USENIO);
1020     if (value != null && !value.isEmpty()) {
1021       FilesystemBasedFileParameterImpl.useNio = value.getBoolean();
1022     }
1023     value = hashConfig.get(XML_BLOCKSIZE);
1024     if (value != null && !value.isEmpty()) {
1025       setBlocksize(value.getInteger());
1026     }
1027     value = hashConfig.get(XML_DELETEONABORT);
1028     if (value != null && !value.isEmpty()) {
1029       setDeleteOnAbort(value.getBoolean());
1030     }
1031     value = hashConfig.get(XML_ACTIVE_OR_PASSIVE);
1032     if (value != null && !value.isEmpty()) {
1033       setActivePassiveMode(value.getInteger());
1034     }
1035     // We use Apache Commons IO
1036     FilesystemBasedDirJdkAbstract.ueApacheCommonsIo = true;
1037     return true;
1038   }
1039 
1040   private boolean loadNetworkServer() {
1041     XmlValue value = hashConfig.get(XML_SERVER_PORT);
1042     final int port;
1043     if (value != null && !value.isEmpty()) {
1044       port = value.getInteger();
1045     } else {
1046       port = 21;
1047     }
1048     setServerPort(port);
1049     value = hashConfig.get(XML_SERVER_ADDRESS);
1050     String address = null;
1051     if (value != null && !value.isEmpty()) {
1052       address = value.getString();
1053     }
1054     setServerAddress(address);
1055     int min = 100;
1056     int max = 65535;
1057     value = hashConfig.get(XML_RANGE_PORT_MIN);
1058     if (value != null && !value.isEmpty()) {
1059       min = value.getInteger();
1060     }
1061     value = hashConfig.get(XML_RANGE_PORT_MAX);
1062     if (value != null && !value.isEmpty()) {
1063       max = value.getInteger();
1064     }
1065     logger.warn("Passive Port range Min: " + min + " Max: " + max);
1066     final CircularIntValue rangePort = new CircularIntValue(min, max);
1067     setRangePort(rangePort);
1068     value = hashConfig.get(XML_SERVER_HTTPS_PORT);
1069     int httpsport = 8067;
1070     if (value != null && !value.isEmpty()) {
1071       httpsport = value.getInteger();
1072     }
1073     serverHttpsPort = httpsport;
1074     return true;
1075   }
1076 
1077   /**
1078    * Set the Crypto Key from the Document
1079    *
1080    * @return True if OK
1081    */
1082   private boolean setCryptoKey() {
1083     final XmlValue value = hashConfig.get(XML_PATH_CRYPTOKEY);
1084     if (value == null || value.isEmpty()) {
1085       logger.error("Unable to find CryptoKey in Config file");
1086       return false;
1087     }
1088     final String filename = value.getString();
1089     final File key = new File(filename);
1090     final Des des = new Des();
1091     try {
1092       des.setSecretKey(key);
1093     } catch (final CryptoException e) {
1094       logger.error("Unable to load CryptoKey from Config file");
1095       return false;
1096     } catch (final IOException e) {
1097       logger.error("Unable to load CryptoKey from Config file");
1098       return false;
1099     }
1100     cryptoKey = des;
1101     return true;
1102   }
1103 
1104   /**
1105    * @return True if the global Exec parameters are correctly loaded
1106    */
1107   private boolean loadExec() {
1108     // Specific Exec command options
1109     XmlValue value = hashConfig.get(XML_RETRIEVE_COMMAND);
1110     if (value == null || value.isEmpty()) {
1111       logger.error("Unable to find Retrieve Command in Config file");
1112       return false;
1113     }
1114     final String retrieve = value.getString();
1115     value = hashConfig.get(XML_DELAYRETRIEVE_COMMAND);
1116     long retrievedelay = 0;
1117     if (value != null && !value.isEmpty()) {
1118       retrievedelay = (value.getLong() / 10) * 10;
1119     }
1120     value = hashConfig.get(XML_STORE_COMMAND);
1121     if (value == null || value.isEmpty()) {
1122       logger.error("Unable to find Store Command in Config file");
1123       return false;
1124     }
1125     final String store = value.getString();
1126     value = hashConfig.get(XML_DELAYSTORE_COMMAND);
1127     long storedelay = 0;
1128     if (value != null && !value.isEmpty()) {
1129       storedelay = (value.getLong() / 10) * 10;
1130     }
1131     AbstractExecutor.initializeExecutor(retrieve, retrievedelay, store,
1132                                         storedelay);
1133     return true;
1134   }
1135 
1136   /**
1137    * Load database parameter
1138    *
1139    * @return True if OK
1140    */
1141   private boolean loadDatabase() {
1142     XmlValue value = hashConfig.get(XML_DBDRIVER);
1143     if (value == null || value.isEmpty()) {
1144       logger.error("Unable to find DBDriver in Config file");
1145       DbConstantFtp.gatewayAdmin = new DbAdmin(); // no database support
1146     } else {
1147       final String dbdriver = value.getString();
1148       value = hashConfig.get(XML_DBSERVER);
1149       if (value == null || value.isEmpty()) {
1150         logger.error("Unable to find DBServer in Config file");
1151         return false;
1152       }
1153       final String dbserver = value.getString();
1154       value = hashConfig.get(XML_DBUSER);
1155       if (value == null || value.isEmpty()) {
1156         logger.error("Unable to find DBUser in Config file");
1157         return false;
1158       }
1159       final String dbuser = value.getString();
1160       value = hashConfig.get(XML_DBPASSWD);
1161       if (value == null || value.isEmpty()) {
1162         logger.error("Unable to find DBPassword in Config file");
1163         return false;
1164       }
1165       final String dbpasswd = value.getString();
1166       if (dbdriver == null || dbserver == null || dbuser == null ||
1167           dbpasswd == null || dbdriver.length() == 0 ||
1168           dbserver.length() == 0 || dbuser.length() == 0 ||
1169           dbpasswd.length() == 0) {
1170         logger.error("Unable to find Correct DB data in Config file");
1171         return false;
1172       }
1173       try {
1174         DbConstantFtp.gatewayAdmin =
1175             DbModelFactoryFtp.initialize(dbdriver, dbserver, dbuser, dbpasswd,
1176                                          true);
1177         org.waarp.common.database.DbConstant.admin = DbConstantFtp.gatewayAdmin;
1178       } catch (final WaarpDatabaseNoConnectionException e2) {
1179         logger.error("Unable to Connect to DB", e2);
1180         return false;
1181       }
1182     }
1183     return true;
1184   }
1185 
1186   protected final boolean loadSsl() {
1187     // StoreKey for Server
1188     XmlValue value = hashConfig.get(XML_PATH_KEYPATH);
1189     if (value == null || value.isEmpty()) {
1190       logger.info("Unable to find Key Path");
1191       getFtpInternalConfiguration().setUsingNativeSsl(false);
1192       getFtpInternalConfiguration().setAcceptAuthProt(false);
1193       return true;
1194     } else {
1195       final String keypath = value.getString();
1196       if (keypath == null || keypath.length() == 0) {
1197         logger.error("Bad Key Path");
1198         return false;
1199       }
1200       value = hashConfig.get(XML_PATH_KEYSTOREPASS);
1201       if (value == null || value.isEmpty()) {
1202         logger.error("Unable to find KeyStore Passwd");
1203         return false;
1204       }
1205       final String keystorepass = value.getString();
1206       if (keystorepass == null || keystorepass.length() == 0) {
1207         logger.error("Bad KeyStore Passwd");
1208         return false;
1209       }
1210       value = hashConfig.get(XML_PATH_KEYPASS);
1211       if (value == null || value.isEmpty()) {
1212         logger.error("Unable to find Key Passwd");
1213         return false;
1214       }
1215       final String keypass = value.getString();
1216       if (keypass == null || keypass.length() == 0) {
1217         logger.error("Bad Key Passwd");
1218         return false;
1219       }
1220       try {
1221         FtpsInitializer.waarpSecureKeyStore =
1222             new WaarpSecureKeyStore(keypath, keystorepass, keypass);
1223       } catch (final CryptoException e) {
1224         logger.error("Bad SecureKeyStore construction");
1225         return false;
1226       }
1227 
1228     }
1229     // TrustedKey for OpenR66 server
1230     value = hashConfig.get(XML_PATH_TRUSTKEYPATH);
1231     if (value == null || value.isEmpty()) {
1232       logger.info("Unable to find TRUST Key Path");
1233       FtpsInitializer.waarpSecureKeyStore.initEmptyTrustStore();
1234     } else {
1235       final String keypath = value.getString();
1236       if (keypath == null || keypath.length() == 0) {
1237         logger.error("Bad TRUST Key Path");
1238         return false;
1239       }
1240       value = hashConfig.get(XML_PATH_TRUSTKEYSTOREPASS);
1241       if (value == null || value.isEmpty()) {
1242         logger.error("Unable to find TRUST KeyStore Passwd");
1243         return false;
1244       }
1245       final String keystorepass = value.getString();
1246       if (keystorepass == null || keystorepass.length() == 0) {
1247         logger.error("Bad TRUST KeyStore Passwd");
1248         return false;
1249       }
1250       boolean useClientAuthent = false;
1251       value = hashConfig.get(XML_USECLIENT_AUTHENT);
1252       if (value != null && !value.isEmpty()) {
1253         useClientAuthent = value.getBoolean();
1254       }
1255       try {
1256         FtpsInitializer.waarpSecureKeyStore.initTrustStore(keypath,
1257                                                            keystorepass,
1258                                                            useClientAuthent);
1259       } catch (final CryptoException e) {
1260         logger.error("Bad TrustKeyStore construction");
1261         return false;
1262       }
1263     }
1264     FtpsInitializer.waarpSslContextFactory =
1265         new WaarpSslContextFactory(FtpsInitializer.waarpSecureKeyStore);
1266     boolean useImplicit = false;
1267     value = hashConfig.get(XML_IMPLICIT_FTPS);
1268     if (value != null && !value.isEmpty()) {
1269       useImplicit = value.getBoolean();
1270     }
1271     boolean useExplicit = false;
1272     value = hashConfig.get(XML_EXPLICIT_FTPS);
1273     if (value != null && !value.isEmpty()) {
1274       useExplicit = value.getBoolean();
1275     }
1276     if (useImplicit && useExplicit) {
1277       logger.error("Only one of IMPLICIT or EXPLICIT could be True");
1278       return false;
1279     }
1280     if (!useImplicit && !useExplicit) {
1281       logger.error(
1282           "Since all SecureStore are specified, one of IMPLICIT or EXPLICIT should be True");
1283       logger.warn("FTPS support will be ignored...");
1284       getFtpInternalConfiguration().setUsingNativeSsl(false);
1285       getFtpInternalConfiguration().setAcceptAuthProt(false);
1286       return true;
1287     }
1288     getFtpInternalConfiguration().setUsingNativeSsl(useImplicit);
1289     getFtpInternalConfiguration().setAcceptAuthProt(useExplicit);
1290     return true;
1291   }
1292 
1293   /**
1294    * Initiate the configuration from the xml file for server
1295    *
1296    * @param filename
1297    *
1298    * @return True if OK
1299    */
1300   public final boolean setConfigurationServerFromXml(final String filename) {
1301     final Document document;
1302     // Open config file
1303     try {
1304       document = XmlUtil.getNewSaxReader().read(filename);
1305     } catch (final DocumentException e) {
1306       logger.error("Unable to read the XML Config file: " + filename + ": {}",
1307                    e.getMessage());
1308       return false;
1309     }
1310     if (document == null) {
1311       logger.error("Unable to read the XML Config file: " + filename);
1312       return false;
1313     }
1314     XmlValue[] configuration = XmlUtil.read(document, configServer);
1315     hashConfig = new XmlHash(configuration);
1316     // Now read the configuration
1317     if (!loadIdentity()) {
1318       logger.error("Cannot load Identity");
1319       return false;
1320     }
1321     if (!loadDatabase()) {
1322       logger.error("Cannot load Database configuration");
1323       return false;
1324     }
1325     if (!loadServerParam()) {
1326       logger.error("Cannot load Server Parameters");
1327       return false;
1328     }
1329     if (!loadDirectory()) {
1330       logger.error("Cannot load Directory configuration");
1331       return false;
1332     }
1333     if (!loadLimit()) {
1334       logger.error("Cannot load Limit configuration");
1335       return false;
1336     }
1337     if (!loadNetworkServer()) {
1338       logger.error("Cannot load Network configuration");
1339       return false;
1340     }
1341     if (!loadExec()) {
1342       logger.error("Cannot load Exec configuration");
1343       return false;
1344     }
1345     // if no database, must load authentication from file
1346     if (!loadAuthentication()) {
1347       logger.error("Cannot load Authentication configuration");
1348       return false;
1349     }
1350     if (!loadSsl()) {
1351       // ignore and continue => No SSL
1352       getFtpInternalConfiguration().setUsingNativeSsl(false);
1353       getFtpInternalConfiguration().setAcceptAuthProt(false);
1354     }
1355     hashConfig.clear();
1356     hashConfig = null;
1357     configuration = null;
1358     logger.debug("File based configuration loaded");
1359     return true;
1360   }
1361 
1362   /**
1363    * Configure HTTPS
1364    */
1365   public final void configureHttps() {
1366     logger.debug("Start HTTPS");
1367     // Now start the HTTPS support
1368     // Configure the server.
1369     /*
1370      * Bootstrap for Https server
1371      */
1372     final ServerBootstrap httpsBootstrap = new ServerBootstrap();
1373     httpExecutor = new NioEventLoopGroup(getServerThread() * 10,
1374                                          new WaarpThreadFactory(
1375                                              "HttpExecutor"));
1376     serverGroup = new NioEventLoopGroup(getServerThread(),
1377                                         new WaarpThreadFactory("HTTP_Server"));
1378     workerGroup = new NioEventLoopGroup(getServerThread() * 10,
1379                                         new WaarpThreadFactory("HTTP_Worker"));
1380     WaarpNettyUtil.setServerBootstrap(httpsBootstrap, serverGroup, workerGroup,
1381                                       (int) getTimeoutCon());
1382 
1383     // Configure the pipeline factory.
1384     httpsBootstrap.childHandler(new HttpSslInitializer(isUseHttpCompression()));
1385     httpChannelGroup =
1386         new DefaultChannelGroup("HttpOpenR66", httpExecutor.next());
1387 
1388     // Bind and start to accept incoming connections.
1389     logger.warn("Start Https Support on port: " + serverHttpsPort + " with " +
1390                 (isUseHttpCompression()? "" : "no") + " compression support");
1391     final ChannelFuture future =
1392         httpsBootstrap.bind(new InetSocketAddress(serverHttpsPort));
1393     if (WaarpNettyUtil.awaitIsSuccessOfInterrupted(future)) {
1394       httpChannelGroup.add(future.channel());
1395     }
1396   }
1397 
1398   /**
1399    * Configure ConstraintLimitHandler
1400    */
1401   public final void configureConstraint() {
1402     logger.debug("Configure constraints");
1403     getConstraintLimitHandler().setHandler(
1404         getFtpInternalConfiguration().getGlobalTrafficShapingHandler());
1405   }
1406 
1407   /**
1408    * Configure LocalExec
1409    */
1410   public final void configureLExec() {
1411     if (isUseLocalExec()) {
1412       logger.debug("Start LExec");
1413       LocalExecClient.initialize(getClientThread(), getMaxGlobalMemory());
1414     }
1415   }
1416 
1417   /**
1418    * Configure the SNMP support if needed
1419    *
1420    * @throws FtpNoConnectionException
1421    */
1422   public final void configureSnmp() throws FtpNoConnectionException {
1423     logger.debug("Start SNMP");
1424     setMonitoring(new FtpMonitoring(null));
1425     if (getSnmpConfig() != null) {
1426       final int snmpPortShow = getServerPort();
1427       setFtpMib(new FtpPrivateMib(snmpPortShow));
1428       WaarpMOFactory.setFactory(new FtpVariableFactory());
1429       setAgentSnmp(
1430           new WaarpSnmpAgent(new File(getSnmpConfig()), getMonitoring(),
1431                              getFtpMib()));
1432       try {
1433         getAgentSnmp().start();
1434         logger.debug("SNMP configured");
1435       } catch (final IOException e) {
1436         getMonitoring().releaseResources();
1437         setMonitoring(null);
1438         setFtpMib(null);
1439         setAgentSnmp(null);
1440         throw new FtpNoConnectionException("AgentSnmp Error while starting", e);
1441       }
1442     }
1443   }
1444 
1445   /**
1446    * @param serverkey the SERVERADMINKEY to set
1447    */
1448   public final void setSERVERKEY(final byte[] serverkey) {
1449     serverAdminKey = serverkey;
1450   }
1451 
1452   /**
1453    * Check the password for Shutdown
1454    *
1455    * @param password
1456    *
1457    * @return True if the password is OK
1458    */
1459   @Override
1460   public final boolean checkPassword(final String password) {
1461     if (password == null) {
1462       return false;
1463     }
1464     return Arrays.equals(serverAdminKey,
1465                          password.getBytes(WaarpStringUtils.UTF8));
1466   }
1467 
1468   /**
1469    * Initialize Authentication from current authenticationFile
1470    *
1471    * @param filename the filename from which authentication will be
1472    *     loaded
1473    * @param purge if True, the current authentications are totally
1474    *     replaced
1475    *     by the new ones
1476    *
1477    * @return True if OK
1478    */
1479   @SuppressWarnings("unchecked")
1480   public final boolean initializeAuthent(final String filename,
1481                                          final boolean purge) {
1482     logger.debug("Load authent");
1483     final Document document;
1484     try {
1485       document = XmlUtil.getNewSaxReader().read(filename);
1486     } catch (final DocumentException e) {
1487       logger.error(
1488           "Unable to read the XML Authentication file: " + filename + ": {}",
1489           e.getMessage());
1490       return false;
1491     }
1492     if (document == null) {
1493       logger.error("Unable to read the XML Authentication file: " + filename);
1494       return false;
1495     }
1496     final XmlValue[] configurationXml = XmlUtil.read(document, authentElements);
1497     XmlHash hashConfigXml = new XmlHash(configurationXml);
1498 
1499     XmlValue value = hashConfigXml.get(XML_AUTHENTIFICATION_ENTRY);
1500     final List<XmlValue[]> list = (List<XmlValue[]>) value.getList();
1501     final ConcurrentHashMap<String, SimpleAuth> newAuthents =
1502         new ConcurrentHashMap<String, SimpleAuth>();
1503     for (final XmlValue[] xmlValues : list) {
1504       hashConfigXml = new XmlHash(xmlValues);
1505       value = hashConfigXml.get(XML_AUTHENTICATION_USER);
1506       if (value == null || value.isEmpty()) {
1507         logger.error("Unable to find a User in Config file");
1508         continue;
1509       }
1510       final String user = value.getString();
1511       value = hashConfigXml.get(XML_AUTHENTICATION_ACCOUNT);
1512       if (value == null || value.isEmpty()) {
1513         logger.error("Unable to find a Account in Config file: " + user);
1514         continue;
1515       }
1516       final String[] account;
1517       final List<String> listaccount = (List<String>) value.getList();
1518       if (!listaccount.isEmpty()) {
1519         account = new String[listaccount.size()];
1520         int i = 0;
1521         for (final String s : listaccount) {
1522           account[i] = s;
1523           final File directory =
1524               new File(getBaseDirectory() + '/' + user + '/' + account[i]);
1525           directory.mkdirs();//NOSONAR
1526           i++;
1527         }
1528       } else {
1529         logger.error("Unable to find a Account in Config file: " + user);
1530         continue;
1531       }
1532       value = hashConfigXml.get(XML_AUTHENTICATION_ADMIN);
1533       boolean isAdmin = false;
1534       if (value != null && !value.isEmpty()) {
1535         isAdmin = value.getBoolean();
1536       }
1537       String retrcmd = null;
1538       long retrdelay = 0;
1539       String storcmd = null;
1540       long stordelay = 0;
1541       value = hashConfigXml.get(XML_RETRIEVE_COMMAND);
1542       if (value != null && !value.isEmpty()) {
1543         retrcmd = value.getString();
1544       }
1545       value = hashConfigXml.get(XML_DELAYRETRIEVE_COMMAND);
1546       if (value != null && !value.isEmpty()) {
1547         retrdelay = (value.getLong() / 10) * 10;
1548       }
1549       value = hashConfigXml.get(XML_STORE_COMMAND);
1550       if (value != null && !value.isEmpty()) {
1551         storcmd = value.getString();
1552       }
1553       value = hashConfigXml.get(XML_DELAYSTORE_COMMAND);
1554       if (value != null && !value.isEmpty()) {
1555         stordelay = (value.getLong() / 10) * 10;
1556       }
1557       final String passwd;
1558       value = hashConfigXml.get(XML_AUTHENTICATION_PASSWDFILE);
1559       if (value != null && !value.isEmpty()) {
1560         // load key from file
1561         final File key = new File(value.getString());
1562         if (!key.canRead()) {
1563           logger.error(
1564               "Cannot read key for user " + user + ':' + key.getName());
1565           continue;
1566         }
1567         try {
1568           final byte[] byteKeys = getCryptoKey().decryptHexFile(key);
1569           passwd = new String(byteKeys, WaarpStringUtils.UTF8);
1570         } catch (final Exception e2) {
1571           logger.error("Cannot read key for user " + user, e2);
1572           continue;
1573         }
1574       } else {
1575         value = hashConfigXml.get(XML_AUTHENTICATION_PASSWD);
1576         if (value != null && !value.isEmpty()) {
1577           final String encrypted = value.getString();
1578           final byte[] byteKeys;
1579           try {
1580             byteKeys = getCryptoKey().decryptHexInBytes(encrypted);
1581             passwd = new String(byteKeys, WaarpStringUtils.UTF8);
1582           } catch (final Exception e) {
1583             logger.error("Unable to Decrypt Key for user " + user, e);
1584             continue;
1585           }
1586         } else {
1587           logger.error("Unable to find Password in Config file");
1588           // DO NOT Allow empty key
1589           continue;
1590         }
1591       }
1592       final SimpleAuth auth =
1593           new SimpleAuth(user, passwd, account, storcmd, stordelay, retrcmd,
1594                          retrdelay);
1595       auth.setAdmin(isAdmin);
1596       newAuthents.put(user, auth);
1597       hashConfigXml.clear();
1598     }
1599     hashConfigXml.clear();
1600     if (purge) {
1601       authentications.clear();
1602     }
1603     authentications.putAll(newAuthents);
1604     newAuthents.clear();
1605     return true;
1606   }
1607 
1608   /**
1609    * Export the Authentication to the original files
1610    *
1611    * @param filename the filename where the authentication will be
1612    *     exported
1613    *
1614    * @return True if successful
1615    */
1616   public final boolean saveAuthenticationFile(final String filename) {
1617     final Document document = XmlUtil.createEmptyDocument();
1618     final XmlValue[] roots = new XmlValue[1];
1619     final XmlValue root = new XmlValue(authentElements[0]);
1620     roots[0] = root;
1621     final Enumeration<SimpleAuth> auths = authentications.elements();
1622     while (auths.hasMoreElements()) {
1623       final SimpleAuth auth = auths.nextElement();
1624       final XmlValue[] values = new XmlValue[configAuthenticationDecls.length];
1625       for (int i = 0; i < configAuthenticationDecls.length; i++) {
1626         values[i] = new XmlValue(configAuthenticationDecls[i]);
1627       }
1628       try {
1629         values[0].setFromString(auth.getUser());
1630         // PasswdFile: none values[1].setFromString()
1631         values[2].setFromString(auth.getPassword());
1632         // Accounts
1633         final String[] accts = auth.getAccounts();
1634         for (final String string : accts) {
1635           values[3].addFromString(string);
1636         }
1637         values[4].setValue(auth.isAdmin());
1638         values[5].setFromString(auth.getRetrCmd());
1639         values[6].setValue(auth.getRetrDelay());
1640         values[7].setFromString(auth.getStorCmd());
1641         values[8].setValue(auth.getStorDelay());
1642       } catch (final InvalidArgumentException e1) {
1643         logger.error(ERROR_DURING_WRITE_AUTHENTICATION_FILE, e1);
1644         return false;
1645       } catch (final InvalidObjectException e) {
1646         logger.error(ERROR_DURING_WRITE_AUTHENTICATION_FILE, e);
1647         return false;
1648       }
1649       try {
1650         root.addValue(values);
1651       } catch (final InvalidObjectException e) {
1652         logger.error(ERROR_DURING_WRITE_AUTHENTICATION_FILE, e);
1653         return false;
1654       }
1655     }
1656     XmlUtil.write(document, roots);
1657     try {
1658       XmlUtil.saveDocument(filename, document);
1659     } catch (final IOException e1) {
1660       logger.error("Cannot write to file: " + filename + " since {}",
1661                    e1.getMessage());
1662       return false;
1663     }
1664     return true;
1665   }
1666 
1667   /**
1668    * @param user
1669    *
1670    * @return the SimpleAuth if any for this user
1671    */
1672   public final SimpleAuth getSimpleAuth(final String user) {
1673     return authentications.get(user);
1674   }
1675 
1676   /**
1677    * @param format Format in HTML to use as ouput format
1678    *
1679    * @return the Html String containing the table of all Authentication
1680    *     entries
1681    */
1682   public final String getHtmlAuth(final String format) {
1683     final String result;
1684     final StringBuilder builder = new StringBuilder();
1685     /*
1686      * XXXUSERXXX XXXPWDXXX XXXACTSXXX XXXADMXXX XXXSTCXXX XXXSTDXXX XXXRTCXXX XXXRTDXXX
1687      */
1688     final Enumeration<SimpleAuth> simpleAuths = authentications.elements();
1689     SimpleAuth auth;
1690     while (simpleAuths.hasMoreElements()) {
1691       auth = simpleAuths.nextElement();
1692       String newElt = format.replace("XXXUSERXXX", auth.getUser());
1693       newElt = newElt.replace("XXXPWDXXX", auth.getPassword());
1694       if (auth.getStorCmd() != null) {
1695         newElt = newElt.replace("XXXSTCXXX", auth.getStorCmd());
1696       } else {
1697         newElt = newElt.replace("XXXSTCXXX", "");
1698       }
1699       if (auth.getRetrCmd() != null) {
1700         newElt = newElt.replace("XXXRTCXXX", auth.getRetrCmd());
1701       } else {
1702         newElt = newElt.replace("XXXRTCXXX", "");
1703       }
1704       newElt = newElt.replace("XXXSTDXXX", Long.toString(auth.getStorDelay()));
1705       newElt = newElt.replace("XXXRTDXXX", Long.toString(auth.getRetrDelay()));
1706       newElt = newElt.replace("XXXADMXXX", Boolean.toString(auth.isAdmin()));
1707       if (auth.getAccounts() != null) {
1708         final StringBuilder accts = new StringBuilder();
1709         for (int i = 0; i < auth.getAccounts().length - 1; i++) {
1710           accts.append(auth.getAccounts()[i]).append(", ");
1711         }
1712         accts.append(auth.getAccounts()[auth.getAccounts().length - 1]);
1713         newElt = newElt.replace("XXXACTSXXX", accts.toString());
1714       } else {
1715         newElt = newElt.replace("XXXACTSXXX", "No Account");
1716       }
1717       builder.append(newElt);
1718     }
1719     result = builder.toString();
1720     return result;
1721   }
1722 
1723   /**
1724    * Only available with Database support for Waarp
1725    *
1726    * @param format Format in HTML to use as ouput format
1727    * @param limit number of TransferLog to populate
1728    *
1729    * @return the Html String containing the table of all Transfer entries
1730    */
1731   public final String getHtmlTransfer(final String format, final int limit) {
1732     final String result;
1733     final StringBuilder builder = new StringBuilder();
1734     /*
1735      * XXXIDXXX XXXUSERXXX XXXACCTXXX XXXFILEXXX XXXMODEXXX XXXSTATUSXXX XXXINFOXXX XXXUPINFXXX XXXSTARTXXX
1736      * XXXSTOPXXX
1737      */
1738     DbPreparedStatement preparedStatement = null;
1739     try {
1740       try {
1741         preparedStatement = DbTransferLog.getStatusPrepareStament(
1742             DbConstantFtp.gatewayAdmin.getSession(), null, limit);
1743         preparedStatement.executeQuery();
1744       } catch (final WaarpDatabaseNoConnectionException e) {
1745         return "";
1746       } catch (final WaarpDatabaseSqlException e) {
1747         return "";
1748       }
1749       try {
1750         while (preparedStatement.getNext()) {
1751           final DbTransferLog log =
1752               DbTransferLog.getFromStatement(preparedStatement);
1753           String newElt =
1754               format.replace("XXXIDXXX", Long.toString(log.getSpecialId()));
1755           newElt = newElt.replace("XXXUSERXXX", log.getUser());
1756           newElt = newElt.replace("XXXACCTXXX", log.getAccount());
1757           newElt = newElt.replace("XXXFILEXXX", log.getFilename());
1758           newElt = newElt.replace("XXXMODEXXX", log.getMode());
1759           newElt = newElt.replace("XXXSTATUSXXX", log.getErrorInfo().getMesg());
1760           newElt = newElt.replace("XXXINFOXXX", log.getInfotransf());
1761           newElt = newElt.replace("XXXUPINFXXX", log.getUpdatedInfo().name());
1762           newElt = newElt.replace("XXXSTARTXXX", log.getStart().toString());
1763           newElt = newElt.replace("XXXSTOPXXX", log.getStop().toString());
1764           builder.append(newElt);
1765         }
1766       } catch (final WaarpDatabaseNoConnectionException e) {
1767         return "";
1768       } catch (final WaarpDatabaseSqlException e) {
1769         return "";
1770       }
1771       result = builder.toString();
1772       return result;
1773     } finally {
1774       if (preparedStatement != null) {
1775         preparedStatement.realClose();
1776       }
1777     }
1778   }
1779 
1780   /**
1781    * @see FtpConfiguration#getNextRangePort()
1782    */
1783   @Override
1784   public final int getNextRangePort() {
1785     try {
1786       return ((CircularIntValue) getProperty(RANGE_PORT)).getNext();
1787     } catch (final FtpUnknownFieldException e) {
1788       return -1;
1789     }
1790   }
1791 
1792   /**
1793    * @param rangePort the range of available ports for Passive
1794    *     connections
1795    */
1796   private void setRangePort(final CircularIntValue rangePort) {
1797     setProperty(RANGE_PORT, rangePort);
1798   }
1799 
1800   /**
1801    * @return the httpPipelineExecutor
1802    */
1803   public final EventExecutorGroup getHttpPipelineExecutor() {
1804     return httpExecutor;
1805   }
1806 
1807   /**
1808    * @return the httpChannelGroup
1809    */
1810   public final ChannelGroup getHttpChannelGroup() {
1811     return httpChannelGroup;
1812   }
1813 
1814   /**
1815    * Finalize resources attached to handlers
1816    */
1817   private static class GgChannelGroupFutureListener
1818       implements ChannelGroupFutureListener {
1819     final EventExecutorGroup executorWorker;
1820     final String name;
1821 
1822     private GgChannelGroupFutureListener(final String name,
1823                                          final EventExecutorGroup executorWorker) {
1824       this.name = name;
1825       this.executorWorker = executorWorker;
1826     }
1827 
1828     @Override
1829     public final void operationComplete(final ChannelGroupFuture future) {
1830       if (executorWorker != null) {
1831         executorWorker.shutdownGracefully();
1832       }
1833       logger.info("Done with shutdown {}", name);
1834     }
1835   }
1836 
1837   @Override
1838   public final void releaseResources() {
1839     logger.debug("Release resources");
1840     super.releaseResources();
1841     if (httpChannelGroup != null) {
1842       final int result = httpChannelGroup.size();
1843       logger.debug("HttpChannelGroup: {}", result);
1844       httpChannelGroup.close().addListener(
1845           new GgChannelGroupFutureListener("HttpChannelGroup", workerGroup));
1846     }
1847     if (httpExecutor != null) {
1848       httpExecutor.shutdownGracefully();
1849     }
1850     if (isUseLocalExec()) {
1851       LocalExecClient.releaseResources();
1852     }
1853     if (getConstraintLimitHandler() != null) {
1854       getConstraintLimitHandler().release();
1855     }
1856     if (getAgentSnmp() != null) {
1857       getAgentSnmp().stop();
1858     }
1859     if (workerGroup != null) {
1860       workerGroup.shutdownGracefully();
1861     }
1862     if (serverGroup != null) {
1863       serverGroup.shutdownGracefully();
1864     }
1865     DbAdmin.closeAllConnection();
1866   }
1867 
1868   @Override
1869   public final void inShutdownProcess() {
1870     if (getFtpMib() != null) {
1871       getFtpMib().notifyStartStop("Shutdown in progress for " + getHostId(),
1872                                   "Gives extra seconds: " + getTimeoutCon());
1873     }
1874   }
1875 
1876   /**
1877    * @return the authenticationFile
1878    */
1879   public final String getAuthenticationFile() {
1880     return authenticationFile;
1881   }
1882 
1883   /**
1884    * @param authenticationFile the authenticationFile to set
1885    */
1886   public final void setAuthenticationFile(final String authenticationFile) {
1887     this.authenticationFile = authenticationFile;
1888   }
1889 
1890   /**
1891    * @return the httpBasePath
1892    */
1893   public final String getHttpBasePath() {
1894     return httpBasePath;
1895   }
1896 
1897   /**
1898    * @param httpBasePath the httpBasePath to set
1899    */
1900   public final void setHttpBasePath(final String httpBasePath) {
1901     this.httpBasePath = httpBasePath;
1902   }
1903 
1904   /**
1905    * @return the useHttpCompression
1906    */
1907   public final boolean isUseHttpCompression() {
1908     return useHttpCompression;
1909   }
1910 
1911   /**
1912    * @param useHttpCompression the useHttpCompression to set
1913    */
1914   public final void setUseHttpCompression(final boolean useHttpCompression) {
1915     this.useHttpCompression = useHttpCompression;
1916   }
1917 
1918   /**
1919    * @return the useLocalExec
1920    */
1921   public final boolean isUseLocalExec() {
1922     return useLocalExec;
1923   }
1924 
1925   /**
1926    * @param useLocalExec the useLocalExec to set
1927    */
1928   public final void setUseLocalExec(final boolean useLocalExec) {
1929     this.useLocalExec = useLocalExec;
1930   }
1931 
1932   /**
1933    * @return the cryptoKey
1934    */
1935   public final Des getCryptoKey() {
1936     return cryptoKey;
1937   }
1938 
1939   /**
1940    * @param cryptoKey the cryptoKey to set
1941    */
1942   public final void setCryptoKey(final Des cryptoKey) {
1943     this.cryptoKey = cryptoKey;
1944   }
1945 
1946   /**
1947    * @return the hostId
1948    */
1949   public final String getHostId() {
1950     return hostId;
1951   }
1952 
1953   /**
1954    * @param hostId the hostId to set
1955    */
1956   public final void setHostId(final String hostId) {
1957     this.hostId = hostId;
1958   }
1959 
1960   /**
1961    * @return the adminName
1962    */
1963   public final String getAdminName() {
1964     return adminName;
1965   }
1966 
1967   /**
1968    * @param adminName the adminName to set
1969    */
1970   public final void setAdminName(final String adminName) {
1971     this.adminName = adminName;
1972   }
1973 
1974   /**
1975    * @return the constraintLimitHandler
1976    */
1977   public final FtpConstraintLimitHandler getConstraintLimitHandler() {
1978     return constraintLimitHandler;
1979   }
1980 
1981   /**
1982    * @param constraintLimitHandler the constraintLimitHandler to set
1983    */
1984   public final void setConstraintLimitHandler(
1985       final FtpConstraintLimitHandler constraintLimitHandler) {
1986     this.constraintLimitHandler = constraintLimitHandler;
1987   }
1988 
1989   /**
1990    * @return the snmpConfig
1991    */
1992   public final String getSnmpConfig() {
1993     return snmpConfig;
1994   }
1995 
1996   /**
1997    * @param snmpConfig the snmpConfig to set
1998    */
1999   public final void setSnmpConfig(final String snmpConfig) {
2000     this.snmpConfig = snmpConfig;
2001   }
2002 
2003   /**
2004    * @return the agentSnmp
2005    */
2006   public final WaarpSnmpAgent getAgentSnmp() {
2007     return agentSnmp;
2008   }
2009 
2010   /**
2011    * @param agentSnmp the agentSnmp to set
2012    */
2013   public final void setAgentSnmp(final WaarpSnmpAgent agentSnmp) {
2014     this.agentSnmp = agentSnmp;
2015   }
2016 
2017   /**
2018    * @return the ftpMib
2019    */
2020   public final FtpPrivateMib getFtpMib() {
2021     return ftpMib;
2022   }
2023 
2024   /**
2025    * @param ftpMib the ftpMib to set
2026    */
2027   public final void setFtpMib(final FtpPrivateMib ftpMib) {
2028     this.ftpMib = ftpMib;
2029   }
2030 
2031   /**
2032    * @return the monitoring
2033    */
2034   public final FtpMonitoring getMonitoring() {
2035     return monitoring;
2036   }
2037 
2038   /**
2039    * @param monitoring the monitoring to set
2040    */
2041   public final void setMonitoring(final FtpMonitoring monitoring) {
2042     this.monitoring = monitoring;
2043   }
2044 }