blob: 7163119cb57634ef862f48051c66fe69542ad220 [file] [log] [blame]
adlr@google.com3defe6a2009-12-04 20:57:17 +00001// Copyright (c) 2009 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 "update_engine/omaha_request_prep_action.h"
6#include <sys/utsname.h>
Andrew de los Reyes970bb282009-12-09 16:34:04 -08007#include <errno.h>
Andrew de los Reyes785bc352010-05-26 12:34:53 -07008#include <map>
adlr@google.com3defe6a2009-12-04 20:57:17 +00009#include <string>
Andrew de los Reyes970bb282009-12-09 16:34:04 -080010#include "base/string_util.h"
Andrew de los Reyes785bc352010-05-26 12:34:53 -070011#include "update_engine/simple_key_value_store.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000012#include "update_engine/utils.h"
13
Andrew de los Reyes785bc352010-05-26 12:34:53 -070014using std::map;
adlr@google.com3defe6a2009-12-04 20:57:17 +000015using std::string;
16
17// This gathers local system information and prepares info used by the
18// update check action.
19
Andrew de los Reyes970bb282009-12-09 16:34:04 -080020namespace {
21const string OmahaIdPath() {
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080022 return string(chromeos_update_engine::utils::kStatefulPartition) +
23 "/etc/omaha_id";
Andrew de los Reyes970bb282009-12-09 16:34:04 -080024}
25} // namespace {}
26
adlr@google.com3defe6a2009-12-04 20:57:17 +000027namespace chromeos_update_engine {
28
29void OmahaRequestPrepAction::PerformAction() {
30 // TODO(adlr): honor force_full_update_
Andrew de los Reyes970bb282009-12-09 16:34:04 -080031 ScopedActionCompleter completer(processor_, this);
32 string machine_id;
33 TEST_AND_RETURN(GetMachineId(&machine_id));
Andrew de los Reyesf9714432010-05-04 10:21:23 -070034 const string version(GetLsbValue("CHROMEOS_RELEASE_VERSION", ""));
adlr@google.com3defe6a2009-12-04 20:57:17 +000035 const string sp(version + "_" + GetMachineType());
Andrew de los Reyesf9714432010-05-04 10:21:23 -070036 const string track(GetLsbValue("CHROMEOS_RELEASE_TRACK", ""));
37 const string update_url(GetLsbValue("CHROMEOS_AUSERVER",
38 UpdateCheckParams::kUpdateUrl));
Andrew de los Reyes37c20322010-06-30 13:27:19 -070039 const string board(GetLsbValue("CHROMEOS_RELEASE_BOARD", ""));
adlr@google.com3defe6a2009-12-04 20:57:17 +000040
41 UpdateCheckParams out(machine_id, // machine_id
42 machine_id, // user_id (use machine_id)
43 UpdateCheckParams::kOsPlatform,
44 UpdateCheckParams::kOsVersion,
45 sp, // e.g. 0.2.3.3_i686
Andrew de los Reyes37c20322010-06-30 13:27:19 -070046 board, // e.g. x86-generic
adlr@google.com3defe6a2009-12-04 20:57:17 +000047 UpdateCheckParams::kAppId,
48 version, // app version (from lsb-release)
Andrew de los Reyesf9714432010-05-04 10:21:23 -070049 "en-US", // lang
50 track, // track
Andrew de los Reyesf98bff82010-05-06 13:33:25 -070051 update_url);
adlr@google.com3defe6a2009-12-04 20:57:17 +000052
53 CHECK(HasOutputPipe());
54 SetOutputObject(out);
Andrew de los Reyes970bb282009-12-09 16:34:04 -080055 completer.set_success(true);
adlr@google.com3defe6a2009-12-04 20:57:17 +000056}
57
Andrew de los Reyes970bb282009-12-09 16:34:04 -080058namespace {
59const size_t kGuidDataByteLength = 128 / 8;
60const string::size_type kGuidStringLength = 38;
61// Formats 16 bytes (128 bits) of data as a GUID:
62// "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" where X is a hex digit
63string GuidFromData(const unsigned char data[kGuidDataByteLength]) {
64 return StringPrintf(
65 "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
66 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
67 data[8], data[9], data[10], data[11], data[12], data[13], data[14],
68 data[15]);
69}
70}
71
72// Returns true on success.
73bool OmahaRequestPrepAction::GetMachineId(std::string* out_id) const {
74 // See if we have an existing Machine ID
75 const string omaha_id_path = root_ + OmahaIdPath();
76
77 if (utils::ReadFileToString(omaha_id_path, out_id) &&
78 out_id->size() == kGuidStringLength) {
79 return true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000080 }
Andrew de los Reyes970bb282009-12-09 16:34:04 -080081
82 // Create a new ID
83 int rand_fd = open("/dev/urandom", O_RDONLY, 0);
84 TEST_AND_RETURN_FALSE_ERRNO(rand_fd >= 0);
85 ScopedFdCloser rand_fd_closer(&rand_fd);
86 unsigned char buf[kGuidDataByteLength];
87 size_t bytes_read = 0;
88 while (bytes_read < sizeof(buf)) {
89 ssize_t rc = read(rand_fd, buf + bytes_read, sizeof(buf) - bytes_read);
90 TEST_AND_RETURN_FALSE_ERRNO(rc > 0);
91 bytes_read += rc;
92 }
93 string guid = GuidFromData(buf);
94 TEST_AND_RETURN_FALSE(
95 utils::WriteFile(omaha_id_path.c_str(), guid.data(), guid.size()));
96 *out_id = guid;
97 return true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000098}
99
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700100string OmahaRequestPrepAction::GetLsbValue(
101 const string& key, const string& default_value) const {
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -0800102 string files[] = {string(utils::kStatefulPartition) + "/etc/lsb-release",
adlr@google.com3defe6a2009-12-04 20:57:17 +0000103 "/etc/lsb-release"};
104 for (unsigned int i = 0; i < arraysize(files); i++) {
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700105 // TODO(adlr): make sure files checked are owned as root (and all
106 // their parents are recursively, too).
adlr@google.com3defe6a2009-12-04 20:57:17 +0000107 string file_data;
108 if (!utils::ReadFileToString(root_ + files[i], &file_data))
109 continue;
Andrew de los Reyes785bc352010-05-26 12:34:53 -0700110
111 map<string, string> data = simple_key_value_store::ParseString(file_data);
112 if (utils::MapContainsKey(data, key))
113 return data[key];
adlr@google.com3defe6a2009-12-04 20:57:17 +0000114 }
115 // not found
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700116 return default_value;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000117}
118
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700119string OmahaRequestPrepAction::GetMachineType() const {
adlr@google.com3defe6a2009-12-04 20:57:17 +0000120 struct utsname buf;
121 string ret;
122 if (uname(&buf) == 0)
123 ret = buf.machine;
124 return ret;
125}
126
127} // namespace chromeos_update_engine