* @brief Sample service implementation.
*/
#include <string.h>
+#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string>
#include <sstream>
#include <fstream>
+#include <memory>
+#include <stdexcept>
#include <dpl/errno_string.h>
+#include <dpl/fstream_accessors.h>
#include <dpl/log/log.h>
+#include <exception.h>
#include <file-system.h>
namespace {
-static const std::string CKM_DATA_PATH = "/opt/data/ckm/";
-static const std::string CKM_KEY_PREFIX = "key-";
-static const std::string CKM_DB_KEY_PREFIX = "db-key-";
-static const std::string CKM_DB_PREFIX = "db-";
-static const std::string CKM_REMOVED_APP_PREFIX = "removed-app-";
+const std::string CKM_DATA_PATH = "/opt/data/ckm/";
+const std::string CKM_KEY_PREFIX = "key-";
+const std::string CKM_DB_KEY_PREFIX = "db-key-";
+const std::string CKM_DB_PREFIX = "db-";
+const std::string CKM_REMOVED_APP_PREFIX = "removed-app-";
+const std::string CKM_LOCK_FILE = "/var/run/key-manager.pid";
} // namespace anonymous
RawBuffer FileSystem::loadFile(const std::string &path) const {
std::ifstream is(path);
- if (is.fail())
+ if (is.fail() && ENOENT == errno)
return RawBuffer();
+ if (is.fail()) {
+ auto description = GetErrnoString(errno);
+ ThrowErr(Exc::FileSystemFailed,
+ "Error opening file: ", path, " Reason: ", description);
+ }
+
std::istreambuf_iterator<char> begin(is),end;
std::vector<char> buff(begin,end); // This trick does not work with boost vector
return loadFile(getDBDEKPath());
}
-bool FileSystem::saveFile(const std::string &path, const RawBuffer &buffer) const {
- std::ofstream os(path, std::ios::out | std::ofstream::binary);
+void FileSystem::saveFile(const std::string &path, const RawBuffer &buffer) const {
+ std::ofstream os(path, std::ios::out | std::ofstream::binary | std::ofstream::trunc);
std::copy(buffer.begin(), buffer.end(), std::ostreambuf_iterator<char>(os));
- return !os.fail();
+
+ // Prevent desynchronization in batter remove test.
+ os.flush();
+ fsync(FstreamAccessors<std::ofstream>::GetFd(os)); // flush kernel space buffer
+ os.close();
+
+ if (os.fail())
+ ThrowErr(Exc::FileSystemFailed, "Failed to save file: ", path);
}
-bool FileSystem::saveDKEK(const RawBuffer &buffer) const {
- return saveFile(getDKEKPath(), buffer);
+void FileSystem::saveDKEK(const RawBuffer &buffer) const {
+ saveFile(getDKEKPath(), buffer);
}
-bool FileSystem::saveDBDEK(const RawBuffer &buffer) const {
- return saveFile(getDBDEKPath(), buffer);
+void FileSystem::saveDBDEK(const RawBuffer &buffer) const {
+ saveFile(getDBDEKPath(), buffer);
}
-bool FileSystem::addRemovedApp(const std::string &smackLabel) const
+void FileSystem::addRemovedApp(const std::string &smackLabel) const
{
std::ofstream outfile;
outfile.open(getRemovedAppsPath(), std::ios_base::app);
outfile << smackLabel << std::endl;
outfile.close();
- return !outfile.fail();
+ if (outfile.fail()) {
+ auto desc = GetErrnoString(errno);
+ ThrowErr(Exc::FileSystemFailed,
+ "Could not update file: ", getRemovedAppsPath(), " Reason: ", desc);
+ }
}
AppLabelVector FileSystem::clearRemovedsApps() const
errno = 0;
if ((mkdir(CKM_DATA_PATH.c_str(), 0700)) && (errno != EEXIST)) {
int err = errno;
- LogError("Error in mkdir. Data directory could not be created. Errno: "
- << err << " (" << GetErrnoString(err) << ")");
+ LogError("Error in mkdir " << CKM_DATA_PATH << ". Reason: " << GetErrnoString(err));
return -1; // TODO set up some error code
}
return 0;
struct dirent* pDirEntry = NULL;
while ( (!readdir_r(dirp.get(), pEntry.get(), &pDirEntry)) && pDirEntry ) {
-
// Ignore files with diffrent prefix
if (strncmp(pDirEntry->d_name, CKM_KEY_PREFIX.c_str(), CKM_KEY_PREFIX.size())) {
continue;
try {
uids.push_back(static_cast<uid_t>(std::stoi((pDirEntry->d_name)+CKM_KEY_PREFIX.size())));
} catch (const std::invalid_argument) {
- LogError("Error in extracting uid from db file. Error=std::invalid_argument."
+ LogDebug("Error in extracting uid from db file. Error=std::invalid_argument."
"This will be ignored.File=" << pDirEntry->d_name << "");
} catch(const std::out_of_range) {
- LogError("Error in extracting uid from db file. Error=std::out_of_range."
+ LogDebug("Error in extracting uid from db file. Error=std::out_of_range."
"This will be ignored. File="<< pDirEntry->d_name << "");
}
}
if (unlink(getDBPath().c_str())) {
retCode = -1;
err = errno;
- LogError("Error in unlink user database: " << getDBPath()
+ LogDebug("Error in unlink user database: " << getDBPath()
<< "Errno: " << errno << " " << GetErrnoString(err));
}
if (unlink(getDKEKPath().c_str())) {
retCode = -1;
err = errno;
- LogError("Error in unlink user DKEK: " << getDKEKPath()
+ LogDebug("Error in unlink user DKEK: " << getDKEKPath()
<< "Errno: " << errno << " " << GetErrnoString(err));
}
if (unlink(getDBDEKPath().c_str())) {
retCode = -1;
err = errno;
- LogError("Error in unlink user DBDEK: " << getDBDEKPath()
+ LogDebug("Error in unlink user DBDEK: " << getDBDEKPath()
<< "Errno: " << errno << " " << GetErrnoString(err));
}
if (unlink(getRemovedAppsPath().c_str())) {
retCode = -1;
err = errno;
- LogError("Error in unlink user's Removed Apps File: " << getRemovedAppsPath()
+ LogDebug("Error in unlink user's Removed Apps File: " << getRemovedAppsPath()
<< "Errno: " << errno << " " << GetErrnoString(err));
}
return retCode;
}
+FileLock FileSystem::lock()
+{
+ FileLock fl(CKM_LOCK_FILE.c_str());
+ return fl;
+}
+
} // namespace CKM