1use super::*;
2use std::collections::HashMap;
3use swagger::scan::active::{ActiveScan, ActiveScanType};
4use swagger::scan::passive::PassiveSwaggerScan;
5use swagger::scan::Level;
6use swagger::{Authorization, Check, EpTable, ParamTable, PassiveScanType, Swagger, OAS, OAS3_1, Server};
7
8pub fn run_passive_swagger_scan<T>(
9 scan_try: Result<PassiveSwaggerScan<T>, &'static str>,
10 verbosity: u8,
11 output_file: Option<String>,
12 passive_scan_type: PassiveScanType,
13 json: bool,
14) -> Result<i8, &'static str>
15where
16 T: OAS + Serialize + for<'de> Deserialize<'de> + std::fmt::Debug,
17{
18 let mut scan = match scan_try {
19 Ok(s) => s,
20 Err(e) => {
21 return Err(e);
22 }
23 };
24 scan.run(passive_scan_type);
25 if json {
26 let mut out_json: HashMap<&str, Vec<swagger::scan::Alert>> = HashMap::new();
27 for check in scan.passive_checks.iter() {
28 if !check.inner().is_empty() {
29 out_json.insert(check.name(), check.inner().clone());
30 }
31 }
32 print!("{}", serde_json::to_string(&out_json).unwrap());
33 } else {
34 scan.print(verbosity);
35 }
36 let failed = scan.passive_checks.iter().any(|c| c.result() == "FAILED"); if let Some(f) = output_file {
38 let print = if json {
39 serde_json::to_string(&scan).unwrap()
40 } else {
41 scan.print_to_file_string()
42 };
43 write_to_file(&f, print);
44 }
45 if failed {
46 Ok(101)
47 } else {
48 Ok(0)
49 }
50}
51
52pub async fn run_active_swagger_scan<T>(
53 scan_try: Result<ActiveScan<T>, &'static str>,
54 verbosity: u8,
55 output_file: Option<String>,
56 auth: Authorization,
57 scan_type: ActiveScanType,
58 json: bool,
59 _servers: Option<Vec<Server>>,
60) -> Result<i8, &'static str>
61where
62 T: OAS + Serialize + for<'de> Deserialize<'de> + std::fmt::Debug,
63{
64 let mut scan = match scan_try {
65 Ok(s) => s,
66 Err(e) => {
67 return Err(e);
68 }
69 };
70 scan.run(scan_type, &auth).await;
71 if json {
72 let mut out_json: HashMap<&str, Vec<swagger::scan::Alert>> = HashMap::new();
73 for check in scan.checks.iter() {
74 if !check.inner().is_empty() {
75 out_json.insert(check.name(), check.inner().clone());
76 }
77 }
78 print!("{}", serde_json::to_string(&out_json).unwrap());
79 } else {
80 scan.print(verbosity);
81 }
82 let failed = scan
83 .checks
84 .iter()
85 .any(|c| (c.result() == "FAILED") || (c.top_severity() > Level::Info));
86 if let Some(f) = output_file {
87 let print = scan.print_to_file_string();
88 write_to_file(&f, print);
89 }
90 if failed {
91 Ok(101)
92 } else {
93 Ok(0)
94 }
95}
96
97#[allow(clippy::too_many_arguments)]
99pub async fn run_swagger(
100 file: &str,
101 verbosity: u8,
102 output_file: Option<String>,
103 auth: Authorization,
104 no_active: bool,
105 active_scan_type: ActiveScanType,
106 passive_scan_type: PassiveScanType,
107 json: bool, ) -> i8 {
108 let (value, version) = if let Some((v1, v2)) = get_oas_value_version(file) {
109 (v1, v2)
110 } else { return -1 };
111 if version.starts_with("3.") {
112 if json {
113 print!("{{\"passive checks\":");
114 }
115 let passive_result = run_passive_swagger_scan::<OAS3_1>(
116 PassiveSwaggerScan::<OAS3_1>::new(value.clone()),
117 verbosity,
118 output_file.clone(),
119 passive_scan_type,
120 json,
121 );
122 if let Err(e) = passive_result {
123 print_err(e);
124 return -1;
125 }
126 if json {
127 print!(",\"active checks\":");
128 }
129 let active_result = if !no_active && value.get("servers").is_some() {
130 run_active_swagger_scan::<OAS3_1>(
131 ActiveScan::<OAS3_1>::new(value.clone()),
132 verbosity,
133 output_file.clone(),
134 auth,
135 active_scan_type,
136 json,
137 None, )
139 .await
140 } else {
141 Ok(0)
142 };
143 if let Err(e) = active_result {
144 print_err(e);
145 return -1;
146 }
147 if json {
148 print!("}}")
149 }
150 if passive_result.unwrap() == 0 && active_result.unwrap() == 0 {
151 0i8
152 } else {
153 101i8
154 }
155 } else {
156 print_err("Unsupported OpenAPI specification version");
157 -1
158 }
159}
160
161pub fn param_table(file: &str, param: Option<String>) {
162 let (value, version) = if let Some((v1, v2)) = get_oas_value_version(file) {
163 (v1, v2)
164 } else {
165 return;
166 };
167 if version.starts_with("3.0") {
168 let table = ParamTable::new::<Swagger>(&value);
169 if let Some(p) = param {
170 table.named_param(&p).print();
171 } else {
172 table.print();
173 }
174 } else if version.starts_with("3.1") {
175 let table = ParamTable::new::<OAS3_1>(&value);
176 if let Some(p) = param {
177 table.named_param(&p).print();
178 } else {
179 table.print();
180 }
181 } else {
182 print_err("Unsupported OpenAPI specification version");
183 }
184}
185
186pub fn ep_table(file: &str, path: Option<String>) {
187 let (value, version) = if let Some((v1, v2)) = get_oas_value_version(file) {
188 (v1, v2)
189 } else {
190 return;
191 };
192 if version.starts_with("3.0") {
193 let table = EpTable::new::<Swagger>(&value);
194 if let Some(p) = path {
195 table.path_only(&p).print();
196 } else {
197 table.print();
198 }
199 } else if version.starts_with("3.1") {
200 let table = EpTable::new::<OAS3_1>(&value);
201 if let Some(p) = path {
202 table.path_only(&p).print();
203 } else {
204 table.print();
205 }
206 } else {
207 print_err("Unsupported OpenAPI specification version");
208 }
209}