File: browser_dm_token_storage_linux.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (208 lines) | stat: -rw-r--r-- 6,605 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/policy/browser_dm_token_storage_linux.h"

#include <string>
#include <string_view>

#include "base/base64url.h"
#include "base/files/file_util.h"
#include "base/files/important_file_writer.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/hash/sha1.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/syslog_logging.h"
#include "base/task/task_traits.h"
#include "base/task/thread_pool.h"
#include "base/threading/scoped_blocking_call.h"
#include "chrome/common/chrome_paths.h"
#include "components/policy/core/common/policy_logger.h"

namespace policy {

namespace {

const char kDmTokenBaseDir[] = FILE_PATH_LITERAL("Policy/Enrollment/");
const char kMachineIdFilename[] = FILE_PATH_LITERAL("/etc/machine-id");

#if !BUILDFLAG(IS_CHROMEOS)
const char kEnrollmentTokenFilename[] =
    FILE_PATH_LITERAL("enrollment/CloudManagementEnrollmentToken");

// Enrollment Mandatory Option.
const char kEnrollmentOptionsFilePath[] =
    FILE_PATH_LITERAL("enrollment/CloudManagementEnrollmentOptions");
const char kEnrollmentMandatoryOption[] = "Mandatory";
#endif  // !BUILDFLAG(IS_CHROMEOS)

bool GetDmTokenFilePath(base::FilePath* token_file_path,
                        const std::string& client_id,
                        bool create_dir) {
  if (!base::PathService::Get(chrome::DIR_USER_DATA, token_file_path)) {
    LOG_POLICY(WARNING, CBCM_ENROLLMENT)
        << "Failed to get user data directory path.";
    return false;
  }

  *token_file_path = token_file_path->Append(kDmTokenBaseDir);

  if (create_dir && !base::CreateDirectory(*token_file_path)) {
    LOG_POLICY(WARNING, CBCM_ENROLLMENT)
        << "Failed to create DMToken storage directory: " << *token_file_path;
    return false;
  }

  *token_file_path = token_file_path->Append(client_id);

  return true;
}

bool StoreDMTokenInUserDataDir(const std::string& token,
                               const std::string& client_id) {
  base::FilePath token_file_path;
  if (!GetDmTokenFilePath(&token_file_path, client_id, /*create_dir=*/true)) {
    return false;
  }

  return base::ImportantFileWriter::WriteFileAtomically(token_file_path, token);
}

bool DeleteDMTokenFromUserDataDir(const std::string& client_id) {
  base::FilePath token_file_path;
  if (!GetDmTokenFilePath(&token_file_path, client_id, /*create_dir=*/false)) {
    return false;
  }

  return base::DeleteFile(token_file_path);
}

}  // namespace

BrowserDMTokenStorageLinux::BrowserDMTokenStorageLinux()
    : task_runner_(base::ThreadPool::CreateTaskRunner({base::MayBlock()})) {}

BrowserDMTokenStorageLinux::~BrowserDMTokenStorageLinux() = default;

std::string BrowserDMTokenStorageLinux::InitClientId() {
  if (!client_id_.empty())
    return client_id_;

  // The client ID is derived from /etc/machine-id
  // (https://www.freedesktop.org/software/systemd/man/machine-id.html). As per
  // guidelines, this ID must not be transmitted outside of the machine, which
  // is why we hash it first and then encode it in base64 before transmitting
  // it.
  const int machine_id_size = 32;
  std::string machine_id;
  machine_id = ReadMachineIdFile();
  std::string_view machine_id_trimmed =
      base::TrimWhitespaceASCII(machine_id, base::TRIM_TRAILING);
  if (machine_id_trimmed.size() != machine_id_size) {
    SYSLOG(ERROR) << "Error: /etc/machine-id contains "
                  << machine_id_trimmed.size() << " characters ("
                  << machine_id_size << " were expected).";
    return std::string();
  }

  std::string machine_id_base64;
  base::Base64UrlEncode(base::SHA1HashString(std::string(machine_id_trimmed)),
                        base::Base64UrlEncodePolicy::OMIT_PADDING,
                        &machine_id_base64);

  client_id_ = machine_id_base64;
  return client_id_;
}

std::string BrowserDMTokenStorageLinux::InitEnrollmentToken() {
#if BUILDFLAG(IS_CHROMEOS)
  return std::string();
#else
  std::string enrollment_token;
  base::FilePath dir_policy_files_path;

  if (!base::PathService::Get(chrome::DIR_POLICY_FILES,
                              &dir_policy_files_path)) {
    return std::string();
  }

  base::FilePath token_file_path =
      dir_policy_files_path.Append(kEnrollmentTokenFilename);

  if (!base::ReadFileToString(token_file_path, &enrollment_token))
    return std::string();

  return std::string(
      base::TrimWhitespaceASCII(enrollment_token, base::TRIM_ALL));
#endif  // BUILDFLAG(IS_CHROMEOS)
}

std::string BrowserDMTokenStorageLinux::InitDMToken() {
  base::FilePath token_file_path;
  if (!GetDmTokenFilePath(&token_file_path, InitClientId(), false))
    return std::string();

  std::string token;
  if (!base::ReadFileToString(token_file_path, &token))
    return std::string();

  return std::string(base::TrimWhitespaceASCII(token, base::TRIM_ALL));
}

bool BrowserDMTokenStorageLinux::InitEnrollmentErrorOption() {
#if BUILDFLAG(IS_CHROMEOS)
  return false;
#else
  std::string options;
  base::FilePath dir_policy_files_path;

  if (!base::PathService::Get(chrome::DIR_POLICY_FILES,
                              &dir_policy_files_path)) {
    return false;
  }

  base::FilePath options_file_path =
      dir_policy_files_path.Append(kEnrollmentOptionsFilePath);

  if (!base::ReadFileToString(options_file_path, &options))
    return false;

  return base::TrimWhitespaceASCII(options, base::TRIM_ALL) ==
         kEnrollmentMandatoryOption;
#endif  // BUILDFLAG(IS_CHROMEOS)
}

bool BrowserDMTokenStorageLinux::CanInitEnrollmentToken() const {
  return true;
}

BrowserDMTokenStorage::StoreTask BrowserDMTokenStorageLinux::SaveDMTokenTask(
    const std::string& token,
    const std::string& client_id) {
  return base::BindOnce(&StoreDMTokenInUserDataDir, token, client_id);
}

BrowserDMTokenStorage::StoreTask BrowserDMTokenStorageLinux::DeleteDMTokenTask(
    const std::string& client_id) {
  return base::BindOnce(&DeleteDMTokenFromUserDataDir, client_id);
}

scoped_refptr<base::TaskRunner>
BrowserDMTokenStorageLinux::SaveDMTokenTaskRunner() {
  return task_runner_;
}

std::string BrowserDMTokenStorageLinux::ReadMachineIdFile() {
  std::string machine_id;
  if (!base::ReadFileToString(base::FilePath(kMachineIdFilename), &machine_id))
    return std::string();
  return machine_id;
}

}  // namespace policy