shodanz 2.0.1 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
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