diff --git a/docs/_docs/getting-started/configuration.md b/docs/_docs/getting-started/configuration.md index a3ac42f378..308ac78d0c 100644 --- a/docs/_docs/getting-started/configuration.md +++ b/docs/_docs/getting-started/configuration.md @@ -115,6 +115,11 @@ alpine.database.username=sa # Specifies the password to use when authenticating to the database. # alpine.database.password= +# Optional +# Specifies a path to the file holding the database password. +# To be used as alternative to alpine.database.password. +# alpine.database.password.file= + # Optional # Specifies if the database connection pool is enabled. alpine.database.pool.enabled=true diff --git a/docs/_docs/getting-started/database-support.md b/docs/_docs/getting-started/database-support.md index 0b61053404..a2c8aedbbb 100644 --- a/docs/_docs/getting-started/database-support.md +++ b/docs/_docs/getting-started/database-support.md @@ -14,8 +14,8 @@ Dependency-Track supports the following database servers: | RDBMS | Supported Versions | Recommended | |:---------------------|:-------------------|:------------| -| PostgreSQL | >= 9.0 | ✅ | -| Microsoft SQL Server | >= 2012 | ✅ | +| PostgreSQL | >= 12.0 | ✅ | +| Microsoft SQL Server | >= 2017 | ⚠️ | | MySQL | 5.6 - 5.7 | ❌ | Dependency-Track requires extensive unicode support, which is not provided per default in MySQL. @@ -23,6 +23,10 @@ Both PostgreSQL and SQL Server have been proven to work very well in production MySQL / MariaDB can require [lots of extra care](https://github.com/DependencyTrack/dependency-track/issues/271#issuecomment-1108923693). **Only use MySQL if you know what you're doing**! +> Support for H2, Microsoft SQL Server, and MySQL will be dropped in Dependency-Track v5. +> From then onwards, the project will focus on PostgreSQL. When setting up a new instance +> of Dependency-Track v4.x, consider using PostgreSQL. + Refer to the [Configuration] documentation for how database settings may be changed. ### Examples diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html index d14be053a9..29b660225b 100755 --- a/docs/_layouts/default.html +++ b/docs/_layouts/default.html @@ -66,7 +66,7 @@

{% if page.category %}{{ page.category }}{% else %}{{ site.title }}{% endif

{{ page.title }}

- {% include anchor_headings.html html=content anchorBody="#" anchorClass="anchor" %} + {% include anchor_headings.html html=content anchorBody="#" anchorClass="anchor" generateId=true h_max=3 %}
diff --git a/docs/_posts/2018-03-30-v3.0.2.md b/docs/_posts/2018-03-30-v3.0.2.md index 3c8b88756c..49fddb12a4 100644 --- a/docs/_posts/2018-03-30-v3.0.2.md +++ b/docs/_posts/2018-03-30-v3.0.2.md @@ -5,4 +5,4 @@ type: minor **Fixes:** -* Responded to changes in NVD data feed URLs by correcting the XML 1.2 and 2.0 URLs used for mirroring. +* Responded to changes in NVD data feed URLs by correcting the XML 1.2 and 2.0 URLs used for mirroring. \ No newline at end of file diff --git a/docs/_posts/2018-10-02-v3.2.2.md b/docs/_posts/2018-10-02-v3.2.2.md index c0aa0b8c93..24e138aa50 100644 --- a/docs/_posts/2018-10-02-v3.2.2.md +++ b/docs/_posts/2018-10-02-v3.2.2.md @@ -11,14 +11,14 @@ type: minor * Added checksums.xml including SHA-1, SHA-256, SHA-512 checksums for traditional and embedded wars to GitHub releases. -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.2.2/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | fead4ed834b4738b8c19c427ae57653f7af4a3b8 | | SHA-256 | ee53ceacb07b0b0b4dfa88e2bdc2e905668f0dd6d42ca1000b3204d0a2ee1842 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.2.2/dependency-track.war) | Algorithm | Checksum | | SHA-1 | defbb7a40bb12c3beacdeb43fb5fd325d226da50 | -| SHA-256 | c154f0f07c9875d602d3e1df93d93d617e83f350ef683bdb16eb193d03a86ea5 | +| SHA-256 | c154f0f07c9875d602d3e1df93d93d617e83f350ef683bdb16eb193d03a86ea5 | \ No newline at end of file diff --git a/docs/_posts/2018-10-25-v3.3.0.md b/docs/_posts/2018-10-25-v3.3.0.md index f4965b8a59..ff08901be6 100644 --- a/docs/_posts/2018-10-25-v3.3.0.md +++ b/docs/_posts/2018-10-25-v3.3.0.md @@ -56,14 +56,14 @@ alpine.ldap.team.synchronization * [Configuration]({{ site.baseurl }}{% link _docs/getting-started/configuration.md %}) (updated) * [LDAP Configuration]({{ site.baseurl }}{% link _docs/getting-started/ldap-configuration.md %}) (examples) -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.3.0/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | 413b47068dd1272f0ea6c4af67dc1465fcf10674 | | SHA-256 | 5632d6efa8c6ea2633bb767d09c73c4ee68e9319b638ce00da4c422f5123c906 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.3.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 1a8dc64a7535375fdd4ff789eeb9d3635dcba019 | -| SHA-256 | 96e20c0b72e3d8c460dfe3ce2b9aca72c6114492747db9afffca9784c64d23b9 | +| SHA-256 | 96e20c0b72e3d8c460dfe3ce2b9aca72c6114492747db9afffca9784c64d23b9 | \ No newline at end of file diff --git a/docs/_posts/2018-11-13-v3.3.1.md b/docs/_posts/2018-11-13-v3.3.1.md index 3e8d7ac4f5..213c991b62 100644 --- a/docs/_posts/2018-11-13-v3.3.1.md +++ b/docs/_posts/2018-11-13-v3.3.1.md @@ -19,14 +19,14 @@ type: minor The format of the findings API has changed and will not be versioned. This API is used to present findings from the audit tab in the UI. If this API was being used outside the UI, please note that the response format has changed. -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.3.1/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | f7a0fcf9568a765b9bb3cdf3465f475810c333e8 | | SHA-256 | f5693cab665932c80e7056c37ed93bf61a1638e252e48e9c0717b8d0c4740ea4 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.3.1/dependency-track.war) | Algorithm | Checksum | | SHA-1 | bfcf20a5cb87d562b781419f7b989c35ff67e390 | -| SHA-256 | 91156bc404ab84a09e912302888ef06c52813764e88ad73039550a9ff2e82b91 | +| SHA-256 | 91156bc404ab84a09e912302888ef06c52813764e88ad73039550a9ff2e82b91 | \ No newline at end of file diff --git a/docs/_posts/2018-12-22-v3.4.0.md b/docs/_posts/2018-12-22-v3.4.0.md index cfc3666705..934b63bd77 100644 --- a/docs/_posts/2018-12-22-v3.4.0.md +++ b/docs/_posts/2018-12-22-v3.4.0.md @@ -27,14 +27,14 @@ type: major * Updated OpenUnirest which addressed configuration issue with library not honoring proxy server settings -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.4.0/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | 676e04e0ef002e371da3b5eab239b0ab55dffe57 | | SHA-256 | 006801f124d190e929ab7e6352adcc0bf89047259eff5a15cf4d54a01d7b402d | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.4.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 15309c0818034ac99f603b52f242748b255818b9 | -| SHA-256 | 624fa3e7f458b163a0bbb8f05ee7cb1cf052d6d4ea53ff2b43686dd55bb83135 | +| SHA-256 | 624fa3e7f458b163a0bbb8f05ee7cb1cf052d6d4ea53ff2b43686dd55bb83135 | \ No newline at end of file diff --git a/docs/_posts/2019-04-16-v3.4.1.md b/docs/_posts/2019-04-16-v3.4.1.md index 1fe022eb38..4925710cd3 100644 --- a/docs/_posts/2019-04-16-v3.4.1.md +++ b/docs/_posts/2019-04-16-v3.4.1.md @@ -8,14 +8,14 @@ type: minor * Fixed defect that caused high CPU consumption (via thread exhaustion) in some cases when NPM Audit was enabled. -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.4.1/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | f8da8e34a3cabcf72b721488f5294710ff632bf6 | | SHA-256 | 72391cc636c2159ffc0c516f2001688129a3b6424164c98ce9045c0fd5c3219b | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.4.1/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 1cdb5b6c5698229b21acbc610df77ec819ad5180 | -| SHA-256 | 619e9ae00feb9f9723bef68981d32932d2d5cdf808b192619bf072d525224f5e | +| SHA-256 | 619e9ae00feb9f9723bef68981d32932d2d5cdf808b192619bf072d525224f5e | \ No newline at end of file diff --git a/docs/_posts/2019-06-07-v3.5.0.md b/docs/_posts/2019-06-07-v3.5.0.md index 73c7121e75..882e35b735 100644 --- a/docs/_posts/2019-06-07-v3.5.0.md +++ b/docs/_posts/2019-06-07-v3.5.0.md @@ -35,14 +35,14 @@ Under most situations, changing these values is not recommended and may introduc One important change introduced in this release is the default value of `alpine.database.pool.max.lifetime` has changed from 30 minutes (in previous releases) to 10 minutes. -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.5.0/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | 7d66f0530d74ff9bc0de628d5e76b5ee6ed6ead7 | | SHA-256 | 8bbf820fde7843a680fd51eed831aeddd61507f5420abb68b46859168cc98919 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.5.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 0bb9a0737a36ebbcd88fe91ca595f12957e85583 | -| SHA-256 | 143ed44988419ba84cc3956e602e297f025149f19faa65f32c0e8311b71fed5b | +| SHA-256 | 143ed44988419ba84cc3956e602e297f025149f19faa65f32c0e8311b71fed5b | \ No newline at end of file diff --git a/docs/_posts/2019-07-17-v3.5.1.md b/docs/_posts/2019-07-17-v3.5.1.md index 1c3b0cae3f..a49081f17c 100644 --- a/docs/_posts/2019-07-17-v3.5.1.md +++ b/docs/_posts/2019-07-17-v3.5.1.md @@ -8,14 +8,14 @@ type: minor * [GHSA-jp9v-w6vw-9m5v](https://github.com/DependencyTrack/dependency-track/security/advisories/GHSA-jp9v-w6vw-9m5v) Cross-Site Scripting (XSS): Persistent -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.5.1/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | aafdfa3142dc478b95f1d6ffc268b2a1832ccb29 | | SHA-256 | 73bbe06a22f84ce7b099da3c552e267c980f0f8c58ca6cccdd3eaa210bfe9b6c | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.5.1/dependency-track.war) | Algorithm | Checksum | | SHA-1 | cf71dbf7ae697038d6a42485f14991f343ffdeff | -| SHA-256 | 271705e72e94e9f9fb36159ea110a05ff465c4d1f2572a89570774e57c08a247 | +| SHA-256 | 271705e72e94e9f9fb36159ea110a05ff465c4d1f2572a89570774e57c08a247 | \ No newline at end of file diff --git a/docs/_posts/2019-09-28-v3.6.0.md b/docs/_posts/2019-09-28-v3.6.0.md index f9fd96508a..6df477a38c 100644 --- a/docs/_posts/2019-09-28-v3.6.0.md +++ b/docs/_posts/2019-09-28-v3.6.0.md @@ -36,14 +36,14 @@ type: major * Replaced embedded Dependency-Check library with internal CPE analyzer * Dependency-Track no longer mirrors XML data feeds from the NVD -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.6.0/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | 6cd17d5a31472f7f60e674e2d7fc2e3050085808 | | SHA-256 | bbb72fa3b6246b7afa7c22b103f0c85daf82565a38ae12973043775e6b27fd6e | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.6.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | f7b88825dbaf8b837977954f5a7e506952ed8361 | -| SHA-256 | a1d0d308a46d30399e9ff9a0334fe3be70345aa12c30c0d1d6bfccdcafe062e2 | +| SHA-256 | a1d0d308a46d30399e9ff9a0334fe3be70345aa12c30c0d1d6bfccdcafe062e2 | \ No newline at end of file diff --git a/docs/_posts/2019-10-01-v3.6.1.md b/docs/_posts/2019-10-01-v3.6.1.md index e54c011112..9c0141dff2 100644 --- a/docs/_posts/2019-10-01-v3.6.1.md +++ b/docs/_posts/2019-10-01-v3.6.1.md @@ -7,14 +7,14 @@ type: minor * Fixed issue that prevented upgrades to 3.6.0 when using Microsoft SQL Server -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.6.1/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | f18f248d2601878b3d437e3c6539311dc4a31c47 | | SHA-256 | b24cc49e8483c4841d6bc3efa9c1f944836a9524028960ee463ae4db7dac7c02 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.6.1/dependency-track.war) | Algorithm | Checksum | | SHA-1 | b758993e26f812494ca0191e7ad39037f2cd79ea | -| SHA-256 | da128b3602ea4e0214558074abd3df30201e7d858b79a7abb5065d358db19b40 | +| SHA-256 | da128b3602ea4e0214558074abd3df30201e7d858b79a7abb5065d358db19b40 | \ No newline at end of file diff --git a/docs/_posts/2019-12-16-v3.7.0.md b/docs/_posts/2019-12-16-v3.7.0.md index a66cc7fec3..83d9c741db 100644 --- a/docs/_posts/2019-12-16-v3.7.0.md +++ b/docs/_posts/2019-12-16-v3.7.0.md @@ -35,14 +35,14 @@ type: major * Columns: * LAST_SCAN_IMPORTED (in PROJECT table) -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.7.0/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | e946c65ec0ff5ba12e843789b917caab635bfe62 | | SHA-256 | bd02a522a8c9beeb8dd7964f07eb27a7a02ce8bbf6a7c8af3378bb26fc98a087 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.7.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 22da81fb91b5641fcb805c74063c11e521fe0ad4 | -| SHA-256 | 9207e25b19d34b57804f25e9881e663ebb56333520b039c5ccfd93209295b0a1 | +| SHA-256 | 9207e25b19d34b57804f25e9881e663ebb56333520b039c5ccfd93209295b0a1 | \ No newline at end of file diff --git a/docs/_posts/2020-01-07-v3.7.1.md b/docs/_posts/2020-01-07-v3.7.1.md index f62359efa6..72801aa721 100644 --- a/docs/_posts/2020-01-07-v3.7.1.md +++ b/docs/_posts/2020-01-07-v3.7.1.md @@ -11,14 +11,14 @@ type: minor * Fixed portfolio metrics issue that allowed multiple operations to be executed simultaneously leading to performance degradation -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.7.1/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | 5cd02dc5c6ca8aba3cea1ad5ad03d039ecdd757c | | SHA-256 | f80f527d96692a45f3bba86849551debf4b407bd880f104b890912975cc865ca | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.7.1/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 766d5394ce7a5a0e08c96a55930adc3377897d99 | -| SHA-256 | 4e6233013af574585d93dd99586455a810ea434c3bc5da95e53aad45751f5bc2 | +| SHA-256 | 4e6233013af574585d93dd99586455a810ea434c3bc5da95e53aad45751f5bc2 | \ No newline at end of file diff --git a/docs/_posts/2020-03-22-v3.8.0.md b/docs/_posts/2020-03-22-v3.8.0.md index 408f82b574..23f0372230 100644 --- a/docs/_posts/2020-03-22-v3.8.0.md +++ b/docs/_posts/2020-03-22-v3.8.0.md @@ -30,13 +30,13 @@ type: major * The `nist` and `index` directories inside the Dependency-Track data directory will be deleted upon upgrade. This will force the NVD to be downloaded and reprocessed and the indexes to be rebuilt. * The internal vulnerable software dictionary, generated automatically from the NVD, will be wiped upon upgrade. This will take several minutes to complete and should not be interrupted. -###### dependency-track-embedded.war +###### [dependency-track-embedded.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.8.0/dependency-track-embedded.war) | Algorithm | Checksum | | SHA-1 | 091627dfa144a1313bf9090d8f67b4760e635b23 | | SHA-256 | 56674c40da9dc4277b6c8238d0dc6cc28bdf3b4cc51b7b845606b1a2c149070b | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/3.8.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 1db04afbc1b66421dd6fe0db816ec14362b895d1 | @@ -44,4 +44,4 @@ type: major ###### Software Bill-of-Materials (SBOM) ###### -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/3.8.0/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/3.8.0/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-01-03-v4.0.0.md b/docs/_posts/2021-01-03-v4.0.0.md index 12304ea73c..b76bcfe38a 100644 --- a/docs/_posts/2021-01-03-v4.0.0.md +++ b/docs/_posts/2021-01-03-v4.0.0.md @@ -43,19 +43,19 @@ type: major * The MySQL Connector distributed with the Docker image has been updated to version 8.0.22. When using MySQL, `ALPINE_DATABASE_DRIVER_PATH` has to be set to `/extlib/mysql-connector-java-8.0.22.jar`. Note that `ALPINE_DATABASE_DRIVER` may need to be updated as well. Refer to the [official upgrading instructions](https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-upgrading-to-8.0.html). * The Postgres driver distributed with the Docker image has been updated to version 42.2.18. When using Postgres, `ALPINE_DATABASE_DRIVER_PATH` has to be set to `/extlib/postgresql-42.2.18.jar`. -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.0/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 9124352542544c5662d3ebf34d951e61f08ff231 | | SHA-256 | 6b6b8d608b467da087fb7ebe12fb6bbb2a418d97168baa186b1320fdb3b49a91 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.0/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 9a4f516e5fcd6eae117465732e3dcaa69227d238 | | SHA-256 | 2e66976b5f890186e64255484f262564e23e8a3ce482769374959c7ddc55c42c | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | a489586be032890ec6cddc5ec839da57026837a7 | @@ -64,4 +64,4 @@ type: major ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.0/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.0/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.0/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-01-12-v4.0.1.md b/docs/_posts/2021-01-12-v4.0.1.md index 7507287615..24c6c87c30 100644 --- a/docs/_posts/2021-01-12-v4.0.1.md +++ b/docs/_posts/2021-01-12-v4.0.1.md @@ -7,19 +7,19 @@ type: minor * Fixes issue that resulted in policy violations being returned for all projects rather than the project for which the query is made for. -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.1/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 5fb224978c700f5c38d49527669da262a324a9be | | SHA-256 | d46594ec65c0a30b645eb13419bdc36df41cc6d71053b8bb9efdee80d4de7b99 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.1/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | d9275f0b660b54205ec811c0d0cab9f584ba2a91 | | SHA-256 | 89e155529036c5f8eb977f0c611eac2abc9496c55d2c49dd4dec14dbc5acb431 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.1/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 59b571d0b1ee97a12342938d0d3b17b287c86ad4 | @@ -28,4 +28,4 @@ type: minor ###### Software Bill of Materials (SBOM) ###### * [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.1/bom.json) -* [bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.1/bom.xml) +* [bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.0.1/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-02-09-v4.1.0.md b/docs/_posts/2021-02-09-v4.1.0.md index bd5a99475b..26669619df 100644 --- a/docs/_posts/2021-02-09-v4.1.0.md +++ b/docs/_posts/2021-02-09-v4.1.0.md @@ -26,19 +26,19 @@ type: major `application/vnd.cyclonedx+json` -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.1.0/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | ed951e6a1db32b5541b646f7595cce28345c816d | | SHA-256 | e459525d279abef75f0d6cef756636503b1040939778df14decaaca65d284db1 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.1.0/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 669955757d9f5fe1e145ac61e761358986697b3d | | SHA-256 | a33f70500087fc6cfa9ffdeba1ac20de474ba28c1572f85337f04765e961f66c | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.1.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | a2ab12792eebcf420e6f0b07baa4a49bce5e0082 | @@ -47,4 +47,4 @@ type: major ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.1.0/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.1.0/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.1.0/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-03-17-v4.2.0.md b/docs/_posts/2021-03-17-v4.2.0.md index def659b2d3..dc6eb077de 100644 --- a/docs/_posts/2021-03-17-v4.2.0.md +++ b/docs/_posts/2021-03-17-v4.2.0.md @@ -23,19 +23,19 @@ type: major * The internal port the frontend container listens on has changed from port 80 to port 8080. docker-compose files may need to be updated to reflect this change. Updated compose files are [available for download](https://dependencytrack.org/docker-compose.yml). * Starting with Dependency-Track v4.2, the API Server and the Frontend now have the same major and minor (semantic) version. Patch versions however, may continue to be unique. -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.0/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | f1776e778405b5f6be2903d317463a74153c5319 | | SHA-256 | a47a3073def269e810d53de781cd7c22620e94ca80df3f781d528a7a5fe4c779 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.0/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | c3c2f931cc4f835eddd0013a885e13c16f990ea9 | | SHA-256 | 7d61818c281c6540ff4273d4d4c5d9d6e63b86b55f13e92fca7ba2921613800c | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.0/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 1634d6cf94761d3b0839f4b4a4d9fdd53d314ba6 | @@ -44,4 +44,4 @@ type: major ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.0/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.0/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.0/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-03-20-v4.2.1.md b/docs/_posts/2021-03-20-v4.2.1.md index 60d522afb2..861119084f 100644 --- a/docs/_posts/2021-03-20-v4.2.1.md +++ b/docs/_posts/2021-03-20-v4.2.1.md @@ -13,19 +13,19 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.1/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 92a0e935c7d4309e67fc7eb149191d96a1635c8b | | SHA-256 | 80cc253d05ccb91aa432667bf7d418bc8327f82b1dfe770aec71c434d0ecd308 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.1/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 930d89d1a37e85130a6603969f30253fe842a6e0 | | SHA-256 | 2b27c6f1918a897f22b48542010611c67fa137f399521a45c900ee59120b81c5 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.1/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 7a3061da05f67fd4f98b149eeb6d588389d1b202 | @@ -34,4 +34,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.1/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.1/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.1/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-05-07-v4.2.2.md b/docs/_posts/2021-05-07-v4.2.2.md index 1786bbddcc..b583caa99d 100644 --- a/docs/_posts/2021-05-07-v4.2.2.md +++ b/docs/_posts/2021-05-07-v4.2.2.md @@ -13,19 +13,19 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.2/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 60a87ecafd9ba4b0ba119a65e1a041b0c5f576ea | | SHA-256 | bd20dbee794fa0c37c345526204058dbfbdd734acaf257783f9cb47e2cf17c63 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.2/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 748b3fbf89efb61d29a468e3cd1c90bfcaeb3c4e | | SHA-256 | 93948be57b0e7864b872a2869c840c50bf9f2b3d1e9cc75794abea4c53038851 | -###### dependency-track.war +###### [dependency-track.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.2/dependency-track.war) | Algorithm | Checksum | | SHA-1 | 35b61e4309303a7ad605c21cfa5eddcbabcfa15f | @@ -34,4 +34,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.2/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.2/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.2.2/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-08-02-v4.3.0.md b/docs/_posts/2021-08-02-v4.3.0.md index 182393a7a5..e6f0b7c67e 100644 --- a/docs/_posts/2021-08-02-v4.3.0.md +++ b/docs/_posts/2021-08-02-v4.3.0.md @@ -47,13 +47,13 @@ The user interface clearly states that Portfolio Access Control is beta. By defa * Removed legacy support for the traditional WAR (was previously deprecated and unsupported) - [#1070](https://github.com/DependencyTrack/dependency-track/issues/1070) -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.0/dependency-track-apiserver.jar) | Algorithm | Checksum | | SHA-1 | 1c19a467705631c3c4449fa3f95c9d4a73d26caa | | SHA-256 | 34e0cc69eb6934d9e25573d29870cefce75d07d97fb06d58e8830f566256e1dc | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.0/dependency-track-bundled.jar) | Algorithm | Checksum | | SHA-1 | 3e3a9edb9a9077fc5e2b2634f5967d1a61b0e1cb | @@ -62,4 +62,4 @@ The user interface clearly states that Portfolio Access Control is beta. By defa ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.0/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.0/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.0/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-08-03-v4.3.1.md b/docs/_posts/2021-08-03-v4.3.1.md index 3b5bb179f2..f6e048848e 100644 --- a/docs/_posts/2021-08-03-v4.3.1.md +++ b/docs/_posts/2021-08-03-v4.3.1.md @@ -13,13 +13,13 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.1/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 6c188379b93f2b4052bb73649608db69175b0efc | | SHA-256 | 6008b32cc3cf6b13d0e7efaff335290102580bd6b518f50d630b99280a9b5538 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.1/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 9ff235da5d4b6fb9e9fe4b6762c5dfa8d83073e9 | @@ -28,4 +28,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.1/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.1/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.1/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-08-07-v4.3.2.md b/docs/_posts/2021-08-07-v4.3.2.md index bcf3efdc43..f3b98c616b 100644 --- a/docs/_posts/2021-08-07-v4.3.2.md +++ b/docs/_posts/2021-08-07-v4.3.2.md @@ -13,13 +13,13 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.2/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 9746e03d0bd7dc02ca1d94aa29a6445144fb7589 | | SHA-256 | 283282536ec276bf048428fc02aee119ff9e42f995c67cf169e2bd2a7a92cd31 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.2/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 1cb384c6f5fc457cddbb93c55b7188cf5b446f6f | @@ -28,4 +28,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.2/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.2/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.2/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-08-20-v4.3.3.md b/docs/_posts/2021-08-20-v4.3.3.md index 274311d968..8d858a3db3 100644 --- a/docs/_posts/2021-08-20-v4.3.3.md +++ b/docs/_posts/2021-08-20-v4.3.3.md @@ -15,13 +15,13 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.3/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | e28bc741856904115e54dd5bf2ef09addde011e8 | | SHA-256 | b748e9b43a25068dc5096f5a68d2e21d5450fca1d3805350042a566c4506d2ba | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.3/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | e884e3e32e18ff608837cc2d33b1d1760a00d0c7 | @@ -30,4 +30,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.3/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.3/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.3/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-08-31-v4.3.4.md b/docs/_posts/2021-08-31-v4.3.4.md index db377623ba..9fb5b33314 100644 --- a/docs/_posts/2021-08-31-v4.3.4.md +++ b/docs/_posts/2021-08-31-v4.3.4.md @@ -13,13 +13,13 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.4/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 813e3a7207e47a7ee6769a1e74b040942f8995b5 | | SHA-256 | 1f8bae644dc6982933ec080167d90a66d8090055d75aad7e924a91a9cb8783c8 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.4/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 11db7cb3cf83b4e0d6ac121061b42d3f7e3c2c4e | @@ -28,4 +28,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.4/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.4/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.4/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-09-20-v4.3.5.md b/docs/_posts/2021-09-20-v4.3.5.md index d27350d282..448a67f3d1 100644 --- a/docs/_posts/2021-09-20-v4.3.5.md +++ b/docs/_posts/2021-09-20-v4.3.5.md @@ -6,13 +6,13 @@ type: patch No changes in this release. -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.5/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | d13ea84585009e70da2745690f4580b8db2a6e75 | | SHA-256 | 5334a13a5cc0662986d1643463c22bd6a7f3875165ad89296e2f9704b51acec5 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.5/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 2aee316ac07c5941a7ba734c30bec4f517cc2df1 | @@ -21,4 +21,4 @@ No changes in this release. ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.5/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.5/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.5/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2021-09-20-v4.3.6.md b/docs/_posts/2021-09-20-v4.3.6.md index 2767cea7c7..62b1cb0143 100644 --- a/docs/_posts/2021-09-20-v4.3.6.md +++ b/docs/_posts/2021-09-20-v4.3.6.md @@ -14,13 +14,13 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.6/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | d41721f52bfb17c9ba507a1ac01532071643d8ac | | SHA-256 | 83f0bc7199677e3f6f84a76673b936ca73a6b8f54d5cb7cf181f77d548d47a6b | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.6/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 31fb39d8fecb6ec1e5c02d0fdede7a3e7e1cd952 | @@ -29,4 +29,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.6/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.6/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.3.6/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2022-02-17-v4.4.0.md b/docs/_posts/2022-02-17-v4.4.0.md index 9789d36ad4..2246b47dd8 100644 --- a/docs/_posts/2022-02-17-v4.4.0.md +++ b/docs/_posts/2022-02-17-v4.4.0.md @@ -43,13 +43,13 @@ The permission also grants access to the findings API. **Upgrade Notes:** * Users and teams with `VULNERABILITY_ANALYSIS` permission are automatically granted the `VIEW_VULNERABILITY` permission during the automatic upgrade. -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.0/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | c81d753ce4376cee1ae4d2a8cf9710a9b8ceee45 | | SHA-256 | 31e685e79b658f661ce28f8c5cbc96906d23d408a2ade70ff7e7a8e20f054972 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.0/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 2b15b51c64938997ec9fbcf66054436064d9ef23 | @@ -58,4 +58,4 @@ The permission also grants access to the findings API. ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.0/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.0/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.0/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2022-02-18-v4.4.1.md b/docs/_posts/2022-02-18-v4.4.1.md index dd46c352da..99a4a8ad39 100644 --- a/docs/_posts/2022-02-18-v4.4.1.md +++ b/docs/_posts/2022-02-18-v4.4.1.md @@ -14,13 +14,13 @@ type: patch * For MSSQL users only: If an upgrade to v4.4.0 was previously attempted and no rollback was performed yet, the following SQL statement must be executed before launching v4.4.1: `DELETE FROM "PERMISSION" WHERE "NAME" = 'VIEW_VULNERABILITY'` -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.1/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 9d6f20709009193540c4c152f0c0757d3b26bd5e | | SHA-256 | c3eaeee440bfd1a734fb009983c97792407b107d64d4e9035a179b9b27c8ca49 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.1/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | ebadb4576ea419eb42807f5ef2bedb572de02df0 | @@ -29,4 +29,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.1/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.1/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.1/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2022-03-04-v4.4.2.md b/docs/_posts/2022-03-04-v4.4.2.md index aecc90fdcd..e5c8ab63bf 100644 --- a/docs/_posts/2022-03-04-v4.4.2.md +++ b/docs/_posts/2022-03-04-v4.4.2.md @@ -13,13 +13,13 @@ type: patch **Upgrade Notes:** -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.2/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 172f569eb85f1182500571a160b134e8b1005ebf | | SHA-256 | 5869df68cd29d48366d653a697bc198e0f3396c2897cd4a668743fc7157fb8df | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.2/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 49e73a820426a39ab83e6ec2a12f1c24e198a144 | @@ -28,4 +28,4 @@ type: patch ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.2/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.2/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.4.2/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2022-05-18-v4.5.0.md b/docs/_posts/2022-05-18-v4.5.0.md index 013490f509..2801689f40 100644 --- a/docs/_posts/2022-05-18-v4.5.0.md +++ b/docs/_posts/2022-05-18-v4.5.0.md @@ -42,13 +42,13 @@ type: major * Users and teams with `POLICY_VIOLATION_ANALYSIS` permission are automatically granted the `VIEW_POLICY_VIOLATION` permission during the automatic upgrade. * Location of `config.json` in the frontend container changed from `/app/static/config.json` to `/opt/owasp/dependency-track-frontend/static/config.json` -###### dependency-track-apiserver.war +###### [dependency-track-apiserver.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.5.0/dependency-track-apiserver.war) | Algorithm | Checksum | | SHA-1 | 8db4707e3458b122e73cce92e7dc143c115db962 | | SHA-256 | 0c3d75501a0545f90e862aa0e2920f0c6146abcd436983531de7757ff294f568 | -###### dependency-track-bundled.war +###### [dependency-track-bundled.war](https://github.com/DependencyTrack/dependency-track/releases/download/4.5.0/dependency-track-bundled.war) | Algorithm | Checksum | | SHA-1 | 984aafe85ac2dc361f9b0adf3c26d99decbab641 | @@ -57,4 +57,4 @@ type: major ###### Software Bill of Materials (SBOM) ###### [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.5.0/bom.json) -[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.5.0/bom.xml) +[bom.xml](https://github.com/DependencyTrack/dependency-track/releases/download/4.5.0/bom.xml) \ No newline at end of file diff --git a/docs/_posts/2022-10-11-v4.6.0.md b/docs/_posts/2022-10-11-v4.6.0.md index 9d0189335d..babef7def4 100644 --- a/docs/_posts/2022-10-11-v4.6.0.md +++ b/docs/_posts/2022-10-11-v4.6.0.md @@ -119,21 +119,21 @@ Special thanks to everyone who contributed code to implement enhancements and fi *@AbdelHajou, @awegg, @dGuerr, @k3rnelpan1c-dev, @maaheeb, @officerNordberg, @rbt-mm, @rkg-mm, @s-spindler, @sahibamittal, @stephan-strate, @syalioune, @tmehnert, @yangsec888* -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.0/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | e40fb14764fb5eb9fcd654472434c3701c44f208 | | SHA-256 | 29d422816b593ddef89b07e9bc1c72a5cfb141eaea4a1d59615309089bab03ea | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.0/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 9e1b283c442e1bfb2c5c4ea23b1a1590cf7afc5d | | SHA-256 | 1e6ba17e6dc1f6422826a020ece5ec6ae2bef1aa9ae563f57653ed6bc0944f14 | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.6.0/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| diff --git a/docs/_posts/2022-10-13-v4.6.1.md b/docs/_posts/2022-10-13-v4.6.1.md index 4748636dd5..d37967137e 100644 --- a/docs/_posts/2022-10-13-v4.6.1.md +++ b/docs/_posts/2022-10-13-v4.6.1.md @@ -11,14 +11,14 @@ For a complete list of changes, refer to the respective GitHub milestones: * [API server milestone 4.6.1](https://github.com/DependencyTrack/dependency-track/milestone/28?closed=1) -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.1/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | f3c8e2007f2795b12f438b6b9318c4d5c448fa0b | | SHA-256 | e293756b5e27d6c3213dfbeead946bf220d278d418c817c74a81fda395764977 | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.1/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -29,4 +29,4 @@ For a complete list of changes, refer to the respective GitHub milestones: * API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.1/bom.json) -[#2043]: https://github.com/DependencyTrack/dependency-track/issues/2043 +[#2043]: https://github.com/DependencyTrack/dependency-track/issues/2043 \ No newline at end of file diff --git a/docs/_posts/2022-10-24-v4.6.2.md b/docs/_posts/2022-10-24-v4.6.2.md index e5188fdd2c..41baff61e7 100644 --- a/docs/_posts/2022-10-24-v4.6.2.md +++ b/docs/_posts/2022-10-24-v4.6.2.md @@ -20,21 +20,21 @@ For a complete list of changes, refer to the respective GitHub milestones: * [API server milestone 4.6.2](https://github.com/DependencyTrack/dependency-track/milestone/28?closed=1) * [Frontend milestone 4.6.1](https://github.com/DependencyTrack/frontend/milestone/12?closed=1) -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.2/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 313b2ee9bd957f8bd2b0baba524044197501b2a9 | | SHA-256 | 7ee92f572cebe6d8d8f9e37ab6067e5849c83c56c98b38a21418557260efbfdc | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.2/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | e009cc9345ae5bdb321c651df769a6d02dfc5a67 | | SHA-256 | 0e67de28a99aec1d2e3c4592b42f04e86084129f58f3d338b572fdc5b7064899 | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.6.2/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -47,4 +47,4 @@ For a complete list of changes, refer to the respective GitHub milestones: * Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.6.1/bom.json) [#300]: https://github.com/DependencyTrack/frontend/pull/300 -[GHSA-c33w-pm52-mqvf]: https://github.com/DependencyTrack/frontend/security/advisories/GHSA-c33w-pm52-mqvf +[GHSA-c33w-pm52-mqvf]: https://github.com/DependencyTrack/frontend/security/advisories/GHSA-c33w-pm52-mqvf \ No newline at end of file diff --git a/docs/_posts/2022-11-18-v4.6.3.md b/docs/_posts/2022-11-18-v4.6.3.md index 162ff6afdf..f2dcc81230 100644 --- a/docs/_posts/2022-11-18-v4.6.3.md +++ b/docs/_posts/2022-11-18-v4.6.3.md @@ -19,14 +19,14 @@ For a complete list of changes, refer to the respective GitHub milestones: * [API server milestone 4.6.3](https://github.com/DependencyTrack/dependency-track/milestone/30?closed=1) -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.3/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 68b806410c2e68fe8c586b93044f29a648f96466 | | SHA-256 | d9b5337419addee26658da8e421f0286aaa92160b8f6f85caca83aa1a328611f | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.3/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -38,4 +38,4 @@ For a complete list of changes, refer to the respective GitHub milestones: * API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.6.3/bom.json) [#2115]: https://github.com/DependencyTrack/dependency-track/issues/2115 -[component analysis cache]: {{ site.baseurl }}{% link _docs/analysis-types/known-vulnerabilities.md %}#analysis-result-cache +[component analysis cache]: {{ site.baseurl }}{% link _docs/analysis-types/known-vulnerabilities.md %}#analysis-result-cache \ No newline at end of file diff --git a/docs/_posts/2022-12-16-v4.7.0.md b/docs/_posts/2022-12-16-v4.7.0.md index 5a89488b19..d83cd48cfe 100644 --- a/docs/_posts/2022-12-16-v4.7.0.md +++ b/docs/_posts/2022-12-16-v4.7.0.md @@ -98,21 +98,21 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@mehab], [@nathan-mittelette], [@omerlh], [@rbt-mm], [@ribbybibby], [@s-spindler], [@sahibamittal], [@syalioune], [@valentijnscholten] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.7.0/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 99f1a012a983b8256d9346e64d3dd27e92d1c808 | | SHA-256 | 373e8efa1a8995193b7c068ea34974040627553647905d38e1dce053333eeb10 | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.7.0/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | c7faee42162e1712377fbd8a03dfd9e3ef251a23 | | SHA-256 | 631807c24fd76c0f44d4494a44147e0414ab471ac1e12fe4ebff054f363a8f0f | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.7.0/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -198,4 +198,4 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@s-spindler]: https://github.com/s-spindler [@sahibamittal]: https://github.com/sahibamittal [@syalioune]: https://github.com/syalioune -[@valentijnscholten]: https://github.com/valentijnscholten +[@valentijnscholten]: https://github.com/valentijnscholten \ No newline at end of file diff --git a/docs/_posts/2023-01-31-v4.7.1.md b/docs/_posts/2023-01-31-v4.7.1.md index 4809736271..0a05b8a812 100644 --- a/docs/_posts/2023-01-31-v4.7.1.md +++ b/docs/_posts/2023-01-31-v4.7.1.md @@ -23,21 +23,21 @@ Special thanks to everyone who contributed code to fix defects: [@JoergBruenner], [@mehab], [@rbt-mm], [@sergioasantiago], [@syalioune] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.7.1/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | ef119b6f5fb422687e5152528bdb3e40e89c8733 | | SHA-256 | 7fbccad45c730226ab9df1ff51aaa2dba90b93cf22547bbe395d3f3b849c8371 | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.7.1/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 94ca9179dad020c45adfdf0152b3f20081f7cf8b | | SHA-256 | fe3fad9d43235df30880e547f838f65fe6365919dbc19107e4da349a5dce104f | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.7.1/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| diff --git a/docs/_posts/2023-04-18-v4.8.0.md b/docs/_posts/2023-04-18-v4.8.0.md index 1e8eef644d..6d70472f62 100644 --- a/docs/_posts/2023-04-18-v4.8.0.md +++ b/docs/_posts/2023-04-18-v4.8.0.md @@ -119,21 +119,21 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@mehab], [@msymons], [@mvandermade], [@rbt-mm], [@roadSurfer], [@s-spindler], [@sahibamittal], [@syalioune] [@valentijnscholten], [@walterdeboer], [@zgael] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.8.0/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 883754d3ed227a124976c3f9247345be48cc0561 | | SHA-256 | 0ab7e3a1d0cd308a9193a6bec7b561f3911d19052312a82e4a59607d4ff50fd0 | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.8.0/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 979f02a5bf3ea5d8b0bba7d4e73a725de1920219 | | SHA-256 | af9f6d79e7828b4f744f9f82215486c0b5649abf6544d0374c945b2ab5d8b58a | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.8.0/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -237,4 +237,4 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@syalioune]: https://github.com/syalioune [@valentijnscholten]: https://github.com/valentijnscholten [@walterdeboer]: https://github.com/walterdeboer -[@zgael]: https://github.com/zgael +[@zgael]: https://github.com/zgael \ No newline at end of file diff --git a/docs/_posts/2023-05-16-v4.8.1.md b/docs/_posts/2023-05-16-v4.8.1.md index 5cbf28aed9..d21f3fc3c5 100644 --- a/docs/_posts/2023-05-16-v4.8.1.md +++ b/docs/_posts/2023-05-16-v4.8.1.md @@ -30,21 +30,21 @@ discussions on GitHub & Slack to testing of fixes. Special thanks to everyone who contributed code to fix defects: [@heubeck], [@jakubrak], [@sahibamittal], [@valentijnscholten] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.8.1/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 553d17a940220d79b686ce6b64d65c0854915f1b | | SHA-256 | 56db674f5b467eac0a5b3fde99bc6285fd9135ad84e8fa0328ed6ace64fc723c | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.8.1/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | b2f0e053083ac672a9eaef19f7363ac854bdb91a | | SHA-256 | e1bd03ea89b312c2125791a0d46ca99aa62365140a4f175d2f45cbb1d59a87a6 | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.8.1/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| diff --git a/docs/_posts/2023-05-17-v4.8.2.md b/docs/_posts/2023-05-17-v4.8.2.md index 982f15c69a..a062f2ddd6 100644 --- a/docs/_posts/2023-05-17-v4.8.2.md +++ b/docs/_posts/2023-05-17-v4.8.2.md @@ -15,14 +15,14 @@ For a complete list of changes, refer to the respective GitHub milestone: * [API server milestone 4.8.2](https://github.com/DependencyTrack/dependency-track/milestone/33?closed=1) -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.8.2/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | bfc8758eb30ab90f4280cb37ea959964f74706b9 | | SHA-256 | 2b1d249d98f72b863deb4769665efc119a3ef8db195838decddce9a2a12f36b4 | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.8.2/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -34,4 +34,4 @@ For a complete list of changes, refer to the respective GitHub milestone: * API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.8.2/bom.json) [apiserver/#2750]: https://github.com/DependencyTrack/dependency-track/pull/2750 -[apiserver/#2766]: https://github.com/DependencyTrack/dependency-track/issues/2766 +[apiserver/#2766]: https://github.com/DependencyTrack/dependency-track/issues/2766 \ No newline at end of file diff --git a/docs/_posts/2023-10-16-v4.9.0.md b/docs/_posts/2023-10-16-v4.9.0.md index 1572f70718..b7555a710e 100644 --- a/docs/_posts/2023-10-16-v4.9.0.md +++ b/docs/_posts/2023-10-16-v4.9.0.md @@ -87,21 +87,21 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@mattmatician], [@melba-lopez], [@muellerst-hg], [@nathan-mittelette], [@sahibamittal], [@sephiroth-j], [@syalioune], [@takumakume], [@valentijnscholten], [@walterdeboer] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.9.0/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | cd4ec4f1ed075f37476f46da11451158d7460502 | | SHA-256 | 281f091107ef79d9b1e9361dc78608260b364eaa7dbbaeb29d4f7aef1a4bf67b | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.9.0/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 6f3a077219fb49a502a88fcbb40e05865a23f5c5 | | SHA-256 | 4ca0b061ed83fa0b34ede8158f3ec0e2a7380c2736731995cf330f809076951f | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.9.0/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -190,4 +190,4 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@syalioune]: https://github.com/syalioune [@takumakume]: https://github.com/takumakume [@valentijnscholten]: https://github.com/valentijnscholten -[@walterdeboer]: https://github.com/walterdeboer +[@walterdeboer]: https://github.com/walterdeboer \ No newline at end of file diff --git a/docs/_posts/2023-10-30-v4.9.1.md b/docs/_posts/2023-10-30-v4.9.1.md index 6a857e8b08..ae04f34bcf 100644 --- a/docs/_posts/2023-10-30-v4.9.1.md +++ b/docs/_posts/2023-10-30-v4.9.1.md @@ -24,21 +24,21 @@ We thank all organizations and individuals who contributed to this release, from Special thanks to everyone who contributed code to implement enhancements and fix defects: [@muellerst-hg] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.9.1/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 99da5f705c3b0048ecf621e8c738a87147c693d9 | | SHA-256 | 5d925f08f85fe7f39231357c4a4c8057fd354e048b7c9407efb20af78033ecec | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.9.1/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 487801d69bffb2e8def5aad9aa55c34be8cddcb2 | | SHA-256 | 19ac4ede2932ff54c42e0466cdf7d5b410f7a44784562f237fc5b4b8891a8dc8 | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.9.1/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| diff --git a/docs/_posts/2023-12-08-v4.10.0.md b/docs/_posts/2023-12-08-v4.10.0.md index 6d90c8728d..377fcf387d 100644 --- a/docs/_posts/2023-12-08-v4.10.0.md +++ b/docs/_posts/2023-12-08-v4.10.0.md @@ -65,21 +65,21 @@ We thank all organizations and individuals who contributed to this release, from Special thanks to everyone who contributed code to implement enhancements and fix defects: [@AbdelHajou], [@Nikemare], [@acdha], [@dimitri-rebrikov], [@jadyndev], [@leec94], [@mehab], [@melba-lopez], [@rbt-mm], [@rkg-mm], [@willienel], [@ybelMekk] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.10.0/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | c308b1f6a2d73fc2bba9da2cc33bf7e3ec49e851 | | SHA-256 | d06f4550e16451ccb7843c36534172744934a7dc69e1d48e970a6eec24e49dc3 | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.10.0/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | b94fb9cbaa91c4e332bcec266e10a0f325f12e22 | | SHA-256 | cf27db44e637b4bc551c16e659e81890f4c5d4f3b4ea9893ebf1717bff98b999 | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.10.0/frontend-dist.zip) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -135,4 +135,4 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@rbt-mm]: https://github.com/rbt-mm [@rkg-mm]: https://github.com/rkg-mm [@willienel]: https://github.com/willienel -[@ybelMekk]: https://github.com/ybelMekk +[@ybelMekk]: https://github.com/ybelMekk \ No newline at end of file diff --git a/docs/_posts/2023-12-19-v4.10.1.md b/docs/_posts/2023-12-19-v4.10.1.md index de988b2a5e..4a657081a3 100644 --- a/docs/_posts/2023-12-19-v4.10.1.md +++ b/docs/_posts/2023-12-19-v4.10.1.md @@ -33,14 +33,14 @@ We thank all organizations and individuals who contributed to this release, from Special thanks to everyone who contributed code to implement enhancements and fix defects: [@jadyndev] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.10.1/dependency-track-apiserver.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| | SHA-1 | 1d728ce1788e5db8b3a9308338a9e7e8ab5af12e | | SHA-256 | e30731cd1915d3a1578cf5d8c8596d247fb11a82a3fe4c1ba2fb9fad01667aef | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.10.1/dependency-track-bundled.jar) | Algorithm | Checksum | |:----------|:-----------------------------------------------------------------| @@ -57,4 +57,4 @@ Special thanks to everyone who contributed code to implement enhancements and fi [apiserver/#3315]: https://github.com/DependencyTrack/dependency-track/pull/3315 [apiserver/#3323]: https://github.com/DependencyTrack/dependency-track/pull/3323 -[@jadyndev]: https://github.com/jadyndev +[@jadyndev]: https://github.com/jadyndev \ No newline at end of file diff --git a/docs/_posts/2024-05-07-v4.11.0.md b/docs/_posts/2024-05-07-v4.11.0.md index 13bbaa1415..3576beff09 100644 --- a/docs/_posts/2024-05-07-v4.11.0.md +++ b/docs/_posts/2024-05-07-v4.11.0.md @@ -181,21 +181,21 @@ Special thanks to everyone who contributed code to implement enhancements and fi [@baburkin], [@fnxpt], [@kepten], [@leec94], [@lukas-braune], [@malice00], [@mehab], [@mge-mm] [@mikkeschiren], [@mykter], [@rbt-mm], [@rkesters], [@rkg-mm], [@sahibamittal], [@sebD], [@setchy], [@validide] -###### dependency-track-apiserver.jar +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.0/dependency-track-apiserver.jar) -| Algorithm | Checksum | -|:----------|:---------| -| SHA-1 | | -| SHA-256 | | +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | a9dae58a25c8aeeb54134ff054214505eb170db9 | +| SHA-256 | 03160957fced99c3d923bbb5c6cb352740da1970bd4775b52bb451b95c4cefaf | -###### dependency-track-bundled.jar +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.0/dependency-track-bundled.jar) -| Algorithm | Checksum | -|:----------|:---------| -| SHA-1 | | -| SHA-256 | | +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 59b78c3f6b1979ba29c1bd754b7dc1005101fc49 | +| SHA-256 | 1a34808cd6c7a9bf7b181e4f175c077f1ee5d5a9daf327b330db9b1c63aac2d3 | -###### frontend-dist.zip +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.0/frontend-dist.zip) | Algorithm | Checksum | |:----------|:------------------------------------------------------------------------------------| diff --git a/docs/_posts/2024-05-19-v4.11.1.md b/docs/_posts/2024-05-19-v4.11.1.md new file mode 100644 index 0000000000..6e392bbd9a --- /dev/null +++ b/docs/_posts/2024-05-19-v4.11.1.md @@ -0,0 +1,59 @@ +--- +title: v4.11.1 +type: patch +--- + +**Fixes:** + +* Fix failing JSON BOM validation when `specVersion` is not one of the first fields - [apiserver/#3698] +* Fix broken global vuln audit view for MSSQL - [apiserver/#3701] +* Fix OS package vulnerabilities not being detected by Trivy - [apiserver/#3729] +* Improve Japanese translation - [frontend/#869] +* Fix broken *Vulnerabilities* progress bar in *Project* -> *Components* view - [frontend/#873] + +For a complete list of changes, refer to the respective GitHub milestones: + +* [API server milestone 4.11.1](https://github.com/DependencyTrack/dependency-track/milestone/37?closed=1) +* [Frontend milestone 4.11.1](https://github.com/DependencyTrack/frontend/milestone/22?closed=1) + +We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes. + +Special thanks to everyone who contributed code to implement enhancements and fix defects: +[@aravindparappil46], [@fnxpt], [@tiwatsuka] + +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.1/dependency-track-apiserver.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | aa3d8ffc6b8f9d15a801148a93275ebeba922010 | +| SHA-256 | ed08e60e0761ced93454c14194da02be5950805911dbc7f7c611bdf0e753b437 | + +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.1/dependency-track-bundled.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | c57f1b8c003d95daa871096cbc37a6c03cd08907 | +| SHA-256 | e7613d6654083ab6e2c4ae24459444efe4d83df5d2c4d27e58a94bc809e2627a | + +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.1/frontend-dist.zip) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 995e21388806efc102bf7bc14bc6ac5a3c354fc7 | +| SHA-256 | 27e7d91ba0fe3b54dcbef8a7c44c1ee0b9afe2ba3d96c47b55d3beca68206fd2 | + +###### Software Bill of Materials (SBOM) + +* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.1/bom.json) +* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.11.1/bom.json) + +[apiserver/#3698]: https://github.com/DependencyTrack/dependency-track/pull/3698 +[apiserver/#3701]: https://github.com/DependencyTrack/dependency-track/pull/3701 +[apiserver/#3729]: https://github.com/DependencyTrack/dependency-track/pull/3729 + +[frontend/#869]: https://github.com/DependencyTrack/frontend/pull/869 +[frontend/#873]: https://github.com/DependencyTrack/frontend/pull/873 + +[@aravindparappil46]: https://github.com/aravindparappil46 +[@fnxpt]: https://github.com/fnxpt +[@tiwatsuka]: https://github.com/tiwatsuka \ No newline at end of file diff --git a/docs/_posts/2024-06-01-v4.11.2.md b/docs/_posts/2024-06-01-v4.11.2.md new file mode 100644 index 0000000000..e322ec4729 --- /dev/null +++ b/docs/_posts/2024-06-01-v4.11.2.md @@ -0,0 +1,65 @@ +--- +title: v4.11.2 +type: patch +--- + +**Fixes:** + +* Handle breaking change in Trivy v0.51.2 server API - [apiserver/#3785] +* Fix licenses not being resolved by name - [apiserver/#3786] +* Fix project name not showing in Jira tickets for *NEW_VULNERABLE_DEPENDENCY* notifications - [apiserver/#3787] +* Fix parsing of NuGet timestamps with offset - [apiserver/#3788] +* Fix Slack notifications failing when no base URL is configured - [apiserver/#3792] +* Fix project version dropdown exceeding the screen size - [frontend/#882] +* Update English translation - [frontend/#883] +* Update French translation - [frontend/#884] + +For a complete list of changes, refer to the respective GitHub milestones: + +* [API server milestone 4.11.2](https://github.com/DependencyTrack/dependency-track/milestone/39?closed=1) +* [Frontend milestone 4.11.2](https://github.com/DependencyTrack/frontend/milestone/24?closed=1) + +We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes. + +Special thanks to everyone who contributed code to implement enhancements and fix defects: +[@aravindparappil46], [@lgrguricmileusnic], [@molusk], [@sahibamittal] + +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.2/dependency-track-apiserver.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 174956bf3cd2dab16cfd36e7ab1b5d7001b99160 | +| SHA-256 | 135cf4361bbbc65f488796bf196c8d2d3cbebec931b249e037551c6fbbae2ed7 | + +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.2/dependency-track-bundled.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | af75c903b033418ea6326cbb4e6885afba99ee94 | +| SHA-256 | 5020ac51158038439b7482d5c5fec151773162724dce1779249bf73053456d34 | + +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.2/frontend-dist.zip) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 1119cb6abbcdfe014f013205d40ae11668bd5c83 | +| SHA-256 | 9d122fc6ddea378afc87bf555949f6c201281c9289a36ae97900b7bee4cbc7f5 | + +###### Software Bill of Materials (SBOM) + +* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.2/bom.json) +* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.11.2/bom.json) + +[apiserver/#3785]: https://github.com/DependencyTrack/dependency-track/pull/3785 +[apiserver/#3786]: https://github.com/DependencyTrack/dependency-track/pull/3786 +[apiserver/#3787]: https://github.com/DependencyTrack/dependency-track/pull/3787 +[apiserver/#3788]: https://github.com/DependencyTrack/dependency-track/pull/3788 +[apiserver/#3792]: https://github.com/DependencyTrack/dependency-track/pull/3792 +[frontend/#882]: https://github.com/DependencyTrack/frontend/pull/882 +[frontend/#883]: https://github.com/DependencyTrack/frontend/pull/883 +[frontend/#884]: https://github.com/DependencyTrack/frontend/pull/884 + +[@aravindparappil46]: https://github.com/aravindparappil46 +[@lgrguricmileusnic]: https://github.com/lgrguricmileusnic +[@molusk]: https://github.com/molusk +[@sahibamittal]: https://github.com/sahibamittal \ No newline at end of file diff --git a/docs/_posts/2024-06-03-v4.11.3.md b/docs/_posts/2024-06-03-v4.11.3.md new file mode 100644 index 0000000000..a738904eb9 --- /dev/null +++ b/docs/_posts/2024-06-03-v4.11.3.md @@ -0,0 +1,43 @@ +--- +title: v4.11.3 +type: patch +--- + +**Fixes:** + +* Fix `JDODataStoreException` for unresolved licenses during BOM upload processing - [apiserver/#3801] + +For a complete list of changes, refer to the respective GitHub milestones: + +* [API server milestone 4.11.3](https://github.com/DependencyTrack/dependency-track/milestone/40?closed=1) +* [Frontend milestone 4.11.3](https://github.com/DependencyTrack/frontend/milestone/25?closed=1) + +We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes. + +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.3/dependency-track-apiserver.jar) + +| Algorithm | Checksum | +|:----------|:---------| +| SHA-1 | ff4284ce635f4da916e907af20bb0e9339349ecd | +| SHA-256 | f1e34cc7a0c5e2fe444e934aa221853ac762ee79997bc10fa712ee6ac8f776d8 | + +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.3/dependency-track-bundled.jar) + +| Algorithm | Checksum | +|:----------|:---------| +| SHA-1 | beea18173e6a52180ac1a8ee721dd7f775eaaf2d | +| SHA-256 | d62557345bb244b5d34e7a56d057e264044524d8df7964df23383a2ace658cbd | + +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.3/frontend-dist.zip) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | dc7859636f1bf7a3772dc0e8de27535031511a4c | +| SHA-256 | 88684d3bbd0aa2ff300ae419653f85957deaf00d9ca615a747386997b3f0e154 | + +###### Software Bill of Materials (SBOM) + +* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.3/bom.json) +* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.11.3/bom.json) + +[apiserver/#3801]: https://github.com/DependencyTrack/dependency-track/pull/3801 \ No newline at end of file diff --git a/docs/_posts/2024-06-24-v4.11.4.md b/docs/_posts/2024-06-24-v4.11.4.md new file mode 100644 index 0000000000..2f35f72d8e --- /dev/null +++ b/docs/_posts/2024-06-24-v4.11.4.md @@ -0,0 +1,69 @@ +--- +title: v4.11.4 +type: patch +--- + +**Enhancements:** + +* Add support for ingestion of CycloneDX v1.6 BOMs - [apiserver/#3863] +* Improve German translation - [frontend/#917] +* Improve Chinese translation - [frontend/#918] + +**Fixes:** + +* Fix inverted "show inactive" filter in vulnerability audit view - [apiserver/#3864] +* Fix BOM validation failing when URL contains encoded `[` and `]` characters - [apiserver/#3866] +* Fix external references not being updated via `POST /v1/component` - [apiserver/#3867] +* Fix possible XXE injection during CycloneDX validation and parsing - [GHSA-7r6q-xj4c-37g4] / [apiserver/#3871] + +For a complete list of changes, refer to the respective GitHub milestones: + +* [API server milestone 4.11.4](https://github.com/DependencyTrack/dependency-track/milestone/41?closed=1) +* [Frontend milestone 4.11.4](https://github.com/DependencyTrack/frontend/milestone/26?closed=1) + +We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes. + +Special thanks to everyone who contributed code to implement enhancements and fix defects: +[@2000rosser], [@fupgang], [@sahibamittal], [@zeed-w-beez] + +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.4/dependency-track-apiserver.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 19531d4f02cccf26478b3a63feba355da8726b3f | +| SHA-256 | 9a09259ba4c19d02b81a39fb5894df758f19ff1bb43538d4b999b4a5789a9d9b | + +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.4/dependency-track-bundled.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 3c4bb658783157ae9c408b8323e25e55c9ab25fd | +| SHA-256 | 73fc867d347da8a8af14f8c6812e13b870037a28d7de83e2837db9c27d840100 | + +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.4/frontend-dist.zip) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 5c462c69fd18bdcd87dc2c2d757a1eb268e6e679 | +| SHA-256 | ea747f848de6a6def6f73209d7f43424c6314d09bc8ea37be621be50dbac755b | + +###### Software Bill of Materials (SBOM) + +* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.4/bom.json) +* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.11.4/bom.json) + +[apiserver/#3863]: https://github.com/DependencyTrack/dependency-track/pull/3863 +[apiserver/#3864]: https://github.com/DependencyTrack/dependency-track/pull/3864 +[apiserver/#3866]: https://github.com/DependencyTrack/dependency-track/pull/3866 +[apiserver/#3867]: https://github.com/DependencyTrack/dependency-track/pull/3867 +[apiserver/#3871]: https://github.com/DependencyTrack/dependency-track/pull/3871 + +[frontend/#917]: https://github.com/DependencyTrack/frontend/pull/917 +[frontend/#918]: https://github.com/DependencyTrack/frontend/pull/918 + +[GHSA-7r6q-xj4c-37g4]: https://github.com/DependencyTrack/dependency-track/security/advisories/GHSA-7r6q-xj4c-37g4 + +[@2000rosser]: https://github.com/2000rosser +[@fupgang]: https://github.com/fupgang +[@sahibamittal]: https://github.com/sahibamittal +[@zeed-w-beez]: https://github.com/zeed-w-beez \ No newline at end of file diff --git a/docs/_posts/2024-07-08-v4.11.5.md b/docs/_posts/2024-07-08-v4.11.5.md new file mode 100644 index 0000000000..93f7dcc47e --- /dev/null +++ b/docs/_posts/2024-07-08-v4.11.5.md @@ -0,0 +1,63 @@ +--- +title: v4.11.5 +type: patch +--- + +This release primarily addresses an inability to mirror the NVD via its REST API. The NVD REST API recently experienced +increased load, causing service disruptions. Dependency-Track users who opted into API mirroring will have seen +symptoms of this as `NvdApiException: NVD Returned Status Code: 503` errors in the logs. + +To reduce load on their systems, [NIST started to block](https://github.com/jeremylong/Open-Vulnerability-Project/issues/184#issuecomment-2214217254) +requests with a certain `User-Agent` header, which Dependency-Track happens to use. Upgrading to v4.11.5 +will allow Dependency-Track to no longer be subject to this block. + +Users who can't immediately update, yet are reliant on NVD data being current, can switch back to the +feed file based mirroring by disabling *Enable mirroring via API* in the administration panel. + +**Fixes:** + +* Fix broken NVD mirroring via REST API - [apiserver/#3940] +* Fix BOM processing V2 dispatching `BOM_CONSUMED` and `BOM_PROCESSED` notification with scope `SYSTEM` instead of `PORTFOLIO` - [apiserver/#3941] +* Fix BOM export producing invalid CycloneDX for custom licenses - [apiserver/#3942] + +For a complete list of changes, refer to the respective GitHub milestones: + +* [API server milestone 4.11.5](https://github.com/DependencyTrack/dependency-track/milestone/42?closed=1) +* [Frontend milestone 4.11.5](https://github.com/DependencyTrack/frontend/milestone/27?closed=1) + +We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes. + +Special thanks to everyone who contributed code to implement enhancements and fix defects: +[@2000rosser] + +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.5/dependency-track-apiserver.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 8fd45ea6ae725e8e7dac59ec9d471fcdaeb42c6d | +| SHA-256 | c39c15849cbb7dd19833ea689c20aaf92bc9f6965b758961e1d2a01a2b09f86f | + +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.5/dependency-track-bundled.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | eba6cbaa6c2da9ffb295da83ed39af68ff4130a8 | +| SHA-256 | 7ebb11573b2a59084ed98fe92d363240c910dc7b5aa7ebeda64bee7d47089d9a | + +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.5/frontend-dist.zip) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 0992c02871d536eaa1d3971a01ce815daf115129 | +| SHA-256 | fa427fd6dde55fe6a327a82f52edcdbe29a04f23d360742fe446b0c8e1714647 | + +###### Software Bill of Materials (SBOM) + +* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.5/bom.json) +* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.11.5/bom.json) + +[apiserver/#3940]: https://github.com/DependencyTrack/dependency-track/pull/3940 +[apiserver/#3941]: https://github.com/DependencyTrack/dependency-track/pull/3941 +[apiserver/#3942]: https://github.com/DependencyTrack/dependency-track/pull/3942 + +[@2000rosser]: https://github.com/2000rosser \ No newline at end of file diff --git a/docs/_posts/2024-08-10-v4.11.6.md b/docs/_posts/2024-08-10-v4.11.6.md new file mode 100644 index 0000000000..f8d1fa90ba --- /dev/null +++ b/docs/_posts/2024-08-10-v4.11.6.md @@ -0,0 +1,70 @@ +--- +title: v4.11.6 +type: patch +--- + +**Enhancements:** + +* Improve French translation - [frontend/#964] + +**Fixes:** + +* Handle breaking change in Trivy v0.54.0 server API - [apiserver/#4040] +* Fix validation error when XML BOM declares multiple namespaces - [apiserver/#4041] +* Fix `JDOUserException` when multiple licenses match a component's license name - [apiserver/#4042] +* Fix anchors in changelog documentation - [apiserver/#4043] +* Fix project link for new vulnerable dependency in email notifications - [apiserver/#4044] +* Fix `parent` field occasionally missing in `/api/v1/project/{uuid}` responses - [apiserver/#4049] +* Fix VEX export returning invalid CycloneDX - [apiserver/#4054] + +For a complete list of changes, refer to the respective GitHub milestones: + +* [API server milestone 4.11.6](https://github.com/DependencyTrack/dependency-track/milestone/43?closed=1) +* [Frontend milestone 4.11.6](https://github.com/DependencyTrack/frontend/milestone/28?closed=1) + +We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes. + +Special thanks to everyone who contributed code to implement enhancements and fix defects: +[@2000rosser], [@JCHacking], [@SaberStrat], [@molusk], [@philippn] + +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.6/dependency-track-apiserver.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | daab7ed5b760ff909e4b9cc041b89c3374c1d955 | +| SHA-256 | a76cc3417728bdc880f41af613e543d3e5f033d7b0b1db84ffb397bcbcb3936b | + +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.6/dependency-track-bundled.jar) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | 8ff2bd4db69e7083d501a4c489f703677044a5f0 | +| SHA-256 | fd1c25e2b2d727f377eeec8240370558a9796225fe4dc0f258021b1061fbc36f | + +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.6/frontend-dist.zip) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | c91bede201957c994f338a043a44ebd32824319e | +| SHA-256 | 55ea0735b80c8cc17d31590ba16c3650943a3cdb595accf3540fefd1670ee1b9 | + +###### Software Bill of Materials (SBOM) + +* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.6/bom.json) +* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.11.6/bom.json) + +[apiserver/#4040]: https://github.com/DependencyTrack/dependency-track/pull/4040 +[apiserver/#4041]: https://github.com/DependencyTrack/dependency-track/pull/4041 +[apiserver/#4042]: https://github.com/DependencyTrack/dependency-track/pull/4042 +[apiserver/#4043]: https://github.com/DependencyTrack/dependency-track/pull/4043 +[apiserver/#4044]: https://github.com/DependencyTrack/dependency-track/pull/4044 +[apiserver/#4049]: https://github.com/DependencyTrack/dependency-track/pull/4049 +[apiserver/#4054]: https://github.com/DependencyTrack/dependency-track/pull/4054 + +[frontend/#964]: https://github.com/DependencyTrack/frontend/pull/964 + +[@2000rosser]: https://github.com/2000rosser +[@JCHacking]: https://github.com/JCHacking +[@SaberStrat]: https://github.com/SaberStrat +[@molusk]: https://github.com/molusk +[@philippn]: https://github.com/philippn diff --git a/docs/_posts/2024-08-14-v4.11.7.md b/docs/_posts/2024-08-14-v4.11.7.md new file mode 100644 index 0000000000..3cb91d1fa2 --- /dev/null +++ b/docs/_posts/2024-08-14-v4.11.7.md @@ -0,0 +1,43 @@ +--- +title: v4.11.7 +type: patch +--- + +**Fixes:** + +* Fix `directDependencies`, `externalReferences`, and `metadata` fields missing from `/api/v1/project/{uuid}` response when not already cached - [apiserver/#4071] + +For a complete list of changes, refer to the respective GitHub milestones: + +* [API server milestone 4.11.7](https://github.com/DependencyTrack/dependency-track/milestone/44?closed=1) +* [Frontend milestone 4.11.7](https://github.com/DependencyTrack/frontend/milestone/29?closed=1) + +We thank all organizations and individuals who contributed to this release, from logging issues to taking part in discussions on GitHub & Slack to testing of fixes. + +###### [dependency-track-apiserver.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.7/dependency-track-apiserver.jar) + +| Algorithm | Checksum | +|:----------|:---------| +| SHA-1 | 9a916abcbb478a4dbad101f5335acdf2b8462062 | +| SHA-256 | 2df1b2ea67a16cdc6108c3ac2f538018e529205ce5f36a6da78f2feefeddd2c8 | + +###### [dependency-track-bundled.jar](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.7/dependency-track-bundled.jar) + +| Algorithm | Checksum | +|:----------|:---------| +| SHA-1 | c5a30ee550af8a943bb77167e515fb6422e51b36 | +| SHA-256 | 4665cdd14351d7b1c41004ffc57791297c4ec5fc7f958635cff246d1b1a95eed | + +###### [frontend-dist.zip](https://github.com/DependencyTrack/frontend/releases/download/4.11.7/frontend-dist.zip) + +| Algorithm | Checksum | +|:----------|:-----------------------------------------------------------------| +| SHA-1 | f481a9fca8e9f1eca7693cd638eef0eb5a1ed5a2 | +| SHA-256 | 332cc69c102c3df90f41c10687b78553dfb8bf6a66ffb6236f97d24fc932b2b7 | + +###### Software Bill of Materials (SBOM) + +* API Server: [bom.json](https://github.com/DependencyTrack/dependency-track/releases/download/4.11.7/bom.json) +* Frontend: [bom.json](https://github.com/DependencyTrack/frontend/releases/download/4.11.7/bom.json) + +[apiserver/#4071]: https://github.com/DependencyTrack/dependency-track/pull/4071 diff --git a/pom.xml b/pom.xml index 05f08fddd5..c381c31cf7 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ org.dependencytrack dependency-track war - 4.11.0 + 4.11.8-SNAPSHOT Dependency-Track https://dependencytrack.org/ @@ -81,7 +81,7 @@ - 4.11.0 + 4.11.7 ${project.parent.version} 4.2.1 0.1.2 @@ -93,15 +93,22 @@ 1.26.1 1.4.2 1.0.1 - 8.0.3 + 9.0.5 1.6.15 + 2.17.1 + 2.17.1 2.3.9 20240303 3.2.7 8.11.3 3.9.6 5.15.0 - 6.0.1 + + 11.13 + 6.1.2 1.5.0 3.2.2 2.2.0 @@ -336,19 +343,6 @@ ${lib.cloud-sql-connector-jdbc-sqlserver.version} - - - xerces - xercesImpl - 2.12.2 - - - xml-apis - xml-apis - - - - org.apache.commons commons-compress diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile index b48899717b..34103e40fa 100644 --- a/src/main/docker/Dockerfile +++ b/src/main/docker/Dockerfile @@ -1,6 +1,6 @@ -FROM eclipse-temurin:21.0.3_9-jre-jammy@sha256:a56ee1f79cf57b2b31152cd471a4c85b6deb3057e4a1fbe8e50b57e7d2a1d7c9 AS jre-build +FROM eclipse-temurin:21.0.4_7-jre-jammy@sha256:870aae69d4521fdaf26e952f8026f75b37cb721e6302d4d4d7100f6b09823057 AS jre-build -FROM debian:stable-slim@sha256:ff394977014e94e9a7c67bb22f5014ea069d156b86e001174f4bae6f4618297a +FROM debian:stable-slim@sha256:f8bbfa052db81e5b8ac12e4a1d8310a85d1509d4d0d5579148059c0e8b717d4e # Arguments that can be passed at build time # Directory names must end with / to avoid errors when ADDing and COPYing diff --git a/src/main/java/org/dependencytrack/model/Finding.java b/src/main/java/org/dependencytrack/model/Finding.java index 78910d3389..aa174b14fa 100644 --- a/src/main/java/org/dependencytrack/model/Finding.java +++ b/src/main/java/org/dependencytrack/model/Finding.java @@ -100,8 +100,7 @@ public class Finding implements Serializable { // language=SQL public static final String QUERY_ALL_FINDINGS = """ - SELECT DISTINCT - "COMPONENT"."UUID" + SELECT "COMPONENT"."UUID" , "COMPONENT"."NAME" , "COMPONENT"."GROUP" , "COMPONENT"."VERSION" @@ -147,8 +146,6 @@ public class Finding implements Serializable { AND "COMPONENT"."PROJECT_ID" = "ANALYSIS"."PROJECT_ID" INNER JOIN "PROJECT" ON "COMPONENT"."PROJECT_ID" = "PROJECT"."ID" - LEFT JOIN "PROJECT_ACCESS_TEAMS" - ON "PROJECT"."ID" = "PROJECT_ACCESS_TEAMS"."PROJECT_ID" """; private final UUID project; diff --git a/src/main/java/org/dependencytrack/model/GroupedFinding.java b/src/main/java/org/dependencytrack/model/GroupedFinding.java index c4a1fb4fa4..d25a821063 100644 --- a/src/main/java/org/dependencytrack/model/GroupedFinding.java +++ b/src/main/java/org/dependencytrack/model/GroupedFinding.java @@ -68,8 +68,6 @@ public class GroupedFinding implements Serializable { AND "COMPONENT"."PROJECT_ID" = "ANALYSIS"."PROJECT_ID" INNER JOIN "PROJECT" ON "COMPONENT"."PROJECT_ID" = "PROJECT"."ID" - LEFT JOIN "PROJECT_ACCESS_TEAMS" - ON "PROJECT"."ID" = "PROJECT_ACCESS_TEAMS"."PROJECT_ID" """; private final Map vulnerability = new LinkedHashMap<>(); diff --git a/src/main/java/org/dependencytrack/model/Project.java b/src/main/java/org/dependencytrack/model/Project.java index 6c0ad11894..802cfe65dc 100644 --- a/src/main/java/org/dependencytrack/model/Project.java +++ b/src/main/java/org/dependencytrack/model/Project.java @@ -73,9 +73,9 @@ @PersistenceCapable @FetchGroups({ @FetchGroup(name = "ALL", members = { - @Persistent(name = "name"), @Persistent(name = "author"), @Persistent(name = "publisher"), + @Persistent(name = "manufacturer"), @Persistent(name = "supplier"), @Persistent(name = "group"), @Persistent(name = "name"), @@ -85,12 +85,18 @@ @Persistent(name = "cpe"), @Persistent(name = "purl"), @Persistent(name = "swidTagId"), + @Persistent(name = "directDependencies"), @Persistent(name = "uuid"), @Persistent(name = "parent"), @Persistent(name = "children"), @Persistent(name = "properties"), @Persistent(name = "tags"), + @Persistent(name = "lastBomImport"), + @Persistent(name = "lastBomImportFormat"), + @Persistent(name = "lastInheritedRiskScore"), + @Persistent(name = "active"), @Persistent(name = "accessTeams"), + @Persistent(name = "externalReferences"), @Persistent(name = "metadata") }), @FetchGroup(name = "METADATA", members = { diff --git a/src/main/java/org/dependencytrack/model/ProjectMetadata.java b/src/main/java/org/dependencytrack/model/ProjectMetadata.java index 6fb10e2788..a783cfe1f1 100644 --- a/src/main/java/org/dependencytrack/model/ProjectMetadata.java +++ b/src/main/java/org/dependencytrack/model/ProjectMetadata.java @@ -26,6 +26,8 @@ import javax.jdo.annotations.Column; import javax.jdo.annotations.Convert; +import javax.jdo.annotations.FetchGroup; +import javax.jdo.annotations.FetchGroups; import javax.jdo.annotations.IdGeneratorStrategy; import javax.jdo.annotations.PersistenceCapable; import javax.jdo.annotations.Persistent; @@ -41,6 +43,12 @@ * * @since 4.10.0 */ +@FetchGroups(value = { + @FetchGroup(name = "ALL", members = { + @Persistent(name = "supplier"), + @Persistent(name = "authors") + }) +}) @PersistenceCapable(table = "PROJECT_METADATA") @JsonInclude(Include.NON_NULL) public class ProjectMetadata { diff --git a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java index 1ef5903fe7..09098c7cf8 100644 --- a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java +++ b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDXExporter.java @@ -18,9 +18,9 @@ */ package org.dependencytrack.parser.cyclonedx; -import org.cyclonedx.BomGeneratorFactory; -import org.cyclonedx.CycloneDxSchema; +import org.cyclonedx.Version; import org.cyclonedx.exception.GeneratorException; +import org.cyclonedx.generators.BomGeneratorFactory; import org.cyclonedx.model.Bom; import org.dependencytrack.model.Component; import org.dependencytrack.model.Finding; @@ -80,14 +80,13 @@ private Bom create(List components, final List serv } final List cycloneComponents = (Variant.VEX != variant && components != null) ? components.stream().map(component -> ModelConverter.convert(qm, component)).collect(Collectors.toList()) : null; final List cycloneServices = (Variant.VEX != variant && services != null) ? services.stream().map(service -> ModelConverter.convert(qm, service)).collect(Collectors.toList()) : null; - final List cycloneVulnerabilities = (findings != null) ? findings.stream().map(finding -> ModelConverter.convert(qm, variant, finding)).collect(Collectors.toList()) : null; final Bom bom = new Bom(); bom.setSerialNumber("urn:uuid:" + UUID.randomUUID()); bom.setVersion(1); bom.setMetadata(ModelConverter.createMetadata(project)); bom.setComponents(cycloneComponents); bom.setServices(cycloneServices); - bom.setVulnerabilities(cycloneVulnerabilities); + bom.setVulnerabilities(ModelConverter.generateVulnerabilities(qm, variant, findings)); if (cycloneComponents != null) { bom.setDependencies(ModelConverter.generateDependencies(project, components)); } @@ -95,10 +94,12 @@ private Bom create(List components, final List serv } public String export(final Bom bom, final Format format) throws GeneratorException { + // TODO: The output version should be user-controllable. + if (Format.JSON == format) { - return BomGeneratorFactory.createJson(CycloneDxSchema.VERSION_LATEST, bom).toJsonString(); + return BomGeneratorFactory.createJson(Version.VERSION_15, bom).toJsonString(); } else { - return BomGeneratorFactory.createXml(CycloneDxSchema.VERSION_LATEST, bom).toXmlString(); + return BomGeneratorFactory.createXml(Version.VERSION_15, bom).toXmlString(); } } diff --git a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidator.java b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidator.java index 84afedc263..6da17ac789 100644 --- a/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidator.java +++ b/src/main/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidator.java @@ -22,13 +22,13 @@ import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.json.JsonMapper; -import org.codehaus.stax2.XMLInputFactory2; -import org.cyclonedx.CycloneDxSchema; +import org.cyclonedx.Version; import org.cyclonedx.exception.ParseException; import org.cyclonedx.parsers.JsonParser; import org.cyclonedx.parsers.Parser; import org.cyclonedx.parsers.XmlParser; +import javax.xml.XMLConstants; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; @@ -45,12 +45,14 @@ import static org.cyclonedx.CycloneDxSchema.NS_BOM_13; import static org.cyclonedx.CycloneDxSchema.NS_BOM_14; import static org.cyclonedx.CycloneDxSchema.NS_BOM_15; -import static org.cyclonedx.CycloneDxSchema.Version.VERSION_10; -import static org.cyclonedx.CycloneDxSchema.Version.VERSION_11; -import static org.cyclonedx.CycloneDxSchema.Version.VERSION_12; -import static org.cyclonedx.CycloneDxSchema.Version.VERSION_13; -import static org.cyclonedx.CycloneDxSchema.Version.VERSION_14; -import static org.cyclonedx.CycloneDxSchema.Version.VERSION_15; +import static org.cyclonedx.CycloneDxSchema.NS_BOM_16; +import static org.cyclonedx.Version.VERSION_10; +import static org.cyclonedx.Version.VERSION_11; +import static org.cyclonedx.Version.VERSION_12; +import static org.cyclonedx.Version.VERSION_13; +import static org.cyclonedx.Version.VERSION_14; +import static org.cyclonedx.Version.VERSION_15; +import static org.cyclonedx.Version.VERSION_16; /** * @since 4.11.0 @@ -92,10 +94,13 @@ public void validate(final byte[] bomBytes) { } private FormatAndVersion detectFormatAndSchemaVersion(final byte[] bomBytes) { + final var suppressedExceptions = new ArrayList(2); + try { - final CycloneDxSchema.Version version = detectSchemaVersionFromJson(bomBytes); + final Version version = detectSchemaVersionFromJson(bomBytes); return new FormatAndVersion(Format.JSON, version); } catch (JsonParseException e) { + suppressedExceptions.add(e); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Failed to parse BOM as JSON", e); } @@ -104,18 +109,21 @@ private FormatAndVersion detectFormatAndSchemaVersion(final byte[] bomBytes) { } try { - final CycloneDxSchema.Version version = detectSchemaVersionFromXml(bomBytes); + final Version version = detectSchemaVersionFromXml(bomBytes); return new FormatAndVersion(Format.XML, version); } catch (XMLStreamException e) { + suppressedExceptions.add(e); if (LOGGER.isDebugEnabled()) { LOGGER.debug("Failed to parse BOM as XML", e); } } - throw new InvalidBomException("BOM is neither valid JSON nor XML"); + final var exception = new InvalidBomException("BOM is neither valid JSON nor XML"); + suppressedExceptions.forEach(exception::addSuppressed); + throw exception; } - private CycloneDxSchema.Version detectSchemaVersionFromJson(final byte[] bomBytes) throws IOException { + private Version detectSchemaVersionFromJson(final byte[] bomBytes) throws IOException { try (final com.fasterxml.jackson.core.JsonParser jsonParser = jsonMapper.createParser(bomBytes)) { JsonToken currentToken = jsonParser.nextToken(); if (currentToken != JsonToken.START_OBJECT) { @@ -125,8 +133,8 @@ private CycloneDxSchema.Version detectSchemaVersionFromJson(final byte[] bomByte .formatted(JsonToken.START_OBJECT.asString(), currentTokenAsString)); } - CycloneDxSchema.Version schemaVersion = null; - while (jsonParser.nextToken() != JsonToken.END_OBJECT) { + Version schemaVersion = null; + while (jsonParser.nextToken() != null) { final String fieldName = jsonParser.getCurrentName(); if ("specVersion".equals(fieldName)) { if (jsonParser.nextToken() == JsonToken.VALUE_STRING) { @@ -138,6 +146,7 @@ private CycloneDxSchema.Version detectSchemaVersionFromJson(final byte[] bomByte case "1.3" -> VERSION_13; case "1.4" -> VERSION_14; case "1.5" -> VERSION_15; + case "1.6" -> VERSION_16; default -> throw new InvalidBomException("Unrecognized specVersion %s".formatted(specVersion)); }; @@ -153,12 +162,18 @@ private CycloneDxSchema.Version detectSchemaVersionFromJson(final byte[] bomByte } } - private CycloneDxSchema.Version detectSchemaVersionFromXml(final byte[] bomBytes) throws XMLStreamException { - final XMLInputFactory xmlInputFactory = XMLInputFactory2.newFactory(); + private Version detectSchemaVersionFromXml(final byte[] bomBytes) throws XMLStreamException { + final XMLInputFactory xmlInputFactory = XMLInputFactory.newFactory(); + xmlInputFactory.setProperty(XMLConstants.FEATURE_SECURE_PROCESSING, true); + // NB: Setting XMLConstants.ACCESS_EXTERNAL_DTD to empty string is recommended by SAST tools, + // but Woodstox does not support it: https://github.com/FasterXML/woodstox/issues/51 + // Setting IS_SUPPORTING_EXTERNAL_ENTITIES to false achieves the same: + // https://github.com/FasterXML/woodstox/issues/50#issuecomment-388842419 + xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); final var bomBytesStream = new ByteArrayInputStream(bomBytes); final XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(bomBytesStream); - CycloneDxSchema.Version schemaVersion = null; + Version schemaVersion = null; while (xmlStreamReader.hasNext()) { if (xmlStreamReader.next() == XMLEvent.START_ELEMENT) { if (!"bom".equalsIgnoreCase(xmlStreamReader.getLocalName())) { @@ -177,8 +192,13 @@ private CycloneDxSchema.Version detectSchemaVersionFromXml(final byte[] bomBytes case NS_BOM_13 -> VERSION_13; case NS_BOM_14 -> VERSION_14; case NS_BOM_15 -> VERSION_15; + case NS_BOM_16 -> VERSION_16; default -> null; }; + + if (schemaVersion != null) { + break; + } } if (schemaVersion == null) { @@ -202,7 +222,7 @@ private enum Format { XML } - private record FormatAndVersion(Format format, CycloneDxSchema.Version version) { + private record FormatAndVersion(Format format, Version version) { } } diff --git a/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java b/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java index 003d85a18f..958933da07 100644 --- a/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java +++ b/src/main/java/org/dependencytrack/parser/cyclonedx/util/ModelConverter.java @@ -33,6 +33,7 @@ import org.cyclonedx.model.Hash; import org.cyclonedx.model.LicenseChoice; import org.cyclonedx.model.Swid; +import org.cyclonedx.model.license.Expression; import org.dependencytrack.model.Analysis; import org.dependencytrack.model.AnalysisJustification; import org.dependencytrack.model.AnalysisResponse; @@ -212,9 +213,9 @@ public static Component convertComponent(final org.cyclonedx.model.Component cdx } final var licenseCandidates = new ArrayList(); - if (cdxComponent.getLicenseChoice() != null) { - if (cdxComponent.getLicenseChoice().getLicenses() != null) { - cdxComponent.getLicenseChoice().getLicenses().stream() + if (cdxComponent.getLicenses() != null) { + if (cdxComponent.getLicenses().getLicenses() != null) { + cdxComponent.getLicenses().getLicenses().stream() .filter(license -> isNotBlank(license.getId()) || isNotBlank(license.getName())) .peek(license -> { // License text can be large, but we don't need it for further processing. Drop it. @@ -223,12 +224,13 @@ public static Component convertComponent(final org.cyclonedx.model.Component cdx .forEach(licenseCandidates::add); } - if (isNotBlank(cdxComponent.getLicenseChoice().getExpression())) { + final Expression licenseExpression = cdxComponent.getLicenses().getExpression(); + if (licenseExpression != null && isNotBlank(licenseExpression.getValue())) { // If the expression consists of just one license ID, add it as another option. final var expressionParser = new SpdxExpressionParser(); - final SpdxExpression expression = expressionParser.parse(cdxComponent.getLicenseChoice().getExpression()); + final SpdxExpression expression = expressionParser.parse(licenseExpression.getValue()); if (!SpdxExpression.INVALID.equals(expression)) { - component.setLicenseExpression(trim(cdxComponent.getLicenseChoice().getExpression())); + component.setLicenseExpression(trim(licenseExpression.getValue())); if (expression.getSpdxLicenseId() != null) { final var expressionLicense = new org.cyclonedx.model.License(); @@ -240,7 +242,7 @@ public static Component convertComponent(final org.cyclonedx.model.Component cdx LOGGER.warn(""" Encountered invalid license expression "%s" for \ Component{group=%s, name=%s, version=%s, bomRef=%s}; Skipping\ - """.formatted(cdxComponent.getLicenseChoice().getExpression(), component.getGroup(), + """.formatted(cdxComponent.getLicenses().getExpression(), component.getGroup(), component.getName(), component.getVersion(), component.getBomRef())); } } @@ -526,16 +528,16 @@ public static Component convert(final QueryManager qm, final org.cyclonedx.model } } - final LicenseChoice licenseChoice = cycloneDxComponent.getLicenseChoice(); - if (licenseChoice != null) { + final LicenseChoice licenses = cycloneDxComponent.getLicenses(); + if (licenses != null) { final List licenseOptions = new ArrayList<>(); - if (licenseChoice.getExpression() != null) { + if (licenses.getExpression() != null && isNotBlank(licenses.getExpression().getValue())) { final var expressionParser = new SpdxExpressionParser(); - final SpdxExpression parsedExpression = expressionParser.parse(licenseChoice.getExpression()); + final SpdxExpression parsedExpression = expressionParser.parse(licenses.getExpression().getValue()); if (!Objects.equals(parsedExpression, SpdxExpression.INVALID)) { // store license expression, but don't overwrite manual changes to the field if (component.getLicenseExpression() == null) { - component.setLicenseExpression(licenseChoice.getExpression()); + component.setLicenseExpression(licenses.getExpression().getValue()); } // if the expression just consists of one license id, we can add it as another license option if (parsedExpression.getSpdxLicenseId() != null) { @@ -547,34 +549,34 @@ public static Component convert(final QueryManager qm, final org.cyclonedx.model LOGGER.warn(""" Encountered invalid license expression "%s" for \ Component{group=%s, name=%s, version=%s, bomRef=%s}; Skipping\ - """.formatted(licenseChoice.getExpression(), component.getGroup(), + """.formatted(licenses.getExpression(), component.getGroup(), component.getName(), component.getVersion(), component.getBomRef())); } } // add license options from the component's license array. These will have higher priority // than the one from the parsed expression, because the following loop iterates through all // the options and does not stop once it found a match. - if (licenseChoice.getLicenses() != null && !licenseChoice.getLicenses().isEmpty()) { - licenseOptions.addAll(licenseChoice.getLicenses()); + if (licenses.getLicenses() != null && !licenses.getLicenses().isEmpty()) { + licenseOptions.addAll(licenses.getLicenses()); } // try to find a license in the database among the license options for (final org.cyclonedx.model.License cycloneLicense : licenseOptions) { if (cycloneLicense != null) { if (StringUtils.isNotBlank(cycloneLicense.getId())) { - final License license = qm.getLicense(StringUtils.trimToNull(cycloneLicense.getId())); - if (license != null) { + final License license = qm.getLicenseByIdOrName(StringUtils.trimToNull(cycloneLicense.getId())); + if (license != License.UNRESOLVED) { component.setResolvedLicense(license); } } else if (StringUtils.isNotBlank(cycloneLicense.getName())) { - final License license = qm.getLicense(StringUtils.trimToNull(cycloneLicense.getName())); - if (license != null) { + final License license = qm.getLicenseByIdOrName(StringUtils.trimToNull(cycloneLicense.getName())); + if (license != License.UNRESOLVED) { component.setResolvedLicense(license); } else { - final License customLicense = qm.getCustomLicense(StringUtils.trimToNull(cycloneLicense.getName())); - if (customLicense != null) { + final License customLicense = qm.getCustomLicenseByName(StringUtils.trimToNull(cycloneLicense.getName())); + if (customLicense != License.UNRESOLVED) { component.setResolvedLicense(customLicense); } } @@ -749,28 +751,34 @@ public static org.cyclonedx.model.Component convert(final QueryManager qm, final cycloneComponent.addHash(new Hash(Hash.Algorithm.SHA3_512, component.getSha3_512())); } - final LicenseChoice licenseChoice = new LicenseChoice(); + final LicenseChoice licenses = new LicenseChoice(); if (component.getResolvedLicense() != null) { final org.cyclonedx.model.License license = new org.cyclonedx.model.License(); - license.setId(component.getResolvedLicense().getLicenseId()); + if (!component.getResolvedLicense().isCustomLicense()) { + license.setId(component.getResolvedLicense().getLicenseId()); + } else { + license.setName(component.getResolvedLicense().getName()); + } license.setUrl(component.getLicenseUrl()); - licenseChoice.addLicense(license); - cycloneComponent.setLicenseChoice(licenseChoice); + licenses.addLicense(license); + cycloneComponent.setLicenses(licenses); } else if (component.getLicense() != null) { final org.cyclonedx.model.License license = new org.cyclonedx.model.License(); license.setName(component.getLicense()); license.setUrl(component.getLicenseUrl()); - licenseChoice.addLicense(license); - cycloneComponent.setLicenseChoice(licenseChoice); + licenses.addLicense(license); + cycloneComponent.setLicenses(licenses); } else if (StringUtils.isNotEmpty(component.getLicenseUrl())) { final org.cyclonedx.model.License license = new org.cyclonedx.model.License(); license.setUrl(component.getLicenseUrl()); - licenseChoice.addLicense(license); - cycloneComponent.setLicenseChoice(licenseChoice); + licenses.addLicense(license); + cycloneComponent.setLicenses(licenses); } if (component.getLicenseExpression() != null) { - licenseChoice.setExpression(component.getLicenseExpression()); - cycloneComponent.setLicenseChoice(licenseChoice); + final var licenseExpression = new Expression(); + licenseExpression.setValue(component.getLicenseExpression()); + licenses.setExpression(licenseExpression); + cycloneComponent.setLicenses(licenses); } @@ -1176,6 +1184,18 @@ public static org.cyclonedx.model.vulnerability.Vulnerability convert(final Quer return cdxVulnerability; } + public static List generateVulnerabilities(final QueryManager qm, final CycloneDXExporter.Variant variant, + final List findings) { + if (findings == null) { + return Collections.emptyList(); + } + final var vulnerabilitiesSeen = new HashSet(); + return findings.stream() + .map(finding -> convert(qm, variant, finding)) + .filter(vulnerabilitiesSeen::add) + .toList(); + } + /** * Converts a parsed Bom to a native list of Dependency-Track component objects * diff --git a/src/main/java/org/dependencytrack/parser/trivy/model/Application.java b/src/main/java/org/dependencytrack/parser/trivy/model/Application.java index fdffec2a10..d56f34abe4 100644 --- a/src/main/java/org/dependencytrack/parser/trivy/model/Application.java +++ b/src/main/java/org/dependencytrack/parser/trivy/model/Application.java @@ -19,20 +19,51 @@ package org.dependencytrack.parser.trivy.model; import java.util.ArrayList; +import java.util.List; public class Application { + private String type; - private ArrayList libraries; + private List packages; + + /** + * NB: GSON doesn't support serialization of getters, it can only deal with fields. + * Need to have libraries as redundant field to packages, with Jackson we could just + * use a computed getter with {@link com.fasterxml.jackson.annotation.JsonGetter}. + * Migrate this to Jackson eventually. + * + * @see GitHub issue + * @deprecated Kept for compatibility with Trivy <= 0.51.1 + */ + @Deprecated(forRemoval = true) + private List libraries; - public Application(String type) { + public Application(final String type) { this.type = type; - this.libraries = new ArrayList(); + this.packages = new ArrayList<>(); + this.libraries = new ArrayList<>(); + } + + public String getType() { + return type; + } + + public void setType(String value) { + this.type = value; } - public String getType() { return type; } - public void setType(String value) { this.type = value; } + public List getPackages() { + return packages; + } + + public void setPackages(List value) { + this.packages = value; + this.libraries = value; + } + + public void addPackage(Package value) { + this.packages.add(value); + this.libraries.add(value); + } - public ArrayList getLibraries() { return libraries; } - public void setLibraries(ArrayList value) { this.libraries = value; } - public void addLibrary(Library value) { this.libraries.add(value); } } \ No newline at end of file diff --git a/src/main/java/org/dependencytrack/parser/trivy/model/Library.java b/src/main/java/org/dependencytrack/parser/trivy/model/Library.java deleted file mode 100644 index d8092e186e..0000000000 --- a/src/main/java/org/dependencytrack/parser/trivy/model/Library.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of Dependency-Track. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * Copyright (c) OWASP Foundation. All Rights Reserved. - */ -package org.dependencytrack.parser.trivy.model; - -public class Library { - private String name; - private String version; - private String[] licenses; - private OS layer; - - public Library(String name, String version) { - this.name = name; - this.version = version; - this.licenses = new String[] {}; - this.layer = new OS(); - } - - public String getName() { return name; } - public void setName(String value) { this.name = value; } - - public String getVersion() { return version; } - public void setVersion(String value) { this.version = value; } - - public String[] getLicenses() { return licenses; } - public void setLicenses(String[] value) { this.licenses = value; } - - public OS getLayer() { return layer; } - public void setLayer(OS value) { this.layer = value; } -} diff --git a/src/main/java/org/dependencytrack/parser/trivy/model/Options.java b/src/main/java/org/dependencytrack/parser/trivy/model/Options.java index bce21e204b..888f162187 100644 --- a/src/main/java/org/dependencytrack/parser/trivy/model/Options.java +++ b/src/main/java/org/dependencytrack/parser/trivy/model/Options.java @@ -21,13 +21,32 @@ import com.google.gson.annotations.SerializedName; public class Options { + + /** + * NB: GSON doesn't support serialization of getters, it can only deal with fields. + * Need to have libraries as redundant field to packages, with Jackson we could just + * use a computed getter with {@link com.fasterxml.jackson.annotation.JsonGetter}. + * Migrate this to Jackson eventually. + * + * @see GitHub issue + * @deprecated Kept for compatibility with Trivy < 0.54.0 + */ + @Deprecated(forRemoval = true) @SerializedName("vuln_type") private String[] vulnType; + + @SerializedName("pkg_types") + private String[] pkgTypes; + private String[] scanners; - public String[] getVulnType() { return vulnType; } - public void setVulnType(String[] value) { this.vulnType = value; } + public void setPkgTypes(String[] value) { + this.pkgTypes = value; + this.vulnType = value; + } + + public void setScanners(String[] value) { + this.scanners = value; + } - public String[] getScanners() { return scanners; } - public void setScanners(String[] value) { this.scanners = value; } } \ No newline at end of file diff --git a/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java b/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java index 83d956797a..abd22a0c51 100644 --- a/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/ComponentQueryManager.java @@ -418,6 +418,7 @@ public Component updateComponent(Component transientComponent, boolean commitInd component.setInternal(transientComponent.isInternal()); component.setAuthor(transientComponent.getAuthor()); component.setSupplier(transientComponent.getSupplier()); + component.setExternalReferences(transientComponent.getExternalReferences()); final Component result = persist(component); Event.dispatch(new IndexEvent(IndexEvent.Action.UPDATE, result)); commitSearchIndex(commitIndex, Component.class); diff --git a/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java b/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java index 3732200cf6..c6c495787a 100644 --- a/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/FindingsSearchQueryManager.java @@ -18,9 +18,6 @@ */ package org.dependencytrack.persistence; -import alpine.model.ApiKey; -import alpine.model.Team; -import alpine.model.UserPrincipal; import alpine.persistence.OrderDirection; import alpine.persistence.PaginatedResult; import alpine.resources.AlpineRequest; @@ -39,7 +36,6 @@ import javax.jdo.PersistenceManager; import javax.jdo.Query; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -107,7 +103,7 @@ public class FindingsSearchQueryManager extends QueryManager implements IQueryMa public PaginatedResult getAllFindings(final Map filters, final boolean showSuppressed, final boolean showInactive) { StringBuilder queryFilter = new StringBuilder(); Map params = new HashMap<>(); - if (showInactive) { + if (!showInactive) { queryFilter.append(" WHERE (\"PROJECT\".\"ACTIVE\" = :active OR \"PROJECT\".\"ACTIVE\" IS NULL)"); params.put("active", true); } @@ -165,7 +161,7 @@ public PaginatedResult getAllFindings(final Map filters, final b public PaginatedResult getAllFindingsGroupedByVulnerability(final Map filters, final boolean showInactive) { StringBuilder queryFilter = new StringBuilder(); Map params = new HashMap<>(); - if (showInactive) { + if (!showInactive) { queryFilter.append(" WHERE (\"PROJECT\".\"ACTIVE\" = :active OR \"PROJECT\".\"ACTIVE\" IS NULL)"); params.put("active", true); } @@ -347,44 +343,37 @@ private void processInputFilter(StringBuilder queryFilter, Map p } private void preprocessACLs(StringBuilder queryFilter, final Map params) { - if (super.principal != null && isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED)) { - final List teams; - if (super.principal instanceof UserPrincipal userPrincipal) { - teams = userPrincipal.getTeams(); - if (super.hasAccessManagementPermission(userPrincipal)) { - return; - } - } else if (super.principal instanceof final ApiKey apiKey) { - teams = apiKey.getTeams(); - if (super.hasAccessManagementPermission(apiKey)) { - return; - } - } else { - teams = Collections.emptyList(); - } - if (teams != null && !teams.isEmpty()) { - final StringBuilder sb = new StringBuilder(); - for (int i = 0, teamsSize = teams.size(); i < teamsSize; i++) { - final Team team = super.getObjectById(Team.class, teams.get(i).getId()); - sb.append(" \"PROJECT_ACCESS_TEAMS\".\"TEAM_ID\" = :team").append(i); - params.put("team" + i, team.getId()); - if (i < teamsSize - 1) { - sb.append(" OR "); - } - } - if (queryFilter != null && !queryFilter.isEmpty()) { - queryFilter.append(" AND (").append(sb).append(")"); - } else if (queryFilter != null) { - queryFilter.append("WHERE (").append(sb).append(")"); - } - } else { - params.put("false", false); - if (queryFilter != null && !queryFilter.isEmpty()) { - queryFilter.append(" AND :false"); - } else if (queryFilter != null) { - queryFilter.append("WHERE :false"); - } - } + if (!isEnabled(ConfigPropertyConstants.ACCESS_MANAGEMENT_ACL_ENABLED) + || hasAccessManagementPermission(this.principal)) { + return; + } + + if (queryFilter.isEmpty()) { + queryFilter.append(" WHERE "); + } else { + queryFilter.append(" AND "); + } + + final var teamIds = new ArrayList<>(getTeamIds(principal)); + if (teamIds.isEmpty()) { + queryFilter.append(":false"); + params.put("false", false); + return; + } + + // NB: Need to work around the fact that the RDBMSes can't agree on how to do member checks. Oh joy! :))) + final var teamIdChecks = new ArrayList(); + for (int i = 0; i < teamIds.size(); i++) { + teamIdChecks.add("\"PROJECT_ACCESS_TEAMS\".\"TEAM_ID\" = :teamId" + i); + params.put("teamId" + i, teamIds.get(i)); } + + queryFilter.append(""" + EXISTS ( + SELECT 1 + FROM "PROJECT_ACCESS_TEAMS" + WHERE "PROJECT_ACCESS_TEAMS"."PROJECT_ID" = "PROJECT"."ID" + AND (%s) + )""".formatted(String.join(" OR ", teamIdChecks))); } } diff --git a/src/main/java/org/dependencytrack/persistence/LicenseQueryManager.java b/src/main/java/org/dependencytrack/persistence/LicenseQueryManager.java index 0830237886..b31c548929 100644 --- a/src/main/java/org/dependencytrack/persistence/LicenseQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/LicenseQueryManager.java @@ -28,6 +28,7 @@ import javax.jdo.PersistenceManager; import javax.jdo.Query; import java.util.List; +import java.util.Map; final class LicenseQueryManager extends QueryManager implements IQueryManager { @@ -93,6 +94,20 @@ public License getLicense(String licenseId) { return singleResult(query.execute(licenseId)); } + public License getLicenseByIdOrName(final String licenseIdOrName) { + final Query query = pm.newQuery(License.class); + query.setFilter("licenseId == :licenseIdOrName || name == :licenseIdOrName"); + query.setNamedParameters(Map.of("licenseIdOrName", licenseIdOrName)); + query.setOrdering("licenseId asc"); // Ensure result is consistent. + query.setRange(0, 1); // Multiple licenses can have the same name; Pick the first one. + try { + final License license = query.executeUnique(); + return license != null ? license : License.UNRESOLVED; + } finally { + query.closeAll(); + } + } + /** * Returns a Custom License object from the specified name * @param licenseName license name of custom license @@ -105,6 +120,21 @@ public License getCustomLicense(String licenseName) { return singleResult(query.execute(licenseName)); } + @Override + public License getCustomLicenseByName(final String licenseName) { + final Query query = pm.newQuery(License.class); + query.setFilter("name == :name && customLicense == true"); + query.setParameters(licenseName); + query.setOrdering("licenseId asc"); // Ensure result is consistent. + query.setRange(0, 1); // Multiple licenses can have the same name; Pick the first one. + try { + final License license = query.executeUnique(); + return license != null ? license : License.UNRESOLVED; + } finally { + query.closeAll(); + } + } + /** * Creates a new License. * @param license the License object to create diff --git a/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java b/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java index 6b1a97b7f5..acfc7b4770 100644 --- a/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/ProjectQueryManager.java @@ -217,7 +217,7 @@ public PaginatedResult getProjects(final String name, final boolean excludeInact */ @Override public Project getProject(final String uuid) { - final Project project = getObjectByUuid(Project.class, uuid, Project.FetchGroup.ALL.name()); + final Project project = getObjectByUuid(Project.class, UUID.fromString(uuid), List.of(Project.FetchGroup.ALL.name())); if (project != null) { // set Metrics to minimize the number of round trips a client needs to make project.setMetrics(getMostRecentProjectMetrics(project)); diff --git a/src/main/java/org/dependencytrack/persistence/QueryManager.java b/src/main/java/org/dependencytrack/persistence/QueryManager.java index e8b2f7f813..310bd0d6c8 100644 --- a/src/main/java/org/dependencytrack/persistence/QueryManager.java +++ b/src/main/java/org/dependencytrack/persistence/QueryManager.java @@ -31,6 +31,7 @@ import alpine.resources.AlpineRequest; import com.github.packageurl.PackageURL; import com.google.common.collect.Lists; +import org.apache.commons.lang3.ClassUtils; import org.datanucleus.PropertyNames; import org.datanucleus.api.jdo.JDOQuery; import org.dependencytrack.event.IndexEvent; @@ -88,6 +89,7 @@ import java.security.Principal; import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -351,6 +353,30 @@ public QueryManager withL2CacheDisabled() { return this; } + /** + * Get the IDs of the {@link Team}s a given {@link Principal} is a member of. + * + * @return A {@link Set} of {@link Team} IDs + * @since 4.11.1 + */ + protected Set getTeamIds(final Principal principal) { + final var principalTeamIds = new HashSet(); + + if (principal instanceof final UserPrincipal userPrincipal + && userPrincipal.getTeams() != null) { + for (final Team userInTeam : userPrincipal.getTeams()) { + principalTeamIds.add(userInTeam.getId()); + } + } else if (principal instanceof final ApiKey apiKey + && apiKey.getTeams() != null) { + for (final Team userInTeam : apiKey.getTeams()) { + principalTeamIds.add(userInTeam.getId()); + } + } + + return principalTeamIds; + } + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //// BEGIN WRAPPER METHODS //// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -594,10 +620,18 @@ public License getLicense(String licenseId) { return getLicenseQueryManager().getLicense(licenseId); } + public License getLicenseByIdOrName(final String licenseIdOrName) { + return getLicenseQueryManager().getLicenseByIdOrName(licenseIdOrName); + } + public License getCustomLicense(String licenseName) { return getLicenseQueryManager().getCustomLicense(licenseName); } + public License getCustomLicenseByName(final String licenseName) { + return getLicenseQueryManager().getCustomLicenseByName(licenseName); + } + public License synchronizeLicense(License license, boolean commitIndex) { return getLicenseQueryManager().synchronizeLicense(license, commitIndex); } @@ -1283,6 +1317,16 @@ public void commitSearchIndex(Class clazz) { commitSearchIndex(true, clazz); } + public boolean hasAccessManagementPermission(final Object principal) { + if (principal instanceof final UserPrincipal userPrincipal) { + return hasAccessManagementPermission(userPrincipal); + } else if (principal instanceof final ApiKey apiKey) { + return hasAccessManagementPermission(apiKey); + } + + throw new IllegalArgumentException("Provided principal is of invalid type " + ClassUtils.getName(principal)); + } + public boolean hasAccessManagementPermission(final UserPrincipal userPrincipal) { return getProjectQueryManager().hasAccessManagementPermission(userPrincipal); } @@ -1309,15 +1353,17 @@ public PaginatedResult getTags(String policyUuid) { * @param fetchGroups Fetch groups to use for this operation * @return The object if found, otherwise {@code null} * @param Type of the object - * @throws Exception When closing the query failed * @since 4.6.0 */ - public T getObjectByUuid(final Class clazz, final UUID uuid, final List fetchGroups) throws Exception { - try (final Query query = pm.newQuery(clazz)) { - query.setFilter("uuid == :uuid"); - query.setParameters(uuid); - query.getFetchPlan().setGroups(fetchGroups); + public T getObjectByUuid(final Class clazz, final UUID uuid, final List fetchGroups) { + final Query query = pm.newQuery(clazz); + query.setFilter("uuid == :uuid"); + query.setParameters(uuid); + query.getFetchPlan().setGroups(fetchGroups); + try { return query.executeUnique(); + } finally { + query.closeAll(); } } diff --git a/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java b/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java index 23e90d1252..1391044b73 100644 --- a/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java +++ b/src/main/java/org/dependencytrack/resources/v1/ComponentResource.java @@ -418,6 +418,7 @@ public Response updateComponent(Component jsonComponent) { component.setSha3_256(StringUtils.trimToNull(jsonComponent.getSha3_256())); component.setSha3_384(StringUtils.trimToNull(jsonComponent.getSha3_384())); component.setSha3_512(StringUtils.trimToNull(jsonComponent.getSha3_512())); + component.setExternalReferences(jsonComponent.getExternalReferences()); final License resolvedLicense = qm.getLicense(jsonComponent.getLicense()); if (resolvedLicense != null) { diff --git a/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java b/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java index c8d72843da..e18f04176a 100644 --- a/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java +++ b/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTask.java @@ -23,7 +23,7 @@ import alpine.event.framework.Subscriber; import alpine.notification.Notification; import alpine.notification.NotificationLevel; -import org.cyclonedx.BomParserFactory; +import org.cyclonedx.parsers.BomParserFactory; import org.cyclonedx.parsers.Parser; import org.dependencytrack.event.BomUploadEvent; import org.dependencytrack.event.NewVulnerableDependencyAnalysisEvent; diff --git a/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTaskV2.java b/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTaskV2.java index b6b0619e04..65c96c1761 100644 --- a/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTaskV2.java +++ b/src/main/java/org/dependencytrack/tasks/BomUploadProcessingTaskV2.java @@ -26,8 +26,8 @@ import org.apache.commons.collections4.MultiValuedMap; import org.apache.commons.collections4.multimap.HashSetValuedHashMap; import org.apache.commons.lang3.exception.ExceptionUtils; -import org.cyclonedx.BomParserFactory; import org.cyclonedx.exception.ParseException; +import org.cyclonedx.parsers.BomParserFactory; import org.cyclonedx.parsers.Parser; import org.datanucleus.flush.FlushMode; import org.datanucleus.store.query.QueryNotUniqueException; @@ -673,8 +673,7 @@ private static void resolveAndApplyLicense(final QueryManager qm, // by priority, and simply take the first resolvable candidate. for (final org.cyclonedx.model.License licenseCandidate : component.getLicenseCandidates()) { if (isNotBlank(licenseCandidate.getId())) { - final License resolvedLicense = licenseCache.computeIfAbsent(licenseCandidate.getId(), - licenseId -> resolveLicense(qm, licenseId)); + final License resolvedLicense = licenseCache.computeIfAbsent(licenseCandidate.getId(), qm::getLicenseByIdOrName); if (resolvedLicense != License.UNRESOLVED) { component.setResolvedLicense(resolvedLicense); component.setLicenseUrl(trimToNull(licenseCandidate.getUrl())); @@ -683,16 +682,14 @@ private static void resolveAndApplyLicense(final QueryManager qm, } if (isNotBlank(licenseCandidate.getName())) { - final License resolvedLicense = licenseCache.computeIfAbsent(licenseCandidate.getName(), - licenseName -> resolveLicense(qm, licenseName)); + final License resolvedLicense = licenseCache.computeIfAbsent(licenseCandidate.getName(), qm::getLicenseByIdOrName); if (resolvedLicense != License.UNRESOLVED) { component.setResolvedLicense(resolvedLicense); component.setLicenseUrl(trimToNull(licenseCandidate.getUrl())); break; } - final License resolvedCustomLicense = customLicenseCache.computeIfAbsent(licenseCandidate.getName(), - licenseName -> resolveCustomLicense(qm, licenseName)); + final License resolvedCustomLicense = customLicenseCache.computeIfAbsent(licenseCandidate.getName(), qm::getCustomLicenseByName); if (resolvedCustomLicense != License.UNRESOLVED) { component.setResolvedLicense(resolvedCustomLicense); component.setLicenseUrl(trimToNull(licenseCandidate.getUrl())); @@ -714,30 +711,6 @@ private static void resolveAndApplyLicense(final QueryManager qm, } } - private static License resolveLicense(final QueryManager qm, final String licenseId) { - final Query query = qm.getPersistenceManager().newQuery(License.class); - query.setFilter("licenseId == :licenseId"); - query.setParameters(licenseId); - try { - final License license = query.executeUnique(); - return license != null ? license : License.UNRESOLVED; - } finally { - query.closeAll(); - } - } - - private static License resolveCustomLicense(final QueryManager qm, final String licenseName) { - final Query query = qm.getPersistenceManager().newQuery(License.class); - query.setFilter("name == :name && customLicense == true"); - query.setParameters(licenseName); - try { - final License license = query.executeUnique(); - return license != null ? license : License.UNRESOLVED; - } finally { - query.closeAll(); - } - } - private static Set getAllComponentIds(final QueryManager qm, final Project project, final Class clazz) { final Query query = qm.getPersistenceManager().newQuery(clazz); query.setFilter("project == :project"); @@ -799,7 +772,7 @@ private static Event createRepoMetaAnalysisEvent(final Context ctx, final List components) { map.put(key, component); LOGGER.debug("add library %s".formatted(component.toString())); - app.addLibrary(new Library(name, component.getVersion())); + app.addPackage(new Package(name, component.getVersion(), null, null, null, null, null)); } else { String srcName = null; String srcVersion = null; @@ -259,6 +258,14 @@ public void analyze(final List components) { srcVersion = property.getPropertyValue(); } else if (property.getPropertyName().equals("trivy:SrcRelease")) { srcRelease = property.getPropertyValue(); + } else if (!pkgType.contains("-") && property.getPropertyName().equals("trivy:PkgType")) { + pkgType = property.getPropertyValue(); + + String distro = component.getPurl().getQualifiers().get("distro"); + + if (distro != null) { + pkgType += "-" + distro; + } } } @@ -292,6 +299,7 @@ public void analyze(final List components) { pkgs.forEach((key, value) -> { var info = new BlobInfo(); info.setPackageInfos(new PackageInfo[]{value}); + LOGGER.debug("looking for os %s".formatted(key)); if (os.get(key) != null) { info.setOS(os.get(key)); } @@ -406,7 +414,7 @@ private TrivyResponse scanBlob(PutRequest input) { scan.setBlobIDS(new String[]{input.getDiffID()}); final var opts = new Options(); - opts.setVulnType(new String[]{"os", "library"}); + opts.setPkgTypes(new String[]{"os", "library"}); opts.setScanners(new String[]{"vuln"}); scan.setOptions(opts); diff --git a/src/main/java/org/dependencytrack/util/XmlUtil.java b/src/main/java/org/dependencytrack/util/XmlUtil.java index 2bb2f549a9..beb4f9bb2d 100644 --- a/src/main/java/org/dependencytrack/util/XmlUtil.java +++ b/src/main/java/org/dependencytrack/util/XmlUtil.java @@ -18,83 +18,14 @@ */ package org.dependencytrack.util; -import org.xml.sax.SAXException; -import org.xml.sax.SAXNotRecognizedException; -import org.xml.sax.SAXNotSupportedException; - import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; -import java.io.InputStream; - -import static org.apache.xerces.jaxp.JAXPConstants.JAXP_SCHEMA_LANGUAGE; - -import static org.apache.xerces.jaxp.JAXPConstants.JAXP_SCHEMA_SOURCE; -import static org.apache.xerces.jaxp.JAXPConstants.W3C_XML_SCHEMA; - public final class XmlUtil { - private XmlUtil() { } - - /** - * Constructs a validating secure SAX Parser. - * - * @param schemaStream One or more inputStreams with the schema(s) that the - * parser should be able to validate the XML against, one InputStream per - * schema - * @return a SAX Parser - * @throws javax.xml.parsers.ParserConfigurationException is thrown if there - * is a parser configuration exception - * @throws org.xml.sax.SAXNotRecognizedException thrown if there is an - * unrecognized feature - * @throws org.xml.sax.SAXNotSupportedException thrown if there is a - * non-supported feature - * @throws org.xml.sax.SAXException is thrown if there is a - * org.xml.sax.SAXException - */ - public static SAXParser buildSecureSaxParser(InputStream... schemaStream) throws ParserConfigurationException, - SAXNotRecognizedException, SAXNotSupportedException, SAXException { - final SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setValidating(true); - factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - factory.setFeature("http://xml.org/sax/features/external-general-entities", false); - factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); - factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); - factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); - System.setProperty("javax.xml.accessExternalSchema", "file, https"); - - final SAXParser saxParser = factory.newSAXParser(); - saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); - saxParser.setProperty(JAXP_SCHEMA_SOURCE, schemaStream); - return saxParser; - } - - /** - * Constructs a secure SAX Parser. - * - * @return a SAX Parser - * @throws javax.xml.parsers.ParserConfigurationException thrown if there is - * a parser configuration exception - * @throws org.xml.sax.SAXNotRecognizedException thrown if there is an - * unrecognized feature - * @throws org.xml.sax.SAXNotSupportedException thrown if there is a - * non-supported feature - * @throws org.xml.sax.SAXException is thrown if there is a - * org.xml.sax.SAXException - */ - public static SAXParser buildSecureSaxParser() throws ParserConfigurationException, - SAXNotRecognizedException, SAXNotSupportedException, SAXException { - final SAXParserFactory factory = SAXParserFactory.newInstance(); - factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); - factory.setFeature("http://xml.org/sax/features/external-general-entities", false); - factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); - return factory.newSAXParser(); + private XmlUtil() { } /** @@ -102,7 +33,7 @@ public static SAXParser buildSecureSaxParser() throws ParserConfigurationExcepti * * @return a new document builder * @throws javax.xml.parsers.ParserConfigurationException thrown if there is - * a parser configuration exception + * a parser configuration exception */ public static DocumentBuilder buildSecureDocumentBuilder() throws ParserConfigurationException { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9b3aba9a61..a6f5fa53a8 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -81,6 +81,11 @@ alpine.database.username=sa # Specifies the password to use when authenticating to the database. # alpine.database.password= +# Optional +# Specifies a path to the file holding the database password. +# To be used as alternative to alpine.database.password. +# alpine.database.password.file= + # Optional # Specifies if the database connection pool is enabled. alpine.database.pool.enabled=true diff --git a/src/main/resources/templates/notification/publisher/email.peb b/src/main/resources/templates/notification/publisher/email.peb index 5711273e97..f8aa69144d 100644 --- a/src/main/resources/templates/notification/publisher/email.peb +++ b/src/main/resources/templates/notification/publisher/email.peb @@ -21,7 +21,7 @@ Project: [{{ affectedProject.name }} : {{ affectedProject.version }}] Project URL: {{ baseUrl }}/projects/{{ affectedProject.uuid }} {% endif %}{% endfor %}{% endif %}{% elseif notification.group == "NEW_VULNERABLE_DEPENDENCY" %} Project: {{ subject.component.project.toString }} -Project URL: {{ baseUrl }}/projects/?uuid={{ subject.component.project.uuid }} +Project URL: {{ baseUrl }}/projects/{{ subject.component.project.uuid }} Component: {{ subject.component.toString }} Component URL: {{ baseUrl }}/component/?uuid={{ subject.component.uuid }} diff --git a/src/main/resources/templates/notification/publisher/jira.peb b/src/main/resources/templates/notification/publisher/jira.peb index 3e5b0b3985..996abe94c7 100644 --- a/src/main/resources/templates/notification/publisher/jira.peb +++ b/src/main/resources/templates/notification/publisher/jira.peb @@ -6,7 +6,7 @@ "issuetype": { "name": "{{ jiraTicketType }}" }, - "summary": "[Dependency-Track] [{{ notification.group | escape(strategy="json") }}] {% if notification.group == "NEW_VULNERABILITY" %}[{{ subject.vulnerability.severity }}] New {{ subject.vulnerability.severity | lower }} vulnerability identified: {{ subject.vulnerability.vulnId }}{% elseif notification.group == "NEW_VULNERABLE_DEPENDENCY" %}Vulnerable dependency introduced on project {{ subject.dependency.project.name | escape(strategy="json") }}{% else %}{{ notification.title | escape(strategy="json") }}{% endif %}", + "summary": "[Dependency-Track] [{{ notification.group | escape(strategy="json") }}] {% if notification.group == "NEW_VULNERABILITY" %}[{{ subject.vulnerability.severity }}] New {{ subject.vulnerability.severity | lower }} vulnerability identified: {{ subject.vulnerability.vulnId }}{% elseif notification.group == "NEW_VULNERABLE_DEPENDENCY" %}Vulnerable dependency introduced on project {{ subject.component.project.name | escape(strategy="json") }}{% else %}{{ notification.title | escape(strategy="json") }}{% endif %}", {% if notification.group == "NEW_VULNERABILITY" %} "description": "A new vulnerability has been identified on your project(s).\n\\\\\n\\\\\n*Vulnerability description*\n{code:none|bgColor=white|borderStyle=none}{{ subject.vulnerability.description | escape(strategy="json") }}{code}\n\n*VulnID*\n{{ subject.vulnerability.vulnId }}\n\n*Severity*\n{{ subject.vulnerability.severity | lower | capitalize }}\n\n*Component*\n[{{ subject.component | escape(strategy="json") }}|{{ baseUrl }}/components/{{ subject.component.uuid }}]\n\n*Affected project(s)*\n{% for project in subject.affectedProjects %}- [{{ project.name | escape(strategy="json") }} ({{ project.version | escape(strategy="json") }})|{{ baseUrl }}/projects/{{ project.uuid }}]\n{% endfor %}" {% elseif notification.group == "NEW_VULNERABLE_DEPENDENCY" %} diff --git a/src/main/resources/templates/notification/publisher/slack.peb b/src/main/resources/templates/notification/publisher/slack.peb index c3947b057b..98d30c3d23 100644 --- a/src/main/resources/templates/notification/publisher/slack.peb +++ b/src/main/resources/templates/notification/publisher/slack.peb @@ -60,7 +60,7 @@ "text": "{{ subject.component.toString | escape(strategy="json") }}" } ] - }, + }{% if baseUrl is not empty %}, { "type": "actions", "elements": [ @@ -84,6 +84,7 @@ } ] } + {% endif %} ] } {% elseif notification.group == "NEW_VULNERABLE_DEPENDENCY" %} @@ -132,7 +133,7 @@ "text": "{{ subject.component.project.toString | escape(strategy="json") }}" } ] - }, + }{% if baseUrl is not empty %}, { "type": "actions", "elements": [ @@ -156,6 +157,7 @@ } ] } + {% endif %} ] } {% elseif notification.group == "PROJECT_AUDIT_CHANGE" %} @@ -250,7 +252,7 @@ "text": "{{ subject.project.toString | escape(strategy="json") }}" } ] - }, + }{% if baseUrl is not empty %}, { "type": "actions", "elements": [ @@ -283,6 +285,7 @@ } ] } + {% endif %} ] } {% elseif notification.group == "POLICY_VIOLATION" %} @@ -357,7 +360,7 @@ "text": "{{ subject.project.toString | escape(strategy="json") }}" } ] - }, + }{% if baseUrl is not empty %}, { "type": "actions", "elements": [ @@ -381,6 +384,7 @@ } ] } + {% endif %} ] } {% else %} diff --git a/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java index 5df72bea0d..9a0044c019 100644 --- a/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java +++ b/src/test/java/org/dependencytrack/notification/publisher/AbstractPublisherTest.java @@ -38,6 +38,7 @@ import org.dependencytrack.notification.vo.BomConsumedOrProcessed; import org.dependencytrack.notification.vo.BomProcessingFailed; import org.dependencytrack.notification.vo.NewVulnerabilityIdentified; +import org.dependencytrack.notification.vo.NewVulnerableDependency; import org.junit.Test; import javax.json.Json; @@ -150,6 +151,27 @@ public void testInformWithNewVulnerabilityNotification() { .isThrownBy(() -> publisherInstance.inform(PublishContext.from(notification), notification, createConfig())); } + @Test + public void testInformWithNewVulnerableDependencyNotification() { + final var project = createProject(); + final var component = createComponent(project); + final var vuln = createVulnerability(); + + final var subject = new NewVulnerableDependency(component, List.of(vuln)); + + final var notification = new Notification() + .scope(NotificationScope.PORTFOLIO) + .group(NotificationGroup.NEW_VULNERABLE_DEPENDENCY) + .level(NotificationLevel.INFORMATIONAL) + .title(NotificationConstants.Title.NEW_VULNERABLE_DEPENDENCY) + .content("") + .timestamp(LocalDateTime.ofEpochSecond(66666, 666, ZoneOffset.UTC)) + .subject(subject); + + assertThatNoException() + .isThrownBy(() -> publisherInstance.inform(PublishContext.from(notification), notification, createConfig())); + } + @Test public void testInformWithProjectAuditChangeNotification() { final var project = createProject(); diff --git a/src/test/java/org/dependencytrack/notification/publisher/JiraPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/JiraPublisherTest.java index 6c3670faf2..1474fbb2f2 100644 --- a/src/test/java/org/dependencytrack/notification/publisher/JiraPublisherTest.java +++ b/src/test/java/org/dependencytrack/notification/publisher/JiraPublisherTest.java @@ -182,6 +182,29 @@ public void testInformWithNewVulnerabilityNotification() { """))); } + @Override + public void testInformWithNewVulnerableDependencyNotification() { + super.testInformWithNewVulnerableDependencyNotification(); + + verify(postRequestedFor(urlPathEqualTo("/rest/api/2/issue")) + .withHeader("Authorization", equalTo("Basic amlyYVVzZXI6amlyYVBhc3N3b3Jk")) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "fields": { + "project": { + "key": "PROJECT" + }, + "issuetype": { + "name": "Task" + }, + "summary": "[Dependency-Track] [NEW_VULNERABLE_DEPENDENCY] Vulnerable dependency introduced on project projectName", + "description": "A component which contains one or more vulnerabilities has been added to your project.\\n\\\\\\\\\\n\\\\\\\\\\n*Project*\\n[pkg:maven/org.acme/projectName@projectVersion|https://example.com/projects/c9c9539a-e381-4b36-ac52-6a7ab83b2c95]\\n\\n*Component*\\n[componentName : componentVersion|https://example.com/components/94f87321-a5d1-4c2f-b2fe-95165debebc6]\\n\\n*Vulnerabilities*\\n- INT-001 (Medium)\\n" + } + } + """))); + } + @Override public void testInformWithProjectAuditChangeNotification() { super.testInformWithProjectAuditChangeNotification(); diff --git a/src/test/java/org/dependencytrack/notification/publisher/MattermostPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/MattermostPublisherTest.java index f5902b7f3b..927d406b02 100644 --- a/src/test/java/org/dependencytrack/notification/publisher/MattermostPublisherTest.java +++ b/src/test/java/org/dependencytrack/notification/publisher/MattermostPublisherTest.java @@ -105,6 +105,21 @@ public void testInformWithNewVulnerabilityNotification() { """))); } + @Override + public void testInformWithNewVulnerableDependencyNotification() { + super.testInformWithNewVulnerableDependencyNotification(); + + verify(postRequestedFor(anyUrl()) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "username" : "Dependency Track", + "icon_url" : "https://raw.githubusercontent.com/DependencyTrack/branding/master/dt-logo-symbol-blue-background.png", + "text" : "#### Vulnerable Dependency Introduced\\n\\n**Project**: \\n**Component**: componentName : componentVersion\\n[View Project](https://example.com/projects/) - [View Component](https://example.com/components/94f87321-a5d1-4c2f-b2fe-95165debebc6)" + } + """))); + } + @Override public void testInformWithProjectAuditChangeNotification() { super.testInformWithProjectAuditChangeNotification(); diff --git a/src/test/java/org/dependencytrack/notification/publisher/MsTeamsPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/MsTeamsPublisherTest.java index a7f22ed354..7aaf2290d9 100644 --- a/src/test/java/org/dependencytrack/notification/publisher/MsTeamsPublisherTest.java +++ b/src/test/java/org/dependencytrack/notification/publisher/MsTeamsPublisherTest.java @@ -240,6 +240,40 @@ public void testInformWithNewVulnerabilityNotification() { """))); } + @Override + public void testInformWithNewVulnerableDependencyNotification() { + super.testInformWithNewVulnerableDependencyNotification(); + + verify(postRequestedFor(anyUrl()) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "@type": "MessageCard", + "@context": "http://schema.org/extensions", + "summary": "Vulnerable Dependency Introduced", + "title": "Vulnerable Dependency Introduced", + "sections": [ + { + "activityTitle": "Dependency-Track", + "activitySubtitle": "1970-01-01T18:31:06.000000666", + "activityImage": "https://raw.githubusercontent.com/DependencyTrack/branding/master/dt-logo-symbol-blue-background.png", + "facts": [ + { + "name": "Project", + "value": "pkg:maven/org.acme/projectName@projectVersion" + }, + { + "name": "Component", + "value": "componentName : componentVersion" + } + ], + "text": "" + } + ] + } + """))); + } + @Override public void testInformWithProjectAuditChangeNotification() { super.testInformWithProjectAuditChangeNotification(); diff --git a/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java index 9739227bfc..fe80f7ae71 100644 --- a/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java +++ b/src/test/java/org/dependencytrack/notification/publisher/SendMailPublisherTest.java @@ -227,17 +227,17 @@ public void testInformWithDataSourceMirroringNotification() { GitHub Advisory Mirroring -------------------------------------------------------------------------------- - + Level: ERROR Scope: SYSTEM Group: DATASOURCE_MIRRORING - + -------------------------------------------------------------------------------- - + An error occurred mirroring the contents of GitHub Advisories. Check log for details. - + -------------------------------------------------------------------------------- - + 1970-01-01T18:31:06.000000666 """); }); @@ -255,9 +255,9 @@ public void testInformWithNewVulnerabilityNotification() { assertThat(content.getBodyPart(0)).isInstanceOf(MimeBodyPart.class); assertThat((String) content.getBodyPart(0).getContent()).isEqualToIgnoringNewLines(""" New Vulnerability Identified - + -------------------------------------------------------------------------------- - + Vulnerability ID: INT-001 Vulnerability URL: /vulnerability/?source=INTERNAL&vulnId=INT-001 Severity: MEDIUM @@ -268,13 +268,55 @@ public void testInformWithNewVulnerabilityNotification() { Version: projectVersion Description: projectDescription Project URL: /projects/c9c9539a-e381-4b36-ac52-6a7ab83b2c95 - + + -------------------------------------------------------------------------------- + + + + -------------------------------------------------------------------------------- + + 1970-01-01T18:31:06.000000666 + """); + }); + } + + @Override + public void testInformWithNewVulnerableDependencyNotification() { + super.testInformWithNewVulnerableDependencyNotification(); + + assertThat(greenMail.getReceivedMessages()).satisfiesExactly(message -> { + assertThat(message.getSubject()).isEqualTo("[Dependency-Track] Vulnerable Dependency Introduced"); + assertThat(message.getContent()).isInstanceOf(MimeMultipart.class); + final MimeMultipart content = (MimeMultipart) message.getContent(); + assertThat(content.getCount()).isEqualTo(1); + assertThat(content.getBodyPart(0)).isInstanceOf(MimeBodyPart.class); + assertThat((String) content.getBodyPart(0).getContent()).isEqualToIgnoringNewLines(""" + Vulnerable Dependency Introduced + + -------------------------------------------------------------------------------- + + Project: pkg:maven/org.acme/projectName@projectVersion + Project URL: /projects/c9c9539a-e381-4b36-ac52-6a7ab83b2c95 + Component: componentName : componentVersion + Component URL: /component/?uuid=94f87321-a5d1-4c2f-b2fe-95165debebc6 + + Vulnerabilities + + Vulnerability ID: INT-001 + Vulnerability URL: /vulnerability/?source=INTERNAL&vulnId=INT-001 + Severity: MEDIUM + Source: INTERNAL + Description: + vulnerabilityDescription + + + -------------------------------------------------------------------------------- - - - + + + -------------------------------------------------------------------------------- - + 1970-01-01T18:31:06.000000666 """); }); @@ -292,30 +334,30 @@ public void testInformWithProjectAuditChangeNotification() { assertThat(content.getBodyPart(0)).isInstanceOf(MimeBodyPart.class); assertThat((String) content.getBodyPart(0).getContent()).isEqualToIgnoringNewLines(""" Analysis Decision: Finding Suppressed - + -------------------------------------------------------------------------------- - + Analysis Type: Project Analysis - + Analysis State: FALSE_POSITIVE Suppressed: true Vulnerability ID: INT-001 Vulnerability URL: /vulnerability/?source=INTERNAL&vulnId=INT-001 Severity: MEDIUM Source: INTERNAL - + Component: componentName : componentVersion Component URL: /component/?uuid=94f87321-a5d1-4c2f-b2fe-95165debebc6 Project: pkg:maven/org.acme/projectName@projectVersion Description: projectDescription Project URL: /projects/c9c9539a-e381-4b36-ac52-6a7ab83b2c95 - + -------------------------------------------------------------------------------- - - - + + + -------------------------------------------------------------------------------- - + 1970-01-01T18:31:06.000000666 """); }); diff --git a/src/test/java/org/dependencytrack/notification/publisher/SlackPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/SlackPublisherTest.java index 1ce6b5540c..1e47eba589 100644 --- a/src/test/java/org/dependencytrack/notification/publisher/SlackPublisherTest.java +++ b/src/test/java/org/dependencytrack/notification/publisher/SlackPublisherTest.java @@ -18,11 +18,15 @@ */ package org.dependencytrack.notification.publisher; +import alpine.model.ConfigProperty; +import org.junit.Test; + import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl; import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; import static com.github.tomakehurst.wiremock.client.WireMock.equalToJson; import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; import static com.github.tomakehurst.wiremock.client.WireMock.verify; +import static org.dependencytrack.model.ConfigPropertyConstants.GENERAL_BASE_URL; public class SlackPublisherTest extends AbstractWebhookPublisherTest { @@ -315,6 +319,87 @@ public void testInformWithNewVulnerabilityNotification() { """))); } + @Override + public void testInformWithNewVulnerableDependencyNotification() { + super.testInformWithNewVulnerableDependencyNotification(); + + verify(postRequestedFor(anyUrl()) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "New Vulnerable Dependency" + } + }, + { + "type": "context", + "elements": [ + { + "text": "*INFORMATIONAL* | *PORTFOLIO*", + "type": "mrkdwn" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "text": "Vulnerable Dependency Introduced", + "type": "mrkdwn" + }, + "fields": [ + { + "type": "mrkdwn", + "text": "*Component*" + }, + { + "type": "plain_text", + "text": "componentName : componentVersion" + }, + { + "type": "mrkdwn", + "text": "*Project*" + }, + { + "type": "plain_text", + "text": "pkg:maven/org.acme/projectName@projectVersion" + } + ] + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "text": { + "type": "plain_text", + "text": "View Project" + }, + "action_id": "actionId-1", + "url": "https://example.com/projects/" + }, + { + "type": "button", + "text": { + "type": "plain_text", + "text": "View Component" + }, + "action_id": "actionId-2", + "url": "https://example.com/components/94f87321-a5d1-4c2f-b2fe-95165debebc6" + } + ] + } + ] + } + """))); + } + @Override public void testInformWithProjectAuditChangeNotification() { super.testInformWithProjectAuditChangeNotification(); @@ -451,4 +536,261 @@ public void testInformWithProjectAuditChangeNotification() { """))); } + @Test + public void testInformWithNewVulnerabilityNotificationWithoutBaseUrl() { + final ConfigProperty baseUrlProperty = qm.getConfigProperty( + GENERAL_BASE_URL.getGroupName(), + GENERAL_BASE_URL.getPropertyName() + ); + baseUrlProperty.setPropertyValue(null); + qm.persist(baseUrlProperty); + + super.testInformWithNewVulnerabilityNotification(); + + verify(postRequestedFor(anyUrl()) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "New Vulnerability" + } + }, + { + "type": "context", + "elements": [ + { + "text": "*INFORMATIONAL* | *PORTFOLIO*", + "type": "mrkdwn" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "text": "New Vulnerability Identified", + "type": "mrkdwn" + }, + "fields": [ + { + "type": "mrkdwn", + "text": "*VulnID*" + }, + { + "type": "plain_text", + "text": "INT-001" + }, + { + "type": "mrkdwn", + "text": "*Severity*" + }, + { + "type": "plain_text", + "text": "MEDIUM" + }, + { + "type": "mrkdwn", + "text": "*Source*" + }, + { + "type": "plain_text", + "text": "INTERNAL" + }, + { + "type": "mrkdwn", + "text": "*Component*" + }, + { + "type": "plain_text", + "text": "componentName : componentVersion" + } + ] + } + ] + } + """))); + } + + @Test + public void testInformWithNewVulnerableDependencyNotificationWithoutBaseUrl() { + final ConfigProperty baseUrlProperty = qm.getConfigProperty( + GENERAL_BASE_URL.getGroupName(), + GENERAL_BASE_URL.getPropertyName() + ); + baseUrlProperty.setPropertyValue(null); + qm.persist(baseUrlProperty); + + super.testInformWithNewVulnerableDependencyNotification(); + + verify(postRequestedFor(anyUrl()) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "New Vulnerable Dependency" + } + }, + { + "type": "context", + "elements": [ + { + "text": "*INFORMATIONAL* | *PORTFOLIO*", + "type": "mrkdwn" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "text": "Vulnerable Dependency Introduced", + "type": "mrkdwn" + }, + "fields": [ + { + "type": "mrkdwn", + "text": "*Component*" + }, + { + "type": "plain_text", + "text": "componentName : componentVersion" + }, + { + "type": "mrkdwn", + "text": "*Project*" + }, + { + "type": "plain_text", + "text": "pkg:maven/org.acme/projectName@projectVersion" + } + ] + } + ] + } + """))); + } + + @Test + public void testInformWithProjectAuditChangeNotificationWithoutBaseUrl() { + final ConfigProperty baseUrlProperty = qm.getConfigProperty( + GENERAL_BASE_URL.getGroupName(), + GENERAL_BASE_URL.getPropertyName() + ); + baseUrlProperty.setPropertyValue(null); + qm.persist(baseUrlProperty); + + super.testInformWithProjectAuditChangeNotification(); + + verify(postRequestedFor(anyUrl()) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "blocks": [ + { + "type": "header", + "text": { + "type": "plain_text", + "text": "Project Audit Change" + } + }, + { + "type": "context", + "elements": [ + { + "text": "*INFORMATIONAL* | *PORTFOLIO*", + "type": "mrkdwn" + } + ] + }, + { + "type": "divider" + }, + { + "type": "section", + "text": { + "text": "Analysis Decision: Finding Suppressed", + "type": "plain_text" + }, + "fields": [ + { + "type": "mrkdwn", + "text": "*Analysis State*" + }, + { + "type": "plain_text", + "emoji": true, + "text": "FALSE_POSITIVE" + }, + { + "type": "mrkdwn", + "text": "*Suppressed*" + }, + { + "type": "plain_text", + "text": "true" + }, + { + "type": "mrkdwn", + "text": "*VulnID*" + }, + { + "type": "plain_text", + "text": "INT-001" + }, + { + "type": "mrkdwn", + "text": "*Severity*" + }, + { + "type": "plain_text", + "text": "MEDIUM" + }, + { + "type": "mrkdwn", + "text": "*Source*" + }, + { + "type": "plain_text", + "text": "INTERNAL" + } + ] + }, + { + "type": "section", + "fields": [ + { + "type": "mrkdwn", + "text": "*Component*" + }, + { + "type": "plain_text", + "text": "componentName : componentVersion" + }, + { + "type": "mrkdwn", + "text": "*Project*" + }, + { + "type": "plain_text", + "text": "pkg:maven/org.acme/projectName@projectVersion" + } + ] + } + ] + } + """))); + } + } diff --git a/src/test/java/org/dependencytrack/notification/publisher/WebhookPublisherTest.java b/src/test/java/org/dependencytrack/notification/publisher/WebhookPublisherTest.java index cf97ceec6d..7dc26f53bc 100644 --- a/src/test/java/org/dependencytrack/notification/publisher/WebhookPublisherTest.java +++ b/src/test/java/org/dependencytrack/notification/publisher/WebhookPublisherTest.java @@ -231,6 +231,78 @@ public void testInformWithNewVulnerabilityNotification() { """))); } + @Override + public void testInformWithNewVulnerableDependencyNotification() { + super.testInformWithNewVulnerableDependencyNotification(); + + verify(postRequestedFor(anyUrl()) + .withHeader("Content-Type", equalTo("application/json")) + .withRequestBody(equalToJson(""" + { + "notification": { + "level": "INFORMATIONAL", + "scope": "PORTFOLIO", + "group": "NEW_VULNERABLE_DEPENDENCY", + "timestamp": "1970-01-01T18:31:06.000000666", + "title": "Vulnerable Dependency Introduced", + "content": "", + "subject": { + "project": { + "uuid": "c9c9539a-e381-4b36-ac52-6a7ab83b2c95", + "name": "projectName", + "version": "projectVersion", + "description": "projectDescription", + "purl": "pkg:maven/org.acme/projectName@projectVersion", + "tags": "tag1,tag2" + }, + "component": { + "uuid": "94f87321-a5d1-4c2f-b2fe-95165debebc6", + "name": "componentName", + "version": "componentVersion" + }, + "vulnerabilities": [ + { + "uuid": "bccec5d5-ec21-4958-b3e8-22a7a866a05a", + "vulnId": "INT-001", + "source": "INTERNAL", + "aliases": [ + { + "source": "OSV", + "vulnId": "OSV-001" + } + ], + "title": "vulnerabilityTitle", + "subtitle": "vulnerabilitySubTitle", + "description": "vulnerabilityDescription", + "recommendation": "vulnerabilityRecommendation", + "cvssv2": 5.5, + "cvssv3": 6.6, + "owaspRRLikelihood": 1.1, + "owaspRRTechnicalImpact": 2.2, + "owaspRRBusinessImpact": 3.3, + "severity": "MEDIUM", + "cwe": { + "cweId": 666, + "name": "Operation on Resource in Wrong Phase of Lifetime" + }, + "cwes": [ + { + "cweId": 666, + "name": "Operation on Resource in Wrong Phase of Lifetime" + }, + { + "cweId": 777, + "name": "Regular Expression without Anchors" + } + ] + } + ] + } + } + } + """))); + } + @Override public void testInformWithProjectAuditChangeNotification() { super.testInformWithProjectAuditChangeNotification(); diff --git a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporterTest.java b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporterTest.java index 82a956fdeb..e8cb67002d 100644 --- a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporterTest.java +++ b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDXVexImporterTest.java @@ -1,8 +1,8 @@ package org.dependencytrack.parser.cyclonedx; import org.assertj.core.api.Assertions; -import org.cyclonedx.BomParserFactory; import org.cyclonedx.exception.ParseException; +import org.cyclonedx.parsers.BomParserFactory; import org.dependencytrack.PersistenceCapableTest; import org.dependencytrack.model.Analysis; import org.dependencytrack.model.AnalysisJustification; diff --git a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java index 6ec7f2b48a..9ad3ab5cf5 100644 --- a/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java +++ b/src/test/java/org/dependencytrack/parser/cyclonedx/CycloneDxValidatorTest.java @@ -18,11 +18,32 @@ */ package org.dependencytrack.parser.cyclonedx; +import com.github.tomakehurst.wiremock.WireMockServer; +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.PathMatcher; +import java.nio.file.Paths; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; + +import static com.github.tomakehurst.wiremock.client.WireMock.anyRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.anyUrl; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatNoException; +import static org.assertj.core.api.Assertions.catchThrowableOfType; +@RunWith(JUnitParamsRunner.class) public class CycloneDxValidatorTest { private CycloneDxValidator validator; @@ -132,7 +153,7 @@ public void testValidateJsonWithInvalidComponentType() { .extracting(InvalidBomException::getValidationErrors).asList() .containsExactly(""" $.components[0].type: does not have a value in the enumeration \ - [application, framework, library, container, operating-system, device, firmware, file]\ + ["application", "framework", "library", "container", "operating-system", "device", "firmware", "file"]\ """); } @@ -162,4 +183,99 @@ public void testValidateXmlWithInvalidComponentType() { valid with respect to its type, 'classification'."""); } + @Test // https://github.com/DependencyTrack/dependency-track/issues/3696 + public void testValidateJsonWithSpecVersionAtTheBottom() { + assertThatNoException() + .isThrownBy(() -> validator.validate(""" + { + "metadata": {}, + "components": [], + "bomFormat": "CycloneDX", + "specVersion": "1.5" + } + """.getBytes())); + } + + @SuppressWarnings("unused") + private Object[] testValidateWithValidBomParameters() throws Exception { + final PathMatcher pathMatcherJson = FileSystems.getDefault().getPathMatcher("glob:**/valid-bom-*.json"); + final PathMatcher pathMatcherXml = FileSystems.getDefault().getPathMatcher("glob:**/valid-bom-*.xml"); + final var bomFilePaths = new ArrayList(); + + Files.walkFileTree(Paths.get("./src/test/resources/unit/cyclonedx"), new SimpleFileVisitor<>() { + @Override + public FileVisitResult visitFile(final Path file, final BasicFileAttributes attrs) { + if (pathMatcherJson.matches(file) || pathMatcherXml.matches(file)) { + bomFilePaths.add(file); + } + + return FileVisitResult.CONTINUE; + } + }); + + return bomFilePaths.stream().sorted().toArray(); + } + + @Test + @Parameters(method = "testValidateWithValidBomParameters") + public void testValidateWithValidBom(final Path bomFilePath) throws Exception { + final byte[] bomBytes = Files.readAllBytes(bomFilePath); + + assertThatNoException().isThrownBy(() -> validator.validate(bomBytes)); + } + + @Test // https://github.com/DependencyTrack/dependency-track/issues/3831 + public void testValidateJsonWithUrlContainingEncodedBrackets() { + assertThatNoException() + .isThrownBy(() -> validator.validate(""" + { + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "components": [ + { + "type": "library", + "name": "acme-library", + "externalReferences": [ + { + "type": "website", + "url": "https://example.com/foo?bar=%5Bbaz%5D" + } + ] + } + ] + } + """.getBytes())); + } + + @Test + public void testValidateXmlWithXxeProtection() { + final var wireMock = new WireMockServer(options().dynamicPort()); + wireMock.start(); + + try { + final Throwable throwable = catchThrowableOfType( + () -> validator.validate(""" + + %%sp;]> + + """.formatted(wireMock.port()).getBytes()), + InvalidBomException.class + ); + + // Ensure we failed for the right reason. + assertThat(throwable.getSuppressed()).hasSize(2); + assertThat(throwable.getSuppressed()).anySatisfy(suppressed -> assertThat(suppressed) + .hasMessageContaining(""" + Encountered a reference to external entity "sp", but stream reader has feature \ + "javax.xml.stream.isSupportingExternalEntities" disabled""" + ) + ); + + // Ensure that in fact no request was performed. + wireMock.verify(0, anyRequestedFor(anyUrl())); + } finally { + wireMock.stop(); + } + } + } \ No newline at end of file diff --git a/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java index 1258943ad4..506327949a 100644 --- a/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/BomResourceTest.java @@ -312,6 +312,81 @@ public void exportProjectAsCycloneDxInventoryTest() { assertThat(componentWithVulnAndAnalysis.getDirectDependencies()).isNotNull(); } + @Test + public void exportProjectAsCycloneDxLicenseTest() { + Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false); + Component c = new Component(); + c.setProject(project); + c.setName("sample-component"); + c.setVersion("1.0"); + org.dependencytrack.model.License license = new org.dependencytrack.model.License(); + license.setId(1234); + license.setName("CustomName"); + license.setCustomLicense(true); + c.setResolvedLicense(license); + c.setDirectDependencies("[]"); + Component component = qm.createComponent(c, false); + qm.persist(project); + Response response = jersey.target(V1_BOM + "/cyclonedx/project/" + project.getUuid()).request() + .header(X_API_KEY, apiKey) + .get(Response.class); + + final String jsonResponse = getPlainTextBody(response); + assertThatNoException().isThrownBy(() -> CycloneDxValidator.getInstance().validate(jsonResponse.getBytes())); + assertThatJson(jsonResponse) + .withMatcher("component", equalTo(component.getUuid().toString())) + .withMatcher("projectUuid", equalTo(project.getUuid().toString())) + .isEqualTo(json(""" + { + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "${json-unit.ignore}", + "version": 1, + "metadata": { + "timestamp": "${json-unit.any-string}", + "tools": [ + { + "vendor": "OWASP", + "name": "Dependency-Track", + "version": "${json-unit.any-string}" + } + ], + "component": { + "type": "library", + "bom-ref": "${json-unit.matches:projectUuid}", + "name": "Acme Example", + "version": "1.0" + } + }, + "components": [ + { + "type": "library", + "bom-ref": "${json-unit.matches:component}", + "name": "sample-component", + "version": "1.0", + "licenses": [ + { + "license": { + "name": "CustomName" + } + } + ] + } + ], + "dependencies": [ + { + "ref": "${json-unit.matches:projectUuid}", + "dependsOn": [] + }, + { + "ref": "${json-unit.matches:component}", + "dependsOn": [] + } + ] + } + """)); + } + @Test public void exportProjectAsCycloneDxInventoryWithVulnerabilitiesTest() { var vulnerability = new Vulnerability(); @@ -914,7 +989,7 @@ public void uploadBomInvalidJsonTest() { "title": "The uploaded BOM is invalid", "detail": "Schema validation failed", "errors": [ - "$.components[0].type: does not have a value in the enumeration [application, framework, library, container, operating-system, device, firmware, file]" + "$.components[0].type: does not have a value in the enumeration [\\"application\\", \\"framework\\", \\"library\\", \\"container\\", \\"operating-system\\", \\"device\\", \\"firmware\\", \\"file\\"]" ] } """); @@ -999,9 +1074,15 @@ public void uploadBomTooLargeViaPutTest() { { "status": 400, "title": "The provided JSON payload could not be mapped", - "detail": "The BOM is too large to be transmitted safely via Base64 encoded JSON value. Please use the \\"POST /api/v1/bom\\" endpoint with Content-Type \\"multipart/form-data\\" instead. Original cause: String length (20000001) exceeds the maximum length (20000000) (through reference chain: org.dependencytrack.resources.v1.vo.BomSubmitRequest[\\"bom\\"])" + "detail": "The BOM is too large to be transmitted safely via Base64 encoded JSON value. Please use the \\"POST /api/v1/bom\\" endpoint with Content-Type \\"multipart/form-data\\" instead. Original cause: String value length (20000001) exceeds the maximum allowed (20000000, from `StreamReadConstraints.getMaxStringLength()`) (through reference chain: org.dependencytrack.resources.v1.vo.BomSubmitRequest[\\"bom\\"])" } """); } + @Test + public void validateCycloneDxBomWithMultipleNamespacesTest() throws Exception { + byte[] bom = resourceToByteArray("/unit/bom-issue4008.xml"); + assertThatNoException().isThrownBy(() -> CycloneDxValidator.getInstance().validate(bom)); + } + } diff --git a/src/test/java/org/dependencytrack/resources/v1/ComponentResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/ComponentResourceTest.java index bfa2d17f3d..0fb649f8d1 100644 --- a/src/test/java/org/dependencytrack/resources/v1/ComponentResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/ComponentResourceTest.java @@ -28,6 +28,7 @@ import org.dependencytrack.ResourceTest; import org.dependencytrack.model.Component; import org.dependencytrack.model.ConfigPropertyConstants; +import org.dependencytrack.model.ExternalReference; import org.dependencytrack.model.Project; import org.dependencytrack.model.RepositoryMetaComponent; import org.dependencytrack.model.RepositoryType; @@ -525,17 +526,29 @@ public void updateComponentTest() { component.setProject(project); component.setName("My Component"); component.setVersion("1.0"); - component = qm.createComponent(component, false); - component.setDescription("Test component"); + qm.createComponent(component, false); + + var jsonComponent = new Component(); + jsonComponent.setUuid(component.getUuid()); + jsonComponent.setPurl("pkg:maven/org.acme/abc"); + jsonComponent.setName("My Component"); + jsonComponent.setVersion("1.0"); + jsonComponent.setDescription("Test component"); + var externalReference = new ExternalReference(); + externalReference.setType(org.cyclonedx.model.ExternalReference.Type.WEBSITE); + externalReference.setUrl("test.com"); + jsonComponent.setExternalReferences(List.of(externalReference)); + Response response = jersey.target(V1_COMPONENT).request() .header(X_API_KEY, apiKey) - .post(Entity.entity(component, MediaType.APPLICATION_JSON)); + .post(Entity.entity(jsonComponent, MediaType.APPLICATION_JSON)); Assert.assertEquals(200, response.getStatus(), 0); JsonObject json = parseJsonObject(response); Assert.assertNotNull(json); Assert.assertEquals("My Component", json.getString("name")); Assert.assertEquals("1.0", json.getString("version")); Assert.assertEquals("Test component", json.getString("description")); + Assert.assertEquals(1, json.getJsonArray("externalReferences").size()); } @Test diff --git a/src/test/java/org/dependencytrack/resources/v1/ProjectResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/ProjectResourceTest.java index dd3229bb7a..1b8f46c0b9 100644 --- a/src/test/java/org/dependencytrack/resources/v1/ProjectResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/ProjectResourceTest.java @@ -31,6 +31,7 @@ import org.dependencytrack.model.AnalysisJustification; import org.dependencytrack.model.AnalysisResponse; import org.dependencytrack.model.AnalysisState; +import org.dependencytrack.model.Classifier; import org.dependencytrack.model.Component; import org.dependencytrack.model.ConfigPropertyConstants; import org.dependencytrack.model.ExternalReference; @@ -38,6 +39,7 @@ import org.dependencytrack.model.OrganizationalEntity; import org.dependencytrack.model.Project; import org.dependencytrack.model.ProjectMetadata; +import org.dependencytrack.model.ProjectMetrics; import org.dependencytrack.model.ProjectProperty; import org.dependencytrack.model.ServiceComponent; import org.dependencytrack.model.Tag; @@ -55,13 +57,17 @@ import javax.json.Json; import javax.json.JsonArray; import javax.json.JsonObject; +import javax.json.JsonObjectBuilder; import javax.ws.rs.HttpMethod; import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.time.Duration; import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -252,19 +258,211 @@ public void getProjectsDescOrderedRequestTest() { @Test public void getProjectByUuidTest() { - Project project = qm.createProject("ABC", null, "1.0", null, null, null, true, false); - Response response = jersey.target(V1_PROJECT + "/" + project.getUuid()) + final var parentProject = new Project(); + parentProject.setName("parent"); + parentProject.setVersion("1.2.3"); + qm.persist(parentProject); + + final var manufacturer = new OrganizationalEntity(); + manufacturer.setName("manufacturer"); + + final var supplier = new OrganizationalEntity(); + supplier.setName("supplier"); + + final var property = new ProjectProperty(); + property.setGroupName("groupName"); + property.setPropertyName("propertyName"); + property.setPropertyValue("propertyValue"); + property.setPropertyType(PropertyType.STRING); + + final var externalRef = new ExternalReference(); + externalRef.setUrl("https://example.com"); + externalRef.setType(Type.WEBSITE); + + final var project = new Project(); + project.setAuthor("author"); + project.setPublisher("publisher"); + project.setManufacturer(manufacturer); + project.setSupplier(supplier); + project.setGroup("group"); + project.setName("name"); + project.setVersion("1.0.0"); + project.setClassifier(Classifier.LIBRARY); + project.setDescription("description"); + project.setDirectDependencies("[{\"uuid\":\"c162be63-35f0-4059-b28b-327e6a01390a\"}]"); + project.setCpe("cpe:2.3:*:vendor:product:1.0.0:update:edition:lang:swEdition:targetSw:targetHw:other"); + project.setPurl("pkg:maven/namespace/name@1.0.0"); + project.setSwidTagId("swidTagId"); + project.setParent(parentProject); + project.setProperties(List.of(property)); + project.setLastBomImport(new Date(1643767322000L)); + project.setLastBomImportFormat("lastBomImportFormat"); + project.setLastInheritedRiskScore(66.6); + project.setActive(false); + project.setExternalReferences(List.of(externalRef)); + qm.persist(project); + + qm.bind(project, List.of(qm.createTag("tag-1"))); + + final var metadataAuthor = new OrganizationalContact(); + metadataAuthor.setName("metadataAuthor"); + final var metadataSupplier = new OrganizationalEntity(); + metadataSupplier.setName("metadataSupplier"); + final var metadata = new ProjectMetadata(); + metadata.setAuthors(List.of(metadataAuthor)); + metadata.setSupplier(metadataSupplier); + metadata.setProject(project); + qm.persist(metadata); + + final var metrics = new ProjectMetrics(); + metrics.setProject(project); + metrics.setCritical(6); + metrics.setHigh(6); + metrics.setMedium(6); + metrics.setLow(6); + metrics.setUnassigned(6); + metrics.setVulnerabilities(6); + metrics.setVulnerableComponents(6); + metrics.setComponents(6); + metrics.setFindingsTotal(6); + metrics.setFindingsAudited(6); + metrics.setFindingsUnaudited(6); + metrics.setInheritedRiskScore(66.6); + metrics.setSuppressed(6); + metrics.setPolicyViolationsTotal(6); + metrics.setPolicyViolationsFail(6); + metrics.setPolicyViolationsInfo(6); + metrics.setPolicyViolationsWarn(6); + metrics.setPolicyViolationsAudited(6); + metrics.setPolicyViolationsUnaudited(6); + metrics.setPolicyViolationsLicenseAudited(6); + metrics.setPolicyViolationsLicenseTotal(6); + metrics.setPolicyViolationsLicenseUnaudited(6); + metrics.setPolicyViolationsOperationalAudited(6); + metrics.setPolicyViolationsOperationalTotal(6); + metrics.setPolicyViolationsOperationalUnaudited(6); + metrics.setPolicyViolationsSecurityAudited(6); + metrics.setPolicyViolationsSecurityTotal(6); + metrics.setPolicyViolationsSecurityUnaudited(6); + metrics.setFirstOccurrence(new Date(1677812583000L)); + metrics.setLastOccurrence(new Date(1677812583000L)); + qm.persist(metrics); + + final UUID parentProjectUuid = parentProject.getUuid(); + final UUID projectUuid = project.getUuid(); + + // Nuke L1 and L2 cache and close PM to ensure all changes are flushed. + qm.getPersistenceManager().getPersistenceManagerFactory().getDataStoreCache().evictAll(); + qm.getPersistenceManager().evictAll(); + qm.close(); + + final Response response = jersey.target(V1_PROJECT + "/" + projectUuid) .request() .header(X_API_KEY, apiKey) - .get(Response.class); - Assert.assertEquals(200, response.getStatus(), 0); - Assert.assertNull(response.getHeaderString(TOTAL_COUNT_HEADER)); - JsonObject json = parseJsonObject(response); - Assert.assertNotNull(json); - Assert.assertEquals("ABC", json.getString("name")); - Assert.assertEquals(1, json.getJsonArray("versions").size()); - Assert.assertEquals(project.getUuid().toString(), json.getJsonArray("versions").getJsonObject(0).getJsonString("uuid").getString()); - Assert.assertEquals("1.0", json.getJsonArray("versions").getJsonObject(0).getJsonString("version").getString()); + .get(); + assertThat(response.getStatus()).isEqualTo(200); + assertThatJson(getPlainTextBody(response)) + .withMatcher("parentProjectUuid", equalTo(parentProjectUuid.toString())) + .withMatcher("projectUuid", equalTo(projectUuid.toString())) + .isEqualTo(/* language=JSON */ """ + { + "active": false, + "author": "author", + "children": [], + "classifier": "LIBRARY", + "cpe": "cpe:2.3:*:vendor:product:1.0.0:update:edition:lang:swEdition:targetSw:targetHw:other", + "description": "description", + "directDependencies": "[{\\"uuid\\":\\"c162be63-35f0-4059-b28b-327e6a01390a\\"}]", + "externalReferences": [ + { + "type": "website", + "url": "https://example.com" + } + ], + "group": "group", + "lastBomImport": 1643767322000, + "lastBomImportFormat": "lastBomImportFormat", + "lastInheritedRiskScore": 66.6, + "manufacturer": { + "name": "manufacturer" + }, + "metadata": { + "supplier": { + "name": "metadataSupplier" + }, + "authors": [ + { + "name":"metadataAuthor" + } + ] + }, + "metrics":{ + "critical": 6, + "high": 6, + "medium": 6, + "low": 6, + "unassigned": 6, + "vulnerabilities": 6, + "vulnerableComponents":6, + "components": 6, + "suppressed": 6, + "findingsTotal": 6, + "findingsAudited": 6, + "findingsUnaudited": 6, + "inheritedRiskScore": 66.6, + "policyViolationsFail": 6, + "policyViolationsWarn": 6, + "policyViolationsInfo": 6, + "policyViolationsTotal": 6, + "policyViolationsAudited": 6, + "policyViolationsUnaudited": 6, + "policyViolationsSecurityTotal": 6, + "policyViolationsSecurityAudited": 6, + "policyViolationsSecurityUnaudited": 6, + "policyViolationsLicenseTotal": 6, + "policyViolationsLicenseAudited": 6, + "policyViolationsLicenseUnaudited": 6, + "policyViolationsOperationalTotal": 6, + "policyViolationsOperationalAudited": 6, + "policyViolationsOperationalUnaudited": 6, + "firstOccurrence": 1677812583000, + "lastOccurrence": 1677812583000 + }, + "name": "name", + "parent": { + "name": "parent", + "uuid": "${json-unit.matches:parentProjectUuid}", + "version": "1.2.3" + }, + "properties": [ + { + "groupName": "groupName", + "propertyName": "propertyName", + "propertyType": "STRING", + "propertyValue": "propertyValue" + } + ], + "publisher": "publisher", + "purl": "pkg:maven/namespace/name@1.0.0", + "supplier": { + "name": "supplier" + }, + "swidTagId": "swidTagId", + "tags": [ + { + "name": "tag-1" + } + ], + "uuid": "${json-unit.matches:projectUuid}", + "version": "1.0.0", + "versions": [ + { + "uuid": "${json-unit.matches:projectUuid}", + "version": "1.0.0" + } + ] + } + """); } @Test @@ -1078,4 +1276,76 @@ public void cloneProjectWithAclTest() { Assert.assertTrue(UuidUtil.isValidUUID(json.getString("token"))); } + @Test // https://github.com/DependencyTrack/dependency-track/issues/4048 + public void issue4048RegressionTest() { + final int projectsPerLevel = 10; + final int maxDepth = 5; + + final Map> projectUuidsByLevel = new HashMap<>(); + + // Create multiple parent-child hierarchies of projects. + for (int i = 0; i < maxDepth; i++) { + final List parentUuids = projectUuidsByLevel.get(i - 1); + + for (int j = 0; j < projectsPerLevel; j++) { + final UUID parentUuid = i > 0 ? parentUuids.get(j) : null; + + final JsonObjectBuilder requestBodyBuilder = Json.createObjectBuilder() + .add("name", "project-%d-%d".formatted(i, j)) + .add("version", "%d.%d".formatted(i, j)); + if (parentUuid != null) { + requestBodyBuilder.add("parent", Json.createObjectBuilder() + .add("uuid", parentUuid.toString())); + } + + final Response response = jersey.target(V1_PROJECT) + .request() + .header(X_API_KEY, apiKey) + .put(Entity.json(requestBodyBuilder.build().toString())); + assertThat(response.getStatus()).isEqualTo(201); + final JsonObject jsonResponse = parseJsonObject(response); + + projectUuidsByLevel.compute(i, (ignored, uuids) -> { + final UUID uuid = UUID.fromString(jsonResponse.getString("uuid")); + if (uuids == null) { + return new ArrayList<>(List.of(uuid)); + } + + uuids.add(uuid); + return uuids; + }); + } + } + + // Pick out the UUIDs of projects that should have a parent (i.e. level 1 or above). + final List childUuids = projectUuidsByLevel.entrySet().stream() + .filter(entry -> entry.getKey() > 0) + .map(Map.Entry::getValue) + .flatMap(List::stream) + .toList(); + + // Create a [uuid -> level] mapping for better assertion failure reporting. + final Map levelByChildUuid = projectUuidsByLevel.entrySet().stream() + .filter(entry -> entry.getKey() > 0) + .flatMap(entry -> { + final Integer level = entry.getKey(); + return entry.getValue().stream().map(uuid -> Map.entry(uuid, level)); + }) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + // Request all child projects individually. + // Ensure that the parent field is populated for all of them. + for (final UUID uuid : childUuids) { + final Response response = jersey.target(V1_PROJECT + "/" + uuid) + .request() + .header(X_API_KEY, apiKey) + .get(); + assertThat(response.getStatus()).isEqualTo(200); + final JsonObject json = parseJsonObject(response); + assertThat(json.getJsonObject("parent")) + .withFailMessage("Parent missing on level: " + levelByChildUuid.get(uuid)) + .isNotEmpty(); + } + } + } diff --git a/src/test/java/org/dependencytrack/resources/v1/VexResourceTest.java b/src/test/java/org/dependencytrack/resources/v1/VexResourceTest.java index 6b82ee739e..4457ff6a02 100644 --- a/src/test/java/org/dependencytrack/resources/v1/VexResourceTest.java +++ b/src/test/java/org/dependencytrack/resources/v1/VexResourceTest.java @@ -212,6 +212,227 @@ public void exportProjectAsCycloneDxTest() { """); } + @Test + public void exportVexWithSameVulnAnalysisValidJsonTest() { + var project = new Project(); + project.setName("acme-app"); + project.setVersion("1.0.0"); + project.setClassifier(Classifier.APPLICATION); + qm.persist(project); + + var componentAWithVuln = new Component(); + componentAWithVuln.setProject(project); + componentAWithVuln.setName("acme-lib-a"); + componentAWithVuln.setVersion("1.0.0"); + componentAWithVuln = qm.createComponent(componentAWithVuln, false); + + var componentBWithVuln = new Component(); + componentBWithVuln.setProject(project); + componentBWithVuln.setName("acme-lib-b"); + componentBWithVuln.setVersion("1.0.0"); + componentBWithVuln = qm.createComponent(componentBWithVuln, false); + + var vuln = new Vulnerability(); + vuln.setVulnId("INT-001"); + vuln.setSource(Vulnerability.Source.INTERNAL); + vuln.setSeverity(Severity.HIGH); + vuln = qm.createVulnerability(vuln, false); + qm.addVulnerability(vuln, componentAWithVuln, AnalyzerIdentity.NONE); + qm.makeAnalysis(componentAWithVuln, vuln, AnalysisState.RESOLVED, null, AnalysisResponse.UPDATE, null, true); + qm.addVulnerability(vuln, componentBWithVuln, AnalyzerIdentity.NONE); + qm.makeAnalysis(componentBWithVuln, vuln, AnalysisState.RESOLVED, null, AnalysisResponse.UPDATE, null, true); + + qm.persist(project); + + final Response response = jersey.target("%s/cyclonedx/project/%s".formatted(V1_VEX, project.getUuid())) + .request() + .header(X_API_KEY, apiKey) + .get(Response.class); + assertThat(response.getStatus()).isEqualTo(200); + final String jsonResponse = getPlainTextBody(response); + assertThatNoException().isThrownBy(() -> CycloneDxValidator.getInstance().validate(jsonResponse.getBytes())); + assertThatJson(jsonResponse) + .withMatcher("vulnUuid", equalTo(vuln.getUuid().toString())) + .withMatcher("projectUuid", equalTo(project.getUuid().toString())) + .isEqualTo(""" + { + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "${json-unit.any-string}", + "version": 1, + "metadata": { + "timestamp": "${json-unit.any-string}", + "component": { + "type": "application", + "bom-ref": "${json-unit.matches:projectUuid}", + "name": "acme-app", + "version": "1.0.0" + }, + "tools": [ + { + "vendor": "OWASP", + "name": "Dependency-Track", + "version": "${json-unit.any-string}" + } + ] + }, + "vulnerabilities": [ + { + "bom-ref": "${json-unit.matches:vulnUuid}", + "id": "INT-001", + "source": { + "name": "INTERNAL" + }, + "ratings": [ + { + "source": { + "name": "INTERNAL" + }, + "severity": "high", + "method": "other" + } + ], + "analysis":{ + "state": "resolved", + "response": [ + "update" + ] + }, + "affects": [ + { + "ref": "${json-unit.matches:projectUuid}" + } + ] + } + ] + } + """); + } + + @Test + public void exportVexWithDifferentVulnAnalysisValidJsonTest() { + var project = new Project(); + project.setName("acme-app"); + project.setVersion("1.0.0"); + project.setClassifier(Classifier.APPLICATION); + qm.persist(project); + + var componentAWithVuln = new Component(); + componentAWithVuln.setProject(project); + componentAWithVuln.setName("acme-lib-a"); + componentAWithVuln.setVersion("1.0.0"); + componentAWithVuln = qm.createComponent(componentAWithVuln, false); + + var componentBWithVuln = new Component(); + componentBWithVuln.setProject(project); + componentBWithVuln.setName("acme-lib-b"); + componentBWithVuln.setVersion("1.0.0"); + componentBWithVuln = qm.createComponent(componentBWithVuln, false); + + var vuln = new Vulnerability(); + vuln.setVulnId("INT-001"); + vuln.setSource(Vulnerability.Source.INTERNAL); + vuln.setSeverity(Severity.HIGH); + vuln = qm.createVulnerability(vuln, false); + qm.addVulnerability(vuln, componentAWithVuln, AnalyzerIdentity.NONE); + qm.makeAnalysis(componentAWithVuln, vuln, AnalysisState.IN_TRIAGE, null, AnalysisResponse.UPDATE, null, true); + qm.addVulnerability(vuln, componentBWithVuln, AnalyzerIdentity.NONE); + qm.makeAnalysis(componentBWithVuln, vuln, AnalysisState.EXPLOITABLE, null, AnalysisResponse.UPDATE, null, true); + + qm.persist(project); + + final Response response = jersey.target("%s/cyclonedx/project/%s".formatted(V1_VEX, project.getUuid())) + .request() + .header(X_API_KEY, apiKey) + .get(Response.class); + assertThat(response.getStatus()).isEqualTo(200); + final String jsonResponse = getPlainTextBody(response); + assertThatNoException().isThrownBy(() -> CycloneDxValidator.getInstance().validate(jsonResponse.getBytes())); + assertThatJson(jsonResponse) + .withMatcher("vulnUuid", equalTo(vuln.getUuid().toString())) + .withMatcher("projectUuid", equalTo(project.getUuid().toString())) + .isEqualTo(""" + { + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "${json-unit.any-string}", + "version": 1, + "metadata": { + "timestamp": "${json-unit.any-string}", + "component": { + "type": "application", + "bom-ref": "${json-unit.matches:projectUuid}", + "name": "acme-app", + "version": "1.0.0" + }, + "tools": [ + { + "vendor": "OWASP", + "name": "Dependency-Track", + "version": "${json-unit.any-string}" + } + ] + }, + "vulnerabilities": [ + { + "bom-ref": "${json-unit.matches:vulnUuid}", + "id": "INT-001", + "source": { + "name": "INTERNAL" + }, + "ratings": [ + { + "source": { + "name": "INTERNAL" + }, + "severity": "high", + "method": "other" + } + ], + "analysis":{ + "state": "in_triage", + "response": [ + "update" + ] + }, + "affects": [ + { + "ref": "${json-unit.matches:projectUuid}" + } + ] + }, + { + "bom-ref": "${json-unit.matches:vulnUuid}", + "id": "INT-001", + "source": { + "name": "INTERNAL" + }, + "ratings": [ + { + "source": { + "name": "INTERNAL" + }, + "severity": "high", + "method": "other" + } + ], + "analysis":{ + "state": "exploitable", + "response": [ + "update" + ] + }, + "affects": [ + { + "ref": "${json-unit.matches:projectUuid}" + } + ] + } + ] + } + """); + } + @Test public void uploadVexInvalidJsonTest() { initializeWithPermissions(Permissions.BOM_UPLOAD); @@ -262,7 +483,7 @@ public void uploadVexInvalidJsonTest() { "title": "The uploaded BOM is invalid", "detail": "Schema validation failed", "errors": [ - "$.components[0].type: does not have a value in the enumeration [application, framework, library, container, operating-system, device, firmware, file]" + "$.components[0].type: does not have a value in the enumeration [\\"application\\", \\"framework\\", \\"library\\", \\"container\\", \\"operating-system\\", \\"device\\", \\"firmware\\", \\"file\\"]" ] } """); @@ -345,7 +566,7 @@ public void uploadVexTooLargeViaPutTest() { { "status": 400, "title": "The provided JSON payload could not be mapped", - "detail": "The VEX is too large to be transmitted safely via Base64 encoded JSON value. Please use the \\"POST /api/v1/vex\\" endpoint with Content-Type \\"multipart/form-data\\" instead. Original cause: String length (20000001) exceeds the maximum length (20000000) (through reference chain: org.dependencytrack.resources.v1.vo.VexSubmitRequest[\\"vex\\"])" + "detail": "The VEX is too large to be transmitted safely via Base64 encoded JSON value. Please use the \\"POST /api/v1/vex\\" endpoint with Content-Type \\"multipart/form-data\\" instead. Original cause: String value length (20000001) exceeds the maximum allowed (20000000, from `StreamReadConstraints.getMaxStringLength()`) (through reference chain: org.dependencytrack.resources.v1.vo.VexSubmitRequest[\\"vex\\"])" } """); } diff --git a/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java b/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java index 72e972ab38..351f64804e 100644 --- a/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/BomUploadProcessingTaskTest.java @@ -1046,6 +1046,84 @@ public void informWithExistingComponentPropertiesAndBomWithComponentProperties() }); } + @Test + public void informWithLicenseResolutionByNameTest() { + final var license = new License(); + license.setLicenseId("MIT"); + license.setName("MIT License"); + qm.persist(license); + + final var project = new Project(); + project.setName("acme-license-app"); + qm.persist(project); + + final byte[] bomBytes = """ + { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b80", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-lib-x", + "licenses": [ + { + "license": { + "name": "MIT License" + } + } + ] + } + ] + } + """.getBytes(StandardCharsets.UTF_8); + + final var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), bomBytes); + new BomUploadProcessingTaskV2().inform(bomUploadEvent); + awaitBomProcessedNotification(bomUploadEvent); + + assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> { + assertThat(component.getResolvedLicense()).isNotNull(); + assertThat(component.getResolvedLicense().getLicenseId()).isEqualTo("MIT"); + }); + } + + @Test + public void informWithUnresolvedLicenseByNameTest() { + final var project = new Project(); + project.setName("acme-license-app"); + qm.persist(project); + + final byte[] bomBytes = """ + { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b80", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-lib-x", + "licenses": [ + { + "license": { + "name": "MIT License" + } + } + ] + } + ] + } + """.getBytes(StandardCharsets.UTF_8); + + final var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), bomBytes); + new BomUploadProcessingTaskV2().inform(bomUploadEvent); + awaitBomProcessedNotification(bomUploadEvent); + + assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> assertThat(component.getResolvedLicense()).isNull()); + } + @Test // https://github.com/DependencyTrack/dependency-track/issues/1905 public void informIssue1905Test() throws Exception { // Known to now work with old task implementation. @@ -1199,12 +1277,62 @@ public void informIssue3371Test() throws Exception { } } + @Test // https://github.com/DependencyTrack/dependency-track/issues/3957 + public void informIssue3957Test() { + final var licenseA = new License(); + licenseA.setLicenseId("GPL-1.0"); + licenseA.setName("GNU General Public License v1.0 only"); + qm.persist(licenseA); + + final var licenseB = new License(); + licenseB.setLicenseId("GPL-1.0-only"); + licenseB.setName("GNU General Public License v1.0 only"); + qm.persist(licenseB); + + final var project = new Project(); + project.setName("acme-license-app"); + qm.persist(project); + + final byte[] bomBytes = """ + { + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b80", + "version": 1, + "components": [ + { + "type": "library", + "name": "acme-lib-x", + "licenses": [ + { + "license": { + "name": "GNU General Public License v1.0 only" + } + } + ] + } + ] + } + """.getBytes(StandardCharsets.UTF_8); + + final var bomUploadEvent = new BomUploadEvent(qm.detach(Project.class, project.getId()), bomBytes); + new BomUploadProcessingTaskV2().inform(bomUploadEvent); + awaitBomProcessedNotification(bomUploadEvent); + + qm.getPersistenceManager().evictAll(); + assertThat(qm.getAllComponents(project)).satisfiesExactly(component -> { + assertThat(component.getResolvedLicense()).isNotNull(); + assertThat(component.getResolvedLicense().getLicenseId()).isEqualTo("GPL-1.0"); + }); + } + private void awaitBomProcessedNotification(final BomUploadEvent bomUploadEvent) { try { await("BOM Processed Notification") .atMost(Duration.ofSeconds(3)) .untilAsserted(() -> assertThat(NOTIFICATIONS) - .anyMatch(n -> NotificationGroup.BOM_PROCESSED.name().equals(n.getGroup()))); + .anyMatch(n -> NotificationGroup.BOM_PROCESSED.name().equals(n.getGroup()) + && NotificationScope.PORTFOLIO.name().equals(n.getScope()))); } catch (ConditionTimeoutException e) { final Optional optionalNotification = NOTIFICATIONS.stream() .filter(n -> NotificationGroup.BOM_PROCESSING_FAILED.name().equals(n.getGroup())) diff --git a/src/test/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzerTest.java b/src/test/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzerTest.java index 5c95722304..e591d02f25 100644 --- a/src/test/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzerTest.java +++ b/src/test/java/org/dependencytrack/tasks/repositories/NugetMetaAnalyzerTest.java @@ -31,7 +31,12 @@ import java.nio.file.Files; import java.nio.file.Paths; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import static org.dependencytrack.tasks.repositories.NugetMetaAnalyzer.SUPPORTED_DATE_FORMATS; import static org.mockserver.model.HttpRequest.request; import static org.mockserver.model.HttpResponse.response; @@ -121,6 +126,19 @@ public void testAnalyzerWithPrivatePackageRepository() throws Exception { Assert.assertEquals("5.0.2", metaModel.getLatestVersion()); Assert.assertNotNull(metaModel.getPublishedTimestamp()); } + + @Test + public void testPublishedDateTimeFormat() throws ParseException { + Date dateParsed = null; + for (DateFormat dateFormat : SUPPORTED_DATE_FORMATS) { + try { + dateParsed = dateFormat.parse("1900-01-01T00:00:00+00:00"); + } catch (ParseException e) {} + } + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + Assert.assertEquals(dateFormat.parse("1900-01-01T00:00:00+00:00"), dateParsed); + } + private String readResourceFileToString(String fileName) throws Exception { return Files.readString(Paths.get(getClass().getResource(fileName).toURI())); } diff --git a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java index 51f876b5d3..1c86489cdb 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskIntegrationTest.java @@ -26,14 +26,17 @@ import org.dependencytrack.model.Component; import org.dependencytrack.model.Project; import org.dependencytrack.model.Vulnerability; -import org.junit.AfterClass; +import org.junit.After; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import org.testcontainers.containers.GenericContainer; import org.testcontainers.images.PullPolicy; import org.testcontainers.utility.DockerImageName; +import java.util.Arrays; +import java.util.Collection; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; @@ -42,23 +45,38 @@ import static org.dependencytrack.model.ConfigPropertyConstants.SCANNER_TRIVY_ENABLED; import static org.testcontainers.containers.wait.strategy.Wait.forLogMessage; +@RunWith(Parameterized.class) public class TrivyAnalysisTaskIntegrationTest extends PersistenceCapableTest { - private static GenericContainer trivyContainer; + @Parameterized.Parameters(name = "[{index}] trivyVersion={0}") + public static Collection testParameters() { + return Arrays.asList(new Object[][]{ + {"0.51.1"}, // Pre breaking change of Application#libraries -> Application#packages + {"0.51.2"}, // Post breaking change of Application#libraries -> Application#packages + {"latest"} + }); + } + + private final String trivyVersion; + private GenericContainer trivyContainer; - @BeforeClass + public TrivyAnalysisTaskIntegrationTest(String trivyVersion) { + this.trivyVersion = trivyVersion; + } + + @Before + @Override @SuppressWarnings("resource") - public static void setUpClass() { - trivyContainer = new GenericContainer<>(DockerImageName.parse("aquasec/trivy:latest")) + public void before() throws Exception { + super.before(); + + trivyContainer = new GenericContainer<>(DockerImageName.parse("aquasec/trivy:" + trivyVersion)) .withImagePullPolicy(PullPolicy.alwaysPull()) .withCommand("server --listen :8080 --token TrivyToken") .withExposedPorts(8080) .waitingFor(forLogMessage(".*Listening :8080.*", 1)); trivyContainer.start(); - } - @Before - public void setUp() throws Exception { qm.createConfigProperty( SCANNER_TRIVY_ENABLED.getGroupName(), SCANNER_TRIVY_ENABLED.getPropertyName(), @@ -82,11 +100,14 @@ public void setUp() throws Exception { ); } - @AfterClass - public static void tearDownClass() { + @After + @Override + public void after() { if (trivyContainer != null) { trivyContainer.stop(); } + + super.after(); } @Test @@ -271,6 +292,8 @@ public void testWithPackageWithTrivyProperties() { qm.createComponentProperty(component, "aquasecurity", "trivy:SrcName", "glibc", IConfigProperty.PropertyType.STRING, null); qm.createComponentProperty(component, "aquasecurity", "trivy:SrcVersion", "2.35", IConfigProperty.PropertyType.STRING, null); qm.createComponentProperty(component, "aquasecurity", "trivy:SrcRelease", "0ubuntu3.4", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:PkgType", "ubuntu", IConfigProperty.PropertyType.STRING, null); + final var analysisEvent = new TrivyAnalysisEvent(List.of(osComponent, component)); new TrivyAnalysisTask().inform(analysisEvent); @@ -292,4 +315,94 @@ public void testWithPackageWithTrivyProperties() { }); } + /** + * This test documents the case where Trivy generates a sbom and operative system is not entirely on distro qualifier. + *

+ * Here's an excerpt of the properties included: + *

+     * "properties": [
+     *   {
+     *     "name": "aquasecurity:trivy:LayerDiffID",
+     *    "value": "sha256:7815e55122d4badd6ca652188bb24c925a9c8d710ee712fbb7f3cff29900943c"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:LayerDigest",
+     *     "value": "sha256:bd6651fa9674b8273dfcd61f21610a43fc31ea7b6d0123e7508a89510477deb4"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:PkgID",
+     *     "value": "git@2.43.0-r0"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:PkgType",
+     *     "value": "alpine"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:SrcName",
+     *     "value": "git"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:SrcVersion",
+     *     "value": "2.43.0-r0"
+     *   },
+     *   {
+     *     "name": "aquasecurity:trivy:SrcVersion",
+     *     "value": "2.35"
+     *   }
+     * ]
+     * 
+ *

+ * To reproduce, run: + *

+     * docker run -it --rm aquasec/trivy image --format cyclonedx aquasec/trivy:0.51.1
+     * 
+ * + * @see Add support for CycloneDX component properties + * @see Support component properties with Trivy + */ + @Test + public void testWithPackageWithTrivyPropertiesWithDistroWithoutOS() { + final var project = new Project(); + project.setName("acme-app"); + qm.persist(project); + + final var osComponent = new Component(); + osComponent.setProject(project); + osComponent.setName("alpine"); + osComponent.setVersion("3.19.1"); + osComponent.setClassifier(Classifier.OPERATING_SYSTEM); + qm.persist(osComponent); + + final var component = new Component(); + component.setProject(project); + component.setName("git"); + component.setVersion("2.43.0-r0"); + component.setClassifier(Classifier.LIBRARY); + component.setPurl("pkg:apk/alpine/git@2.43.0-r0?arch=x86_64&distro=3.19.1"); + qm.persist(component); + + qm.createComponentProperty(component, "aquasecurity", "trivy:PkgID", "git@2.43.0-r0", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:PkgType", "alpine", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:SrcName", "git", IConfigProperty.PropertyType.STRING, null); + qm.createComponentProperty(component, "aquasecurity", "trivy:SrcVersion", "2.43.0-r0", IConfigProperty.PropertyType.STRING, null); + + final var analysisEvent = new TrivyAnalysisEvent(List.of(osComponent, component)); + new TrivyAnalysisTask().inform(analysisEvent); + + assertThat(qm.getAllVulnerabilities(component)).anySatisfy(vuln -> { + assertThat(vuln.getVulnId()).isEqualTo("CVE-2024-32002"); + assertThat(vuln.getSource()).isEqualTo(Vulnerability.Source.NVD.name()); + + // NB: Can't assert specific values here, as we're testing against + // a moving target. These values may change over time. We do proper + // assertions in TrivyAnalyzerTaskTest. + assertThat(vuln.getTitle()).isNotBlank(); + assertThat(vuln.getDescription()).isNotBlank(); + assertThat(vuln.getCreated()).isNotNull(); + assertThat(vuln.getPublished()).isNotNull(); + assertThat(vuln.getUpdated()).isNotNull(); + assertThat(vuln.getSeverity()).isNotNull(); + assertThat(vuln.getReferences()).isNotBlank(); + }); + } } diff --git a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskTest.java index ee4a074504..cbe5778e1d 100644 --- a/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/scanners/TrivyAnalysisTaskTest.java @@ -366,10 +366,25 @@ Those using Woodstox to parse XML data may be vulnerable to Denial of Service at "applications": [ { "type": "jar", + "packages": [ + { + "name": "com.fasterxml.woodstox:woodstox-core", + "version": "5.0.0", + "src_name": "com.fasterxml.woodstox:woodstox-core", + "src_version": "5.0.0", + "licenses": [], + "layer": { + "eosl": false, + "extended": false + } + } + ], "libraries": [ { "name": "com.fasterxml.woodstox:woodstox-core", "version": "5.0.0", + "src_name": "com.fasterxml.woodstox:woodstox-core", + "src_version": "5.0.0", "licenses": [], "layer": { "eosl": false, @@ -395,6 +410,10 @@ Those using Woodstox to parse XML data may be vulnerable to Denial of Service at "${json-unit.regex}(^sha256:[a-f0-9]{64}$)" ], "options": { + "pkg_types": [ + "os", + "library" + ], "vuln_type": [ "os", "library" diff --git a/src/test/resources/unit/bom-issue4008.xml b/src/test/resources/unit/bom-issue4008.xml new file mode 100644 index 0000000000..f4d2a5630b --- /dev/null +++ b/src/test/resources/unit/bom-issue4008.xml @@ -0,0 +1,99 @@ + + + + + + Author + author@example.com + 123-456-7890 + + + + + Foo Incorporated + https://foo.bar.com + + Foo Jr. + foojr@bar.com + 123-456-7890 + + + DependencyTrack + Acme example + + + https://acme.example + + + https://acme.example + + + https://acme.example + + + https://acme.example + + + + + Foo Incorporated + https://foo.bar.com + + Foo Sr. + foo@bar.com + 800-123-4567 + + + + Foo Incorporated + https://foo.bar.com + + Foo Jr. + foojr@bar.com + 123-456-7890 + + + + + + + Foo Incorporated + https://foo.bar.com + + Foo Jr. + foojr@bar.com + 123-456-7890 + + + Sometimes this field is long because it is composed of a list of authors...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... + Example Incorporated + com.example + xmlutil + 1.0.0 + A makebelieve XML utility library + + 2b67669c925048d1a5c7f124d9ba1d2a + 72ca79908c814022905e86f8bbecd9b829352139 + 1389877662864d2bb0488b4b1e417ce5647a1687084341178a203b243dfe90e7 + + + + Apache-2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + + + Copyright Example Inc. All rights reserved. + cpe:/a:example:xmlutil:1.0.0 + pkg:maven/com.example/xmlutil@1.0.0?packaging=jar + false + + foo + bar + baz + qux + qux + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + + + + diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.0.xml b/src/test/resources/unit/cyclonedx/valid-bom-1.0.xml new file mode 100644 index 0000000000..f0bfba2211 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.0.xml @@ -0,0 +1,69 @@ + + + + + org.example + myapplication + 1.0.0 + An example application + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + + Apache-2.0 + + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + + + twitter + bootstrap + 3.3.7 + The most popular front-end framework for developing responsive, mobile first projects on the web. + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + MIT + + + pkg:npm/bootstrap@3.3.7 + false + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Apache-2.0 + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + + + + diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.1.xml b/src/test/resources/unit/cyclonedx/valid-bom-1.1.xml new file mode 100644 index 0000000000..06fc5e870a --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.1.xml @@ -0,0 +1,118 @@ + + + + + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + \ No newline at end of file diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.2.json b/src/test/resources/unit/cyclonedx/valid-bom-1.2.json new file mode 100644 index 0000000000..629793568e --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.2.json @@ -0,0 +1,177 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.2", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "author": "Example Super Heros", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.2.xml b/src/test/resources/unit/cyclonedx/valid-bom-1.2.xml new file mode 100644 index 0000000000..6be1b4f062 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.2.xml @@ -0,0 +1,181 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Acme Super Heros + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + Example Super Heros + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.3.json b/src/test/resources/unit/cyclonedx/valid-bom-1.3.json new file mode 100644 index 0000000000..75550db716 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.3.json @@ -0,0 +1,177 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.3", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "author": "Example Super Heros", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.3.xml b/src/test/resources/unit/cyclonedx/valid-bom-1.3.xml new file mode 100644 index 0000000000..c9cda0c6df --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.3.xml @@ -0,0 +1,181 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Acme Super Heros + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + Example Super Heros + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.4.json b/src/test/resources/unit/cyclonedx/valid-bom-1.4.json new file mode 100644 index 0000000000..a6494a7b6f --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.4.json @@ -0,0 +1,177 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.4", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "author": "Example Super Heros", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.4.xml b/src/test/resources/unit/cyclonedx/valid-bom-1.4.xml new file mode 100644 index 0000000000..a675a96762 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.4.xml @@ -0,0 +1,181 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Acme Super Heros + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + Example Super Heros + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.5.json b/src/test/resources/unit/cyclonedx/valid-bom-1.5.json new file mode 100644 index 0000000000..23197b9a03 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.5.json @@ -0,0 +1,177 @@ +{ + "bomFormat": "CycloneDX", + "specVersion": "1.5", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacture": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4=" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "author": "Example Super Heros", + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.5.xml b/src/test/resources/unit/cyclonedx/valid-bom-1.5.xml new file mode 100644 index 0000000000..913285eac6 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.5.xml @@ -0,0 +1,181 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Acme Super Heros + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + Example Super Heros + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.6.json b/src/test/resources/unit/cyclonedx/valid-bom-1.6.json new file mode 100644 index 0000000000..c07ab7b0c4 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.6.json @@ -0,0 +1,201 @@ +{ + "$schema": "http://cyclonedx.org/schema/bom-1.6.schema.json", + "bomFormat": "CycloneDX", + "specVersion": "1.6", + "serialNumber": "urn:uuid:3e671687-395b-41f5-a30f-a58921a69b79", + "version": 1, + "metadata": { + "timestamp": "2020-04-13T20:20:39+00:00", + "tools": [ + { + "vendor": "Awesome Vendor", + "name": "Awesome Tool", + "version": "9.1.2", + "hashes": [ + { + "alg": "SHA-1", + "content": "25ed8e31b995bb927966616df2a42b979a2717f0" + }, + { + "alg": "SHA-256", + "content": "a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df" + } + ] + } + ], + "authors": [ + { + "name": "Samantha Wright", + "email": "samantha.wright@example.com", + "phone": "800-555-1212" + } + ], + "component": { + "type": "application", + "author": "Acme Super Heros", + "name": "Acme Application", + "version": "9.1.1", + "swid": { + "tagId": "swidgen-242eb18a-503e-ca37-393b-cf156ef09691_9.1.1", + "name": "Acme Application", + "version": "9.1.1", + "text": { + "contentType": "text/xml", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + } + } + }, + "manufacturer": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Professional Services", + "email": "professional.services@example.com" + } + ] + }, + "supplier": { + "name": "Acme, Inc.", + "url": [ + "https://example.com" + ], + "contact": [ + { + "name": "Acme Distribution", + "email": "distribution@example.com" + } + ] + } + }, + "components": [ + { + "bom-ref": "pkg:npm/acme/component@1.0.0", + "type": "library", + "author": "Joane Doe et al.", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14", + "hashes": [ + { + "alg": "MD5", + "content": "3942447fac867ae5cdb3229b658f4d48" + }, + { + "alg": "SHA-1", + "content": "e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a" + }, + { + "alg": "SHA-256", + "content": "f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b" + }, + { + "alg": "SHA-512", + "content": "e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282" + } + ], + "licenses": [ + { + "license": { + "id": "Apache-2.0", + "text": { + "contentType": "text/plain", + "encoding": "base64", + "content": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg==" + }, + "url": "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + ], + "purl": "pkg:npm/acme/component@1.0.0", + "pedigree": { + "ancestors": [ + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + }, + { + "type": "library", + "publisher": "Acme Inc", + "group": "com.acme", + "name": "tomcat-catalina", + "version": "9.0.14" + } + ], + "commits": [ + { + "uid": "7638417db6d59f3c431d3e1f261cc637155684cd", + "url": "https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd", + "author": { + "timestamp": "2018-11-13T20:20:39+00:00", + "name": "me", + "email": "me@acme.org" + } + } + ] + } + }, + { + "type": "library", + "supplier": { + "name": "Example, Inc.", + "url": [ + "https://example.com", + "https://example.net" + ], + "contact": [ + { + "name": "Example Support AMER Distribution", + "email": "support@example.com", + "phone": "800-555-1212" + }, + { + "name": "Example Support APAC", + "email": "support@apac.example.com" + } + ] + }, + "manufacturer": { + "name": "Example-2, Inc.", + "url": [ + "https://example.org" + ], + "contact": [ + { + "email": "support@example.org" + } + ] + }, + "authors": [ + { + "name": "Anthony Edward Stark", + "phone": "555-212-970-4133", + "email": "ironman@example.org" + }, + { + "name": "Peter Benjamin Parker", + "email": "spiderman@example.org" + } + ], + "group": "org.example", + "name": "mylibrary", + "version": "1.0.0", + "scope": "required" + } + ], + "dependencies": [ + { + "ref": "pkg:npm/acme/component@1.0.0", + "dependsOn": [ + "pkg:npm/acme/component@1.0.0" + ] + } + ] +} diff --git a/src/test/resources/unit/cyclonedx/valid-bom-1.6.xml b/src/test/resources/unit/cyclonedx/valid-bom-1.6.xml new file mode 100644 index 0000000000..6760b9da06 --- /dev/null +++ b/src/test/resources/unit/cyclonedx/valid-bom-1.6.xml @@ -0,0 +1,198 @@ + + + + 2020-04-07T07:01:00Z + + + Awesome Vendor + Awesome Tool + 9.1.2 + + 25ed8e31b995bb927966616df2a42b979a2717f0 + a74f733635a19aefb1f73e5947cef59cd7440c6952ef0f03d09d974274cbd6df + + + + + + Samantha Wright + samantha.wright@example.com + 800-555-1212 + + + + Acme Super Heros + Acme Application + 9.1.1 + + PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiID8+CjxTb2Z0d2FyZUlkZW50aXR5IHhtbDpsYW5nPSJFTiIgbmFtZT0iQWNtZSBBcHBsaWNhdGlvbiIgdmVyc2lvbj0iOS4xLjEiIAogdmVyc2lvblNjaGVtZT0ibXVsdGlwYXJ0bnVtZXJpYyIgCiB0YWdJZD0ic3dpZGdlbi1iNTk1MWFjOS00MmMwLWYzODItM2YxZS1iYzdhMmE0NDk3Y2JfOS4xLjEiIAogeG1sbnM9Imh0dHA6Ly9zdGFuZGFyZHMuaXNvLm9yZy9pc28vMTk3NzAvLTIvMjAxNS9zY2hlbWEueHNkIj4gCiB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiAKIHhzaTpzY2hlbWFMb2NhdGlvbj0iaHR0cDovL3N0YW5kYXJkcy5pc28ub3JnL2lzby8xOTc3MC8tMi8yMDE1LWN1cnJlbnQvc2NoZW1hLnhzZCBzY2hlbWEueHNkIiA+CiAgPE1ldGEgZ2VuZXJhdG9yPSJTV0lEIFRhZyBPbmxpbmUgR2VuZXJhdG9yIHYwLjEiIC8+IAogIDxFbnRpdHkgbmFtZT0iQWNtZSwgSW5jLiIgcmVnaWQ9ImV4YW1wbGUuY29tIiByb2xlPSJ0YWdDcmVhdG9yIiAvPiAKPC9Tb2Z0d2FyZUlkZW50aXR5Pg== + + + + Acme, Inc. + https://example.com + + Acme Professional Services + professional.services@example.com + + + + Acme, Inc. + https://example.com + + Acme Distribution + distribution@example.com + + + + + + Joane Doe et al. + Acme Inc + com.acme + tomcat-catalina + 9.0.14 + Modified version of Apache Catalina + required + + 3942447fac867ae5cdb3229b658f4d48 + e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a + f498a8ff2dd007e29c2074f5e4b01a9a01775c3ff3aeaf6906ea503bc5791b7b + e8f33e424f3f4ed6db76a482fde1a5298970e442c531729119e37991884bdffab4f9426b7ee11fccd074eeda0634d71697d6f88a460dce0ac8d627a29f7d1282 + + + + Apache-2.0 + CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFwYWNoZSBMaWNlbnNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlcnNpb24gMi4wLCBKYW51YXJ5IDIwMDQKICAgICAgICAgICAgICAgICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzLwoKICAgVEVSTVMgQU5EIENPTkRJVElPTlMgRk9SIFVTRSwgUkVQUk9EVUNUSU9OLCBBTkQgRElTVFJJQlVUSU9OCgogICAxLiBEZWZpbml0aW9ucy4KCiAgICAgICJMaWNlbnNlIiBzaGFsbCBtZWFuIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBmb3IgdXNlLCByZXByb2R1Y3Rpb24sCiAgICAgIGFuZCBkaXN0cmlidXRpb24gYXMgZGVmaW5lZCBieSBTZWN0aW9ucyAxIHRocm91Z2ggOSBvZiB0aGlzIGRvY3VtZW50LgoKICAgICAgIkxpY2Vuc29yIiBzaGFsbCBtZWFuIHRoZSBjb3B5cmlnaHQgb3duZXIgb3IgZW50aXR5IGF1dGhvcml6ZWQgYnkKICAgICAgdGhlIGNvcHlyaWdodCBvd25lciB0aGF0IGlzIGdyYW50aW5nIHRoZSBMaWNlbnNlLgoKICAgICAgIkxlZ2FsIEVudGl0eSIgc2hhbGwgbWVhbiB0aGUgdW5pb24gb2YgdGhlIGFjdGluZyBlbnRpdHkgYW5kIGFsbAogICAgICBvdGhlciBlbnRpdGllcyB0aGF0IGNvbnRyb2wsIGFyZSBjb250cm9sbGVkIGJ5LCBvciBhcmUgdW5kZXIgY29tbW9uCiAgICAgIGNvbnRyb2wgd2l0aCB0aGF0IGVudGl0eS4gRm9yIHRoZSBwdXJwb3NlcyBvZiB0aGlzIGRlZmluaXRpb24sCiAgICAgICJjb250cm9sIiBtZWFucyAoaSkgdGhlIHBvd2VyLCBkaXJlY3Qgb3IgaW5kaXJlY3QsIHRvIGNhdXNlIHRoZQogICAgICBkaXJlY3Rpb24gb3IgbWFuYWdlbWVudCBvZiBzdWNoIGVudGl0eSwgd2hldGhlciBieSBjb250cmFjdCBvcgogICAgICBvdGhlcndpc2UsIG9yIChpaSkgb3duZXJzaGlwIG9mIGZpZnR5IHBlcmNlbnQgKDUwJSkgb3IgbW9yZSBvZiB0aGUKICAgICAgb3V0c3RhbmRpbmcgc2hhcmVzLCBvciAoaWlpKSBiZW5lZmljaWFsIG93bmVyc2hpcCBvZiBzdWNoIGVudGl0eS4KCiAgICAgICJZb3UiIChvciAiWW91ciIpIHNoYWxsIG1lYW4gYW4gaW5kaXZpZHVhbCBvciBMZWdhbCBFbnRpdHkKICAgICAgZXhlcmNpc2luZyBwZXJtaXNzaW9ucyBncmFudGVkIGJ5IHRoaXMgTGljZW5zZS4KCiAgICAgICJTb3VyY2UiIGZvcm0gc2hhbGwgbWVhbiB0aGUgcHJlZmVycmVkIGZvcm0gZm9yIG1ha2luZyBtb2RpZmljYXRpb25zLAogICAgICBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIHNvZnR3YXJlIHNvdXJjZSBjb2RlLCBkb2N1bWVudGF0aW9uCiAgICAgIHNvdXJjZSwgYW5kIGNvbmZpZ3VyYXRpb24gZmlsZXMuCgogICAgICAiT2JqZWN0IiBmb3JtIHNoYWxsIG1lYW4gYW55IGZvcm0gcmVzdWx0aW5nIGZyb20gbWVjaGFuaWNhbAogICAgICB0cmFuc2Zvcm1hdGlvbiBvciB0cmFuc2xhdGlvbiBvZiBhIFNvdXJjZSBmb3JtLCBpbmNsdWRpbmcgYnV0CiAgICAgIG5vdCBsaW1pdGVkIHRvIGNvbXBpbGVkIG9iamVjdCBjb2RlLCBnZW5lcmF0ZWQgZG9jdW1lbnRhdGlvbiwKICAgICAgYW5kIGNvbnZlcnNpb25zIHRvIG90aGVyIG1lZGlhIHR5cGVzLgoKICAgICAgIldvcmsiIHNoYWxsIG1lYW4gdGhlIHdvcmsgb2YgYXV0aG9yc2hpcCwgd2hldGhlciBpbiBTb3VyY2Ugb3IKICAgICAgT2JqZWN0IGZvcm0sIG1hZGUgYXZhaWxhYmxlIHVuZGVyIHRoZSBMaWNlbnNlLCBhcyBpbmRpY2F0ZWQgYnkgYQogICAgICBjb3B5cmlnaHQgbm90aWNlIHRoYXQgaXMgaW5jbHVkZWQgaW4gb3IgYXR0YWNoZWQgdG8gdGhlIHdvcmsKICAgICAgKGFuIGV4YW1wbGUgaXMgcHJvdmlkZWQgaW4gdGhlIEFwcGVuZGl4IGJlbG93KS4KCiAgICAgICJEZXJpdmF0aXZlIFdvcmtzIiBzaGFsbCBtZWFuIGFueSB3b3JrLCB3aGV0aGVyIGluIFNvdXJjZSBvciBPYmplY3QKICAgICAgZm9ybSwgdGhhdCBpcyBiYXNlZCBvbiAob3IgZGVyaXZlZCBmcm9tKSB0aGUgV29yayBhbmQgZm9yIHdoaWNoIHRoZQogICAgICBlZGl0b3JpYWwgcmV2aXNpb25zLCBhbm5vdGF0aW9ucywgZWxhYm9yYXRpb25zLCBvciBvdGhlciBtb2RpZmljYXRpb25zCiAgICAgIHJlcHJlc2VudCwgYXMgYSB3aG9sZSwgYW4gb3JpZ2luYWwgd29yayBvZiBhdXRob3JzaGlwLiBGb3IgdGhlIHB1cnBvc2VzCiAgICAgIG9mIHRoaXMgTGljZW5zZSwgRGVyaXZhdGl2ZSBXb3JrcyBzaGFsbCBub3QgaW5jbHVkZSB3b3JrcyB0aGF0IHJlbWFpbgogICAgICBzZXBhcmFibGUgZnJvbSwgb3IgbWVyZWx5IGxpbmsgKG9yIGJpbmQgYnkgbmFtZSkgdG8gdGhlIGludGVyZmFjZXMgb2YsCiAgICAgIHRoZSBXb3JrIGFuZCBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YuCgogICAgICAiQ29udHJpYnV0aW9uIiBzaGFsbCBtZWFuIGFueSB3b3JrIG9mIGF1dGhvcnNoaXAsIGluY2x1ZGluZwogICAgICB0aGUgb3JpZ2luYWwgdmVyc2lvbiBvZiB0aGUgV29yayBhbmQgYW55IG1vZGlmaWNhdGlvbnMgb3IgYWRkaXRpb25zCiAgICAgIHRvIHRoYXQgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIHRoYXQgaXMgaW50ZW50aW9uYWxseQogICAgICBzdWJtaXR0ZWQgdG8gTGljZW5zb3IgZm9yIGluY2x1c2lvbiBpbiB0aGUgV29yayBieSB0aGUgY29weXJpZ2h0IG93bmVyCiAgICAgIG9yIGJ5IGFuIGluZGl2aWR1YWwgb3IgTGVnYWwgRW50aXR5IGF1dGhvcml6ZWQgdG8gc3VibWl0IG9uIGJlaGFsZiBvZgogICAgICB0aGUgY29weXJpZ2h0IG93bmVyLiBGb3IgdGhlIHB1cnBvc2VzIG9mIHRoaXMgZGVmaW5pdGlvbiwgInN1Ym1pdHRlZCIKICAgICAgbWVhbnMgYW55IGZvcm0gb2YgZWxlY3Ryb25pYywgdmVyYmFsLCBvciB3cml0dGVuIGNvbW11bmljYXRpb24gc2VudAogICAgICB0byB0aGUgTGljZW5zb3Igb3IgaXRzIHJlcHJlc2VudGF0aXZlcywgaW5jbHVkaW5nIGJ1dCBub3QgbGltaXRlZCB0bwogICAgICBjb21tdW5pY2F0aW9uIG9uIGVsZWN0cm9uaWMgbWFpbGluZyBsaXN0cywgc291cmNlIGNvZGUgY29udHJvbCBzeXN0ZW1zLAogICAgICBhbmQgaXNzdWUgdHJhY2tpbmcgc3lzdGVtcyB0aGF0IGFyZSBtYW5hZ2VkIGJ5LCBvciBvbiBiZWhhbGYgb2YsIHRoZQogICAgICBMaWNlbnNvciBmb3IgdGhlIHB1cnBvc2Ugb2YgZGlzY3Vzc2luZyBhbmQgaW1wcm92aW5nIHRoZSBXb3JrLCBidXQKICAgICAgZXhjbHVkaW5nIGNvbW11bmljYXRpb24gdGhhdCBpcyBjb25zcGljdW91c2x5IG1hcmtlZCBvciBvdGhlcndpc2UKICAgICAgZGVzaWduYXRlZCBpbiB3cml0aW5nIGJ5IHRoZSBjb3B5cmlnaHQgb3duZXIgYXMgIk5vdCBhIENvbnRyaWJ1dGlvbi4iCgogICAgICAiQ29udHJpYnV0b3IiIHNoYWxsIG1lYW4gTGljZW5zb3IgYW5kIGFueSBpbmRpdmlkdWFsIG9yIExlZ2FsIEVudGl0eQogICAgICBvbiBiZWhhbGYgb2Ygd2hvbSBhIENvbnRyaWJ1dGlvbiBoYXMgYmVlbiByZWNlaXZlZCBieSBMaWNlbnNvciBhbmQKICAgICAgc3Vic2VxdWVudGx5IGluY29ycG9yYXRlZCB3aXRoaW4gdGhlIFdvcmsuCgogICAyLiBHcmFudCBvZiBDb3B5cmlnaHQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICBjb3B5cmlnaHQgbGljZW5zZSB0byByZXByb2R1Y2UsIHByZXBhcmUgRGVyaXZhdGl2ZSBXb3JrcyBvZiwKICAgICAgcHVibGljbHkgZGlzcGxheSwgcHVibGljbHkgcGVyZm9ybSwgc3VibGljZW5zZSwgYW5kIGRpc3RyaWJ1dGUgdGhlCiAgICAgIFdvcmsgYW5kIHN1Y2ggRGVyaXZhdGl2ZSBXb3JrcyBpbiBTb3VyY2Ugb3IgT2JqZWN0IGZvcm0uCgogICAzLiBHcmFudCBvZiBQYXRlbnQgTGljZW5zZS4gU3ViamVjdCB0byB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCBlYWNoIENvbnRyaWJ1dG9yIGhlcmVieSBncmFudHMgdG8gWW91IGEgcGVycGV0dWFsLAogICAgICB3b3JsZHdpZGUsIG5vbi1leGNsdXNpdmUsIG5vLWNoYXJnZSwgcm95YWx0eS1mcmVlLCBpcnJldm9jYWJsZQogICAgICAoZXhjZXB0IGFzIHN0YXRlZCBpbiB0aGlzIHNlY3Rpb24pIHBhdGVudCBsaWNlbnNlIHRvIG1ha2UsIGhhdmUgbWFkZSwKICAgICAgdXNlLCBvZmZlciB0byBzZWxsLCBzZWxsLCBpbXBvcnQsIGFuZCBvdGhlcndpc2UgdHJhbnNmZXIgdGhlIFdvcmssCiAgICAgIHdoZXJlIHN1Y2ggbGljZW5zZSBhcHBsaWVzIG9ubHkgdG8gdGhvc2UgcGF0ZW50IGNsYWltcyBsaWNlbnNhYmxlCiAgICAgIGJ5IHN1Y2ggQ29udHJpYnV0b3IgdGhhdCBhcmUgbmVjZXNzYXJpbHkgaW5mcmluZ2VkIGJ5IHRoZWlyCiAgICAgIENvbnRyaWJ1dGlvbihzKSBhbG9uZSBvciBieSBjb21iaW5hdGlvbiBvZiB0aGVpciBDb250cmlidXRpb24ocykKICAgICAgd2l0aCB0aGUgV29yayB0byB3aGljaCBzdWNoIENvbnRyaWJ1dGlvbihzKSB3YXMgc3VibWl0dGVkLiBJZiBZb3UKICAgICAgaW5zdGl0dXRlIHBhdGVudCBsaXRpZ2F0aW9uIGFnYWluc3QgYW55IGVudGl0eSAoaW5jbHVkaW5nIGEKICAgICAgY3Jvc3MtY2xhaW0gb3IgY291bnRlcmNsYWltIGluIGEgbGF3c3VpdCkgYWxsZWdpbmcgdGhhdCB0aGUgV29yawogICAgICBvciBhIENvbnRyaWJ1dGlvbiBpbmNvcnBvcmF0ZWQgd2l0aGluIHRoZSBXb3JrIGNvbnN0aXR1dGVzIGRpcmVjdAogICAgICBvciBjb250cmlidXRvcnkgcGF0ZW50IGluZnJpbmdlbWVudCwgdGhlbiBhbnkgcGF0ZW50IGxpY2Vuc2VzCiAgICAgIGdyYW50ZWQgdG8gWW91IHVuZGVyIHRoaXMgTGljZW5zZSBmb3IgdGhhdCBXb3JrIHNoYWxsIHRlcm1pbmF0ZQogICAgICBhcyBvZiB0aGUgZGF0ZSBzdWNoIGxpdGlnYXRpb24gaXMgZmlsZWQuCgogICA0LiBSZWRpc3RyaWJ1dGlvbi4gWW91IG1heSByZXByb2R1Y2UgYW5kIGRpc3RyaWJ1dGUgY29waWVzIG9mIHRoZQogICAgICBXb3JrIG9yIERlcml2YXRpdmUgV29ya3MgdGhlcmVvZiBpbiBhbnkgbWVkaXVtLCB3aXRoIG9yIHdpdGhvdXQKICAgICAgbW9kaWZpY2F0aW9ucywgYW5kIGluIFNvdXJjZSBvciBPYmplY3QgZm9ybSwgcHJvdmlkZWQgdGhhdCBZb3UKICAgICAgbWVldCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CgogICAgICAoYSkgWW91IG11c3QgZ2l2ZSBhbnkgb3RoZXIgcmVjaXBpZW50cyBvZiB0aGUgV29yayBvcgogICAgICAgICAgRGVyaXZhdGl2ZSBXb3JrcyBhIGNvcHkgb2YgdGhpcyBMaWNlbnNlOyBhbmQKCiAgICAgIChiKSBZb3UgbXVzdCBjYXVzZSBhbnkgbW9kaWZpZWQgZmlsZXMgdG8gY2FycnkgcHJvbWluZW50IG5vdGljZXMKICAgICAgICAgIHN0YXRpbmcgdGhhdCBZb3UgY2hhbmdlZCB0aGUgZmlsZXM7IGFuZAoKICAgICAgKGMpIFlvdSBtdXN0IHJldGFpbiwgaW4gdGhlIFNvdXJjZSBmb3JtIG9mIGFueSBEZXJpdmF0aXZlIFdvcmtzCiAgICAgICAgICB0aGF0IFlvdSBkaXN0cmlidXRlLCBhbGwgY29weXJpZ2h0LCBwYXRlbnQsIHRyYWRlbWFyaywgYW5kCiAgICAgICAgICBhdHRyaWJ1dGlvbiBub3RpY2VzIGZyb20gdGhlIFNvdXJjZSBmb3JtIG9mIHRoZSBXb3JrLAogICAgICAgICAgZXhjbHVkaW5nIHRob3NlIG5vdGljZXMgdGhhdCBkbyBub3QgcGVydGFpbiB0byBhbnkgcGFydCBvZgogICAgICAgICAgdGhlIERlcml2YXRpdmUgV29ya3M7IGFuZAoKICAgICAgKGQpIElmIHRoZSBXb3JrIGluY2x1ZGVzIGEgIk5PVElDRSIgdGV4dCBmaWxlIGFzIHBhcnQgb2YgaXRzCiAgICAgICAgICBkaXN0cmlidXRpb24sIHRoZW4gYW55IERlcml2YXRpdmUgV29ya3MgdGhhdCBZb3UgZGlzdHJpYnV0ZSBtdXN0CiAgICAgICAgICBpbmNsdWRlIGEgcmVhZGFibGUgY29weSBvZiB0aGUgYXR0cmlidXRpb24gbm90aWNlcyBjb250YWluZWQKICAgICAgICAgIHdpdGhpbiBzdWNoIE5PVElDRSBmaWxlLCBleGNsdWRpbmcgdGhvc2Ugbm90aWNlcyB0aGF0IGRvIG5vdAogICAgICAgICAgcGVydGFpbiB0byBhbnkgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaW4gYXQgbGVhc3Qgb25lCiAgICAgICAgICBvZiB0aGUgZm9sbG93aW5nIHBsYWNlczogd2l0aGluIGEgTk9USUNFIHRleHQgZmlsZSBkaXN0cmlidXRlZAogICAgICAgICAgYXMgcGFydCBvZiB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgd2l0aGluIHRoZSBTb3VyY2UgZm9ybSBvcgogICAgICAgICAgZG9jdW1lbnRhdGlvbiwgaWYgcHJvdmlkZWQgYWxvbmcgd2l0aCB0aGUgRGVyaXZhdGl2ZSBXb3Jrczsgb3IsCiAgICAgICAgICB3aXRoaW4gYSBkaXNwbGF5IGdlbmVyYXRlZCBieSB0aGUgRGVyaXZhdGl2ZSBXb3JrcywgaWYgYW5kCiAgICAgICAgICB3aGVyZXZlciBzdWNoIHRoaXJkLXBhcnR5IG5vdGljZXMgbm9ybWFsbHkgYXBwZWFyLiBUaGUgY29udGVudHMKICAgICAgICAgIG9mIHRoZSBOT1RJQ0UgZmlsZSBhcmUgZm9yIGluZm9ybWF0aW9uYWwgcHVycG9zZXMgb25seSBhbmQKICAgICAgICAgIGRvIG5vdCBtb2RpZnkgdGhlIExpY2Vuc2UuIFlvdSBtYXkgYWRkIFlvdXIgb3duIGF0dHJpYnV0aW9uCiAgICAgICAgICBub3RpY2VzIHdpdGhpbiBEZXJpdmF0aXZlIFdvcmtzIHRoYXQgWW91IGRpc3RyaWJ1dGUsIGFsb25nc2lkZQogICAgICAgICAgb3IgYXMgYW4gYWRkZW5kdW0gdG8gdGhlIE5PVElDRSB0ZXh0IGZyb20gdGhlIFdvcmssIHByb3ZpZGVkCiAgICAgICAgICB0aGF0IHN1Y2ggYWRkaXRpb25hbCBhdHRyaWJ1dGlvbiBub3RpY2VzIGNhbm5vdCBiZSBjb25zdHJ1ZWQKICAgICAgICAgIGFzIG1vZGlmeWluZyB0aGUgTGljZW5zZS4KCiAgICAgIFlvdSBtYXkgYWRkIFlvdXIgb3duIGNvcHlyaWdodCBzdGF0ZW1lbnQgdG8gWW91ciBtb2RpZmljYXRpb25zIGFuZAogICAgICBtYXkgcHJvdmlkZSBhZGRpdGlvbmFsIG9yIGRpZmZlcmVudCBsaWNlbnNlIHRlcm1zIGFuZCBjb25kaXRpb25zCiAgICAgIGZvciB1c2UsIHJlcHJvZHVjdGlvbiwgb3IgZGlzdHJpYnV0aW9uIG9mIFlvdXIgbW9kaWZpY2F0aW9ucywgb3IKICAgICAgZm9yIGFueSBzdWNoIERlcml2YXRpdmUgV29ya3MgYXMgYSB3aG9sZSwgcHJvdmlkZWQgWW91ciB1c2UsCiAgICAgIHJlcHJvZHVjdGlvbiwgYW5kIGRpc3RyaWJ1dGlvbiBvZiB0aGUgV29yayBvdGhlcndpc2UgY29tcGxpZXMgd2l0aAogICAgICB0aGUgY29uZGl0aW9ucyBzdGF0ZWQgaW4gdGhpcyBMaWNlbnNlLgoKICAgNS4gU3VibWlzc2lvbiBvZiBDb250cmlidXRpb25zLiBVbmxlc3MgWW91IGV4cGxpY2l0bHkgc3RhdGUgb3RoZXJ3aXNlLAogICAgICBhbnkgQ29udHJpYnV0aW9uIGludGVudGlvbmFsbHkgc3VibWl0dGVkIGZvciBpbmNsdXNpb24gaW4gdGhlIFdvcmsKICAgICAgYnkgWW91IHRvIHRoZSBMaWNlbnNvciBzaGFsbCBiZSB1bmRlciB0aGUgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YKICAgICAgdGhpcyBMaWNlbnNlLCB3aXRob3V0IGFueSBhZGRpdGlvbmFsIHRlcm1zIG9yIGNvbmRpdGlvbnMuCiAgICAgIE5vdHdpdGhzdGFuZGluZyB0aGUgYWJvdmUsIG5vdGhpbmcgaGVyZWluIHNoYWxsIHN1cGVyc2VkZSBvciBtb2RpZnkKICAgICAgdGhlIHRlcm1zIG9mIGFueSBzZXBhcmF0ZSBsaWNlbnNlIGFncmVlbWVudCB5b3UgbWF5IGhhdmUgZXhlY3V0ZWQKICAgICAgd2l0aCBMaWNlbnNvciByZWdhcmRpbmcgc3VjaCBDb250cmlidXRpb25zLgoKICAgNi4gVHJhZGVtYXJrcy4gVGhpcyBMaWNlbnNlIGRvZXMgbm90IGdyYW50IHBlcm1pc3Npb24gdG8gdXNlIHRoZSB0cmFkZQogICAgICBuYW1lcywgdHJhZGVtYXJrcywgc2VydmljZSBtYXJrcywgb3IgcHJvZHVjdCBuYW1lcyBvZiB0aGUgTGljZW5zb3IsCiAgICAgIGV4Y2VwdCBhcyByZXF1aXJlZCBmb3IgcmVhc29uYWJsZSBhbmQgY3VzdG9tYXJ5IHVzZSBpbiBkZXNjcmliaW5nIHRoZQogICAgICBvcmlnaW4gb2YgdGhlIFdvcmsgYW5kIHJlcHJvZHVjaW5nIHRoZSBjb250ZW50IG9mIHRoZSBOT1RJQ0UgZmlsZS4KCiAgIDcuIERpc2NsYWltZXIgb2YgV2FycmFudHkuIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvcgogICAgICBhZ3JlZWQgdG8gaW4gd3JpdGluZywgTGljZW5zb3IgcHJvdmlkZXMgdGhlIFdvcmsgKGFuZCBlYWNoCiAgICAgIENvbnRyaWJ1dG9yIHByb3ZpZGVzIGl0cyBDb250cmlidXRpb25zKSBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICAgICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IKICAgICAgaW1wbGllZCwgaW5jbHVkaW5nLCB3aXRob3V0IGxpbWl0YXRpb24sIGFueSB3YXJyYW50aWVzIG9yIGNvbmRpdGlvbnMKICAgICAgb2YgVElUTEUsIE5PTi1JTkZSSU5HRU1FTlQsIE1FUkNIQU5UQUJJTElUWSwgb3IgRklUTkVTUyBGT1IgQQogICAgICBQQVJUSUNVTEFSIFBVUlBPU0UuIFlvdSBhcmUgc29sZWx5IHJlc3BvbnNpYmxlIGZvciBkZXRlcm1pbmluZyB0aGUKICAgICAgYXBwcm9wcmlhdGVuZXNzIG9mIHVzaW5nIG9yIHJlZGlzdHJpYnV0aW5nIHRoZSBXb3JrIGFuZCBhc3N1bWUgYW55CiAgICAgIHJpc2tzIGFzc29jaWF0ZWQgd2l0aCBZb3VyIGV4ZXJjaXNlIG9mIHBlcm1pc3Npb25zIHVuZGVyIHRoaXMgTGljZW5zZS4KCiAgIDguIExpbWl0YXRpb24gb2YgTGlhYmlsaXR5LiBJbiBubyBldmVudCBhbmQgdW5kZXIgbm8gbGVnYWwgdGhlb3J5LAogICAgICB3aGV0aGVyIGluIHRvcnQgKGluY2x1ZGluZyBuZWdsaWdlbmNlKSwgY29udHJhY3QsIG9yIG90aGVyd2lzZSwKICAgICAgdW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IChzdWNoIGFzIGRlbGliZXJhdGUgYW5kIGdyb3NzbHkKICAgICAgbmVnbGlnZW50IGFjdHMpIG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzaGFsbCBhbnkgQ29udHJpYnV0b3IgYmUKICAgICAgbGlhYmxlIHRvIFlvdSBmb3IgZGFtYWdlcywgaW5jbHVkaW5nIGFueSBkaXJlY3QsIGluZGlyZWN0LCBzcGVjaWFsLAogICAgICBpbmNpZGVudGFsLCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMgb2YgYW55IGNoYXJhY3RlciBhcmlzaW5nIGFzIGEKICAgICAgcmVzdWx0IG9mIHRoaXMgTGljZW5zZSBvciBvdXQgb2YgdGhlIHVzZSBvciBpbmFiaWxpdHkgdG8gdXNlIHRoZQogICAgICBXb3JrIChpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGRhbWFnZXMgZm9yIGxvc3Mgb2YgZ29vZHdpbGwsCiAgICAgIHdvcmsgc3RvcHBhZ2UsIGNvbXB1dGVyIGZhaWx1cmUgb3IgbWFsZnVuY3Rpb24sIG9yIGFueSBhbmQgYWxsCiAgICAgIG90aGVyIGNvbW1lcmNpYWwgZGFtYWdlcyBvciBsb3NzZXMpLCBldmVuIGlmIHN1Y2ggQ29udHJpYnV0b3IKICAgICAgaGFzIGJlZW4gYWR2aXNlZCBvZiB0aGUgcG9zc2liaWxpdHkgb2Ygc3VjaCBkYW1hZ2VzLgoKICAgOS4gQWNjZXB0aW5nIFdhcnJhbnR5IG9yIEFkZGl0aW9uYWwgTGlhYmlsaXR5LiBXaGlsZSByZWRpc3RyaWJ1dGluZwogICAgICB0aGUgV29yayBvciBEZXJpdmF0aXZlIFdvcmtzIHRoZXJlb2YsIFlvdSBtYXkgY2hvb3NlIHRvIG9mZmVyLAogICAgICBhbmQgY2hhcmdlIGEgZmVlIGZvciwgYWNjZXB0YW5jZSBvZiBzdXBwb3J0LCB3YXJyYW50eSwgaW5kZW1uaXR5LAogICAgICBvciBvdGhlciBsaWFiaWxpdHkgb2JsaWdhdGlvbnMgYW5kL29yIHJpZ2h0cyBjb25zaXN0ZW50IHdpdGggdGhpcwogICAgICBMaWNlbnNlLiBIb3dldmVyLCBpbiBhY2NlcHRpbmcgc3VjaCBvYmxpZ2F0aW9ucywgWW91IG1heSBhY3Qgb25seQogICAgICBvbiBZb3VyIG93biBiZWhhbGYgYW5kIG9uIFlvdXIgc29sZSByZXNwb25zaWJpbGl0eSwgbm90IG9uIGJlaGFsZgogICAgICBvZiBhbnkgb3RoZXIgQ29udHJpYnV0b3IsIGFuZCBvbmx5IGlmIFlvdSBhZ3JlZSB0byBpbmRlbW5pZnksCiAgICAgIGRlZmVuZCwgYW5kIGhvbGQgZWFjaCBDb250cmlidXRvciBoYXJtbGVzcyBmb3IgYW55IGxpYWJpbGl0eQogICAgICBpbmN1cnJlZCBieSwgb3IgY2xhaW1zIGFzc2VydGVkIGFnYWluc3QsIHN1Y2ggQ29udHJpYnV0b3IgYnkgcmVhc29uCiAgICAgIG9mIHlvdXIgYWNjZXB0aW5nIGFueSBzdWNoIHdhcnJhbnR5IG9yIGFkZGl0aW9uYWwgbGlhYmlsaXR5LgoKICAgRU5EIE9GIFRFUk1TIEFORCBDT05ESVRJT05TCgogICBBUFBFTkRJWDogSG93IHRvIGFwcGx5IHRoZSBBcGFjaGUgTGljZW5zZSB0byB5b3VyIHdvcmsuCgogICAgICBUbyBhcHBseSB0aGUgQXBhY2hlIExpY2Vuc2UgdG8geW91ciB3b3JrLCBhdHRhY2ggdGhlIGZvbGxvd2luZwogICAgICBib2lsZXJwbGF0ZSBub3RpY2UsIHdpdGggdGhlIGZpZWxkcyBlbmNsb3NlZCBieSBicmFja2V0cyAiW10iCiAgICAgIHJlcGxhY2VkIHdpdGggeW91ciBvd24gaWRlbnRpZnlpbmcgaW5mb3JtYXRpb24uIChEb24ndCBpbmNsdWRlCiAgICAgIHRoZSBicmFja2V0cyEpICBUaGUgdGV4dCBzaG91bGQgYmUgZW5jbG9zZWQgaW4gdGhlIGFwcHJvcHJpYXRlCiAgICAgIGNvbW1lbnQgc3ludGF4IGZvciB0aGUgZmlsZSBmb3JtYXQuIFdlIGFsc28gcmVjb21tZW5kIHRoYXQgYQogICAgICBmaWxlIG9yIGNsYXNzIG5hbWUgYW5kIGRlc2NyaXB0aW9uIG9mIHB1cnBvc2UgYmUgaW5jbHVkZWQgb24gdGhlCiAgICAgIHNhbWUgInByaW50ZWQgcGFnZSIgYXMgdGhlIGNvcHlyaWdodCBub3RpY2UgZm9yIGVhc2llcgogICAgICBpZGVudGlmaWNhdGlvbiB3aXRoaW4gdGhpcmQtcGFydHkgYXJjaGl2ZXMuCgogICBDb3B5cmlnaHQgW3l5eXldIFtuYW1lIG9mIGNvcHlyaWdodCBvd25lcl0KCiAgIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwogICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuCiAgIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdAoKICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKICAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogICBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4= + https://www.apache.org/licenses/LICENSE-2.0.txt + + + pkg:maven/com.acme/tomcat-catalina@9.0.14?packaging=jar + + + + Apache Super Heros + Apache + org.apache.tomcat + tomcat-catalina + 9.0.14 + Apache Catalina + + + Apache-2.0 + + + pkg:maven/org.apache.tomcat/tomcat-catalina@9.0.14?packaging=jar + + + + + 7638417db6d59f3c431d3e1f261cc637155684cd + https://location/to/7638417db6d59f3c431d3e1f261cc637155684cd + + 2018-11-07T22:01:45Z + John Doe + john.doe@example.com + + + 2018-11-07T22:01:45Z + Jane Doe + jane.doe@example.com + + Initial commit + + + Commentary here + + + + + Example Inc. + https://example.com + https://example.net + + Example Support AMER + support@example.com + 800-555-1212 + + + Example Support APAC + support@apac.example.com + + + + Example-2, Inc.Example-2, Inc. + https://example.org + + support@example.org + + + + + Anthony Edward Stark + ironman@example.org + 555-212-970-4133 + + + Peter Benjamin Parker + spiderman@example.org + + + org.example + mylibrary + 1.0.0 + required + + 2342c2eaf1feb9a80195dbaddf2ebaa3 + 68b78babe00a053f9e35ec6a2d9080f5b90122b0 + 708f1f53b41f11f02d12a11b1a38d2905d47b099afc71a0f1124ef8582ec7313 + 387b7ae16b9cae45f830671541539bf544202faae5aac544a93b7b0a04f5f846fa2f4e81ef3f1677e13aed7496408a441f5657ab6d54423e56bf6f38da124aef + + + EPL-2.0 OR GPL-2.0-with-classpath-exception + + Copyright Example Inc. All rights reserved. + cpe:/a:example:myapplication:1.0.0 + pkg:maven/com.example/myapplication@1.0.0?packaging=war + false + + + http://example.org/docs + All component versions are documented here + + + http://example.org/security + + + + + Example Super Heros + com.example + myframework + 1.0.0 + Example Inc, enterprise framework + required + + cfcb0b64aacd2f81c1cd546543de965a + 7fbeef2346c45d565c3341f037bce4e088af8a52 + 0384db3cec55d86a6898c489fdb75a8e75fe66b26639634983d2f3c3558493d1 + 854909cdb9e3ca183056837144aab6d8069b377bd66445087cc7157bf0c3f620418705dd0b83bdc2f73a508c2bdb316ca1809d75ee6972d02023a3e7dd655c79 + + + + Some random license + + + pkg:maven/com.example/myframework@1.0.0?packaging=war + false + + + http://example.com/myframework + + + http://example.com/security + + + + + pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy