View Javadoc
1   /*
2    * This file is part of dependency-check-cli.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck;
19  
20  import java.io.File;
21  import java.io.FileNotFoundException;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.util.List;
25  import java.util.logging.Level;
26  import java.util.logging.Logger;
27  import org.apache.commons.cli.ParseException;
28  import org.owasp.dependencycheck.cli.CliParser;
29  import org.owasp.dependencycheck.data.nvdcve.CveDB;
30  import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
31  import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
32  import org.owasp.dependencycheck.dependency.Dependency;
33  import org.owasp.dependencycheck.reporting.ReportGenerator;
34  import org.owasp.dependencycheck.utils.LogUtils;
35  import org.owasp.dependencycheck.utils.Settings;
36  
37  /**
38   * The command line interface for the DependencyCheck application.
39   *
40   * @author Jeremy Long <jeremy.long@owasp.org>
41   */
42  public class App {
43  
44      /**
45       * The location of the log properties configuration file.
46       */
47      private static final String LOG_PROPERTIES_FILE = "log.properties";
48  
49      /**
50       * The main method for the application.
51       *
52       * @param args the command line arguments
53       */
54      public static void main(String[] args) {
55          final App app = new App();
56          app.run(args);
57      }
58  
59      /**
60       * Main CLI entry-point into the application.
61       *
62       * @param args the command line arguments
63       */
64      public void run(String[] args) {
65  
66          final CliParser cli = new CliParser();
67          try {
68              cli.parse(args);
69          } catch (FileNotFoundException ex) {
70              System.err.println(ex.getMessage());
71              cli.printHelp();
72              return;
73          } catch (ParseException ex) {
74              System.err.println(ex.getMessage());
75              cli.printHelp();
76              return;
77          }
78  
79          final InputStream in = App.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
80          LogUtils.prepareLogger(in, cli.getVerboseLog());
81  
82          if (cli.isGetVersion()) {
83              cli.printVersionInfo();
84          } else if (cli.isRunScan()) {
85              updateSettings(cli);
86              runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getApplicationName(), cli.getScanFiles());
87          } else {
88              cli.printHelp();
89          }
90      }
91  
92      /**
93       * Scans the specified directories and writes the dependency reports to the reportDirectory.
94       *
95       * @param reportDirectory the path to the directory where the reports will be written
96       * @param outputFormat the output format of the report
97       * @param applicationName the application name for the report
98       * @param files the files/directories to scan
99       */
100     private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files) {
101         Engine scanner = null;
102         try {
103             scanner = new Engine();
104 
105             for (String file : files) {
106                 scanner.scan(file);
107             }
108 
109             scanner.analyzeDependencies();
110             final List<Dependency> dependencies = scanner.getDependencies();
111             DatabaseProperties prop = null;
112             CveDB cve = null;
113             try {
114                 cve = new CveDB();
115                 cve.open();
116                 prop = cve.getDatabaseProperties();
117             } catch (DatabaseException ex) {
118                 Logger.getLogger(App.class.getName()).log(Level.FINE, "Unable to retrieve DB Properties", ex);
119             } finally {
120                 if (cve != null) {
121                     cve.close();
122                 }
123             }
124             final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers(), prop);
125             try {
126                 report.generateReports(reportDirectory, outputFormat);
127             } catch (IOException ex) {
128                 Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an IO error while attempting to generate the report.");
129                 Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
130             } catch (Throwable ex) {
131                 Logger.getLogger(App.class.getName()).log(Level.SEVERE, "There was an error while attempting to generate the report.");
132                 Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
133             }
134         } catch (DatabaseException ex) {
135             Logger.getLogger(App.class.getName()).log(Level.SEVERE, "Unable to connect to the dependency-check database; analysis has stopped");
136             Logger.getLogger(App.class.getName()).log(Level.FINE, "", ex);
137         } finally {
138             if (scanner != null) {
139                 scanner.cleanup();
140             }
141         }
142     }
143 
144     /**
145      * Updates the global Settings.
146      *
147      * @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding
148      * settings in the core engine.
149      */
150     private void updateSettings(CliParser cli) {
151 
152         final boolean autoUpdate = cli.isAutoUpdate();
153         final String connectionTimeout = cli.getConnectionTimeout();
154         final String proxyUrl = cli.getProxyUrl();
155         final String proxyPort = cli.getProxyPort();
156         final String proxyUser = cli.getProxyUsername();
157         final String proxyPass = cli.getProxyPassword();
158         final String dataDirectory = cli.getDataDirectory();
159         final File propertiesFile = cli.getPropertiesFile();
160         final String suppressionFile = cli.getSuppressionFile();
161         final boolean nexusDisabled = cli.isNexusDisabled();
162         final String nexusUrl = cli.getNexusUrl();
163         final boolean nexusUsesProxy = cli.isNexusUsesProxy();
164         final String databaseDriverName = cli.getDatabaseDriverName();
165         final String databaseDriverPath = cli.getDatabaseDriverPath();
166         final String connectionString = cli.getConnectionString();
167         final String databaseUser = cli.getDatabaseUser();
168         final String databasePassword = cli.getDatabasePassword();
169         final String additionalZipExtensions = cli.getAdditionalZipExtensions();
170 
171         if (propertiesFile != null) {
172             try {
173                 Settings.mergeProperties(propertiesFile);
174             } catch (FileNotFoundException ex) {
175                 final String msg = String.format("Unable to load properties file '%s'", propertiesFile.getPath());
176                 Logger.getLogger(App.class.getName()).log(Level.SEVERE, msg);
177                 Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
178             } catch (IOException ex) {
179                 final String msg = String.format("Unable to find properties file '%s'", propertiesFile.getPath());
180                 Logger.getLogger(App.class.getName()).log(Level.SEVERE, msg);
181                 Logger.getLogger(App.class.getName()).log(Level.FINE, null, ex);
182             }
183         }
184         if (dataDirectory != null) {
185             Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
186         } else if (System.getProperty("basedir") != null) {
187             final File dataDir = new File(System.getProperty("basedir"), "data");
188             Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
189         } else {
190             final File jarPath = new File(App.class.getProtectionDomain().getCodeSource().getLocation().getPath());
191             final File base = jarPath.getParentFile();
192             final String sub = Settings.getString(Settings.KEYS.DATA_DIRECTORY);
193             final File dataDir = new File(base, sub);
194             Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDir.getAbsolutePath());
195         }
196         Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
197         if (proxyUrl != null && !proxyUrl.isEmpty()) {
198             Settings.setString(Settings.KEYS.PROXY_URL, proxyUrl);
199         }
200         if (proxyPort != null && !proxyPort.isEmpty()) {
201             Settings.setString(Settings.KEYS.PROXY_PORT, proxyPort);
202         }
203         if (proxyUser != null && !proxyUser.isEmpty()) {
204             Settings.setString(Settings.KEYS.PROXY_USERNAME, proxyUser);
205         }
206         if (proxyPass != null && !proxyPass.isEmpty()) {
207             Settings.setString(Settings.KEYS.PROXY_PASSWORD, proxyPass);
208         }
209         if (connectionTimeout != null && !connectionTimeout.isEmpty()) {
210             Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, connectionTimeout);
211         }
212         if (suppressionFile != null && !suppressionFile.isEmpty()) {
213             Settings.setString(Settings.KEYS.SUPPRESSION_FILE, suppressionFile);
214         }
215         Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED, !nexusDisabled);
216         if (nexusUrl != null && !nexusUrl.isEmpty()) {
217             Settings.setString(Settings.KEYS.ANALYZER_NEXUS_URL, nexusUrl);
218         }
219         Settings.setBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY, nexusUsesProxy);
220         if (databaseDriverName != null && !databaseDriverName.isEmpty()) {
221             Settings.setString(Settings.KEYS.DB_DRIVER_NAME, databaseDriverName);
222         }
223         if (databaseDriverPath != null && !databaseDriverPath.isEmpty()) {
224             Settings.setString(Settings.KEYS.DB_DRIVER_PATH, databaseDriverPath);
225         }
226         if (connectionString != null && !connectionString.isEmpty()) {
227             Settings.setString(Settings.KEYS.DB_CONNECTION_STRING, connectionString);
228         }
229         if (databaseUser != null && !databaseUser.isEmpty()) {
230             Settings.setString(Settings.KEYS.DB_USER, databaseUser);
231         }
232         if (databasePassword != null && !databasePassword.isEmpty()) {
233             Settings.setString(Settings.KEYS.DB_PASSWORD, databasePassword);
234         }
235         if (additionalZipExtensions != null && !additionalZipExtensions.isEmpty()) {
236             Settings.setString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS, additionalZipExtensions);
237         }
238     }
239 }