Class: Google::SafeBrowsingClient

Inherits:
Object
  • Object
show all
Includes:
SafeBrowsingUpdateHelper
Defined in:
lib/google/safe_browsing_client.rb

Constant Summary collapse

FULL_HASH_TIMEOUT =

secs

2

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from SafeBrowsingUpdateHelper

#gen_chunk_nums_string, #safe_browsing_service, #save_redirect_urls, #update_add_shavar_chunk, #update_add_sub_chunks, #update_local_shavar_info, #update_next_update_time, #update_redirect_urls, #update_shavar_chunk, #update_sub_shavar_chunk

Constructor Details

#initializeSafeBrowsingClient

Returns a new instance of SafeBrowsingClient.



21
22
23
24
25
# File 'lib/google/safe_browsing_client.rb', line 21

def initialize
  @headers = {
    :'User-Agent'    => 'Faraday Ruby Client'
  }
end

Instance Attribute Details

#headersObject

Returns the value of attribute headers.



8
9
10
# File 'lib/google/safe_browsing_client.rb', line 8

def headers
  @headers
end

Instance Method Details

#api_serverObject



27
28
29
# File 'lib/google/safe_browsing_client.rb', line 27

def api_server
  'https://safebrowsing.clients.google.com'
end

#chunk_data(redirect_url, options = {}) ⇒ Object

To get shavar chunk data from the redirect url



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/google/safe_browsing_client.rb', line 89

def chunk_data redirect_url, options = {}
  url = 'https://' + redirect_url if /\Ahttps?/ !~ redirect_url
  
  conn = Faraday.new(headers: headers) do |builder|
    builder.use Faraday::Request::UrlEncoded
    builder.adapter ::Faraday.default_adapter
  end

  r = conn.post do |req|
    req.url url
  end

  if successful_status_code?(r.status)
    r.body
  else
    process_error_response(r.status)
  end

end

#download_data_request_body(list_name) ⇒ Object

s;200 googpub-phish-shavar;a:1-3,5,8:s:4-5 acme-white-shavar;a:1-7:s:1-2



145
146
147
# File 'lib/google/safe_browsing_client.rb', line 145

def download_data_request_body list_name
  gen_list_request(list_name)
end

#download_urlObject



41
42
43
# File 'lib/google/safe_browsing_client.rb', line 41

def download_url
  '/safebrowsing/downloads?client=%s&apikey=%s&appver=%s&pver=%s' % [CLIENT, API_KEY, APP_VER, P_VER]
end

#full_hash(hash_prefixes) ⇒ Object

hash_prefixes: [‘5b3583c0’, ‘b3e357a6’] }

Returns:

  • # { ‘goog-malware-shavar’ (list_name)

    => {
        :add_chunk_num1 => [full_hash0, full_hash1, ...]
        :add_chunk_num2 => [full_hash0]
       }
    


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/google/safe_browsing_client.rb', line 119

def full_hash hash_prefixes
  conn = Faraday.new(url: api_server, headers: headers) do |builder|
    builder.use Faraday::Request::UrlEncoded
    builder.adapter ::Faraday.default_adapter
  end
  
  request_body = full_hash_request_body hash_prefixes
  
  r = conn.post do |req|
    req.url full_hash_url
    req.body = request_body 
    req.options[:timeout] = FULL_HASH_TIMEOUT
  end
        
  if successful_status_code?(r.status)
    SafeBrowsingParser.parse_full_hash_entries r.body
  else
    process_error_response(r.status)
  end
end

#full_hash_request_body(prefixes) ⇒ Object

BODY = HEADER LF PREFIXES EOF HEADER = PREFIXSIZE “:” LENGTH PREFIXSIZE = DIGIT+ # Size of each prefix in bytes LENGTH = DIGIT+ # Size of PREFIXES in bytes

The prefixes should all have the same length of bytes



173
174
175
176
177
178
179
180
181
182
183
# File 'lib/google/safe_browsing_client.rb', line 173

def full_hash_request_body prefixes
  return "" if prefixes.empty?
  
  prefix_size = prefixes.first.size / 2
  
  s = StringIO.new("")
  s << prefix_size.to_s << ":"
  s << (prefix_size * prefixes.size).to_s << NL
  s << pack_hash_prefix(prefixes, prefix_size)
  s.string
end

#full_hash_urlObject



45
46
47
# File 'lib/google/safe_browsing_client.rb', line 45

def full_hash_url
  '/safebrowsing/gethash?client=%s&apikey=%s&appver=%s&pver=%s' % [CLIENT, API_KEY, APP_VER, P_VER]
end

#gen_list_request(list) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/google/safe_browsing_client.rb', line 149

def gen_list_request list
  list = SafeBrowsingList.where(name: list).first
  s = StringIO.new("")
  s << list.name << SEMI_COLON
  add_chunk_ids = gen_chunk_nums_string(
                      SafeBrowsingShavar.add_chunk_nums_for_list(list.name).map(&:chunk_num))
  sub_chunk_ids = gen_chunk_nums_string(
                      SafeBrowsingShavar.sub_chunk_nums_for_list(list.name).map(&:chunk_num))
  
  s << SafeBrowsingShavar::CHUNK_TYPE_ADD << COLON << add_chunk_ids unless add_chunk_ids.blank?
  s << COLON if !add_chunk_ids.blank? && !sub_chunk_ids.blank?
  s << SafeBrowsingShavar::CHUNK_TYPE_SUB << COLON << sub_chunk_ids unless sub_chunk_ids.blank?
  s << NL
  s.string
end

#list_urlObject

goog-malware-shavar goog-regtest-shavar goog-whitedomain-shavar googpub-phish-shavar



37
38
39
# File 'lib/google/safe_browsing_client.rb', line 37

def list_url
  '/safebrowsing/list?client=%s&apikey=%s&appver=%s&pver=%s' % [CLIENT, API_KEY, APP_VER, P_VER]
end

#pack_hash_prefix(prefixes, prefix_size) ⇒ Object



185
186
187
188
189
190
191
# File 'lib/google/safe_browsing_client.rb', line 185

def pack_hash_prefix prefixes, prefix_size
  s = StringIO.new("")
  prefixes.each do |pre|
    s << [pre].pack("H#{prefix_size*2}")
  end
  s.string
end

#process_error_response(status) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/google/safe_browsing_client.rb', line 193

def process_error_response status
  case status.to_s
  when /\A204/
    raise Error::NoContent
  when /\A4/
    raise Error::InvalidRequest
  when /\A5/
    raise Error::ServiceUnavailable
  else
    raise Error::UnknownError
  end
end

#shavar_data_update(list_name, options = {}) ⇒ Object

resp = <<-END_OF_SAMPLE n:1200 i:googpub-phish-shavar u:cache.google.com/first_redirect_example u:cache.google.com/second_redirect_example sd:1,2 i:acme-white-shavar u:cache.google.com/second_redirect_example ad:1-2,4-5,7 sd:2-6

END_OF_SAMPLE

parser = Faraday::Response::SafeBrowsingUpdateParser.new

r = parser.parse resp



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/google/safe_browsing_client.rb', line 65

def shavar_data_update list_name, options = {}
  conn = Faraday.new(url: api_server, headers: headers) do |builder|
    builder.use Faraday::Request::UrlEncoded
    builder.use Faraday::Response::SafeBrowsingUpdateParser
    builder.adapter ::Faraday.default_adapter
  end
  
  request_body = download_data_request_body(list_name)
  
  r = conn.post do |req|
    req.url download_url
    req.body = request_body
  end

  if successful_status_code?(r.status)
    r.body
  else
    process_error_response(r.status)
  end
end

#successful_status_code?(status_code) ⇒ Boolean

Returns:

  • (Boolean)


206
207
208
# File 'lib/google/safe_browsing_client.rb', line 206

def successful_status_code?(status_code)
  status_code.to_s == '200'
end