* See the License for the specific language governing permissions and
* limitations under the License
*/
+#include <iomanip>
+
+#include <klay/error.h>
+#include <klay/exception.h>
#include <klay/filesystem.h>
#include <klay/audit/logger.h>
-#include <klay/exception.h>
+#include "../kernel-keyring.h"
#include "../file-footer.h"
#include "ecryptfs-engine.h"
-namespace ode {
-
-EcryptfsEngine::EcryptfsEngine(const std::string &src, const std::string &dest, const ProgressBar &prgsBar) :
- mSource(src), mDestination(dest), progressBar(prgsBar)
-{
-}
-
-EcryptfsEngine::~EcryptfsEngine()
-{
-}
-
-key_serial_t EcryptfsEngine::add_key(const char *type,
- const char *description,
- const void *payload,
- size_t plen,
- key_serial_t ringid)
-{
- return ::syscall(__NR_add_key, type, description, payload, plen, ringid);
-}
-
-long EcryptfsEngine::keyctl_search(key_serial_t ringid,
- const char *type,
- const char *description,
- key_serial_t destringid)
-{
- return ::syscall(__NR_keyctl, KEYCTL_SEARCH, ringid, type, description, destringid);
-}
-
-void EcryptfsEngine::hexConvert(char *dest, unsigned char *src, int srcLen)
-{
- for (int i = 0; i < srcLen; i++)
- ::sprintf(&dest[i * 2], "%.2x", (unsigned char)src[i]);
- dest[srcLen * 2] = '\0';
-}
-
-int EcryptfsEngine::add_user_auth_token_to_keyring(ecryptfs_payload *payload)
-{
- int result = ERR_NO;
-
- if (keyctl_search(KEY_SPEC_USER_KEYRING, AUTH_TOKEN_TYPE,
- (const char *)payload->token.password.signature, 0) <= 0) {
- if (add_key(AUTH_TOKEN_TYPE, (const char *)payload->token.password.signature,
- (void *)payload, sizeof(ecryptfs_payload), KEY_SPEC_USER_KEYRING) <= 0) {
- result = ERR_FAILED_AUTH;
- } else {
- INFO("Token added = " + std::string((const char *)payload->token.password.signature));
- }
- }
-
- return result;
-}
+#if 0
+#define MEDIA_EXCLUSION_LIST "temp_video/Camera/DCIM:mp3|mpga|m4a|mp4|wav|amr|awb|wma|ogg|oga|aac|mka|flac|3gp|3ga|mid|midi|xmf|rtttl|rtx|ota|smf|spm|imy|mpeg|m4v|3gp|3gpp|3g2|3gpp2|wmv|asf|mkv|webm|ts|avi|jpg|jpeg|gif|png|bmp|wbmp|divx|flv|ac3|mov|tiff|f4v|mpeg3|voice"
+#endif
-int EcryptfsEngine::smack_check(void)
-{
- struct statfs sfs;
- int ret;
- int checksmack = 0;
+#define CIPHER_MODE "aes"
+#define ENCRYPTION_CHECKER_NAME ".ecryptfs_encrypted"
+
+
+#define ECRYPTFS_VERSION_MAJOR 0x00
+#define ECRYPTFS_VERSION_MINOR 0x04
+#define ECRYPTFS_VERSION ((ECRYPTFS_VERSION_MAJOR << 8) | ECRYPTFS_VERSION_MINOR)
+
+#define ECRYPTFS_MAX_KEY_BYTES 64
+#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
+#define ECRYPTFS_SIG_SIZE 8
+#define ECRYPTFS_SIG_SIZE_HEX (ECRYPTFS_SIG_SIZE*2)
+#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_SIG_SIZE_HEX
+#define ECRYPTFS_SALT_SIZE 8
+#define ECRYPTFS_MAX_KEY_MOD_NAME_BYTES 16
+
+struct ecryptfs_session_key {
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001
+#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002
+#define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004
+#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008
+ int32_t flags;
+ int32_t encrypted_key_size;
+ int32_t decrypted_key_size;
+ uint8_t encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES];
+ uint8_t decrypted_key[ECRYPTFS_MAX_KEY_BYTES];
+};
+
+struct ecryptfs_password {
+ int32_t password_bytes;
+ int32_t hash_algo;
+ int32_t hash_iterations;
+ int32_t session_key_encryption_key_bytes;
+#define ECRYPTFS_PERSISTENT_PASSWORD 0x01
+#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02
+ uint32_t flags;
+ uint8_t session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
+ uint8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+ uint8_t salt[ECRYPTFS_SALT_SIZE];
+};
+
+struct ecryptfs_private_key {
+ uint32_t key_size;
+ uint32_t data_len;
+ uint8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1];
+ char key_mod_alias[ECRYPTFS_MAX_KEY_MOD_NAME_BYTES + 1];
+ uint8_t data[];
+};
+
+enum ecryptfs_token_types {ECRYPTFS_PASSWORD, ECRYPTFS_PRIVATE_KEY};
+
+struct ecryptfs_auth_tok {
+ uint16_t version;
+ uint16_t token_type;
+#define ECRYPTFS_ENCRYPT_ONLY 0x00000001
+ uint32_t flags;
+ struct ecryptfs_session_key session_key;
+ uint8_t reserved[32];
+ union {
+ struct ecryptfs_password password;
+ struct ecryptfs_private_key private_key;
+ } token;
+} __attribute__((packed));
+
+#if 0
+#define ECRYPTFS_IOCTL_GET_ATTRIBUTES _IOR('l', 0x10, unsigned int)
+#define ECRYPTFS_WAS_ENCRYPTED 0x0080
+#define ECRYPTFS_WAS_ENCRYPTED_OTHER_DEVICE 0x0100
+#endif
- do {
- ret = ::statfs(SMACKFS_MNT, &sfs);
- } while (ret < 0 && errno == EINTR);
+#define ECRYPTFS_AUTH_TOKEN_TYPE "user"
- if (ret == 0 && sfs.f_type == SMACKFS_MAGIC)
- checksmack = 1;
- return checksmack;
-}
+namespace ode {
-void EcryptfsEngine::build_ecryptfs_options(char *ecryptfs_opts, char *sig, int excludeMediaTypes)
-{
- ::sprintf(ecryptfs_opts, ECRYPTFS_PLAINTEXT_PASSTHOUGH","
- ECRYPTFS_SIGNATURE"%s,"
- ECRYPTFS_CIPHERA"%s,"
- ECRYPTFS_KEY_BYTES"%d", sig, ECRYPTFS_FEK_CIPHER, MAX_KEY_BYTES);
-
- if (excludeMediaTypes == EXCL_MEDIA_ON) {
- INFO("building options with media files filtering.");
- ::strcat(ecryptfs_opts, ",");
- ::strcat(ecryptfs_opts, ECRYPTFS_ENABLE_FILTERING);
- ::strcat(ecryptfs_opts, ECRYPTFS_MEDIA_EXCLUSION_LIST);
- } else if (excludeMediaTypes == EXCL_ALL_NEW_ON) {
- INFO("building options with all new files filtering.");
- ::strcat(ecryptfs_opts, ",");
- ::strcat(ecryptfs_opts, ECRYPTFS_ENABLE_FILTERING);
- ::strcat(ecryptfs_opts, ECRYPTFS_GLOBAL_EXCLUSION_LIST);
- } else {
- INFO("building options without file encryption filtering.");
- }
- if (smack_check()) {
- INFO("smack fs was enabled, add smack labeling");
- ::strcat(ecryptfs_opts, ",");
- ::strcat(ecryptfs_opts, SMACKFS_MOUNT_OPT);
- }
-}
+namespace {
-void EcryptfsEngine::mount(const data &key)
+unsigned long long getAvailableSpace(const std::string& mountPoint)
{
- int result = ERR_NO;
- unsigned char master_key[MAX_KEY_BYTES] = {0};
- char ecryptfs_opts[ECRYPTFS_MAX_OPTIONS] = {0};
- INFO("Source: " + mSource);
- INFO("Destination: " + mDestination);
- INFO("EcryptfsMount: ");
- if (key.size() == 0)
- throw runtime::Exception("Key size is zero.");
-
- for (unsigned int iter = 0; iter < key.size(); iter++) {
- master_key[iter] = key[iter];
- }
-
- if (isEcryptfsMountpointMounted(mDestination) == 0) {
- INFO("Already Mounted");
- throw runtime::Exception("Already Mounted.");
+ struct statfs statbuf;
+ if (::statfs(mountPoint.c_str(), &statbuf)) {
+ throw runtime::Exception("Failed to access " + mountPoint);
}
- //MOUNT_ECRYPTFS_DRIVE
- memset(&(sde_payload), 0, sizeof(ecryptfs_payload));
-
- sde_payload.version = ECRYPTFS_VERSION;
- sde_payload.token_type = ECRYPTFS_PWD_PAYLOAD_TYPE;
- sde_payload.token.password.session_key_encryption_key_bytes = MAX_KEY_BYTES;
- sde_payload.token.password.flags = ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
- memcpy(sde_payload.token.password.session_key_encryption_key, master_key, MAX_KEY_BYTES);
-
- hexConvert((char *)sde_payload.token.password.signature, master_key, SIG_SIZE);
-
- result = add_user_auth_token_to_keyring(&sde_payload);
- if (result == ERR_NO) {
- build_ecryptfs_options(ecryptfs_opts, (char *)sde_payload.token.password.signature, mExcludeMedia);
- INFO("encrypted fs option : " + std::string(ecryptfs_opts) + ", source : " + mSource + ", dest : " + mDestination);
- if (::mount(mSource.c_str(), mDestination.c_str(), ECRYPTFS_MOUNT_DEVICE, MS_NODEV, ecryptfs_opts) != 0) {
- INFO("Unable to mount drive: " + std::string(strerror(errno)));
- throw runtime::Exception("Unable to mount drive.");
- } else {
- INFO("Mount is completed.");
- }
- } else {
- INFO("Unable to add token to keyring");
- throw runtime::Exception("Unable to add token to keyring.");
- }
+ return (unsigned long long)statbuf.f_bfree * statbuf.f_bsize;
}
-void EcryptfsEngine::umount()
+bool wasEncrypted(const std::string &path)
{
- int result = ERR_NO;
-
- INFO("EcryptfsUmount");
- if (isEcryptfsMountpointMounted(mDestination) == 0) {
- if (::umount(mDestination.c_str()) != 0) {
- if (::umount2(mDestination.c_str(), MNT_EXPIRE) != 0) {
- INFO("Unmount failed for drive " + mDestination + "err(" + std::to_string(errno) + std::string(strerror(errno)) + ")");
- if (errno == EAGAIN) {
- INFO("Trying Unmount again");
- if (::umount2(mDestination.c_str(), MNT_EXPIRE) != 0) {
- INFO("Unmount failed for drive" + mDestination + "err(" + std::to_string(errno) + std::string(strerror(errno)) + ")");
- throw runtime::Exception("Unmount failed for drive.");
- }
- } else {
- INFO("Drive " + mDestination + "unmounted failed ");
- throw runtime::Exception("Unmount failed for drive.");
- }
- }
- }
+#ifdef ECRYPTFS_IOCTL_GET_ATTRIBUTES
+ unsigned int attrs = 0;
+ bool ret = false;
+ int fd = 0;
- if (result == ERR_NO)
- INFO("Drive " + mDestination + " unmounted successfully");
- else {
- INFO("Drive " + mDestination + " unmounted failed");
- throw runtime::Exception("Unmount failed for drive.");
- }
+ fd = ::open(path.c_str(), O_RDWR);
+ if (fd < 0) {
+ throw runtime::Exception("Failed to open " + path);
}
-}
-void EcryptfsEngine::encrypt(const data &key)
-{
- int result = ERR_NO;
-
- INFO("EcryptfsEncrypt");
- if (!isMountpointMounted(mSource)) {
- INFO("SD Card not inserted!");
- throw runtime::Exception("SD Card not inserted.");
+ if (::ioctl(fd, ECRYPTFS_IOCTL_GET_ATTRIBUTES, &attrs) == 0 &&
+ (attrs & ECRYPTFS_WAS_ENCRYPTED)) {
+ ret = true;
}
+ ::close(fd);
- result = DoCrypt(key, mDestination.c_str(), 1, EXCL_MEDIA_ON);
- if (result != ERR_NO) {
- INFO("Encrypt failed!");
- throw runtime::Exception("Encrypt failed.");
- }
+ return ret;
+#else
+ return true;
+#endif
}
-void EcryptfsEngine::decrypt(const data &key)
-{
- int result = ERR_NO;
+unsigned long long getEncryptedSize(const runtime::File &file) {
+ unsigned long long originalSize = file.size();
+ unsigned long long result = 0;
- INFO("EcryptfsDecrypt");
- if (!isMountpointMounted(mSource)) {
- INFO("SD Card not inserted!");
- throw runtime::Exception("SD Card not inserted.");
+ if (originalSize % 4096) {
+ originalSize = (1 + originalSize / 4096) * 4096;
}
- result = DoCrypt(key, mDestination.c_str(), 0, EXCL_ALL_NEW_ON);
- if (result != ERR_NO) {
- INFO("Decrypt failed!");
- throw runtime::Exception("Decrypt failed.");
+#ifdef ECRYPTFS_IOCTL_GET_ATTRIBUTES
+ if (wasEncrypted(file.getPath())) {
+ result = originalSize;
+ } else {
+#endif
+ result = originalSize + 2 * 4096;
+#ifdef ECRYPTFS_IOCTL_GET_ATTRIBUTES
}
-}
+#endif
-int EcryptfsEngine::DoCrypt(const data &key, const char *path, int reqEnc, int excludeMedia)
-{
- int result = ERR_NO;
- const char *cryptTempFile = CRYPT_META_FILE;
- INFO("DoCrypt: reqEnc: " + std::to_string(reqEnc) + ", excludeMedia: " + std::to_string(excludeMedia));
-
- mPath = path;
- mReqEnc = reqEnc;
- mExcludeMedia = excludeMedia;
- mMetaDataFile = new char[::strlen(mPath) +::strlen(cryptTempFile) + 2];
- if (mMetaDataFile) {
- ::sprintf(mMetaDataFile, "%s%s%s", mPath, "/", cryptTempFile);
+ //TODO : block size have to not hard-coded.
+ // If there is a better way, the followings have to be changed.
+ unsigned int blockSize = 4096;
+ if (result % blockSize) {
+ result = (1 + result / blockSize) * blockSize;
}
- if (reqEnc)
- result = DoEncrypt(key);
- else
- result = DoDecrypt(key);
-
return result;
}
-int EcryptfsEngine::DoEncrypt(const data &key)
-{
- INFO("DoEncrypt()");
-
- try {
- mount(key);
- } catch (runtime::Exception &e) {
- INFO("EcryptfsEngine: Error mounting " + std::string(mPath));
- goto error;
- }
-
- if (createEncryptMetaData(mMetaDataFile) != 0) {
- goto error;
- }
-
- if (preScanForEncrypt(mPath) != 0) {
- goto error;
- }
+unsigned long long getDecryptedSize(const runtime::File &file) {
+ unsigned long long originalSize = file.size();
+ unsigned long long result = originalSize;
- if (mTotalFileCt) {
- mTotalCopied = 0;
- mLastProg = 0;
- progressBar.update(mLastProg);
- INFO("calling the recursive function EncryptFile (" + std::string(mPath) + ")");
- if (cryptInplace(mPath, "", false) != 0) {
- INFO("Ecryptfs: Full Encryption couldn't complete");
- goto error;
+ if (wasEncrypted(file.getPath())) {
+ if (originalSize > 2 * 4096) {
+ result = originalSize - 2 * 4096;
}
- progressBar.done();
- }
-
- return 0;
-error:
- deleteEncryptMetaData(mMetaDataFile);
- umount();
- return -1;
-}
-
-int EcryptfsEngine::DoDecrypt(const data &key)
-{
- INFO("DoDecrypt()");
-
- if (checkEncryptMetaData(ORIG_META_FILE_PATH) != 0) {
- goto success;
- }
-
- try {
- mount(key);
- } catch (runtime::Exception &e) {
- INFO("EcryptfsEngine: Error mounting " + std::string(mPath));
- goto error;
}
- if (preScanForDecrypt(mPath) != 0) {
- goto error;
- }
+ result = originalSize;
- if (mTotalFileCt) {
- mTotalCopied = 0;
- mLastProg = 0;
- progressBar.update(mLastProg);
- INFO("calling the recursive function EncryptFile (" + std::string(mPath) + ")");
- if (cryptInplace(mPath, "", true) != 0) {
- INFO("Ecryptfs: Full Decryption couldn't complete");
- goto error;
- }
- progressBar.done();
+ //TODO : block size have to not hard-coded.
+ // If there is a better way, the followings have to be changed.
+ unsigned int blockSize = 4096;
+ if (result % blockSize) {
+ result = (1 + result / blockSize) * blockSize;
}
- deleteEncryptMetaData(mMetaDataFile);
-success:
- INFO("Decryption Completed !!!");
- umount();
- return 0;
-error:
- umount();
- return -1;
-}
-
-void EcryptfsEngine::progress(long long size)
-{
- int complPercentage = 0;
-
- if (mTotalStSz != 0) {
- complPercentage = (size * 100) / mTotalStSz;
- if ((complPercentage - mLastProg) >= DELTA_PROGRESS) {
- INFO("Progress: " + std::to_string(complPercentage) + "%, Total Size: " + std::to_string(mTotalStSz));
- mLastProg = complPercentage;
- progressBar.update(mLastProg);
- }
- }
+ return result;
}
-long long EcryptfsEngine::CopyImpl(int sfd, int dfd, long long fullsz, bool enctype)
+bool isEnoughToCopyInPlace(const std::string& path,
+ const std::function<unsigned long long(const runtime::File&)> getSizeFunc)
{
- long long ret = -1;
- long long total = 0;
-
- char buffer [ECRYPTFS_BUFFER_SIZE];
-
- INFO("CopyImpl");
- while (1) {
- ssize_t rdsz = 0;
+ unsigned long long availableSpace = getAvailableSpace(path);
- rdsz = FullRead(sfd, buffer, ECRYPTFS_BUFFER_SIZE);
- if (!rdsz) {
- ret = 0;
- break;
- }
-
- if (rdsz < 0) {
- INFO("Error reading src file");
- break;
- }
-
- if (dfd >= 0) {
- ssize_t wrsz = FullWrite(dfd, buffer, rdsz);
- if (wrsz < rdsz) {
- INFO("Write Error");
- break;
+ std::function<bool(const std::string &path)> check;
+ check = [&check, &getSizeFunc, availableSpace](const std::string &path) {
+ for (runtime::DirectoryIterator iter(path), end;
+ iter != end; ++iter) {
+ if (iter->isDirectory()) {
+ if (!check(iter->getPath())) {
+ return false;
+ }
+ } else if (getSizeFunc(*iter) > availableSpace) {
+ //TODO : have to consider changing file size
+ // when encrypt/decrypt
+ return false;
}
}
- total += rdsz;
- mTotalCopied += rdsz;
-
- progress(mTotalCopied);
- }
+ return true;
+ };
- return ret ? -1 : total;
+ return check(path);
}
-ssize_t EcryptfsEngine::FullRead(int fd, void *buf, size_t count)
-{
- ssize_t n;
-
- do {
- n = ::read(fd, buf, count);
- } while (n < 0 && errno == EINTR);
-
- return n;
-}
-ssize_t EcryptfsEngine::FullWrite(int fd, const void *buf, size_t len)
+void copyInPlace(const std::string& source, const std::string& destination,
+ const std::string& temp,
+ const std::function<bool(const std::string&)> &isTarget,
+ const std::function<void(unsigned long long)> &addProgress)
{
- ssize_t total = 0;
-
- while (len) {
- ssize_t n;
+ for (runtime::DirectoryIterator iter(source), end;
+ iter != end; ++iter) {
+ if (iter->isDirectory()) {
+ copyInPlace(iter->getPath(), destination + "/" + iter->getName(),
+ temp, isTarget, addProgress);
+ } else if (isTarget(iter->getPath())) {
+ std::string tempFilePath = temp + "/" + iter->getName();
+ std::string destFilePath = destination + "/" + iter->getName();
- do {
- n = ::write(fd, buf, len);
- } while (n < 0 && errno == EINTR);
+ iter->copyTo(tempFilePath);
+ iter->remove();
+ if (::rename(tempFilePath.c_str(), destFilePath.c_str()) != 0) {
+ throw runtime::Exception("Failed to rename from " + tempFilePath + " to " + destFilePath);
+ }
- if (n < 0) {
- if (total)
- return total;
- return n;
+ addProgress(iter->size());
}
-
- total += n;
- buf = ((const char *)buf) + n;
- len -= n;
}
-
- return total;
}
-int EcryptfsEngine::CopyFile(const char *src, const char *dest, struct stat *src_stat, bool enctype)
+void ecryptfsMount(const std::string &source, const std::string &destination, const std::vector<unsigned char> &key)
{
- int sfd, dfd;
- struct utimbuf times;
- long long retval = 0;
+ ecryptfs_auth_tok payload;
+ std::string mountOption;
- INFO("Copy start " + std::string(src) + " => " + std::string(dest));
+ ::memset(&(payload), 0, sizeof(ecryptfs_auth_tok));
- sfd = ::open(src, O_RDONLY, 0666);
+ payload.version = ECRYPTFS_VERSION;
+ payload.token_type = ECRYPTFS_PASSWORD;
+ payload.token.password.flags = ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET;
+ payload.token.password.session_key_encryption_key_bytes =
+ (ECRYPTFS_MAX_KEY_BYTES > key.size())? key.size() :
+ ECRYPTFS_MAX_KEY_BYTES;
+ ::memcpy(payload.token.password.session_key_encryption_key, key.data(),
+ payload.token.password.session_key_encryption_key_bytes);
- if (sfd < 0) {
- INFO("Cann't open " + std::string(src));
- return -1;
+ std::stringstream signature;
+ signature<< std::hex << std::setfill('0') << std::setw(2);
+ for (unsigned int byte : key) {
+ signature << byte;
+ }
+ for (int i = key.size(); i < ECRYPTFS_SIG_SIZE; i++) {
+ signature << (unsigned int) 0;
}
+ ::memcpy((char *)payload.token.password.signature,
+ signature.str().c_str(), ECRYPTFS_PASSWORD_SIG_SIZE);
- dfd = ::open(dest, O_WRONLY | O_CREAT | O_TRUNC, src_stat->st_mode);
- if (dfd < 0) {
- INFO("Error opening the destination file " + std::string(dest));
- ::close(sfd);
- return -1;
- }
-
- retval = CopyImpl(sfd, dfd, src_stat->st_size, enctype);
-
- if (retval < 0) {
- INFO("Encryption Error CopyData returned <" + std::to_string(retval) + "> : <" + std::string(src) + "> errno " + std::to_string(errno) + " " + std::string(strerror(errno)));
- ::close(sfd);
- ::close(dfd);
- return retval;
+ if (KernelKeyRing::search(KEY_SPEC_USER_KEYRING, ECRYPTFS_AUTH_TOKEN_TYPE,
+ (char *)payload.token.password.signature, 0) < 0) {
+ if (KernelKeyRing::add(ECRYPTFS_AUTH_TOKEN_TYPE,
+ (char *)payload.token.password.signature,
+ (void *)&payload, sizeof(payload),
+ KEY_SPEC_USER_KEYRING) < 0) {
+ throw runtime::Exception("Unable to add token to keyring.");
+ }
}
- times.actime = src_stat->st_atime;
- times.modtime = src_stat->st_mtime;
-
- if (::utime(dest, ×) < 0)
- INFO("can't preserve times of '" + std::string(src) + "'");
+ mountOption = "ecryptfs_passthrough"
+ ",ecryptfs_sig=" + std::string((char *)payload.token.password.signature) +
+ ",ecryptfs_cipher=" CIPHER_MODE
+ ",ecryptfs_key_bytes=" + std::to_string(payload.token.password.session_key_encryption_key_bytes);
- INFO("Copy Completed");
-
- if (::fsync(dfd) != 0)
- INFO("can't fsync of '" + std::string(src) + "'");
- if (::posix_fadvise(dfd, 0, src_stat->st_size, POSIX_FADV_DONTNEED) < 0)
- INFO("can't fadvise of '" + std::string(dest) + "'");
-
- ::close(sfd);
- ::close(dfd);
+#ifdef MEDIA_EXCLUSION_LIST
+ mountOption += ",ecryptfs_enable_filtering=" MEDIA_EXCLUSION_LIST;
+#endif
- return 0;
-}
+ INFO("option = " + mountOption);
+ INFO("source = " + source);
+ INFO("dest = " + destination);
-void EcryptfsEngine::syncdatafile(const char *src)
-{
- int sfd;
- sfd = ::open(src, O_WRONLY);
- if (sfd < 0) {
- INFO("Cann't open " + std::string(src));
- return;
+ if (::mount(source.c_str(), destination.c_str(), "ecryptfs", MS_NODEV,
+ mountOption.c_str()) != 0) {
+ throw runtime::Exception(runtime::GetSystemErrorMessage());
}
- if (::fsync(sfd) != 0)
- INFO("can't fsync of '" + std::string(src) + "'");
- /* just open and close for flushing file to ecryptfs */
- ::close(sfd);
}
-int EcryptfsEngine::cryptInplace(const char *src, const char *tmpdest, bool dec_fl)
-{
- struct stat src_stat;
- int retval = 0;
- int enc_fl = 0;
-
- if (::lstat(src, & src_stat) < 0)
- INFO("source : < " + std::string(src) + "> is a dangling link");
-
- if (S_ISDIR(src_stat.st_mode)) {
- /* dir call recursively */
- DIR *dp;
- struct dirent *d;
-
- dp = ::opendir(src);
- if (NULL == dp) {
- retval = -1;
- return retval;
- }
-
- while ((d = ::readdir(dp)) != NULL) {
- char *nsrc = NULL;
- char *ntmpdest = NULL;
- nsrc = catSubpathFile(src, d->d_name, &ntmpdest);
- if (nsrc == NULL) {
- if (ntmpdest != NULL) delete [] ntmpdest;
- continue;
- }
-
- if (cryptInplace(nsrc, ntmpdest, dec_fl) < 0) {
- INFO("Encryptfile returned error for nsrc <" + std::string(nsrc) + ">");
- retval = -1;
- delete [] ntmpdest;
- delete [] nsrc;
- break;
- }
- delete [] ntmpdest;
- delete [] nsrc;
- }
- ::closedir(dp);
- } else if (S_ISREG(src_stat.st_mode)) {
- enc_fl = fn_was_encrypted(src);
-
- if (enc_fl == WAS_ECRYPTED_ERROR)
- return enc_fl;
-
- if ((!dec_fl && enc_fl == WAS_NOT_ENCRYPTED) ||
- (dec_fl && enc_fl == WAS_ENCRYPTED)) {
- INFO("ENC/DEC " + std::string(src));
-
- retval = CopyFile(src, tmpdest, &src_stat, dec_fl);
- if (retval) {
- INFO("CopyFileImpl returned error <" + std::to_string(retval) + "> errno " + std::to_string(errno) + std::string(strerror(errno)));
- return retval;
- }
- ::unlink(src);
- retval = ::rename(tmpdest, src);
- syncdatafile(src);
- if (retval) {
- INFO("rename returned error <" + std::to_string(retval) + "> errno " + std::to_string(errno) + std::string(strerror(errno)));
- return retval;
- }
- } else
- INFO("File already encrpyted/Decrypted : <" + std::string(src) + ">");
+void ecryptfsUmount(const std::string &destination)
+{
+ if (::umount(destination.c_str()) != 0) {
+ throw runtime::Exception(runtime::GetSystemErrorMessage());
}
- return retval;
+ //TODO : remove key from keyring
}
-int EcryptfsEngine::preScanForEncrypt(const char *src)
-{
- sizeinfo_type szinfo;
- struct statfs statbuf;
- int result = ERR_NO;
-
- INFO("preScanForEncrypt");
- do {
- ::memset(&szinfo, 0, sizeof(sizeinfo_type));
- if (!::statfs(src, &statbuf)) {
- szinfo.availsz = (long long)statbuf.f_bfree * statbuf.f_bsize;
- szinfo.blocksz = (int)statbuf.f_bsize;
- INFO("Free size available from statfs : <" + std::to_string(szinfo.availsz) + ">");
- } else {
- INFO("can't access " + std::string(src));
- return PRESCAN_ERR;
- }
-
- mPreScanEncryptErr = 0;
- result = getEncryptedSize(src, &szinfo);
-
- INFO("Prescan Free <" + std::to_string(szinfo.availsz) + ">, source size <" + std::to_string(szinfo.cursz) + ">, Source Encrypted size <" + std::to_string(szinfo.encsz) + "> largeFileSz <"
- + std::to_string(szinfo.largesz) + "> filecount <" + std::to_string(szinfo.filecount) + "> for <" + std::string(src) + ">");
- INFO("retval <" + std::to_string(result) + "> PrescanencryptErr <" + std::to_string(mPreScanEncryptErr) + ">");
-
- mTotalFileCt = szinfo.filecount;
- mTotalStSz = szinfo.totalstsz;
-
- if (mPreScanEncryptErr == PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR) {
- result = PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR;
- } else if ((mPreScanEncryptErr == PRESCAN_ERR) || (result == PRESCAN_ERR)) {
-#if !defined(NDEBUG)
- int total = (szinfo.encsz + szinfo.largesz - szinfo.cursz + 12 * 1024) / 1024;
- int needed = total - szinfo.availsz / 1024;
-#endif
- if (isEcryptfsMountpointMounted(mPath)) {
- umount();
- INFO("Unmounting mpath <" + std::string(mPath) + ">");
- }
-
- INFO("Prescan failed with Too full error, need more space, " + std::to_string(needed) + " extra, total " + std::to_string(total));
- result = PRESCAN_ERR;
- }
-
- if (result == PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR) {
- INFO("EcryptfsEngine: Need to run Prescan Again");
- continue;
- }
-
- if (result == 0) {
- INFO("EcryptfsEngine: Prescan completed successfully");
- return result;
- }
-
- INFO("EcryptfsEngine: Cannot encrypt, Disk Space is not enough");
- return PRESCAN_ERR;
- } while (1);
-}
+} // namespace
-int EcryptfsEngine::preScanForDecrypt(const char *src)
+EcryptfsEngine::EcryptfsEngine(const std::string &src, const std::string &dest, const ProgressBar &prg) :
+ source(src), destination(dest), progress(prg)
{
- sizeinfo_type szinfo;
- struct statfs statbuf;
- int result = ERR_NO;
-
- INFO("preScanForDecrypt");
- do {
- ::memset(&szinfo, 0, sizeof(EcryptfsEngine::sizeinfo_type));
- if (!::statfs(src, &statbuf)) {
- szinfo.availsz = (long long)statbuf.f_bfree * statbuf.f_bsize;
- szinfo.blocksz = (int)statbuf.f_bsize;
- INFO("Free size available from statfs : <" + std::to_string(szinfo.availsz) + ">");
- } else {
- INFO("can't access " + std::string(src));
- return PRESCAN_ERR;
- }
-
- mPreScanEncryptErr = 0;
- result = getDecryptedSize(src, &szinfo);
-
- INFO("Prescan Decrypt Free <" + std::to_string(szinfo.availsz) + ">, source size <" + std::to_string(szinfo.cursz) + ">, Source Decrypted size <" + std::to_string(szinfo.decsz) + "> largeFileSz <"
- + std::to_string(szinfo.largesz) + "> filecount <" + std::to_string(szinfo.filecount) + "> for <" + std::string(src) + ">");
- INFO("retval <" + std::to_string(result) + "> PrescanencryptErr <" + std::to_string(mPreScanEncryptErr) + ">");
-
- mTotalFileCt = szinfo.filecount;
- mTotalStSz = szinfo.totalstsz;
-
- if (mPreScanEncryptErr == PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR) {
- result = PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR;
- } else if ((mPreScanEncryptErr == PRESCAN_ERR) || (result == PRESCAN_ERR)) {
-#if !defined(NDEBUG)
- int total = (szinfo.encsz + szinfo.largesz - szinfo.cursz + 12 * 1024) / 1024;
- int needed = total - szinfo.availsz / 1024;
-#endif
- if (isEcryptfsMountpointMounted(mPath)) {
- umount();
- INFO("Unmounting mpath <" + std::string(mPath) + ">");
- }
-
- INFO("Prescan failed with Too full error, need more space, " + std::to_string(needed) + " extra, total " + std::to_string(total));
- result = PRESCAN_ERR;
- }
-
- if (result == PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR) {
- INFO("EcryptfsEngine: Need to run Prescan Again");
- continue;
- }
-
- if (result == 0) {
- INFO("EcryptfsEngine: Prescan completed successfully");
- return 0;
- }
-
- INFO("EcryptfsEngine: Cannot encrypt, Disk Space is not enough");
- return PRESCAN_ERR;
- } while (1);
}
-int EcryptfsEngine::getEncryptedSize(const char *src, EcryptfsEngine::sizeinfo_type *szinfo)
+EcryptfsEngine::~EcryptfsEngine()
{
- struct stat src_stat;
- int result = ERR_NO;
- INFO("getEncryptedSize: " + std::string(src));
- if (::lstat(src, &src_stat) < 0)
- INFO("getEncryptedSize: source : <" + std::string(src) + "> is a dangling link");
- if (S_ISDIR(src_stat.st_mode)) {
- /* dir call recursively */
- DIR *dp;
- struct dirent *d;
-
- /* TODO check for recursion
- * no need to Create dir
- * */
- dp = ::opendir(src);
- if (NULL == dp) {
- result = -1;
- INFO("getEncryptedSize: opendir return null <" + std::string(src) + ">");
- return result;
- }
-
- while ((d = ::readdir(dp)) != NULL) {
- char *nsrc = NULL;
- char *ntmpdest = NULL;
-
- nsrc = catSubpathFile(src, d->d_name, &ntmpdest);
-
- if (nsrc == NULL) {
- if (ntmpdest) delete [] ntmpdest;
- continue;
- }
-
- if ((result = getEncryptedSize(nsrc, szinfo)) < 0) {
- INFO("getEncryptedSize() reutnred error for nsrc <" + std::string(nsrc) + "> result < " + std::to_string(result) + ">");
- if (result == PRESCAN_ERR)
- mPreScanEncryptErr = result;
- }
- delete [] ntmpdest;
- delete [] nsrc;
- }
- ::closedir(dp);
- } else if (S_ISREG(src_stat.st_mode)) {
- long long padded_sz = src_stat.st_size;
- long long new_enc_sz = 0;
- int enc_fl = fn_was_encrypted(src);
-
- INFO("fn_was_encrypted returned: " + std::to_string(enc_fl));
-
- if (padded_sz % 4096)
- padded_sz = (1 + padded_sz / 4096) * 4096;
-
- if (enc_fl != WAS_NOT_ENCRYPTED) {
- INFO("Skipping " + std::string(src));
- new_enc_sz = padded_sz;
- } else {
- INFO("PRE ENC " + std::string(src));
- INFO("fn_was_encrypted returned: " + std::to_string(enc_fl));
- new_enc_sz = padded_sz + 2 * 4096;
-
- if (szinfo->largesz < src_stat.st_size)
- szinfo->largesz = src_stat.st_size;
-
- szinfo->filecount += 1;
- szinfo->totalstsz += src_stat.st_size;
- }
-
- // Pad it to block size
- if (new_enc_sz % szinfo->blocksz)
- new_enc_sz = (1 + new_enc_sz / szinfo->blocksz) * szinfo->blocksz;
-
- szinfo->encsz += new_enc_sz;
-
- if ((enc_fl == WAS_NOT_ENCRYPTED) && ((szinfo->encsz - szinfo->cursz) > szinfo->availsz)) {
- if (mPreScanEncryptErr == PRESCAN_TEMP_FILE_EXIST_ERR) {
- result = PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR;
- } else
- result = PRESCAN_ERR;
- }
-
- {
- long long padded_cursz = src_stat.st_size;
-
- if (padded_cursz % szinfo->blocksz)
- padded_cursz = (1 + padded_cursz / szinfo->blocksz) * szinfo->blocksz;
-
- szinfo->cursz += padded_cursz;
- }
- }
-
- return result;
}
-int EcryptfsEngine::getDecryptedSize(const char *src, EcryptfsEngine::sizeinfo_type *szinfo)
+void EcryptfsEngine::mount(const data &key)
{
- struct stat src_stat;
- int result = ERR_NO;
- INFO("getDecryptedSize: " + std::string(src));
- if (::lstat(src, & src_stat) < 0)
- INFO("getDecryptedSize: source : <" + std::string(src) + "> is a dangling link");
-
- if (S_ISDIR(src_stat.st_mode)) {
- /* dir call recursively */
- DIR *dp;
- struct dirent *d;
-
- /* TODO check for recursion
- * no need to Create dir
- * */
- dp = ::opendir(src);
- if (NULL == dp) {
- result = -1;
- INFO("getDecryptedSize: opendir return null <" + std::string(src) + ">");
- return result;
- }
-
- while ((d = ::readdir(dp)) != NULL) {
- char *nsrc = NULL;
- char *ntmpdest = NULL;
-
- nsrc = catSubpathFile(src, d->d_name, &ntmpdest);
-
- if (nsrc == NULL) {
- if (ntmpdest != NULL) delete [] ntmpdest;
- continue;
- }
-
- if ((result = getDecryptedSize(nsrc, szinfo)) < 0) {
- INFO("getDecryptedSize() reutnred error for nsrc <" + std::string(nsrc) + "> result < " + std::to_string(result) + ">");
- if (result == PRESCAN_ERR) {
- mPreScanDecryptErr = result;
- }
- }
- delete [] ntmpdest;
- delete [] nsrc;
- }
- ::closedir(dp);
- } else if (S_ISREG(src_stat.st_mode)) {
- long long decsize = 0;
- long long paddedsize = 0;
- long long paddedstsz = 0;
- int enc_fl = fn_was_encrypted(src);
-
- INFO("fn_was_encrypted returned: " + std::to_string(enc_fl));
-
- if (src_stat.st_size > 2 * 4096)
- decsize = src_stat.st_size - 2 * 4096;
-
- paddedsize = decsize;
- if (decsize % szinfo->blocksz)
- paddedsize = (1 + decsize / szinfo->blocksz) * szinfo->blocksz;
-
- paddedstsz = src_stat.st_size;
- if (paddedstsz % szinfo->blocksz)
- paddedstsz = (1 + paddedstsz / szinfo->blocksz) * szinfo->blocksz;
-
- if (enc_fl == WAS_ENCRYPTED) {
- INFO("PRE ENC " + std::string(src));
- szinfo->filecount += 1;
- szinfo->totalstsz += src_stat.st_size;
-
- if (szinfo->largesz < src_stat.st_size)
- szinfo->largesz = src_stat.st_size;
-
- if ((decsize > szinfo->availsz) ||
- (!decsize && (paddedstsz > szinfo->availsz))) {
- int tmpneeded;
- INFO("Runtime Error source: " + std::string(src) + ", decsz <" + std::to_string(szinfo->decsz) + "> cursz <" + std::to_string(szinfo->cursz) + ">, largesz <" +
- std::to_string(szinfo->largesz) + "> st_size <" + std::to_string(src_stat.st_size) + "> availsz <" + std::to_string(szinfo->availsz) + ">");
- if (mPreScanDecryptErr == PRESCAN_TEMP_FILE_EXIST_ERR)
- result = PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR;
- else
- result = PRESCAN_ERR;
-
- if (decsize)
- tmpneeded = decsize - szinfo->availsz;
- else
- tmpneeded = paddedstsz - szinfo->availsz;
-
- if (szinfo->neededsz < tmpneeded) {
- szinfo->neededsz = tmpneeded;
- if (decsize)
- szinfo->totalneedsz = decsize;
- else
- szinfo->totalneedsz = paddedstsz;
- }
- } else {
- if (decsize) {
- long long delta = paddedsize - decsize - 2 * 4096;
-
- szinfo->decsz += paddedsize;
- if (delta > 0)
- szinfo->availsz += delta;
- } else
- szinfo->decsz += paddedstsz;
-
- szinfo->cursz += paddedstsz;
- }
- } else {
- INFO("in decrypting case fn_was_encrypted returned: " + std::to_string(enc_fl));
- INFO("Skipping " << std::string(src));
- szinfo->decsz += paddedstsz;
- szinfo->cursz += paddedstsz;
- }
- }
-
- return result;
+ ecryptfsMount(source, destination, key);
}
-char *EcryptfsEngine::catSubpathFile(const char *src, const char *filename, char **prefixtmp)
+void EcryptfsEngine::umount()
{
- if (src == NULL || filename == NULL || prefixtmp == NULL)
- return NULL;
-
- char *catstr = new char[::strlen(src) + ::strlen(filename) + 2];
- int len = ::strlen(src);
- const char *prefix = ".tmp_eCfs";
-
- if (filename && check_dots(filename)) {
- delete [] catstr;
- return NULL;
- }
-
- *prefixtmp = new char[::strlen(src) + ::strlen(filename) + ::strlen(prefix) + 2];
-
- while (*filename == '/')
- filename++;
-
- if (src [len - 1] == '/') {
- ::sprintf(catstr, "%s%s", src, filename);
- ::sprintf(*prefixtmp, "%s%s%s", src, prefix, filename);
- } else {
- ::sprintf(catstr, "%s%s%s", src, "/", filename);
- ::sprintf(*prefixtmp, "%s%s%s%s", src, "/", prefix, filename);
- }
-
- if (!::strncmp(filename, prefix, ::strlen(prefix))) {
- INFO("Deleting Existing Temp file " + std::string(filename));
- if (!mPreScanEncryptErr)
- mPreScanEncryptErr = PRESCAN_TEMP_FILE_EXIST_ERR;
- else
- mPreScanEncryptErr = PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR;
- if (!mPreScanDecryptErr)
- mPreScanDecryptErr = PRESCAN_TEMP_FILE_EXIST_ERR;
- else
- mPreScanDecryptErr = PRESCAN_TEMP_FILE_EXIST_AND_SIZE_ERR;
- ::unlink(catstr);
- delete [] * prefixtmp;
- delete [] catstr;
- *prefixtmp = NULL;
- return NULL;
- }
-
- return catstr;
+ ecryptfsUmount(destination);
}
-int EcryptfsEngine::fn_was_encrypted(const char *filePath)
+void EcryptfsEngine::encrypt(const data &key)
{
- int fd = 0;
- int ret = WAS_NOT_ENCRYPTED;
- __u32 attrs = 0;
-
- if (filePath == NULL) {
- INFO("Ecryptfs: fn_was_encrypted: source file path is null");
- return WAS_ECRYPTED_ERROR;
+ if (!isEnoughToCopyInPlace(source, getDecryptedSize)) {
+ throw runtime::Exception("No space to encryption");
}
- fd = ::open(filePath, O_RDWR);
- if (fd < 0) {
- INFO("Ecryptfs: fn_was_encrypted: cannot open file " + std::string(strerror(errno)));
- return WAS_ECRYPTED_ERROR;
- }
+ progress.update(0);
- if (::ioctl(fd, ECRYPTFS_IOCTL_GET_ATTRIBUTES, &attrs)) {
- INFO("Ecryptfs: fn_was_encrypted: ioctl fail " + std::string(strerror(errno)));
- ::close(fd);
- return WAS_ECRYPTED_ERROR;
- }
-
- INFO("Ecryptfs: IOCT_GET_ATTRIBUTE = " + std::to_string(attrs));
- if ((attrs & ECRYPTFS_WAS_ENCRYPTED) == ECRYPTFS_WAS_ENCRYPTED)
- ret = WAS_ENCRYPTED;
- else if ((attrs & ECRYPTFS_WAS_ENCRYPTED_OTHER_DEVICE) == ECRYPTFS_WAS_ENCRYPTED_OTHER_DEVICE)
- ret = WAS_ENCRYPTED_OTHER_DEVICE;
-
- ::close(fd);
-
- return ret;
-}
-
-int EcryptfsEngine::createEncryptMetaData(const char *filename)
-{
- int fd = -1;
- INFO("createEncryptMetaData");
-
- fd = ::open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
- if (fd < 0) {
- INFO("Cann't open " + std::string(filename));
- return -1;
+ try {
+ ecryptfsMount(source, destination, key);
+ } catch (runtime::Exception &e) {
+ throw runtime::Exception("Failed to mount - " + std::string(e.what()));
}
- if (::fsync(fd) != 0)
- INFO("Cann't fsync of '" + std::string(filename) + "'");
- ::close(fd);
- return 0;
-}
-int EcryptfsEngine::checkEncryptMetaData(const char *path)
-{
- struct stat src_stat;
- int retval = 0;
-
- if (path == NULL) {
- if (mMetaDataFile) {
- if (::lstat(mMetaDataFile, &src_stat) < 0)
- if (errno == ENOENT)
- retval = -1;
- }
- } else {
- std::cout << path << std::endl;
- if (::stat(path, &src_stat) < 0)
- if (errno == ENOENT)
- retval = -1;
+ try {
+ unsigned long long totalSize = getAvailableSpace(source), current;
+ runtime::File tempDir(destination + "/" ENCRYPTION_CHECKER_NAME);
+
+ tempDir.makeDirectory();
+ copyInPlace(destination, destination, tempDir.getPath(),
+ [](const std::string &file) {
+ return true;
+ },
+ [¤t, &totalSize, this](unsigned long long size) {
+ current += size;
+ this->progress.update(current * 100 / totalSize);
+ });
+ } catch (runtime::Exception &e) {
+ try {
+ ecryptfsUmount(destination);
+ } catch (runtime::Exception &e) {}
+ throw runtime::Exception("Failed to encrypt file - " + std::string(e.what()));
}
- return retval;
-}
+ sync();
-void EcryptfsEngine::deleteEncryptMetaData(const char *filename)
-{
- if (checkEncryptMetaData(filename) == 0)
- ::unlink(filename);
+ progress.done();
}
-int EcryptfsEngine::isMountpointMounted(const std::string &path)
+void EcryptfsEngine::decrypt(const data &key)
{
- char device[256];
- char mount_path[256];
- char rest[256];
- FILE *fp;
- char line[1024];
-
- if (!(fp = ::fopen("/proc/mounts", "r"))) {
- INFO("Error opening /proc/mounts (" + std::string(strerror(errno)) + ")");
- return 0;
+ if (!isEnoughToCopyInPlace(destination, getEncryptedSize)) {
+ throw runtime::Exception("No space to encryption");
}
- while (::fgets(line, sizeof(line), fp)) {
- line[::strlen(line) - 1] = '\0';
- ::sscanf(line, "%255s %255s %255s\n", device, mount_path, rest);
- if (!::strcmp(mount_path, path.c_str())) {
- ::fclose(fp);
- return 1;
- }
- }
+ progress.update(0);
- ::fclose(fp);
- return 0;
-}
-
-int EcryptfsEngine::isEcryptfsMountpointMounted(const std::string &path)
-{
- char device[256];
- char mount_path[256];
- char dev_path[256];
- char rest[256];
- FILE *fp;
- char line[1024];
-
- if (!(fp = ::fopen("/proc/mounts", "r"))) {
- INFO("Error opening /proc/mounts (" + std::string(strerror(errno)) + ")");
- return -1;
+ try {
+ unsigned long long totalSize = getAvailableSpace(source), current;
+ runtime::File tempDir(source + "/" ENCRYPTION_CHECKER_NAME);
+ runtime::File tempMountpoint(tempDir.getPath() + "/mount");
+
+ tempMountpoint.makeDirectory();
+ ecryptfsMount(source, tempMountpoint.getPath(), key);
+
+ copyInPlace(tempMountpoint.getPath(), source,
+ tempDir.getPath(), wasEncrypted,
+ [¤t, &totalSize, this](unsigned long long size) {
+ current += size;
+ this->progress.update(current * 100 / totalSize);
+ });
+ ecryptfsUmount(tempMountpoint.getPath());
+
+ tempDir.remove(true);
+ } catch (runtime::Exception &e) {
+ throw runtime::Exception("Failed to decrypt file - " + std::string(e.what()));
}
- while (::fgets(line, sizeof(line), fp)) {
- line[strlen(line) - 1] = '\0';
- ::sscanf(line, "%255s %255s %255s %255s\n", dev_path, mount_path, device, rest);
- if (!::strcmp(mount_path, path.c_str()) && !strcmp(device, "ecryptfs")) {
- ::fclose(fp);
- INFO("Returning True mount_path<" + std::string(mount_path) + ">,path <" + path + ">, device <" + std::string(device) + ">");
- return 0;
- }
- }
+ sync();
- fclose(fp);
- return -1;
+ progress.done();
}
const EcryptfsEngine::data EcryptfsEngine::getKeyMeta()
{
- return FileFooter::read(mSource);
+ return FileFooter::read(source);
}
void EcryptfsEngine::setKeyMeta(const data &meta)
{
- FileFooter::write(mSource, meta);
+ FileFooter::write(source, meta);
}
} // namespace ode