36 #define DEVICE_MAPPER_DIR "/dev/mapper/" 41 const uint CryptoManager::signonMinumumDbSize = 8;
42 const char CryptoManager::signonDefaultFileSystemName[] =
"signonfs";
43 const char CryptoManager::signonDefaultFileSystemType[] =
EXT2;
45 const QString CryptoManager::keychainFilePath()
const 47 return m_fileSystemMountPath + QDir::separator() + QLatin1String(
"keychain");
50 void CryptoManager::addKeyToKeychain(
const QByteArray &key)
const 53 if (keychainContainsKey(key))
return;
55 QSettings keychain(keychainFilePath(), QSettings::IniFormat);
56 int keyCount = keychain.allKeys().count();
57 keychain.setValue(QString::number(++keyCount), QVariant(key));
60 void CryptoManager::removeKeyFromKeychain(
const QByteArray &key)
const 62 QSettings keychain(keychainFilePath(), QSettings::IniFormat);
63 foreach (QString keyIt, keychain.allKeys()) {
64 if (keychain.value(keyIt).toByteArray() == key) {
65 keychain.remove(keyIt);
71 bool CryptoManager::keychainContainsKey(
const QByteArray &key)
const 73 QSettings keychain(keychainFilePath(), QSettings::IniFormat);
74 foreach (QString keyIt, keychain.allKeys()) {
75 if (keychain.value(keyIt).toByteArray() == key)
83 SignOn::AbstractCryptoManager(parent),
84 m_fileSystemPath(QString()),
85 m_fileSystemMapPath(QString()),
86 m_fileSystemName(QString()),
87 m_fileSystemMountPath(QString()),
88 m_loopDeviceName(QString()),
89 m_fileSystemType(
Ext2),
92 updateMountState(Unmounted);
94 BLAME() <<
"Could not load `dm_mod`!";
104 QString storagePath =
105 QDir(configuration.value(QLatin1String(
"StoragePath")).toString()).path();
106 if (storagePath.startsWith(QLatin1Char(
'~')))
107 storagePath.replace(0, 1, QDir::homePath());
109 QString encryptedFSPath =
110 storagePath + QDir::separator() +
111 QLatin1String(signonDefaultFileSystemName);
114 quint32 storageSize =
115 configuration.value(QLatin1String(
"Size")).toUInt(&isOk);
116 if (!isOk || storageSize < signonMinumumDbSize) {
117 storageSize = signonMinumumDbSize;
118 TRACE() <<
"Less than minimum possible storage size configured." 119 <<
"Setting to the minimum of:" << signonMinumumDbSize <<
"Mb";
122 QString fileSystemType =
123 configuration.value(QLatin1String(
"FileSystemType")).toString();
125 setFileSystemPath(encryptedFSPath);
126 setFileSystemSize(storageSize);
127 setFileSystemType(fileSystemType);
129 checkFileSystemSetup();
133 void CryptoManager::setFileSystemPath(
const QString &path)
135 m_fileSystemPath = path;
137 QFileInfo fsFileInfo(path);
139 m_fileSystemName = fsFileInfo.fileName();
141 m_fileSystemMountPath = path + QLatin1String(
"-mnt");
144 bool CryptoManager::setFileSystemSize(
const quint32 size)
147 TRACE() <<
"Minumum encrypted file size is 4 Mb.";
150 m_fileSystemSize = size;
154 bool CryptoManager::setFileSystemType(
const QString &type)
156 QString cmpBase = type.toLower();
157 if (cmpBase == QLatin1String(
EXT2)) {
158 m_fileSystemType =
Ext2;
160 }
else if (cmpBase == QLatin1String(
EXT3)) {
161 m_fileSystemType =
Ext3;
163 }
else if (cmpBase == QLatin1String(
EXT4)) {
164 m_fileSystemType =
Ext4;
170 void CryptoManager::checkFileSystemSetup()
172 setFileSystemSetup(QFile::exists(m_fileSystemPath));
177 if (m_mountState == Mounted) {
178 TRACE() <<
"Ecrypyted file system already mounted.";
182 if (encryptionKey().isEmpty()) {
183 TRACE() <<
"No access code set. Stopping mount process.";
188 BLAME() <<
"Could not load `dm_mod`!";
192 clearFileSystemResources();
195 if (m_loopDeviceName.isNull()) {
196 BLAME() <<
"No free loop device available!";
202 BLAME() <<
"Could not create partition file.";
206 checkFileSystemSetup();
210 BLAME() <<
"Failed to setup loop device:" << m_loopDeviceName;
214 updateMountState(LoopSet);
217 BLAME() <<
"Failed to LUKS format.";
221 updateMountState(LoopLuksFormatted);
225 TRACE() <<
"Filesystem exists, closing";
232 BLAME() <<
"Failed to LUKS open";
236 updateMountState(LoopLuksOpened);
240 BLAME() <<
"Could not format mapped partition.";
245 if (!mountMappedDevice()) {
246 BLAME() <<
"Failed to mount ecrypted file system.";
251 addKeyToKeychain(encryptionKey());
252 updateMountState(Mounted);
260 if (m_mountState == Mounted) {
261 TRACE() <<
"Ecrypyted file system already mounted.";
265 if (encryptionKey().isEmpty()) {
266 TRACE() <<
"No access code set. Stopping mount process.";
270 clearFileSystemResources();
273 BLAME() <<
"Could not load `dm_mod`!";
278 if (m_loopDeviceName.isNull()) {
279 BLAME() <<
"No free loop device available!";
284 BLAME() <<
"Failed to setup loop device:" << m_loopDeviceName;
288 updateMountState(LoopSet);
297 BLAME() <<
"Failed to LUKS open.";
301 updateMountState(LoopLuksOpened);
303 if (!mountMappedDevice()) {
304 TRACE() <<
"Failed to mount ecrypted file system.";
309 addKeyToKeychain(encryptionKey());
310 updateMountState(Mounted);
314 void CryptoManager::clearFileSystemResources()
322 TRACE() <<
"--- START clearing secure storage possibly used resources." 323 " Ignore possible errors. ---";
325 if (!unmountMappedDevice())
326 TRACE() <<
"Unmounting mapped device failed.";
330 TRACE() <<
"Failed to LUKS close.";
342 TRACE() <<
"--- DONE clearing secure storage possibly used resources. ---";
347 if (m_mountState == Unmounted) {
348 TRACE() <<
"Ecrypyted file system not mounted.";
352 setFileSystemMounted(
false);
355 if ((m_mountState >= Mounted)
356 && !unmountMappedDevice()) {
357 TRACE() <<
"Failed to unmount mapped loop device.";
360 TRACE() <<
"Mapped loop device unmounted.";
363 if ((m_mountState >= LoopLuksOpened)
365 TRACE() <<
"Failed to LUKS close.";
368 TRACE() <<
"Luks close succeeded.";
371 if ((m_mountState >= LoopSet)
373 TRACE() <<
"Failed to release loop device.";
376 TRACE() <<
"Loop device released.";
379 updateMountState(Unmounted);
385 if (m_mountState > Unmounted) {
396 return m_fileSystemMountPath;
401 return QStringList() << m_fileSystemPath;
404 void CryptoManager::updateMountState(
const FileSystemMountState state)
406 TRACE() <<
"Updating mount state:" << state;
407 if (state == m_mountState)
return;
409 m_mountState = state;
410 setFileSystemMounted(state == Mounted);
413 bool CryptoManager::mountMappedDevice()
416 if (!QFile::exists(m_fileSystemMountPath)) {
418 if (!dir.mkpath(m_fileSystemMountPath)) {
419 BLAME() <<
"Could not create target mount dir path.";
424 TRACE() <<
"Failed to set User ownership for " 425 "the secure storage mount target.";
432 bool CryptoManager::unmountMappedDevice()
438 const SignOn::Key &existingKey)
443 if (m_mountState >= LoopLuksOpened) {
445 m_loopDeviceName, key, existingKey)) {
447 addKeyToKeychain(key);
451 TRACE() <<
"FAILED to occupy key slot on the encrypted file system header.";
456 const SignOn::Key &remainingKey)
458 if (m_mountState >= LoopLuksOpened) {
460 m_loopDeviceName, key, remainingKey))
462 removeKeyFromKeychain(key);
465 TRACE() <<
"FAILED to release key slot from the encrypted file system " 472 if (fileSystemIsMounted() && (encryptionKey() == key))
475 if(!fileSystemIsMounted()) {
476 setEncryptionKey(key);
483 return keychainContainsKey(key);
502 void CryptoManager::serializeData()
504 TRACE() <<
"m_accessCode" << encryptionKey();
505 TRACE() <<
"m_fileSystemPath" << m_fileSystemPath;
506 TRACE() <<
"m_fileSystemMapPath" << m_fileSystemMapPath;
507 TRACE() <<
"m_fileSystemName" << m_fileSystemName;
508 TRACE() <<
"m_loopDeviceName" << m_loopDeviceName;
509 TRACE() <<
"m_fileSystemType" << m_fileSystemType;
510 TRACE() <<
"m_fileSystemSize" << m_fileSystemSize;
static bool setupDevice(const QString &deviceName, const QString &blockDevice)
Mounts a block device to loopback device.
bool deleteFileSystem()
Deletes the encrypted file system.
static bool formatPartitionFile(const QString &fileName, const quint32 fileSystemType)
Formats a file (block device) for a specific file system type (ext2,ext3,ext4)
~CryptoManager()
Destroys a CryptoManager object.
static bool createPartitionFile(const QString &fileName, const quint32 fileSize)
Creates a random data file of fileSize Mb.
bool mountFileSystem()
Mounts the encrypted file system.
bool removeEncryptionKey(const SignOn::Key &key, const SignOn::Key &remainingKey)
Releases an existing used keyslot in the LUKS partition's header.
static bool formatFile(const QByteArray &key, const QString &deviceName)
Formats the file system.
#define DEVICE_MAPPER_DIR
bool initialize(const QVariantMap &configuration)
static bool loadDmMod()
Loads the dm_mod kernel module.
QStringList backupFiles() const
static bool closeFile(const QString &deviceName)
Closes the file system.
static bool umount(const QString &target)
Unmounts a block device from a specific location.
bool setUserOwnership(const QString &filePath)
CryptoManager(QObject *parent=0)
Constructs a CryptoManager object with the given parent.
static bool removeKeySlot(const QString &deviceName, const QByteArray &key, const QByteArray &remainingKey)
Removes a key ocupying an encryption header slot.
bool encryptionKeyInUse(const SignOn::Key &key)
#define MINUMUM_ENCRYPTED_FILE_SYSTEM_SIZE
QString fileSystemMountPath() const
static bool addKeySlot(const QString &deviceName, const QByteArray &key, const QByteArray &existingKey)
Adds a key to a free encryption header slot.
bool addEncryptionKey(const SignOn::Key &key, const SignOn::Key &existingKey)
Adds an encryption key to one of the available keyslots of the LUKS partition's header.
bool unmountFileSystem()
Unmounts the encrypted file system.
static bool mount(const QString &source, const QString &target, const QString &fileSystemType=QLatin1String("ext2"))
Mounts a block device to a specific location.
static bool releaseDevice(const QString &deviceName)
Releases a used loopback device.
static QString findAvailableDevice()
Finds an available loopback device.
static bool openFile(const QByteArray &key, const QString &deviceName, const QString &deviceMap)
Opens the file system.
bool setupFileSystem()
Sets up an encrypted file system.