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