■ ■ ■ ■ ■ ■ ■
main/src/main/java/com/google/tsunami/main/cli/TsunamiCli.java
| skipped 22 lines |
23 | 23 | | |
24 | 24 | | import com.google.common.base.Splitter; |
25 | 25 | | import com.google.common.base.Stopwatch; |
| 26 | + | import com.google.common.collect.ImmutableList; |
26 | 27 | | import com.google.common.collect.Iterables; |
| 28 | + | import com.google.common.collect.Lists; |
27 | 29 | | import com.google.common.flogger.GoogleLogger; |
28 | 30 | | import com.google.inject.AbstractModule; |
29 | 31 | | import com.google.inject.Guice; |
| skipped 7 lines |
37 | 39 | | import com.google.tsunami.common.io.archiving.GoogleCloudStorageArchiverModule; |
38 | 40 | | import com.google.tsunami.common.net.http.HttpClientModule; |
39 | 41 | | import com.google.tsunami.common.reflection.ClassGraphModule; |
| 42 | + | import com.google.tsunami.common.server.ServerPortCommand; |
40 | 43 | | import com.google.tsunami.common.time.SystemUtcClockModule; |
41 | 44 | | import com.google.tsunami.main.cli.option.MainCliOptions; |
| 45 | + | import com.google.tsunami.main.cli.server.RemoteServerLoader; |
| 46 | + | import com.google.tsunami.main.cli.server.RemoteServerLoaderModule; |
42 | 47 | | import com.google.tsunami.plugin.PluginExecutionModule; |
43 | 48 | | import com.google.tsunami.plugin.PluginLoadingModule; |
| 49 | + | import com.google.tsunami.plugin.RemoteVulnDetectorLoadingModule; |
44 | 50 | | import com.google.tsunami.plugin.payload.PayloadGeneratorModule; |
45 | 51 | | import com.google.tsunami.proto.ScanResults; |
46 | 52 | | import com.google.tsunami.proto.ScanStatus; |
| skipped 4 lines |
51 | 57 | | import io.github.classgraph.ScanResult; |
52 | 58 | | import java.io.IOException; |
53 | 59 | | import java.security.SecureRandom; |
| 60 | + | import java.util.List; |
54 | 61 | | import java.util.Optional; |
55 | 62 | | import java.util.concurrent.ExecutionException; |
56 | 63 | | import javax.inject.Inject; |
| skipped 5 lines |
62 | 69 | | private final DefaultScanningWorkflow scanningWorkflow; |
63 | 70 | | private final ScanResultsArchiver scanResultsArchiver; |
64 | 71 | | private final MainCliOptions mainCliOptions; |
| 72 | + | private final RemoteServerLoader remoteServerLoader; |
65 | 73 | | |
66 | 74 | | @Inject |
67 | 75 | | TsunamiCli( |
68 | 76 | | DefaultScanningWorkflow scanningWorkflow, |
69 | 77 | | ScanResultsArchiver scanResultsArchiver, |
70 | | - | MainCliOptions mainCliOptions) { |
| 78 | + | MainCliOptions mainCliOptions, |
| 79 | + | RemoteServerLoader remoteServerLoader) { |
71 | 80 | | this.scanningWorkflow = checkNotNull(scanningWorkflow); |
72 | 81 | | this.scanResultsArchiver = checkNotNull(scanResultsArchiver); |
73 | 82 | | this.mainCliOptions = checkNotNull(mainCliOptions); |
| 83 | + | this.remoteServerLoader = checkNotNull(remoteServerLoader); |
74 | 84 | | } |
75 | 85 | | |
76 | 86 | | public boolean run() |
| skipped 1 lines |
78 | 88 | | String logId = (mainCliOptions.logId == null) ? "" : (mainCliOptions.logId + ": "); |
79 | 89 | | // TODO(b/171405612): Find a way to print the log ID at every log line. |
80 | 90 | | logger.atInfo().log("%sTsunamiCli starting...", logId); |
| 91 | + | |
| 92 | + | ImmutableList<Process> languageServerProcesses = remoteServerLoader.runServerProcesses(); |
81 | 93 | | ScanResults scanResults = scanningWorkflow.run(buildScanTarget()); |
| 94 | + | languageServerProcesses.forEach(Process::destroy); |
82 | 95 | | |
83 | 96 | | logger.atInfo().log("Tsunami scan finished, saving results."); |
84 | 97 | | saveResults(scanResults); |
| skipped 54 lines |
139 | 152 | | protected void configure() { |
140 | 153 | | // TODO(b/171405612): Find a way to use the log ID extracted by the CLI options. |
141 | 154 | | String logId = extractLogId(args); |
| 155 | + | |
| 156 | + | // TODO(b/241964583): Only use LanguageServerOptions to extract language server args. |
| 157 | + | ImmutableList<ServerPortCommand> commands = extractPluginServerArgs(args); |
| 158 | + | |
142 | 159 | | install(new ClassGraphModule(classScanResult)); |
143 | 160 | | install(new ConfigModule(classScanResult, tsunamiConfig)); |
144 | 161 | | install(new CliOptionsModule(classScanResult, "TsunamiCli", args)); |
| skipped 5 lines |
150 | 167 | | install(new PluginExecutionModule()); |
151 | 168 | | install(new PluginLoadingModule(classScanResult)); |
152 | 169 | | install(new PayloadGeneratorModule(new SecureRandom())); |
| 170 | + | install(new RemoteServerLoaderModule(commands)); |
| 171 | + | install(new RemoteVulnDetectorLoadingModule(commands)); |
| 172 | + | } |
| 173 | + | |
| 174 | + | private ImmutableList<ServerPortCommand> extractPluginServerArgs(String[] args) { |
| 175 | + | var paths = extractPluginServerPaths(args); |
| 176 | + | var ports = extractPluginServerPorts(args); |
| 177 | + | if (paths.size() == ports.size()) { |
| 178 | + | List<ServerPortCommand> commands = Lists.newArrayList(); |
| 179 | + | for (int i = 0; i < paths.size(); ++i) { |
| 180 | + | commands.add(ServerPortCommand.create(paths.get(i), ports.get(i))); |
| 181 | + | } |
| 182 | + | return ImmutableList.copyOf(commands); |
| 183 | + | } |
| 184 | + | return ImmutableList.of(); |
| 185 | + | } |
| 186 | + | |
| 187 | + | private ImmutableList<String> extractPluginServerPaths(String[] args) { |
| 188 | + | for (int i = 0; i < args.length; ++i) { |
| 189 | + | if (args[i].startsWith("--plugin-server-paths=")) { |
| 190 | + | var paths = Iterables.get(Splitter.on('=').split(args[i]), 1); |
| 191 | + | return ImmutableList.copyOf(Splitter.on(',').split(paths)); |
| 192 | + | } |
| 193 | + | } |
| 194 | + | return ImmutableList.of(); |
| 195 | + | } |
| 196 | + | |
| 197 | + | private ImmutableList<String> extractPluginServerPorts(String[] args) { |
| 198 | + | for (int i = 0; i < args.length; ++i) { |
| 199 | + | if (args[i].startsWith("--plugin-server-ports=")) { |
| 200 | + | var ports = Iterables.get(Splitter.on('=').split(args[i]), 1); |
| 201 | + | return ImmutableList.copyOf(Splitter.on(',').split(ports)); |
| 202 | + | } |
| 203 | + | } |
| 204 | + | return ImmutableList.of(); |
153 | 205 | | } |
154 | 206 | | |
155 | 207 | | private String extractLogId(String[] args) { |
| skipped 26 lines |
182 | 234 | | if (!injector.getInstance(TsunamiCli.class).run()) { |
183 | 235 | | System.exit(1); |
184 | 236 | | } |
185 | | - | |
186 | 237 | | logger.atInfo().log("Full Tsunami scan took %s.", stopwatch.stop()); |
187 | 238 | | } catch (Throwable e) { |
188 | 239 | | logger.atSevere().withCause(e).log("Exiting due to workflow execution exceptions."); |
| skipped 30 lines |