google_safe_browsing 0.4.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2FiMzExYzAyYmY2NTgwZTliYjMzZmFkODJhMDkyZTg3MWU5MWUxMA==
5
+ data.tar.gz: !binary |-
6
+ YWZlYTI2Nzc5NTA0NDU0NWNjYjg2ODIyZGIxMjY5MGNjMDE1MWIxOA==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NWU5ZGNmMjI1NTBlOTZhNGNmOWZhOWZlYTg4NDQ3OTg5NmIyYzJmYjdjZTc0
10
+ NmEyY2RmMGM0MDg2N2FmMjJkY2QwM2U4ODM2ODRhOTgxMWYwZGJlNWQ2ODFk
11
+ NzI0YzVhMzlkYWNjNjNmMDg4YTcyYTkzZGI1ODc2M2IwMGQyMjI=
12
+ data.tar.gz: !binary |-
13
+ OTBmYzk0MzVhN2M2MzI4MGM0M2RhZmNkNTRiYWM3NDRlNDQ4MWE5M2E1ZTBl
14
+ Yzk3YzU0OWUwMzRjNWJkMDE1ZjJiMWFiNjcwYzJhMmI0NWM5NDRjOGYxMzFj
15
+ YWJhZDFmODgwYTI3OWI2MzhlZTk5OTAxYjZmNjQyNjYzNDc1MjU=
data/APACHE-LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2012 Mobile Defense
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -10,6 +10,7 @@ It includes:
10
10
  * method to lookup a url
11
11
  * rake tasks to update hash database
12
12
  * Autonomous updating via Resque and Resque Scheduler (optional)
13
+ * Message Authentication Codes (optional; on by default)
13
14
 
14
15
  ----------------------
15
16
 
@@ -12,6 +12,8 @@ require 'google_safe_browsing/canonicalize'
12
12
  require 'google_safe_browsing/chunk_helper'
13
13
  require 'google_safe_browsing/hash_helper'
14
14
  require 'google_safe_browsing/http_helper'
15
+ require 'google_safe_browsing/invalid_mac_validation'
16
+ require 'google_safe_browsing/key_helper'
15
17
  require 'google_safe_browsing/response_helper'
16
18
  require 'google_safe_browsing/top_level_domain'
17
19
 
@@ -25,14 +27,21 @@ module GoogleSafeBrowsing
25
27
 
26
28
  # Handles the configuration values for the module
27
29
  class Config
28
- attr_accessor :client, :app_ver, :p_ver, :host, :current_lists, :api_key
30
+ attr_accessor :client, :app_ver, :p_ver, :host, :current_lists, :api_key,
31
+ :mac_required, :client_key, :wrapped_key, :rekey_host
29
32
 
30
33
  def initialize
31
34
  @client = 'api'
32
35
  @app_ver = VERSION
33
36
  @p_ver = '2.2'
34
37
  @host = 'http://safebrowsing.clients.google.com/safebrowsing'
38
+ @rekey_host = 'https://sb-ssl.google.com/safebrowsing'
35
39
  @current_lists = [ 'googpub-phish-shavar', 'goog-malware-shavar' ]
40
+ @mac_required = true
41
+ end
42
+
43
+ def have_keys?
44
+ @mac_required && @client_key.present? && @wrapped_key.present?
36
45
  end
37
46
  end
38
47
 
@@ -5,6 +5,8 @@ module GoogleSafeBrowsing
5
5
  #
6
6
  # @return (Integer) the number of seconds before this method should be called again
7
7
  def self.update
8
+ HttpHelper.get_keys unless GoogleSafeBrowsing.config.have_keys?
9
+
8
10
  data_response = HttpHelper.get_data
9
11
 
10
12
  to_do_array = ResponseHelper.parse_data_response(data_response.body)
@@ -1,8 +1,8 @@
1
1
  module GoogleSafeBrowsing
2
2
  class ChunkHelper
3
- def self.build_chunk_list(*list)
4
- lists = if list.any?
5
- list.to_a
3
+ def self.build_chunk_list(*lists)
4
+ lists = if lists.any?
5
+ lists.to_a
6
6
  else
7
7
  GoogleSafeBrowsing.config.current_lists
8
8
  end
@@ -21,29 +21,21 @@ module GoogleSafeBrowsing
21
21
  order(:chunk_number).uniq.collect{|c| c.chunk_number }
22
22
  action_strings << "s:#{squish_number_list(nums)}" if nums.any?
23
23
 
24
- ret += "#{action_strings.join(':')}\n"
24
+ ret += "#{action_strings.join(':')}#{":mac" if GoogleSafeBrowsing.config.have_keys?}\n"
25
25
  end
26
26
 
27
- #puts ret
28
27
  ret
29
28
  end
30
29
 
31
30
  def self.squish_number_list(chunks)
32
31
  num_strings = []
32
+ streak_begin = last_num = chunks.shift
33
33
 
34
- streak_begin = chunks[0]
35
- last_num = chunks.shift
36
34
  chunks.each do |c|
37
- if c == last_num+1
38
- #puts "streak continues"
39
- else
40
- #puts "streak has ended"
35
+ unless c == last_num+1
41
36
  if streak_begin != last_num
42
- streak_string = "#{streak_begin}-#{last_num}"
43
- #puts "there is a streak: #{streak_string}"
44
- num_strings << streak_string
37
+ num_strings << "#{streak_begin}-#{last_num}"
45
38
  else
46
- #puts "streak was one long: #{last_num}"
47
39
  num_strings << last_num
48
40
  end
49
41
  streak_begin = c
@@ -21,7 +21,6 @@ module GoogleSafeBrowsing
21
21
  urls.each do |u|
22
22
  hash = ( Digest::SHA256.new << u ).to_s
23
23
  hashes << GsbHash.new(hash)
24
- #puts "#{u} -- #{hash}"
25
24
  end
26
25
  hashes
27
26
  end
@@ -1,47 +1,126 @@
1
1
  module GoogleSafeBrowsing
2
2
  class HttpHelper
3
- def self.uri_builder(action)
4
- uri = URI("#{GoogleSafeBrowsing.config.host}/#{action}#{encoded_params}")
5
- uri
6
- end
3
+ def self.uri_builder(action, use_ssl=false)
4
+ host = GoogleSafeBrowsing.config.host
5
+ host = switch_to_https(host) if use_ssl
7
6
 
8
- def self.encoded_params
9
- "?client=#{GoogleSafeBrowsing.config.client}" +
10
- "&apikey=#{GoogleSafeBrowsing.config.api_key}" +
11
- "&appver=#{GoogleSafeBrowsing.config.app_ver}" +
12
- "&pver=#{GoogleSafeBrowsing.config.p_ver}"
7
+ uri = URI("#{host}/#{action}#{encoded_params}")
8
+ uri
13
9
  end
14
10
 
15
11
  def self.request_full_hashes(hash_array)
12
+ get_keys unless GoogleSafeBrowsing.config.have_keys?
13
+
16
14
  uri = uri_builder('gethash')
17
- request = Net::HTTP::Post.new(uri.request_uri)
18
- request.body = "4:#{hash_array.length * 4}\n"
19
- hash_array.each do |h|
20
- request.body << BinaryHelper.hex_to_bin(h[0..7])
21
- end
22
15
 
23
- response = Net::HTTP.start(uri.host) { |http| http.request request }
16
+ response = post_data(uri) do
17
+ body = "4:#{hash_array.length * 4}\n"
18
+ hash_array.each do |h|
19
+ body << BinaryHelper.hex_to_bin(h[0..7])
20
+ end
21
+
22
+ body
23
+ end
24
24
 
25
- if response.is_a?(Net::HTTPSuccess) && !response.body.blank? # we are seeing blank responses from Google
25
+ if response.is_a?(Net::HTTPSuccess) && !response.body.blank?
26
26
  ResponseHelper.parse_full_hash_response(response.body)
27
27
  else
28
- # if response not good, return empty array to represent no full hashes
29
28
  []
30
29
  end
31
30
  end
32
31
 
33
32
  def self.get_data(list=nil)
34
- # Get (via Post) List Data
35
33
  uri = uri_builder('downloads')
36
- request = Net::HTTP::Post.new(uri.request_uri)
37
- request.body = ChunkHelper.build_chunk_list(list)
38
34
 
39
- Net::HTTP.start(uri.host) { |http| http.request request }
35
+ post_data(uri) do
36
+ ChunkHelper.build_chunk_list(list)
37
+ end
40
38
  end
41
39
 
42
- def get_lists
43
- uri = uri_builder('list')
44
- Net::HTTP.get(uri).split("\n")
40
+ def self.get_keys
41
+ uri = URI("#{GoogleSafeBrowsing.config.rekey_host}/newkey#{encoded_params}")
42
+
43
+ http = Net::HTTP.new(uri.host, uri.port)
44
+ http.use_ssl = true
45
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
46
+
47
+ request = Net::HTTP::Get.new(uri.request_uri)
48
+ response = http.request(request)
49
+ response.body.split("\n").each do |key_line|
50
+ key_name, _, key_value = key_line.split(':')
51
+ key_value.gsub!('=', '')
52
+
53
+ case key_name
54
+ when 'clientkey'
55
+ key_value = KeyHelper::web_safe_base64_decode(key_value)
56
+ GoogleSafeBrowsing.config.client_key = key_value
57
+ when 'wrappedkey'
58
+ GoogleSafeBrowsing.config.wrapped_key = key_value
59
+ end
60
+ end
45
61
  end
62
+
63
+ private
64
+ REKEY_PREFIX = 'e:pleaserekey'
65
+
66
+ def self.encoded_params
67
+ params = "?client=#{GoogleSafeBrowsing.config.client}" <<
68
+ "&apikey=#{GoogleSafeBrowsing.config.api_key}" <<
69
+ "&appver=#{GoogleSafeBrowsing.config.app_ver}" <<
70
+ "&pver=#{GoogleSafeBrowsing.config.p_ver}"
71
+
72
+ params << "&wrkey=#{GoogleSafeBrowsing.config.wrapped_key}" if GoogleSafeBrowsing.config.have_keys?
73
+
74
+ params
75
+ end
76
+
77
+ def self.with_keys(uri)
78
+ begin
79
+ get_keys unless GoogleSafeBrowsing.config.have_keys?
80
+ response = yield uri
81
+ end while self.please_rekey?(response.body)
82
+
83
+ lines = response.body.split("\n")
84
+ mac = lines.shift
85
+ if mac[0..1] == 'm:'
86
+ mac = mac[2..-1].chomp
87
+ data = lines.join("\n") << "\n"
88
+ else
89
+ data = lines.join("\n")
90
+ end
91
+
92
+ if self.valid_mac?(data, mac)
93
+ response
94
+ else
95
+ raise InvalidMACValidation, "The MAC returned from '#{uri}' is not valid."
96
+ end
97
+ end
98
+
99
+ def self.valid_mac?(data, mac)
100
+ KeyHelper.compute_mac_code(data) == mac
101
+ end
102
+
103
+ def self.post_data(uri)
104
+ with_keys uri do
105
+ request = Net::HTTP::Post.new(uri.request_uri)
106
+ request.body = yield uri
107
+
108
+ Net::HTTP.start(uri.host) { |http| http.request request }
109
+ end
110
+ end
111
+
112
+ def self.please_rekey?(body)
113
+ if body.split("\n").include? REKEY_PREFIX
114
+ GoogleSafeBrowsing.config.client_key = nil
115
+ GoogleSafeBrowsing.config.wrapped_key = nil
116
+ true
117
+ else
118
+ false
119
+ end
120
+ end
121
+
122
+ def self.switch_to_https(url)
123
+ "https#{url[4..-1]}"
124
+ end
46
125
  end
47
126
  end
@@ -0,0 +1,2 @@
1
+ class InvalidMACValidation < StandardError
2
+ end
@@ -0,0 +1,23 @@
1
+ module GoogleSafeBrowsing
2
+ class KeyHelper
3
+
4
+ def self.web_safe_base64_decode(str)
5
+ str.tr!('-_', '+/')
6
+ str << '=' while str.length % 4 != 0
7
+ Base64.decode64(str)
8
+ end
9
+
10
+ def self.web_safe_base64_encode(str)
11
+ str = Base64.encode64(str).chomp
12
+ str.tr('+/', '-_')
13
+ end
14
+
15
+ def self.compute_mac_code(data)
16
+ sha1 = OpenSSL::HMAC.digest('sha1',
17
+ GoogleSafeBrowsing.config.client_key,
18
+ data)
19
+ web_safe_base64_encode sha1
20
+ end
21
+ end
22
+ end
23
+
@@ -18,8 +18,6 @@ module GoogleSafeBrowsing
18
18
  end
19
19
 
20
20
  def self.parse_data_response(response)
21
- #print "\n\n#{response}\n\n"
22
- data_urls = []
23
21
  ret = {}
24
22
 
25
23
  ret[:lists] = []
@@ -43,25 +41,34 @@ module GoogleSafeBrowsing
43
41
  when 'ad'
44
42
  # vals[1] is a CHUNKLIST number or range representing add chunks to delete
45
43
  # we can also delete the associated Shavar Hashes
46
- # we no longer have to report hat we received these chunks
44
+ # we no longer have to report that we received these chunks
47
45
  chunk_number_clause = ChunkHelper.chunklist_to_sql(vals[1])
48
- AddShavar.delete_all([ "list = ? and (#{chunk_number_clause})", current_list ])
46
+ AddShavar.delete_all([ "list = ? and (?)", current_list, chunk_number_clause ])
49
47
  when 'sd'
50
48
  # vals[1] is a CHUNKLIST number or range representing sub chunks to delete
51
- # we no longer have to report hat we received these chunks
49
+ # we no longer have to report that we received these chunks
52
50
  chunk_number_clause = ChunkHelper.chunklist_to_sql(vals[1])
53
- SubShavar.delete_all([ "list = ? and (#{chunk_number_clause})", current_list ])
51
+ SubShavar.delete_all([ "list = ? and (?)", current_list, chunk_number_clause ])
54
52
  end
55
53
  end
56
54
 
57
- #ret[:data_urls] = data_urls
58
-
59
55
  ret
60
56
  end
61
57
 
62
58
  def self.receive_data(url, list)
59
+ urls = url.split(',')
60
+ url = urls[0]
61
+ mac = urls[1]
63
62
 
64
63
  open(url) do |f|
64
+ body = f.read
65
+
66
+ unless mac.blank? || HttpHelper.valid_mac?(body, mac)
67
+ raise InvalidMACVerification
68
+ end
69
+
70
+ f.rewind
71
+
65
72
  while(line = f.gets)
66
73
  line_actions = parse_data_line(line)
67
74
 
@@ -133,31 +140,48 @@ module GoogleSafeBrowsing
133
140
  end
134
141
  end
135
142
 
136
- # actually perform inserts
137
143
  while @add_shavar_values && @add_shavar_values.any?
138
- AddShavar.connection.execute( "insert into gsb_add_shavars (prefix, host_key, chunk_number, list) " +
139
- " values #{@add_shavar_values.pop(10000).join(', ')}")
144
+ AddShavar.connection.execute <<-SQL
145
+ INSERT INTO gsb_add_shavars (prefix, host_key, chunk_number, list)
146
+ VALUES #{pop_and_join @add_shavar_values}
147
+ SQL
140
148
  end
141
149
  while @sub_shavar_values && @sub_shavar_values.any?
142
- SubShavar.connection.execute( "insert into gsb_sub_shavars (prefix, host_key, add_chunk_number, chunk_number, list) " +
143
- " values #{@sub_shavar_values.pop(10000).join(', ')}")
150
+ SubShavar.connection.execute <<-SQL
151
+ INSERT INTO gsb_sub_shavars (prefix,
152
+ host_key,
153
+ add_chunk_number,
154
+ chunk_number,
155
+ list)
156
+ VALUES #{pop_and_join @sub_shavar_values}
157
+ SQL
144
158
  end
145
- # remove invalid full_hases
146
- FullHash.connection.execute("delete from gsb_full_hashes using gsb_full_hashes " +
147
- "inner join gsb_sub_shavars on " +
148
- "gsb_sub_shavars.add_chunk_number = gsb_full_hashes.add_chunk_number " +
149
- "and gsb_sub_shavars.list = gsb_full_hashes.list;")
159
+
160
+ FullHash.connection.execute <<-SQL
161
+ DELETE FROM gsb_full_hashes
162
+ USING gsb_full_hashes
163
+ INNER JOIN gsb_sub_shavars ON
164
+ gsb_sub_shavars.add_chunk_number = gsb_full_hashes.add_chunk_number
165
+ AND gsb_sub_shavars.list = gsb_full_hashes.list;
166
+ SQL
167
+
150
168
  @add_shavar_values = []
151
169
  @sub_shavar_values = []
152
170
  end
153
171
 
154
172
  def self.record_add_shavar_to_insert(h)
155
173
  @add_shavar_values ||= []
156
- @add_shavar_values << "('#{h[:prefix]}', '#{h[:host_key]}', '#{h[:chunk_number]}', '#{h[:list]}')"
174
+ values = [ h[:prefix], h[:host_key], h[:chunk_number], h[:list] ]
175
+ @add_shavar_values << "(#{escape_and_join values})"
157
176
  end
158
177
  def self.record_sub_shavar_to_insert(h)
159
178
  @sub_shavar_values ||= []
160
- @sub_shavar_values << "('#{h[:prefix]}', '#{h[:host_key]}', '#{h[:add_chunk_number]}', '#{h[:chunk_number]}', '#{h[:list]}')"
179
+ values = [ h[:prefix],
180
+ h[:host_key],
181
+ h[:add_chunk_number],
182
+ h[:chunk_number],
183
+ h[:list] ]
184
+ @sub_shavar_values << "(#{escape_and_join values})"
161
185
  end
162
186
 
163
187
  def self.parse_data_line(line)
@@ -168,14 +192,17 @@ module GoogleSafeBrowsing
168
192
  ret[ :chunk_number ] = split_line[1].to_i
169
193
  ret[ :hash_length ] = split_line[2].to_i
170
194
  ret[ :chunk_length ] = split_line[3].to_i
171
-
172
- #puts "Chunk ##{s_chunk_count + a_chunk_count}"
173
- #puts "Action: #{action}"
174
- #puts "Chunk Number: #{split_line[1]}"
175
- #puts "Hash Length: #{hash_length}"
176
- #puts "Chunk Length: #{chunk_length}"
177
- ##puts "Chuch Data:\n#{chunk}\nend"
178
195
  ret
179
196
  end
197
+
198
+ def self.escape_and_join(values)
199
+ values.map do |v|
200
+ ActiveRecord::Base::sanitize(v)
201
+ end.join(', ')
202
+ end
203
+
204
+ def self.pop_and_join(records)
205
+ records.pop(10000).join(', ')
206
+ end
180
207
  end
181
208
  end
@@ -1,3 +1,3 @@
1
1
  module GoogleSafeBrowsing
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google_safe_browsing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
5
- prerelease:
4
+ version: 0.5.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Chris Marshall
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-08-27 00:00:00.000000000 Z
11
+ date: 2013-05-01 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rails
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: ruby-ip
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: activerecord
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,6 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - ! '>='
60
53
  - !ruby/object:Gem::Version
@@ -62,7 +55,6 @@ dependencies:
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: sqlite3
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - ! '>='
68
60
  - !ruby/object:Gem::Version
@@ -70,7 +62,6 @@ dependencies:
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - ! '>='
76
67
  - !ruby/object:Gem::Version
@@ -78,7 +69,6 @@ dependencies:
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rspec-rails
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - ! '>='
84
74
  - !ruby/object:Gem::Version
@@ -86,7 +76,6 @@ dependencies:
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - ! '>='
92
81
  - !ruby/object:Gem::Version
@@ -94,7 +83,6 @@ dependencies:
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: generator_spec
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - ! '>='
100
88
  - !ruby/object:Gem::Version
@@ -102,7 +90,20 @@ dependencies:
102
90
  type: :development
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
106
107
  requirements:
107
108
  - - ! '>='
108
109
  - !ruby/object:Gem::Version
@@ -127,6 +128,8 @@ files:
127
128
  - lib/google_safe_browsing/google_safe_browsing_railtie.rb
128
129
  - lib/google_safe_browsing/hash_helper.rb
129
130
  - lib/google_safe_browsing/http_helper.rb
131
+ - lib/google_safe_browsing/invalid_mac_validation.rb
132
+ - lib/google_safe_browsing/key_helper.rb
130
133
  - lib/google_safe_browsing/rescheduler.rb
131
134
  - lib/google_safe_browsing/response_helper.rb
132
135
  - lib/google_safe_browsing/sub_shavar.rb
@@ -134,37 +137,30 @@ files:
134
137
  - lib/google_safe_browsing/version.rb
135
138
  - lib/google_safe_browsing.rb
136
139
  - lib/tasks/google_safe_browsing_tasks.rake
137
- - MIT-LICENSE
140
+ - APACHE-LICENSE
138
141
  - Rakefile
139
- - README.mkd
142
+ - README.md
140
143
  homepage: https://github.com/mobiledefense/mobiledefense_google_safe_browsing
141
144
  licenses: []
145
+ metadata: {}
142
146
  post_install_message:
143
147
  rdoc_options: []
144
148
  require_paths:
145
149
  - lib
146
150
  required_ruby_version: !ruby/object:Gem::Requirement
147
- none: false
148
151
  requirements:
149
152
  - - ! '>='
150
153
  - !ruby/object:Gem::Version
151
154
  version: '0'
152
- segments:
153
- - 0
154
- hash: 809089230686412521
155
155
  required_rubygems_version: !ruby/object:Gem::Requirement
156
- none: false
157
156
  requirements:
158
157
  - - ! '>='
159
158
  - !ruby/object:Gem::Version
160
159
  version: '0'
161
- segments:
162
- - 0
163
- hash: 809089230686412521
164
160
  requirements: []
165
161
  rubyforge_project:
166
- rubygems_version: 1.8.24
162
+ rubygems_version: 2.0.0
167
163
  signing_key:
168
- specification_version: 3
164
+ specification_version: 4
169
165
  summary: Rails 3 plugin for Google's Safe Browsing API v2
170
166
  test_files: []
data/MIT-LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright 2012 Chris Marshall
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.