View Javadoc

1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, 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 GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package openr66.configuration;
22  
23  import goldengate.common.database.exception.GoldenGateDatabaseException;
24  import goldengate.common.database.exception.GoldenGateDatabaseNoConnectionException;
25  import goldengate.common.database.exception.GoldenGateDatabaseSqlException;
26  import goldengate.common.logging.GgInternalLogger;
27  import goldengate.common.logging.GgInternalLoggerFactory;
28  import goldengate.common.xml.XmlDecl;
29  import goldengate.common.xml.XmlHash;
30  import goldengate.common.xml.XmlType;
31  import goldengate.common.xml.XmlUtil;
32  import goldengate.common.xml.XmlValue;
33  
34  import java.io.File;
35  import java.io.IOException;
36  import java.util.Iterator;
37  import java.util.List;
38  
39  import openr66.database.DbConstant;
40  import openr66.database.data.DbHostAuth;
41  import openr66.protocol.configuration.Configuration;
42  import openr66.protocol.exception.OpenR66ProtocolSystemException;
43  
44  import org.dom4j.Document;
45  import org.dom4j.DocumentException;
46  import org.dom4j.DocumentHelper;
47  import org.dom4j.Element;
48  import org.dom4j.io.SAXReader;
49  import org.dom4j.tree.DefaultElement;
50  
51  /**
52   * Authentication from File support
53   *
54   * @author Frederic Bregier
55   *
56   */
57  public class AuthenticationFileBasedConfiguration {
58      /**
59       * Internal Logger
60       */
61      private static final GgInternalLogger logger = GgInternalLoggerFactory
62              .getLogger(AuthenticationFileBasedConfiguration.class);
63  
64      /**
65       * Authentication Fields
66       */
67      private static final String XML_AUTHENTIFICATION_ROOT = "authent";
68      /**
69       * Authentication Fields
70       */
71      private static final String XML_AUTHENTIFICATION_ENTRY = "entry";
72      /**
73       * Authentication Fields
74       */
75      private static final String XML_AUTHENTIFICATION_BASED = "/"+
76          XML_AUTHENTIFICATION_ROOT+"/"+XML_AUTHENTIFICATION_ENTRY;
77  
78      /**
79       * Authentication Fields
80       */
81      private static final String XML_AUTHENTIFICATION_HOSTID = "hostid";
82  
83      /**
84       * Authentication Fields
85       */
86      private static final String XML_AUTHENTIFICATION_KEYFILE = "keyfile";
87  
88      /**
89       * Authentication Fields
90       */
91      private static final String XML_AUTHENTIFICATION_KEY = "key";
92  
93      /**
94       * Authentication Fields
95       */
96      private static final String XML_AUTHENTIFICATION_ADMIN = "admin";
97  
98      /**
99       * Authentication Fields
100      */
101     private static final String XML_AUTHENTIFICATION_ADDRESS = "address";
102     /**
103      * Authentication Fields
104      */
105     private static final String XML_AUTHENTIFICATION_PORT = "port";
106     /**
107      * Authentication Fields
108      */
109     private static final String XML_AUTHENTIFICATION_ISSSL = "isssl";
110     /**
111      * Authentication Fields
112      */
113     private static final String XML_AUTHENTIFICATION_ISCLIENT = "isclient";
114     
115     /**
116      * Structure of the Configuration file
117      *
118      */
119     private static final XmlDecl [] configAuthenticationDecls = {
120         // identity
121         new XmlDecl(XmlType.STRING, XML_AUTHENTIFICATION_HOSTID), 
122         new XmlDecl(XmlType.STRING, XML_AUTHENTIFICATION_KEYFILE),
123         new XmlDecl(XmlType.STRING, XML_AUTHENTIFICATION_KEY),
124         new XmlDecl(XmlType.BOOLEAN, XML_AUTHENTIFICATION_ADMIN),
125         new XmlDecl(XmlType.STRING, XML_AUTHENTIFICATION_ADDRESS),
126         new XmlDecl(XmlType.INTEGER, XML_AUTHENTIFICATION_PORT),
127         new XmlDecl(XmlType.BOOLEAN, XML_AUTHENTIFICATION_ISSSL),
128         new XmlDecl(XmlType.BOOLEAN, XML_AUTHENTIFICATION_ISCLIENT)
129     };
130     /**
131      * Global Structure for Server Configuration
132      */
133     private static final XmlDecl[] authentElements = {
134         new XmlDecl(XML_AUTHENTIFICATION_ENTRY, XmlType.XVAL, XML_AUTHENTIFICATION_BASED, 
135                 configAuthenticationDecls, true)
136     };
137     /**
138      * Load Authentication from File
139      * @param filename
140      * @return True if OK
141      */
142     @SuppressWarnings("unchecked")
143     public static boolean loadAuthentication(Configuration config, String filename) {
144         Document document = null;
145         try {
146             document = new SAXReader().read(filename);
147         } catch (DocumentException e) {
148             logger.error("Unable to read the XML Authentication file: " +
149                     filename, e);
150             return false;
151         }
152         if (document == null) {
153             logger.error("Unable to read the XML Authentication file: " +
154                     filename);
155             return false;
156         }
157         XmlValue[] values = XmlUtil.read(document, authentElements);
158         XmlHash hash = new XmlHash(values);
159         XmlValue value = hash.get(XML_AUTHENTIFICATION_ENTRY);
160         List<XmlValue[]> list = (List<XmlValue[]>) value.getList();
161         Iterator<XmlValue[]> iterator = list.iterator();
162         File key;
163         byte[] byteKeys;
164         while (iterator.hasNext()) {
165             XmlValue [] subvalues = iterator.next();
166             XmlHash subHash = new XmlHash(subvalues);
167             value = subHash.get(XML_AUTHENTIFICATION_HOSTID);
168             if (value == null || (value.isEmpty())) {
169                 continue;
170             }
171             String refHostId = value.getString();
172             value = subHash.get(XML_AUTHENTIFICATION_KEYFILE);
173             if (value == null || (value.isEmpty())) {
174                 value = subHash.get(XML_AUTHENTIFICATION_KEY);
175                 if (value == null || (value.isEmpty())) {
176                     // Allow empty key
177                     byteKeys = null;
178                 } else {
179                     String skey = value.getString();
180                     // key is crypted
181                     if (skey.length() > 0) {
182                         try {
183                             byteKeys = config.cryptoKey.decryptHexInBytes(skey);
184                         } catch (Exception e) {
185                             logger.error("Cannot read key for hostId " + refHostId+":"+skey);
186                             continue;
187                         }
188                     } else {
189                         byteKeys = null;
190                     }
191                 }
192             } else {
193                 String skey = value.getString();
194                 // load key from file
195                 key = new File(skey);
196                 if (!key.canRead()) {
197                     logger.error("Cannot read key for hostId " + refHostId+":"+skey);
198                     continue;
199                 }
200                 try {
201                     byteKeys = config.cryptoKey.decryptHexFile(key);
202                 } catch (Exception e2) {
203                     logger.error("Cannot read key for hostId " + refHostId, e2);
204                     continue;
205                 }
206             }
207             boolean isAdmin = false;
208             value = subHash.get(XML_AUTHENTIFICATION_ADMIN);
209             if (value != null && (!value.isEmpty())) {
210                 isAdmin = value.getBoolean();
211             }
212             value = subHash.get(XML_AUTHENTIFICATION_ADDRESS);
213             if (value == null || (value.isEmpty())) {
214                 continue;
215             }
216             String address = value.getString();
217             int port;
218             value = subHash.get(XML_AUTHENTIFICATION_PORT);
219             if (value != null && (!value.isEmpty())) {
220                 port = value.getInteger();
221             } else {
222                 continue;
223             }
224             boolean isSsl = false;
225             value = subHash.get(XML_AUTHENTIFICATION_ISSSL);
226             if (value != null && (!value.isEmpty())) {
227                 isSsl = value.getBoolean();
228             }
229             boolean isClient = false;
230             value = subHash.get(XML_AUTHENTIFICATION_ISCLIENT);
231             if (value != null && (!value.isEmpty())) {
232                 isClient = value.getBoolean();
233             }
234             DbHostAuth auth = new DbHostAuth(DbConstant.admin.session,
235                     refHostId, address, port, isSsl, byteKeys, isAdmin, isClient);
236             try {
237                 if (auth.exist()) {
238                     auth.update();
239                 } else {
240                     auth.insert();
241                 }
242             } catch (GoldenGateDatabaseException e) {
243                 logger.error("Cannot create Authentication for hostId {}",refHostId);
244                 continue;
245             }
246             logger.debug("Add {} {}",refHostId,auth);
247         }
248         document = null;
249         hash.clear();
250         values = null;
251         return true;
252     }
253     /**
254      * Construct a new Element with value
255      * @param name
256      * @param value
257      * @return the new Element
258      */
259     private static Element newElement(String name, String value) {
260         Element node = new DefaultElement(name);
261         node.addText(value);
262         return node;
263     }
264     /**
265      * Write all authentication to a file with filename
266      * @param filename
267      * @throws OpenR66ProtocolSystemException
268      * @throws GoldenGateDatabaseNoConnectionException
269      * @throws GoldenGateDatabaseSqlException
270      */
271     public static void writeXML(Configuration config, String filename) throws OpenR66ProtocolSystemException, GoldenGateDatabaseNoConnectionException, GoldenGateDatabaseSqlException {
272         Document document = DocumentHelper.createDocument();
273         Element root = document.addElement(XML_AUTHENTIFICATION_ROOT);
274         DbHostAuth []hosts = DbHostAuth.getAllHosts(DbConstant.admin.session);
275         for (DbHostAuth auth: hosts) {
276             Element entry = new DefaultElement(XML_AUTHENTIFICATION_ENTRY);
277             entry.add(newElement(XML_AUTHENTIFICATION_HOSTID, auth.getHostid()));
278             byte [] key = auth.getHostkey();
279             String encode;
280             try {
281                 encode = config.cryptoKey.cryptToHex(key);
282             } catch (Exception e) {
283                encode = "";
284             }
285             entry.add(newElement(XML_AUTHENTIFICATION_KEY, encode));
286             entry.add(newElement(XML_AUTHENTIFICATION_ADMIN, Boolean.toString(auth.isAdminrole())));
287             entry.add(newElement(XML_AUTHENTIFICATION_ADDRESS, auth.getAddress()));
288             entry.add(newElement(XML_AUTHENTIFICATION_PORT, Integer.toString(auth.getPort())));
289             entry.add(newElement(XML_AUTHENTIFICATION_ISSSL, Boolean.toString(auth.isSsl())));
290             root.add(entry);
291         }
292         try {
293             XmlUtil.writeXML(filename, null, document);
294         } catch (IOException e) {
295             throw new OpenR66ProtocolSystemException("Cannot write file: "+filename, e);
296         }
297     }
298 }