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