blob: 1ab6f2cb5e2a6d12466fe3c6a86fee5f5e65e0de [file] [log] [blame]
Darin Petkova4a8a8c2010-07-15 22:21:12 -07001// Copyright (c) 2010 The Chromium OS 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_params.h"
6
7#include <errno.h>
8#include <fcntl.h>
9#include <sys/utsname.h>
10
11#include <map>
12#include <string>
13
14#include "base/string_util.h"
15#include "update_engine/simple_key_value_store.h"
16#include "update_engine/utils.h"
17
18using std::map;
19using std::string;
20
21namespace {
22const string OmahaIdPath() {
23 return string(chromeos_update_engine::utils::kStatefulPartition) +
24 "/etc/omaha_id";
25}
26} // namespace {}
27
28namespace chromeos_update_engine {
29
30bool OmahaRequestDeviceParams::Init() {
31 TEST_AND_RETURN_FALSE(GetMachineId(&machine_id));
32 user_id = machine_id;
33 os_platform = OmahaRequestParams::kOsPlatform;
34 os_version = OmahaRequestParams::kOsVersion;
35 app_version = GetLsbValue("CHROMEOS_RELEASE_VERSION", "");
36 os_sp = app_version + "_" + GetMachineType();
37 os_board = GetLsbValue("CHROMEOS_RELEASE_BOARD", "");
38 app_id = OmahaRequestParams::kAppId;
39 app_lang = "en-US";
40 app_track = GetLsbValue("CHROMEOS_RELEASE_TRACK", "");
Andrew de los Reyes3f0303a2010-07-15 22:35:35 -070041 struct stat stbuf;
42
43 // Deltas are only okay if the /.nodelta file does not exist.
44 // If we don't know (i.e. stat() returns some unexpected error),
45 // then err on the side of caution and say deltas are not okay
46 delta_okay = (stat((root_ + "/.nodelta").c_str(), &stbuf) < 0) &&
47 (errno == ENOENT);
48
Darin Petkova4a8a8c2010-07-15 22:21:12 -070049 update_url = GetLsbValue("CHROMEOS_AUSERVER",
50 OmahaRequestParams::kUpdateUrl);
51 return true;
52}
53
54namespace {
55const size_t kGuidDataByteLength = 128 / 8;
56const string::size_type kGuidStringLength = 38;
57// Formats 16 bytes (128 bits) of data as a GUID:
58// "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" where X is a hex digit
59string GuidFromData(const unsigned char data[kGuidDataByteLength]) {
60 return StringPrintf(
61 "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
62 data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
63 data[8], data[9], data[10], data[11], data[12], data[13], data[14],
64 data[15]);
65}
66}
67
68// Returns true on success.
69bool OmahaRequestDeviceParams::GetMachineId(std::string* out_id) const {
70 // Checks if we have an existing Machine ID.
71 const string omaha_id_path = root_ + OmahaIdPath();
72
73 if (utils::ReadFileToString(omaha_id_path, out_id) &&
74 out_id->size() == kGuidStringLength) {
75 return true;
76 }
77
78 // Creates a new ID.
79 int rand_fd = open("/dev/urandom", O_RDONLY, 0);
80 TEST_AND_RETURN_FALSE_ERRNO(rand_fd >= 0);
81 ScopedFdCloser rand_fd_closer(&rand_fd);
82 unsigned char buf[kGuidDataByteLength];
83 size_t bytes_read = 0;
84 while (bytes_read < sizeof(buf)) {
85 ssize_t rc = read(rand_fd, buf + bytes_read, sizeof(buf) - bytes_read);
86 TEST_AND_RETURN_FALSE_ERRNO(rc > 0);
87 bytes_read += rc;
88 }
89 string guid = GuidFromData(buf);
90 TEST_AND_RETURN_FALSE(
91 utils::WriteFile(omaha_id_path.c_str(), guid.data(), guid.size()));
92 *out_id = guid;
93 return true;
94}
95
96string OmahaRequestDeviceParams::GetLsbValue(
97 const string& key, const string& default_value) const {
98 string files[] = {string(utils::kStatefulPartition) + "/etc/lsb-release",
99 "/etc/lsb-release"};
100 for (unsigned int i = 0; i < arraysize(files); ++i) {
101 // TODO(adlr): make sure files checked are owned as root (and all
102 // their parents are recursively, too).
103 string file_data;
104 if (!utils::ReadFileToString(root_ + files[i], &file_data))
105 continue;
106
107 map<string, string> data = simple_key_value_store::ParseString(file_data);
108 if (utils::MapContainsKey(data, key))
109 return data[key];
110 }
111 // not found
112 return default_value;
113}
114
115string OmahaRequestDeviceParams::GetMachineType() const {
116 struct utsname buf;
117 string ret;
118 if (uname(&buf) == 0)
119 ret = buf.machine;
120 return ret;
121}
122
123} // namespace chromeos_update_engine