• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2015 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "tpm_manager/server/local_data_store_impl.h"
18 
19 #include <fcntl.h>
20 
21 #include <string>
22 
23 #include <base/files/file_path.h>
24 #include <base/files/file_util.h>
25 #include <base/files/important_file_writer.h>
26 
27 using base::FilePath;
28 
29 namespace tpm_manager {
30 
31 #if defined(__ANDROID__)
32 const char kTpmLocalDataFile[] = "/data/misc/tpm_managerd/local_tpm_data";
33 #else
34 const char kTpmLocalDataFile[] = "/var/lib/tpm_manager/local_tpm_data";
35 #endif
36 const mode_t kLocalDataPermissions = 0600;
37 
Read(LocalData * data)38 bool LocalDataStoreImpl::Read(LocalData* data) {
39   CHECK(data);
40   FilePath path(kTpmLocalDataFile);
41   if (!base::PathExists(path)) {
42     data->Clear();
43     return true;
44   }
45   int permissions = 0;
46   if (base::GetPosixFilePermissions(path, &permissions) &&
47       (permissions & ~kLocalDataPermissions) != 0) {
48     base::SetPosixFilePermissions(path, kLocalDataPermissions);
49   }
50   std::string file_data;
51   if (!ReadFileToString(path, &file_data)) {
52     LOG(ERROR) << "Error reading data store file.";
53     return false;
54   }
55   if (!data->ParseFromString(file_data)) {
56     LOG(ERROR) << "Error parsing file data into protobuf.";
57     return false;
58   }
59   return true;
60 }
61 
Write(const LocalData & data)62 bool LocalDataStoreImpl::Write(const LocalData& data) {
63   std::string file_data;
64   if (!data.SerializeToString(&file_data)) {
65     LOG(ERROR) << "Error serializing file to string.";
66     return false;
67   }
68   FilePath path(kTpmLocalDataFile);
69   if (!base::CreateDirectory(path.DirName())) {
70     LOG(ERROR) << "Cannot create directory: " << path.DirName().value();
71     return false;
72   }
73   if (!base::ImportantFileWriter::WriteFileAtomically(path, file_data)) {
74     LOG(ERROR) << "Failed to write file: " << path.value();
75     return false;
76   }
77   if (!base::SetPosixFilePermissions(path, kLocalDataPermissions)) {
78     LOG(ERROR) << "Failed to set permissions for file: " << path.value();
79     return false;
80   }
81   // Sync the parent directory.
82   std::string dir_name = path.DirName().value();
83   int dir_fd = HANDLE_EINTR(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
84   if (dir_fd < 0) {
85     PLOG(WARNING) << "Could not open " << dir_name << " for syncing";
86     return false;
87   }
88   // POSIX specifies EINTR as a possible return value of fsync().
89   int result = HANDLE_EINTR(fsync(dir_fd));
90   if (result < 0) {
91     PLOG(WARNING) << "Failed to sync " << dir_name;
92     close(dir_fd);
93     return false;
94   }
95   // close() may not be retried on error.
96   result = IGNORE_EINTR(close(dir_fd));
97   if (result < 0) {
98     PLOG(WARNING) << "Failed to close after sync " << dir_name;
99     return false;
100   }
101   return true;
102 }
103 
104 }  // namespace tpm_manager
105