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