1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.owasp.dependencycheck.data.nvdcve;
19
20 import java.io.IOException;
21 import java.io.UnsupportedEncodingException;
22 import java.sql.Connection;
23 import java.sql.PreparedStatement;
24 import java.sql.ResultSet;
25 import java.sql.SQLException;
26 import java.sql.Statement;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.Map.Entry;
34 import java.util.MissingResourceException;
35 import java.util.Properties;
36 import java.util.ResourceBundle;
37 import java.util.Set;
38 import org.owasp.dependencycheck.data.cwe.CweDB;
39 import org.owasp.dependencycheck.dependency.Reference;
40 import org.owasp.dependencycheck.dependency.Vulnerability;
41 import org.owasp.dependencycheck.dependency.VulnerableSoftware;
42 import org.owasp.dependencycheck.utils.DBUtils;
43 import org.owasp.dependencycheck.utils.DependencyVersion;
44 import org.owasp.dependencycheck.utils.DependencyVersionUtil;
45 import org.owasp.dependencycheck.utils.Pair;
46 import org.owasp.dependencycheck.utils.Settings;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
49
50
51
52
53
54
55 public class CveDB {
56
57
58
59
60 private static final Logger LOGGER = LoggerFactory.getLogger(CveDB.class);
61
62
63
64 private Connection conn;
65
66
67
68 private ResourceBundle statementBundle = null;
69
70
71
72
73
74
75 private boolean batchSupported;
76
77
78
79
80
81
82
83
84 public CveDB() throws DatabaseException {
85 super();
86 try {
87 open();
88 try {
89 final String databaseProductName = conn.getMetaData().getDatabaseProductName();
90 batchSupported = conn.getMetaData().supportsBatchUpdates();
91 LOGGER.debug("Database dialect: {}", databaseProductName);
92 final Locale dbDialect = new Locale(databaseProductName);
93 statementBundle = ResourceBundle.getBundle("data/dbStatements", dbDialect);
94 } catch (SQLException se) {
95 LOGGER.warn("Problem loading database specific dialect!", se);
96 statementBundle = ResourceBundle.getBundle("data/dbStatements");
97 }
98 databaseProperties = new DatabaseProperties(this);
99 } catch (DatabaseException ex) {
100 throw ex;
101 }
102 }
103
104
105
106
107
108
109 protected Connection getConnection() {
110 return conn;
111 }
112
113
114
115
116
117
118
119
120 public final void open() throws DatabaseException {
121 if (!isOpen()) {
122 conn = ConnectionFactory.getConnection();
123 }
124 }
125
126
127
128
129
130 public void close() {
131 if (conn != null) {
132 try {
133 conn.close();
134 } catch (SQLException ex) {
135 LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
136 LOGGER.debug("", ex);
137 } catch (Throwable ex) {
138 LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details.");
139 LOGGER.debug("", ex);
140 }
141 conn = null;
142 }
143 }
144
145
146
147
148
149
150 public boolean isOpen() {
151 return conn != null;
152 }
153
154
155
156
157
158
159 public void commit() throws SQLException {
160
161
162
163
164 }
165
166
167
168
169
170
171 @Override
172 @SuppressWarnings("FinalizeDeclaration")
173 protected void finalize() throws Throwable {
174 LOGGER.debug("Entering finalize");
175 close();
176 super.finalize();
177 }
178
179
180
181
182 private DatabaseProperties databaseProperties;
183
184
185
186
187
188
189 public DatabaseProperties getDatabaseProperties() {
190 return databaseProperties;
191 }
192
193
194
195
196
197
198
199
200
201
202
203 public Set<VulnerableSoftware> getCPEs(String vendor, String product) {
204 final Set<VulnerableSoftware> cpe = new HashSet<VulnerableSoftware>();
205 ResultSet rs = null;
206 PreparedStatement ps = null;
207 try {
208 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ENTRIES"));
209 ps.setString(1, vendor);
210 ps.setString(2, product);
211 rs = ps.executeQuery();
212
213 while (rs.next()) {
214 final VulnerableSoftware vs = new VulnerableSoftware();
215 vs.setCpe(rs.getString(1));
216 cpe.add(vs);
217 }
218 } catch (SQLException ex) {
219 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
220 LOGGER.debug("", ex);
221 } finally {
222 DBUtils.closeResultSet(rs);
223 DBUtils.closeStatement(ps);
224 }
225 return cpe;
226 }
227
228
229
230
231
232
233
234
235 public Set<Pair<String, String>> getVendorProductList() throws DatabaseException {
236 final Set<Pair<String, String>> data = new HashSet<Pair<String, String>>();
237 ResultSet rs = null;
238 PreparedStatement ps = null;
239 try {
240 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_VENDOR_PRODUCT_LIST"));
241 rs = ps.executeQuery();
242 while (rs.next()) {
243 data.add(new Pair<String, String>(rs.getString(1), rs.getString(2)));
244 }
245 } catch (SQLException ex) {
246 final String msg = "An unexpected SQL Exception occurred; please see the verbose log for more details.";
247 throw new DatabaseException(msg, ex);
248 } finally {
249 DBUtils.closeResultSet(rs);
250 DBUtils.closeStatement(ps);
251 }
252 return data;
253 }
254
255
256
257
258
259
260 Properties getProperties() {
261 final Properties prop = new Properties();
262 PreparedStatement ps = null;
263 ResultSet rs = null;
264 try {
265 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_PROPERTIES"));
266 rs = ps.executeQuery();
267 while (rs.next()) {
268 prop.setProperty(rs.getString(1), rs.getString(2));
269 }
270 } catch (SQLException ex) {
271 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
272 LOGGER.debug("", ex);
273 } finally {
274 DBUtils.closeStatement(ps);
275 DBUtils.closeResultSet(rs);
276 }
277 return prop;
278 }
279
280
281
282
283
284
285
286 void saveProperty(String key, String value) {
287 try {
288 try {
289 final PreparedStatement mergeProperty = getConnection().prepareStatement(statementBundle.getString("MERGE_PROPERTY"));
290 try {
291 mergeProperty.setString(1, key);
292 mergeProperty.setString(2, value);
293 mergeProperty.executeUpdate();
294 } finally {
295 DBUtils.closeStatement(mergeProperty);
296 }
297 } catch (MissingResourceException mre) {
298
299 PreparedStatement updateProperty = null;
300 PreparedStatement insertProperty = null;
301 try {
302 updateProperty = getConnection().prepareStatement(statementBundle.getString("UPDATE_PROPERTY"));
303 updateProperty.setString(1, value);
304 updateProperty.setString(2, key);
305 if (updateProperty.executeUpdate() == 0) {
306 insertProperty = getConnection().prepareStatement(statementBundle.getString("INSERT_PROPERTY"));
307 insertProperty.setString(1, key);
308 insertProperty.setString(2, value);
309 insertProperty.executeUpdate();
310 }
311 } finally {
312 DBUtils.closeStatement(updateProperty);
313 DBUtils.closeStatement(insertProperty);
314 }
315 }
316 } catch (SQLException ex) {
317 LOGGER.warn("Unable to save property '{}' with a value of '{}' to the database", key, value);
318 LOGGER.debug("", ex);
319 }
320 }
321
322
323
324
325
326
327
328
329 public List<Vulnerability> getVulnerabilities(String cpeStr) throws DatabaseException {
330 final VulnerableSoftware cpe = new VulnerableSoftware();
331 try {
332 cpe.parseName(cpeStr);
333 } catch (UnsupportedEncodingException ex) {
334 LOGGER.trace("", ex);
335 }
336 final DependencyVersion detectedVersion = parseDependencyVersion(cpe);
337 final List<Vulnerability> vulnerabilities = new ArrayList<Vulnerability>();
338
339 PreparedStatement ps = null;
340 ResultSet rs = null;
341 try {
342 ps = getConnection().prepareStatement(statementBundle.getString("SELECT_CVE_FROM_SOFTWARE"));
343 ps.setString(1, cpe.getVendor());
344 ps.setString(2, cpe.getProduct());
345 rs = ps.executeQuery();
346 String currentCVE = "";
347
348 final Map<String, Boolean> vulnSoftware = new HashMap<String, Boolean>();
349 while (rs.next()) {
350 final String cveId = rs.getString(1);
351 if (!currentCVE.equals(cveId)) {
352 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
353 if (matchedCPE != null) {
354 final Vulnerability v = getVulnerability(currentCVE);
355 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
356 vulnerabilities.add(v);
357 }
358 vulnSoftware.clear();
359 currentCVE = cveId;
360 }
361
362 final String cpeId = rs.getString(2);
363 final String previous = rs.getString(3);
364 final Boolean p = previous != null && !previous.isEmpty();
365 vulnSoftware.put(cpeId, p);
366 }
367
368 final Entry<String, Boolean> matchedCPE = getMatchingSoftware(vulnSoftware, cpe.getVendor(), cpe.getProduct(), detectedVersion);
369 if (matchedCPE != null) {
370 final Vulnerability v = getVulnerability(currentCVE);
371 v.setMatchedCPE(matchedCPE.getKey(), matchedCPE.getValue() ? "Y" : null);
372 vulnerabilities.add(v);
373 }
374 } catch (SQLException ex) {
375 throw new DatabaseException("Exception retrieving vulnerability for " + cpeStr, ex);
376 } finally {
377 DBUtils.closeResultSet(rs);
378 DBUtils.closeStatement(ps);
379 }
380 return vulnerabilities;
381 }
382
383
384
385
386
387
388
389
390 public Vulnerability getVulnerability(String cve) throws DatabaseException {
391 PreparedStatement psV = null;
392 PreparedStatement psR = null;
393 PreparedStatement psS = null;
394 ResultSet rsV = null;
395 ResultSet rsR = null;
396 ResultSet rsS = null;
397 Vulnerability vuln = null;
398
399 try {
400 psV = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY"));
401 psV.setString(1, cve);
402 rsV = psV.executeQuery();
403 if (rsV.next()) {
404 vuln = new Vulnerability();
405 vuln.setName(cve);
406 vuln.setDescription(rsV.getString(2));
407 String cwe = rsV.getString(3);
408 if (cwe != null) {
409 final String name = CweDB.getCweName(cwe);
410 if (name != null) {
411 cwe += ' ' + name;
412 }
413 }
414 final int cveId = rsV.getInt(1);
415 vuln.setCwe(cwe);
416 vuln.setCvssScore(rsV.getFloat(4));
417 vuln.setCvssAccessVector(rsV.getString(5));
418 vuln.setCvssAccessComplexity(rsV.getString(6));
419 vuln.setCvssAuthentication(rsV.getString(7));
420 vuln.setCvssConfidentialityImpact(rsV.getString(8));
421 vuln.setCvssIntegrityImpact(rsV.getString(9));
422 vuln.setCvssAvailabilityImpact(rsV.getString(10));
423
424 psR = getConnection().prepareStatement(statementBundle.getString("SELECT_REFERENCES"));
425 psR.setInt(1, cveId);
426 rsR = psR.executeQuery();
427 while (rsR.next()) {
428 vuln.addReference(rsR.getString(1), rsR.getString(2), rsR.getString(3));
429 }
430 psS = getConnection().prepareStatement(statementBundle.getString("SELECT_SOFTWARE"));
431 psS.setInt(1, cveId);
432 rsS = psS.executeQuery();
433 while (rsS.next()) {
434 final String cpe = rsS.getString(1);
435 final String prevVersion = rsS.getString(2);
436 if (prevVersion == null) {
437 vuln.addVulnerableSoftware(cpe);
438 } else {
439 vuln.addVulnerableSoftware(cpe, prevVersion);
440 }
441 }
442 }
443 } catch (SQLException ex) {
444 throw new DatabaseException("Error retrieving " + cve, ex);
445 } finally {
446 DBUtils.closeResultSet(rsV);
447 DBUtils.closeResultSet(rsR);
448 DBUtils.closeResultSet(rsS);
449 DBUtils.closeStatement(psV);
450 DBUtils.closeStatement(psR);
451 DBUtils.closeStatement(psS);
452 }
453 return vuln;
454 }
455
456
457
458
459
460
461
462
463 public void updateVulnerability(Vulnerability vuln) throws DatabaseException {
464 PreparedStatement selectVulnerabilityId = null;
465 PreparedStatement deleteVulnerability = null;
466 PreparedStatement deleteReferences = null;
467 PreparedStatement deleteSoftware = null;
468 PreparedStatement updateVulnerability = null;
469 PreparedStatement insertVulnerability = null;
470 PreparedStatement insertReference = null;
471 PreparedStatement selectCpeId = null;
472 PreparedStatement insertCpe = null;
473 PreparedStatement insertSoftware = null;
474
475 try {
476 selectVulnerabilityId = getConnection().prepareStatement(statementBundle.getString("SELECT_VULNERABILITY_ID"));
477 deleteVulnerability = getConnection().prepareStatement(statementBundle.getString("DELETE_VULNERABILITY"));
478 deleteReferences = getConnection().prepareStatement(statementBundle.getString("DELETE_REFERENCE"));
479 deleteSoftware = getConnection().prepareStatement(statementBundle.getString("DELETE_SOFTWARE"));
480 updateVulnerability = getConnection().prepareStatement(statementBundle.getString("UPDATE_VULNERABILITY"));
481 final String[] ids = {"id"};
482 insertVulnerability = getConnection().prepareStatement(statementBundle.getString("INSERT_VULNERABILITY"),
483
484 ids);
485 insertReference = getConnection().prepareStatement(statementBundle.getString("INSERT_REFERENCE"));
486 selectCpeId = getConnection().prepareStatement(statementBundle.getString("SELECT_CPE_ID"));
487 insertCpe = getConnection().prepareStatement(statementBundle.getString("INSERT_CPE"),
488
489 ids);
490 insertSoftware = getConnection().prepareStatement(statementBundle.getString("INSERT_SOFTWARE"));
491 int vulnerabilityId = 0;
492 selectVulnerabilityId.setString(1, vuln.getName());
493 ResultSet rs = selectVulnerabilityId.executeQuery();
494 if (rs.next()) {
495 vulnerabilityId = rs.getInt(1);
496
497 deleteReferences.setInt(1, vulnerabilityId);
498 deleteReferences.execute();
499 deleteSoftware.setInt(1, vulnerabilityId);
500 deleteSoftware.execute();
501 }
502 DBUtils.closeResultSet(rs);
503 rs = null;
504
505 if (vulnerabilityId != 0) {
506 if (vuln.getDescription().contains("** REJECT **")) {
507 deleteVulnerability.setInt(1, vulnerabilityId);
508 deleteVulnerability.executeUpdate();
509 } else {
510 updateVulnerability.setString(1, vuln.getDescription());
511 updateVulnerability.setString(2, vuln.getCwe());
512 updateVulnerability.setFloat(3, vuln.getCvssScore());
513 updateVulnerability.setString(4, vuln.getCvssAccessVector());
514 updateVulnerability.setString(5, vuln.getCvssAccessComplexity());
515 updateVulnerability.setString(6, vuln.getCvssAuthentication());
516 updateVulnerability.setString(7, vuln.getCvssConfidentialityImpact());
517 updateVulnerability.setString(8, vuln.getCvssIntegrityImpact());
518 updateVulnerability.setString(9, vuln.getCvssAvailabilityImpact());
519 updateVulnerability.setInt(10, vulnerabilityId);
520 updateVulnerability.executeUpdate();
521 }
522 } else {
523 insertVulnerability.setString(1, vuln.getName());
524 insertVulnerability.setString(2, vuln.getDescription());
525 insertVulnerability.setString(3, vuln.getCwe());
526 insertVulnerability.setFloat(4, vuln.getCvssScore());
527 insertVulnerability.setString(5, vuln.getCvssAccessVector());
528 insertVulnerability.setString(6, vuln.getCvssAccessComplexity());
529 insertVulnerability.setString(7, vuln.getCvssAuthentication());
530 insertVulnerability.setString(8, vuln.getCvssConfidentialityImpact());
531 insertVulnerability.setString(9, vuln.getCvssIntegrityImpact());
532 insertVulnerability.setString(10, vuln.getCvssAvailabilityImpact());
533 insertVulnerability.execute();
534 try {
535 rs = insertVulnerability.getGeneratedKeys();
536 rs.next();
537 vulnerabilityId = rs.getInt(1);
538 } catch (SQLException ex) {
539 final String msg = String.format("Unable to retrieve id for new vulnerability for '%s'", vuln.getName());
540 throw new DatabaseException(msg, ex);
541 } finally {
542 DBUtils.closeResultSet(rs);
543 rs = null;
544 }
545 }
546
547 for (Reference r : vuln.getReferences()) {
548 insertReference.setInt(1, vulnerabilityId);
549 insertReference.setString(2, r.getName());
550 insertReference.setString(3, r.getUrl());
551 insertReference.setString(4, r.getSource());
552
553 if (batchSupported) {
554 insertReference.addBatch();
555 } else {
556 insertReference.execute();
557 }
558 }
559
560 if (batchSupported) {
561 insertReference.executeBatch();
562 }
563
564 for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
565 int cpeProductId = 0;
566 selectCpeId.setString(1, s.getName());
567 try {
568 rs = selectCpeId.executeQuery();
569 if (rs.next()) {
570 cpeProductId = rs.getInt(1);
571 }
572 } catch (SQLException ex) {
573 throw new DatabaseException("Unable to get primary key for new cpe: " + s.getName(), ex);
574 } finally {
575 DBUtils.closeResultSet(rs);
576 rs = null;
577 }
578
579 if (cpeProductId == 0) {
580 insertCpe.setString(1, s.getName());
581 insertCpe.setString(2, s.getVendor());
582 insertCpe.setString(3, s.getProduct());
583 insertCpe.executeUpdate();
584 cpeProductId = DBUtils.getGeneratedKey(insertCpe);
585 }
586 if (cpeProductId == 0) {
587 throw new DatabaseException("Unable to retrieve cpeProductId - no data returned");
588 }
589
590 insertSoftware.setInt(1, vulnerabilityId);
591 insertSoftware.setInt(2, cpeProductId);
592
593 if (s.getPreviousVersion() == null) {
594 insertSoftware.setNull(3, java.sql.Types.VARCHAR);
595 } else {
596 insertSoftware.setString(3, s.getPreviousVersion());
597 }
598 if (batchSupported) {
599 insertSoftware.addBatch();
600 } else {
601 try {
602 insertSoftware.execute();
603 } catch (SQLException ex) {
604 if (ex.getMessage().contains("Duplicate entry")) {
605 final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName());
606 LOGGER.debug(msg, ex);
607 } else {
608 throw ex;
609 }
610 }
611 }
612 }
613 if (batchSupported) {
614 insertSoftware.executeBatch();
615 }
616 } catch (SQLException ex) {
617 final String msg = String.format("Error updating '%s'", vuln.getName());
618 LOGGER.debug(msg, ex);
619 throw new DatabaseException(msg, ex);
620 } finally {
621 DBUtils.closeStatement(selectVulnerabilityId);
622 DBUtils.closeStatement(deleteReferences);
623 DBUtils.closeStatement(deleteSoftware);
624 DBUtils.closeStatement(updateVulnerability);
625 DBUtils.closeStatement(deleteVulnerability);
626 DBUtils.closeStatement(insertVulnerability);
627 DBUtils.closeStatement(insertReference);
628 DBUtils.closeStatement(selectCpeId);
629 DBUtils.closeStatement(insertCpe);
630 DBUtils.closeStatement(insertSoftware);
631 }
632 }
633
634
635
636
637
638
639 public boolean dataExists() {
640 Statement cs = null;
641 ResultSet rs = null;
642 try {
643 cs = conn.createStatement();
644 rs = cs.executeQuery("SELECT COUNT(*) records FROM cpeEntry");
645 if (rs.next()) {
646 if (rs.getInt(1) > 0) {
647 return true;
648 }
649 }
650 } catch (SQLException ex) {
651 String dd;
652 try {
653 dd = Settings.getDataDirectory().getAbsolutePath();
654 } catch (IOException ex1) {
655 dd = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
656 }
657 LOGGER.error("Unable to access the local database.\n\nEnsure that '{}' is a writable directory. "
658 + "If the problem persist try deleting the files in '{}' and running {} again. If the problem continues, please "
659 + "create a log file (see documentation at http://jeremylong.github.io/DependencyCheck/) and open a ticket at "
660 + "https://github.com/jeremylong/DependencyCheck/issues and include the log file.\n\n",
661 dd, dd, Settings.getString(Settings.KEYS.APPLICATION_VAME));
662 LOGGER.debug("", ex);
663 } finally {
664 DBUtils.closeResultSet(rs);
665 DBUtils.closeStatement(cs);
666 }
667 return false;
668 }
669
670
671
672
673
674
675 public void cleanupDatabase() {
676 PreparedStatement ps = null;
677 try {
678 ps = getConnection().prepareStatement(statementBundle.getString("CLEANUP_ORPHANS"));
679 if (ps != null) {
680 ps.executeUpdate();
681 }
682 } catch (SQLException ex) {
683 LOGGER.error("An unexpected SQL Exception occurred; please see the verbose log for more details.");
684 LOGGER.debug("", ex);
685 } finally {
686 DBUtils.closeStatement(ps);
687 }
688 }
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704 Entry<String, Boolean> getMatchingSoftware(Map<String, Boolean> vulnerableSoftware, String vendor, String product,
705 DependencyVersion identifiedVersion) {
706
707 final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
708
709 final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
710 final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
711 String majorVersionMatch = null;
712 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
713 final DependencyVersion v = parseDependencyVersion(entry.getKey());
714 if (v == null || "-".equals(v.toString())) {
715 return entry;
716 }
717 if (entry.getValue()) {
718 if (matchesAnyPrevious) {
719 return entry;
720 }
721 if (identifiedVersion != null && identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0))) {
722 majorVersionMatch = v.getVersionParts().get(0);
723 }
724 majorVersionsAffectingAllPrevious.add(v.getVersionParts().get(0));
725 }
726 }
727 if (matchesAnyPrevious) {
728 return null;
729 }
730
731 final boolean canSkipVersions = majorVersionMatch != null && majorVersionsAffectingAllPrevious.size() > 1;
732
733
734 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
735 if (!entry.getValue()) {
736 final DependencyVersion v = parseDependencyVersion(entry.getKey());
737
738 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
739 continue;
740 }
741
742
743 if (identifiedVersion.equals(v)) {
744 return entry;
745 }
746 }
747 }
748 for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
749 if (entry.getValue()) {
750 final DependencyVersion v = parseDependencyVersion(entry.getKey());
751
752 if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
753 continue;
754 }
755
756
757 if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
758 if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
759 return entry;
760 }
761 }
762 }
763 }
764 return null;
765 }
766
767
768
769
770
771
772
773
774 private DependencyVersion parseDependencyVersion(String cpeStr) {
775 final VulnerableSoftware cpe = new VulnerableSoftware();
776 try {
777 cpe.parseName(cpeStr);
778 } catch (UnsupportedEncodingException ex) {
779
780 LOGGER.trace("", ex);
781 }
782 return parseDependencyVersion(cpe);
783 }
784
785
786
787
788
789
790
791
792 private DependencyVersion parseDependencyVersion(VulnerableSoftware cpe) {
793 final DependencyVersion cpeVersion;
794 if (cpe.getVersion() != null && !cpe.getVersion().isEmpty()) {
795 final String versionText;
796 if (cpe.getUpdate() != null && !cpe.getUpdate().isEmpty()) {
797 versionText = String.format("%s.%s", cpe.getVersion(), cpe.getUpdate());
798 } else {
799 versionText = cpe.getVersion();
800 }
801 cpeVersion = DependencyVersionUtil.parseVersion(versionText);
802 } else {
803 cpeVersion = new DependencyVersion("-");
804 }
805 return cpeVersion;
806 }
807
808
809
810
811
812
813 public void deleteUnusedCpe() {
814 PreparedStatement ps = null;
815 try {
816 ps = getConnection().prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
817 ps.executeUpdate();
818 } catch (SQLException ex) {
819 LOGGER.error("Unable to delete CPE dictionary entries", ex);
820 } finally {
821 DBUtils.closeStatement(ps);
822 }
823 }
824
825
826
827
828
829
830
831
832
833
834
835 public void addCpe(String cpe, String vendor, String product) {
836 PreparedStatement ps = null;
837 try {
838 ps = getConnection().prepareStatement(statementBundle.getString("ADD_DICT_CPE"));
839 ps.setString(1, cpe);
840 ps.setString(2, vendor);
841 ps.setString(3, product);
842 ps.executeUpdate();
843 } catch (SQLException ex) {
844 LOGGER.error("Unable to add CPE dictionary entry", ex);
845 } finally {
846 DBUtils.closeStatement(ps);
847 }
848 }
849 }