Add WritePasswordToFile in TempFileManager

Adds WritePasswordToFile function in TempFileManager in order to save
passwords that are passed into Mount

Bug: chromium:757625
Change-Id: I8489d90fc18fec1206b1c5fe87457db9381063b3
Reviewed-on: https://chromium-review.googlesource.com/1020408
Reviewed-by: Zentaro Kavanagh <zentaro@chromium.org>
Commit-Queue: Allen Vicencio <allenvic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#553995}
diff --git a/chrome/browser/chromeos/smb_client/temp_file_manager.cc b/chrome/browser/chromeos/smb_client/temp_file_manager.cc
index ab43184..92e6dad 100644
--- a/chrome/browser/chromeos/smb_client/temp_file_manager.cc
+++ b/chrome/browser/chromeos/smb_client/temp_file_manager.cc
@@ -75,5 +75,21 @@
   return temp_fd;
 }
 
+base::ScopedFD TempFileManager::WritePasswordToFile(
+    const std::string& password) {
+  const size_t password_size = password.size();
+  std::vector<uint8_t> password_data(sizeof(password_size) + password.size());
+
+  // Write the password length in the first sizeof(password_size) bytes of the
+  // buffer.
+  std::memcpy(password_data.data(), &password_size, sizeof(password_size));
+
+  // Append |password| starting at the end of password_size.
+  std::memcpy(password_data.data() + sizeof(password_size), password.c_str(),
+              password.size());
+
+  return CreateTempFile(password_data);
+}
+
 }  // namespace smb_client
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/smb_client/temp_file_manager.h b/chrome/browser/chromeos/smb_client/temp_file_manager.h
index 7812a5f..2e3a3df0 100644
--- a/chrome/browser/chromeos/smb_client/temp_file_manager.h
+++ b/chrome/browser/chromeos/smb_client/temp_file_manager.h
@@ -30,6 +30,11 @@
   // descriptor which will be invalid on failure.
   base::ScopedFD CreateTempFile(const std::vector<uint8_t>& data);
 
+  // Writes |password| into a file with the format of
+  // "{password_length}{password}". Returns a file descriptor of the file
+  // containing the password.
+  base::ScopedFD WritePasswordToFile(const std::string& password);
+
  private:
   // Creates a temporary file in temp_dir_ path. This also calls unlink() on the
   // created file. Returns a file descriptor which will be invalid on failure.
diff --git a/chrome/browser/chromeos/smb_client/temp_file_manager_unittest.cc b/chrome/browser/chromeos/smb_client/temp_file_manager_unittest.cc
index a385787..a7a924f 100644
--- a/chrome/browser/chromeos/smb_client/temp_file_manager_unittest.cc
+++ b/chrome/browser/chromeos/smb_client/temp_file_manager_unittest.cc
@@ -21,6 +21,25 @@
   return lseek(fd, 0, SEEK_CUR);
 }
 
+// Gets a password from |password_fd|. The data has to be in the format of
+// "{password_length}{password}".
+std::string GetPassword(const base::ScopedFD& password_fd) {
+  size_t password_length = 0;
+
+  // Read sizeof(password_length) bytes from the file to get the length.
+  EXPECT_TRUE(base::ReadFromFD(password_fd.get(),
+                               reinterpret_cast<char*>(&password_length),
+                               sizeof(password_length)));
+
+  // Read the password into the buffer.
+  char password_buffer[password_length + 1];
+  EXPECT_TRUE(
+      base::ReadFromFD(password_fd.get(), password_buffer, password_length));
+
+  password_buffer[password_length] = '\0';
+  return std::string(password_buffer);
+}
+
 }  // namespace
 
 class TempFileManagerTest : public testing::Test {
@@ -94,5 +113,25 @@
   EXPECT_EQ(expected, actual);
 }
 
+// CreatePassword should return a valid FD even with an empty password.
+TEST_F(TempFileManagerTest, WritePasswordToFileIsValidWithEmptyPassword) {
+  const std::string password;
+  TempFileManager file_manager;
+
+  base::ScopedFD fd = file_manager.WritePasswordToFile(password);
+  EXPECT_TRUE(fd.is_valid());
+  EXPECT_EQ(password, GetPassword(fd));
+}
+
+// The password should be readable from the file.
+TEST_F(TempFileManagerTest, WritePasswordToFileIsValidWithPassword) {
+  const std::string password = "testing123";
+  TempFileManager file_manager;
+
+  base::ScopedFD fd = file_manager.WritePasswordToFile(password);
+  EXPECT_TRUE(fd.is_valid());
+  EXPECT_EQ(password, GetPassword(fd));
+}
+
 }  // namespace smb_client
 }  // namespace chromeos