View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2013 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.data.nvdcve;
19  
20  import java.time.Instant;
21  import java.time.ZoneId;
22  import java.time.ZonedDateTime;
23  import java.time.format.DateTimeFormatter;
24  import java.util.Map;
25  import java.util.Map.Entry;
26  import java.util.Properties;
27  import java.util.TreeMap;
28  import javax.annotation.concurrent.ThreadSafe;
29  
30  import org.owasp.dependencycheck.data.update.exception.UpdateException;
31  import org.owasp.dependencycheck.utils.DateUtil;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  /**
36   * This is a wrapper around a set of properties that are stored in the database.
37   * This class is safe to be accessed from multiple threads in parallel.
38   *
39   * @author Jeremy Long
40   */
41  @ThreadSafe
42  public class DatabaseProperties {
43  
44      /**
45       * The Logger.
46       */
47      private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class);
48      /**
49       * The last modified request data for the NVD API.
50       */
51      public static final String NVD_API_LAST_MODIFIED = "nvd.api.last.modified";
52      /**
53       * The date the NVD API was last checked for an update.
54       */
55      public static final String NVD_API_LAST_CHECKED = "nvd.api.last.checked";
56      /**
57       * The date the NVD cache was last checked for an update.
58       */
59      public static final String NVD_CACHE_LAST_CHECKED = "nvd.cache.last.checked";
60      /**
61       * The date the NVD cache data was last modified/updated.
62       */
63      public static final String NVD_CACHE_LAST_MODIFIED = "nvd.cache.last.modified";
64      /**
65       * The key for the last time the CPE data was updated.
66       */
67      public static final String LAST_CPE_UPDATE = "LAST_CPE_UPDATE";
68      /**
69       * The key for the database schema version.
70       */
71      public static final String VERSION = "version";
72      /**
73       * The key for the last check time for the Known Exploited Vulnerabilities.
74       */
75      public static final String KEV_LAST_CHECKED = "kev.checked";
76      /**
77       * The key for the last check time for the Retire JS repository.
78       */
79      public static final String RETIRE_LAST_CHECKED = "retirejs.checked";
80      /**
81       * The key for the last check time for the hosted suppression file.
82       */
83      public static final String HOSTED_SUPPRESSION_LAST_CHECKED = "hosted.suppression.checked";
84      /**
85       * The key for the version the Known Exploited Vulnerabilities.
86       */
87      public static final String KEV_VERSION = "kev.version";
88      /**
89       * A collection of properties about the data.
90       */
91      private final Properties properties;
92      /**
93       * A reference to the database.
94       */
95      private final CveDB cveDB;
96  
97      /**
98       * Constructs a new data properties object.
99       *
100      * @param cveDB the database object holding the properties
101      */
102     DatabaseProperties(CveDB cveDB) {
103         this.cveDB = cveDB;
104         this.properties = cveDB.getProperties();
105     }
106 
107     /**
108      * Returns whether or not any properties are set.
109      *
110      * @return whether or not any properties are set
111      */
112     public synchronized boolean isEmpty() {
113         return properties == null || properties.isEmpty();
114     }
115 
116     /**
117      * Saves the key value pair to the properties store.
118      *
119      * @param key the property key
120      * @param value the property value
121      * @throws UpdateException is thrown if there is an update exception
122      */
123     public synchronized void save(String key, String value) throws UpdateException {
124         properties.put(key, value);
125         cveDB.saveProperty(key, value);
126     }
127 
128     /**
129      * Returns the property value for the given key. If the key is not contained
130      * in the underlying properties null is returned.
131      *
132      * @param key the property key
133      * @return the value of the property
134      */
135     public synchronized String getProperty(String key) {
136         return properties.getProperty(key);
137     }
138 
139     /**
140      * Returns the property value for the given key. If the key is not contained
141      * in the underlying properties the default value is returned.
142      *
143      * @param key the property key
144      * @param defaultValue the default value
145      * @return the value of the property
146      */
147     public synchronized String getProperty(String key, String defaultValue) {
148         return properties.getProperty(key, defaultValue);
149     }
150 
151     /**
152      * Returns the collection of Database Properties as a properties collection.
153      *
154      * @return the collection of Database Properties
155      */
156     public synchronized Properties getProperties() {
157         return properties;
158     }
159 
160     /**
161      * Returns a map of the meta data from the database properties. This
162      * primarily contains timestamps of when the NVD CVE information was last
163      * updated.
164      *
165      * @return a map of the database meta data
166      */
167     public synchronized Map<String, String> getMetaData() {
168         final Map<String, String> map = new TreeMap<>();
169         for (Entry<Object, Object> entry : properties.entrySet()) {
170             final String key = (String) entry.getKey();
171             if (!"version".equals(key)) {
172                 if (DatabaseProperties.NVD_API_LAST_CHECKED.equals(key)) {
173                     map.put("NVD API Last Checked", entry.getValue().toString());
174 
175                 } else if (DatabaseProperties.NVD_API_LAST_MODIFIED.equals(key)) {
176                     map.put("NVD API Last Modified", entry.getValue().toString());
177 
178                 } else if (DatabaseProperties.NVD_CACHE_LAST_CHECKED.equals(key)) {
179                     map.put("NVD Cache Last Checked", entry.getValue().toString());
180 
181                 } else if (DatabaseProperties.NVD_CACHE_LAST_MODIFIED.equals(key)) {
182                     map.put("NVD Cache Last Modified", entry.getValue().toString());
183                 }
184             }
185         }
186         return map;
187     }
188 
189     /**
190      * Retrieves a zoned date time.
191      *
192      * @param key the property key
193      * @return the zoned date time
194      */
195     public ZonedDateTime getTimestamp(String key) {
196         return DatabaseProperties.getTimestamp(properties, key);
197     }
198 
199     /**
200      * Stores a timestamp.
201      *
202      * @param key the property key
203      * @param timestamp the zoned date time
204      */
205     public void save(String key, ZonedDateTime timestamp) throws UpdateException {
206         final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
207         save(key, dtf.format(timestamp));
208     }
209 
210     /**
211      * Stores a timestamp in the properties file.
212      *
213      * @param properties the properties to store the timestamp
214      * @param key the property key
215      * @param timestamp the zoned date time
216      */
217     public static void setTimestamp(Properties properties, String key, ZonedDateTime timestamp) throws UpdateException {
218         final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
219         properties.put(key, dtf.format(timestamp));
220     }
221 
222     /**
223      * Retrieves a zoned date time.
224      *
225      * @param properties the properties file containing the date time
226      * @param key the property key
227      * @return the zoned date time
228      */
229     public static ZonedDateTime getTimestamp(Properties properties, String key) {
230         final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
231         final String val = properties.getProperty(key);
232         if (val != null) {
233             final String value = properties.getProperty(key);
234             return ZonedDateTime.parse(value, dtf);
235         }
236         return null;
237     }
238 
239     /**
240      * Retrieves a zoned date time.
241      *
242      * @param properties the properties file containing the date time
243      * @param key the property key
244      * @return the zoned date time
245      */
246     public static ZonedDateTime getIsoTimestamp(Properties properties, String key) {
247         //final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
248         final DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
249         final String val = properties.getProperty(key);
250         if (val != null) {
251             final String value = properties.getProperty(key);
252             return ZonedDateTime.parse(value, dtf);
253         }
254         return null;
255     }
256 
257     /**
258      * Returns the database property value in seconds.
259      *
260      * @param key the key to the property
261      * @return the property value in seconds
262      */
263     public long getPropertyInSeconds(String key) {
264         final String value = getProperty(key, "0");
265         return DateUtil.getEpochValueInSeconds(value);
266     }
267 
268 }