Skip to main content

shodan_client/
response.rs

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, // Type is a reserved keyword
87    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 acceptable_cas: Vec<String>,
265    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}