Coverage Report - org.owasp.dependencycheck.dependency.Dependency
 
Classes in this File Line Coverage Branch Coverage Complexity
Dependency
0%
0/106
0%
0/118
2.683
 
 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) 2012 Jeremy Long. All Rights Reserved.
 17  
  */
 18  
 package org.owasp.dependencycheck.dependency;
 19  
 
 20  
 import java.io.File;
 21  
 import java.io.IOException;
 22  
 import java.security.NoSuchAlgorithmException;
 23  
 import java.util.Set;
 24  
 import java.util.SortedSet;
 25  
 import java.util.TreeSet;
 26  
 import java.util.logging.Level;
 27  
 import java.util.logging.Logger;
 28  
 import org.owasp.dependencycheck.utils.Checksum;
 29  
 import org.owasp.dependencycheck.utils.FileUtils;
 30  
 
 31  
 /**
 32  
  * A program dependency. This object is one of the core components within DependencyCheck. It is used to collect
 33  
  * information about the dependency in the form of evidence. The Evidence is then used to determine if there are any
 34  
  * known, published, vulnerabilities associated with the program dependency.
 35  
  *
 36  
  * @author Jeremy Long <jeremy.long@owasp.org>
 37  
  */
 38  0
 public class Dependency implements Comparable<Dependency> {
 39  
 
 40  
     /**
 41  
      * The actual file path of the dependency on disk.
 42  
      */
 43  
     private String actualFilePath;
 44  
     /**
 45  
      * The file path to display.
 46  
      */
 47  
     private String filePath;
 48  
     /**
 49  
      * The file name of the dependency.
 50  
      */
 51  
     private String fileName;
 52  
     /**
 53  
      * The file extension of the dependency.
 54  
      */
 55  
     private String fileExtension;
 56  
     /**
 57  
      * The md5 hash of the dependency.
 58  
      */
 59  
     private String md5sum;
 60  
     /**
 61  
      * The SHA1 hash of the dependency.
 62  
      */
 63  
     private String sha1sum;
 64  
     /**
 65  
      * A list of Identifiers.
 66  
      */
 67  
     private Set<Identifier> identifiers;
 68  
     /**
 69  
      * A collection of vendor evidence.
 70  
      */
 71  
     private final EvidenceCollection vendorEvidence;
 72  
     /**
 73  
      * A collection of product evidence.
 74  
      */
 75  
     private final EvidenceCollection productEvidence;
 76  
     /**
 77  
      * A collection of version evidence.
 78  
      */
 79  
     private final EvidenceCollection versionEvidence;
 80  
 
 81  
     /**
 82  
      * Constructs a new Dependency object.
 83  
      */
 84  0
     public Dependency() {
 85  0
         vendorEvidence = new EvidenceCollection();
 86  0
         productEvidence = new EvidenceCollection();
 87  0
         versionEvidence = new EvidenceCollection();
 88  0
         identifiers = new TreeSet<Identifier>();
 89  0
         vulnerabilities = new TreeSet<Vulnerability>(new VulnerabilityComparator());
 90  0
     }
 91  
 
 92  
     /**
 93  
      * Constructs a new Dependency object.
 94  
      *
 95  
      * @param file the File to create the dependency object from.
 96  
      */
 97  
     public Dependency(File file) {
 98  0
         this();
 99  0
         this.actualFilePath = file.getPath();
 100  0
         this.filePath = this.actualFilePath;
 101  0
         this.fileName = file.getName();
 102  0
         this.fileExtension = FileUtils.getFileExtension(fileName);
 103  0
         determineHashes(file);
 104  0
     }
 105  
 
 106  
     /**
 107  
      * Returns the file name of the dependency.
 108  
      *
 109  
      * @return the file name of the dependency
 110  
      */
 111  
     public String getFileName() {
 112  
         return this.fileName;
 113  
     }
 114  
 
 115  
     /**
 116  
      * Returns the file name of the dependency with the backslash escaped for use in JavaScript. This is a complete hack
 117  
      * as I could not get the replace to work in the template itself.
 118  
      *
 119  
      * @return the file name of the dependency with the backslash escaped for use in JavaScript
 120  
      */
 121  
     public String getFileNameForJavaScript() {
 122  0
         return this.fileName.replace("\\", "\\\\");
 123  
     }
 124  
 
 125  
     /**
 126  
      * Sets the file name of the dependency.
 127  
      *
 128  
      * @param fileName the file name of the dependency
 129  
      */
 130  
     public void setFileName(String fileName) {
 131  
         this.fileName = fileName;
 132  
     }
 133  
 
 134  
     /**
 135  
      * Sets the actual file path of the dependency on disk.
 136  
      *
 137  
      * @param actualFilePath the file path of the dependency
 138  
      */
 139  
     public void setActualFilePath(String actualFilePath) {
 140  0
         this.actualFilePath = actualFilePath;
 141  0
         if (this.sha1sum == null) {
 142  0
             final File file = new File(this.actualFilePath);
 143  0
             determineHashes(file);
 144  
         }
 145  0
     }
 146  
 
 147  
     /**
 148  
      * Gets the file path of the dependency.
 149  
      *
 150  
      * @return the file path of the dependency
 151  
      */
 152  
     public String getActualFilePath() {
 153  
         return this.actualFilePath;
 154  
     }
 155  
 
 156  
     /**
 157  
      * Gets a reference to the File object.
 158  
      *
 159  
      * @return the File object
 160  
      */
 161  
     public File getActualFile() {
 162  0
         return new File(this.actualFilePath);
 163  
     }
 164  
 
 165  
     /**
 166  
      * Sets the file path of the dependency.
 167  
      *
 168  
      * @param filePath the file path of the dependency
 169  
      */
 170  
     public void setFilePath(String filePath) {
 171  
         this.filePath = filePath;
 172  
     }
 173  
 
 174  
     /**
 175  
      * <p>
 176  
      * Gets the file path of the dependency.</p>
 177  
      * <p>
 178  
      * <b>NOTE:</b> This may not be the actual path of the file on disk. The actual path of the file on disk can be
 179  
      * obtained via the getActualFilePath().</p>
 180  
      *
 181  
      * @return the file path of the dependency
 182  
      */
 183  
     public String getFilePath() {
 184  
         return this.filePath;
 185  
     }
 186  
 
 187  
     /**
 188  
      * Sets the file name of the dependency.
 189  
      *
 190  
      * @param fileExtension the file name of the dependency
 191  
      */
 192  
     public void setFileExtension(String fileExtension) {
 193  
         this.fileExtension = fileExtension;
 194  
     }
 195  
 
 196  
     /**
 197  
      * Gets the file extension of the dependency.
 198  
      *
 199  
      * @return the file extension of the dependency
 200  
      */
 201  
     public String getFileExtension() {
 202  
         return this.fileExtension;
 203  
     }
 204  
 
 205  
     /**
 206  
      * Returns the MD5 Checksum of the dependency file.
 207  
      *
 208  
      * @return the MD5 Checksum
 209  
      */
 210  
     public String getMd5sum() {
 211  
         return this.md5sum;
 212  
     }
 213  
 
 214  
     /**
 215  
      * Sets the MD5 Checksum of the dependency.
 216  
      *
 217  
      * @param md5sum the MD5 Checksum
 218  
      */
 219  
     public void setMd5sum(String md5sum) {
 220  
         this.md5sum = md5sum;
 221  
     }
 222  
 
 223  
     /**
 224  
      * Returns the SHA1 Checksum of the dependency.
 225  
      *
 226  
      * @return the SHA1 Checksum
 227  
      */
 228  
     public String getSha1sum() {
 229  
         return this.sha1sum;
 230  
     }
 231  
 
 232  
     /**
 233  
      * Sets the SHA1 Checksum of the dependency.
 234  
      *
 235  
      * @param sha1sum the SHA1 Checksum
 236  
      */
 237  
     public void setSha1sum(String sha1sum) {
 238  
         this.sha1sum = sha1sum;
 239  
     }
 240  
 
 241  
     /**
 242  
      * Returns a List of Identifiers.
 243  
      *
 244  
      * @return an ArrayList of Identifiers
 245  
      */
 246  
     public Set<Identifier> getIdentifiers() {
 247  
         return this.identifiers;
 248  
     }
 249  
 
 250  
     /**
 251  
      * Sets a List of Identifiers.
 252  
      *
 253  
      * @param identifiers A list of Identifiers
 254  
      */
 255  
     public void setIdentifiers(Set<Identifier> identifiers) {
 256  
         this.identifiers = identifiers;
 257  
     }
 258  
 
 259  
     /**
 260  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 261  
      *
 262  
      * @param type the type of identifier (such as CPE)
 263  
      * @param value the value of the identifier
 264  
      * @param url the URL of the identifier
 265  
      */
 266  
     public void addIdentifier(String type, String value, String url) {
 267  0
         final Identifier i = new Identifier(type, value, url);
 268  0
         this.identifiers.add(i);
 269  0
     }
 270  
 
 271  
     /**
 272  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 273  
      *
 274  
      * @param type the type of identifier (such as CPE)
 275  
      * @param value the value of the identifier
 276  
      * @param url the URL of the identifier
 277  
      * @param confidence the confidence in the Identifier being accurate
 278  
      */
 279  
     public void addIdentifier(String type, String value, String url, Confidence confidence) {
 280  0
         final Identifier i = new Identifier(type, value, url);
 281  0
         i.setConfidence(confidence);
 282  0
         this.identifiers.add(i);
 283  0
     }
 284  
 
 285  
     /**
 286  
      * Adds an entry to the list of detected Identifiers for the dependency file.
 287  
      *
 288  
      * @param identifier the identifier to add
 289  
      */
 290  
     public void addIdentifier(Identifier identifier) {
 291  0
         this.identifiers.add(identifier);
 292  0
     }
 293  
 
 294  
     /**
 295  
      * Returns the evidence used to identify this dependency.
 296  
      *
 297  
      * @return an EvidenceCollection.
 298  
      */
 299  
     public EvidenceCollection getEvidence() {
 300  0
         return EvidenceCollection.merge(this.productEvidence, this.vendorEvidence, this.versionEvidence);
 301  
     }
 302  
 
 303  
     /**
 304  
      * Returns the evidence used to identify this dependency.
 305  
      *
 306  
      * @return an EvidenceCollection.
 307  
      */
 308  
     public EvidenceCollection getEvidenceUsed() {
 309  0
         return EvidenceCollection.mergeUsed(this.productEvidence, this.vendorEvidence, this.versionEvidence);
 310  
     }
 311  
 
 312  
     /**
 313  
      * Gets the Vendor Evidence.
 314  
      *
 315  
      * @return an EvidenceCollection.
 316  
      */
 317  
     public EvidenceCollection getVendorEvidence() {
 318  
         return this.vendorEvidence;
 319  
     }
 320  
 
 321  
     /**
 322  
      * Gets the Product Evidence.
 323  
      *
 324  
      * @return an EvidenceCollection.
 325  
      */
 326  
     public EvidenceCollection getProductEvidence() {
 327  
         return this.productEvidence;
 328  
     }
 329  
 
 330  
     /**
 331  
      * Gets the Version Evidence.
 332  
      *
 333  
      * @return an EvidenceCollection.
 334  
      */
 335  
     public EvidenceCollection getVersionEvidence() {
 336  
         return this.versionEvidence;
 337  
     }
 338  
     /**
 339  
      * The description of the JAR file.
 340  
      */
 341  
     private String description;
 342  
 
 343  
     /**
 344  
      * Get the value of description.
 345  
      *
 346  
      * @return the value of description
 347  
      */
 348  
     public String getDescription() {
 349  
         return description;
 350  
     }
 351  
 
 352  
     /**
 353  
      * Set the value of description.
 354  
      *
 355  
      * @param description new value of description
 356  
      */
 357  
     public void setDescription(String description) {
 358  
         this.description = description;
 359  
     }
 360  
     /**
 361  
      * The license that this dependency uses.
 362  
      */
 363  
     private String license;
 364  
 
 365  
     /**
 366  
      * Get the value of license.
 367  
      *
 368  
      * @return the value of license
 369  
      */
 370  
     public String getLicense() {
 371  
         return license;
 372  
     }
 373  
 
 374  
     /**
 375  
      * Set the value of license.
 376  
      *
 377  
      * @param license new value of license
 378  
      */
 379  
     public void setLicense(String license) {
 380  
         this.license = license;
 381  
     }
 382  
     /**
 383  
      * A list of vulnerabilities for this dependency.
 384  
      */
 385  
     private SortedSet<Vulnerability> vulnerabilities;
 386  
 
 387  
     /**
 388  
      * Get the list of vulnerabilities.
 389  
      *
 390  
      * @return the list of vulnerabilities
 391  
      */
 392  
     public SortedSet<Vulnerability> getVulnerabilities() {
 393  
         return vulnerabilities;
 394  
     }
 395  
 
 396  
     /**
 397  
      * Set the value of vulnerabilities.
 398  
      *
 399  
      * @param vulnerabilities new value of vulnerabilities
 400  
      */
 401  
     public void setVulnerabilities(SortedSet<Vulnerability> vulnerabilities) {
 402  
         this.vulnerabilities = vulnerabilities;
 403  
     }
 404  
 
 405  
     /**
 406  
      * Determines the sha1 and md5 sum for the given file.
 407  
      *
 408  
      * @param file the file to create checksums for
 409  
      */
 410  
     private void determineHashes(File file) {
 411  0
         String md5 = null;
 412  0
         String sha1 = null;
 413  
         try {
 414  0
             md5 = Checksum.getMD5Checksum(file);
 415  0
             sha1 = Checksum.getSHA1Checksum(file);
 416  0
         } catch (IOException ex) {
 417  0
             final String msg = String.format("Unable to read '%s' to determine hashes.", file.getName());
 418  0
             Logger.getLogger(Dependency.class.getName()).log(Level.WARNING, msg);
 419  0
             Logger.getLogger(Dependency.class.getName()).log(Level.FINE, null, ex);
 420  0
         } catch (NoSuchAlgorithmException ex) {
 421  0
             final String msg = "Unable to use MD5 of SHA1 checksums.";
 422  0
             Logger.getLogger(Dependency.class.getName()).log(Level.WARNING, msg);
 423  0
             Logger.getLogger(Dependency.class.getName()).log(Level.FINE, null, ex);
 424  0
         }
 425  0
         this.setMd5sum(md5);
 426  0
         this.setSha1sum(sha1);
 427  0
     }
 428  
 
 429  
     /**
 430  
      * Adds a vulnerability to the dependency.
 431  
      *
 432  
      * @param vulnerability a vulnerability outlining a vulnerability.
 433  
      */
 434  
     public void addVulnerability(Vulnerability vulnerability) {
 435  0
         this.vulnerabilities.add(vulnerability);
 436  0
     }
 437  
     /**
 438  
      * A collection of related dependencies.
 439  
      */
 440  0
     private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
 441  
 
 442  
     /**
 443  
      * Get the value of relatedDependencies.
 444  
      *
 445  
      * @return the value of relatedDependencies
 446  
      */
 447  
     public Set<Dependency> getRelatedDependencies() {
 448  
         return relatedDependencies;
 449  
     }
 450  
 
 451  
     /**
 452  
      * Set the value of relatedDependencies.
 453  
      *
 454  
      * @param relatedDependencies new value of relatedDependencies
 455  
      */
 456  
     public void setRelatedDependencies(Set<Dependency> relatedDependencies) {
 457  
         this.relatedDependencies = relatedDependencies;
 458  
     }
 459  
 
 460  
     /**
 461  
      * Adds a related dependency.
 462  
      *
 463  
      * @param dependency a reference to the related dependency
 464  
      */
 465  
     public void addRelatedDependency(Dependency dependency) {
 466  0
         relatedDependencies.add(dependency);
 467  0
     }
 468  
 
 469  
     /**
 470  
      * Implementation of the Comparable<Dependency> interface. The comparison is solely based on the file name.
 471  
      *
 472  
      * @param o a dependency to compare
 473  
      * @return an integer representing the natural ordering
 474  
      */
 475  
     public int compareTo(Dependency o) {
 476  0
         return this.getFileName().compareToIgnoreCase(o.getFileName());
 477  
     }
 478  
 
 479  
     /**
 480  
      * Implementation of the equals method.
 481  
      *
 482  
      * @param obj the object to compare
 483  
      * @return true if the objects are equal, otherwise false
 484  
      */
 485  
     @Override
 486  
     public boolean equals(Object obj) {
 487  0
         if (obj == null) {
 488  0
             return false;
 489  
         }
 490  0
         if (getClass() != obj.getClass()) {
 491  0
             return false;
 492  
         }
 493  0
         final Dependency other = (Dependency) obj;
 494  0
         if ((this.actualFilePath == null) ? (other.actualFilePath != null) : !this.actualFilePath.equals(other.actualFilePath)) {
 495  0
             return false;
 496  
         }
 497  0
         if ((this.filePath == null) ? (other.filePath != null) : !this.filePath.equals(other.filePath)) {
 498  0
             return false;
 499  
         }
 500  0
         if ((this.fileName == null) ? (other.fileName != null) : !this.fileName.equals(other.fileName)) {
 501  0
             return false;
 502  
         }
 503  0
         if ((this.fileExtension == null) ? (other.fileExtension != null) : !this.fileExtension.equals(other.fileExtension)) {
 504  0
             return false;
 505  
         }
 506  0
         if ((this.md5sum == null) ? (other.md5sum != null) : !this.md5sum.equals(other.md5sum)) {
 507  0
             return false;
 508  
         }
 509  0
         if ((this.sha1sum == null) ? (other.sha1sum != null) : !this.sha1sum.equals(other.sha1sum)) {
 510  0
             return false;
 511  
         }
 512  0
         if (this.identifiers != other.identifiers && (this.identifiers == null || !this.identifiers.equals(other.identifiers))) {
 513  0
             return false;
 514  
         }
 515  0
         if (this.vendorEvidence != other.vendorEvidence && (this.vendorEvidence == null || !this.vendorEvidence.equals(other.vendorEvidence))) {
 516  0
             return false;
 517  
         }
 518  0
         if (this.productEvidence != other.productEvidence && (this.productEvidence == null || !this.productEvidence.equals(other.productEvidence))) {
 519  0
             return false;
 520  
         }
 521  0
         if (this.versionEvidence != other.versionEvidence && (this.versionEvidence == null || !this.versionEvidence.equals(other.versionEvidence))) {
 522  0
             return false;
 523  
         }
 524  0
         if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) {
 525  0
             return false;
 526  
         }
 527  0
         if ((this.license == null) ? (other.license != null) : !this.license.equals(other.license)) {
 528  0
             return false;
 529  
         }
 530  0
         if (this.vulnerabilities != other.vulnerabilities && (this.vulnerabilities == null || !this.vulnerabilities.equals(other.vulnerabilities))) {
 531  0
             return false;
 532  
         }
 533  0
         if (this.relatedDependencies != other.relatedDependencies
 534  
                 && (this.relatedDependencies == null || !this.relatedDependencies.equals(other.relatedDependencies))) {
 535  0
             return false;
 536  
         }
 537  0
         return true;
 538  
     }
 539  
 
 540  
     /**
 541  
      * Generates the HashCode.
 542  
      *
 543  
      * @return the HashCode
 544  
      */
 545  
     @Override
 546  
     public int hashCode() {
 547  0
         int hash = 3;
 548  0
         hash = 47 * hash + (this.actualFilePath != null ? this.actualFilePath.hashCode() : 0);
 549  0
         hash = 47 * hash + (this.filePath != null ? this.filePath.hashCode() : 0);
 550  0
         hash = 47 * hash + (this.fileName != null ? this.fileName.hashCode() : 0);
 551  0
         hash = 47 * hash + (this.fileExtension != null ? this.fileExtension.hashCode() : 0);
 552  0
         hash = 47 * hash + (this.md5sum != null ? this.md5sum.hashCode() : 0);
 553  0
         hash = 47 * hash + (this.sha1sum != null ? this.sha1sum.hashCode() : 0);
 554  0
         hash = 47 * hash + (this.identifiers != null ? this.identifiers.hashCode() : 0);
 555  0
         hash = 47 * hash + (this.vendorEvidence != null ? this.vendorEvidence.hashCode() : 0);
 556  0
         hash = 47 * hash + (this.productEvidence != null ? this.productEvidence.hashCode() : 0);
 557  0
         hash = 47 * hash + (this.versionEvidence != null ? this.versionEvidence.hashCode() : 0);
 558  0
         hash = 47 * hash + (this.description != null ? this.description.hashCode() : 0);
 559  0
         hash = 47 * hash + (this.license != null ? this.license.hashCode() : 0);
 560  0
         hash = 47 * hash + (this.vulnerabilities != null ? this.vulnerabilities.hashCode() : 0);
 561  0
         hash = 47 * hash + (this.relatedDependencies != null ? this.relatedDependencies.hashCode() : 0);
 562  0
         return hash;
 563  
     }
 564  
 
 565  
     /**
 566  
      * Standard toString() implementation showing the filename, actualFilePath, and filePath.
 567  
      *
 568  
      * @return the string representation of the file
 569  
      */
 570  
     @Override
 571  
     public String toString() {
 572  0
         return "Dependency{ fileName='" + fileName + "', actualFilePath='" + actualFilePath + "', filePath='" + filePath + "'}";
 573  
     }
 574  
 }