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.ZonedDateTime;
21  import java.time.format.DateTimeFormatter;
22  import java.util.Map;
23  import java.util.Map.Entry;
24  import java.util.Properties;
25  import java.util.TreeMap;
26  import javax.annotation.concurrent.ThreadSafe;
27  
28  import org.owasp.dependencycheck.utils.DateUtil;
29  import org.slf4j.Logger;
30  import org.slf4j.LoggerFactory;
31  
32  /**
33   * This is a wrapper around a set of properties that are stored in the database.
34   * This class is safe to be accessed from multiple threads in parallel.
35   *
36   * @author Jeremy Long
37   */
38  @ThreadSafe
39  public class DatabaseProperties {
40  
41      /**
42       * The Logger.
43       */
44      private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseProperties.class);
45      /**
46       * The last modified request data for the NVD API.
47       */
48      public static final String NVD_API_LAST_MODIFIED = "nvd.api.last.modified";
49      /**
50       * The date the NVD API was last checked for an update.
51       */
52      public static final String NVD_API_LAST_CHECKED = "nvd.api.last.checked";
53      /**
54       * The date the NVD cache was last checked for an update.
55       */
56      public static final String NVD_CACHE_LAST_CHECKED = "nvd.cache.last.checked";
57      /**
58       * The date the NVD cache data was last modified/updated.
59       */
60      public static final String NVD_CACHE_LAST_MODIFIED = "nvd.cache.last.modified";
61      /**
62       * The key for the last time the CPE data was updated.
63       */
64      public static final String LAST_CPE_UPDATE = "LAST_CPE_UPDATE";
65      /**
66       * The key for the database schema version.
67       */
68      public static final String VERSION = "version";
69      /**
70       * The key for the last check time for the Known Exploited Vulnerabilities.
71       */
72      public static final String KEV_LAST_CHECKED = "kev.checked";
73      /**
74       * The key for the version the Known Exploited Vulnerabilities.
75       */
76      public static final String KEV_VERSION = "kev.version";
77      /**
78       * A collection of properties about the data.
79       */
80      private final Properties properties;
81      /**
82       * A reference to the database.
83       */
84      private final CveDB cveDB;
85  
86      /**
87       * Constructs a new data properties object.
88       *
89       * @param cveDB the database object holding the properties
90       */
91      DatabaseProperties(CveDB cveDB) {
92          this.cveDB = cveDB;
93          this.properties = cveDB.getProperties();
94      }
95  
96      /**
97       * Returns whether or not any properties are set.
98       *
99       * @return whether or not any properties are set
100      */
101     public synchronized boolean isEmpty() {
102         return properties == null || properties.isEmpty();
103     }
104 
105     /**
106      * Saves the key value pair to the properties store.
107      *
108      * @param key the property key
109      * @param value the property value
110      */
111     public synchronized void save(String key, String value) {
112         properties.put(key, value);
113         cveDB.saveProperty(key, value);
114     }
115 
116     /**
117      * Returns the property value for the given key. If the key is not contained
118      * in the underlying properties null is returned.
119      *
120      * @param key the property key
121      * @return the value of the property
122      */
123     public synchronized String getProperty(String key) {
124         return properties.getProperty(key);
125     }
126 
127     /**
128      * Returns the property value for the given key. If the key is not contained
129      * in the underlying properties the default value is returned.
130      *
131      * @param key the property key
132      * @param defaultValue the default value
133      * @return the value of the property
134      */
135     public synchronized String getProperty(String key, String defaultValue) {
136         return properties.getProperty(key, defaultValue);
137     }
138 
139     /**
140      * Returns the collection of Database Properties as a properties collection.
141      *
142      * @return the collection of Database Properties
143      */
144     public synchronized Properties getProperties() {
145         return properties;
146     }
147 
148     /**
149      * Returns a map of the meta data from the database properties. This
150      * primarily contains timestamps of when the NVD CVE information was last
151      * updated.
152      *
153      * @return a map of the database meta data
154      */
155     public synchronized Map<String, String> getMetaData() {
156         final Map<String, String> map = new TreeMap<>();
157         for (Entry<Object, Object> entry : properties.entrySet()) {
158             final String key = (String) entry.getKey();
159             if (!"version".equals(key)) {
160                 if (DatabaseProperties.NVD_API_LAST_CHECKED.equals(key)) {
161                     map.put("NVD API Last Checked", entry.getValue().toString());
162 
163                 } else if (DatabaseProperties.NVD_API_LAST_MODIFIED.equals(key)) {
164                     map.put("NVD API Last Modified", entry.getValue().toString());
165 
166                 } else if (DatabaseProperties.NVD_CACHE_LAST_CHECKED.equals(key)) {
167                     map.put("NVD Cache Last Checked", entry.getValue().toString());
168 
169                 } else if (DatabaseProperties.NVD_CACHE_LAST_MODIFIED.equals(key)) {
170                     map.put("NVD Cache Last Modified", entry.getValue().toString());
171                 }
172             }
173         }
174         return map;
175     }
176 
177     /**
178      * Retrieves a zoned date time.
179      *
180      * @param key the property key
181      * @return the zoned date time
182      */
183     public ZonedDateTime getTimestamp(String key) {
184         return DatabaseProperties.getTimestamp(properties, key);
185     }
186 
187     /**
188      * Stores a timestamp.
189      *
190      * @param key the property key
191      * @param timestamp the zoned date time
192      */
193     public void save(String key, ZonedDateTime timestamp) {
194         final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
195         save(key, dtf.format(timestamp));
196     }
197 
198     /**
199      * Stores a timestamp in the properties file.
200      *
201      * @param properties the properties to store the timestamp
202      * @param key the property key
203      * @param timestamp the zoned date time
204      */
205     public static void setTimestamp(Properties properties, String key, ZonedDateTime timestamp) {
206         final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
207         properties.put(key, dtf.format(timestamp));
208     }
209 
210     /**
211      * Retrieves a zoned date time.
212      *
213      * @param properties the properties file containing the date time
214      * @param key the property key
215      * @return the zoned date time
216      */
217     public static ZonedDateTime getTimestamp(Properties properties, String key) {
218         final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
219         final String val = properties.getProperty(key);
220         if (val != null) {
221             final String value = properties.getProperty(key);
222             return ZonedDateTime.parse(value, dtf);
223         }
224         return null;
225     }
226 
227     /**
228      * Retrieves a zoned date time.
229      *
230      * @param properties the properties file containing the date time
231      * @param key the property key
232      * @return the zoned date time
233      */
234     public static ZonedDateTime getIsoTimestamp(Properties properties, String key) {
235         //final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssX");
236         final DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
237         final String val = properties.getProperty(key);
238         if (val != null) {
239             final String value = properties.getProperty(key);
240             return ZonedDateTime.parse(value, dtf);
241         }
242         return null;
243     }
244 
245     /**
246      * Returns the database property value in seconds.
247      *
248      * @param key the key to the property
249      * @return the property value in seconds
250      */
251     public long getPropertyInSeconds(String key) {
252         final String value = getProperty(key, "0");
253         return DateUtil.getEpochValueInSeconds(value);
254     }
255 
256 }