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 }