shodanz 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32aa0999f1cb087637e0abe8428bd70592f22a3761da87be09bcf1a2bd8c2d37
4
- data.tar.gz: a6d8a053446c3163bb3ee7630c5663510e6568469cd0569e6c6d4ad67d1873a3
3
+ metadata.gz: 410e95de412de33cdbe2fb4fd47ed7eda7e9bdbc1dc86f68a09050cf5ec316fc
4
+ data.tar.gz: 94dc8c3425f95bd0d7294499618e58f2f3e4b88f174f132ced5b2316a52800b1
5
5
  SHA512:
6
- metadata.gz: d3c5e27187e510f5b811bee421194b269bcc1092bc4b212c7a172c342f1b6a4c932314e5198e89b16509ce6c1345714e232461e4c3b34de1bf2262797a435bdf
7
- data.tar.gz: d66f4fc7e68963a54870b789a1b63ada8ffe3174947f6b641dfa8b43547d77ef37b73fc16ff7c4f8715244be8449037dcc5fa2b7028cf50424b43a6004c4297b
6
+ metadata.gz: 29dea01f7e595b0b7eb6700eaa5e04dac0a426606c6bd28882b9ac484c48e48bb9ff35aa26cfd7b60996cde16273ff27d92534dd5e7909997c75c58c94b0d228
7
+ data.tar.gz: e7c851400c229bd11749d4acafc8c9b784ef29b61c40f1187db7774886f565aa82935086f648178eac2e3f6782f5618572074fa5a468803c670a3ae31d4ed2d6
data/README.md CHANGED
@@ -289,10 +289,10 @@ The Exploits API provides access to several exploit/ vulnerability data sources.
289
289
  Search across a variety of data sources for exploits and use facets to get summary information.
290
290
 
291
291
  ```ruby
292
- client.search("python") # Search for Snek vulns.
293
- client.search(post: 22) # Port number for the affected service if the exploit is remote.
294
- client.search(type: "shellcode") # A category of exploit to search for.
295
- client.search(osvdb: "100007") # Open Source Vulnerability Database ID for the exploit.
292
+ client.exploits_api.search("python") # Search for python vulns.
293
+ client.exploits_api.search(port: 22) # Port number for the affected service if the exploit is remote.
294
+ client.exploits_api.search(type: "shellcode") # A category of exploit to search for.
295
+ client.exploits_api.search(osvdb: "100007") # Open Source Vulnerability Database ID for the exploit.
296
296
  ```
297
297
 
298
298
  #### Count
@@ -300,10 +300,10 @@ client.search(osvdb: "100007") # Open Source Vulnerability Database ID for
300
300
  This method behaves identical to the Exploits API `search` method with the difference that it doesn't return any results.
301
301
 
302
302
  ```ruby
303
- client.count("python") # Count Snek vulns.
304
- client.count(port: 22) # Port number for the affected service if the exploit is remote.
305
- client.count(type: "shellcode") # A category of exploit to search for.
306
- client.count(osvdb: "100007") # Open Source Vulnerability Database ID for the exploit.
303
+ client.exploits_api.count("python") # Count python vulns.
304
+ client.exploits_api.count(port: 22) # Port number for the affected service if the exploit is remote.
305
+ client.exploits_api.count(type: "shellcode") # A category of exploit to search for.
306
+ client.exploits_api.count(osvdb: "100007") # Open Source Vulnerability Database ID for the exploit.
307
307
  ```
308
308
 
309
309
  ## License
@@ -61,40 +61,51 @@ module Shodanz
61
61
 
62
62
  private
63
63
 
64
- RATELIMIT = 'rate limit reached'
65
- NOINFO = 'no information available'
66
- NOQUERY = 'empty search query'
64
+ RATELIMIT = 'rate limit reached'
65
+ NOINFO = 'no information available'
66
+ NOQUERY = 'empty search query'
67
+ ACCESSDENIED = 'access denied'
68
+ INVALIDKEY = 'invalid API key'
67
69
 
68
70
  def handle_any_json_errors(json)
69
- return json unless json.is_a?(Hash) && json.key?('error')
70
-
71
- raise Shodanz::Errors::RateLimited if json['error'].casecmp(RATELIMIT) >= 0
72
- raise Shodanz::Errors::NoInformation if json['error'].casecmp(NOINFO) >= 0
73
- raise Shodanz::Errors::NoQuery if json['error'].casecmp(NOQUERY) >= 0
74
-
75
- json
71
+ if json.is_a?(Hash) && json.key?('error')
72
+ raise Shodanz::Errors::RateLimited if json['error'].casecmp(RATELIMIT) >= 0
73
+ raise Shodanz::Errors::NoInformation if json['error'].casecmp(NOINFO) >= 0
74
+ raise Shodanz::Errors::NoQuery if json['error'].casecmp(NOQUERY) >= 0
75
+ raise Shodanz::Errors::AccessDenied if json['error'].casecmp(ACCESSDENIED) >= 0
76
+ raise Shodanz::Errors::InvalidKey if json['error'].casecmp(INVALIDKEY) >= 0
77
+ end
78
+ return json
76
79
  end
77
80
 
78
- def getter(path, **params)
81
+ def getter(path, one_shot=false, **params)
79
82
  # param keys should all be strings
80
83
  params = params.transform_keys(&:to_s)
81
84
  # build up url string based on special params
82
85
  url = "#{@url}#{path}?key=#{@key}"
83
86
  # special params
84
87
  params.each do |param,value|
85
- url += "&#{param}=#{value}" unless value.is_a?(String) && value.empty?
88
+ next if value.is_a?(String) && value.empty?
89
+ value = URI.encode_www_form_component("#{value}")
90
+ url += "&#{param}=#{value}"
86
91
  end
92
+
87
93
  resp = @internet.get(url)
88
94
 
89
95
  # parse all lines in the response body as JSON
90
96
  json = JSON.parse(resp.body.join)
91
97
 
98
+ @internet.close if one_shot
99
+
92
100
  handle_any_json_errors(json)
101
+
102
+ return json
93
103
  ensure
94
104
  resp&.close
105
+ @internet = Async::HTTP::Internet.new if one_shot
95
106
  end
96
107
 
97
- def poster(path, **params)
108
+ def poster(path, one_shot=false, **params)
98
109
  # param keys should all be strings
99
110
  params = params.transform_keys(&:to_s)
100
111
  # make POST request to server
@@ -103,9 +114,14 @@ module Shodanz
103
114
  # parse all lines in the response body as JSON
104
115
  json = JSON.parse(resp.body.join)
105
116
 
117
+ @internet.close if one_shot
118
+
106
119
  handle_any_json_errors(json)
120
+
121
+ return json
107
122
  ensure
108
123
  resp&.close
124
+ @internet = Async::HTTP::Internet.new if one_shot
109
125
  end
110
126
 
111
127
  def slurper(path, **params)
@@ -135,25 +151,25 @@ module Shodanz
135
151
 
136
152
  def async_get(path, **params)
137
153
  Async::Task.current.async do
138
- getter(path, **params)
154
+ getter(path, false, **params)
139
155
  end
140
156
  end
141
157
 
142
158
  def sync_get(path, **params)
143
159
  Async do
144
- getter(path, **params)
160
+ getter(path, true, **params)
145
161
  end.wait
146
162
  end
147
163
 
148
164
  def async_post(path, **params)
149
165
  Async::Task.current.async do
150
- poster(path, **params)
166
+ poster(path, false, **params)
151
167
  end
152
168
  end
153
169
 
154
170
  def sync_post(path, **params)
155
171
  Async do
156
- poster(path, **params)
172
+ poster(path, true, **params)
157
173
  end.wait
158
174
  end
159
175
 
@@ -25,5 +25,17 @@ module Shodanz
25
25
  super
26
26
  end
27
27
  end
28
+
29
+ class AccessDenied < StandardError
30
+ def initialize(msg = 'Shodan subscription doesn\'t support action, check API permissions!')
31
+ super
32
+ end
33
+ end
34
+
35
+ class InvalidKey < StandardError
36
+ def initialize(msg = 'Invalid API key used, or none given!')
37
+ super
38
+ end
39
+ end
28
40
  end
29
41
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Shodanz
4
- VERSION = '2.0.1'
4
+ VERSION = '2.0.2'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shodanz
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kent 'picatz' Gruber
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-28 00:00:00.000000000 Z
11
+ date: 2020-02-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async-http