1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_PARSER_H_
6#define CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_PARSER_H_
7
8// Parse the data returned from the chunk response.
9//
10// Based on the SafeBrowsing v2.1 protocol:
11// http://code.google.com/p/google-safe-browsing/wiki/Protocolv2Spec
12//
13// Read the response from a SafeBrowsing request, and parse into useful pieces.
14// The protocol is generally line oriented, but can contain binary data in the
15// actual chunk responses. The consumer of the protocol data should instantiate
16// the parser and call the appropriate parsing function on the data.
17//
18// Examples of protocol responses:
19//
20// 1. List identification
21//    i:goog-phish-shavar\n
22//    <command>:<command_data>\n
23//
24// 2. Minimum time to wait (seconds) until the next download request can be made
25//    n:1200\n
26//    <command>:<time_in_seconds>\n
27//
28// 3. Redirect URL for retrieving a chunk
29//    u:cache.googlevideo.com/safebrowsing/rd/goog-phish-shavar_a_1\n
30//    <command>:<url>\n
31//
32// 4. Add and sub chunks
33//   a:1:4:523\n...    <-- Add chunk + binary data
34//   s:13:4:17\n...    <-- Sub chunk + binary data
35//   <chunk_type>:<chunk_number>:<prefix_len>:<chunk_bytes>\n<binary_data>
36//
37// 5. Add-del and sub-del requests
38//    ad:1-4000,5001\n    <-- Add-del
39//    sd:1,3,5,7,903\n    <-- Sub-del
40//    <command>:<chunk_range>\n
41
42
43#include <string>
44#include <vector>
45
46#include "base/basictypes.h"
47#include "chrome/browser/safe_browsing/chunk_range.h"
48#include "chrome/browser/safe_browsing/safe_browsing_util.h"
49
50
51class SafeBrowsingProtocolParser {
52 public:
53  SafeBrowsingProtocolParser();
54
55  // Parse the response of an update request. Results for chunk deletions (both
56  // add-del and sub-del are returned in 'chunk_deletes', and new chunk URLs to
57  // download are contained in 'chunk_urls'. The next time the client is allowed
58  // to request another update is returned in 'next_update_sec'. 'reset' will
59  // be set to true if the SafeBrowsing service wants us to dump our database.
60  // Returns 'true'if it was able to decode the chunk properly, 'false' if not
61  // decoded properly and the results should be ignored.
62  bool ParseUpdate(const char* chunk_data,
63                   int chunk_len,
64                   int* next_update_sec,
65                   bool* reset,
66                   std::vector<SBChunkDelete>* chunk_deletes,
67                   std::vector<ChunkUrl>* chunk_urls);
68
69  // Parse the response from a chunk URL request and returns the hosts/prefixes
70  // for adds and subs in "chunks".  Returns 'true' on successful parsing,
71  // 'false' otherwise. Any result should be ignored when a parse has failed.
72  bool ParseChunk(const std::string& list_name,
73                  const char* chunk_data,
74                  int chunk_len,
75                  SBChunkList* chunks);
76
77  // Parse the result of a GetHash request, returning the list of full hashes.
78  bool ParseGetHash(const char* chunk_data,
79                    int chunk_len,
80                    std::vector<SBFullHashResult>* full_hashes);
81
82  // Convert a list of partial hashes into a proper GetHash request.
83  void FormatGetHash(const std::vector<SBPrefix>& prefixes,
84                     std::string* request);
85
86 private:
87  bool ParseAddChunk(const std::string& list_name,
88                     const char* data,
89                     int data_len,
90                     int hash_len,
91                     std::deque<SBChunkHost>* hosts);
92  bool ParseSubChunk(const std::string& list_name,
93                     const char* data,
94                     int data_len,
95                     int hash_len,
96                     std::deque<SBChunkHost>* hosts);
97
98  // Helper functions used by ParseAddChunk and ParseSubChunk.
99  static bool ReadHostAndPrefixCount(const char** data,
100                                     int* remaining,
101                                     SBPrefix* host,
102                                     int* count);
103  static bool ReadChunkId(const char** data, int* remaining, int* chunk_id);
104  static bool ReadPrefixes(
105      const char** data, int* remaining, SBEntry* entry, int count);
106
107  // The name of the current list
108  std::string list_name_;
109
110  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingProtocolParser);
111};
112
113
114#endif  // CHROME_BROWSER_SAFE_BROWSING_PROTOCOL_PARSER_H_
115