Home | History | Annotate | Download | only in win
      1 // Copyright 2013 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 #include "chrome/browser/install_verification/win/module_ids.h"
      6 
      7 #include <utility>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/logging.h"
     11 #include "base/strings/string_number_conversions.h"
     12 #include "base/strings/string_piece.h"
     13 #include "base/strings/string_tokenizer.h"
     14 #include "base/strings/string_util.h"
     15 #include "grit/browser_resources.h"
     16 #include "ui/base/resource/resource_bundle.h"
     17 
     18 namespace {
     19 
     20 struct { size_t id; const char* module_name_digest; }
     21   kExpectedInstallModules[] = {
     22     {1u, "c8cc47613e155f2129f480c6ced84549"},  // chrome.dll
     23     {2u, "49b78a23b0d8d5d8fb60d4e472b22764"},  // chrome_child.dll
     24   };
     25 
     26 // Parses a line consisting of a positive decimal number and a 32-digit
     27 // hexadecimal number, separated by a space. Inserts the output, if valid, into
     28 // |module_ids|. Unexpected leading or trailing characters will cause
     29 // the line to be ignored, as will invalid decimal/hexadecimal characters.
     30 void ParseAdditionalModuleID(
     31     const base::StringPiece& line,
     32     ModuleIDs* module_ids) {
     33   DCHECK(module_ids);
     34 
     35   base::CStringTokenizer line_tokenizer(line.begin(), line.end(), " ");
     36 
     37   if (!line_tokenizer.GetNext())
     38     return;  // Empty string.
     39   base::StringPiece id_piece(line_tokenizer.token_piece());
     40 
     41   if (!line_tokenizer.GetNext())
     42     return;  // No delimiter (' ').
     43   base::StringPiece digest_piece(line_tokenizer.token_piece());
     44 
     45   if (line_tokenizer.GetNext())
     46     return;  // Unexpected trailing characters.
     47 
     48   unsigned id = 0;
     49   if (!StringToUint(id_piece, &id))
     50     return;  // First token was not decimal.
     51 
     52   if (digest_piece.length() != 32)
     53     return;  // Second token is not the right length.
     54 
     55   for (base::StringPiece::const_iterator it = digest_piece.begin();
     56        it != digest_piece.end(); ++it) {
     57     if (!IsHexDigit(*it))
     58       return;  // Second token has invalid characters.
     59   }
     60 
     61   // This is a valid line.
     62   module_ids->insert(std::make_pair(digest_piece.as_string(), id));
     63 }
     64 
     65 }  // namespace
     66 
     67 void ParseAdditionalModuleIDs(
     68     const base::StringPiece& raw_data,
     69     ModuleIDs* module_ids) {
     70   DCHECK(module_ids);
     71 
     72   base::CStringTokenizer file_tokenizer(raw_data.begin(),
     73                                         raw_data.end(),
     74                                         "\r\n");
     75   while (file_tokenizer.GetNext()) {
     76     ParseAdditionalModuleID(base::StringPiece(file_tokenizer.token_piece()),
     77                             module_ids);
     78   }
     79 }
     80 
     81 void LoadModuleIDs(ModuleIDs* module_ids) {
     82   for (size_t i = 0; i < arraysize(kExpectedInstallModules); ++i) {
     83     module_ids->insert(
     84         std::make_pair(
     85             kExpectedInstallModules[i].module_name_digest,
     86             kExpectedInstallModules[i].id));
     87   }
     88   ParseAdditionalModuleIDs(
     89       ResourceBundle::GetSharedInstance().GetRawDataResource(
     90           IDR_ADDITIONAL_MODULE_IDS),
     91       module_ids);
     92 }
     93