├── .github ├── dependabot.yml ├── lock.yml └── workflows │ ├── codeql-analysis.yml │ └── maven.yml ├── .gitignore ├── LICENSE ├── README.md ├── logging └── log4j.xml ├── pom.xml ├── src ├── main │ ├── java │ │ └── org │ │ │ └── cyclonedx │ │ │ └── contrib │ │ │ └── com │ │ │ └── lmco │ │ │ └── efoss │ │ │ └── unix │ │ │ └── sbom │ │ │ ├── UnixSbomGeneratorApplication.java │ │ │ ├── exceptions │ │ │ └── SBomException.java │ │ │ ├── generator │ │ │ ├── AlpineSBomGenerator.java │ │ │ ├── RedHatSBomGenerator.java │ │ │ ├── SBomGenerator.java │ │ │ ├── UbuntuSBomGenerator.java │ │ │ └── UnixSBomGenerator.java │ │ │ └── utils │ │ │ ├── DateUtils.java │ │ │ └── OperatingSystemUtils.java │ └── resources │ │ └── application.properties └── test │ ├── java │ └── org │ │ └── cyclonedx │ │ └── contrib │ │ └── com │ │ └── lmco │ │ └── efoss │ │ └── unix │ │ └── sbom │ │ ├── UnixSbomGeneratorApplicationTests.java │ │ ├── generator │ │ ├── AlpineSBomGeneratorTest.java │ │ ├── BaseSBomGeneratorTest.java │ │ ├── RedHatSBomGeneratorTest.java │ │ ├── SBomGeneratorTest.java │ │ ├── UbuntuSBomGeneratorTest.java │ │ └── UnixSBomGeneratorTest.java │ │ └── utils │ │ ├── DateUtilsTest.java │ │ ├── Log4JTestWatcher.java │ │ ├── OperatingSystemUtilsTest.java │ │ └── TestUtils.java │ └── resources │ ├── license │ ├── COPYING │ ├── redhat │ │ ├── COPYING │ │ └── LICENSE │ └── ubuntu │ │ └── copyright │ ├── logging │ ├── AlpineSBomGeneratorTestLog4J.xml │ ├── DateUtilsAppender.xml │ ├── OperatingSystemUtilsTestLog4J.xml │ ├── RedHatSBomGeneratorTestLog4J.xml │ ├── SBomGeneratorTestLog4J.xml │ ├── UbuntuSBomGeneratorTestLog4J.xml │ ├── UnixSBomGeneratorTestLog4J.xml │ └── UnixSbomGeneratorApplicationAppender.xml │ ├── operatingSystem │ └── ubuntu.txt │ ├── osReleaseFiles │ ├── alpine-os-release.txt │ ├── centos-os-release.txt │ ├── debian-os-release.txt │ ├── redhat-os-release.txt │ └── ubuntu-os-release.txt │ ├── packageDetails │ ├── alpine.txt │ ├── expectedAlpineDetailMap.txt │ ├── expectedRedhatDetailMap.txt │ ├── expectedUbuntuDetailMap.txt │ ├── redhat.txt │ └── ubuntu.txt │ ├── packageList │ ├── alpine.txt │ ├── expectedAlpinePackages.txt │ ├── expectedRedhatPackages.txt │ ├── expectedUbuntuPackages.txt │ ├── redhat.txt │ └── ubuntu.txt │ ├── purl │ ├── redhatPurl.txt │ └── redhatPurl2.txt │ ├── sboms │ ├── bom.json │ └── bom.xml │ └── version │ ├── alpineVersion.txt │ └── ubuntuVersion.txt └── start.sh /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/lock.yml: -------------------------------------------------------------------------------- 1 | # Configuration for lock-threads - https://github.com/dessant/lock-threads 2 | daysUntilLock: 90 3 | exemptLabels: [] 4 | lockLabel: false 5 | lockComment: > 6 | This thread has been automatically locked since there has not been 7 | any recent activity after it was closed. Please open a new issue for 8 | related bugs. 9 | setLockReason: true 10 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: ['main', master] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: ['main', master] 9 | workflow_dispatch: { } 10 | schedule: 11 | - cron: '0 9 * * 5' 12 | 13 | jobs: 14 | analyze: 15 | name: Analyze 16 | runs-on: ubuntu-latest 17 | 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | # Override automatic language detection by changing the below list 22 | # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python'] 23 | language: ['java'] 24 | # Learn more... 25 | # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection 26 | 27 | steps: 28 | - name: Checkout repository 29 | uses: actions/checkout@v2.3.5 30 | with: 31 | # We must fetch at least the immediate parents so that if this is 32 | # a pull request then we can checkout the head. 33 | fetch-depth: 2 34 | 35 | # If this run was triggered by a pull request event, then checkout 36 | # the head of the pull request instead of the merge commit. 37 | - run: git checkout HEAD^2 38 | if: ${{ github.event_name == 'pull_request' }} 39 | 40 | # Initializes the CodeQL tools for scanning. 41 | - name: Initialize CodeQL 42 | uses: github/codeql-action/init@v1 43 | with: 44 | languages: ${{ matrix.language }} 45 | # If you wish to specify custom queries, you can do so here or in a config file. 46 | # By default, queries listed here will override any specified in a config file. 47 | # Prefix the list here with "+" to use these queries and those in the config file. 48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 49 | 50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 51 | # If this step fails, then you should remove it and run the build manually (see below) 52 | - name: Autobuild 53 | uses: github/codeql-action/autobuild@v1 54 | 55 | # ℹ️ Command-line programs to run using the OS shell. 56 | # 📚 https://git.io/JvXDl 57 | 58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 59 | # and modify them (or add more) to build your code if your project 60 | # uses a compiled language 61 | 62 | #- run: | 63 | # make bootstrap 64 | # make release 65 | 66 | - name: Perform CodeQL Analysis 67 | uses: github/codeql-action/analyze@v1 68 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | name: Maven CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2.3.5 12 | - name: Set up Java 11 13 | uses: actions/setup-java@v2 14 | with: 15 | distribution: 'adopt' 16 | java-version: '11' 17 | - name: Build with Maven 18 | run: mvn package --file pom.xml 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | /logs/ 33 | /output/ 34 | /unitTests/ 35 | /bin/ 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ***** SECURITY CLASSIFICATION: UNCLASSIFIED ******************************** 2 | 3 | Common Software Factory Pipeline 4 | 5 | Copyright 2019 - Lockheed Martin Corporation. 6 | 7 | DFARS Clause reference: 252.227-7013 (a)(16) and 252.227-7014 (a)(16) 8 | Unlimited Rights. The Government has the right to use, modify, 9 | reproduce, perform, display, release or disclose this computer software 10 | in whole or in part, in any manner, and for any purpose whatsoever, 11 | and to have or authorize others to do so. 12 | 13 | ****************************** UNCLASSIFIED ******************************** 14 | 15 | Apache License 16 | Version 2.0, January 2004 17 | http://www.apache.org/licenses/ 18 | 19 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 20 | 21 | 1. Definitions. 22 | 23 | "License" shall mean the terms and conditions for use, reproduction, 24 | and distribution as defined by Sections 1 through 9 of this document. 25 | 26 | "Licensor" shall mean the copyright owner or entity authorized by 27 | the copyright owner that is granting the License. 28 | 29 | "Legal Entity" shall mean the union of the acting entity and all 30 | other entities that control, are controlled by, or are under common 31 | control with that entity. For the purposes of this definition, 32 | "control" means (i) the power, direct or indirect, to cause the 33 | direction or management of such entity, whether by contract or 34 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 35 | outstanding shares, or (iii) beneficial ownership of such entity. 36 | 37 | "You" (or "Your") shall mean an individual or Legal Entity 38 | exercising permissions granted by this License. 39 | 40 | "Source" form shall mean the preferred form for making modifications, 41 | including but not limited to software source code, documentation 42 | source, and configuration files. 43 | 44 | "Object" form shall mean any form resulting from mechanical 45 | transformation or translation of a Source form, including but 46 | not limited to compiled object code, generated documentation, 47 | and conversions to other media types. 48 | 49 | "Work" shall mean the work of authorship, whether in Source or 50 | Object form, made available under the License, as indicated by a 51 | copyright notice that is included in or attached to the work 52 | (an example is provided in the Appendix below). 53 | 54 | "Derivative Works" shall mean any work, whether in Source or Object 55 | form, that is based on (or derived from) the Work and for which the 56 | editorial revisions, annotations, elaborations, or other modifications 57 | represent, as a whole, an original work of authorship. For the purposes 58 | of this License, Derivative Works shall not include works that remain 59 | separable from, or merely link (or bind by name) to the interfaces of, 60 | the Work and Derivative Works thereof. 61 | 62 | "Contribution" shall mean any work of authorship, including 63 | the original version of the Work and any modifications or additions 64 | to that Work or Derivative Works thereof, that is intentionally 65 | submitted to Licensor for inclusion in the Work by the copyright owner 66 | or by an individual or Legal Entity authorized to submit on behalf of 67 | the copyright owner. For the purposes of this definition, "submitted" 68 | means any form of electronic, verbal, or written communication sent 69 | to the Licensor or its representatives, including but not limited to 70 | communication on electronic mailing lists, source code control systems, 71 | and issue tracking systems that are managed by, or on behalf of, the 72 | Licensor for the purpose of discussing and improving the Work, but 73 | excluding communication that is conspicuously marked or otherwise 74 | designated in writing by the copyright owner as "Not a Contribution." 75 | 76 | "Contributor" shall mean Licensor and any individual or Legal Entity 77 | on behalf of whom a Contribution has been received by Licensor and 78 | subsequently incorporated within the Work. 79 | 80 | 2. Grant of Copyright License. Subject to the terms and conditions of 81 | this License, each Contributor hereby grants to You a perpetual, 82 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 83 | copyright license to reproduce, prepare Derivative Works of, 84 | publicly display, publicly perform, sublicense, and distribute the 85 | Work and such Derivative Works in Source or Object form. 86 | 87 | 3. Grant of Patent License. Subject to the terms and conditions of 88 | this License, each Contributor hereby grants to You a perpetual, 89 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 90 | (except as stated in this section) patent license to make, have made, 91 | use, offer to sell, sell, import, and otherwise transfer the Work, 92 | where such license applies only to those patent claims licensable 93 | by such Contributor that are necessarily infringed by their 94 | Contribution(s) alone or by combination of their Contribution(s) 95 | with the Work to which such Contribution(s) was submitted. If You 96 | institute patent litigation against any entity (including a 97 | cross-claim or counterclaim in a lawsuit) alleging that the Work 98 | or a Contribution incorporated within the Work constitutes direct 99 | or contributory patent infringement, then any patent licenses 100 | granted to You under this License for that Work shall terminate 101 | as of the date such litigation is filed. 102 | 103 | 4. Redistribution. You may reproduce and distribute copies of the 104 | Work or Derivative Works thereof in any medium, with or without 105 | modifications, and in Source or Object form, provided that You 106 | meet the following conditions: 107 | 108 | (a) You must give any other recipients of the Work or 109 | Derivative Works a copy of this License; and 110 | 111 | (b) You must cause any modified files to carry prominent notices 112 | stating that You changed the files; and 113 | 114 | (c) You must retain, in the Source form of any Derivative Works 115 | that You distribute, all copyright, patent, trademark, and 116 | attribution notices from the Source form of the Work, 117 | excluding those notices that do not pertain to any part of 118 | the Derivative Works; and 119 | 120 | (d) If the Work includes a "NOTICE" text file as part of its 121 | distribution, then any Derivative Works that You distribute must 122 | include a readable copy of the attribution notices contained 123 | within such NOTICE file, excluding those notices that do not 124 | pertain to any part of the Derivative Works, in at least one 125 | of the following places: within a NOTICE text file distributed 126 | as part of the Derivative Works; within the Source form or 127 | documentation, if provided along with the Derivative Works; or, 128 | within a display generated by the Derivative Works, if and 129 | wherever such third-party notices normally appear. The contents 130 | of the NOTICE file are for informational purposes only and 131 | do not modify the License. You may add Your own attribution 132 | notices within Derivative Works that You distribute, alongside 133 | or as an addendum to the NOTICE text from the Work, provided 134 | that such additional attribution notices cannot be construed 135 | as modifying the License. 136 | 137 | You may add Your own copyright statement to Your modifications and 138 | may provide additional or different license terms and conditions 139 | for use, reproduction, or distribution of Your modifications, or 140 | for any such Derivative Works as a whole, provided Your use, 141 | reproduction, and distribution of the Work otherwise complies with 142 | the conditions stated in this License. 143 | 144 | 5. Submission of Contributions. Unless You explicitly state otherwise, 145 | any Contribution intentionally submitted for inclusion in the Work 146 | by You to the Licensor shall be under the terms and conditions of 147 | this License, without any additional terms or conditions. 148 | Notwithstanding the above, nothing herein shall supersede or modify 149 | the terms of any separate license agreement you may have executed 150 | with Licensor regarding such Contributions. 151 | 152 | 6. Trademarks. This License does not grant permission to use the trade 153 | names, trademarks, service marks, or product names of the Licensor, 154 | except as required for reasonable and customary use in describing the 155 | origin of the Work and reproducing the content of the NOTICE file. 156 | 157 | 7. Disclaimer of Warranty. Unless required by applicable law or 158 | agreed to in writing, Licensor provides the Work (and each 159 | Contributor provides its Contributions) on an "AS IS" BASIS, 160 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 161 | implied, including, without limitation, any warranties or conditions 162 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 163 | PARTICULAR PURPOSE. You are solely responsible for determining the 164 | appropriateness of using or redistributing the Work and assume any 165 | risks associated with Your exercise of permissions under this License. 166 | 167 | 8. Limitation of Liability. In no event and under no legal theory, 168 | whether in tort (including negligence), contract, or otherwise, 169 | unless required by applicable law (such as deliberate and grossly 170 | negligent acts) or agreed to in writing, shall any Contributor be 171 | liable to You for damages, including any direct, indirect, special, 172 | incidental, or consequential damages of any character arising as a 173 | result of this License or out of the use or inability to use the 174 | Work (including but not limited to damages for loss of goodwill, 175 | work stoppage, computer failure or malfunction, or any and all 176 | other commercial damages or losses), even if such Contributor 177 | has been advised of the possibility of such damages. 178 | 179 | 9. Accepting Warranty or Additional Liability. While redistributing 180 | the Work or Derivative Works thereof, You may choose to offer, 181 | and charge a fee for, acceptance of support, warranty, indemnity, 182 | or other liability obligations and/or rights consistent with this 183 | License. However, in accepting such obligations, You may act only 184 | on Your own behalf and on Your sole responsibility, not on behalf 185 | of any other Contributor, and only if You agree to indemnify, 186 | defend, and hold each Contributor harmless for any liability 187 | incurred by, or claims asserted against, such Contributor by reason 188 | of your accepting any such warranty or additional liability. 189 | 190 | END OF TERMS AND CONDITIONS 191 | 192 | APPENDIX: How to apply the Apache License to your work. 193 | 194 | To apply the Apache License to your work, attach the following 195 | boilerplate notice, with the fields enclosed by brackets "{}" 196 | replaced with your own identifying information. (Don't include 197 | the brackets!) The text should be enclosed in the appropriate 198 | comment syntax for the file format. We also recommend that a 199 | file or class name and description of purpose be included on the 200 | same "printed page" as the copyright notice for easier 201 | identification within third-party archives. 202 | 203 | Copyright {yyyy} {name of copyright owner} 204 | 205 | Licensed under the Apache License, Version 2.0 (the "License"); 206 | you may not use this file except in compliance with the License. 207 | You may obtain a copy of the License at 208 | 209 | http://www.apache.org/licenses/LICENSE-2.0 210 | 211 | Unless required by applicable law or agreed to in writing, software 212 | distributed under the License is distributed on an "AS IS" BASIS, 213 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 214 | See the License for the specific language governing permissions and 215 | limitations under the License. 216 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/CycloneDX/cyclonedx-linux-generator/workflows/Maven%20CI/badge.svg)](https://github.com/CycloneDX/cyclonedx-linux-generator/actions?workflow=Maven+CI) 2 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.cyclonedx.contrib.com.lmco.efoss.unix.sbom/cyclonedx-linux-generator/badge.svg)](https://maven-badges.herokuapp.com/maven-central/org.cyclonedx.contrib.com.lmco.efoss.unix.sbom/cyclonedx-linux-generator) 3 | [![License](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)][License] 4 | [![Website](https://img.shields.io/badge/https://-cyclonedx.org-blue.svg)](https://cyclonedx.org/) 5 | [![Slack Invite](https://img.shields.io/badge/Slack-Join-blue?logo=slack&labelColor=393939)](https://cyclonedx.org/slack/invite) 6 | [![Group Discussion](https://img.shields.io/badge/discussion-groups.io-blue.svg)](https://groups.io/g/CycloneDX) 7 | [![Twitter](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Follow)](https://twitter.com/CycloneDX_Spec) 8 | 9 | 10 | # cyclonedx-linux-generator 11 | Lockheed Martin developed utility to generate CycloneDX SBOMs for Linux distributions 12 | 13 | This project creates a utility that users can utilize in generating Software Bill of Materials (SBom) file for Unix Operating Systems. It currently will create an SBOM for Alpine, Debian, Centos, Redhat and Ubuntu. 14 | 15 | This utility can also work well with docker containers who runs Alpine(*), Debian, Centos, Redhat or Ubuntu. 16 | 17 | Note: For Alpine you must have bash and java installed to run. 18 | 19 | ## Prerequisites 20 | - Open JDK11 21 | - Apache Maven 3.6.3 or greater installed 22 | - (Recommended) java IDE Eclipse with Subclipse 4.3.0 plug-in 23 | - Unix Based Operating System. 24 | 25 | ## Usage: 26 | 27 | ### To Build this project into an artifact via maven. 28 | ### Maven Command 29 |
30 |     mvn clean package
31 | 
32 | 33 | ### To Run 34 | To run as a standalone java application, you can look at the "start.sh" shell script for an example. 35 | You can also use the provided "start.sh" script as a pass through to the jar. It assumes all the basic settings. 36 | 37 | ### Help is available. 38 |
39 |     ./start.sh -h
40 | 
41 | 42 | ### Help Output shows options for running the SBomCombiner application. 43 |
44 | usage: help
45 |     -g, --group <arg>     (Optional) Group value to assign to top level component.
46 |     -h, --help            will print out the command line options.
47 |     -i, --image <arg>     (Optional) Docker Image file to use as top level component.
48 |     -n, --name <arg>      (Optional) Name value to assign to top level component.
49 |     -nc, --no-components  (Optional) Will only campture master component.  Will not include any components in the list of Components.
50 |      -v, --version <arg>  (Optional) Version value to assign to top level component.
51 | 
52 | 53 | ### Logging 54 | ### Logs 55 | "start.sh" script will create a directory for the logs (logs). 56 | 57 | ### Output 58 | ### bom.xml 59 | "start.sh" will create a directory (output) for the bom.xml file. 60 | 61 | Copyright & License 62 | ------------------- 63 | 64 | CycloneDX Linux Generator is Copyright (c) Lockheed Martin Corporation. All Rights Reserved. 65 | 66 | Permission to modify and redistribute is granted under the terms of the Apache 2.0 license. See the [License] file for the full license. 67 | 68 | [License]: https://github.com/CycloneDX/cyclonedx-linux-generator/blob/master/LICENSE 69 | -------------------------------------------------------------------------------- /logging/log4j.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.cyclonedx.contrib.com.lmco.efoss.unix.sbom 7 | linux-sbom-generator 8 | 3.1.0-SNAPSHOT 9 | linux-sbom-generator 10 | Unix SBOM Generator 11 | https://github.com/CycloneDX/cyclonedx-linux-generator 12 | 13 | 14 | 5.0.4 15 | 2.5.3 16 | 1.3 17 | 18 | 3.9.0 19 | 20 | 11 21 | 11 22 | UTF-8 23 | 24 | 25 | 26 | scm:git:git@github.com:CycloneDX/cyclonedx-linux-generator.git 27 | https://github.com/CycloneDX/cyclonedx-linux-generator.git 28 | scm:git:git@github.com:CycloneDX/cyclonedx-linux-generator.git 29 | HEAD 30 | 31 | 32 | 33 | GitHub 34 | https://github.com/CycloneDX/cyclonedx-linux-generator/issues 35 | 36 | 37 | 38 | GitHub 39 | https://github.com/CycloneDX/cyclonedx-linux-generator/actions 40 | 41 | 42 | 43 | 44 | ossrh 45 | https://oss.sonatype.org/content/repositories/snapshots 46 | 47 | 48 | ossrh 49 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 50 | 51 | 52 | 53 | 54 | 55 | maven-central 56 | https://repo1.maven.org/maven2 57 | 58 | 59 | 60 | ossrh-snapshot 61 | https://oss.sonatype.org/content/repositories/snapshots 62 | 63 | always 64 | true 65 | 66 | 67 | 68 | 69 | 70 | 71 | ossrh-snapshot 72 | https://oss.sonatype.org/content/repositories/snapshots 73 | 74 | always 75 | true 76 | 77 | 78 | always 79 | true 80 | 81 | 82 | 83 | 84 | 85 | 86 | org.cyclonedx.contrib.com.lmco.efoss.sbom 87 | sbom-commons 88 | 1.2.0-SNAPSHOT 89 | 90 | 91 | 92 | org.cyclonedx 93 | cyclonedx-core-java 94 | ${cyclonedx.core.java.version} 95 | 96 | 97 | 98 | org.jmockit 99 | jmockit 100 | 1.49 101 | 102 | 103 | org.apache.logging.log4j 104 | log4j-core 105 | 2.17.0 106 | 107 | 108 | junit 109 | junit 110 | 4.13.2 111 | 112 | 113 | com.google.guava 114 | guava 115 | 31.0.1-jre 116 | 117 | 118 | commons-io 119 | commons-io 120 | 2.11.0 121 | 122 | 123 | com.fasterxml.jackson.dataformat 124 | jackson-dataformat-xml 125 | 2.12.5 126 | 127 | 128 | org.mockito 129 | mockito-inline 130 | ${mockito.version} 131 | 132 | 133 | org.mockito 134 | mockito-junit-jupiter 135 | ${mockito.version} 136 | 137 | 138 | org.junit.jupiter 139 | junit-jupiter-api 140 | 141 | 142 | 143 | 144 | org.junit.jupiter 145 | junit-jupiter 146 | 5.8.1 147 | 148 | 149 | commons-cli 150 | commons-cli 151 | 1.4 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | org.cyclonedx 160 | cyclonedx-maven-plugin 161 | ${cyclonedx.maven.plugin.version} 162 | 163 | 164 | 165 | org.jacoco 166 | jacoco-maven-plugin 167 | 0.8.7 168 | 169 | 170 | 171 | maven-antrun-plugin 172 | 3.0.0 173 | 174 | 175 | maven-assembly-plugin 176 | 3.3.0 177 | 178 | 179 | maven-clean-plugin 180 | 3.1.0 181 | 182 | 183 | maven-compiler-plugin 184 | 3.8.1 185 | 186 | 187 | maven-dependency-plugin 188 | 3.2.0 189 | 190 | 191 | maven-release-plugin 192 | 2.5.3 193 | 194 | 195 | maven-deploy-plugin 196 | 2.8.2 197 | 198 | 199 | maven-enforcer-plugin 200 | 3.0.0 201 | 202 | 203 | maven-failsafe-plugin 204 | 2.22.2 205 | 206 | 207 | maven-help-plugin 208 | 3.2.0 209 | 210 | 211 | maven-install-plugin 212 | 2.5.2 213 | 214 | 215 | maven-invoker-plugin 216 | 3.2.2 217 | 218 | 219 | maven-jar-plugin 220 | 3.2.0 221 | 222 | 223 | maven-javadoc-plugin 224 | 3.3.1 225 | 226 | 227 | maven-resources-plugin 228 | 3.2.0 229 | 230 | 231 | maven-shade-plugin 232 | 3.2.4 233 | 234 | 235 | maven-source-plugin 236 | 3.2.1 237 | 238 | 239 | maven-surefire-plugin 240 | 2.22.2 241 | 242 | 243 | maven-war-plugin 244 | 3.3.2 245 | 246 | 247 | 248 | 249 | 250 | 251 | maven-clean-plugin 252 | 253 | 254 | 255 | logs/ 256 | 257 | **/* 258 | 259 | false 260 | 261 | 262 | output/ 263 | 264 | **/* 265 | 266 | false 267 | 268 | 269 | unitTests/ 270 | 271 | **/* 272 | 273 | false 274 | 275 | 276 | 277 | 278 | 279 | org.jacoco 280 | jacoco-maven-plugin 281 | 282 | 283 | 284 | prepare-agent 285 | 286 | 287 | 288 | report 289 | prepare-package 290 | 291 | report 292 | 293 | 294 | 295 | 296 | 297 | org.apache.maven.plugins 298 | maven-javadoc-plugin 299 | 300 | ${java.home}/bin 301 | 302 | 303 | 304 | attach-javadocs 305 | 306 | jar 307 | 308 | 309 | 310 | 311 | 312 | org.apache.maven.plugins 313 | maven-assembly-plugin 314 | 315 | 316 | jar-with-dependencies 317 | 318 | 319 | 320 | true 321 | org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.UnixSbomGeneratorApplication 322 | true 323 | true 324 | 325 | 326 | 327 | 328 | 329 | package 330 | 331 | single 332 | 333 | 334 | 335 | 336 | 337 | org.cyclonedx 338 | cyclonedx-maven-plugin 339 | 340 | 341 | verify 342 | 343 | makeAggregateBom 344 | 345 | 346 | 347 | 348 | library 349 | ${cyclonedx.schema.version} 350 | true 351 | true 352 | true 353 | true 354 | true 355 | true 356 | false 357 | all 358 | 359 | 360 | 361 | 362 | 363 | -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/UnixSbomGeneratorApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom; 11 | 12 | import java.util.Date; 13 | 14 | import org.apache.commons.cli.CommandLine; 15 | import org.apache.commons.cli.CommandLineParser; 16 | import org.apache.commons.cli.DefaultParser; 17 | import org.apache.commons.cli.HelpFormatter; 18 | import org.apache.commons.cli.Option; 19 | import org.apache.commons.cli.Options; 20 | import org.apache.log4j.Logger; 21 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 22 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator.SBomGenerator; 23 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.DateUtils; 24 | 25 | /** 26 | * (U) This Spring Boot application is used to build a Software Build Of Materials (SBOM) for a Unix 27 | * Virtual Machine (VM), regardless if it is Centos, Redhat, or Ubuntu. 28 | * 29 | * @author wrgoff 30 | * @since 22 April 2020 31 | */ 32 | public class UnixSbomGeneratorApplication 33 | { 34 | private static final Logger logger = Logger 35 | .getLogger(UnixSbomGeneratorApplication.class.getName()); 36 | 37 | 38 | /** 39 | * (U) Main method used to start the building of the linux operating system building of the 40 | * Software Bill Of Materials (SBOM). 41 | * 42 | * @param args String array of arguments. 43 | */ 44 | public static void main(String[] args) 45 | { 46 | int softwareProcessed = 0; 47 | 48 | Date startDate = DateUtils.rightNowDate(); 49 | boolean failed = false; 50 | 51 | CommandLineParser cliParser = new DefaultParser(); 52 | Options cliOptions = createCliOptions(); 53 | boolean runningHelp = false; 54 | try 55 | { 56 | CommandLine cli = cliParser.parse(cliOptions, args); 57 | if (cli.hasOption("help")) 58 | { 59 | runningHelp = true; 60 | HelpFormatter formatter = new HelpFormatter(); 61 | formatter.printHelp("help", cliOptions); 62 | } 63 | else 64 | { 65 | softwareProcessed = SBomGenerator.generateSBom(cli); 66 | } 67 | } 68 | catch (SBomException sbe) 69 | { 70 | logger.error(sbe.getMessage(), sbe); 71 | failed = true; 72 | } 73 | catch (Exception e) 74 | { 75 | failed = true; 76 | logger.error("Encountered an unexpected error while attempting to build the Software " + 77 | "Bill Of Materials for your operating system!", e); 78 | 79 | } 80 | finally 81 | { 82 | if (logger.isInfoEnabled()) 83 | { 84 | StringBuilder msg = new StringBuilder("It took " + DateUtils.computeDiff(startDate, 85 | DateUtils.rightNowDate())); 86 | if (failed) 87 | msg.append(" to fail to "); 88 | else 89 | msg.append(" to successfully "); 90 | 91 | if (runningHelp) 92 | msg.append("show the usage."); 93 | else 94 | { 95 | msg.append("build the Software Bill Of Materials (SBOM)!"); 96 | if (!failed) 97 | msg.append(" With " + softwareProcessed + " components!"); 98 | } 99 | logger.info(msg.toString()); 100 | } 101 | } 102 | } 103 | 104 | /** 105 | * (U) This method is used to create the valid options for command line usage. 106 | * 107 | * @return Options for use when running via command line. 108 | */ 109 | private static Options createCliOptions() 110 | { 111 | Options cliOptions = new Options(); 112 | cliOptions.addOption(new Option("h", "help", false, "will print out the command line " + 113 | "options.")); 114 | cliOptions.addOption(new Option("i", "image", true, 115 | "Docker Image file to use as top level component.")); 116 | cliOptions.addOption(new Option("g", "group", true, 117 | "Group value to assign to top level component.")); 118 | cliOptions.addOption(new Option("n", "name", true, 119 | "Name value to assign to top level component.")); 120 | cliOptions.addOption(new Option("v", "version", true, 121 | "Version value to assign to top level component.")); 122 | cliOptions.addOption(new Option("nc", "no-components", false, "Will only campture master " + 123 | "component. Will not include any components in the list of Components.")); 124 | 125 | return cliOptions; 126 | } 127 | 128 | } -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/exceptions/SBomException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions; 11 | 12 | /** 13 | * (U) This class is the Software Bill Of Materials (SBOM) Exception class. 14 | * 15 | * @author wrgoff 16 | * @since 22 April 2020 17 | */ 18 | public class SBomException extends RuntimeException 19 | { 20 | private static final long serialVersionUID = 8505738900643528230L; 21 | 22 | /** 23 | * (U) Constructs a new SBomException with null as its details. 24 | */ 25 | public SBomException() 26 | {} 27 | 28 | /** 29 | * (U) Constructs a new SBomException with the specified detail message. 30 | * 31 | * @param message String value to set the message to. 32 | */ 33 | public SBomException(String message) 34 | { 35 | super(message); 36 | } 37 | 38 | /** 39 | * (U) Constructs a new SBomException with the specified detail message and cause. 40 | * 41 | * @param message String value to set the message to. 42 | * @param cause Throwable class to set the cause to. 43 | */ 44 | public SBomException(String message, Throwable cause) 45 | { 46 | super(message, cause); 47 | } 48 | 49 | /** 50 | * (U) Constructs a new SBomException with the specified detail message, cause, suppression flag 51 | * set to either enabled or disabled, and the writable stack trace flag set to either enable or 52 | * disabled. 53 | * 54 | * @param message String value to set the message to. 55 | * @param cause Throwable class to set the cause to. 56 | * @param enableSuppression boolean used to set the enabled suppression flag to. 57 | * @param writeableStackTrace boolean used to set the write able stack trace flag to. 58 | */ 59 | public SBomException(String message, Throwable cause, boolean enableSuppression, 60 | boolean writeableStackTrace) 61 | { 62 | super(message, cause, enableSuppression, writeableStackTrace); 63 | } 64 | 65 | /** 66 | * (U) Constructs a new SBomException with the cause set. 67 | * 68 | * @param cause Throwable class to set the cause to. 69 | */ 70 | public SBomException(Throwable cause) 71 | { 72 | super(cause); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/AlpineSBomGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStreamReader; 15 | import java.util.List; 16 | import java.util.Map; 17 | 18 | import org.cyclonedx.model.Bom; 19 | import org.cyclonedx.model.Component; 20 | 21 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 22 | 23 | /** 24 | * (U) This class is responsible for generating the Software Bill Of Materials (SBOM) for all Alpine 25 | * Linux Operating Systems. Or any Linux operating systems using the APK package manager. 26 | * 27 | * @author wrgoff 28 | * @since 6 October 2020 29 | */ 30 | public class AlpineSBomGenerator extends UnixSBomGenerator 31 | { 32 | private static final CharSequence POLICY = "policy:"; 33 | // Unix Commands. 34 | private static final String PACKAGE_MANAGER = "apk"; 35 | private static final String SOFTWARE_DETAIL_CMD = "apk -vv info "; 36 | private static final String SOFTWARE_LIST_CMD = "apk info"; 37 | 38 | private static final String SOFTWARE_VERSION_CMD = "apk policy "; 39 | 40 | private ProcessBuilder processBuilder = new ProcessBuilder(); 41 | 42 | /** 43 | * (U) This method is used to generate the Software Bill Of Materials (SBOM) for all RedHat 44 | * Linux Operating systems. 45 | * 46 | * @return Bom The Software Bill Of Materials for this RedHat Linux Operating System. 47 | * @throws SBomException if we are unable to build the SBOM. 48 | */ 49 | public Bom generateSBom() 50 | { 51 | List softwareList = generateListOfSoftware(SOFTWARE_LIST_CMD, '\n', 52 | null); 53 | 54 | Bom bom = new Bom(); 55 | 56 | if (logger.isDebugEnabled()) 57 | logger.debug("Processing " + softwareList.size() + " software programs."); 58 | 59 | Map detailMap = null; 60 | String version = null; 61 | Component component = null; 62 | for (String software : softwareList) 63 | { 64 | if (logger.isDebugEnabled()) 65 | logger.debug("Generating Component (" + software + ")"); 66 | detailMap = produceDetailMap(software); 67 | version = getVersion(software); 68 | component = createComponents(software, detailMap, null, null, 69 | version, null, null); 70 | bom.addComponent(addPackageManager(component, PACKAGE_MANAGER)); 71 | } 72 | return bom; 73 | } 74 | 75 | /** 76 | * (U) This method is responsible for getting the version for a specific package. 77 | * @param software String value of the software to get the version for. 78 | * @return String the version of the software. 79 | * @throws SBomException if we are unable to run the command to get the version. 80 | */ 81 | public String getVersion(String software) 82 | { 83 | String version = null; 84 | 85 | String cmd = SOFTWARE_VERSION_CMD + software; 86 | 87 | processBuilder.command("bash", "-c", cmd); 88 | 89 | try 90 | { 91 | Process process = processBuilder.start(); 92 | version = parseVersion(process, cmd); 93 | } 94 | catch (IOException ioe) 95 | { 96 | String error = "Unable to build unix process to get software version (" + cmd + ")!"; 97 | logger.error(error, ioe); 98 | throw new SBomException(error, ioe); 99 | } 100 | return version; 101 | } 102 | 103 | /** 104 | * (U) This method is used to parse the version from the linux command that ran. 105 | * 106 | * @param reader BufferedReader to get the version from. 107 | * @return String the version associated with a piece of software. 108 | * @throws SBomException if we are unable to read the version from the reader. 109 | */ 110 | public String parseVersion(BufferedReader reader) 111 | { 112 | String version = null; 113 | 114 | try 115 | { 116 | String line; 117 | boolean foundStart = false; 118 | 119 | while ((line = reader.readLine()) != null) 120 | { 121 | if (!line.trim().startsWith("WARNING:")) 122 | { 123 | if (foundStart) 124 | { 125 | version = line.trim(); 126 | if (version.endsWith(":")) 127 | { 128 | version = version.substring(0, version.length() - 1); 129 | } 130 | break; 131 | } 132 | if (line.contains(POLICY)) 133 | foundStart = true; 134 | } 135 | } 136 | } 137 | catch (IOException ioe) 138 | { 139 | String error = "Unable to process output from unix process to get version for a " + 140 | "specific piece of software."; 141 | logger.error(error, ioe); 142 | throw new SBomException(error, ioe); 143 | } 144 | return version; 145 | } 146 | 147 | /** 148 | * (U) This method is used to parse the version from a process created from a Unix command. 149 | * 150 | * @param process Process to pull the version from. 151 | * @param cmd String value of the Unix command that was run. 152 | * @return String the version pulled from the output of the unix command that was run. 153 | * @throws SBomException in the event we are unable to complete the processing of the unix 154 | * command. 155 | */ 156 | public String parseVersion(Process process, String cmd) 157 | { 158 | String version = null; 159 | 160 | try (BufferedReader reader = new BufferedReader( 161 | new InputStreamReader(process.getInputStream()))) 162 | { 163 | version = parseVersion(reader); 164 | 165 | int exitVal = process.waitFor(); 166 | if (exitVal != 0) 167 | { 168 | String error = "Unexpected process exit value (" + exitVal + "), while " + 169 | "attempting to get Software Version (" + cmd + ")!"; 170 | logger.error(error); 171 | throw new SBomException(error); 172 | } 173 | } 174 | catch (SBomException sbom) 175 | { 176 | throw sbom; 177 | } 178 | catch (Exception e) 179 | { 180 | String error = "Unexpected error while attempting to software version (" + cmd + 181 | ")!"; 182 | logger.error(error, e); 183 | throw new SBomException(error, e); 184 | } 185 | return version; 186 | } 187 | 188 | /** 189 | * (U) This method is used to produce a Detail Map of the Software in question. This will be 190 | * used to create a CycloneDx Component. 191 | * 192 | * @param software String value of the component to build the detail map for. 193 | * @return Map containing the key value pairs about the software. 194 | * @throws SBomException in the event we can NOT produce the detail map of the software. 195 | */ 196 | private Map produceDetailMap(String software) 197 | { 198 | String cmd = SOFTWARE_DETAIL_CMD + software; 199 | 200 | return (produceDetailMap(cmd, AVAILABLE_LINUX_FLAVORS.ALPINE)); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/RedHatSBomGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.File; 14 | import java.io.IOException; 15 | import java.io.InputStreamReader; 16 | import java.nio.file.Files; 17 | import java.nio.file.Paths; 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | import org.cyclonedx.model.Bom; 23 | import org.cyclonedx.model.Component; 24 | import org.cyclonedx.model.LicenseChoice; 25 | 26 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 27 | 28 | /** 29 | * * (U) This class is responsible for generating the Software Bill Of Materials (SBOM) for all 30 | * Oracle Red Hat Linux Operating Systems. 31 | * 32 | * @author wrgoff 33 | * @since 24 April 2020 34 | */ 35 | public class RedHatSBomGenerator extends UnixSBomGenerator 36 | { 37 | private static final List POSSIBLE_LICENSE_FILES = new ArrayList<>( 38 | List.of("LICENSE.txt", 39 | "LICENSE", "COPYING", "COPYING.LGPL", "PORTING", "Copying")); 40 | 41 | private static final String PACKAGE_MANAGER = "yum"; 42 | 43 | // Unix Commands. 44 | private static final String PURL_CMD = "yumdownloader --urls"; 45 | private static final String SOFTWARE_DETAIL_CMD = "yum info"; 46 | private static final String SOFTWARE_LIST_CMD = "yum list installed"; 47 | 48 | private ProcessBuilder processBuilder = new ProcessBuilder(); 49 | 50 | /** 51 | * (U) This method is used to generate the Software Bill Of Materials (SBOM) for all RedHat 52 | * Linux Operating systems. 53 | * 54 | * @return Bom The Software Bill Of Materials for this RedHat Linux Operating System. 55 | * @throws SBomException if we are unable to build the SBOM. 56 | */ 57 | public Bom generateSBom() 58 | { 59 | List softwareList = generateListOfSoftware(SOFTWARE_LIST_CMD, ' ', 60 | "Installed Packages"); 61 | 62 | Bom bom = new Bom(); 63 | 64 | if (logger.isDebugEnabled()) 65 | logger.debug("Processing " + softwareList.size() + " software programs."); 66 | 67 | Map detailMap = null; 68 | String version = null; 69 | String group = null; 70 | LicenseChoice license = null; 71 | String purl = null; 72 | Component component = null; 73 | for (String software : softwareList) 74 | { 75 | if (logger.isDebugEnabled()) 76 | logger.debug("Generating Component (" + software + ")"); 77 | detailMap = produceDetailMap(software); 78 | version = detailMap.get("Version"); 79 | group = detailMap.get("Release"); 80 | license = processLicense(software, version); 81 | purl = getPurl(software); 82 | component = createComponents(software, detailMap, license, group, 83 | version, purl, detailMap.get("Priority")); 84 | bom.addComponent(addPackageManager(component, PACKAGE_MANAGER)); 85 | } 86 | return bom; 87 | } 88 | 89 | /** 90 | * (U) This method is used to attempt to figure out which file is the license file. If any. 91 | * 92 | * @param software String value of the software we are attempting to get the license file for. 93 | * @param version String value of the version of the software we are attempting to get the 94 | * license for. 95 | * @return String if NOT null contains a file name, which should be the license file. 96 | */ 97 | public String getLicenseFileName(String software, String version) 98 | { 99 | File tempFile = null; 100 | 101 | software = software.trim(); 102 | 103 | if (software.endsWith(".x86_64")) 104 | software = software.replace(".x86_64", ""); 105 | 106 | if (version != null) 107 | software = software + "-" + version.trim(); 108 | 109 | if (logger.isDebugEnabled()) 110 | logger.debug("Attempting to get license file from " + SOFTWARE_LICENSE_DIR + software + 111 | "."); 112 | 113 | for (String fileToTry : POSSIBLE_LICENSE_FILES) 114 | { 115 | tempFile = new File(SOFTWARE_LICENSE_DIR + software, fileToTry); 116 | if (tempFile.exists()) 117 | return (SOFTWARE_LICENSE_DIR + software + "/" + fileToTry); 118 | } 119 | return null; 120 | } 121 | 122 | /** 123 | * (U) This method is used to get the Product Uniform Resource Locator (PURL) or as we know it 124 | * the download Uniform Resource Locator (URL). 125 | * 126 | * @param software String value of the software to get the PURL for. 127 | * @return String the URL that will be used to download this software product. 128 | * @throws SBomException in the event we are unable to get the PURL from the server. 129 | */ 130 | public String getPurl(String software) 131 | { 132 | String purl = null; 133 | 134 | String cmd = PURL_CMD + " " + software; 135 | 136 | processBuilder.command("bash", "-c", cmd); 137 | 138 | if (logger.isDebugEnabled()) 139 | logger.debug("Attempting to get PURL for " + software + "."); 140 | 141 | try 142 | { 143 | Process process = processBuilder.start(); 144 | purl = parsePurl(process, software); 145 | } 146 | catch (IOException ioe) 147 | { 148 | String error = "Unable to build unix process to get software package's PURL (" + cmd + 149 | ")!"; 150 | logger.error(error, ioe); 151 | throw new SBomException(error, ioe); 152 | } 153 | return purl; 154 | } 155 | 156 | /** 157 | * (U) This method is used to parse the PURL from the output of the command process. 158 | * 159 | * @param process Process that is running the YUM command. 160 | * @param software String value of the software, used for debugging purposes. 161 | * @return String the PURL if available. 162 | * @throws SBomException if we are unable to process the output of the YUM command. 163 | */ 164 | public String parsePurl(Process process, String software) 165 | { 166 | String purl = null; 167 | 168 | try (BufferedReader reader = new BufferedReader( 169 | new InputStreamReader(process.getInputStream()))) 170 | { 171 | purl = parsePurlCmdOutput(reader); 172 | 173 | if (purl == null) 174 | logger.warn("No PURL found for software package (" + software + ")."); 175 | 176 | int exitVal = process.waitFor(); 177 | if (exitVal != 0) 178 | { 179 | String error = "Unexpected process exit value (" + exitVal + "), while " + 180 | "attempting to get a software package's (" + software + ")!"; 181 | logger.warn(error); 182 | } 183 | } 184 | catch (SBomException sbom) 185 | { 186 | throw sbom; 187 | } 188 | catch (Exception e) 189 | { 190 | String error = "Unexpected error while attempting to lookup a software " + 191 | "package's (" + software + ")!"; 192 | logger.error(error, e); 193 | throw new SBomException(error, e); 194 | } 195 | return purl; 196 | } 197 | 198 | /** 199 | * (U) This method is used to parse the Unix Command Output to get the download Uniform Resource 200 | * Locator (URL) also known as the Product Uniform Resource Locator (PURL) 201 | * 202 | * @param reader BufferedReader to parse the output form. 203 | * @return String the PURL or download URL that can be used to download the software package. 204 | * @throws SBomException in the event we are unable to parse the command's output. 205 | */ 206 | public String parsePurlCmdOutput(BufferedReader reader) 207 | { 208 | String purl = null; 209 | try 210 | { 211 | String line; 212 | boolean found = false; 213 | while (((line = reader.readLine()) != null) && (!found)) 214 | { 215 | if (line.startsWith("http")) 216 | { 217 | purl = line.trim(); 218 | found = true; 219 | } 220 | else if (line.startsWith("No Match for argument")) // No PURL found. 221 | { 222 | found = true; 223 | } 224 | } 225 | } 226 | catch (IOException ioe) 227 | { 228 | String error = "Unable to process output from unix process to get the Package " + 229 | "download URL."; 230 | logger.error(error, ioe); 231 | throw new SBomException(error, ioe); 232 | } 233 | return purl; 234 | } 235 | 236 | /** 237 | * (U) This method is responsible for getting the license (if present) and placing it in the 238 | * LicenseChoice Object passed back. 239 | * 240 | * @param software String value of the software we are attempting to get the license for. 241 | * @param version String value of the version of the software we are attempting to get the 242 | * license for. 243 | * @return LicenseChoice that contains information about the license. 244 | */ 245 | private LicenseChoice processLicense(String software, String version) 246 | { 247 | if (logger.isDebugEnabled()) 248 | logger.debug("Attempting to get license file for " + software + "."); 249 | 250 | LicenseChoice licenseChoice = null; 251 | 252 | String licenseFile = getLicenseFileName(software, version); 253 | 254 | try 255 | { 256 | if (licenseFile != null) 257 | { 258 | if (logger.isDebugEnabled()) 259 | logger.debug("Attempting to process license (" + licenseFile + ")"); 260 | 261 | String licenseTxt = new String(Files.readAllBytes(Paths.get(licenseFile))); 262 | licenseChoice = parseLicenseText(licenseTxt, AVAILABLE_LINUX_FLAVORS.REDHAT); 263 | } 264 | else 265 | logger.warn("Unable to find suitable license file for " + software + "."); 266 | } 267 | catch (IOException ioe) 268 | { 269 | logger.warn("Unable to read license file (" + licenseFile + ")", ioe); 270 | } 271 | return licenseChoice; 272 | } 273 | 274 | /** 275 | * (U) This method is used to produce a Detail Map of the Software in question. This will be 276 | * used to create a CycloneDx Component. 277 | * 278 | * @param software String value of the component to build the detail map for. 279 | * @return Map containing the key value pairs about the software. 280 | * @throws SBomException in the event we can NOT produce the detail map of the software. 281 | */ 282 | private Map produceDetailMap(String software) 283 | { 284 | String cmd = SOFTWARE_DETAIL_CMD + " " + software; 285 | 286 | return (produceDetailMap(cmd, AVAILABLE_LINUX_FLAVORS.REDHAT)); 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/SBomGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.File; 13 | import java.io.FileWriter; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.net.MalformedURLException; 17 | import java.net.URL; 18 | import java.nio.file.Files; 19 | import java.nio.file.Paths; 20 | import java.nio.file.StandardCopyOption; 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | import java.util.TreeMap; 24 | 25 | import org.apache.commons.cli.CommandLine; 26 | import org.apache.log4j.Logger; 27 | import org.cyclonedx.CycloneDxSchema; 28 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.utils.DateUtils; 29 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.utils.SBomCommons; 30 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.utils.SBomCommonsException; 31 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.utils.StringUtils; 32 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 33 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.OperatingSystemUtils; 34 | import org.cyclonedx.model.Bom; 35 | import org.cyclonedx.model.Component; 36 | import org.cyclonedx.model.Hash; 37 | import org.cyclonedx.model.Metadata; 38 | import org.cyclonedx.model.Tool; 39 | import org.cyclonedx.util.BomUtils; 40 | 41 | import com.github.packageurl.MalformedPackageURLException; 42 | import com.github.packageurl.PackageURL; 43 | 44 | /** 45 | * (U) This class is responsible for the actual generation of the Software Bill Of Materials (SBOM) 46 | * of the Unix operating system. 47 | * 48 | * @author wrgoff 49 | * @since 22 April 2020 50 | */ 51 | public class SBomGenerator 52 | { 53 | private static final CharSequence ALPINE = "ALPINE"; 54 | 55 | private static final CharSequence DEBIAN = "DEBIAN"; 56 | private static final Logger logger = Logger.getLogger(SBomGenerator.class.getName()); 57 | private static final CharSequence UBUNTU = "UBUNTU"; 58 | 59 | private static final String dockerImageFile = "DockerImage"; 60 | 61 | /** 62 | * Constructor. 63 | */ 64 | private SBomGenerator() 65 | { 66 | } 67 | 68 | /** 69 | * (U) This method is used to create the Tools, and add the UnixSBomGenerator to 70 | * the list of tools. 71 | * 72 | * @param bom Software Bom to add the UnixSbomGenerator Tool to. 73 | */ 74 | public static void addBomTools(Bom bom) 75 | { 76 | Metadata metadata = new Metadata(); 77 | metadata.setTimestamp(DateUtils.rightNowDate()); 78 | 79 | Tool unixSbomGenerator = new Tool(); 80 | unixSbomGenerator.setName("UnixSBomGenerator"); 81 | unixSbomGenerator.setVendor("Lockheed Martin"); 82 | 83 | String version = "unknown"; 84 | try 85 | { 86 | String path = SBomGenerator.class.getProtectionDomain().getCodeSource().getLocation() 87 | .getPath(); 88 | 89 | String jarSub = "UnixSbomGenerator-"; 90 | int index = path.indexOf(jarSub); 91 | int endIndex = path.indexOf(".jar"); 92 | 93 | version = path.substring(index + jarSub.length(), endIndex); 94 | } 95 | catch (Exception e) 96 | { 97 | logger.warn("Unable to determine verison of UnixSBomGenerator Tool!"); 98 | } 99 | unixSbomGenerator.setVersion(version); 100 | List completeToolList = new ArrayList<>(); 101 | completeToolList.add(unixSbomGenerator); 102 | 103 | metadata.setTools(completeToolList); 104 | 105 | bom.setMetadata(metadata); 106 | } 107 | 108 | /** 109 | * (U) This method creates the file and places the contents in the file. 110 | * 111 | * @param bom Bill of Materials to put in the file. 112 | * @param format Enumeration that tell us which file we are producing. 113 | * @throws SBomException if we are unable to produce the file. 114 | */ 115 | public static void createBomFile(Bom bom, SBomCommons.AVAILABLE_FORMATS format) 116 | { 117 | File file = new File("output/bom." + format.toString().toLowerCase()); 118 | try (FileWriter writer = new FileWriter(file)) 119 | { 120 | writer.write(SBomCommons.generateOutputString(bom, format)); 121 | } 122 | catch (SBomCommonsException sce) 123 | { 124 | logger.error(sce); 125 | throw new SBomException(sce); 126 | } 127 | catch (IOException ioe) 128 | { 129 | String error = "Unable to write to " + format.toString() + " SBOM File!"; 130 | logger.error(error, ioe); 131 | throw new SBomException(error); 132 | } 133 | } 134 | 135 | /** 136 | * (U) This method prepares the master Component. 137 | * 138 | * @param imageUrl String value of where go get the image from. 139 | * @param name String value of the name if supplied. 140 | * @param group String value of the group if supplied. 141 | * @param version String value of the version if supplied. 142 | * @return Component, either null if no imageUrl, name, group, or version are 143 | * supplied. Else it will be filled in. 144 | * @throws SBomException in the event we are unable to pull the image from the 145 | * imageUrl provided. 146 | */ 147 | public static Component createMasterComponent(String imageUrl, String name, 148 | String group, String version) throws SBomException 149 | { 150 | Component master = null; 151 | if ((StringUtils.isValid(imageUrl)) || 152 | (StringUtils.isValid(name) && ((StringUtils.isValid(version))))) 153 | { 154 | master = createMasterComponent(imageUrl); 155 | 156 | if (StringUtils.isValid(imageUrl)) 157 | { 158 | TreeMap qualifiers = new TreeMap<>(); 159 | qualifiers.put("repository_url", getBaseUrl(imageUrl)); 160 | qualifiers.put("type", "image"); 161 | try 162 | { 163 | PackageURL packageUrl = new PackageURL( 164 | PackageURL.StandardTypes.DOCKER, null, 165 | name.toLowerCase(), version, qualifiers, 166 | getSubPath(imageUrl)); 167 | master.setPurl(packageUrl); 168 | master.setBomRef(master.getPurl()); 169 | } 170 | catch (MalformedPackageURLException e) 171 | { 172 | String error = "Failed to build the Package URL!"; 173 | logger.error(error, e); 174 | throw new SBomException(error); 175 | } 176 | } 177 | if (StringUtils.isValid(name)) 178 | master.setName(name.toLowerCase()); 179 | if (StringUtils.isValid(group)) 180 | master.setGroup(group.toLowerCase()); 181 | if (StringUtils.isValid(version)) 182 | master.setVersion(version); 183 | } 184 | 185 | return master; 186 | } 187 | 188 | /** 189 | * (U) This method is used to generate the XML and JSon files containing the Software Bill of 190 | * Materials. 191 | * 192 | * @param bom Bill of Materials to create the files form. 193 | * @throws SBomException in the event we can NOT create either the XML of JSon files. 194 | */ 195 | public static void generateBoms(Bom bom) 196 | { 197 | try 198 | { 199 | if (logger.isDebugEnabled()) 200 | logger.debug("Generating bom.xml file from bom entries"); 201 | 202 | Files.createDirectories(Paths.get("output")); 203 | 204 | createBomFile(bom, SBomCommons.AVAILABLE_FORMATS.XML); 205 | createBomFile(bom, SBomCommons.AVAILABLE_FORMATS.JSON); 206 | } 207 | catch (IOException ioe) 208 | { 209 | String error = "Unable to create ouptut directory!"; 210 | logger.error(error, ioe); 211 | throw new SBomException(error); 212 | } 213 | } 214 | 215 | /** 216 | * (U) This method is used to generate the Software Bill Of Materials (SBOM) for 217 | * this operating system. 218 | * 219 | * @param cli CommandLine arguments. 220 | * @return int the number of programs found within the operating system. 221 | * @throws SBomException if we are unable to build the SBOM. 222 | */ 223 | public static int generateSBom(CommandLine cli) 224 | { 225 | OperatingSystemUtils osUtils = new OperatingSystemUtils(); 226 | String vendor = osUtils.getOsVendor(); 227 | 228 | if (logger.isDebugEnabled()) 229 | logger.debug("Attempting to build SBOM for " + vendor + "."); 230 | 231 | Component master = createMasterComponent(cli); 232 | 233 | Bom bom = null; 234 | 235 | int softwareSize = 0; 236 | 237 | if (cli.hasOption("nc")) 238 | { 239 | bom = new Bom(); 240 | bom.setComponents(new ArrayList()); 241 | } 242 | else 243 | { 244 | if (vendor.toUpperCase().trim().contains(ALPINE)) 245 | { 246 | if (logger.isInfoEnabled()) 247 | logger.info(vendor + ", uses the APK package manager."); 248 | AlpineSBomGenerator generator = new AlpineSBomGenerator(); 249 | bom = generator.generateSBom(); 250 | } 251 | else if ((vendor.toUpperCase().trim().contains(UBUNTU)) || 252 | (vendor.toUpperCase().trim().contains(DEBIAN))) 253 | { 254 | if (logger.isInfoEnabled()) 255 | logger.info(vendor + ", uses the APT package manager."); 256 | UbuntuSBomGenerator generator = new UbuntuSBomGenerator(); 257 | bom = generator.generateSBom(); 258 | } 259 | else 260 | { 261 | if (logger.isInfoEnabled()) 262 | logger.info(vendor + ", assuming it is a redhat flavor (Yum Package Manager)."); 263 | RedHatSBomGenerator generator = new RedHatSBomGenerator(); 264 | bom = generator.generateSBom(); 265 | } 266 | } 267 | 268 | if(bom != null) 269 | { 270 | addBomTools(bom); 271 | bom.getMetadata().setComponent(master); 272 | softwareSize = bom.getComponents().size(); 273 | generateBoms(bom); 274 | } 275 | return softwareSize; 276 | } 277 | 278 | /** 279 | * (U) This method is responsible for build the Master Component (upper level 280 | * Component). 281 | * 282 | * @param cli ComandLine options used to build the master component. 283 | * @return Component newly created master component. 284 | * @throws SBomException in the event we are unable to get the image from the 285 | * image URL (if it was provided). 286 | */ 287 | private static Component createMasterComponent(CommandLine cli) throws SBomException 288 | { 289 | Component master = null; 290 | 291 | String imageUrl = cli.getOptionValue("image"); 292 | String name = cli.getOptionValue("name"); 293 | String group = cli.getOptionValue("group"); 294 | String version = cli.getOptionValue("version"); 295 | 296 | if ((!StringUtils.isValid(name)) || (!StringUtils.isValid(version))) 297 | { 298 | OperatingSystemUtils osUtils = new OperatingSystemUtils(); 299 | 300 | if (!StringUtils.isValid(name)) 301 | name = osUtils.getOsVendor(); 302 | if (!StringUtils.isValid(version)) 303 | version = osUtils.getOsVersion(); 304 | } 305 | 306 | master = createMasterComponent(imageUrl, name, group, version); 307 | 308 | return master; 309 | } 310 | 311 | /** 312 | * (U) This method is used to create the master component. It will then fill in 313 | * the image information (if provided). 314 | * 315 | * @param imageUrl String value of where to get the docker image from. 316 | * @return Component created, and filled in if the imageUrl is provided. 317 | * @throws SBomException in the event we are unable to pull the image via the 318 | * image URL provided. 319 | */ 320 | private static Component createMasterComponent(String imageUrl) throws SBomException 321 | { 322 | Component master = new Component(); 323 | master.setType(org.cyclonedx.model.Component.Type.CONTAINER); 324 | 325 | if (StringUtils.isValid(imageUrl)) 326 | { 327 | logger.debug("Attempting to pull docker image(" + imageUrl + ")!"); 328 | if (!imageUrl.startsWith("http")) 329 | imageUrl = "https://" + imageUrl; 330 | 331 | try (InputStream in = new URL(imageUrl).openStream()) 332 | { 333 | Files.copy(in, Paths.get(dockerImageFile), StandardCopyOption.REPLACE_EXISTING); 334 | 335 | List hashes = BomUtils.calculateHashes( 336 | Paths.get(dockerImageFile).toFile(), 337 | CycloneDxSchema.Version.VERSION_13); 338 | master.setHashes(hashes); 339 | } 340 | catch (MalformedURLException e) 341 | { 342 | String error = "Failed to build hashes from image url (" + 343 | imageUrl + ")!"; 344 | logger.error(error, e); 345 | throw new SBomException(error); 346 | } 347 | catch (IOException e) 348 | { 349 | String error = "Failed to build hashes from File pulled from image " + 350 | "url (" + imageUrl + ")!"; 351 | logger.error(error, e); 352 | throw new SBomException(error); 353 | } 354 | finally 355 | { 356 | try 357 | { 358 | Files.delete(Paths.get(dockerImageFile)); 359 | } 360 | catch (IOException e) 361 | { 362 | logger.warn("Failed to delete Docker image file!"); 363 | } 364 | } 365 | } 366 | return master; 367 | } 368 | 369 | /** 370 | * (U) This method is used to get the Base URL that will be used to build the 371 | * package URL. 372 | * 373 | * @param imageUrl String value of where to get the image from. 374 | * @return String the Base URL, that will be used to build the package URL. 375 | */ 376 | private static String getBaseUrl(String imageUrl) 377 | { 378 | String baseUrl = imageUrl; 379 | 380 | if (imageUrl.contains("/")) 381 | baseUrl = baseUrl.substring(0, baseUrl.indexOf('/')); 382 | 383 | return baseUrl; 384 | } 385 | 386 | /** 387 | * (U) This method is used to get the Sub path that will be used to build the 388 | * Package URL. 389 | * 390 | * @param imageUrl String value of where to get the image from. 391 | * @return String the sub path used to build the package URL. 392 | */ 393 | private static String getSubPath(String imageUrl) 394 | { 395 | String subPath = null; 396 | 397 | if (imageUrl.contains("/")) 398 | { 399 | int startIndex = imageUrl.indexOf('/'); 400 | int endIndex = imageUrl.indexOf('/', startIndex + 1); 401 | if ((startIndex > 0) && (endIndex > 0)) 402 | subPath = imageUrl.substring(startIndex + 1, endIndex); 403 | } 404 | 405 | return subPath; 406 | } 407 | } -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/UbuntuSBomGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStreamReader; 15 | import java.nio.file.Files; 16 | import java.nio.file.Paths; 17 | import java.util.List; 18 | import java.util.Map; 19 | 20 | import org.cyclonedx.model.Bom; 21 | import org.cyclonedx.model.Component; 22 | import org.cyclonedx.model.LicenseChoice; 23 | 24 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 25 | 26 | /** 27 | * (U) This class is responsible for generating the Software Bill Of Materials (SBOM) for all Ubuntu 28 | * Linux Operating Systems. 29 | * 30 | * @author wrgoff 31 | * @since 23 April 2020 32 | */ 33 | public class UbuntuSBomGenerator extends UnixSBomGenerator 34 | { 35 | private static final String PACKAGE_MANAGER = "apt"; 36 | 37 | private static final String SOFTWARE_INSTALLED_VERSION = "apt policy"; 38 | private static final String SOFTWARE_DETAIL_CMD = "apt show"; 39 | public static final String SOFTWARE_LIST_CMD = "apt list --installed"; 40 | 41 | private ProcessBuilder processBuilder = new ProcessBuilder(); 42 | 43 | /** 44 | * (U) This method is used to generate the Software Bill Of Materials (SBOM) for all Ubuntu 45 | * Linux Operating systems. 46 | * 47 | * @return Bom The Software Bill Of Materials for this Ubuntu Linux Operating System. 48 | * @throws SBomException if we are unable to build the SBOM. 49 | */ 50 | public Bom generateSBom() 51 | { 52 | List softwareList = generateListOfSoftware(SOFTWARE_LIST_CMD, '/', 53 | ""); 54 | 55 | Bom bom = new Bom(); 56 | 57 | if (logger.isDebugEnabled()) 58 | logger.debug("Processing " + softwareList.size() + " software programs."); 59 | 60 | Map detailMap = null; 61 | String version = null; 62 | String group = null; 63 | LicenseChoice license = null; 64 | Component component = null; 65 | for (String software : softwareList) 66 | { 67 | if (logger.isDebugEnabled()) 68 | logger.debug("Generating Component (" + software + ")"); 69 | detailMap = produceDetailMap(software); 70 | version = detailMap.get("Version"); 71 | group = detailMap.get("Release"); 72 | license = processLicense(software); 73 | component = createComponents(software, detailMap, license, group, 74 | version, null, detailMap.get("Priority")); 75 | bom.addComponent(addPackageManager(component, PACKAGE_MANAGER)); 76 | } 77 | 78 | return bom; 79 | } 80 | 81 | /** 82 | * (U) This method is used to run the command to get the version of the package that is 83 | * currently installed. 84 | * 85 | * @param software String value of the software package to get the version of. 86 | * @return String value of the version of the software that is currently installed. 87 | * @throws SBomException in the event we can NOT get the version. 88 | */ 89 | public String getInstalledVersion(String software) 90 | { 91 | String version = ""; 92 | 93 | String cmd = SOFTWARE_INSTALLED_VERSION + " " + software; 94 | 95 | if (logger.isDebugEnabled()) 96 | logger.debug("Attempting to get software (" + software + ") version via: " + cmd); 97 | 98 | processBuilder.command("bash", "-c", cmd); 99 | 100 | try 101 | { 102 | Process process = processBuilder.start(); 103 | 104 | version = readVersion(process); 105 | } 106 | catch (IOException ioe) 107 | { 108 | String error = "Unable to build unix process to get software version (" + 109 | cmd + 110 | ") on the server!"; 111 | logger.error(error, ioe); 112 | throw new SBomException(error, ioe); 113 | } 114 | 115 | if (logger.isDebugEnabled()) 116 | logger.debug("Found Version (" + version + ") for " + software + "."); 117 | 118 | return version; 119 | } 120 | 121 | /** 122 | * (U) This method is used to parse the version from the reader of the Unix Command being run. 123 | * 124 | * @param reader BufferedReader of the contents of the Unix command being run. 125 | * @return String the version pulled from the reader. 126 | * @throws SBomException in the event we are unable to read from the Unix Command. 127 | */ 128 | public String parseVersion(BufferedReader reader) 129 | { 130 | String version = null; 131 | 132 | String line; 133 | try 134 | { 135 | while ((line = reader.readLine()) != null) 136 | { 137 | line = line.trim(); 138 | if (line.startsWith("Installed")) 139 | { 140 | int index = line.indexOf(':'); 141 | version = line.substring(index + 1).trim(); 142 | break; 143 | } 144 | } 145 | } 146 | catch (IOException e) 147 | { 148 | String error = "Failed to read version."; 149 | logger.error(error, e); 150 | throw new SBomException(error, e); 151 | } 152 | return version; 153 | } 154 | 155 | /** 156 | * (U) This method is responsible for getting the license (if present) and placing it in the 157 | * LicenseChoice Object passed back. 158 | * 159 | * @param software String value of the software we are attempting to get the license for. 160 | * @return LicenseChoice that contains information about the license. 161 | */ 162 | private LicenseChoice processLicense(String software) 163 | { 164 | LicenseChoice licenseChoice = null; 165 | 166 | String licenseFile = SOFTWARE_LICENSE_DIR + software + "/copyright"; 167 | 168 | if (logger.isDebugEnabled()) 169 | logger.debug("Attempting to process license (" + licenseFile + ")"); 170 | 171 | try 172 | { 173 | String licenseTxt = new String(Files.readAllBytes(Paths.get(licenseFile))); 174 | licenseChoice = parseLicenseText(licenseTxt, AVAILABLE_LINUX_FLAVORS.UBUNTU); 175 | } 176 | catch (IOException ioe) 177 | { 178 | logger.warn("Unable to read license file (" + licenseFile + ")", ioe); 179 | } 180 | return licenseChoice; 181 | } 182 | 183 | /** 184 | * (U) This method is used to produce a Detail Map of the Software in question. This will be 185 | * used to create a CycloneDx Component. 186 | * 187 | * @param software String value of the component to build the detail map for. 188 | * @return Map containing the key value pairs about the software. 189 | * @throws SBomException in the event we can NOT produce the detail map of the software. 190 | */ 191 | private Map produceDetailMap(String software) 192 | { 193 | String cmd = SOFTWARE_DETAIL_CMD + " " + software + "=" + getInstalledVersion(software); 194 | 195 | return (produceDetailMap(cmd, AVAILABLE_LINUX_FLAVORS.UBUNTU)); 196 | } 197 | 198 | /** 199 | * (U) This method is used to read the Version from the Command Process. 200 | * 201 | * @param process Process to read the version from. 202 | * @return String the version. 203 | * @throws SBomException in the event we are unable to process the command. 204 | */ 205 | public String readVersion(Process process) 206 | { 207 | String version = null; 208 | try (BufferedReader reader = new BufferedReader( 209 | new InputStreamReader(process.getInputStream()))) 210 | { 211 | version = parseVersion(reader); 212 | 213 | int exitVal = process.waitFor(); 214 | if (exitVal != 0) 215 | { 216 | String error = "Unexpected process exit value (" + exitVal + "), while " + 217 | "attempting to get Installed Software Version!"; 218 | logger.error(error); 219 | throw new SBomException(error); 220 | } 221 | } 222 | catch (SBomException sbom) 223 | { 224 | throw sbom; 225 | } 226 | catch (Exception e) 227 | { 228 | String error = "Unexpected error while attempting to get the software version!"; 229 | logger.error(error, e); 230 | throw new SBomException(error, e); 231 | } 232 | return version; 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/utils/DateUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils; 11 | 12 | import java.text.SimpleDateFormat; 13 | import java.util.ArrayList; 14 | import java.util.Calendar; 15 | import java.util.Collections; 16 | import java.util.Date; 17 | import java.util.EnumSet; 18 | import java.util.List; 19 | import java.util.Map; 20 | import java.util.Objects; 21 | import java.util.Set; 22 | import java.util.TimeZone; 23 | import java.util.TreeMap; 24 | import java.util.concurrent.TimeUnit; 25 | 26 | /** 27 | * (U) This utility class contains utilities for the manipulation of Dates. 28 | * 29 | * @author wrgoff 30 | * @since 22 April 2020 31 | */ 32 | public class DateUtils 33 | { 34 | public enum TimeZoneLocale 35 | { 36 | GMT, LOCAL 37 | } 38 | 39 | private static final String DATE_FORMAT_PATTERN = "yyyy MM dd HH:mm:ss.SSS"; 40 | 41 | 42 | /** 43 | * (U) This method is used to compute the difference between dates. It produces a nice readable formatted 44 | * String. 45 | * 46 | * @param date1 Date to compare to the second date passed in. 47 | * @param date2 Date to compare to the first date passed in. 48 | * @return String a nicely formatted human readable string stating the difference between date 1 and date 2 49 | * passed in. 50 | */ 51 | public static String computeDiff(Date date1, Date date2) 52 | { 53 | Objects.requireNonNull(date1, "Unable to compute the difference from a null date (date1)!"); 54 | Objects.requireNonNull(date2, "Unable to compute the difference from a null date (date2)!"); 55 | 56 | long diffInMillies = date2.getTime() - date1.getTime(); 57 | List units = new ArrayList<>(EnumSet.allOf(TimeUnit.class)); 58 | 59 | Collections.reverse(units); 60 | Map result = new TreeMap<>(); 61 | long milliesRest = diffInMillies; 62 | 63 | for (TimeUnit unit : units) 64 | { 65 | long diff = unit.convert(milliesRest, TimeUnit.MILLISECONDS); 66 | long diffInMilliesForUnit = unit.toMillis(diff); 67 | milliesRest = milliesRest - diffInMilliesForUnit; 68 | result.put(unit, diff); 69 | } 70 | 71 | StringBuilder message = new StringBuilder(); 72 | Set timeUnitsSet = result.keySet(); 73 | List timeUnits = new ArrayList<>(timeUnitsSet); 74 | 75 | Collections.sort(timeUnits, Collections.reverseOrder()); 76 | 77 | long timeUnitValue; 78 | 79 | for (TimeUnit timeUnit : timeUnits) 80 | { 81 | timeUnitValue = result.get(timeUnit); 82 | 83 | if (timeUnitValue > 0) 84 | { 85 | if (message.length() > 0) 86 | { 87 | message.append(", "); 88 | } 89 | message.append(timeUnitValue + " " + timeUnit); 90 | } 91 | } 92 | 93 | if (message.length() == 0) 94 | { 95 | message.append("0 MILLISECONDS"); 96 | } 97 | return message.toString(); 98 | } 99 | 100 | /** 101 | * (U) This method is used to produce a pretty String (used mostly for debugging) of a date. 102 | * 103 | * @param myDate Date to represent in a pretty formatted String. 104 | * @return String value of the date passed in. 105 | */ 106 | public static String dateAsPrettyString(Date myDate) 107 | { 108 | return (dateAsPrettyString(myDate, TimeZoneLocale.GMT)); 109 | } 110 | 111 | /** 112 | * (U) This method is used to produce a pretty String (used mostly for debugging) of a date. 113 | * 114 | * @param myDate Date to represent in a pretty formatted String. 115 | * @param locale Enumeration that tell us if the user wants GMT or local time. 116 | * @return String value of the date passed in. 117 | */ 118 | public static String dateAsPrettyString(Date myDate, TimeZoneLocale locale) 119 | { 120 | String dateString = ""; 121 | if (myDate != null) 122 | { 123 | SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_PATTERN); 124 | 125 | if (TimeZoneLocale.GMT.equals(locale)) 126 | { 127 | sdf.setTimeZone(TimeZone.getTimeZone("GMT")); 128 | } 129 | dateString = sdf.format(myDate); 130 | } 131 | return dateString; 132 | } 133 | 134 | /** 135 | * (U) This method gets the current date. 136 | * 137 | * @return Date the current date/time. 138 | */ 139 | public static Date rightNowDate() 140 | { 141 | Calendar cal = Calendar.getInstance(); 142 | return cal.getTime(); 143 | } 144 | 145 | /** 146 | * (U) This method converts a date into a nice readable String. 147 | * 148 | * @param myDate java.util.Date to produce a readable string from. 149 | * @return String the readable format of the date. 150 | */ 151 | public static String toString(Date myDate) 152 | { 153 | Objects.requireNonNull(myDate, "Cannot convert a null java.util.Date to a String!"); 154 | 155 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT_PATTERN); 156 | 157 | return (simpleDateFormat.format(myDate)); 158 | } 159 | 160 | /** 161 | * (U) Base Constructor. 162 | */ 163 | private DateUtils() 164 | {} 165 | } 166 | -------------------------------------------------------------------------------- /src/main/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/utils/OperatingSystemUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | import org.apache.commons.io.FileUtils; 18 | import org.apache.log4j.Logger; 19 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.utils.StringUtils; 20 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 21 | 22 | import com.google.common.base.CharMatcher; 23 | 24 | /** 25 | * (U) This class is used to determine the operating system. 26 | * 27 | * @author wrgoff 28 | * @since 22 April 2020 29 | */ 30 | public class OperatingSystemUtils 31 | { 32 | private static final Logger logger = Logger.getLogger(OperatingSystemUtils.class.getName()); 33 | 34 | private static final String OS_RELEASE_FILE = "/etc/os-release"; 35 | 36 | private Map osMap = null; 37 | 38 | /** 39 | * (U) Base Constructor. 40 | * 41 | * @throws SBomException in the event we are unable to read the file. 42 | */ 43 | public OperatingSystemUtils() 44 | { 45 | osMap = getOs(); 46 | } 47 | 48 | /** 49 | * (U) Constructor. 50 | * 51 | * @param fileContents String value for the contents of the "/etc/os-release" 52 | * file. 53 | */ 54 | public OperatingSystemUtils(String fileContents) 55 | { 56 | osMap = readOs(fileContents); 57 | } 58 | 59 | /** 60 | * (U) This method is used to get the operating System. 61 | * 62 | * @return String the operating system. 63 | */ 64 | public String getOsVendor() 65 | { 66 | String osVendor = osMap.get("NAME"); 67 | 68 | if (StringUtils.isValid(osVendor)) 69 | osVendor = CharMatcher.is('\"').trimFrom(osVendor); 70 | else 71 | { 72 | logger.warn("Unable to determine OS. Assuming a flavor of Redhat.!"); 73 | osVendor = "REDHAT"; 74 | } 75 | return osVendor; 76 | } 77 | 78 | /** 79 | * (U) This method is used to get the operating System Name. 80 | * 81 | * @return String the operating system name. 82 | */ 83 | public String getOsName() 84 | { 85 | String osName = null; 86 | 87 | if (osMap.containsKey("ID")) 88 | osName = osMap.get("ID"); 89 | else 90 | osName = osMap.get("NAME"); 91 | 92 | osName = osName.replace('"', ' ').trim(); 93 | 94 | return osName; 95 | } 96 | 97 | /** 98 | * (U) This method is used to get the operating System Version. 99 | * 100 | * @return String the operating system version. 101 | */ 102 | public String getOsVersion() 103 | { 104 | String version = null; 105 | 106 | if (osMap.containsKey("VERSION_ID")) 107 | version = osMap.get("VERSION_ID"); 108 | else 109 | version = osMap.get("VERSION"); 110 | 111 | version = version.replace('"', ' ').trim(); 112 | 113 | return version; 114 | } 115 | 116 | /** 117 | * (U) This method is used to get the operating system. From the /etc/os-release 118 | * file. 119 | * 120 | * @return Map containing the information from the os-release file. 121 | * @throws SBomException in the event we are unable to read the file. 122 | */ 123 | public Map getOs() 124 | { 125 | Map detailMap = new HashMap<>(); 126 | 127 | try 128 | { 129 | String content = FileUtils.readFileToString(new File(OS_RELEASE_FILE)); 130 | 131 | detailMap = readOs(content); 132 | } 133 | catch (IOException ioe) 134 | { 135 | String error = "Unable to read file(" + OS_RELEASE_FILE + ") to get the " + 136 | "operating sytem!"; 137 | logger.error(error, ioe); 138 | throw new SBomException(error, ioe); 139 | } 140 | return detailMap; 141 | } 142 | 143 | /** 144 | * (U) This method is used to read the contents of the OS file. 145 | * 146 | * @param content String value read from the file. 147 | * @return Map containing the information about the Operating system. 148 | */ 149 | public Map readOs(String content) 150 | { 151 | Map detailMap = new HashMap<>(); 152 | 153 | String[] contents = content.split("\n"); 154 | String componentDetailName = null; 155 | StringBuilder componentDetailValue = new StringBuilder(); 156 | int index = 0; 157 | 158 | for (String line : contents) 159 | { 160 | if (line.startsWith(" ")) 161 | { 162 | componentDetailValue.append(line); 163 | } 164 | else 165 | { 166 | if (componentDetailName != null) 167 | { 168 | detailMap.put(componentDetailName, componentDetailValue.toString()); 169 | componentDetailName = null; 170 | componentDetailValue = new StringBuilder(); 171 | } 172 | 173 | if (line.contains("=")) 174 | { 175 | index = line.indexOf('='); 176 | componentDetailName = line.substring(0, index); 177 | componentDetailValue.append(line.substring(index + 1).trim()); 178 | } 179 | } 180 | } 181 | return detailMap; 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/UnixSbomGeneratorApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom; 11 | 12 | import java.io.ByteArrayOutputStream; 13 | import java.io.FileDescriptor; 14 | import java.io.FileOutputStream; 15 | import java.io.PrintStream; 16 | import java.util.Date; 17 | 18 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.test.utils.Log4JTestWatcher; 19 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.test.utils.TestUtils; 20 | import org.cyclonedx.contrib.com.lmco.efoss.sbom.commons.utils.DateUtils; 21 | import org.junit.Assert; 22 | import org.junit.Rule; 23 | import org.junit.jupiter.api.Test; 24 | 25 | class UnixSbomGeneratorApplicationTests { 26 | 27 | private static final String LOG4J_FILE = "UnixSbomGeneratorApplicationAppender.xml"; 28 | 29 | @Rule 30 | public static Log4JTestWatcher watcher = new Log4JTestWatcher(LOG4J_FILE, 31 | "UnixSbomGeneratorApplicationTests"); 32 | 33 | private final ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 34 | 35 | /** 36 | * Turns on stdOut output capture 37 | */ 38 | private void captureOut() 39 | { 40 | System.setOut(new PrintStream(outContent)); 41 | } 42 | 43 | /** 44 | * Turns off stdOut capture and returns the contents that have been captured 45 | * 46 | * @return String the contents of our stdOut. 47 | */ 48 | private String getOut() 49 | { 50 | System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out))); 51 | return outContent.toString().replaceAll("\r", ""); 52 | } 53 | 54 | /** 55 | * (U) This method is used to test to make sure our help menu works. It does NOT 56 | * check the contents, but check to make sure it begins "usage: help". 57 | */ 58 | @Test 59 | public void testHelp() 60 | { 61 | String methodName = new Object() 62 | { 63 | }.getClass().getEnclosingMethod().getName(); 64 | 65 | Date startDate = DateUtils.rightNowDate(); 66 | 67 | TestUtils.logTestStart(methodName, watcher.getLogger()); 68 | 69 | String helpUsageText = "usage: help"; 70 | 71 | try 72 | { 73 | captureOut(); 74 | 75 | String[] args = new String[] { 76 | "-h" 77 | }; 78 | UnixSbomGeneratorApplication.main(args); 79 | 80 | String theOutput = getOut(); 81 | 82 | watcher.getLogger().debug("Help Test: \n" + theOutput); 83 | 84 | Assert.assertTrue(theOutput.contains(helpUsageText)); 85 | } 86 | catch (Exception e) 87 | { 88 | String error = "Unexpected error occured while attempting to check to make sure our " + 89 | "help menu works!"; 90 | watcher.getLogger().error(error, e); 91 | Assert.fail(error); 92 | } 93 | finally 94 | { 95 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/AlpineSBomGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.InputStreamReader; 16 | import java.util.Date; 17 | 18 | import org.junit.Assert; 19 | import org.junit.jupiter.api.Assertions; 20 | import org.junit.jupiter.api.Test; 21 | import org.junit.runner.RunWith; 22 | import org.mockito.InjectMocks; 23 | import org.mockito.Mock; 24 | import org.mockito.Mockito; 25 | import org.mockito.MockitoAnnotations; 26 | import org.mockito.junit.MockitoJUnitRunner; 27 | 28 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 29 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.DateUtils; 30 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.Log4JTestWatcher; 31 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.TestUtils; 32 | 33 | 34 | /** 35 | * (U) Test cases for the Alpine Linux SBom Generator. 36 | * 37 | * @author wrgoff 38 | * @since 6 October 2020 39 | */ 40 | @RunWith(MockitoJUnitRunner.class) 41 | class AlpineSBomGeneratorTest extends BaseSBomGeneratorTest 42 | { 43 | private static final String LOG4J_FILE = "AlpineSBomGeneratorTestLog4J.xml"; 44 | 45 | public Log4JTestWatcher watcher = new Log4JTestWatcher(LOG4J_FILE, this.getClass().getName()); 46 | 47 | @Mock 48 | private ProcessBuilder pbMock = new ProcessBuilder(); 49 | 50 | @InjectMocks 51 | private AlpineSBomGenerator generator = new AlpineSBomGenerator(); 52 | 53 | /** 54 | * (U) This method is used to test the reading of a version from the process. 55 | */ 56 | @Test 57 | void readVersionFromProcessTest() 58 | { 59 | String methodName = new Object() 60 | {}.getClass().getEnclosingMethod().getName(); 61 | 62 | Date startDate = DateUtils.rightNowDate(); 63 | 64 | TestUtils.logTestStart(methodName, watcher.getLogger()); 65 | 66 | String expected = "1.1.24-r8"; 67 | String fileName = "/version/alpineVersion.txt"; 68 | 69 | try (InputStream stream = AlpineSBomGeneratorTest.class.getResourceAsStream(fileName)) 70 | { 71 | Process process = TestUtils.mockProcess(stream, null, null); 72 | 73 | String cmd = "apk policy musl"; 74 | 75 | String version = generator.parseVersion(process, cmd); 76 | 77 | if (expected.equalsIgnoreCase(version)) 78 | watcher.getLogger().debug("Got expected version (" + version + ")"); 79 | else 80 | watcher.getLogger().debug("Did NOT get the expected version. Expected: " + 81 | expected + ", Got: " + version); 82 | 83 | Assert.assertEquals(expected, version); 84 | } 85 | catch (Exception e) 86 | { 87 | String error = "Our test case to read the version from a process failed!"; 88 | watcher.getLogger().error(error, e); 89 | Assert.fail(error); 90 | } 91 | finally 92 | { 93 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 94 | } 95 | } 96 | 97 | /** 98 | * (U) This method is used to test the reading of a version from the process. 99 | */ 100 | @Test 101 | void readVersionFailFromProcessTest() 102 | { 103 | String methodName = new Object() 104 | {}.getClass().getEnclosingMethod().getName(); 105 | 106 | Date startDate = DateUtils.rightNowDate(); 107 | 108 | TestUtils.logTestStart(methodName, watcher.getLogger()); 109 | 110 | String cmd = "apk policy musl"; 111 | 112 | String expectedMessage = "Unexpected process exit value (-1), while " + 113 | "attempting to get Software Version (" + cmd + ")!"; 114 | 115 | String fileName = "/version/alpineVersion.txt"; 116 | 117 | try (InputStream stream = AlpineSBomGenerator.class.getResourceAsStream(fileName)) 118 | { 119 | Exception exception = Assertions.assertThrows(SBomException.class, () -> 120 | { 121 | Process process = TestUtils.mockFailedProcess(stream, null, null); 122 | generator.parseVersion(process, cmd); 123 | }); 124 | String actualMessage = exception.getMessage(); 125 | 126 | if (expectedMessage.equals(actualMessage)) 127 | watcher.getLogger().debug("Got expected exception message for a failed process!"); 128 | else 129 | watcher.getLogger().debug("Did NOT get the expected exception " + 130 | "message for a failed process!" + 131 | "\n Expected Message: " + expectedMessage + 132 | "\n Actual Message: " + actualMessage); 133 | 134 | Assert.assertTrue(expectedMessage.equals(actualMessage)); 135 | } 136 | catch (Exception e) 137 | { 138 | String error = "Our test case to read the version from a process failed!"; 139 | watcher.getLogger().error(error, e); 140 | Assert.fail(error); 141 | } 142 | finally 143 | { 144 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 145 | } 146 | } 147 | 148 | /** 149 | * (U) This method is used to test the parsing of the version. 150 | */ 151 | @Test 152 | void testParseVersion() 153 | { 154 | String methodName = new Object() 155 | {}.getClass().getEnclosingMethod().getName(); 156 | 157 | Date startDate = DateUtils.rightNowDate(); 158 | 159 | TestUtils.logTestStart(methodName, watcher.getLogger()); 160 | 161 | String file = "/version/alpineVersion.txt"; 162 | String expected = "1.1.24-r8"; 163 | try 164 | { 165 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 166 | UnixSBomGeneratorTest.class.getResourceAsStream(file)))) 167 | { 168 | String version = generator.parseVersion(reader); 169 | if(expected.equalsIgnoreCase(version)) 170 | watcher.getLogger().debug("Got expected version (" + version + ")"); 171 | else 172 | Assert.assertEquals(expected, version); 173 | } 174 | } 175 | catch (SBomException sbomE) 176 | { 177 | String error = "Our Test case testParseVersion failed to parse the contents of " + 178 | "the Alpine version (" + file + ")."; 179 | watcher.getLogger().error(error, sbomE); 180 | Assert.fail(error); 181 | } 182 | catch (IOException ioe) 183 | { 184 | String error = "Our Test case testParseVersion failed to read the Alpine " + 185 | "version file(" + file + ")."; 186 | watcher.getLogger().error(error, ioe); 187 | Assert.fail("Unable to read Alpine Version File (" + file + "). "); 188 | } 189 | catch (Exception e) 190 | { 191 | String error = "Our Test case testParseVersion failed unexpectedly."; 192 | watcher.getLogger().error(error, e); 193 | Assert.fail(error); 194 | } 195 | finally 196 | { 197 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 198 | } 199 | } 200 | 201 | /** 202 | * (U) This method is used to test the parsing of the version. 203 | */ 204 | @Test 205 | void getVersionTest() 206 | { 207 | String methodName = new Object() 208 | {}.getClass().getEnclosingMethod().getName(); 209 | 210 | Date startDate = DateUtils.rightNowDate(); 211 | 212 | TestUtils.logTestStart(methodName, watcher.getLogger()); 213 | 214 | String file = "/version/alpineVersion.txt"; 215 | String expected = "1.1.24-r8"; 216 | 217 | AutoCloseable openMocks = null; 218 | 219 | try (InputStream stream = AlpineSBomGeneratorTest.class.getResourceAsStream(file)) 220 | { 221 | openMocks = MockitoAnnotations.openMocks(this); 222 | 223 | Process process = TestUtils.mockProcess(stream, null, null); 224 | 225 | Mockito.when(pbMock.start()).thenReturn(process); 226 | 227 | String version = generator.getVersion("musl"); 228 | 229 | if (expected.equalsIgnoreCase(version)) 230 | watcher.getLogger().debug("Got expected version (" + version + ")"); 231 | else 232 | Assert.assertEquals(expected, version); 233 | } 234 | catch (SBomException sbomE) 235 | { 236 | String error = "Our Test case testParseVersion failed to parse the contents of " + 237 | "the Alpine version (" + file + ")."; 238 | watcher.getLogger().error(error, sbomE); 239 | Assert.fail(error); 240 | } 241 | catch (IOException ioe) 242 | { 243 | String error = "Our Test case testParseVersion failed to read the Alpine " + 244 | "version file(" + file + ")."; 245 | watcher.getLogger().error(error, ioe); 246 | Assert.fail("Unable to read Alpine Version File (" + file + "). "); 247 | } 248 | catch (Exception e) 249 | { 250 | String error = "Our Test case testParseVersion failed unexpectedly."; 251 | watcher.getLogger().error(error, e); 252 | Assert.fail(error); 253 | } 254 | finally 255 | { 256 | try 257 | { 258 | openMocks.close(); 259 | } 260 | catch (Exception e) 261 | { 262 | watcher.getLogger().warn("Unable to close Mockito Annotations!"); 263 | } 264 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 265 | } 266 | } 267 | } 268 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/BaseSBomGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStreamReader; 15 | import java.util.HashMap; 16 | import java.util.Map; 17 | import java.util.Set; 18 | 19 | import org.junit.Assert; 20 | 21 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.Log4JTestWatcher; 22 | 23 | /** 24 | * (U) This is the base class used for any common SBomGeneratorTest methods. 25 | * 26 | * @author wrgoff 27 | * @since 29 Apr 2020 28 | */ 29 | public class BaseSBomGeneratorTest 30 | { 31 | 32 | /** 33 | * (U) This method is used to get the list of expected Details. 34 | * 35 | * @param fileName String value of the name of the file to get the expected details from. 36 | * @param watcher Log4JTestWatcher to send any logs to. 37 | * @return Map containing the keys and their values. 38 | */ 39 | protected Map getDetailMap(String fileName, Log4JTestWatcher watcher) 40 | { 41 | Map expectedDetails = new HashMap(); 42 | 43 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 44 | UnixSBomGeneratorTest.class.getResourceAsStream(fileName)))) 45 | { 46 | String line; 47 | String key; 48 | String value; 49 | int index = 0; 50 | while ((line = reader.readLine()) != null) 51 | { 52 | if (line.contains(":")) 53 | { 54 | index = line.indexOf(':'); 55 | key = line.substring(0, index); 56 | value = line.substring(index + 1); 57 | expectedDetails.put(key.trim(), value.trim()); 58 | } 59 | } 60 | } 61 | catch (IOException ioe) 62 | { 63 | String error = "Our Test case failed to read the Expected Package Details " + 64 | "file(" + fileName + ")."; 65 | watcher.getLogger().error(error, ioe); 66 | Assert.fail("Unable to read Expected Package Details File (" + fileName + "). "); 67 | } 68 | return expectedDetails; 69 | } 70 | 71 | /** 72 | * (U) This method is used to get a Detail Map as a String, mostly used for debugging. 73 | * @param detailMap Map to get the values from. 74 | * @param tabs String value for the indentation. 75 | * @return String a nicely formatted string. 76 | */ 77 | protected String getDetailMapAsString(Map detailMap, String tabs) 78 | { 79 | StringBuilder sb = new StringBuilder(); 80 | 81 | Set keys = detailMap.keySet(); 82 | for(String key: keys) 83 | sb.append(tabs + key + " : " + detailMap.get(key) + "\n"); 84 | 85 | return sb.toString(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/RedHatSBomGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.InputStreamReader; 16 | import java.util.ArrayList; 17 | import java.util.Date; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | import org.cyclonedx.model.ExternalReference; 22 | import org.junit.Assert; 23 | import org.junit.jupiter.api.Test; 24 | import org.junit.runner.RunWith; 25 | import org.mockito.InjectMocks; 26 | import org.mockito.Mock; 27 | import org.mockito.Mockito; 28 | import org.mockito.MockitoAnnotations; 29 | import org.mockito.junit.MockitoJUnitRunner; 30 | 31 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 32 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.DateUtils; 33 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.Log4JTestWatcher; 34 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.TestUtils; 35 | 36 | /** 37 | * (U) Test cases for the RedHat SBom Generator. 38 | * 39 | * @author wrgoff 40 | * @since 27 Apr 2020 41 | */ 42 | @RunWith(MockitoJUnitRunner.class) 43 | class RedHatSBomGeneratorTest extends BaseSBomGeneratorTest 44 | { 45 | private static final String LOG4J_FILE = "RedHatSBomGeneratorTestLog4J.xml"; 46 | 47 | private static final String EXPECTED_DETAIL_MAP_FILE = "/packageDetails/expectedRedhatDetailMap.txt"; 48 | 49 | public Log4JTestWatcher watcher = new Log4JTestWatcher(LOG4J_FILE, this.getClass().getName()); 50 | 51 | @InjectMocks 52 | private RedHatSBomGenerator generator = new RedHatSBomGenerator(); 53 | 54 | @Mock 55 | private ProcessBuilder pbMock = new ProcessBuilder(); 56 | 57 | /** 58 | * (U) This method is used to test the parsing of the Map into External References. 59 | */ 60 | @Test 61 | void buildExternalReferencesTest() 62 | { 63 | String methodName = new Object() 64 | {}.getClass().getEnclosingMethod().getName(); 65 | 66 | Date startDate = DateUtils.rightNowDate(); 67 | 68 | TestUtils.logTestStart(methodName, watcher.getLogger()); 69 | 70 | try 71 | { 72 | List expectedRefs = generateExpectedExternalReferences(); 73 | 74 | Map detailMap = getDetailMap(EXPECTED_DETAIL_MAP_FILE, watcher); 75 | 76 | List actualRefs = generator 77 | .buildExternalReferences(detailMap); 78 | 79 | Assert.assertArrayEquals(expectedRefs.toArray(), actualRefs.toArray()); 80 | } 81 | catch (Exception e) 82 | { 83 | String error = "Our Test case buildExternalReferencesTest failed unexpectedly."; 84 | watcher.getLogger().error(error, e); 85 | Assert.fail(error); 86 | } 87 | finally 88 | { 89 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 90 | } 91 | } 92 | 93 | /** 94 | * (U) This method is used to generate the Expected External References. 95 | * 96 | * @return List of ExternalReferences that should be built. 97 | */ 98 | private List generateExpectedExternalReferences() 99 | { 100 | List refs = new ArrayList(); 101 | 102 | ExternalReference webpage = new ExternalReference(); 103 | webpage.setUrl("http://www.info-zip.org/Zip.html"); 104 | webpage.setType(ExternalReference.Type.WEBSITE); 105 | refs.add(webpage); 106 | 107 | return refs; 108 | } 109 | 110 | @Test 111 | void getPurlTest() 112 | { 113 | String methodName = new Object() 114 | {}.getClass().getEnclosingMethod().getName(); 115 | 116 | Date startDate = DateUtils.rightNowDate(); 117 | 118 | TestUtils.logTestStart(methodName, watcher.getLogger()); 119 | 120 | String expected = "https://rhui3.us-west-2.aws.ce.redhat.com/pulp/repos/content/dist/rhel/rhui/server/7/7Server/x86_64/os/Packages/z/zip-3.0-11.el7.x86_64.rpm"; 121 | 122 | AutoCloseable openMocks = null; 123 | 124 | String fileName = "/purl/redhatPurl.txt"; 125 | 126 | try (InputStream stream = RedHatSBomGeneratorTest.class.getResourceAsStream(fileName)) 127 | { 128 | Process process = TestUtils.mockProcess(stream, null, null); 129 | 130 | openMocks = MockitoAnnotations.openMocks(this); 131 | 132 | Mockito.when(pbMock.start()).thenReturn(process); 133 | 134 | String version = generator.getPurl("zip"); 135 | 136 | if (expected.equalsIgnoreCase(version)) 137 | watcher.getLogger().debug("Got expected version (" + version + ")"); 138 | else 139 | Assert.assertEquals(expected, version); 140 | } 141 | catch (Exception e) 142 | { 143 | String error = "Our Test case getPurlTest failed unexpectedly."; 144 | watcher.getLogger().error(error, e); 145 | Assert.fail(error); 146 | } 147 | finally 148 | { 149 | try 150 | { 151 | openMocks.close(); 152 | } 153 | catch (Exception e) 154 | { 155 | watcher.getLogger().warn("Unable to close Mockito Annotations!"); 156 | } 157 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 158 | } 159 | } 160 | 161 | /** 162 | * (U) This method is used to test the reading of a Purl from the process. 163 | */ 164 | @Test 165 | void parsePurlProcessTest() 166 | { 167 | String methodName = new Object() 168 | {}.getClass().getEnclosingMethod().getName(); 169 | 170 | Date startDate = DateUtils.rightNowDate(); 171 | 172 | TestUtils.logTestStart(methodName, watcher.getLogger()); 173 | 174 | String expected = "https://rhui3.us-west-2.aws.ce.redhat.com/pulp/repos/content/dist/rhel/rhui/server/7/7Server/x86_64/os/Packages/z/zip-3.0-11.el7.x86_64.rpm"; 175 | String fileName = "/purl/redhatPurl.txt"; 176 | 177 | try (InputStream stream = RedHatSBomGeneratorTest.class.getResourceAsStream(fileName)) 178 | { 179 | Process process = TestUtils.mockProcess(stream, null, null); 180 | 181 | String purl = generator.parsePurl(process, "zip"); 182 | 183 | if (expected.equalsIgnoreCase(purl)) 184 | watcher.getLogger().debug("Got expected purl (" + purl + ")"); 185 | else 186 | watcher.getLogger().debug("Did NOT get the expected Purl.\n" + 187 | " Expected: " + expected + "\n" + 188 | " Actual: " + purl); 189 | 190 | Assert.assertEquals(expected, purl); 191 | } 192 | catch (Exception e) 193 | { 194 | String error = "Our test case to read the purl from a process failed!"; 195 | watcher.getLogger().error(error, e); 196 | Assert.fail(error); 197 | } 198 | finally 199 | { 200 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 201 | } 202 | } 203 | 204 | /** 205 | * (U) This test method is used to test the parsing of the PURL, if an NO URL is found. 206 | */ 207 | @Test 208 | void parseBadPurlCmdOutput() 209 | { 210 | String methodName = new Object() 211 | {}.getClass().getEnclosingMethod().getName(); 212 | 213 | Date startDate = DateUtils.rightNowDate(); 214 | 215 | TestUtils.logTestStart(methodName, watcher.getLogger()); 216 | 217 | String redhatFile = "/purl/redhatPurl2.txt"; 218 | try 219 | { 220 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 221 | UnixSBomGeneratorTest.class.getResourceAsStream(redhatFile)))) 222 | { 223 | String actualPurl = generator.parsePurlCmdOutput(reader); 224 | if (actualPurl != null) 225 | Assert.fail("Expected a null, but got " + actualPurl); 226 | } 227 | } 228 | catch (SBomException sbomE) 229 | { 230 | String error = "Our Test case parsePurlCmdOutput failed to parse the contents of " + 231 | "the Red Hat package PURL (" + redhatFile + ")."; 232 | watcher.getLogger().error(error, sbomE); 233 | Assert.fail(error); 234 | } 235 | catch (IOException ioe) 236 | { 237 | String error = "Our Test case parsePurlCmdOutput failed to read the Red Hat " + 238 | "package PURL file(" + redhatFile + ")."; 239 | watcher.getLogger().error(error, ioe); 240 | Assert.fail("Unable to read Red Hat Package PURL File (" + redhatFile + "). "); 241 | } 242 | catch (Exception e) 243 | { 244 | String error = "Our Test case parsePurlCmdOutput failed unexpectedly."; 245 | watcher.getLogger().error(error, e); 246 | Assert.fail(error); 247 | } 248 | finally 249 | { 250 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 251 | } 252 | } 253 | 254 | /** 255 | * (U) This test method is used to test the parsing of the PURL, if an actual URL is found. 256 | */ 257 | @Test 258 | void parsePurlCmdOutput() 259 | { 260 | String methodName = new Object() 261 | {}.getClass().getEnclosingMethod().getName(); 262 | 263 | Date startDate = DateUtils.rightNowDate(); 264 | 265 | TestUtils.logTestStart(methodName, watcher.getLogger()); 266 | 267 | String redhatFile = "/purl/redhatPurl.txt"; 268 | try 269 | { 270 | String expectedPurl = "https://rhui3.us-west-2.aws.ce.redhat.com/pulp/repos/content/dist/rhel/rhui/server/7/7Server/x86_64/os/Packages/z/zip-3.0-11.el7.x86_64.rpm"; 271 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 272 | UnixSBomGeneratorTest.class.getResourceAsStream(redhatFile)))) 273 | { 274 | String actualPurl = generator.parsePurlCmdOutput(reader); 275 | 276 | Assert.assertTrue(actualPurl.equals(expectedPurl)); 277 | } 278 | } 279 | catch (SBomException sbomE) 280 | { 281 | String error = "Our Test case parsePurlCmdOutput failed to parse the contents of " + 282 | "the Red Hat package PURL (" + redhatFile + ")."; 283 | watcher.getLogger().error(error, sbomE); 284 | Assert.fail(error); 285 | } 286 | catch (IOException ioe) 287 | { 288 | String error = "Our Test case parsePurlCmdOutput failed to read the Red Hat " + 289 | "package PURL file(" + redhatFile + ")."; 290 | watcher.getLogger().error(error, ioe); 291 | Assert.fail("Unable to read Red Hat Package PURL File (" + redhatFile + "). "); 292 | } 293 | catch (Exception e) 294 | { 295 | String error = "Our Test case parsePurlCmdOutput failed unexpectedly."; 296 | watcher.getLogger().error(error, e); 297 | Assert.fail(error); 298 | } 299 | finally 300 | { 301 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 302 | } 303 | } 304 | 305 | /** 306 | * (U) This test method is used to test the parsing of the PURL, if an NO URL is found. 307 | */ 308 | @Test 309 | void testPurlCmdIOException() 310 | { 311 | String redhatFile = "/purl/redhatPurl2.txt"; 312 | 313 | String methodName = new Object() 314 | {}.getClass().getEnclosingMethod().getName(); 315 | 316 | Date startDate = DateUtils.rightNowDate(); 317 | 318 | TestUtils.logTestStart(methodName, watcher.getLogger()); 319 | 320 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 321 | UnixSBomGeneratorTest.class.getResourceAsStream(redhatFile)))) 322 | { 323 | reader.close(); 324 | generator.parsePurlCmdOutput(reader); 325 | Assert.fail("Expected an SBomException!"); 326 | } 327 | catch (SBomException sbomE) 328 | { 329 | Assert.assertTrue(sbomE.getMessage().equals("Unable to process output from unix " + 330 | "process to get the Package download URL.")); 331 | } 332 | catch (IOException ioe) 333 | { 334 | String error = "Our Test case testPurlCmdIOException failed to throw " + 335 | "expected SBomException."; 336 | watcher.getLogger().error(error, ioe); 337 | Assert.fail("Unable to read Red Hat Package PURL File (" + redhatFile + "). "); 338 | } 339 | catch (Exception e) 340 | { 341 | String error = "Our Test case testPurlCmdIOException failed unexpectedly."; 342 | watcher.getLogger().error(error, e); 343 | Assert.fail(error); 344 | } 345 | finally 346 | { 347 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 348 | } 349 | } 350 | } 351 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/SBomGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.nio.file.Files; 16 | import java.nio.file.Paths; 17 | import java.util.Date; 18 | import java.util.List; 19 | 20 | import org.cyclonedx.exception.ParseException; 21 | import org.cyclonedx.model.Bom; 22 | import org.cyclonedx.model.Tool; 23 | import org.cyclonedx.parsers.Parser; 24 | import org.cyclonedx.parsers.XmlParser; 25 | import org.junit.Assert; 26 | import org.junit.jupiter.api.Test; 27 | 28 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 29 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.DateUtils; 30 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.Log4JTestWatcher; 31 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.TestUtils; 32 | 33 | /** 34 | * (U) This class contains the test cases for the SBomGenerator. 35 | * 36 | * @author wrgoff 37 | * @since 15 October 2020 38 | */ 39 | class SBomGeneratorTest 40 | { 41 | private static final String LOG4J_FILE = "SBomGeneratorTestLog4J.xml"; 42 | 43 | public Log4JTestWatcher watcher = new Log4JTestWatcher(LOG4J_FILE, this.getClass().getName()); 44 | 45 | /** 46 | * (U) This method is used to test that we added the UnixSBomGenerator tool as the first tool in 47 | * the list. 48 | */ 49 | @Test 50 | void addBomToolsTest() 51 | { 52 | String methodName = new Object() 53 | {}.getClass().getEnclosingMethod().getName(); 54 | 55 | Date startDate = DateUtils.rightNowDate(); 56 | 57 | TestUtils.logTestStart(methodName, watcher.getLogger()); 58 | 59 | String file = "/sboms/bom.xml"; 60 | 61 | String expectedToolName = "UnixSBomGenerator"; 62 | try (InputStream stream = UnixSBomGeneratorTest.class.getResourceAsStream(file)) 63 | { 64 | Parser parser = new XmlParser(); 65 | Bom sbom = parser.parse(stream); 66 | 67 | SBomGenerator.addBomTools(sbom); 68 | 69 | List tools = sbom.getMetadata().getTools(); 70 | 71 | Tool tool = tools.get(0); 72 | 73 | Assert.assertEquals(expectedToolName, tool.getName()); 74 | } 75 | catch (Exception sbe) 76 | { 77 | String error = "Failed to Add Unix Bom Tool to the list of tools for " + 78 | "the SBom!"; 79 | watcher.getLogger().error(error, sbe); 80 | Assert.fail(error); 81 | } 82 | finally 83 | { 84 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 85 | } 86 | } 87 | 88 | /** 89 | * (U) This method is used to test the parsing of the Map into External References. 90 | */ 91 | @Test 92 | void geneateBomsTest() 93 | { 94 | String methodName = new Object() 95 | {}.getClass().getEnclosingMethod().getName(); 96 | 97 | Date startDate = DateUtils.rightNowDate(); 98 | 99 | TestUtils.logTestStart(methodName, watcher.getLogger()); 100 | 101 | String file = "/sboms/bom.xml"; 102 | 103 | try (InputStream stream = UnixSBomGeneratorTest.class.getResourceAsStream(file)) 104 | { 105 | Parser parser = new XmlParser(); 106 | Bom sbom = parser.parse(stream); 107 | SBomGenerator.addBomTools(sbom); 108 | 109 | watcher.getLogger().info("sbom: " + sbom.toString()); 110 | 111 | SBomGenerator.generateBoms(sbom); 112 | 113 | Bom generatedSbom = parser.parse(new File("output/bom.xml")); 114 | 115 | if (sbom.getComponents().size() == generatedSbom.getComponents().size()) 116 | { 117 | watcher.getLogger().info("SBomGenerator generated the same number of " + 118 | "components (" + sbom.getComponents().size() + ") as the original!"); 119 | } 120 | else 121 | watcher.getLogger().error("SBomGenerator did NOT generate the same number of " + 122 | "of components as the original. Generated: " + 123 | generatedSbom.getComponents().size() + ", original: " + 124 | sbom.getComponents().size() + "."); 125 | 126 | Assert.assertEquals(sbom.getComponents().size(), 127 | generatedSbom.getComponents().size()); 128 | } 129 | catch (IOException ioe) 130 | { 131 | String error = "Our Test case geneateBomsTest failed to read the Test SBom " + 132 | "from a file(" + file + ")."; 133 | watcher.getLogger().error(error, ioe); 134 | Assert.fail("Unable to read our Test SBom File (" + file + "). "); 135 | } 136 | catch (ParseException e) 137 | { 138 | String error = "Failed to parse the SBom from the file (" + file + ");"; 139 | watcher.getLogger().error(error, e); 140 | Assert.fail(error); 141 | } 142 | catch (SBomException sbe) 143 | { 144 | String error = "Failed to generate SBom file from Sbom!"; 145 | watcher.getLogger().error(error, sbe); 146 | Assert.fail(error); 147 | } 148 | finally 149 | { 150 | try 151 | { 152 | Files.delete(Paths.get("output/bom.xml")); 153 | Files.delete(Paths.get("output/bom.json")); 154 | } 155 | catch (Exception e) 156 | { 157 | watcher.getLogger().warn("Filed to cleanup output files!"); 158 | } 159 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/generator/UbuntuSBomGeneratorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.generator; 11 | 12 | import java.io.BufferedReader; 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.io.InputStreamReader; 16 | import java.util.ArrayList; 17 | import java.util.Date; 18 | import java.util.List; 19 | import java.util.Map; 20 | 21 | import org.cyclonedx.model.ExternalReference; 22 | import org.junit.Assert; 23 | import org.junit.jupiter.api.Assertions; 24 | import org.junit.jupiter.api.Test; 25 | import org.junit.runner.RunWith; 26 | import org.mockito.InjectMocks; 27 | import org.mockito.Mock; 28 | import org.mockito.Mockito; 29 | import org.mockito.MockitoAnnotations; 30 | import org.mockito.junit.MockitoJUnitRunner; 31 | 32 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.exceptions.SBomException; 33 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.DateUtils; 34 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.Log4JTestWatcher; 35 | import org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils.TestUtils; 36 | 37 | /** 38 | * (U) Test cases for the Ubuntu SBom Generator. 39 | * 40 | * @author wrgoff 41 | * @since 29 Apr 2020 42 | */ 43 | @RunWith(MockitoJUnitRunner.class) 44 | class UbuntuSBomGeneratorTest extends BaseSBomGeneratorTest 45 | { 46 | private static final String LOG4J_FILE = "UbuntuSBomGeneratorTestLog4J.xml"; 47 | 48 | private static final String EXPECTED_DETAIL_MAP_FILE = "/packageDetails/expectedUbuntuDetailMap.txt"; 49 | 50 | public Log4JTestWatcher watcher = new Log4JTestWatcher(LOG4J_FILE, this.getClass().getName()); 51 | 52 | @Mock 53 | private ProcessBuilder pbMock = new ProcessBuilder(); 54 | 55 | @InjectMocks 56 | private UbuntuSBomGenerator generator = new UbuntuSBomGenerator(); 57 | 58 | /** 59 | * (U) This method is used to test the parsing of the Map into External References. 60 | */ 61 | @Test 62 | void buildExternalReferencesTest() 63 | { 64 | String methodName = new Object() 65 | {}.getClass().getEnclosingMethod().getName(); 66 | 67 | Date startDate = DateUtils.rightNowDate(); 68 | 69 | TestUtils.logTestStart(methodName, watcher.getLogger()); 70 | 71 | try 72 | { 73 | List expectedRefs = generateExpectedExternalReferences(); 74 | 75 | Map detailMap = getDetailMap(EXPECTED_DETAIL_MAP_FILE, watcher); 76 | 77 | List actualRefs = generator 78 | .buildExternalReferences(detailMap); 79 | 80 | Assert.assertArrayEquals(expectedRefs.toArray(), actualRefs.toArray()); 81 | } 82 | catch (Exception e) 83 | { 84 | String error = "Our Test case buildExternalReferencesTest failed unexpectedly."; 85 | watcher.getLogger().error(error, e); 86 | Assert.fail(error); 87 | } 88 | finally 89 | { 90 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 91 | } 92 | } 93 | 94 | /** 95 | * (U) This method is used to test the parsing of the version. 96 | */ 97 | @Test 98 | void parseVersionTest() 99 | { 100 | String methodName = new Object() 101 | {}.getClass().getEnclosingMethod().getName(); 102 | 103 | Date startDate = DateUtils.rightNowDate(); 104 | 105 | TestUtils.logTestStart(methodName, watcher.getLogger()); 106 | 107 | String file = "/version/ubuntuVersion.txt"; 108 | String expected = "7.58.0-2ubuntu3.10"; 109 | try 110 | { 111 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 112 | UnixSBomGeneratorTest.class.getResourceAsStream(file)))) 113 | { 114 | String version = generator.parseVersion(reader); 115 | if (expected.equalsIgnoreCase(version)) 116 | watcher.getLogger().debug("Got expected version (" + version + ")"); 117 | else 118 | watcher.getLogger().debug("Did NOT get the expected version. Expected: " + 119 | expected + ", Got: " + version); 120 | 121 | Assert.assertEquals(expected, version); 122 | } 123 | } 124 | catch (SBomException sbomE) 125 | { 126 | String error = "Our Test case parseVersionTest failed to parse the contents of " + 127 | "the Ubuntu version (" + file + ")."; 128 | watcher.getLogger().error(error, sbomE); 129 | Assert.fail(error); 130 | } 131 | catch (IOException ioe) 132 | { 133 | String error = "Our Test case parseVersionTest failed to read the Ubuntu " + 134 | "version file(" + file + ")."; 135 | watcher.getLogger().error(error, ioe); 136 | Assert.fail("Unable to read Ubuntu Version File (" + file + "). "); 137 | } 138 | catch (Exception e) 139 | { 140 | String error = "Our Test case parseVersionTest failed unexpectedly."; 141 | watcher.getLogger().error(error, e); 142 | Assert.fail(error); 143 | } 144 | finally 145 | { 146 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 147 | } 148 | } 149 | 150 | /** 151 | * (U) This method is used to test the parsing of the version. 152 | */ 153 | @Test 154 | void parseVersionFailureTest() 155 | { 156 | String methodName = new Object() 157 | {}.getClass().getEnclosingMethod().getName(); 158 | 159 | Date startDate = DateUtils.rightNowDate(); 160 | 161 | TestUtils.logTestStart(methodName, watcher.getLogger()); 162 | 163 | String file = "/version/ubuntuVersion.txt"; 164 | try 165 | { 166 | try (BufferedReader reader = new BufferedReader(new InputStreamReader( 167 | UnixSBomGeneratorTest.class.getResourceAsStream(file)))) 168 | { 169 | reader.close(); 170 | generator.parseVersion(reader); 171 | Assert.fail("Expected an SBomException!"); 172 | } 173 | catch (SBomException sbomE) 174 | { 175 | Assert.assertTrue(sbomE.getMessage().equals("Failed to read version.")); 176 | } 177 | } 178 | catch (IOException ioe) 179 | { 180 | String error = "Our Test case parseVersionFailureTest failed to read the Ubuntu " + 181 | "version file(" + file + ")."; 182 | watcher.getLogger().error(error, ioe); 183 | Assert.fail("Unable to read Ubuntu Version File (" + file + "). "); 184 | } 185 | catch (Exception e) 186 | { 187 | String error = "Our Test case parseVersionFailureTest failed unexpectedly."; 188 | watcher.getLogger().error(error, e); 189 | Assert.fail(error); 190 | } 191 | finally 192 | { 193 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 194 | } 195 | } 196 | 197 | /** 198 | * (U) This method is used to test the reading of a version from the process. 199 | */ 200 | @Test 201 | void readVersionFromProcessTest() 202 | { 203 | String methodName = new Object() 204 | {}.getClass().getEnclosingMethod().getName(); 205 | 206 | Date startDate = DateUtils.rightNowDate(); 207 | 208 | TestUtils.logTestStart(methodName, watcher.getLogger()); 209 | 210 | String expected = "7.58.0-2ubuntu3.10"; 211 | String fileName = "/version/ubuntuVersion.txt"; 212 | 213 | try (InputStream stream = UnixSBomGeneratorTest.class.getResourceAsStream(fileName)) 214 | { 215 | Process process = TestUtils.mockProcess(stream, null, null); 216 | 217 | String version = generator.readVersion(process); 218 | 219 | if (expected.equalsIgnoreCase(version)) 220 | watcher.getLogger().debug("Got expected version (" + version + ")"); 221 | else 222 | watcher.getLogger().debug("Did NOT get the expected version. Expected: " + 223 | expected + ", Got: " + version); 224 | 225 | Assert.assertEquals(expected, version); 226 | } 227 | catch (Exception e) 228 | { 229 | String error = "Our test case to read the version from a process failed!"; 230 | watcher.getLogger().error(error, e); 231 | Assert.fail(error); 232 | } 233 | finally 234 | { 235 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 236 | } 237 | } 238 | 239 | /** 240 | * (U) This method is used to test the reading of a version from the process. 241 | */ 242 | @Test 243 | void readVersionFailFromProcessTest() 244 | { 245 | String methodName = new Object() 246 | {}.getClass().getEnclosingMethod().getName(); 247 | 248 | Date startDate = DateUtils.rightNowDate(); 249 | 250 | TestUtils.logTestStart(methodName, watcher.getLogger()); 251 | 252 | String expectedMessage = "Unexpected process exit value (-1), while " + 253 | "attempting to get Installed Software Version!"; 254 | String fileName = "/version/ubuntuVersion.txt"; 255 | 256 | try (InputStream stream = UnixSBomGeneratorTest.class.getResourceAsStream(fileName)) 257 | { 258 | Exception exception = Assertions.assertThrows(SBomException.class, () -> 259 | { 260 | Process process = TestUtils.mockFailedProcess(stream, null, null); 261 | generator.readVersion(process); 262 | }); 263 | String actualMessage = exception.getMessage(); 264 | 265 | if (expectedMessage.equals(actualMessage)) 266 | watcher.getLogger().debug("Got expected exception message for a failed process!"); 267 | else 268 | watcher.getLogger().debug("Did NOT get the expected exception " + 269 | "message for a failed process!" + 270 | "\n Expected Message: " + expectedMessage + 271 | "\n Actual Message: " + actualMessage); 272 | 273 | Assert.assertTrue(expectedMessage.equals(actualMessage)); 274 | } 275 | catch (Exception e) 276 | { 277 | String error = "Our test case to read the version from a process failed!"; 278 | watcher.getLogger().error(error, e); 279 | Assert.fail(error); 280 | } 281 | finally 282 | { 283 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 284 | } 285 | } 286 | 287 | /** 288 | * (U) This method is used to generate the Expected External References. 289 | * 290 | * @return List of ExternalReferences that should be built. 291 | */ 292 | private List generateExpectedExternalReferences() 293 | { 294 | List refs = new ArrayList(); 295 | 296 | ExternalReference webpage = new ExternalReference(); 297 | webpage.setUrl("http://www.info-zip.org/Zip.html"); 298 | webpage.setType(ExternalReference.Type.WEBSITE); 299 | refs.add(webpage); 300 | 301 | ExternalReference docs = new ExternalReference(); 302 | docs.setUrl("http://us.archive.ubuntu.com/ubuntu bionic/main amd64 Packages"); 303 | docs.setType(ExternalReference.Type.DOCUMENTATION); 304 | refs.add(docs); 305 | 306 | ExternalReference bugs = new ExternalReference(); 307 | bugs.setUrl("https://bugs.launchpad.net/ubuntu/+filebug"); 308 | bugs.setType(ExternalReference.Type.ISSUE_TRACKER); 309 | refs.add(bugs); 310 | 311 | return refs; 312 | } 313 | 314 | /** 315 | * (U) This method is used to test the method to get the Installed Version of a peice of 316 | * software. 317 | */ 318 | @Test 319 | void getInstalledVersionTest() 320 | { 321 | String methodName = new Object() 322 | {}.getClass().getEnclosingMethod().getName(); 323 | 324 | Date startDate = DateUtils.rightNowDate(); 325 | 326 | TestUtils.logTestStart(methodName, watcher.getLogger()); 327 | 328 | String file = "/version/ubuntuVersion.txt"; 329 | String expected = "7.58.0-2ubuntu3.10"; 330 | 331 | AutoCloseable openMocks = null; 332 | 333 | try (InputStream stream = AlpineSBomGeneratorTest.class.getResourceAsStream(file)) 334 | { 335 | openMocks = MockitoAnnotations.openMocks(this); 336 | 337 | Process process = TestUtils.mockProcess(stream, null, null); 338 | 339 | Mockito.when(pbMock.start()).thenReturn(process); 340 | 341 | String version = generator.getInstalledVersion("curl"); 342 | 343 | if (expected.equalsIgnoreCase(version)) 344 | watcher.getLogger().debug("Got expected version (" + version + ")"); 345 | else 346 | Assert.assertEquals(expected, version); 347 | } 348 | catch (SBomException sbomE) 349 | { 350 | String error = "Our Test case testParseVersion failed to parse the contents of " + 351 | "the Ubuntu version (" + file + ")."; 352 | watcher.getLogger().error(error, sbomE); 353 | Assert.fail(error); 354 | } 355 | catch (IOException ioe) 356 | { 357 | String error = "Our Test case testParseVersion failed to read the Alpine " + 358 | "version file(" + file + ")."; 359 | watcher.getLogger().error(error, ioe); 360 | Assert.fail("Unable to read Alpine Version File (" + file + "). "); 361 | } 362 | catch (Exception e) 363 | { 364 | String error = "Our Test case testParseVersion failed unexpectedly."; 365 | watcher.getLogger().error(error, e); 366 | Assert.fail(error); 367 | } 368 | finally 369 | { 370 | try 371 | { 372 | openMocks.close(); 373 | } 374 | catch (Exception e) 375 | { 376 | watcher.getLogger().warn("Unable to close Mockito Annotations!"); 377 | } 378 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 379 | } 380 | } 381 | } 382 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/utils/DateUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils; 11 | 12 | import java.text.SimpleDateFormat; 13 | import java.util.Date; 14 | import java.util.Locale; 15 | import java.util.Objects; 16 | 17 | import org.junit.Assert; 18 | import org.junit.ClassRule; 19 | import org.junit.jupiter.api.Test; 20 | 21 | /** 22 | * (U) Unit tests for our Date Utils Class. 23 | * 24 | * @author wrgoff 25 | * @since 15 October 2020 26 | */ 27 | public class DateUtilsTest 28 | { 29 | private static final String LOG4J_FILE = "DateUtilsAppender.xml"; 30 | 31 | @ClassRule 32 | public static Log4JTestWatcher watcher = new Log4JTestWatcher(LOG4J_FILE, "DateUtilsTest"); 33 | 34 | /** 35 | * (U) Compute Diff between the same date. Should be 0 milliseconds. 36 | */ 37 | @Test 38 | public void zeroDiffTest() 39 | { 40 | String methodName = new Object() 41 | {}.getClass().getEnclosingMethod().getName(); 42 | 43 | Date startDate = DateUtils.rightNowDate(); 44 | 45 | TestUtils.logTestStart(methodName, watcher.getLogger()); 46 | 47 | String same = "0 MILLISECONDS"; 48 | try 49 | { 50 | String diffString = DateUtils.computeDiff(startDate, startDate); 51 | 52 | if (Objects.equals(diffString, same)) 53 | watcher.getLogger().debug("Diff of two dates are Equal (" + same + "), as expected."); 54 | else 55 | watcher.getLogger().debug("Diff of two dates are not what is expected, \n" + 56 | " Expected : " + same + "\n But Got: " + diffString); 57 | 58 | Assert.assertTrue(diffString.equals("0 MILLISECONDS")); 59 | 60 | } 61 | catch (Exception e) 62 | { 63 | String error = "Unexpected error occured while attempt to compare " + 64 | "two date Strings set to the same time."; 65 | watcher.getLogger().error(error, e); 66 | Assert.fail(error); 67 | } 68 | finally 69 | { 70 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 71 | } 72 | } 73 | 74 | /** 75 | * (U) Test the Creation of a String from a date. 76 | */ 77 | @Test 78 | public void toStringTest() 79 | { 80 | String methodName = new Object() 81 | {}.getClass().getEnclosingMethod().getName(); 82 | 83 | Date startDate = DateUtils.rightNowDate(); 84 | 85 | TestUtils.logTestStart(methodName, watcher.getLogger()); 86 | 87 | String expectedString = "2020 08 10 10:15:55.000"; 88 | 89 | try 90 | { 91 | SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss a", 92 | Locale.ENGLISH); 93 | 94 | String dateInString = "10-08-2020 10:15:55 AM"; 95 | Date date = formatter.parse(dateInString); 96 | 97 | String dateString = DateUtils.toString(date); 98 | 99 | if (dateString.equalsIgnoreCase("2020 08 10 10:15:55.000")) 100 | watcher.getLogger().debug("Got expected String from date (" + expectedString + ")"); 101 | else 102 | watcher.getLogger() 103 | .warn("Expected (" + expectedString + "), but got: " + dateString); 104 | 105 | Assert.assertTrue(dateString.equalsIgnoreCase("2020 08 10 10:15:55.000")); 106 | } 107 | catch (Exception e) 108 | { 109 | String error = "Unexpected error occured while attempt create and compare a String " + 110 | "from a date!"; 111 | watcher.getLogger().error(error, e); 112 | Assert.fail(error); 113 | } 114 | finally 115 | { 116 | TestUtils.logTestFinish(methodName, startDate, watcher.getLogger()); 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/utils/Log4JTestWatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | /** 11 | * 12 | */ 13 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils; 14 | 15 | import org.apache.log4j.LogManager; 16 | import org.apache.log4j.Logger; 17 | import org.apache.log4j.xml.DOMConfigurator; 18 | import org.junit.rules.TestWatcher; 19 | import org.junit.runner.Description; 20 | 21 | /** 22 | * 23 | * @author wrgoff 24 | * @since 27 Apr 2020 25 | */ 26 | public class Log4JTestWatcher extends TestWatcher 27 | { 28 | private static final String JUNIT_LOGFILE_DIR = "./src/test/resources/logging/"; 29 | 30 | private Logger logger; 31 | 32 | /** 33 | * (U) This constructor constructs a single class with a handle to the log file for the caller. 34 | * 35 | * @param fileName String value of the file name to get the log4j configuration from. 36 | * @param loggerName String value of the logger's name. 37 | */ 38 | public Log4JTestWatcher(String fileName, String loggerName) 39 | { 40 | // Load log4J config. 41 | DOMConfigurator.configure(JUNIT_LOGFILE_DIR + fileName); 42 | 43 | // super(fileName, loggerName); 44 | logger = LogManager.getLogger(loggerName); 45 | } 46 | 47 | /** 48 | * (U) This method gets a handle to our logger. 49 | * 50 | * @return Logger our logger to log message to. 51 | */ 52 | public Logger getLogger() 53 | { 54 | return logger; 55 | } 56 | 57 | /** 58 | * (U) This method overrides JUnit, so Failed messages go to our logs. 59 | * 60 | * @param e Throwable to log. 61 | * @param description Description object of what failed. 62 | */ 63 | @Override 64 | protected void failed(final Throwable e, final Description description) 65 | { 66 | logger.error("*******Failed: " + description, e); 67 | } 68 | 69 | /** 70 | * (U) This method overrides JUnit, so finished messages go to our logs. 71 | * 72 | * @param description Description object of what has finished. 73 | */ 74 | @Override 75 | protected void finished(Description description) 76 | { 77 | // logger.info("Finished Test: " + description.getMethodName() + "\n\n"); 78 | } 79 | 80 | /** 81 | * (U) This method overrides JUnit, so starting messages go to our logs. 82 | * 83 | * @param description Description object of what was started. 84 | */ 85 | @Override 86 | protected void starting(Description description) 87 | { 88 | // logger.info("Starting Test: " + description.getMethodName()); 89 | } 90 | 91 | /** 92 | * (U) This method overrides JUnit, so Succeed messages go to our logs. 93 | * 94 | * @param description Description object of what succeeded. 95 | */ 96 | @Override 97 | protected void succeeded(final Description description) 98 | { 99 | // logger.debug ("Success: " + description); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/test/java/org/cyclonedx/contrib/com/lmco/efoss/unix/sbom/utils/TestUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018,2019 Lockheed Martin Corporation. 3 | * 4 | * This work is owned by Lockheed Martin Corporation. Lockheed Martin personnel are permitted to use and 5 | * modify this software. Lockheed Martin personnel may also deliver this source code to any US Government 6 | * customer Agency under a "US Government Purpose Rights" license. 7 | * 8 | * See the LICENSE file distributed with this work for licensing and distribution terms 9 | */ 10 | package org.cyclonedx.contrib.com.lmco.efoss.unix.sbom.utils; 11 | 12 | import static org.mockito.Mockito.mock; 13 | import static org.mockito.Mockito.when; 14 | 15 | import java.io.InputStream; 16 | import java.io.OutputStream; 17 | import java.util.Date; 18 | 19 | import org.apache.log4j.Logger; 20 | 21 | 22 | /** 23 | * (U) This class contains utilities used by the various test classes. 24 | * 25 | * @author wrgoff 26 | * @since 9 July 2020 27 | */ 28 | public class TestUtils 29 | { 30 | /** 31 | * (U) This method is used to log the starting of a test. 32 | * 33 | * @param methodName String value of the method that test was started for. 34 | * @param logger Logger to log the event to. 35 | * @return Date the java.util.Date indicating when the test started. 36 | */ 37 | public static Date logTestStart(String methodName, Logger logger) 38 | { 39 | Date startDate = DateUtils.rightNowDate(); 40 | 41 | String msg = "Starting " + methodName + " Test (" + 42 | DateUtils.dateAsPrettyString(startDate) + ")."; 43 | 44 | if (logger.isInfoEnabled()) 45 | logger.info(msg); 46 | 47 | System.out.println(msg); 48 | 49 | return startDate; 50 | } 51 | 52 | /** 53 | * (U) This method is used to log the finishing of a test. 54 | * 55 | * @param methodName String value of the method the test was for. 56 | * @param startDate Date the test started. 57 | * @param logger Logger to log the event to. 58 | */ 59 | public static void logTestFinish(String methodName, Date startDate, Logger logger) 60 | { 61 | if (logger.isInfoEnabled()) 62 | logger.info("It took " + DateUtils.computeDiff(startDate, DateUtils.rightNowDate()) + 63 | " to run the " + methodName + " Test!\n\n"); 64 | } 65 | 66 | /** 67 | * (U) This method is used to create a Mock Process to use for testing. 68 | * 69 | * @param outputStream InputStream to assign to the input stream of the process. 70 | * @param errorStream InputStream to assign to the Error Stream. 71 | * @param inputStream OutputStream to assign to the input steam. 72 | * @return Process mocked process to use for testing. 73 | * @throws InterruptedException in the event something goes wrong. 74 | */ 75 | public static Process mockProcess(InputStream outputStream, 76 | InputStream errorStream, OutputStream inputStream) 77 | throws InterruptedException 78 | { 79 | final Process subProcess = mock(Process.class); 80 | when(subProcess.waitFor()).thenReturn(0); 81 | when(subProcess.getInputStream()).thenReturn(outputStream); 82 | when(subProcess.getErrorStream()).thenReturn(errorStream); 83 | when(subProcess.getOutputStream()).thenReturn(inputStream); 84 | return subProcess; 85 | } 86 | 87 | /** 88 | * (U) This method is used to create a Mock Process to use for testing. 89 | * 90 | * @param outputStream InputStream to assign to the input stream of the process. 91 | * @param errorStream InputStream to assign to the Error Stream. 92 | * @param inputStream OutputStream to assign to the input steam. 93 | * @return Process mocked process to use for testing. 94 | * @throws InterruptedException in the event something goes wrong. 95 | */ 96 | public static Process mockFailedProcess(InputStream outputStream, 97 | InputStream errorStream, OutputStream inputStream) 98 | throws InterruptedException 99 | { 100 | final Process subProcess = mock(Process.class); 101 | when(subProcess.waitFor()).thenReturn(-1); 102 | when(subProcess.getInputStream()).thenReturn(outputStream); 103 | when(subProcess.getErrorStream()).thenReturn(errorStream); 104 | when(subProcess.getOutputStream()).thenReturn(inputStream); 105 | return subProcess; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/test/resources/license/redhat/COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /src/test/resources/license/redhat/LICENSE: -------------------------------------------------------------------------------- 1 | /*- 2 | * $Id$ 3 | */ 4 | 5 | The following is the license that applies to this copy of the Berkeley DB 6 | software. For a license to use the Berkeley DB software under conditions 7 | other than those described here, or to purchase support for this software, 8 | please contact Oracle at berkeleydb-info_us@oracle.com. 9 | 10 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 11 | /* 12 | * Copyright (c) 1990, 2012 Oracle and/or its affiliates. All rights reserved. 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions 16 | * are met: 17 | * 1. Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 2. Redistributions in binary form must reproduce the above copyright 20 | * notice, this list of conditions and the following disclaimer in the 21 | * documentation and/or other materials provided with the distribution. 22 | * 3. Redistributions in any form must be accompanied by information on 23 | * how to obtain complete source code for the DB software and any 24 | * accompanying software that uses the DB software. The source code 25 | * must either be included in the distribution or be available for no 26 | * more than the cost of distribution plus a nominal fee, and must be 27 | * freely redistributable under reasonable conditions. For an 28 | * executable file, complete source code means the source code for all 29 | * modules it contains. It does not include source code for modules or 30 | * files that typically accompany the major components of the operating 31 | * system on which the executable file runs. 32 | * 33 | * THIS SOFTWARE IS PROVIDED BY ORACLE ``AS IS'' AND ANY EXPRESS OR 34 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 35 | * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 36 | * NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL ORACLE BE LIABLE 37 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 38 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 40 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 41 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 42 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 43 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 44 | */ 45 | /* 46 | * Copyright (c) 1990, 1993, 1994, 1995 47 | * The Regents of the University of California. All rights reserved. 48 | * 49 | * Redistribution and use in source and binary forms, with or without 50 | * modification, are permitted provided that the following conditions 51 | * are met: 52 | * 1. Redistributions of source code must retain the above copyright 53 | * notice, this list of conditions and the following disclaimer. 54 | * 2. Redistributions in binary form must reproduce the above copyright 55 | * notice, this list of conditions and the following disclaimer in the 56 | * documentation and/or other materials provided with the distribution. 57 | * 3. Neither the name of the University nor the names of its contributors 58 | * may be used to endorse or promote products derived from this software 59 | * without specific prior written permission. 60 | * 61 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 62 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 63 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 64 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 65 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 66 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 67 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 68 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 69 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 70 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 71 | * SUCH DAMAGE. 72 | */ 73 | /* 74 | * Copyright (c) 1995, 1996 75 | * The President and Fellows of Harvard University. All rights reserved. 76 | * 77 | * Redistribution and use in source and binary forms, with or without 78 | * modification, are permitted provided that the following conditions 79 | * are met: 80 | * 1. Redistributions of source code must retain the above copyright 81 | * notice, this list of conditions and the following disclaimer. 82 | * 2. Redistributions in binary form must reproduce the above copyright 83 | * notice, this list of conditions and the following disclaimer in the 84 | * documentation and/or other materials provided with the distribution. 85 | * 3. Neither the name of the University nor the names of its contributors 86 | * may be used to endorse or promote products derived from this software 87 | * without specific prior written permission. 88 | * 89 | * THIS SOFTWARE IS PROVIDED BY HARVARD AND ITS CONTRIBUTORS ``AS IS'' AND 90 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 91 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 92 | * ARE DISCLAIMED. IN NO EVENT SHALL HARVARD OR ITS CONTRIBUTORS BE LIABLE 93 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 94 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 95 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 96 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 97 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 98 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 99 | * SUCH DAMAGE. 100 | */ 101 | =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= 102 | /*** 103 | * ASM: a very small and fast Java bytecode manipulation framework 104 | * Copyright (c) 2000-2005 INRIA, France Telecom 105 | * All rights reserved. 106 | * 107 | * Redistribution and use in source and binary forms, with or without 108 | * modification, are permitted provided that the following conditions 109 | * are met: 110 | * 1. Redistributions of source code must retain the above copyright 111 | * notice, this list of conditions and the following disclaimer. 112 | * 2. Redistributions in binary form must reproduce the above copyright 113 | * notice, this list of conditions and the following disclaimer in the 114 | * documentation and/or other materials provided with the distribution. 115 | * 3. Neither the name of the copyright holders nor the names of its 116 | * contributors may be used to endorse or promote products derived from 117 | * this software without specific prior written permission. 118 | * 119 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 120 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 121 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 122 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 123 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 124 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 125 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 126 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 127 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 128 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 129 | * THE POSSIBILITY OF SUCH DAMAGE. 130 | */ 131 | -------------------------------------------------------------------------------- /src/test/resources/license/ubuntu/copyright: -------------------------------------------------------------------------------- 1 | This is the Debian prepackaged version of "zip", Info-Zip's fast, portable, 2 | zipfile compression utility. 3 | 4 | This package is currently maintained by Santiago Vila 5 | and built from sources obtained from: 6 | 7 | ftp://ftp.info-zip.org/pub/infozip/src/zip30.tgz 8 | 9 | The changes were fairly minimal, and consisted solely of adding 10 | various debian/* files to the distribution. 11 | 12 | Copyright and license: 13 | 14 | This is version 2007-Mar-4 of the Info-ZIP license. 15 | The definitive version of this document should be available at 16 | ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely and 17 | a copy at http://www.info-zip.org/pub/infozip/license.html. 18 | 19 | 20 | Copyright (c) 1990-2007 Info-ZIP. All rights reserved. 21 | 22 | For the purposes of this copyright and license, "Info-ZIP" is defined as 23 | the following set of individuals: 24 | 25 | Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois, 26 | Jean-loup Gailly, Hunter Goatley, Ed Gordon, Ian Gorman, Chris Herborth, 27 | Dirk Haase, Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz, 28 | David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko, 29 | Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs, 30 | Kai Uwe Rommel, Steve Salisbury, Dave Smith, Steven M. Schweda, 31 | Christian Spieler, Cosmin Truta, Antoine Verheijen, Paul von Behren, 32 | Rich Wales, Mike White. 33 | 34 | This software is provided "as is," without warranty of any kind, express 35 | or implied. In no event shall Info-ZIP or its contributors be held liable 36 | for any direct, indirect, incidental, special or consequential damages 37 | arising out of the use of or inability to use this software. 38 | 39 | Permission is granted to anyone to use this software for any purpose, 40 | including commercial applications, and to alter it and redistribute it 41 | freely, subject to the above disclaimer and the following restrictions: 42 | 43 | 1. Redistributions of source code (in whole or in part) must retain 44 | the above copyright notice, definition, disclaimer, and this list 45 | of conditions. 46 | 47 | 2. Redistributions in binary form (compiled executables and libraries) 48 | must reproduce the above copyright notice, definition, disclaimer, 49 | and this list of conditions in documentation and/or other materials 50 | provided with the distribution. The sole exception to this condition 51 | is redistribution of a standard UnZipSFX binary (including SFXWiz) as 52 | part of a self-extracting archive; that is permitted without inclusion 53 | of this license, as long as the normal SFX banner has not been removed 54 | from the binary or disabled. 55 | 56 | 3. Altered versions--including, but not limited to, ports to new operating 57 | systems, existing ports with new graphical interfaces, versions with 58 | modified or added functionality, and dynamic, shared, or static library 59 | versions not from Info-ZIP--must be plainly marked as such and must not 60 | be misrepresented as being the original source or, if binaries, 61 | compiled from the original source. Such altered versions also must not 62 | be misrepresented as being Info-ZIP releases--including, but not 63 | limited to, labeling of the altered versions with the names "Info-ZIP" 64 | (or any variation thereof, including, but not limited to, different 65 | capitalizations), "Pocket UnZip," "WiZ" or "MacZip" without the 66 | explicit permission of Info-ZIP. Such altered versions are further 67 | prohibited from misrepresentative use of the Zip-Bugs or Info-ZIP 68 | e-mail addresses or the Info-ZIP URL(s), such as to imply Info-ZIP 69 | will provide support for the altered versions. 70 | 71 | 4. Info-ZIP retains the right to use the names "Info-ZIP," "Zip," "UnZip," 72 | "UnZipSFX," "WiZ," "Pocket UnZip," "Pocket Zip," and "MacZip" for its 73 | own source and binary releases. 74 | -------------------------------------------------------------------------------- /src/test/resources/logging/AlpineSBomGeneratorTestLog4J.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/logging/DateUtilsAppender.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/logging/OperatingSystemUtilsTestLog4J.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/logging/RedHatSBomGeneratorTestLog4J.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/logging/SBomGeneratorTestLog4J.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/logging/UbuntuSBomGeneratorTestLog4J.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/logging/UnixSBomGeneratorTestLog4J.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/logging/UnixSbomGeneratorApplicationAppender.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/operatingSystem/ubuntu.txt: -------------------------------------------------------------------------------- 1 | NAME="Ubuntu" 2 | VERSION="18.04.4 LTS (Bionic Beaver)" 3 | ID=ubuntu 4 | ID_LIKE=debian 5 | PRETTY_NAME="Ubuntu 18.04.4 LTS" 6 | VERSION_ID="18.04" 7 | HOME_URL="https://www.ubuntu.com/" 8 | SUPPORT_URL="https://help.ubuntu.com/" 9 | BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" 10 | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" 11 | VERSION_CODENAME=bionic 12 | UBUNTU_CODENAME=bionic -------------------------------------------------------------------------------- /src/test/resources/osReleaseFiles/alpine-os-release.txt: -------------------------------------------------------------------------------- 1 | NAME="Alpine Linux" 2 | ID=alpine 3 | VERSION_ID=3.14.2 4 | PRETTY_NAME="Alpine Linux v3.14" 5 | HOME_URL="https://alpinelinux.org/" 6 | BUG_REPORT_URL="https://bugs.alpinelinux.org/" -------------------------------------------------------------------------------- /src/test/resources/osReleaseFiles/centos-os-release.txt: -------------------------------------------------------------------------------- 1 | NAME="CentOS Linux" 2 | VERSION="8" 3 | ID="centos" 4 | ID_LIKE="rhel fedora" 5 | VERSION_ID="8" 6 | PLATFORM_ID="platform:el8" 7 | PRETTY_NAME="CentOS Linux 8" 8 | ANSI_COLOR="0;31" 9 | CPE_NAME="cpe:/o:centos:centos:8" 10 | HOME_URL="https://centos.org/" 11 | BUG_REPORT_URL="https://bugs.centos.org/" 12 | CENTOS_MANTISBT_PROJECT="CentOS-8" 13 | CENTOS_MANTISBT_PROJECT_VERSION="8" -------------------------------------------------------------------------------- /src/test/resources/osReleaseFiles/debian-os-release.txt: -------------------------------------------------------------------------------- 1 | PRETTY_NAME="Debian GNU/Linux 10 (buster)" 2 | NAME="Debian GNU/Linux" 3 | VERSION_ID="10" 4 | VERSION="10 (buster)" 5 | VERSION_CODENAME=buster 6 | ID=debian 7 | HOME_URL="https://www.debian.org/" 8 | SUPPORT_URL="https://www.debian.org/support" 9 | BUG_REPORT_URL="https://bugs.debian.org/" -------------------------------------------------------------------------------- /src/test/resources/osReleaseFiles/redhat-os-release.txt: -------------------------------------------------------------------------------- 1 | NAME="Red Hat Enterprise Linux" 2 | VERSION="8.1 (Ootpa)" 3 | ID="rhel" 4 | ID_LIKE="fedora" 5 | VERSION_ID="8.1" 6 | PLATFORM_ID="platform:el8" 7 | PRETTY_NAME="Red Hat Enterprise Linux 8.1 (Ootpa)" 8 | ANSI_COLOR="0;31" 9 | CPE_NAME="cpe:/o:redhat:enterprise_linux:8.1:GA" 10 | HOME_URL="https://www.redhat.com/" 11 | BUG_REPORT_URL="https://bugzilla.redhat.com/" 12 | REDHAT_BUGZILLA_PRODUCT="Red Hat Enterprise Linux 8" 13 | REDHAT_BUGZILLA_PRODUCT_VERSION=8.1 14 | REDHAT_SUPPORT_PRODUCT="Red Hat Enterprise Linux" 15 | REDHAT_SUPPORT_PRODUCT_VERSION="8.1" -------------------------------------------------------------------------------- /src/test/resources/osReleaseFiles/ubuntu-os-release.txt: -------------------------------------------------------------------------------- 1 | NAME="Ubuntu" 2 | VERSION="20.04.3 LTS (Focal Fossa)" 3 | ID=ubuntu 4 | ID_LIKE=debian 5 | PRETTY_NAME="Ubuntu 20.04.3 LTS" 6 | VERSION_ID="20.04" 7 | HOME_URL="https://www.ubuntu.com/" 8 | SUPPORT_URL="https://help.ubuntu.com/" 9 | BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" 10 | PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" 11 | VERSION_CODENAME=focal 12 | UBUNTU_CODENAME=focal -------------------------------------------------------------------------------- /src/test/resources/packageDetails/alpine.txt: -------------------------------------------------------------------------------- 1 | WARNING: Ignoring APKINDEX.2c4ac24e.tar.gz: No such file or directory 2 | WARNING: Ignoring APKINDEX.40a3604f.tar.gz: No such file or directory 3 | musl: the musl c library (libc) implementation 4 | musl: https://musl.libc.org/ 5 | musl: 614400 -------------------------------------------------------------------------------- /src/test/resources/packageDetails/expectedAlpineDetailMap.txt: -------------------------------------------------------------------------------- 1 | URL : https://musl.libc.org/ 2 | Description : the musl c library (libc) implementation 3 | -------------------------------------------------------------------------------- /src/test/resources/packageDetails/expectedRedhatDetailMap.txt: -------------------------------------------------------------------------------- 1 | Name : zip 2 | Arch : x86_64 3 | Version : 3.0 4 | Release : 11.el7 5 | Size : 796 k 6 | Repo : installed 7 | From repo : rhel-7-server-rhui-rpms 8 | Summary : A file compression and packaging utility compatible with PKZIP 9 | URL : http://www.info-zip.org/Zip.html 10 | License : BSD 11 | Description : The zip program is a compression and file packaging utility. Zip is analogous to a combination of the UNIX tar and compress commands and is compatible with PKZIP (a compression and file packaging utility for MS-DOS systems). Install the zip package if you need to compress files using the zip program. -------------------------------------------------------------------------------- /src/test/resources/packageDetails/expectedUbuntuDetailMap.txt: -------------------------------------------------------------------------------- 1 | Package : zip 2 | Version : 3.0-11build1 3 | Priority : optional 4 | Section : utils 5 | Origin : Ubuntu 6 | Maintainer : Ubuntu Developers 7 | Original-Maintainer : Santiago Vila 8 | Bugs : https://bugs.launchpad.net/ubuntu/+filebug 9 | Installed-Size : 638 kB 10 | Depends : libbz2-1.0, libc6 (>= 2.14) 11 | Recommends : unzip 12 | Homepage : http://www.info-zip.org/Zip.html 13 | Task : ubuntu-desktop, kubuntu-desktop, xubuntu-core, xubuntu-desktop, lubuntu-desktop-share, lubuntu-gtk-desktop, lubuntu-desktop, lubuntu-qt-desktop, ubuntustudio-desktop-core, ubuntustudio-desktop, ubuntukylin-desktop, ubuntu-mate-core, ubuntu-mate-desktop, ubuntu-budgie-desktop 14 | Supported : 5y 15 | Download-Size : 167 kB 16 | APT-Manual-Installed : no 17 | APT-Sources : http://us.archive.ubuntu.com/ubuntu bionic/main amd64 Packages 18 | Description : Archiver for .zip files This is InfoZIP's zip program. It produces files that are fully compatible with the popular PKZIP program; however, the command line options are not identical. In other words, the end result is the same, but the methods differ. :-) . This version supports encryption. 19 | 20 | -------------------------------------------------------------------------------- /src/test/resources/packageDetails/redhat.txt: -------------------------------------------------------------------------------- 1 | Loaded plugins: amazon-id 2 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 3 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/product/rhui-client-config-server-7.crt 4 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/rhui-client-config-server-7.key 5 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 6 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 7 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 8 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 9 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 10 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 11 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 12 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 13 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 14 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 15 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 16 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 17 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 18 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 19 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 20 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 21 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 22 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 23 | Installed Packages 24 | Name : zip 25 | Arch : x86_64 26 | Version : 3.0 27 | Release : 11.el7 28 | Size : 796 k 29 | Repo : installed 30 | From repo : rhel-7-server-rhui-rpms 31 | Summary : A file compression and packaging utility compatible with PKZIP 32 | URL : http://www.info-zip.org/Zip.html 33 | License : BSD 34 | Description : The zip program is a compression and file packaging utility. Zip is 35 | : analogous to a combination of the UNIX tar and compress commands and 36 | : is compatible with PKZIP (a compression and file packaging utility for 37 | : MS-DOS systems). 38 | : 39 | : Install the zip package if you need to compress files using the zip 40 | : program. 41 | 42 | -------------------------------------------------------------------------------- /src/test/resources/packageDetails/ubuntu.txt: -------------------------------------------------------------------------------- 1 | Package: zip 2 | Version: 3.0-11build1 3 | Priority: optional 4 | Section: utils 5 | Origin: Ubuntu 6 | Maintainer: Ubuntu Developers 7 | Original-Maintainer: Santiago Vila 8 | Bugs: https://bugs.launchpad.net/ubuntu/+filebug 9 | Installed-Size: 638 kB 10 | Depends: libbz2-1.0, libc6 (>= 2.14) 11 | Recommends: unzip 12 | Homepage: http://www.info-zip.org/Zip.html 13 | Task: ubuntu-desktop, kubuntu-desktop, xubuntu-core, xubuntu-desktop, lubuntu-desktop-share, lubuntu-gtk-desktop, lubuntu-desktop, lubuntu-qt-desktop, ubuntustudio-desktop-core, ubuntustudio-desktop, ubuntukylin-desktop, ubuntu-mate-core, ubuntu-mate-desktop, ubuntu-budgie-desktop 14 | Supported: 5y 15 | Download-Size: 167 kB 16 | APT-Manual-Installed: no 17 | APT-Sources: http://us.archive.ubuntu.com/ubuntu bionic/main amd64 Packages 18 | Description: Archiver for .zip files 19 | This is InfoZIP's zip program. It produces files that are fully 20 | compatible with the popular PKZIP program; however, the command line 21 | options are not identical. In other words, the end result is the same, 22 | but the methods differ. :-) 23 | . 24 | This version supports encryption. 25 | 26 | -------------------------------------------------------------------------------- /src/test/resources/packageList/alpine.txt: -------------------------------------------------------------------------------- 1 | WARNING: Ignoring APKINDEX.2c4ac24e.tar.gz: No such file or directory 2 | WARNING: Ignoring APKINDEX.40a3604f.tar.gz: No such file or directory 3 | musl 4 | busybox 5 | alpine-baselayout 6 | alpine-keys 7 | libcrypto1.1 8 | libssl1.1 9 | ca-certificates-bundle 10 | libtls-standalone 11 | ssl_client 12 | zlib 13 | apk-tools 14 | scanelf 15 | musl-utils 16 | libc-utils 17 | ca-certificates 18 | nghttp2-libs 19 | libcurl 20 | expat 21 | pcre2 22 | git -------------------------------------------------------------------------------- /src/test/resources/packageList/expectedAlpinePackages.txt: -------------------------------------------------------------------------------- 1 | musl 2 | busybox 3 | alpine-baselayout 4 | alpine-keys 5 | libcrypto1.1 6 | libssl1.1 7 | ca-certificates-bundle 8 | libtls-standalone 9 | ssl_client 10 | zlib 11 | apk-tools 12 | scanelf 13 | musl-utils 14 | libc-utils 15 | ca-certificates 16 | nghttp2-libs 17 | libcurl 18 | expat 19 | pcre2 20 | git -------------------------------------------------------------------------------- /src/test/resources/packageList/expectedRedhatPackages.txt: -------------------------------------------------------------------------------- 1 | GeoIP.x86_64 2 | NetworkManager.x86_64 3 | NetworkManager-config-server.noarch 4 | NetworkManager-libnm.x86_64 5 | NetworkManager-team.x86_64 6 | NetworkManager-tui.x86_64 7 | PyYAML.x86_64 8 | Red_Hat_Enterprise_Linux-Release_Notes-7-en-US.noarch 9 | acl.x86_64 10 | alsa-lib.x86_64 11 | amazon-cloudwatch-agent.x86_64 12 | amazon-ssm-agent.x86_64 13 | ansible.noarch 14 | audit.x86_64 15 | audit-libs.x86_64 16 | audit-libs-python.x86_64 17 | authconfig.x86_64 18 | avahi-libs.x86_64 19 | aws-cfn-bootstrap.noarch 20 | basesystem.noarch 21 | bash.x86_64 22 | bc.x86_64 23 | bind-export-libs.x86_64 24 | bind-libs.x86_64 25 | bind-libs-lite.x86_64 26 | bind-license.noarch 27 | bind-utils.x86_64 28 | binutils.x86_64 29 | btrfs-progs.x86_64 30 | bzip2-libs.x86_64 31 | ca-certificates.noarch 32 | checkpolicy.x86_64 33 | chkconfig.x86_64 34 | chrony.x86_64 35 | cloud-init.x86_64 36 | cloud-utils-growpart.noarch 37 | compat-libstdc++-33.i686 38 | copy-jdk-configs.noarch 39 | coreutils.x86_64 40 | cpio.x86_64 41 | cracklib.x86_64 42 | cracklib-dicts.x86_64 43 | cronie.x86_64 44 | cronie-anacron.x86_64 45 | crontabs.noarch 46 | cryptsetup-libs.x86_64 47 | cups-libs.x86_64 48 | curl.x86_64 49 | cyrus-sasl-lib.x86_64 50 | dbus.x86_64 51 | dbus-glib.x86_64 52 | dbus-libs.x86_64 53 | dbus-python.x86_64 54 | dejavu-fonts-common.noarch 55 | dejavu-sans-fonts.noarch 56 | desktop-file-utils.x86_64 57 | device-mapper.x86_64 58 | device-mapper-libs.x86_64 59 | device-mapper-multipath.x86_64 60 | device-mapper-multipath-libs.x86_64 61 | dhclient.x86_64 62 | dhcp-common.x86_64 63 | dhcp-libs.x86_64 64 | diffutils.x86_64 65 | dmidecode.x86_64 66 | dos2unix.x86_64 67 | dracut.x86_64 68 | dracut-config-generic.x86_64 69 | dracut-config-rescue.x86_64 70 | dracut-network.x86_64 71 | e2fsprogs.x86_64 72 | e2fsprogs-libs.x86_64 73 | ed.x86_64 74 | elfutils-default-yama-scope.noarch 75 | elfutils-libelf.x86_64 76 | elfutils-libs.x86_64 77 | emacs-filesystem.noarch 78 | epel-release.noarch 79 | ethtool.x86_64 80 | expat.x86_64 81 | file.x86_64 82 | file-libs.x86_64 83 | filesystem.x86_64 84 | findutils.x86_64 85 | fipscheck.x86_64 86 | fipscheck-lib.x86_64 87 | fontconfig.x86_64 88 | fontpackages-filesystem.noarch 89 | fping.x86_64 90 | freetype.x86_64 91 | ftp.x86_64 92 | gawk.x86_64 93 | gdbm.x86_64 94 | gdisk.x86_64 95 | geoipupdate.x86_64 96 | gettext.x86_64 97 | gettext-libs.x86_64 98 | giflib.x86_64 99 | glib2.x86_64 100 | glibc.i686 101 | glibc.x86_64 102 | glibc-common.x86_64 103 | gmp.x86_64 104 | gnupg2.x86_64 105 | gobject-introspection.x86_64 106 | gpgme.x86_64 107 | gpm-libs.x86_64 108 | grep.x86_64 109 | groff-base.x86_64 110 | grub2.x86_64 111 | grub2-common.noarch 112 | grub2-pc.x86_64 113 | grub2-pc-modules.noarch 114 | grub2-tools.x86_64 115 | grub2-tools-extra.x86_64 116 | grub2-tools-minimal.x86_64 117 | grubby.x86_64 118 | gzip.x86_64 119 | hardlink.x86_64 120 | hostname.x86_64 121 | hwdata.x86_64 122 | info.x86_64 123 | initscripts.x86_64 124 | iproute.x86_64 125 | iptables.x86_64 126 | iputils.x86_64 127 | irqbalance.x86_64 128 | iwl7265-firmware.noarch 129 | jansson.x86_64 130 | java-11-openjdk.x86_64 131 | java-11-openjdk-devel.x86_64 132 | java-11-openjdk-headless.x86_64 133 | javapackages-tools.noarch 134 | jbigkit-libs.x86_64 135 | jq.x86_64 136 | json-c.x86_64 137 | kbd.x86_64 138 | kbd-legacy.noarch 139 | kbd-misc.noarch 140 | kernel.x86_64 141 | kernel-tools.x86_64 142 | kernel-tools-libs.x86_64 143 | kexec-tools.x86_64 144 | keyutils-libs.x86_64 145 | kmod.x86_64 146 | kmod-libs.x86_64 147 | kpartx.x86_64 148 | krb5-libs.x86_64 149 | ksh.x86_64 150 | less.x86_64 151 | libICE.x86_64 152 | libSM.x86_64 153 | libX11.x86_64 154 | libX11-common.noarch 155 | libXau.x86_64 156 | libXext.x86_64 157 | libXi.x86_64 158 | libXrender.x86_64 159 | libXtst.x86_64 160 | libacl.x86_64 161 | libaio.x86_64 162 | libassuan.x86_64 163 | libattr.x86_64 164 | libblkid.x86_64 165 | libcap.x86_64 166 | libcap-ng.x86_64 167 | libcgroup.x86_64 168 | libcom_err.x86_64 169 | libcroco.x86_64 170 | libcurl.x86_64 171 | libdaemon.x86_64 172 | libdb.x86_64 173 | libdb-utils.x86_64 174 | libedit.x86_64 175 | libestr.x86_64 176 | libfastjson.x86_64 177 | libffi.x86_64 178 | libfontenc.x86_64 179 | libgcc.i686 180 | libgcc.x86_64 181 | libgcrypt.x86_64 182 | libgomp.x86_64 183 | libgpg-error.x86_64 184 | libgudev1.x86_64 185 | libidn.x86_64 186 | libjpeg-turbo.x86_64 187 | libmnl.x86_64 188 | libmount.x86_64 189 | libndp.x86_64 190 | libnetfilter_conntrack.x86_64 191 | libnfnetlink.x86_64 192 | libnl.x86_64 193 | libnl3.x86_64 194 | libnl3-cli.x86_64 195 | libpcap.x86_64 196 | libpipeline.x86_64 197 | libpng.x86_64 198 | libpwquality.x86_64 199 | libseccomp.x86_64 200 | libselinux.x86_64 201 | libselinux-python.x86_64 202 | libselinux-utils.x86_64 203 | libsemanage.x86_64 204 | libsemanage-python.x86_64 205 | libsepol.x86_64 206 | libsmartcols.x86_64 207 | libss.x86_64 208 | libssh2.x86_64 209 | libstdc++.x86_64 210 | libsysfs.x86_64 211 | libtasn1.x86_64 212 | libteam.x86_64 213 | libtiff.x86_64 214 | libtirpc.x86_64 215 | libunistring.x86_64 216 | libuser.x86_64 217 | libutempter.x86_64 218 | libuuid.x86_64 219 | libverto.x86_64 220 | libwebp.x86_64 221 | libxcb.x86_64 222 | libxml2.x86_64 223 | libxml2-python.x86_64 224 | libxslt.x86_64 225 | libyaml.x86_64 226 | lksctp-tools.x86_64 227 | logrotate.x86_64 228 | lshw.x86_64 229 | lsof.x86_64 230 | lua.x86_64 231 | lz4.x86_64 232 | lzo.x86_64 233 | m2crypto.x86_64 234 | m4.x86_64 235 | mailcap.noarch 236 | mailx.x86_64 237 | make.x86_64 238 | man-db.x86_64 239 | man-pages.noarch 240 | mariadb-libs.x86_64 241 | microcode_ctl.x86_64 242 | mozjs17.x86_64 243 | mtr.x86_64 244 | ncurses.x86_64 245 | ncurses-base.noarch 246 | ncurses-libs.x86_64 247 | net-tools.x86_64 248 | newt.x86_64 249 | newt-python.x86_64 250 | nspr.x86_64 251 | nss.x86_64 252 | nss-pem.x86_64 253 | nss-softokn.x86_64 254 | nss-softokn-freebl.i686 255 | nss-softokn-freebl.x86_64 256 | nss-sysinit.x86_64 257 | nss-tools.x86_64 258 | nss-util.x86_64 259 | numactl.x86_64 260 | numactl-libs.x86_64 261 | oniguruma.x86_64 262 | openldap.x86_64 263 | openldap-clients.x86_64 264 | openssh.x86_64 265 | openssh-clients.x86_64 266 | openssh-server.x86_64 267 | openssl.x86_64 268 | openssl-libs.x86_64 269 | os-prober.x86_64 270 | p11-kit.x86_64 271 | p11-kit-trust.x86_64 272 | pam.x86_64 273 | parted.x86_64 274 | passwd.x86_64 275 | pciutils.x86_64 276 | pciutils-libs.x86_64 277 | pcre.x86_64 278 | pcsc-lite-libs.x86_64 279 | perl.x86_64 280 | perl-Authen-SASL.noarch 281 | perl-Bit-Vector.x86_64 282 | perl-Business-ISBN.noarch 283 | perl-Business-ISBN-Data.noarch 284 | perl-Carp.noarch 285 | perl-Carp-Clan.noarch 286 | perl-Compress-Raw-Bzip2.x86_64 287 | perl-Compress-Raw-Zlib.x86_64 288 | perl-Config-IniFiles.noarch 289 | perl-Convert-ASN1.noarch 290 | perl-Data-Dumper.x86_64 291 | perl-Date-Calc.noarch 292 | perl-Date-Manip.noarch 293 | perl-Digest.noarch 294 | perl-Digest-HMAC.noarch 295 | perl-Digest-MD5.x86_64 296 | perl-Digest-SHA.x86_64 297 | perl-Encode.x86_64 298 | perl-Encode-Locale.noarch 299 | perl-Exporter.noarch 300 | perl-File-Listing.noarch 301 | perl-File-Path.noarch 302 | perl-File-Temp.noarch 303 | perl-Filter.x86_64 304 | perl-GSSAPI.x86_64 305 | perl-Getopt-Long.noarch 306 | perl-HTML-Parser.x86_64 307 | perl-HTML-Tagset.noarch 308 | perl-HTTP-Cookies.noarch 309 | perl-HTTP-Daemon.noarch 310 | perl-HTTP-Date.noarch 311 | perl-HTTP-Message.noarch 312 | perl-HTTP-Negotiate.noarch 313 | perl-HTTP-Tiny.noarch 314 | perl-IO-Compress.noarch 315 | perl-IO-HTML.noarch 316 | perl-IO-Socket-IP.noarch 317 | perl-IO-Socket-SSL.noarch 318 | perl-IO-stringy.noarch 319 | perl-JSON.noarch 320 | perl-LDAP.noarch 321 | perl-LWP-MediaTypes.noarch 322 | perl-List-MoreUtils.x86_64 323 | perl-Mozilla-CA.noarch 324 | perl-Net-HTTP.noarch 325 | perl-Net-LibIDN.x86_64 326 | perl-Net-SSLeay.x86_64 327 | perl-PathTools.x86_64 328 | perl-Pod-Escapes.noarch 329 | perl-Pod-Perldoc.noarch 330 | perl-Pod-Simple.noarch 331 | perl-Pod-Usage.noarch 332 | perl-Scalar-List-Utils.x86_64 333 | perl-Socket.x86_64 334 | perl-Storable.x86_64 335 | perl-Sys-Syslog.x86_64 336 | perl-Text-ParseWords.noarch 337 | perl-Text-Soundex.x86_64 338 | perl-Text-Unidecode.noarch 339 | perl-Time-HiRes.x86_64 340 | perl-Time-Local.noarch 341 | perl-TimeDate.noarch 342 | perl-URI.noarch 343 | perl-WWW-RobotRules.noarch 344 | perl-XML-Filter-BufferText.noarch 345 | perl-XML-NamespaceSupport.noarch 346 | perl-XML-SAX-Base.noarch 347 | perl-XML-SAX-Writer.noarch 348 | perl-constant.noarch 349 | perl-libs.x86_64 350 | perl-libwww-perl.noarch 351 | perl-macros.x86_64 352 | perl-parent.noarch 353 | perl-podlators.noarch 354 | perl-threads.x86_64 355 | perl-threads-shared.x86_64 356 | pinentry.x86_64 357 | pkgconfig.x86_64 358 | policycoreutils.x86_64 359 | policycoreutils-devel.x86_64 360 | policycoreutils-python.x86_64 361 | polkit.x86_64 362 | polkit-pkla-compat.x86_64 363 | popt.x86_64 364 | postfix.x86_64 365 | procps-ng.x86_64 366 | pth.x86_64 367 | pyOpenSSL.x86_64 368 | pygobject2.x86_64 369 | pygpgme.x86_64 370 | pyliblzma.x86_64 371 | pyserial.noarch 372 | pystache.noarch 373 | python.x86_64 374 | python-IPy.noarch 375 | python-babel.noarch 376 | python-backports.x86_64 377 | python-backports-ssl_match_hostname.noarch 378 | python-cffi.x86_64 379 | python-chardet.noarch 380 | python-configobj.noarch 381 | python-daemon.noarch 382 | python-dateutil.noarch 383 | python-decorator.noarch 384 | python-dmidecode.x86_64 385 | python-docutils.noarch 386 | python-enum34.noarch 387 | python-ethtool.x86_64 388 | python-gobject-base.x86_64 389 | python-gudev.x86_64 390 | python-httplib2.noarch 391 | python-hwdata.noarch 392 | python-idna.noarch 393 | python-iniparse.noarch 394 | python-inotify.noarch 395 | python-ipaddr.noarch 396 | python-ipaddress.noarch 397 | python-javapackages.noarch 398 | python-jinja2.noarch 399 | python-jsonpatch.noarch 400 | python-jsonpointer.noarch 401 | python-kitchen.noarch 402 | python-libs.x86_64 403 | python-linux-procfs.noarch 404 | python-lockfile.noarch 405 | python-lxml.x86_64 406 | python-magic.noarch 407 | python-markupsafe.x86_64 408 | python-paramiko.noarch 409 | python-perf.x86_64 410 | python-pillow.x86_64 411 | python-ply.noarch 412 | python-prettytable.noarch 413 | python-pycparser.noarch 414 | python-pycurl.x86_64 415 | python-pyudev.noarch 416 | python-requests.noarch 417 | python-schedutils.x86_64 418 | python-setuptools.noarch 419 | python-six.noarch 420 | python-syspurpose.x86_64 421 | python-urlgrabber.noarch 422 | python-urllib3.noarch 423 | python2-boto.noarch 424 | python2-boto3.noarch 425 | python2-botocore.noarch 426 | python2-cryptography.x86_64 427 | python2-futures.noarch 428 | python2-jmespath.noarch 429 | python2-pyasn1.noarch 430 | python2-rsa.noarch 431 | python2-s3transfer.noarch 432 | python2-simplejson.x86_64 433 | python3.x86_64 434 | python3-libs.x86_64 435 | python3-pip.noarch 436 | python3-setuptools.noarch 437 | pyxattr.x86_64 438 | qemu-guest-agent.x86_64 439 | qrencode-libs.x86_64 440 | qualys-cloud-agent.x86_64 441 | rcs.x86_64 442 | readline.x86_64 443 | redhat-release-eula.noarch 444 | redhat-release-server.x86_64 445 | redhat-support-lib-python.noarch 446 | redhat-support-tool.noarch 447 | rh-amazon-rhui-client.noarch 448 | rhn-check.x86_64 449 | rhn-client-tools.x86_64 450 | rhn-setup.x86_64 451 | rhnlib.noarch 452 | rhnsd.x86_64 453 | rootfiles.noarch 454 | rpm.x86_64 455 | rpm-build-libs.x86_64 456 | rpm-libs.x86_64 457 | rpm-python.x86_64 458 | rsync.x86_64 459 | rsyslog.x86_64 460 | screen.x86_64 461 | sed.x86_64 462 | selinux-policy.noarch 463 | selinux-policy-devel.noarch 464 | selinux-policy-targeted.noarch 465 | setools-libs.x86_64 466 | setup.noarch 467 | sg3_utils.x86_64 468 | sg3_utils-libs.x86_64 469 | shadow-utils.x86_64 470 | shared-mime-info.x86_64 471 | slang.x86_64 472 | snappy.x86_64 473 | splunkforwarder.x86_64 474 | sqlite.x86_64 475 | sshpass.x86_64 476 | strace.x86_64 477 | subscription-manager.x86_64 478 | subscription-manager-rhsm.x86_64 479 | subscription-manager-rhsm-certificates.x86_64 480 | sudo.x86_64 481 | swatch.noarch 482 | systemd.x86_64 483 | systemd-libs.x86_64 484 | systemd-sysv.x86_64 485 | sysvinit-tools.x86_64 486 | tar.x86_64 487 | tcp_wrappers-libs.x86_64 488 | tcpdump.x86_64 489 | tcsh.x86_64 490 | teamd.x86_64 491 | telnet.x86_64 492 | traceroute.x86_64 493 | ttmkfdir.x86_64 494 | tuned.noarch 495 | tzdata.noarch 496 | tzdata-java.noarch 497 | unzip.x86_64 498 | usermode.x86_64 499 | ustr.x86_64 500 | util-linux.x86_64 501 | vasclnt.x86_64 502 | vim-common.x86_64 503 | vim-enhanced.x86_64 504 | vim-filesystem.x86_64 505 | vim-minimal.x86_64 506 | virt-what.x86_64 507 | which.x86_64 508 | wpa_supplicant.x86_64 509 | xClientSIOS.x86_64 510 | xdg-utils.noarch 511 | xfsprogs.x86_64 512 | xinetd.x86_64 513 | xorg-x11-font-utils.x86_64 514 | xorg-x11-fonts-Type1.noarch 515 | xz.x86_64 516 | xz-libs.x86_64 517 | yum.noarch 518 | yum-metadata-parser.x86_64 519 | yum-rhn-plugin.noarch 520 | yum-utils.noarch 521 | zip.x86_64 522 | zlib.x86_64 523 | -------------------------------------------------------------------------------- /src/test/resources/purl/redhatPurl.txt: -------------------------------------------------------------------------------- 1 | Loaded plugins: amazon-id 2 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 3 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/product/rhui-client-config-server-7.crt 4 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/rhui-client-config-server-7.key 5 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 6 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 7 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 8 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 9 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 10 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 11 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 12 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 13 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 14 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 15 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 16 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 17 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 18 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 19 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 20 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 21 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 22 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 23 | https://rhui3.us-west-2.aws.ce.redhat.com/pulp/repos/content/dist/rhel/rhui/server/7/7Server/x86_64/os/Packages/z/zip-3.0-11.el7.x86_64.rpm 24 | -------------------------------------------------------------------------------- /src/test/resources/purl/redhatPurl2.txt: -------------------------------------------------------------------------------- 1 | Loaded plugins: amazon-id 2 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 3 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/product/rhui-client-config-server-7.crt 4 | Repo rhui-client-config-server-7 forced skip_if_unavailable=True due to: /etc/pki/rhui/rhui-client-config-server-7.key 5 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 6 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 7 | Repo rhel-7-server-rhui-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 8 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 9 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 10 | Repo rhel-7-server-rhui-extras-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 11 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 12 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 13 | Repo rhel-7-server-rhui-optional-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 14 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 15 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 16 | Repo rhel-7-server-rhui-rh-common-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 17 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 18 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 19 | Repo rhel-7-server-rhui-supplementary-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 20 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/cdn.redhat.com-chain.crt 21 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/product/content-rhel7.crt 22 | Repo rhel-server-rhui-rhscl-7-rpms forced skip_if_unavailable=True due to: /etc/pki/rhui/content-rhel7.key 23 | No Match for argument amazon-cloudwatch-agent.x86_64 24 | Nothing to download 25 | 26 | -------------------------------------------------------------------------------- /src/test/resources/version/alpineVersion.txt: -------------------------------------------------------------------------------- 1 | WARNING: Ignoring APKINDEX.2c4ac24e.tar.gz: No such file or directory 2 | WARNING: Ignoring APKINDEX.40a3604f.tar.gz: No such file or directory 3 | musl policy: 4 | 1.1.24-r8: 5 | lib/apk/db/installed -------------------------------------------------------------------------------- /src/test/resources/version/ubuntuVersion.txt: -------------------------------------------------------------------------------- 1 | curl: 2 | Installed: 7.58.0-2ubuntu3.10 3 | Candidate: 7.58.0-2ubuntu3.10 4 | Version table: 5 | *** 7.58.0-2ubuntu3.10 500 6 | 500 http://us.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages 7 | 500 http://security.ubuntu.com/ubuntu bionic-security/main amd64 Packages 8 | 100 /var/lib/dpkg/status 9 | 7.58.0-2ubuntu3 500 10 | 500 http://us.archive.ubuntu.com/ubuntu bionic/main amd64 Packages 11 | -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -z "$JAVA_HOME" ] 4 | then 5 | echo "\$JAVA_HOME is empty setting it now." 6 | export JAVA_HOME=./jdk-11 7 | export CLASSPATH=$JAVA_HOME 8 | export PATH=/bin:/usr/bin:$JAVA_HOME/bin 9 | else 10 | echo "\$JAVA_HOME is already set." 11 | fi 12 | 13 | echo $JAVA_HOME 14 | 15 | JAR=$(ls ./target/linux-sbom-generator-[0-9].[0-9].[0-9]-jar-with-dependencies.jar 2> /dev/null) 16 | if [ "$JAR" == "" ] 17 | then 18 | JAR=$(ls ./target/linux-sbom-generator-[0-9].[0-9].[0-9]-SNAPSHOT-jar-with-dependencies.jar 2> /dev/null) 19 | 20 | if [ "$JAR" == "" ] 21 | then 22 | echo "Could not find linux-sbom-generator JAR - did you forget to build it using 'mvn package'?" > /dev/stderr 23 | exit 1 24 | fi 25 | fi 26 | 27 | echo "Found $JAR" 28 | $JAVA_HOME/bin/java -Xms768m -Xmx8192m -Dlog4j.configuration=file:./logging/log4j.xml -jar "$JAR" "$@" 29 | exit $? 30 | --------------------------------------------------------------------------------