RawBuffer key = handle.keyProvider.getPureDEK(wrappedDatabaseDEK);
handle.database = DBCrypto(fs.getDBPath(), key);
handle.crypto = CryptoLogic();
+
+ // remove data of removed apps during locked state
+ AppLabelVector removedApps = fs.clearRemovedsApps();
+ for(auto& appSmackLabel : removedApps) {
+ handle.database.deleteKey(appSmackLabel);
+ }
+
// TODO wipe key
}
} catch (const KeyProvider::Exception::PassWordError &e) {
if (smackLabel.empty()) {
retCode = CKM_API_ERROR_INPUT_PARAM;
} else {
- for(auto &handler: m_userDataMap) {
- handler.second.database.deleteKey(smackLabel);
+ UidVector uids = FileSystem::getUIDsFromDBFile();
+ for (auto userId : uids) {
+ if (0 == m_userDataMap.count(userId)) {
+ FileSystem fs(userId);
+ fs.addRemovedApp(smackLabel);
+ } else {
+ auto &handle = m_userDataMap[userId];
+ handle.database.deleteKey(smackLabel);
+ }
}
}
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <dirent.h>
+#include <cstdlib>
#include <string>
#include <sstream>
#include <fstream>
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-";
} // namespace anonymous
return ss.str();
}
+std::string FileSystem::getRemovedAppsPath() const {
+ std::stringstream ss;
+ ss << CKM_DATA_PATH << CKM_REMOVED_APP_PREFIX << m_uid;
+ return ss.str();
+}
+
RawBuffer FileSystem::loadFile(const std::string &path) const {
std::ifstream is(path);
return saveFile(getDBDEKPath(), buffer);
}
+bool 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();
+}
+
+AppLabelVector FileSystem::clearRemovedsApps() const
+{
+ // read the contents
+ AppLabelVector removedApps;
+ std::string line;
+ std::ifstream removedAppsFile(getRemovedAppsPath());
+ if (removedAppsFile.is_open()) {
+ while (! removedAppsFile.eof() ) {
+ getline (removedAppsFile,line);
+ if(line.size() > 0)
+ removedApps.push_back(line);
+ }
+ removedAppsFile.close();
+ }
+ // truncate the contents
+ std::ofstream truncateFile;
+ truncateFile.open(getRemovedAppsPath(), std::ofstream::out | std::ofstream::trunc);
+ truncateFile.close();
+ return removedApps;
+}
+
int FileSystem::init() {
errno = 0;
if ((mkdir(CKM_DATA_PATH.c_str(), 0700)) && (errno != EEXIST)) {
return 0;
}
+UidVector FileSystem::getUIDsFromDBFile() {
+ UidVector uids;
+ DIR *dirp = NULL;
+ errno = 0;
+
+ if((dirp = opendir(CKM_DATA_PATH.c_str())) == NULL) {
+ int err = errno;
+ LogError("Error in opendir. Data directory could not be read. Errno: "
+ << err << " (" << strerror(err) << ")");
+ return UidVector();
+ }
+
+ struct dirent pPrevDirEntry;
+ struct dirent* pDirEntry = NULL;
+
+ while ((!readdir_r(dirp, &pPrevDirEntry, &pDirEntry)) && pDirEntry && (pDirEntry->d_name)) {
+
+ // Ignore files with diffrent prefix
+ if (strncmp(pDirEntry->d_name, CKM_KEY_PREFIX.c_str(), CKM_KEY_PREFIX.size())) {
+ continue;
+ }
+
+ // We find database. Let's extract user id.
+ 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."
+ "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."
+ "This will be ignored. File="<< pDirEntry->d_name << "");
+ }
+ }
+
+ closedir(dirp);
+ return uids;
+}
+
int FileSystem::removeUserData() const {
int err, retCode = 0;
<< "Errno: " << errno << " " << strerror(err));
}
+ if (unlink(getRemovedAppsPath().c_str())) {
+ retCode = -1;
+ err = errno;
+ LogError("Error in unlink user's Removed Apps File: " << getRemovedAppsPath()
+ << "Errno: " << errno << " " << strerror(err));
+ }
+
return retCode;
}
namespace CKM {
+typedef std::vector<std::string> AppLabelVector;
+typedef std::vector<uid_t> UidVector;
+
class FileSystem {
public:
FileSystem(uid_t uid);
RawBuffer getDBDEK() const;
bool saveDBDEK(const RawBuffer &buffer) const;
+ // Remove all ckm data related to user
int removeUserData() const;
+ bool addRemovedApp(const std::string &smackLabel) const;
+ AppLabelVector clearRemovedsApps() const;
+
static int init();
+ static UidVector getUIDsFromDBFile();
virtual ~FileSystem(){}
protected:
std::string getDBDEKPath() const;
RawBuffer loadFile(const std::string &path) const;
bool saveFile(const std::string &path, const RawBuffer &buffer) const;
+ std::string getRemovedAppsPath() const;
uid_t m_uid;
};