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
 
 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  
 }