blob: 2b019b375a8444efa52a8c45375a66dd981a586c [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>
adlr@google.com3defe6a2009-12-04 20:57:17 +00008#include <string>
Andrew de los Reyes970bb282009-12-09 16:34:04 -08009#include "base/string_util.h"
adlr@google.com3defe6a2009-12-04 20:57:17 +000010#include "update_engine/utils.h"
11
12using std::string;
13
14// This gathers local system information and prepares info used by the
15// update check action.
16
Andrew de los Reyes970bb282009-12-09 16:34:04 -080017namespace {
18const string OmahaIdPath() {
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080019 return string(chromeos_update_engine::utils::kStatefulPartition) +
20 "/etc/omaha_id";
Andrew de los Reyes970bb282009-12-09 16:34:04 -080021}
22} // namespace {}
23
adlr@google.com3defe6a2009-12-04 20:57:17 +000024namespace chromeos_update_engine {
25
26void OmahaRequestPrepAction::PerformAction() {
27 // TODO(adlr): honor force_full_update_
Andrew de los Reyes970bb282009-12-09 16:34:04 -080028 ScopedActionCompleter completer(processor_, this);
29 string machine_id;
30 TEST_AND_RETURN(GetMachineId(&machine_id));
Andrew de los Reyesf9714432010-05-04 10:21:23 -070031 const string version(GetLsbValue("CHROMEOS_RELEASE_VERSION", ""));
adlr@google.com3defe6a2009-12-04 20:57:17 +000032 const string sp(version + "_" + GetMachineType());
Andrew de los Reyesf9714432010-05-04 10:21:23 -070033 const string track(GetLsbValue("CHROMEOS_RELEASE_TRACK", ""));
34 const string update_url(GetLsbValue("CHROMEOS_AUSERVER",
35 UpdateCheckParams::kUpdateUrl));
adlr@google.com3defe6a2009-12-04 20:57:17 +000036
37 UpdateCheckParams out(machine_id, // machine_id
38 machine_id, // user_id (use machine_id)
39 UpdateCheckParams::kOsPlatform,
40 UpdateCheckParams::kOsVersion,
41 sp, // e.g. 0.2.3.3_i686
42 UpdateCheckParams::kAppId,
43 version, // app version (from lsb-release)
Andrew de los Reyesf9714432010-05-04 10:21:23 -070044 "en-US", // lang
45 track, // track
Andrew de los Reyesf98bff82010-05-06 13:33:25 -070046 update_url);
adlr@google.com3defe6a2009-12-04 20:57:17 +000047
48 CHECK(HasOutputPipe());
49 SetOutputObject(out);
Andrew de los Reyes970bb282009-12-09 16:34:04 -080050 completer.set_success(true);
adlr@google.com3defe6a2009-12-04 20:57:17 +000051}
52
Andrew de los Reyes970bb282009-12-09 16:34:04 -080053namespace {
54const size_t kGuidDataByteLength = 128 / 8;
55const string::size_type kGuidStringLength = 38;
56// Formats 16 bytes (128 bits) of data as a GUID:
57// "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" where X is a hex digit
58string GuidFromData(const unsigned char data[kGuidDataByteLength]) {
59 return StringPrintf(
60 "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
61 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
62 data[8], data[9], data[10], data[11], data[12], data[13], data[14],
63 data[15]);
64}
65}
66
67// Returns true on success.
68bool OmahaRequestPrepAction::GetMachineId(std::string* out_id) const {
69 // See if we have an existing Machine ID
70 const string omaha_id_path = root_ + OmahaIdPath();
71
72 if (utils::ReadFileToString(omaha_id_path, out_id) &&
73 out_id->size() == kGuidStringLength) {
74 return true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000075 }
Andrew de los Reyes970bb282009-12-09 16:34:04 -080076
77 // Create a new ID
78 int rand_fd = open("/dev/urandom", O_RDONLY, 0);
79 TEST_AND_RETURN_FALSE_ERRNO(rand_fd >= 0);
80 ScopedFdCloser rand_fd_closer(&rand_fd);
81 unsigned char buf[kGuidDataByteLength];
82 size_t bytes_read = 0;
83 while (bytes_read < sizeof(buf)) {
84 ssize_t rc = read(rand_fd, buf + bytes_read, sizeof(buf) - bytes_read);
85 TEST_AND_RETURN_FALSE_ERRNO(rc > 0);
86 bytes_read += rc;
87 }
88 string guid = GuidFromData(buf);
89 TEST_AND_RETURN_FALSE(
90 utils::WriteFile(omaha_id_path.c_str(), guid.data(), guid.size()));
91 *out_id = guid;
92 return true;
adlr@google.com3defe6a2009-12-04 20:57:17 +000093}
94
Andrew de los Reyesf9714432010-05-04 10:21:23 -070095string OmahaRequestPrepAction::GetLsbValue(
96 const string& key, const string& default_value) const {
Andrew de los Reyes4fe15d02009-12-10 19:01:36 -080097 string files[] = {string(utils::kStatefulPartition) + "/etc/lsb-release",
adlr@google.com3defe6a2009-12-04 20:57:17 +000098 "/etc/lsb-release"};
99 for (unsigned int i = 0; i < arraysize(files); i++) {
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700100 // TODO(adlr): make sure files checked are owned as root (and all
101 // their parents are recursively, too).
adlr@google.com3defe6a2009-12-04 20:57:17 +0000102 string file_data;
103 if (!utils::ReadFileToString(root_ + files[i], &file_data))
104 continue;
105 string::size_type pos = 0;
106 if (!utils::StringHasPrefix(file_data, key + "=")) {
107 pos = file_data.find(string("\n") + key + "=");
108 if (pos != string::npos)
109 pos++; // advance past \n
110 }
111 if (pos == string::npos)
112 continue;
113 pos += key.size() + 1; // advance past the key and the '='
114 string::size_type endpos = file_data.find('\n', pos);
115 string::size_type length =
116 (endpos == string::npos ? string::npos : endpos - pos);
117 return file_data.substr(pos, length);
118 }
119 // not found
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700120 return default_value;
adlr@google.com3defe6a2009-12-04 20:57:17 +0000121}
122
Andrew de los Reyesf9714432010-05-04 10:21:23 -0700123string OmahaRequestPrepAction::GetMachineType() const {
adlr@google.com3defe6a2009-12-04 20:57:17 +0000124 struct utsname buf;
125 string ret;
126 if (uname(&buf) == 0)
127 ret = buf.machine;
128 return ret;
129}
130
131} // namespace chromeos_update_engine