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  package org.waarp.ftp.simpleimpl.config;
21  
22  import org.dom4j.Document;
23  import org.dom4j.DocumentException;
24  import org.waarp.common.crypto.ssl.WaarpSecureKeyStore;
25  import org.waarp.common.crypto.ssl.WaarpSslContextFactory;
26  import org.waarp.common.exception.CryptoException;
27  import org.waarp.common.logging.WaarpLogger;
28  import org.waarp.common.logging.WaarpLoggerFactory;
29  import org.waarp.common.xml.XmlDecl;
30  import org.waarp.common.xml.XmlHash;
31  import org.waarp.common.xml.XmlType;
32  import org.waarp.common.xml.XmlUtil;
33  import org.waarp.common.xml.XmlValue;
34  import org.waarp.ftp.core.config.FtpConfiguration;
35  import org.waarp.ftp.core.control.ftps.FtpsInitializer;
36  
37  /**
38   * FtpConfiguration based on a XML file
39   */
40  public class FileBasedSslConfiguration {
41    /**
42     * Internal Logger
43     */
44    private static final WaarpLogger logger =
45        WaarpLoggerFactory.getLogger(FileBasedSslConfiguration.class);
46  
47    /**
48     * SERVER SSL STOREKEY PATH
49     */
50    private static final String XML_PATH_KEYPATH = "keypath";
51  
52    /**
53     * SERVER SSL KEY PASS
54     */
55    private static final String XML_PATH_KEYPASS = "keypass";
56  
57    /**
58     * SERVER SSL STOREKEY PASS
59     */
60    private static final String XML_PATH_KEYSTOREPASS = "keystorepass";
61  
62    /**
63     * SERVER SSL TRUSTSTOREKEY PATH
64     */
65    private static final String XML_PATH_TRUSTKEYPATH = "trustkeypath";
66  
67    /**
68     * SERVER SSL TRUSTSTOREKEY PASS
69     */
70    private static final String XML_PATH_TRUSTKEYSTOREPASS = "trustkeystorepass";
71  
72    /**
73     * SERVER SSL Use TrustStore for Client Authentication
74     */
75    private static final String XML_USECLIENT_AUTHENT =
76        "trustuseclientauthenticate";
77  
78    /**
79     * Structure of the Configuration file
80     */
81    private static final XmlDecl[] configSslDecls = {
82        // ssl
83        new XmlDecl(XmlType.STRING, XML_PATH_KEYPATH),
84        new XmlDecl(XmlType.STRING, XML_PATH_KEYSTOREPASS),
85        new XmlDecl(XmlType.STRING, XML_PATH_KEYPASS),
86        new XmlDecl(XmlType.STRING, XML_PATH_TRUSTKEYPATH),
87        new XmlDecl(XmlType.STRING, XML_PATH_TRUSTKEYSTOREPASS),
88        new XmlDecl(XmlType.BOOLEAN, XML_USECLIENT_AUTHENT)
89    };
90    /**
91     * Overall structure of the Configuration file
92     */
93    private static final String XML_ROOT = "/config/";
94    private static final String XML_SSL = "ssl";
95    /**
96     * Global Structure for Server Configuration
97     */
98    private static final XmlDecl[] configServer = {
99        new XmlDecl(XML_SSL, XmlType.XVAL, XML_ROOT + XML_SSL, configSslDecls,
100                   false)
101   };
102   private static XmlHash hashConfig;
103 
104   private FileBasedSslConfiguration() {
105   }
106 
107   protected static boolean loadSsl(final FtpConfiguration config) {
108     // StoreKey for Server
109     XmlValue value = hashConfig.get(XML_PATH_KEYPATH);
110     if (value == null || value.isEmpty()) {
111       logger.info("Unable to find Key Path");
112       try {
113         FtpsInitializer.waarpSecureKeyStore =
114             new WaarpSecureKeyStore("secret", "secret");
115       } catch (final CryptoException e) {
116         logger.error("Bad SecureKeyStore construction");
117         return false;
118       }
119     } else {
120       final String keypath = value.getString();
121       if (keypath == null || keypath.length() == 0) {
122         logger.error("Bad Key Path");
123         return false;
124       }
125       value = hashConfig.get(XML_PATH_KEYSTOREPASS);
126       if (value == null || value.isEmpty()) {
127         logger.error("Unable to find KeyStore Passwd");
128         return false;
129       }
130       final String keystorepass = value.getString();
131       if (keystorepass == null || keystorepass.length() == 0) {
132         logger.error("Bad KeyStore Passwd");
133         return false;
134       }
135       value = hashConfig.get(XML_PATH_KEYPASS);
136       if (value == null || value.isEmpty()) {
137         logger.error("Unable to find Key Passwd");
138         return false;
139       }
140       final String keypass = value.getString();
141       if (keypass == null || keypass.length() == 0) {
142         logger.error("Bad Key Passwd");
143         return false;
144       }
145       try {
146         FtpsInitializer.waarpSecureKeyStore =
147             new WaarpSecureKeyStore(keypath, keystorepass, keypass);
148       } catch (final CryptoException e) {
149         logger.error("Bad SecureKeyStore construction");
150         return false;
151       }
152 
153     }
154     // TrustedKey for OpenR66 server
155     value = hashConfig.get(XML_PATH_TRUSTKEYPATH);
156     if (value == null || value.isEmpty()) {
157       logger.info("Unable to find TRUST Key Path");
158       FtpsInitializer.waarpSecureKeyStore.initEmptyTrustStore();
159     } else {
160       final String keypath = value.getString();
161       if (keypath == null || keypath.length() == 0) {
162         logger.error("Bad TRUST Key Path");
163         return false;
164       }
165       value = hashConfig.get(XML_PATH_TRUSTKEYSTOREPASS);
166       if (value == null || value.isEmpty()) {
167         logger.error("Unable to find TRUST KeyStore Passwd");
168         return false;
169       }
170       final String keystorepass = value.getString();
171       if (keystorepass == null || keystorepass.length() == 0) {
172         logger.error("Bad TRUST KeyStore Passwd");
173         return false;
174       }
175       boolean useClientAuthent = false;
176       value = hashConfig.get(XML_USECLIENT_AUTHENT);
177       if (value != null && !value.isEmpty()) {
178         useClientAuthent = value.getBoolean();
179       }
180       try {
181         FtpsInitializer.waarpSecureKeyStore.initTrustStore(keypath,
182                                                            keystorepass,
183                                                            useClientAuthent);
184       } catch (final CryptoException e) {
185         logger.error("Bad TrustKeyStore construction");
186         return false;
187       }
188     }
189     FtpsInitializer.waarpSslContextFactory =
190         new WaarpSslContextFactory(FtpsInitializer.waarpSecureKeyStore);
191     return true;
192   }
193 
194   /**
195    * Initiate the configuration from the xml file for server
196    *
197    * @param filename
198    *
199    * @return True if OK
200    */
201   public static boolean setConfigurationServerFromXml(
202       final FtpConfiguration config, final String filename) {
203     final Document document;
204     // Open config file
205     try {
206       document = XmlUtil.getNewSaxReader().read(filename);
207     } catch (final DocumentException e) {
208       logger.error("Unable to read the XML Config file: " + filename + ": {}",
209                    e.getMessage());
210       return false;
211     }
212     if (document == null) {
213       logger.error("Unable to read the XML Config file: " + filename);
214       return false;
215     }
216     XmlValue[] configuration = XmlUtil.read(document, configServer);
217     hashConfig = new XmlHash(configuration);
218     // Now read the configuration
219     if (!loadSsl(config)) {
220       logger.error("Cannot load SSL configuration");
221       return false;
222     }
223     hashConfig.clear();
224     hashConfig = null;
225     configuration = null;
226     return true;
227   }
228 }