1use std::collections::HashMap;
2
3use serde::Deserialize;
4
5#[derive(Deserialize, Debug)]
6#[serde(untagged)]
7pub enum ShodanClientResponse<T> {
8 Error(ErrorResponse),
9 Response(T),
10}
11
12#[derive(Deserialize, Debug)]
13pub struct ErrorResponse {
14 pub error: String,
15}
16
17#[derive(Deserialize, Debug)]
18pub struct AccountProfileResponse {
19 pub member: bool,
20 pub credits: u32,
21 pub display_name: Option<String>,
22 pub created: String,
23}
24
25#[derive(Deserialize, Debug)]
26pub struct ApiInfoResponse {
27 pub scan_credits: u32,
28 pub usage_limits: ApiInfoResponseUsageLimits,
29 pub plan: String,
30 pub https: bool,
31 pub unlocked: bool,
32 pub query_credits: u32,
33 pub monitored_ips: Option<u32>,
34 pub unlocked_left: u32,
35 pub telnet: bool,
36}
37
38#[derive(Deserialize, Debug)]
39pub struct ApiInfoResponseUsageLimits {
40 pub scan_credits: i32,
41 pub query_credits: i32,
42 pub monitored_ips: i32,
43}
44
45#[derive(Deserialize, Debug)]
46pub struct DirectoryQueryResponse {
47 pub matches: Vec<DirectoryQueryResponseMatch>,
48 pub total: u32,
49}
50
51#[derive(Deserialize, Debug)]
52pub struct DirectoryQueryResponseMatch {
53 pub votes: u32,
54 pub description: String,
55 pub tags: Vec<String>,
56 pub timestamp: String,
57 pub title: String,
58 pub query: String,
59}
60
61#[derive(Deserialize, Debug)]
62pub struct DirectoryQueryTagsResponse {
63 pub matches: Vec<DirectoryQueryTagsResponseMatch>,
64 pub total: u32,
65}
66
67#[derive(Deserialize, Debug)]
68pub struct DirectoryQueryTagsResponseMatch {
69 pub count: u32,
70 pub value: String,
71}
72
73#[derive(Deserialize, Debug)]
74pub struct DnsDomainResponse {
75 pub domain: String,
76 pub tags: Vec<String>,
77 pub data: Vec<DnsDomainDataItem>,
78 pub subdomains: Vec<String>,
79 pub more: bool,
80}
81
82#[derive(Deserialize, Debug)]
83pub struct DnsDomainDataItem {
84 pub subdomain: String,
85 #[serde(rename(deserialize = "type"))]
86 pub item_type: String, pub value: String,
88 pub last_seen: String,
89}
90
91#[derive(Deserialize, Debug)]
92pub struct SearchHostIpResponse {
93 pub last_update: String,
94 pub ip: u32,
95 pub ip_str: String,
96 pub ports: Vec<u16>,
97 pub isp: Option<String>,
98 pub asn: Option<String>,
99 pub os: Option<String>,
100 pub domains: Vec<String>,
101 pub hostnames: Vec<String>,
102 pub org: Option<String>,
103 pub latitude: Option<f64>,
104 pub longitude: Option<f64>,
105 pub country_code: Option<String>,
106 pub country_code_3: Option<String>,
107 pub country_name: Option<String>,
108 pub region_code: Option<String>,
109 pub postal_code: Option<String>,
110 pub city: Option<String>,
111 pub dma_code: Option<u32>,
112 pub tags: Vec<String>,
113 pub area_code: Option<String>,
114}
115
116#[derive(Deserialize, Debug)]
117pub struct CountResponse {
118 pub total: u32,
119 pub facets: Option<HashMap<String, Vec<Facet>>>,
120}
121
122#[derive(Deserialize, Debug)]
123pub struct TokenResponse {
124 pub attributes: HashMap<String, Vec<i32>>,
125 pub errors: Vec<String>,
126 pub string: String,
127 pub filters: Vec<String>,
128}
129
130#[derive(Deserialize, Debug)]
131pub struct Facet {
132 pub count: u32,
133 pub value: String,
134}
135
136#[derive(Debug, Deserialize)]
137pub struct SearchResult {
138 pub matches: Vec<SearchResultMatch>,
139 pub total: i64,
140 pub facets: Option<HashMap<String, Vec<Facet>>>,
141}
142
143#[derive(Debug, Deserialize)]
144pub struct SearchResultMatch {
145 pub hash: i64,
146 pub asn: Option<String>,
147 pub http: Option<Http>,
148 pub os: Option<String>,
149 pub tags: Option<Vec<String>>,
150 pub timestamp: String,
151 pub isp: Option<String>,
152 pub transport: String,
153 #[serde(rename = "_shodan")]
154 pub shodan: Shodan,
155 pub ssl: Option<Ssl>,
156 pub cloud: Option<Cloud>,
157 pub hostnames: Vec<String>,
158 pub location: LocationClass,
159 pub ip: Option<i64>,
160 pub domains: Vec<String>,
161 pub org: Option<String>,
162 pub data: String,
163 pub port: i64,
164 pub ip_str: String,
165 pub product: Option<String>,
166 pub cpe23: Option<Vec<String>>,
167 pub cpe: Option<Vec<String>>,
168 pub version: Option<String>,
169 pub mysql: Option<Mysql>,
170 pub info: Option<String>,
171 pub vulns: Option<HashMap<String, Vuln>>,
172 pub ipv6: Option<String>,
173}
174
175#[derive(Debug, Deserialize)]
176pub struct Cloud {
177 pub region: Option<String>,
178 pub service: Option<String>,
179 pub provider: String,
180}
181
182#[derive(Debug, Deserialize)]
183pub struct Http {
184 pub status: i64,
185 pub robots_hash: Option<i64>,
186 pub redirects: Vec<Redirect>,
187 pub securitytxt: Option<String>,
188 pub title: Option<String>,
189 pub sitemap_hash: Option<i64>,
190 pub robots: Option<String>,
191 pub server: Option<String>,
192 pub headers_hash: i64,
193 pub host: String,
194 pub html: String,
195 pub location: String,
196 pub components: Option<HashMap<String, Component>>,
197 pub html_hash: i64,
198 pub sitemap: Option<String>,
199 pub securitytxt_hash: Option<i64>,
200 pub favicon: Option<Favicon>,
201 pub waf: Option<String>,
202}
203
204#[derive(Debug, Deserialize)]
205pub struct Component {
206 pub categories: Vec<String>,
207}
208
209#[derive(Debug, Deserialize)]
210pub struct Favicon {
211 pub hash: i64,
212 pub data: String,
213 pub location: String,
214}
215
216#[derive(Debug, Deserialize)]
217pub struct Redirect {
218 pub host: String,
219 pub data: String,
220 pub location: String,
221 pub html: Option<String>,
222}
223
224#[derive(Debug, Deserialize)]
225pub struct LocationClass {
226 pub city: String,
227 pub region_code: String,
228 pub area_code: Option<String>,
229 pub longitude: f64,
230 pub latitude: f64,
231 pub country_code: String,
232 pub country_name: String,
233}
234
235#[derive(Debug, Deserialize)]
236pub struct Mysql {
237 pub authentication_plugin: String,
238 pub capabilities: i64,
239 pub server_status: String,
240 pub thread_id: i64,
241 pub version: String,
242 pub extended_server_capabilities: i64,
243 pub protocol_version: i64,
244 pub server_language: i64,
245}
246
247#[derive(Debug, Deserialize)]
248pub struct Shodan {
249 pub region: String,
250 pub ptr: Option<bool>,
251 pub module: String,
252 pub id: String,
253 pub options: HashMap<String, String>,
254 pub crawler: String,
255}
256
257#[derive(Debug, Deserialize)]
258pub struct Ssl {
259 pub chain_sha256: Vec<String>,
260 pub jarm: String,
261 pub chain: Vec<String>,
262 pub dhparams: Option<Dhparams>,
263 pub versions: Vec<String>,
264 pub tlsext: Vec<Tlsext>,
266 #[serde(rename = "ja3s")]
267 pub ja3_s: String,
268 pub cert: Cert,
269 pub cipher: Cipher,
270 pub trust: Trust,
271 pub handshake_states: Vec<String>,
272 pub alpn: Vec<String>,
273 pub ocsp: Ocsp,
274}
275
276#[derive(Debug, Deserialize)]
277pub struct Cert {
278 pub sig_alg: String,
279 pub issued: String,
280 pub expires: String,
281 pub expired: bool,
282 pub version: i64,
283 pub extensions: Vec<Extension>,
284 pub fingerprint: Fingerprint,
285 pub serial: f64,
286 pub subject: Issuer,
287 pub pubkey: Pubkey,
288 pub issuer: Issuer,
289}
290
291#[derive(Debug, Deserialize)]
292pub struct Extension {
293 pub critical: Option<bool>,
294 pub data: String,
295 pub name: String,
296}
297
298#[derive(Debug, Deserialize)]
299pub struct Fingerprint {
300 pub sha256: String,
301 pub sha1: String,
302}
303
304#[derive(Debug, Deserialize)]
305pub struct Issuer {
306 #[serde(rename = "C")]
307 pub c: Option<String>,
308 #[serde(rename = "CN")]
309 pub cn: Option<String>,
310 #[serde(rename = "O")]
311 pub o: Option<String>,
312 #[serde(rename = "L")]
313 pub l: Option<String>,
314 #[serde(rename = "ST")]
315 pub st: Option<String>,
316 #[serde(rename = "OU")]
317 pub ou: Option<String>,
318 #[serde(rename = "emailAddress")]
319 pub email_address: Option<String>,
320}
321
322#[derive(Debug, Deserialize)]
323pub struct Pubkey {
324 #[serde(rename = "type")]
325 pub pubkey_type: String,
326 pub bits: i64,
327}
328
329#[derive(Debug, Deserialize)]
330pub struct Cipher {
331 pub version: String,
332 pub bits: i64,
333 pub name: String,
334}
335
336#[derive(Debug, Deserialize)]
337pub struct Dhparams {
338 pub prime: String,
339 pub public_key: String,
340 pub bits: i64,
341 pub generator: i64,
342 pub fingerprint: Option<String>,
343}
344
345#[derive(Debug, Deserialize)]
346pub struct Ocsp {
347 pub version: Option<String>,
348 pub response_status: Option<String>,
349 pub responder_id: Option<String>,
350 pub cert_status: Option<String>,
351 pub produced_at: Option<String>,
352 pub signature_algorithm: Option<String>,
353 pub next_update: Option<String>,
354 pub this_update: Option<String>,
355 pub certificate_id: Option<CertificateId>,
356}
357
358#[derive(Debug, Deserialize)]
359pub struct CertificateId {
360 pub hash_algorithm: String,
361 pub issuer_name_hash: String,
362 pub issuer_name_key: String,
363 pub serial_number: String,
364}
365
366#[derive(Debug, Deserialize)]
367pub struct Tlsext {
368 pub id: i64,
369 pub name: String,
370}
371
372#[derive(Debug, Deserialize)]
373pub struct Trust {
374 pub revoked: bool,
375 pub browser: Option<Browser>,
376}
377
378#[derive(Debug, Deserialize)]
379pub struct Browser {
380 pub mozilla: bool,
381 pub apple: bool,
382 pub microsoft: bool,
383}
384
385#[derive(Debug, Deserialize)]
386pub struct Vuln {
387 pub verified: bool,
388 pub references: Vec<String>,
389 pub cvss: Option<f64>,
390 pub summary: String,
391}