From e5dc91e4896490e4844ea3fac32a5115d4f89e89 Mon Sep 17 00:00:00 2001 From: hama Date: Thu, 15 Oct 2015 00:30:49 +0200 Subject: [PATCH] file content encoding --- base/ReRandomizer.cpp | 32 ++++- base/ReRandomizer.hpp | 7 ++ base/rebase.hpp | 14 +++ cunit/cuReFileSystem.cpp | 66 ++++++++-- os/ReFileSystem.cpp | 256 +++++++++++++++++++++------------------ os/ReFileSystem.hpp | 41 ++++--- 6 files changed, 264 insertions(+), 152 deletions(-) diff --git a/base/ReRandomizer.cpp b/base/ReRandomizer.cpp index ab67d85..1736b2a 100644 --- a/base/ReRandomizer.cpp +++ b/base/ReRandomizer.cpp @@ -301,6 +301,16 @@ ReSingleSeedRandomizer::ReSingleSeedRandomizer(const char* name) : m_seed(0x1120120419198991ull), m_lastSetSeed(0x1120120419198991ull) { } + +/** + * Modifies the current seed with a 64-bit value. + * + * @param seed the value to modify the current seed + */ +void ReSingleSeedRandomizer::modifySeed(int64_t seed) { + m_seed += seed; +} + /** * Sets the seed to the start point (defined with setSeed()). */ @@ -490,7 +500,19 @@ ReRandomizer::seed_t ReMultiCongruentialGenerator::nextSeed() { return rc; } -/** @brief Sets the instance to a defined start state. +/** + * Modifies the current seed with a 64-bit value. + * + * @param seed the value to modify the current seed + */ +void ReMultiSeedRandomizer::modifySeed(int64_t seed) { + for (int ix = 0; ix < m_countSeeds; ix++) { + m_seeds[ix] += seed; + seed = ((seed << 1) | (seed < 0 ? 1 : 0)); + } +} +/** + * Sets the instance to a defined start state. */ void ReMultiSeedRandomizer::reset() { // assignment does not work: copy on write @@ -622,6 +644,14 @@ ReRandomizer::seed_t ReKISSRandomizer::nextSeed() { return m_params.m_x + m_params.m_y + m_params.m_z; } +/** + * Modifies the current seed with a 64-bit value. + * + * @param seed the value to modify the current seed + */ +void ReKISSRandomizer::modifySeed(int64_t seed) { + m_params.m_x ^= seed; +} /** * Sets the seed to the start point (defined with setSeed()). */ diff --git a/base/ReRandomizer.hpp b/base/ReRandomizer.hpp index b0d1286..bae5487 100644 --- a/base/ReRandomizer.hpp +++ b/base/ReRandomizer.hpp @@ -36,6 +36,10 @@ public: public: virtual void dump() { } + /** @brief Modifies the current seed with a 64-bit value. + * @param seed the value to modify the current seed + */ + virtual void modifySeed(int64_t seed) = 0; /** @brief Sets the instance to a defined start state. */ virtual void reset() = 0; @@ -82,6 +86,7 @@ class ReSingleSeedRandomizer: public ReRandomizer { public: ReSingleSeedRandomizer(const char* name); public: + virtual void modifySeed(int64_t seed); virtual void reset(); seed_t seed() const; void setSeed(seed_t m_seed); @@ -144,6 +149,7 @@ class ReMultiSeedRandomizer: public ReRandomizer { public: ReMultiSeedRandomizer(int countSeeds, const char* name); public: + virtual void modifySeed(int64_t seed); virtual void reset(); virtual void restoreSeed(const QByteArray& seed); virtual void saveSeed(QByteArray& seed) const; @@ -198,6 +204,7 @@ public: virtual void dump(); virtual seed_t nextSeed(); public: + virtual void modifySeed(int64_t seed); virtual void reset(); virtual void restoreSeed(const QByteArray& seed); virtual void saveSeed(QByteArray& seed) const; diff --git a/base/rebase.hpp b/base/rebase.hpp index cb8e2db..322ccd7 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -86,6 +86,20 @@ inline double min(double a, double b) { return a < b ? a : b; } +/** Returns the integer value of a hex digit. + * @param hex the hex digit + * @param defaultValue the value if hex is out of range + * @return defaultValue: hex is not a hex digit
+ * otherwise: the value of the hex digit, + */ +inline int hexToInt(char hex, int defaultValue = -1){ + return hex > 'f' ? defaultValue + : hex > 'a' ? 10 + hex - 'a' + : hex > 'F' ? defaultValue + : hex >= 'A' ? 10 + hex - 'A' + : hex > '9' ? defaultValue + : hex >= '0' ? hex - '0' : defaultValue; +} /** * Rounds a double value to an integer. * diff --git a/cunit/cuReFileSystem.cpp b/cunit/cuReFileSystem.cpp index 2907293..b9c1884 100644 --- a/cunit/cuReFileSystem.cpp +++ b/cunit/cuReFileSystem.cpp @@ -18,7 +18,7 @@ class TestReFileSystem: public ReTest { public: TestReFileSystem() : - ReTest("ReFileSystem") { + ReTest("ReFileSystem") { doIt(); } private: @@ -33,7 +33,7 @@ protected: for (int ix = 1; ix <= 7; ix++) { node.sprintf("test%d.txt", ix); QByteArray fn = ReFileUtils::tempFile(node.toUtf8().constData(), - "refilesystem", false); + "refilesystem", false); ReFileUtils::writeToFile(fn.constData(), node.toUtf8().constData()); fn = m_subDir1; fn.append("text").append(QByteArray::number(ix)); @@ -53,19 +53,19 @@ protected: } void testReListInfos() { - ReLocalFileSytem fs(m_base, &m_logger); + ReLocalFileSystem fs(m_base, &m_logger); checkEqu(QString(m_base), fs.directory()); checkEqu(QString(m_base), fs.basePath()); ReFileMetaDataList nodes; ReIncludeExcludeMatcher matcher(ReListMatcher::allMatchingList(), - ReQStringUtils::m_emptyList, Qt::CaseInsensitive, false); + ReQStringUtils::m_emptyList, Qt::CaseInsensitive, false); fs.listInfos(matcher, nodes); testContains("dir1", nodes); testContains("test1.txt", nodes); testContains("test7.txt", nodes); } void testReadWrite() { - ReLocalFileSytem fs(m_base, &m_logger); + ReLocalFileSystem fs(m_base, &m_logger); QByteArray buffer; buffer.append("abcdefghijklmnopqrstuvwxyz"); checkEqu(0, fs.write("abc.txt", 0LL, buffer)); @@ -75,7 +75,7 @@ protected: QStringList names; names.append("abc.txt"); ReIncludeExcludeMatcher matcher(names, ReQStringUtils::m_emptyList, - Qt::CaseInsensitive, true); + Qt::CaseInsensitive, true); checkEqu(1, fs.listInfos(matcher, nodes)); checkEqu(1, nodes.size()); checkEqu(0, fs.read(nodes.at(0), 0LL, 3, buffer2)); @@ -86,14 +86,14 @@ protected: checkEqu("klmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", buffer2); } void testSetProperties() { - ReLocalFileSytem fs(m_base, &m_logger); + ReLocalFileSystem fs(m_base, &m_logger); ReFileMetaData meta1; const char* trgNode = "later.txt"; ReFileUtils::tempFile(trgNode, "refilesystem", true); QDateTime modified = QDateTime::fromString("2015.09.12 11:44:55.765", - "yyyy.MM.dd hh:mm:ss.zzz"); + "yyyy.MM.dd hh:mm:ss.zzz"); ReFileMetaData meta2(trgNode, modified, ReFileUtils::m_undefinedTime, - -1, -1, (mode_t) - 1, 1); + -1, -1, (mode_t) - 1, 1); checkT(fs.first("test1.txt", meta1)); checkEqu(0, fs.setProperties(meta2, meta1, true)); ReFileMetaData meta3; @@ -103,7 +103,7 @@ protected: void testSetPropertiesOwner() { #ifdef __linux__ if (geteuid() == 0) { - ReLocalFileSytem fs(m_base, &m_logger); + ReLocalFileSystem fs(m_base, &m_logger); ReFileMetaData meta1; ReFileUtils::tempFile("later2.txt", "refilesystem", true); int rights = S_IRUSR | S_IWGRP | S_IRGRP| S_IROTH | S_IWOTH; @@ -134,11 +134,11 @@ protected: } void testCopy() { - ReLocalFileSytem fsSource(m_base, &m_logger); + ReLocalFileSystem fsSource(m_base, &m_logger); QByteArray base2 = ReFileUtils::tempDir("refilesystem.trg", NULL, - false); + false); ReFileUtils::deleteTree(base2, false, &m_logger); - ReLocalFileSytem fsTarget(base2, &m_logger); + ReLocalFileSystem fsTarget(base2, &m_logger); ReFileMetaData metaSource; checkT(fsSource.first("test3.txt", metaSource)); checkEqu(0, fsTarget.copy(metaSource, fsSource)); @@ -168,9 +168,49 @@ protected: } log("ready"); } + void checkName(const char* name, ReCryptFileSystem& fs){ + QByteArray src(name); + QByteArray trg; + QByteArray trg2; + trg = src; + fs.encodeName(trg); + trg2 = trg; + fs.decodeName(trg2); + checkEqu(src, trg2); + } + + void testNamesEncoding(){ + QByteArray dir = ReFileUtils::tempDir("fs"); + ReLocalFileSystem base(dir, &m_logger); + ReKISSRandomizer nameRandom; + ReKISSRandomizer dataRandom; + ReCryptFileSystem fs(base, nameRandom, dataRandom, &m_logger); + checkName("a.b", fs); + checkName("Ä.txt", fs); + checkName("Ää", fs); + checkName(".git", fs); + } + void checkContent(const char* content, ReCryptFileSystem& fs){ + QByteArray src(content); + QByteArray trg; + QByteArray trg2; + + fs.encodeContent(true, src, trg); + fs.decodeContent(true, src, trg); + } + void testContentEncoding(){ + QByteArray dir = ReFileUtils::tempDir("fs"); + ReLocalFileSystem base(dir, &m_logger); + ReKISSRandomizer nameRandom; + ReKISSRandomizer dataRandom; + ReCryptFileSystem fs(base, nameRandom, dataRandom, &m_logger); + + } virtual void run() { init(); + testContentEncoding(); + testNamesEncoding(); testCharTables(); testReListInfos(); testSetProperties(); diff --git a/os/ReFileSystem.cpp b/os/ReFileSystem.cpp index 9df7bcb..c06fc2b 100644 --- a/os/ReFileSystem.cpp +++ b/os/ReFileSystem.cpp @@ -33,39 +33,40 @@ enum { }; const char ReCryptFileSystem::ESC = '%'; +const int ReCryptFileSystem::NODE_LENGHT = 24; const int ReCryptFileSystem::m_indexOfNodeChar[] = { -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 0, 1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, 10, 11, 12, - -1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, -1, -1, 23, -1, -1, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, }; + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 0, 1, -1, 2, 3, 4, 5, 6, 7, 8, -1, 9, 10, 11, 12, + -1, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, -1, -1, -1, 23, -1, -1, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, -1, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, }; const char ReCryptFileSystem::m_nodeChars[] = { ' ', '!', '#', '$', '%', '&', - '\'', '(', ')', '+', ',', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', '=', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', - 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', - 'z', '{', '|', '}', '~', '\x7f', }; + '\'', '(', ')', '+', ',', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '=', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', + 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + '[', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', + 'z', '{', '|', '}', '~', '\x7f', }; const int ReCryptFileSystem::m_countNodeChars = - sizeof ReCryptFileSystem::m_nodeChars; + sizeof ReCryptFileSystem::m_nodeChars; /** * Constructor. * * @param name the name of the filesystem */ ReFileSystem::ReFileSystem(const QString& name, ReLogger* logger) : - m_name(name), + m_name(name), #ifdef __linux__ - m_uid(geteuid()), - m_gid(getegid()), + m_uid(geteuid()), + m_gid(getegid()), #endif - m_writeable(false), - m_logger(logger), - m_buffer(), - m_blocksize(4 * 1024 * 1024), - m_undefinedTime() { + m_writeable(false), + m_logger(logger), + m_buffer(), + m_blocksize(4 * 1024 * 1024), + m_undefinedTime() { } @@ -84,14 +85,14 @@ ReFileSystem::~ReFileSystem() { * */ ReFileSystem::ErrorCode ReFileSystem::copy(ReFileMetaData& source, - ReFileSystem& sourceFS) { + ReFileSystem& sourceFS) { int blocksize = min(m_blocksize, sourceFS.blocksize()); ErrorCode rc = EC_SUCCESS; ErrorCode rc2; int64_t size = 0; while (rc == EC_SUCCESS && size < source.m_size) { if ((rc2 = sourceFS.read(source, size, blocksize, m_buffer)) - != EC_SUCCESS) + != EC_SUCCESS) rc = rc2; else if ((rc2 = write(source.m_node, size, m_buffer)) != EC_SUCCESS) rc = rc2; @@ -100,7 +101,7 @@ ReFileSystem::ErrorCode ReFileSystem::copy(ReFileMetaData& source, close(); sourceFS.close(); ReFileMetaData target(source.m_node, ReFileUtils::m_undefinedTime, - ReFileUtils::m_undefinedTime, m_uid, m_gid); + ReFileUtils::m_undefinedTime, m_uid, m_gid); setProperties(source, target, false); return rc; } @@ -154,7 +155,7 @@ bool ReFileSystem::first(const QString& pattern, ReFileMetaData& file) { QStringList names; names.append(pattern); ReIncludeExcludeMatcher matcher(names, ReQStringUtils::m_emptyList, - Qt::CaseInsensitive, true); + Qt::CaseInsensitive, true); listInfos(matcher, list); bool rc = list.size() > 0; if (rc) @@ -179,12 +180,12 @@ void ReFileSystem::setBlocksize(int blocksize) { * Linux: Mount point, e.g. "/" or "/media/data" * @param logger */ -ReLocalFileSytem::ReLocalFileSytem(const QString& basePath, ReLogger* logger) : - ReFileSystem("localfs", logger), - m_basePath(basePath), - m_dir(basePath), - m_readFile(NULL), - m_writeFile(NULL) { +ReLocalFileSystem::ReLocalFileSystem(const QString& basePath, ReLogger* logger) : + ReFileSystem("localfs", logger), + m_basePath(basePath), + m_dir(basePath), + m_readFile(NULL), + m_writeFile(NULL) { m_directory = basePath; ReQStringUtils::ensureLastChar(m_directory, OS_SEPARATOR); setWriteable(true); @@ -193,7 +194,7 @@ ReLocalFileSytem::ReLocalFileSytem(const QString& basePath, ReLogger* logger) : /** * Destructor. */ -ReLocalFileSytem::~ReLocalFileSytem() { +ReLocalFileSystem::~ReLocalFileSystem() { } @@ -202,14 +203,14 @@ ReLocalFileSytem::~ReLocalFileSytem() { * * @return the base path */ -const QString& ReLocalFileSytem::basePath() const { +const QString& ReLocalFileSystem::basePath() const { return m_basePath; } /** * Closes the open files. */ -void ReLocalFileSytem::close() { +void ReLocalFileSystem::close() { if (m_readFile != NULL) { fclose(m_readFile); m_readFile = NULL; @@ -226,12 +227,12 @@ void ReLocalFileSytem::close() { * @param matcher the matching processor * @return the count of the found entries (list.size()) */ -int ReLocalFileSytem::listInfos(const ReIncludeExcludeMatcher& matcher, - ReFileMetaDataList& list) { +int ReLocalFileSystem::listInfos(const ReIncludeExcludeMatcher& matcher, + ReFileMetaDataList& list) { list.clear(); const QStringList& patterns = matcher.includes().patterns(); QStringList nodes = - patterns.size() == 0 ? m_dir.entryList() : m_dir.entryList(patterns); + patterns.size() == 0 ? m_dir.entryList() : m_dir.entryList(patterns); QStringList::const_iterator it; QByteArray full = m_directory.toUtf8(); full.append(OS_SEPARATOR); @@ -243,9 +244,9 @@ int ReLocalFileSytem::listInfos(const ReIncludeExcludeMatcher& matcher, full.append(node.toUtf8()); if (stat(full.constData(), &info) == 0) { list.append( - ReFileMetaData(node, QDateTime::fromTime_t(info.st_mtime), - QDateTime::fromTime_t(info.st_ctime), info.st_uid, - info.st_gid, info.st_mode, info.st_size)); + ReFileMetaData(node, QDateTime::fromTime_t(info.st_mtime), + QDateTime::fromTime_t(info.st_ctime), info.st_uid, + info.st_gid, info.st_mode, info.st_size)); } } return list.size(); @@ -258,18 +259,18 @@ int ReLocalFileSytem::listInfos(const ReIncludeExcludeMatcher& matcher, * EC_ALREADY_EXISTS: a file with this name exists
* EC_NOT_ACCESSIBLE: creation failed */ -ReFileSystem::ErrorCode ReLocalFileSytem::makeDir(const QString& node) { +ReFileSystem::ErrorCode ReLocalFileSystem::makeDir(const QString& node) { ErrorCode rc = EC_SUCCESS; if (!m_writeable) { m_logger->log(LOG_ERROR, LOC_MAKE_DIR_1, "filesystem is readonly"); rc = EC_FS_READ_ONLY; } else if (m_dir.exists(node)) { m_logger->logv(LOG_ERROR, LOC_MAKE_DIR_2, "node exists already: %s", - fullNameAsUTF8(node).constData()); + fullNameAsUTF8(node).constData()); rc = EC_ALREADY_EXISTS; } else if (!m_dir.mkdir(node)) { m_logger->logv(LOG_ERROR, LOC_MAKE_DIR_2, "cannot create directory: %s", - fullNameAsUTF8(node).constData()); + fullNameAsUTF8(node).constData()); rc = EC_NOT_ACCESSIBLE; } return rc; @@ -283,7 +284,7 @@ ReFileSystem::ErrorCode ReLocalFileSytem::makeDir(const QString& node) { * EC_PATH_NOT_FOUND directory does not exist
* EC_NOT_ACCESSIBLE parent not readable */ -ReFileSystem::ErrorCode ReLocalFileSytem::setDirectory(const QString& path) { +ReFileSystem::ErrorCode ReLocalFileSystem::setDirectory(const QString& path) { ErrorCode rc = m_dir.setCurrent(path) ? EC_SUCCESS : EC_PATH_NOT_FOUND; m_directory = m_dir.absolutePath(); ReQStringUtils::ensureLastChar(m_directory, OS_SEPARATOR); @@ -301,8 +302,8 @@ ReFileSystem::ErrorCode ReLocalFileSytem::setDirectory(const QString& path) { * EC_NOT_READABLE: file can't be opened
* EC_READ: error while reading */ -ReFileSystem::ErrorCode ReLocalFileSytem::read(const ReFileMetaData& source, - int64_t offset, int size, QByteArray& buffer) { +ReFileSystem::ErrorCode ReLocalFileSystem::read(const ReFileMetaData& source, + int64_t offset, int size, QByteArray& buffer) { ErrorCode rc = EC_SUCCESS; if (offset == 0) { if (m_readFile != NULL) @@ -310,8 +311,8 @@ ReFileSystem::ErrorCode ReLocalFileSytem::read(const ReFileMetaData& source, QString fn = fullName(source.m_node); if ((m_readFile = fopen(fn.toUtf8().constData(), "rb")) == NULL) { m_logger->logv(LOG_ERROR, LOC_READ_1, - "cannot open for reading (%d): %s", errno, - fn.toUtf8().constData()); + "cannot open for reading (%d): %s", errno, + fn.toUtf8().constData()); rc = EC_NOT_READABLE; } } @@ -321,7 +322,7 @@ ReFileSystem::ErrorCode ReLocalFileSytem::read(const ReFileMetaData& source, int nRead = fread(buffer.data(), 1, size, m_readFile); if (nRead < 0) { m_logger->logv(LOG_ERROR, LOC_READ_2, "cannot read (%d): %s", errno, - source.m_node.toUtf8().constData()); + source.m_node.toUtf8().constData()); nRead = 0; rc = EC_READ; } @@ -346,28 +347,28 @@ ReFileSystem::ErrorCode ReLocalFileSytem::read(const ReFileMetaData& source, * EC_NOT_ACCESSIBLE: removing failed * */ -ReFileSystem::ErrorCode ReLocalFileSytem::remove(const ReFileMetaData& node) { +ReFileSystem::ErrorCode ReLocalFileSystem::remove(const ReFileMetaData& node) { ErrorCode rc = EC_SUCCESS; if (!m_writeable) { m_logger->log(LOG_ERROR, LOC_REMOVE_1, "filesystem is readonly"); rc = EC_FS_READ_ONLY; } else if (!m_dir.exists(node.m_node)) { m_logger->logv(LOG_ERROR, LOC_REMOVE_2, "node does not exists: %s", - fullNameAsUTF8(node.m_node).constData()); + fullNameAsUTF8(node.m_node).constData()); rc = EC_NOT_EXISTS; } else { if (S_ISDIR(node.m_mode)) { if (!m_dir.rmdir(node.m_node)) { m_logger->logv(LOG_ERROR, LOC_REMOVE_3, - "cannot remove directory: %s", - fullNameAsUTF8(node.m_node).constData()); + "cannot remove directory: %s", + fullNameAsUTF8(node.m_node).constData()); rc = EC_NOT_ACCESSIBLE; } } else { if (!m_dir.remove(node.m_node)) { m_logger->logv(LOG_ERROR, LOC_REMOVE_3, - "cannot remove file: %s", - fullNameAsUTF8(node.m_node).constData()); + "cannot remove file: %s", + fullNameAsUTF8(node.m_node).constData()); rc = EC_NOT_ACCESSIBLE; } } @@ -388,19 +389,19 @@ ReFileSystem::ErrorCode ReLocalFileSytem::remove(const ReFileMetaData& node) { * EC_RENAME: renaming failed * */ -ReFileSystem::ErrorCode ReLocalFileSytem::setProperties( - const ReFileMetaData& source, ReFileMetaData& target, bool force) { +ReFileSystem::ErrorCode ReLocalFileSystem::setProperties( + const ReFileMetaData& source, ReFileMetaData& target, bool force) { ErrorCode rc = EC_SUCCESS; if (!m_writeable) { m_logger->log(LOG_ERROR, LOC_SET_PROPERTIES_1, - "filesystem is readonly"); + "filesystem is readonly"); rc = EC_FS_READ_ONLY; } else do { QByteArray name; bool nameChanged = target.m_node != source.m_node; bool timeChanged = source.m_modified != target.m_modified - && source.m_modified != ReFileUtils::m_undefinedTime; + && source.m_modified != ReFileUtils::m_undefinedTime; #ifdef __linux__ bool modeChanged = (source.m_mode & ALLPERMS) != (target.m_mode & ALLPERMS) && source.m_mode != (mode_t) -1; @@ -422,16 +423,16 @@ ReFileSystem::ErrorCode ReLocalFileSytem::setProperties( name = fullNameAsUTF8(target.m_node); rc = EC_ALREADY_EXISTS; m_logger->logv(LOG_ERROR, LOC_SET_PROPERTIES_2, - "renaming impossible: node exists: %s", - name.constData()); + "renaming impossible: node exists: %s", + name.constData()); break; } else if (!m_dir.rename(target.m_node, source.m_node)) { rc = EC_RENAME; if (name.length() == 0) name = fullNameAsUTF8(target.m_node); m_logger->logv(LOG_ERROR, LOC_SET_PROPERTIES_3, - "renaming impossible: %s -> %s", - source.m_node.toUtf8().constData(), name.constData()); + "renaming impossible: %s -> %s", + source.m_node.toUtf8().constData(), name.constData()); break; } else { name.resize(0); @@ -442,7 +443,7 @@ ReFileSystem::ErrorCode ReLocalFileSytem::setProperties( if (name.length() == 0) name = fullNameAsUTF8(target.m_node); if (!ReFileUtils::setTimes(name.constData(), source.m_modified, - ReFileUtils::m_undefinedTime, m_logger)) + ReFileUtils::m_undefinedTime, m_logger)) rc = EC_NOT_ACCESSIBLE; } @@ -486,8 +487,8 @@ ReFileSystem::ErrorCode ReLocalFileSytem::setProperties( * EC_WRITE: writing failed * */ -ReFileSystem::ErrorCode ReLocalFileSytem::write(const QString& node, - int64_t offset, const QByteArray& buffer) { +ReFileSystem::ErrorCode ReLocalFileSystem::write(const QString& node, + int64_t offset, const QByteArray& buffer) { ErrorCode rc = EC_SUCCESS; if (!writeable()) { m_logger->log(LOG_ERROR, LOC_WRITE_1, "filesystem is readonly"); @@ -499,8 +500,8 @@ ReFileSystem::ErrorCode ReLocalFileSytem::write(const QString& node, QString fn = fullName(node); if ((m_writeFile = fopen(fn.toUtf8().constData(), "wb")) == NULL) { m_logger->logv(LOG_ERROR, LOC_WRITE_2, - "cannot open for writing (%d): %s", errno, - fn.toUtf8().constData()); + "cannot open for writing (%d): %s", errno, + fn.toUtf8().constData()); rc = EC_NOT_WRITEABLE; } } @@ -509,14 +510,14 @@ ReFileSystem::ErrorCode ReLocalFileSytem::write(const QString& node, if (position != offset) { rc = EC_POSITION; m_logger->logv(LOG_ERROR, LOC_WRITE_4, - "wrong file position: %lld/%lld", offset, position); + "wrong file position: %lld/%lld", offset, position); } else { int nWritten = fwrite(buffer.constData(), 1, buffer.length(), - m_writeFile); + m_writeFile); if (nWritten != buffer.length()) { m_logger->logv(LOG_ERROR, LOC_WRITE_3, - "cannot write (%d): %s written: %d/%d", errno, - node.toUtf8().constData(), nWritten, buffer.length()); + "cannot write (%d): %s written: %d/%d", errno, + node.toUtf8().constData(), nWritten, buffer.length()); rc = EC_WRITE; } fflush(m_writeFile); @@ -530,13 +531,13 @@ ReFileSystem::ErrorCode ReLocalFileSytem::write(const QString& node, * Constructor. */ ReFileMetaData::ReFileMetaData() : - m_node(), - m_modified(), - m_created(), - m_owner(-1), - m_group(-1), - m_mode(-1), - m_size(-1) { + m_node(), + m_modified(), + m_created(), + m_owner(-1), + m_group(-1), + m_mode(-1), + m_size(-1) { } @@ -552,14 +553,14 @@ ReFileMetaData::ReFileMetaData() : * @param size the filesize (0 for directories) */ ReFileMetaData::ReFileMetaData(const QString& node, const QDateTime& modified, - const QDateTime& created, int owner, int group, mode_t mode, int64_t size) : - m_node(node), - m_modified(modified), - m_created(created), - m_owner(owner), - m_group(group), - m_mode(mode), - m_size(size) { + const QDateTime& created, int owner, int group, mode_t mode, int64_t size) : + m_node(node), + m_modified(modified), + m_created(created), + m_owner(owner), + m_group(group), + m_mode(mode), + m_size(size) { } @@ -575,13 +576,13 @@ ReFileMetaData::~ReFileMetaData() { * @param source source to copy */ ReFileMetaData::ReFileMetaData(const ReFileMetaData& source) : - m_node(source.m_node), - m_modified(source.m_modified), - m_created(source.m_created), - m_owner(source.m_owner), - m_group(source.m_group), - m_mode(source.m_mode), - m_size(source.m_size) { + m_node(source.m_node), + m_modified(source.m_modified), + m_created(source.m_created), + m_owner(source.m_owner), + m_group(source.m_group), + m_mode(source.m_mode), + m_size(source.m_size) { } @@ -611,15 +612,15 @@ ReFileMetaData&ReFileMetaData::operator =(const ReFileMetaData& source) { * @param contentRandom a pseudo random generator for content */ ReCryptFileSystem::ReCryptFileSystem(ReFileSystem& hostFileSystem, - ReRandomizer& nameRandom, ReRandomizer& contentRandom, ReLogger* logger) : - ReFileSystem("cryptfs", logger), - m_host(hostFileSystem), - m_contentRandom(contentRandom), - m_nameRandom(nameRandom), - m_realRandom(), - m_contentSeed(), - m_nameSeed(), - m_buffer() { + ReRandomizer& nameRandom, ReRandomizer& contentRandom, ReLogger* logger) : + ReFileSystem("cryptfs", logger), + m_host(hostFileSystem), + m_contentRandom(contentRandom), + m_nameRandom(nameRandom), + m_realRandom(), + m_contentSeed(), + m_nameSeed(), + m_buffer() { m_contentRandom.saveSeed(m_contentSeed); m_nameRandom.saveSeed(m_nameSeed); m_buffer.reserve(256); @@ -646,13 +647,13 @@ QString ReCryptFileSystem::decodeName(const QString& name) { /** * Encodes a block of file content. * + * @param first true: this is the first block of the file * @param source the source block * @param target OUT: the target block
* Can be identical to source (in place replacement) */ -void ReCryptFileSystem::decodeContent(const QByteArray& source, - QByteArray& target) { - +void ReCryptFileSystem::decodeContent(bool first, const QByteArray& source, + QByteArray& target) { } /** @@ -692,7 +693,7 @@ QByteArray& ReCryptFileSystem::encodeName(const QByteArray& node) { int pred = 0; for (int ix = 0; ix < length; ix++) { int ix2 = (m_indexOfNodeChar[*trg] + pred - + m_nameRandom.nextInt(m_countNodeChars - 1)) % m_countNodeChars; + + m_nameRandom.nextInt(m_countNodeChars - 1)) % m_countNodeChars; *trg = m_nodeChars[ix2]; pred = ix2; } @@ -702,32 +703,51 @@ QByteArray& ReCryptFileSystem::encodeName(const QByteArray& node) { /** * Encodes a buffer of file content. * + * @param first true: this is the first block of the file * @param source the source buffer * @param target OUT: the target buffer */ -void ReCryptFileSystem::encodeContent(const QByteArray& source, - QByteArray& target) { - m_contentRandom.reset(); +void ReCryptFileSystem::encodeContent(bool first, const QByteArray& source, + QByteArray& target) { + target.resize(0); + if (first) { + int64_t random = m_realRandom.nextInt64(); + // first block contains the random value and the node name of the file: + target.reserve(source.length() + sizeof(random) + 24); + target.fill(' ', sizeof(random) + 24); + memcpy(target.data(), &random, sizeof random); + } + int64_t* trg = reinterpret_cast(target.data() + target.length()); + target.resize(target.length() + source.length()); int count = source.length() / sizeof(int64_t); - int64_t* target = reinterpret_cast(target.data()); - int64_t last = m_trueRandom.nextInt64(); + const int64_t* src = reinterpret_cast(target.constData()); + int64_t last = 0; + for (int ix = 0; ix < count; ix++) { - last = *target ^= m_contentRandom.nextInt64() ^ last; + last = *trg++ = *src++ ^ m_contentRandom.nextInt64() ^ last; + } + int ixMax = source.length() % sizeof(int64_t); + if (ixMax != 0){ + char* trg2 = reinterpret_cast(trg); + char last2 = (char) last; + const char* src2 = reinterpret_cast(src); + for (int ix = 0; ix <= ixMax; ix++){ + last2 = *trg2++ = *src2++ ^ m_contentRandom.nextChar() ^ last2; + } } - } int ReCryptFileSystem::listInfos(const ReIncludeExcludeMatcher& matcher, - ReFileMetaDataList& list) { + ReFileMetaDataList& list) { } ReFileSystem::ErrorCode ReCryptFileSystem::makeDir(const QString& node) { } ReFileSystem::ErrorCode ReCryptFileSystem::read(const ReFileMetaData& source, - int64_t offset, int size, QByteArray& buffer) { + int64_t offset, int size, QByteArray& buffer) { } ReFileSystem::ErrorCode ReCryptFileSystem::write(const QString& target, - int64_t offset, const QByteArray& buffer) { + int64_t offset, const QByteArray& buffer) { } diff --git a/os/ReFileSystem.hpp b/os/ReFileSystem.hpp index 6f207c0..0988bfa 100644 --- a/os/ReFileSystem.hpp +++ b/os/ReFileSystem.hpp @@ -16,8 +16,8 @@ class ReFileMetaData { public: ReFileMetaData(); ReFileMetaData(const QString& node, const QDateTime& modified, - const QDateTime& created, int owner = -1, int group = -1, - mode_t mode = (mode_t) - 1, int64_t size = 0); + const QDateTime& created, int owner = -1, int group = -1, + mode_t mode = (mode_t) - 1, int64_t size = 0); virtual ~ReFileMetaData(); ReFileMetaData(const ReFileMetaData& source); ReFileMetaData& operator =(const ReFileMetaData& source); @@ -73,7 +73,7 @@ public: * @return the count of the found entries (list.size()) */ virtual int listInfos(const ReIncludeExcludeMatcher& matcher, - ReFileMetaDataList& list) = 0; + ReFileMetaDataList& list) = 0; /** Creates a directory. * @param node the name without path (in the current directory) * @return EC_SUCCESS or error code @@ -87,7 +87,7 @@ public: * @return EC_SUCCESS or error code */ virtual ErrorCode read(const ReFileMetaData& source, int64_t offset, - int size, QByteArray& buffer) = 0; + int size, QByteArray& buffer) = 0; /** Removes a file or directory. * @param node the properties ot the node (in the current directory) * @return EC_SUCCESS or error code @@ -108,7 +108,7 @@ public: * @return EC_SUCCESS or error code */ virtual ErrorCode setProperties(const ReFileMetaData& source, - ReFileMetaData& target, bool force) = 0; + ReFileMetaData& target, bool force) = 0; /** Writes a buffer to a file. * @param node the file to write (without path, inside the current directory) * @param offset first position to write @@ -116,7 +116,7 @@ public: * @return EC_SUCCESS or error code */ virtual ErrorCode write(const QString& target, int64_t offset, - const QByteArray& buffer) = 0; + const QByteArray& buffer) = 0; public: virtual ErrorCode copy(ReFileMetaData& source, ReFileSystem& sourceFS); public: @@ -155,10 +155,10 @@ protected: QDateTime m_undefinedTime; }; -class ReLocalFileSytem: public ReFileSystem { +class ReLocalFileSystem: public ReFileSystem { public: - ReLocalFileSytem(const QString& basePath, ReLogger* logger); - virtual ~ReLocalFileSytem(); + ReLocalFileSystem(const QString& basePath, ReLogger* logger); + virtual ~ReLocalFileSystem(); public: const QString& basePath() const; ErrorCode setDirectory(const QString& path); @@ -167,15 +167,15 @@ public: // ReFileSystem interface virtual void close(); virtual int listInfos(const ReIncludeExcludeMatcher& matcher, - ReFileMetaDataList& list); + ReFileMetaDataList& list); ErrorCode makeDir(const QString& node); virtual ErrorCode read(const ReFileMetaData& source, int64_t offset, - int size, QByteArray& buffer); + int size, QByteArray& buffer); ErrorCode remove(const ReFileMetaData& node); ErrorCode setProperties(const ReFileMetaData& source, - ReFileMetaData& target, bool force = false); + ReFileMetaData& target, bool force = false); virtual ErrorCode write(const QString& target, int64_t offset, - const QByteArray& buffer); + const QByteArray& buffer); protected: QString m_basePath; @@ -196,29 +196,30 @@ protected: class ReCryptFileSystem: ReFileSystem { public: static const char ESC; + static const int NODE_LENGHT; public: ReCryptFileSystem(ReFileSystem& hostFileSystem, ReRandomizer& nameRandom, - ReRandomizer& contentRandom, ReLogger* logger); + ReRandomizer& contentRandom, ReLogger* logger); ~ReCryptFileSystem(); public: QString decodeName(const QString& name); - void decodeContent(const QByteArray& source, QByteArray& target); + void decodeContent(bool first, const QByteArray& source, QByteArray& target); QString encodeName(const QString& name); QByteArray& encodeName(const QByteArray& name); - void encodeContent(const QByteArray& source, QByteArray& target); + void encodeContent(bool first, const QByteArray& source, QByteArray& target); virtual int listInfos(const ReIncludeExcludeMatcher& matcher, - ReFileMetaDataList& list); + ReFileMetaDataList& list); virtual ErrorCode makeDir(const QString& node); virtual ErrorCode read(const ReFileMetaData& source, int64_t offset, - int size, QByteArray& buffer); + int size, QByteArray& buffer); virtual ErrorCode write(const QString& target, int64_t offset, - const QByteArray& buffer); + const QByteArray& buffer); protected: ReFileSystem& m_host; ReRandomizer& m_contentRandom; ReRandomizer& m_nameRandom; - ReKISSRandomizer& m_realRandom; + ReKISSRandomizer m_realRandom; QByteArray m_contentSeed; QByteArray m_nameSeed; QByteArray m_buffer; -- 2.39.5