-
Notifications
You must be signed in to change notification settings - Fork 55
/
Copy pathroot.go
179 lines (145 loc) · 7.76 KB
/
root.go
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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package cmd
/*
Copyright © 2021-2024 vdjagilev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
import (
"errors"
"fmt"
"log"
"os"
"github.com/spf13/cobra"
"github.com/vdjagilev/nmap-formatter/v2/formatter"
)
var config = formatter.Config{
OutputOptions: formatter.OutputOptions{
HTMLOptions: formatter.HTMLOutputOptions{},
MarkdownOptions: formatter.MarkdownOutputOptions{},
JSONOptions: formatter.JSONOutputOptions{},
CSVOptions: formatter.CSVOutputOptions{},
SqliteOutputOptions: formatter.SqliteOutputOptions{},
ExcelOptions: formatter.ExcelOutputOptions{},
},
ShowVersion: false,
CurrentVersion: VERSION,
}
// VERSION is describing current version of the nmap-formatter
const VERSION string = "2.1.6"
var workflow formatter.Workflow
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "nmap-formatter [html|csv|md|json|dot|sqlite|excel] [path-to-nmap.xml]",
Short: "Utility that can help you to convert NMAP XML application output to various other formats",
Long: `This utility allows you to convert NMAP XML output to various other formats like (html, csv, markdown (md), json, dot, excel, sqlite)`,
Args: arguments,
RunE: run,
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
if err := rootCmd.Execute(); err != nil {
fmt.Println(err)
os.Exit(1)
}
}
func init() {
// Logging entries go to stderr, while stdout still can be used to save output to the file
log.SetOutput(os.Stderr)
rootCmd.Flags().StringVarP((*string)(&config.OutputFile), "file", "f", "", "-f output-file (by default \"\" will output to STDOUT)")
rootCmd.Flags().BoolVar(&config.ShowVersion, "version", false, "--version, will show you the current version of the app")
rootCmd.Flags().StringArrayVar(&config.CustomOptions, "x-opts", []string{}, "--x-opts=\"some_key=some_value\"")
// Use custom templates for HTML or Markdown output
rootCmd.Flags().StringVar(&config.TemplatePath, "html-use-template", "", "--html-use-template /path/to/template.html")
rootCmd.Flags().StringVar(&config.TemplatePath, "md-use-template", "", "--md-use-template /path/to/template.md")
// Some options related to the output
// Skip hosts that are down, so they won't be listed in the output
rootCmd.Flags().BoolVar(&config.OutputOptions.HTMLOptions.SkipDownHosts, "html-skip-down-hosts", true, "--html-skip-down-hosts=false, would print all hosts that are offline in HTML output")
rootCmd.Flags().BoolVar(&config.OutputOptions.MarkdownOptions.SkipDownHosts, "md-skip-down-hosts", true, "--md-skip-down-hosts=false, would print all hosts that are offline in Markdown output")
rootCmd.Flags().BoolVar(&config.OutputOptions.CSVOptions.SkipDownHosts, "csv-skip-down-hosts", true, "--csv-skip-down-hosts=false, would print all hosts that are offline in CSV output")
// Skip summary (overall meta information from the scan)
rootCmd.Flags().BoolVar(&config.OutputOptions.HTMLOptions.SkipSummary, "html-skip-summary", false, "--html-skip-summary=true, skips summary in HTML output")
rootCmd.Flags().BoolVar(&config.OutputOptions.MarkdownOptions.SkipSummary, "md-skip-summary", false, "--md-skip-summary=true, skips summary in Markdown output")
// Skip traceroute information (from scan machine to the target)
rootCmd.Flags().BoolVar(&config.OutputOptions.HTMLOptions.SkipTraceroute, "html-skip-traceroute", false, "--html-skip-traceroute=true, skips traceroute information in HTML output")
rootCmd.Flags().BoolVar(&config.OutputOptions.MarkdownOptions.SkipTraceroute, "md-skip-traceroute", false, "--md-skip-traceroute=true, skips traceroute information in Markdown output")
// Skip metrics related information
rootCmd.Flags().BoolVar(&config.OutputOptions.HTMLOptions.SkipMetrics, "html-skip-metrics", false, "--html-skip-metrics=true, skips metrics information in HTML output")
rootCmd.Flags().BoolVar(&config.OutputOptions.MarkdownOptions.SkipMetrics, "md-skip-metrics", false, "--md-skip-metrics=true, skips metrics information in Markdown output")
// Skip information from port scripts (nse-scripts)
rootCmd.Flags().BoolVar(&config.OutputOptions.HTMLOptions.SkipPortScripts, "html-skip-port-scripts", false, "--html-skip-port-scripts=true, skips port scripts information in HTML output")
rootCmd.Flags().BoolVar(&config.OutputOptions.MarkdownOptions.SkipPortScripts, "md-skip-port-scripts", false, "--md-skip-port-scripts=true, skips port scripts information in Markdown output")
rootCmd.Flags().BoolVar(&config.OutputOptions.HTMLOptions.DarkMode, "html-dark-mode", true, "--html-dark-mode=false, sets HTML output in dark colours")
rootCmd.Flags().BoolVar(&config.OutputOptions.HTMLOptions.FloatingContentsTable, "html-toc-float", false, "--html-toc-float=true, Table of contents floats along with the scroll")
// Pretty-print json
rootCmd.Flags().BoolVar(&config.OutputOptions.JSONOptions.PrettyPrint, "json-pretty", true, "--json-pretty=false (pretty prints JSON output)")
// Configs related to SQLite
rootCmd.Flags().StringVar(&config.OutputOptions.SqliteOutputOptions.DSN, "sqlite-dsn", "nmap.sqlite", "--sqlite-dsn nmap.sqlite")
rootCmd.Flags().StringVar(&config.OutputOptions.SqliteOutputOptions.ScanIdentifier, "scan-id", "", "--scan-id abc123")
workflow = &formatter.MainWorkflow{}
}
// arguments function validates the arguments passed to the application
// and sets configurations
func arguments(cmd *cobra.Command, args []string) error {
if shouldShowVersion(&config, args) {
return nil
}
if len(args) < 1 {
return errors.New("requires output format argument")
}
config.OutputFormat = formatter.OutputFormat(args[0])
config.InputFileConfig = formatter.InputFileConfig{}
if len(args) > 1 {
config.InputFileConfig.Path = args[1]
} else {
config.InputFileConfig.IsStdin = true
}
return nil
}
// version just prints the current version of nmap-formatter
func version() {
fmt.Printf("nmap-formatter version: %s\n", VERSION)
}
// shouldShowVersion returns boolean whether app should show current version or not
// based on flag passed to the app or first argument
func shouldShowVersion(c *formatter.Config, args []string) bool {
return c.ShowVersion || (len(args) == 1 && args[0] == "version")
}
// run executes the main application workflow and finishes fatally if there is some error
func run(cmd *cobra.Command, args []string) error {
if shouldShowVersion(&config, args) {
version()
return nil
}
err := validate(config)
if err != nil {
return err
}
workflow.SetConfig(&config)
workflow.SetInputFile()
workflow.SetOutputFile()
err = workflow.Execute()
if err != nil {
return err
}
if config.Writer != nil {
config.Writer.Close()
}
if config.InputFileConfig.Source != nil {
config.InputFileConfig.Source.Close()
}
return nil
}