Index: src/platform/update_engine/omaha_request_prep_action.cc |
diff --git a/src/platform/update_engine/omaha_request_prep_action.cc b/src/platform/update_engine/omaha_request_prep_action.cc |
index 21d579954d55c78acf263d886793e1c20920392d..8c015d84ef6d9246addd37f5e392698dba68274b 100644 |
--- a/src/platform/update_engine/omaha_request_prep_action.cc |
+++ b/src/platform/update_engine/omaha_request_prep_action.cc |
@@ -4,7 +4,9 @@ |
#include "update_engine/omaha_request_prep_action.h" |
#include <sys/utsname.h> |
+#include <errno.h> |
#include <string> |
+#include "base/string_util.h" |
#include "update_engine/utils.h" |
using std::string; |
@@ -12,11 +14,19 @@ using std::string; |
// This gathers local system information and prepares info used by the |
// update check action. |
+namespace { |
+const string OmahaIdPath() { |
+ return chromeos_update_engine::utils::kStatefulPartition + "/etc/omaha_id"; |
+} |
+} // namespace {} |
+ |
namespace chromeos_update_engine { |
void OmahaRequestPrepAction::PerformAction() { |
// TODO(adlr): honor force_full_update_ |
- const string machine_id(GetMachineId()); |
+ ScopedActionCompleter completer(processor_, this); |
+ string machine_id; |
+ TEST_AND_RETURN(GetMachineId(&machine_id)); |
const string version(GetLsbValue("GOOGLE_RELEASE")); |
const string sp(version + "_" + GetMachineType()); |
const string track(GetLsbValue("GOOGLE_TRACK")); |
@@ -33,28 +43,49 @@ void OmahaRequestPrepAction::PerformAction() { |
CHECK(HasOutputPipe()); |
SetOutputObject(out); |
- processor_->ActionComplete(this, true); |
+ completer.set_success(true); |
+} |
+ |
+namespace { |
+const size_t kGuidDataByteLength = 128 / 8; |
+const string::size_type kGuidStringLength = 38; |
+// Formats 16 bytes (128 bits) of data as a GUID: |
+// "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}" where X is a hex digit |
+string GuidFromData(const unsigned char data[kGuidDataByteLength]) { |
+ return StringPrintf( |
+ "{%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X}", |
+ data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], |
+ data[8], data[9], data[10], data[11], data[12], data[13], data[14], |
+ data[15]); |
+} |
} |
-std::string OmahaRequestPrepAction::GetMachineId() const { |
- FILE* fp = popen("/sbin/ifconfig", "r"); |
- if (!fp) |
- return ""; |
- string data; |
- for (;;) { |
- char buffer[1000]; |
- size_t r = fread(buffer, 1, sizeof(buffer), fp); |
- if (r <= 0) |
- break; |
- data.insert(data.end(), buffer, buffer + r); |
+// Returns true on success. |
+bool OmahaRequestPrepAction::GetMachineId(std::string* out_id) const { |
+ // See if we have an existing Machine ID |
+ const string omaha_id_path = root_ + OmahaIdPath(); |
+ |
+ if (utils::ReadFileToString(omaha_id_path, out_id) && |
+ out_id->size() == kGuidStringLength) { |
+ return true; |
+ } |
+ |
+ // Create a new ID |
+ int rand_fd = open("/dev/urandom", O_RDONLY, 0); |
+ TEST_AND_RETURN_FALSE_ERRNO(rand_fd >= 0); |
+ ScopedFdCloser rand_fd_closer(&rand_fd); |
+ unsigned char buf[kGuidDataByteLength]; |
+ size_t bytes_read = 0; |
+ while (bytes_read < sizeof(buf)) { |
+ ssize_t rc = read(rand_fd, buf + bytes_read, sizeof(buf) - bytes_read); |
+ TEST_AND_RETURN_FALSE_ERRNO(rc > 0); |
+ bytes_read += rc; |
} |
- fclose(fp); |
- // scan data for MAC address |
- string::size_type pos = data.find(" HWaddr "); |
- if (pos == string::npos) |
- return ""; |
- // 3 * 6 - 1 is the number of bytes of the hwaddr. |
- return data.substr(pos + strlen(" HWaddr "), 3 * 6 - 1); |
+ string guid = GuidFromData(buf); |
+ TEST_AND_RETURN_FALSE( |
+ utils::WriteFile(omaha_id_path.c_str(), guid.data(), guid.size())); |
+ *out_id = guid; |
+ return true; |
} |
std::string OmahaRequestPrepAction::GetLsbValue(const std::string& key) const { |