##### Coverage Report - org.owasp.dependencycheck.data.update.AbstractUpdateTask

Classes in this File | Line Coverage | Branch Coverage | Complexity
AbstractUpdateTask |
51% | 37/72
83% | 10/12
| 2.0;2

1 |  |
     /*
2 |  |
      * This file is part of dependency-check-core.
3 |  |
      *
4 |  |
      * Dependency-check-core is free software: you can redistribute it and/or modify it
5 |  |
      * under the terms of the GNU General Public License as published by the Free
6 |  |
      * Software Foundation, either version 3 of the License, or (at your option) any
7 |  |
      * later version.
8 |  |
      *
9 |  |
      * Dependency-check-core is distributed in the hope that it will be useful, but
10 |  |
      * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 |  |
      * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 |  |
      * details.
13 |  |
      *
14 |  |
      * You should have received a copy of the GNU General Public License along with
15 |  |
      * dependency-check-core. If not, see http://www.gnu.org/licenses/.
16 |  |
      *
17 |  |
      * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
18 |  |
      */
19 |  |
     package org.owasp.dependencycheck.data.update;
20 |  |
21 |  |
     import java.io.File;
22 |  |
     import java.io.IOException;
23 |  |
     import java.net.MalformedURLException;
24 |  |
     import java.sql.SQLException;
25 |  |
     import java.util.List;
26 |  |
     import java.util.Map;
27 |  |
     import java.util.logging.Level;
28 |  |
     import java.util.logging.Logger;
29 |  |
     import javax.xml.parsers.ParserConfigurationException;
30 |  |
     import javax.xml.parsers.SAXParser;
31 |  |
     import javax.xml.parsers.SAXParserFactory;
32 |  |
     import org.owasp.dependencycheck.data.UpdateException;
33 |  |
     import org.owasp.dependencycheck.data.cpe.CpeIndexWriter;
34 |  |
     import org.owasp.dependencycheck.data.nvdcve.CveDB;
35 |  |
     import org.owasp.dependencycheck.utils.FileUtils;
36 |  |
     import org.owasp.dependencycheck.utils.Settings;
37 |  |
     import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
38 |  |
     import org.owasp.dependencycheck.data.nvdcve.NvdCve12Handler;
39 |  |
     import org.owasp.dependencycheck.data.nvdcve.NvdCve20Handler;
40 |  |
     import org.owasp.dependencycheck.dependency.VulnerableSoftware;
41 |  |
     import org.owasp.dependencycheck.utils.DownloadFailedException;
42 |  |
     import org.xml.sax.SAXException;
43 |  |
44 |  |
     /**
45 |  |
      * Class responsible for updating the CPE and NVDCVE data stores.
46 |  |
      *
47 |  |
      * @author Jeremy Long (jeremy.long@owasp.org)
48 |  |
      */
49 |  |
     public abstract class AbstractUpdateTask implements UpdateTask {
50 |  |
51 |  |
         /**
52 |  |
          * Initializes the AbstractUpdateTask.
53 |  |
          *
54 |  |
          * @param properties information about the data store
55 |  |
          * @throws MalformedURLException thrown if the configuration contains a
56 |  |
          * malformed url
57 |  |
          * @throws DownloadFailedException thrown if the timestamp on a file cannot
58 |  |
          * be checked
59 |  |
          * @throws UpdateException thrown if the update fails
60 |  |
          */
61 | 6 |
         public AbstractUpdateTask(DataStoreMetaInfo properties) throws MalformedURLException, DownloadFailedException, UpdateException {
62 | 6 |
             this.properties = properties;
63 | 6 |
             this.updateable = updatesNeeded();
64 | 6 |
         }
65 |  |
         /**
66 |  |
          * A collection of updateable NVD CVE items.
67 |  |
          */
68 |  |
         private Updateable updateable;
69 |  |
         /**
70 |  |
          * Utility to read and write meta-data about the data.
71 |  |
          */
72 | 6 |
         private DataStoreMetaInfo properties = null;
73 |  |
74 |  |
         /**
75 |  |
          * Returns the data store properties.
76 |  |
          *
77 |  |
          * @return the data store properties
78 |  |
          */
79 |  |
         protected DataStoreMetaInfo getProperties() {
80 | 3 |
             return properties;
81 |  |
         }
82 |  |
         /**
83 |  |
          * Reference to the Cve Database.
84 |  |
          */
85 | 6 |
         private CveDB cveDB = null;
86 |  |
87 |  |
         /**
88 |  |
          * Returns the CveDB.
89 |  |
          *
90 |  |
          * @return the CveDB
91 |  |
          */
92 |  |
         protected CveDB getCveDB() {
93 | 0 |
             return cveDB;
94 |  |
         }
95 |  |
         /**
96 |  |
          * Reference to the Cpe Index.
97 |  |
          */
98 | 6 |
         private CpeIndexWriter cpeIndex = null;
99 |  |
100 |  |
         /**
101 |  |
          * Returns the CpeIndex.
102 |  |
          *
103 |  |
          * @return the CpeIndex
104 |  |
          */
105 |  |
         protected CpeIndexWriter getCpeIndex() {
106 | 0 |
             return cpeIndex;
107 |  |
         }
108 |  |
109 |  |
         /**
110 |  |
          * Gets whether or not an update is needed.
111 |  |
          *
112 |  |
          * @return true or false depending on whether an update is needed
113 |  |
          */
114 |  |
         public boolean isUpdateNeeded() {
115 | 0 |
             return updateable.isUpdateNeeded();
116 |  |
         }
117 |  |
118 |  |
         /**
119 |  |
          * Gets the updateable NVD CVE Entries.
120 |  |
          *
121 |  |
          * @return an Updateable object containing the NVD CVE entries
122 |  |
          */
123 |  |
         protected Updateable getUpdateable() {
124 | 0 |
             return updateable;
125 |  |
         }
126 |  |
127 |  |
         /**
128 |  |
          * Determines if the index needs to be updated.
129 |  |
          *
130 |  |
          * @return a collection of updateable resources.
131 |  |
          * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta
132 |  |
          * data is incorrect.
133 |  |
          * @throws DownloadFailedException is thrown if there is an error.
134 |  |
          * downloading the NVD CVE download data file.
135 |  |
          * @throws UpdateException Is thrown if there is an issue with the last
136 |  |
          * updated properties file.
137 |  |
          */
138 |  |
         protected abstract Updateable updatesNeeded() throws MalformedURLException, DownloadFailedException, UpdateException;
139 |  |
140 |  |
         /**
141 |  |
          * <p>Updates the data store to the latest version.</p>
142 |  |
          *
143 |  |
          * @throws UpdateException is thrown if there is an error updating the
144 |  |
          * database
145 |  |
          */
146 |  |
         public abstract void update() throws UpdateException;
147 |  |
         /**
148 |  |
          * A flag indicating whether or not the current data store should be
149 |  |
          * deleted.
150 |  |
          */
151 | 6 |
         private boolean deleteAndRecreate = false;
152 |  |
153 |  |
         /**
154 |  |
          * Get the value of deleteAndRecreate.
155 |  |
          *
156 |  |
          * @return the value of deleteAndRecreate
157 |  |
          */
158 |  |
         public boolean shouldDeleteAndRecreate() {
159 | 1 |
             return deleteAndRecreate;
160 |  |
         }
161 |  |
162 |  |
         /**
163 |  |
          * Set the value of deleteAndRecreate.
164 |  |
          *
165 |  |
          * @param deleteAndRecreate new value of deleteAndRecreate
166 |  |
          */
167 |  |
         protected void setDeleteAndRecreate(boolean deleteAndRecreate) {
168 | 1 |
             this.deleteAndRecreate = deleteAndRecreate;
169 | 1 |
         }
170 |  |
171 |  |
         /**
172 |  |
          * Deletes the existing data directories.
173 |  |
          *
174 |  |
          * @throws IOException thrown if the directory cannot be deleted
175 |  |
          */
176 |  |
         protected void deleteExistingData() throws IOException {
177 | 3 |
             File data = Settings.getFile(Settings.KEYS.CVE_DATA_DIRECTORY);
178 | 3 |
             if (data.exists()) {
179 | 1 |
                 FileUtils.delete(data);
180 |  |
             }
181 | 3 |
             data = Settings.getFile(Settings.KEYS.CPE_DATA_DIRECTORY);
182 | 3 |
             if (data.exists()) {
183 | 1 |
                 FileUtils.delete(data);
184 |  |
             }
185 | 3 |
             data = DataStoreMetaInfo.getPropertiesFile();
186 | 3 |
             if (data.exists()) {
187 | 1 |
                 FileUtils.delete(data);
188 |  |
             }
189 | 3 |
         }
190 |  |
191 |  |
         /**
192 |  |
          * Closes the CVE and CPE data stores.
193 |  |
          */
194 |  |
         protected void closeDataStores() {
195 | 1 |
             if (cveDB != null) {
196 |  |
                 try {
197 | 1 |
                     cveDB.close();
198 | 0 |
                 } catch (Exception ignore) {
199 | 0 |
                     Logger.getLogger(AbstractUpdateTask.class.getName()).log(Level.FINEST, "Error closing the cveDB", ignore);
200 | 1 |
                 }
201 |  |
             }
202 | 1 |
             if (cpeIndex != null) {
203 |  |
                 try {
204 | 1 |
                     cpeIndex.close();
205 | 0 |
                 } catch (Exception ignore) {
206 | 0 |
                     Logger.getLogger(AbstractUpdateTask.class.getName()).log(Level.FINEST, "Error closing the cpeIndex", ignore);
207 | 1 |
                 }
208 |  |
             }
209 | 1 |
         }
210 |  |
211 |  |
         /**
212 |  |
          * Opens the CVE and CPE data stores.
213 |  |
          *
214 |  |
          * @throws UpdateException thrown if a data store cannot be opened
215 |  |
          */
216 |  |
         protected void openDataStores() throws UpdateException {
217 |  |
             //open the cve and cpe data stores
218 |  |
             try {
219 | 1 |
                 cveDB = new CveDB();
220 | 1 |
                 cveDB.open();
221 | 1 |
                 cpeIndex = new CpeIndexWriter();
222 | 1 |
                 cpeIndex.open();
223 | 0 |
             } catch (IOException ex) {
224 | 0 |
                 closeDataStores();
225 | 0 |
                 Logger.getLogger(AbstractUpdateTask.class.getName()).log(Level.FINE, "IO Error opening databases", ex);
226 | 0 |
                 throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
227 | 0 |
             } catch (SQLException ex) {
228 | 0 |
                 closeDataStores();
229 | 0 |
                 Logger.getLogger(AbstractUpdateTask.class.getName()).log(Level.FINE, "SQL Exception opening databases", ex);
230 | 0 |
                 throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
231 | 0 |
             } catch (DatabaseException ex) {
232 | 0 |
                 closeDataStores();
233 | 0 |
                 Logger.getLogger(AbstractUpdateTask.class.getName()).log(Level.FINE, "Database Exception opening databases", ex);
234 | 0 |
                 throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
235 | 0 |
             } catch (ClassNotFoundException ex) {
236 | 0 |
                 closeDataStores();
237 | 0 |
                 Logger.getLogger(AbstractUpdateTask.class.getName()).log(Level.FINE, "Class not found exception opening databases", ex);
238 | 0 |
                 throw new UpdateException("Error updating the CPE/CVE data, please see the log file for more details.");
239 | 1 |
             }
240 | 1 |
         }
241 |  |
242 |  |
         /**
243 |  |
          * Determines if the epoch date is within the range specified of the
244 |  |
          * compareTo epoch time. This takes the (compareTo-date)/1000/60/60/24 to
245 |  |
          * get the number of days. If the calculated days is less then the range the
246 |  |
          * date is considered valid.
247 |  |
          *
248 |  |
          * @param date the date to be checked.
249 |  |
          * @param compareTo the date to compare to.
250 |  |
          * @param range the range in days to be considered valid.
251 |  |
          * @return whether or not the date is within the range.
252 |  |
          */
253 |  |
         protected boolean withinRange(long date, long compareTo, int range) {
254 | 2 |
             final double differenceInDays = (compareTo - date) / 1000.0 / 60.0 / 60.0 / 24.0;
255 | 2 |
             return differenceInDays < range;
256 |  |
         }
257 |  |
258 |  |
         /**
259 |  |
          * Imports the NVD CVE XML File into the Lucene Index.
260 |  |
          *
261 |  |
          * @param file the file containing the NVD CVE XML
262 |  |
          * @param oldVersion contains the file containing the NVD CVE XML 1.2
263 |  |
          * @throws ParserConfigurationException is thrown if there is a parser
264 |  |
          * configuration exception
265 |  |
          * @throws SAXException is thrown if there is a SAXException
266 |  |
          * @throws IOException is thrown if there is a IO Exception
267 |  |
          * @throws SQLException is thrown if there is a SQL exception
268 |  |
          * @throws DatabaseException is thrown if there is a database exception
269 |  |
          * @throws ClassNotFoundException thrown if the h2 database driver cannot be
270 |  |
          * loaded
271 |  |
          */
272 |  |
         protected void importXML(File file, File oldVersion)
273 |  |
                 throws ParserConfigurationException, SAXException, IOException, SQLException, DatabaseException, ClassNotFoundException {
274 |  |
275 | 0 |
             final SAXParserFactory factory = SAXParserFactory.newInstance();
276 | 0 |
             final SAXParser saxParser = factory.newSAXParser();
277 |  |
278 | 0 |
             final NvdCve12Handler cve12Handler = new NvdCve12Handler();
279 | 0 |
             saxParser.parse(oldVersion, cve12Handler);
280 | 0 |
             final Map<String, List<VulnerableSoftware>> prevVersionVulnMap = cve12Handler.getVulnerabilities();
281 |  |
282 | 0 |
             final NvdCve20Handler cve20Handler = new NvdCve20Handler();
283 | 0 |
             cve20Handler.setCveDB(cveDB);
284 | 0 |
             cve20Handler.setPrevVersionVulnMap(prevVersionVulnMap);
285 | 0 |
             cve20Handler.setCpeIndex(cpeIndex);
286 | 0 |
             saxParser.parse(file, cve20Handler);
287 | 0 |
         }
288 |  |
     }