* Constructor.
*/
ReTreeStatistic::ReTreeStatistic() :
- m_files(0),
- m_directories(0),
- m_fileSizes(0L) {
+ m_files(0),
+ m_directories(0),
+ m_fileSizes(0L) {
}
/**
*/
bool ReFileUtils::deleteTree(const QString& path, bool withBase,
- ReLogger* logger) {
+ ReLogger* logger) {
bool rc = true;
QDir dir(path);
if (dir.exists(path)) {
QFileInfo info;
QStringList names = dir.entryList(
- QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs
- | QDir::Files);
+ QDir::NoDotAndDotDot | QDir::System | QDir::Hidden | QDir::AllDirs
+ | QDir::Files);
QStringList::const_iterator it;
for (it = names.constBegin(); it != names.constEnd(); ++it) {
QString full(path);
rc = false;
if (logger != NULL)
logger->logv(LOG_ERROR, LOC_DELETE_TREE_1,
- "cannot delete directory (%d): %s", errno,
- full.toUtf8().constData());
+ "cannot delete directory (%d): %s", errno,
+ full.toUtf8().constData());
}
} else {
if (!QFile::remove(full)) {
rc = false;
if (logger != NULL)
logger->logv(LOG_ERROR, LOC_DELETE_TREE_2,
- "cannot delete file (%d): %s", errno,
- full.toUtf8().constData());
+ "cannot delete file (%d): %s", errno,
+ full.toUtf8().constData());
}
}
}
if (withBase && (rmdir(path.toUtf8())) != 0) {
rc = false;
logger->logv(LOG_ERROR, LOC_DELETE_TREE_3,
- "cannot delete directory (%d): %s", errno, path.toUtf8());
+ "cannot delete directory (%d): %s", errno, path.toUtf8());
}
return rc;
}
rc = path.startsWith(OS_SEPARATOR);
#else
rc = path.length() > 3 && path.at(1) == ':' && path.at(2) == OS_SEPARATOR
- || path.startsWith("\\\\");
+ || path.startsWith("\\\\");
#endif
return rc;
}
rc = path[0] == OS_SEPARATOR;
#else
rc = isalpha(path[0]) && path[1] == ':' && path[2] == OS_SEPARATOR
- || path[0] == OS_SEPARATOR && path[1] == OS_SEPARATOR;
+ || path[0] == OS_SEPARATOR && path[1] == OS_SEPARATOR;
#endif
return rc;
}
// ignore ".": do nothing
} else if (length == 2 && path[0] == '.' && path[1] == '.') {
// remove the last slash and node
- if (rc.size() > minLength) {
+ if (rc.length() > minLength) {
rc.resize(rc.size() - 1);
int ix = rc.lastIndexOf(OS_SEPARATOR);
if (ix > minLength)
if (path[0] == '.' && path[1] == '\0') {
if (rc.size() == 0)
rc.append('.');
- } else if (path[0] == '.' && path[1] == '.' && path[3] == '\0') {
+ } else if (path[0] == '.' && path[1] == '.' && path[2] == '\0' && rc.length() > 0) {
// remove the last slash and node
if (rc.size() > minLength) {
rc.resize(rc.size() - 1);
* @return <code>buffer</code> (for chaining)
*/
QByteArray& ReFileUtils::readFromFile(const char* filename,
- QByteArray& buffer) {
+ QByteArray& buffer) {
FILE* fp = fopen(filename, "r");
if (fp != NULL) {
struct stat info;
* @return <code>true</code>: success
*/
bool ReFileUtils::setTimes(const char* filename, const QDateTime& modified,
- const QDateTime& accessed, ReLogger* logger) {
+ const QDateTime& accessed, ReLogger* logger) {
bool rc = true;
#if defined __linux__
struct timeval vals[2];
* @return the name of an existing directory
*/
QByteArray ReFileUtils::tempDir(const char* node, const char* parent,
- bool withSeparator) {
+ bool withSeparator) {
#if defined __linux__
QByteArray temp("/tmp");
static const char* firstVar = "TMP";
* @return the name of an existing directory
*/
QByteArray ReFileUtils::tempDirEmpty(const char* node, const char* parent,
- bool withSeparator) {
+ bool withSeparator) {
QByteArray rc = tempDir(node, parent, withSeparator);
deleteTree(rc, false, NULL);
return rc;
* @return the full name of a temporary file
*/
QByteArray ReFileUtils::tempFile(const char* node, const char* parent,
- bool deleteIfExists) {
+ bool deleteIfExists) {
QByteArray rc(tempDir(parent));
if (!rc.endsWith('/'))
rc += '/';
* @param mode file write mode: "w" (write) or "a" (append)
*/
void ReFileUtils::writeToFile(const char* filename, const char* content,
- size_t contentLength, const char* mode) {
+ size_t contentLength, const char* mode) {
FILE* fp = fopen(filename, mode);
if (fp != NULL) {
if (contentLength == (size_t) - 1)
*/
#include "base/rebase.hpp"
+//#define WITH_TRACE
+#include "retrace.hpp"
+enum {
+ LOC_READ_1 = LOC_FIRST_OF(LOC_RANDOMIZER), // 12201
+ LOC_DECODE_CONTENT_1, // 12202
+ LOC_DECODE_CONTENT_2, // 12203
+};
+
+const char ReNameScrambler::ESC = '%';
-static bool s_trace = false;
const int ReRandomizer::m_primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31,
- 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109,
- 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
- 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277,
- 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373,
- 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461,
- 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
- 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653,
- 659, 661, 673, 677, 683, 691 };
+ 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109,
+ 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
+ 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277,
+ 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373,
+ 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
+ 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653,
+ 659, 661, 673, 677, 683, 691 };
const int ReRandomizer::m_countPrimes = sizeof ReRandomizer::m_primes
- / sizeof(int);
+ / sizeof(int);
+const int ReNameScrambler::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, };
+const char ReNameScrambler::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', };
+const int ReNameScrambler::m_countNodeChars =
+ sizeof ReNameScrambler::m_nodeChars;
/**
* @brief Constructor.
* @param name the name of the generator
*/
ReRandomizer::ReRandomizer(const char* name) :
- m_name(name) {
+ m_name(name),
+ m_counter(0){
}
/**
* @brief Destructor.
inline int abs(int x) {
return x < 0 ? -x : x;
}
+inline int64_t abs(int64_t x){
+ return x < 0 ? -x : x;
+}
+
#endif
/**
int textLength = text.length();
for (int ix = maxTrg; ix >= 0; ix--) {
last = trg[ix] = last * text.at(ix % textLength)
- + m_primes[ix % m_countPrimes] * text.at((ix + 1) % textLength);
+ + m_primes[ix % m_countPrimes] * text.at((ix + 1) % textLength);
}
// length password > length seed:
for (int ix = maxTrg; ix < textLength; ix++) {
last = trg[ix % maxTrg] ^= last * text.at(ix)
- + m_primes[ix % m_countPrimes];
+ + m_primes[ix % m_countPrimes];
}
// length password < length seed:
for (int ix = textLength; ix <= maxTrg; ix++) {
last = trg[ix] = last * text.at(ix % textLength)
- + m_primes[ix % m_countPrimes];
+ + m_primes[ix % m_countPrimes];
}
// mix of all seed entries:
for (int ix = 0; ix <= maxTrg; ix++)
void* dummy2 = malloc(1);
free(dummy2);
rc = (((seed_t) random) << 31) + ((seed_t) &dummy << 9)
- + ((-random ^ 0x20111958) ^ (seed_t(dummy2)));
+ + ((-random ^ 0x20111958) ^ (seed_t(dummy2)));
#endif
return rc;
}
* @return The next random character.
*/
char ReRandomizer::nextChar() {
- char rc = nextInt(' ', ' ' + CHARRANGE - 1);
+ char rc = nextInt(' ' + CHARRANGE - 1, ' ');
return rc;
}
minValue = maxValue;
maxValue = rc;
}
- seed_t seed = nextSeed();
+ seed_t seed = nextSeed64();
if (minValue == maxValue)
rc = minValue;
else {
int64_t offset = seed % range;
rc = (int) (minValue + offset);
}
- if (s_trace) {
- static int count = 0;
- printf("%c %8x ", count++ % 4 == 0 ? '\n' : ' ', rc);
- }
return rc;
}
minValue = maxValue;
maxValue = rc;
}
- seed_t seed = nextSeed();
+ seed_t seed = nextSeed64();
if (minValue == maxValue)
rc = minValue;
else if (minValue == 0 && maxValue == LLONG_MAX)
else {
// int64 overflow: we need a higher precision:
double rc2 = (double) minValue
- + fmod((double) seed, (double) (maxValue - minValue));
+ + fmod((double) seed, (double) (maxValue - minValue));
rc = (int) rc2;
}
- if (s_trace) {
- static int count = 0;
- printf("%c %16llx ", count++ % 4 == 0 ? '\n' : ' ', (long long) rc);
- }
return rc;
}
* @result The buffer.
*/
const char* ReRandomizer::nextString(int minLength, int maxLength,
- QByteArray &buffer) {
+ QByteArray &buffer) {
int len = nextInt(maxLength, minLength);
buffer.resize(len);
char* ptr = buffer.data();
* @param name the name of the generator
*/
ReSingleSeedRandomizer::ReSingleSeedRandomizer(const char* name) :
- ReRandomizer(name),
- m_seed(0x1120120419198991ull),
- m_lastSetSeed(0x1120120419198991ull) {
+ ReRandomizer(name),
+ m_seed(0x1120120419198991ull),
+ m_lastSetSeed(0x1120120419198991ull) {
}
/**
*/
void ReSingleSeedRandomizer::reset() {
m_seed = m_lastSetSeed;
+ m_counter = 0;
}
/**
*/
void ReSingleSeedRandomizer::setSeed(seed_t seed) {
m_seed = m_lastSetSeed = seed;
- if (s_trace)
- printf(" Seed: %llx ", (long long) seed);
+ TRACE1("setSeed: %llx\n", (long long) seed);
}
/**
* @brief Constructor.
*/
ReCongruentialGeneratorBase::ReCongruentialGeneratorBase() :
- m_factor(214013),
- m_increment(2531011) {
+ m_factor(214013),
+ m_increment(2531011) {
}
/**
*
* @return The next seed.
*/
-ReRandomizer::seed_t ReCongruentialGenerator::nextSeed() {
+ReRandomizer::seed_t ReCongruentialGenerator::nextSeed64() {
m_seed = m_seed * m_factor + m_increment;
+ ++m_counter;
return m_seed;
}
* @brief Constructor.
*/
ReCongruentialGenerator::ReCongruentialGenerator() :
- ReSingleSeedRandomizer("LCG"),
- ReCongruentialGeneratorBase() {
+ ReSingleSeedRandomizer("LCG"),
+ ReCongruentialGeneratorBase() {
}
/**
* @brief Constructor.
*/
ReCongruentialGenerator::ReCongruentialGenerator(const char* name) :
- ReSingleSeedRandomizer(name),
- ReCongruentialGeneratorBase() {
+ ReSingleSeedRandomizer(name),
+ ReCongruentialGeneratorBase() {
}
/**
* Constructor.
*/
ReRotateRandomizer::ReRotateRandomizer() :
- ReCongruentialGenerator("Rotating LCG") {
+ ReCongruentialGenerator("Rotating LCG") {
}
* @return a pseudo random number
*/
-ReRandomizer::seed_t ReRotateRandomizer::nextSeed() {
- seed_t rc = ReCongruentialGenerator::nextSeed();
+ReRandomizer::seed_t ReRotateRandomizer::nextSeed64() {
+ seed_t rc = ReCongruentialGenerator::nextSeed64();
rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffll);
+ ++m_counter;
return rc;
}
*/
ReMultiSeedRandomizer::ReMultiSeedRandomizer(int countSeeds, const char* name) :
- ReRandomizer(name),
- m_countSeeds(min(256, max(countSeeds, 2))),
- m_seedBuffer(),
- m_startSeed(),
- m_seeds() {
+ ReRandomizer(name),
+ m_countSeeds(min(256, max(countSeeds, 2))),
+ m_seedBuffer(),
+ m_startSeed(),
+ m_seeds() {
m_seedBuffer.resize(m_countSeeds * sizeof m_seeds[0]);
m_seeds = reinterpret_cast<seed_t*>(m_seedBuffer.data());
for (int ix = 0; ix < m_countSeeds; ix++) {
int ixPrimes = ix % m_countPrimes;
m_seeds[ix] = m_primes[ixPrimes] * (2 * ix + 1)
- + (seed_t(m_primes[m_countPrimes - 1 - ixPrimes]) << 32);
+ + (seed_t(m_primes[m_countPrimes - 1 - ixPrimes]) << 32);
}
// assignment does not work: copy on write
m_startSeed.resize(m_seedBuffer.length());
*
* @return a pseudo random number
*/
-ReRandomizer::seed_t ReMultiCongruentialGenerator::nextSeed() {
+ReRandomizer::seed_t ReMultiCongruentialGenerator::nextSeed64() {
m_currentSeed = (m_currentSeed + 1) % m_countSeeds;
seed_t rc = m_seeds[m_currentSeed] * m_factor + m_increment;
m_seeds[m_currentSeed] = rc;
rc = ((rc & 0x7fffffff) << 33) | ((rc >> 31) & 0x1ffffffffLL);
+ ++m_counter;
return rc;
}
void ReMultiSeedRandomizer::reset() {
// assignment does not work: copy on write
memcpy(m_seedBuffer.data(), m_startSeed.constData(), m_seedBuffer.length());
+ m_counter = 0;
}
/**
* @param countSeeds number of seeds
*/
ReMultiCongruentialGenerator::ReMultiCongruentialGenerator(int countSeeds) :
- ReMultiSeedRandomizer(countSeeds, "Multi LCG"),
- ReCongruentialGeneratorBase(),
- m_currentSeed(-1) {
+ ReMultiSeedRandomizer(countSeeds, "Multi LCG"),
+ ReCongruentialGeneratorBase(),
+ m_currentSeed(-1) {
}
/**
void ReMultiCongruentialGenerator::reset() {
ReMultiSeedRandomizer::reset();
m_currentSeed = -1;
+ m_counter = 0;
}
/**
* @return
*/
ReXorShift64Randomizer::ReXorShift64Randomizer() :
- ReSingleSeedRandomizer("ShiftXor64") {
+ ReSingleSeedRandomizer("ShiftXor64") {
}
/**
*
* @return the next pseudo random value
*/
-ReRandomizer::seed_t ReXorShift64Randomizer::nextSeed() {
+ReRandomizer::seed_t ReXorShift64Randomizer::nextSeed64() {
m_seed ^= m_seed << 13;
m_seed ^= m_seed >> 7;
m_seed ^= m_seed << 17;
+ ++m_counter;
return m_seed;
}
* Constructor.
*/
ReKISSRandomizer::ReKISSRandomizer() :
- ReRandomizer("KISS"),
- m_params(),
- m_startParams() {
- m_params.m_x = 1234567890987654321ULL;
- m_params.m_y = 362436362436362436ULL;
- m_params.m_z = 1066149217761810ULL;
- m_params.m_c = 123456123456123456ULL;
+ ReRandomizer("KISS"),
+ m_params(),
+ m_startParams() {
+ m_params.m_x = 0x1234567887654321ULL;
+ m_params.m_y = 0x3624363624363636ULL;
+ m_params.m_z = 0x2011195811081965ULL;
+ m_params.m_c = 0x2004199111121989ULL;
m_startParams = m_params;
}
* Dumps the state of the generator.
*/
void ReKISSRandomizer::dump() {
+ printf("%2d: f: %016llx i: %016llx: c: %016llx x: %016llx y: %016llx z: %016llx\n",
+ m_counter,
+ (long long) m_factor, (long long) m_increment,
+ (long long) m_params.m_c, (long long) m_params.m_x,
+ (long long) m_params.m_y, (long long) m_params.m_z);
printf(
- "f: %016llx i: %016llx: c: %016llx x: %016llx y: %016llx z: %016llx\n",
- m_factor, m_increment, m_params.m_x, m_params.m_x, m_params.m_y,
- m_params.m_z);
- printf(
- "f: %016llx i: %016llx: c: %016llx x: %016llx y: %016llx z: %016llx\n",
- m_factor, m_increment, m_startParams.m_x, m_startParams.m_x,
- m_startParams.m_y, m_startParams.m_z);
+ " f: %016llx i: %016llx: c: %016llx x: %016llx y: %016llx z: %016llx\n",
+ (long long) m_factor, (long long) m_increment,
+ (long long) m_startParams.m_c, (long long) m_startParams.m_x,
+ (long long) m_startParams.m_y, (long long) m_startParams.m_z);
}
/**
* Calculates the next pseudo random value.
* @return
*/
-ReRandomizer::seed_t ReKISSRandomizer::nextSeed() {
-
+ReRandomizer::seed_t ReKISSRandomizer::nextSeed64() {
seed_t t;
// Linear congruence generator
m_params.m_z = m_factor * m_params.m_z + m_increment;
m_params.m_c = (m_params.m_x >> 6);
m_params.m_x += t;
m_params.m_c += (m_params.m_x < t);
-
- return m_params.m_x + m_params.m_y + m_params.m_z;
+ ++m_counter;
+ seed_t rc = m_params.m_x + m_params.m_y + m_params.m_z;
+ TRACE2("%3d: %llx\n", m_counter, (long long) rc);
+ return rc;
}
-
/**
* Modifies the current seed with a 64-bit value.
*
*/
void ReKISSRandomizer::reset() {
m_params = m_startParams;
+ m_counter = 0;
}
/**
restore(seeds, m_params);
m_startParams = m_params;
}
+
+/**
+ * Constructor.
+ *
+ * @param contentRandom a pseudo random generator
+ * @param logger the logger
+ */
+ReByteScrambler::ReByteScrambler(ReRandomizer& contentRandom,
+ int reservedLength, int markerLength, ReLogger* logger) :
+ m_contentRandom(contentRandom),
+ m_realRandom(),
+ m_contentSeed(),
+ m_buffer(),
+ m_header(),
+ m_reservedLength(reservedLength),
+ m_markerLength(max(0, min(sizeof(int64_t), markerLength))),
+ m_headerLength(0),
+ m_logger(logger)
+{
+ m_contentRandom.saveSeed(m_contentSeed);
+ m_buffer.reserve(256);
+ m_realRandom.nearTrueRandom();
+ m_headerLength = sizeof (int64_t) + markerLength + m_reservedLength;
+ m_header.resize(m_headerLength);
+}
+
+/**
+ * Constructor.
+ *
+ * @param nameRandom a pseudo random generator
+ * @param logger the logger
+ */
+ReNameScrambler::ReNameScrambler(ReRandomizer& nameRandom, ReLogger* logger) :
+ m_nameRandom(nameRandom),
+ m_nameSeed(),
+ m_logger(logger)
+{
+ nameRandom.saveSeed(m_nameSeed);
+}
+
+/**
+ * Makes the clear text name from an encoded name.
+ *
+ * @param name the encoded name
+ * @return the clear text name
+ */
+QByteArray& ReNameScrambler::decodeName(const QByteArray& name)
+{
+ //@ToDo
+ m_buffer = name;
+ return m_buffer;
+}
+
+/**
+ * Makes a clear text filename.
+ *
+ * @param name encrypted filename
+ * @return the clear text filename
+ */
+QString ReNameScrambler::decodeName(const QString& name) {
+ QString rc = name;
+ return rc;
+}
+
+/**
+ * Encodes a block of file content.
+ *
+ * @param first <code>true</code>: this is the first block of the file
+ * @param source the source block
+ * @param target OUT: the target block<br>
+ * Can be identical to <code>source</code> (in place replacement)
+ * @return <code>true</code>: successful<br>
+ * <code>false</code>: otherwise
+ */
+bool ReByteScrambler::decodeContent(const QByteArray& source,
+ QByteArray& target) {
+ bool rc = true;
+ int offset = 0;
+ target.resize(0);
+ if (rc){
+ target.resize(source.length() - offset);
+ int64_t* trg = reinterpret_cast<int64_t*>(target.data());
+ int count = (source.length() - offset) / sizeof(int64_t);
+ const int64_t* src = reinterpret_cast<const int64_t*>(source.constData() + offset);
+ int64_t last = ReRandomizer::m_primes[0];
+ for (int ix = 0; ix < count; ix++) {
+ int64_t last2 = last;
+ last = *src++;
+ int64_t rand = m_contentRandom.nextSeed64();
+ *trg++ = last ^ rand ^ last2;
+ TRACE_IT(("ix: %d last: %016lx rand %016lx src: %016lx trg: %016lx\n",
+ ix, last2, rand, src[-1], trg[-1]));
+ }
+ int countTail = (source.length() - offset) % sizeof(int64_t);
+ if (countTail != 0){
+ char* trgTail = reinterpret_cast<char*>(trg);
+ char lastTail = (char) last;
+ const char* srcTail = reinterpret_cast<const char*>(src);
+ for (int ix = 0; ix < countTail; ix++){
+ char last2 = lastTail;
+ lastTail = *srcTail++;
+ char rand = m_contentRandom.nextChar();
+ *trgTail++ = lastTail ^ rand ^ last2;
+ TRACE_IT(("ix: %d last: %02x rand %2x src: %02x trg: %02x\n",
+ ix, (uint8_t) last2, (uint8_t) rand,
+ (uint8_t) srcTail[-1], (uint8_t) trgTail[-1]));
+ }
+ }
+ }
+ return rc;
+}
+
+/**
+ * Encodes a buffer of file content.
+ *
+ * @param source the source buffer
+ * @param target OUT: the target buffer.
+ * May be identical to <code>source</code> (in place processing)
+ */
+void ReByteScrambler::encodeContent(const QByteArray& source,
+ QByteArray& target) {
+ target.resize(source.length());
+ int64_t* trg = reinterpret_cast<int64_t*>(target.data());
+ int count = source.length() / sizeof(int64_t);
+ const int64_t* src = reinterpret_cast<const int64_t*>(source.constData());
+ int64_t last = ReRandomizer::m_primes[0];
+
+ for (int ix = 0; ix < count; ix++) {
+ int64_t rand = m_contentRandom.nextSeed64();
+ IF_TRACE(int64_t last2 = last);
+ last = *trg++ = *src++ ^ rand ^ last;
+ TRACE_IT(("ix: %d last: %016lx rand %016lx src: %016lx trg: %016lx\n",
+ ix, last2, rand, src[-1], trg[-1]));
+ }
+ int countTail = source.length() % sizeof(int64_t);
+ if (countTail != 0){
+ char* trgTail = reinterpret_cast<char*>(trg);
+ char lastTail = (char) last;
+ const char* srcTail = reinterpret_cast<const char*>(src);
+ for (int ix = 0; ix < countTail; ix++){
+ char rand = m_contentRandom.nextChar();
+ IF_TRACE(char last2 = lastTail);
+ lastTail = *trgTail++ = *srcTail++ ^ rand ^ lastTail;
+ TRACE_IT(("ix: %d last: %02x rand %2x src: %02x trg: %02x\n",
+ ix, (uint8_t) last2, (uint8_t) rand,
+ (uint8_t) srcTail[-1], (uint8_t) trgTail[-1]));
+ }
+ }
+}
+
+/**
+ * Initializes the scrambler from a header.
+ *
+ * @param header the header with the initializing info. If NULL the internal
+ * header will be used
+ * @param info OUT: the reserved area in the header
+ * @return <code>true</code>: success
+ */
+bool ReByteScrambler::initFromHeader(const QByteArray* header, QByteArray& info)
+{
+ TRACE("initFromHeader():\n");
+ bool rc = true;
+ if (header == NULL)
+ header = &m_header;
+ if (header->length() < m_headerLength ){
+ m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_1, "header length too small: %d/%d",
+ header->length(), m_headerLength);
+ rc = false;
+ } else {
+ int64_t random = * reinterpret_cast<const int64_t*>(header->constData());
+ m_contentRandom.reset();
+ m_contentRandom.modifySeed(random);
+ QByteArray marker;
+ marker.append(reinterpret_cast<const char*>(header->constData()+ sizeof(int64_t)),
+ m_markerLength);
+ QByteArray marker2;
+ m_contentRandom.nextString(m_markerLength, m_markerLength, marker2);
+ if (marker != marker2){
+ m_logger->logv(LOG_ERROR, LOC_DECODE_CONTENT_2, "invalid marker: %s / %s",
+ ReStringUtils::hexDump(marker, m_markerLength, m_markerLength).constData(),
+ ReStringUtils::hexDump(marker2, m_markerLength, m_markerLength).constData());
+ rc = false;
+ }
+ char last = 0x47;
+ const char* src = reinterpret_cast<const char*>(header->data() + sizeof (int64_t) + m_markerLength);
+ int length = *src++;
+ TRACE1("info: Length: %d\n", length);
+ info.resize(0);
+ for (int ix = 0; ix < length; ix++){
+ char last2 = last;
+ last = *src++;
+ char rand = m_contentRandom.nextChar();
+ info.append(last ^ rand ^ last2);
+ }
+ }
+ IF_TRACE(m_contentRandom.dump());
+ return rc;
+}
+
+/**
+ * Initializes the scrambler header.
+ *
+ * Format of the header:
+ * <pre>random (8 byte)
+ * marker (m_markerLength byte)
+ * reserved (m_reservedLength byte)
+ * </pre>
+ *
+ * @param info the content of the "reserved area"
+ */
+void ReByteScrambler::initHeader(const QByteArray& info)
+{
+ TRACE("initHeader():\n");
+ int64_t random = m_realRandom.nextSeed64();
+ m_contentRandom.reset();
+ m_contentRandom.modifySeed(random);
+ m_header.fill(' ', m_headerLength);
+ * reinterpret_cast<int64_t*>(m_header.data()) = random;
+ if (m_markerLength > 0){
+ m_buffer.resize(0);
+ m_contentRandom.nextString(m_markerLength, m_markerLength, m_buffer);
+ memcpy(m_header.data() + sizeof(int64_t), m_buffer, m_markerLength);
+ }
+ char last = 0x47;
+ char* trg = reinterpret_cast<char*>(m_header.data() + sizeof (int64_t) + m_markerLength);
+ int infoLength = min(info.length(), m_reservedLength - 1);
+ TRACE2("info: length: %d reserved: %d\n", infoLength, m_reservedLength);
+ *trg++ = infoLength;
+ for (int ix = 0; ix < infoLength && ix < m_reservedLength; ix++){
+ last = *trg++ = m_contentRandom.nextChar() ^ info.at(ix) ^ last;
+ }
+ TRACE_IT(("random: %016lx marker: %s\n", random,
+ m_buffer.constData()));
+ IF_TRACE(m_contentRandom.dump());
+}
+/**
+ * Encode a filename.
+ *
+ * Method:
+ * <ul><li>Invert the name without extension (first char becomes the last),
+ * add the extension</li>
+ * <li>Replace the "unconvertable" chars (> 127) into "%xx" ('%' with 2 hexdigits)</li>
+ * <li>exchange the char with a value generated by the pseudo random generator</li>
+ * </ul>
+ * @param name clear text filename
+ * @return the encrypted filename
+ */
+QByteArray& ReNameScrambler::encodeName(const QByteArray& node) {
+ QByteArray rc;
+ int length = node.length();
+ int nameLength = rc.lastIndexOf('.');
+ if (nameLength < 0)
+ nameLength = node.length();
+ const char* src = node.constData();
+ unsigned char cc;
+ int ix2 = nameLength - 1;
+ for (int ix = 0; ix < length; ix++) {
+ cc = (unsigned char) src[ix >= nameLength ? ix : ix2--];
+ if (cc != ESC && cc < 128) {
+ m_buffer.append(cc);
+ } else {
+ m_buffer.append(ESC);
+ char hex[3];
+ snprintf(hex, sizeof hex, "%02x", cc);
+ m_buffer.append(hex, 2);
+ }
+ }
+ m_nameRandom.reset();
+ char* trg = m_buffer.data();
+ int pred = 0;
+ for (int ix = 0; ix < length; ix++) {
+ int ix2 = (m_indexOfNodeChar[(int) *trg] + pred
+ + m_nameRandom.nextInt(m_countNodeChars - 1)) % m_countNodeChars;
+ *trg = m_nodeChars[ix2];
+ pred = ix2;
+ }
+ return m_buffer;
+}
+
+
* @param seed the value to modify the current seed
*/
virtual void modifySeed(int64_t seed) = 0;
+ /** @brief Returns the next pseudo random number.
+ * @return the next pseudo random number
+ * */
+ virtual seed_t nextSeed64() = 0;
/** @brief Sets the instance to a defined start state.
*/
virtual void reset() = 0;
static seed_t hash(const QByteArray& text);
static void hash(const QByteArray& text, QByteArray& seed);
-protected:
- /** @brief Returns the next pseudo random number.
- * @return the next pseudo random number
- * */
- virtual seed_t nextSeed() = 0;
protected:
QByteArray m_name;
+ int m_counter;
public:
// the first 125 prime numbers
static const int m_primes[];
* In this implementation modulus is 2**64.
*/
class ReCongruentialGenerator: public ReSingleSeedRandomizer,
- public ReCongruentialGeneratorBase {
+ public ReCongruentialGeneratorBase {
public:
ReCongruentialGenerator();
protected:
ReCongruentialGenerator(const char* name);
protected:
friend class ReShiftRandom;
- virtual seed_t nextSeed();
+ virtual seed_t nextSeed64();
};
/**
public:
ReRotateRandomizer();
protected:
- virtual seed_t nextSeed();
+ virtual seed_t nextSeed64();
};
/**
* Difference: An array of seeds is used (round robin)</code>.
*/
class ReMultiCongruentialGenerator: public ReMultiSeedRandomizer,
- public ReCongruentialGeneratorBase {
+ public ReCongruentialGeneratorBase {
public:
ReMultiCongruentialGenerator(int countSeeds);
public:
virtual void reset();
- virtual seed_t nextSeed();
+ virtual seed_t nextSeed64();
protected:
int m_currentSeed;
};
public:
ReXorShift64Randomizer();
public:
- virtual seed_t nextSeed();
+ virtual seed_t nextSeed64();
};
/**
ReKISSRandomizer();
public:
virtual void dump();
- virtual seed_t nextSeed();
+ virtual seed_t nextSeed64();
public:
virtual void modifySeed(int64_t seed);
virtual void reset();
params_t m_startParams;
};
+/**
+ * A processing unit for encoding/decoding of binary data.
+ */
+class ReByteScrambler{
+public:
+ ReByteScrambler(ReRandomizer& contentRandom,
+ int reservedLength, int markerLength, ReLogger* logger);
+public:
+ bool decodeContent(const QByteArray& source, QByteArray& target);
+ void encodeContent(const QByteArray& source, QByteArray& target);
+ void initHeader(const QByteArray& info = ReStringUtils::m_empty);
+ bool initFromHeader(const QByteArray* header, QByteArray& info);
+protected:
+ ReRandomizer& m_contentRandom;
+ ReKISSRandomizer m_realRandom;
+ QByteArray m_contentSeed;
+ QByteArray m_buffer;
+ QByteArray m_header;
+ int m_reservedLength;
+ int m_markerLength;
+ int m_headerLength;
+ ReLogger* m_logger;
+};
+
+class ReNameScrambler{
+public:
+ ReNameScrambler(ReRandomizer& nameRandom, ReLogger* logger);
+public:
+ QByteArray& decodeName(const QByteArray& name);
+ QString decodeName(const QString& name);
+ QByteArray& encodeName(const QByteArray& name);
+ QString encodeName(const QString& name);
+protected:
+ ReRandomizer& m_nameRandom;
+ QByteArray m_nameSeed;
+ QByteArray m_buffer;
+ ReLogger* m_logger;
+public:
+ static const char ESC;
+public:
+ static const int m_indexOfNodeChar[];
+ static const char m_nodeChars[];
+ static const int m_countNodeChars;
+};
+
#endif /* RANDOMIZER_H_ */
* This is a class with static members only.
*/
+const QByteArray ReStringUtils::m_empty;
+
/**
* @brief Counts the occurrences of a given char in a string.
*
* the prefix of source with the given length
*/
const QByteArray& ReStringUtils::cutString(const QByteArray& source,
- int maxLength, QByteArray& buffer, const char* appendix) {
+ int maxLength, QByteArray& buffer, const char* appendix) {
QByteArray& rc =
- source.length() <= maxLength ? (QByteArray&) source : buffer;
+ source.length() <= maxLength ? (QByteArray&) source : buffer;
if (source.length() > maxLength) {
buffer = source.left(maxLength);
if (appendix != NULL && appendix[0] != '\0')
const char* path = getenv("PATH");
if (path != NULL) {
s_fileSeparator =
- strchr(path, ';') != NULL || strchr(path, '\\') != NULL ?
- '\\' : '/';
+ strchr(path, ';') != NULL || strchr(path, '\\') != NULL ?
+ '\\' : '/';
} else {
if (getenv("windows") != NULL)
s_fileSeparator = '\\';
* @return an array with the splitted source
*/
QList<QByteArray> ReStringUtils::toArray(const char* source,
- const char* separator) {
+ const char* separator) {
const char* end = source;
QList < QByteArray > rc;
rc.reserve(count(source, separator) + 1);
default: {
char buffer[5];
qsnprintf(buffer, sizeof buffer, "\\x%02x",
- ((unsigned int) cc) % 0xff);
+ ((unsigned int) cc) % 0xff);
rc += buffer;
break;
}
* false: error occurred
*/
bool ReStringUtils::write(const char* file, const char* content,
- const char* mode) {
+ const char* mode) {
FILE* fp = fopen(file, mode);
if (fp != NULL) {
fputs(content, fp);
* @param countBlanks IN/OUT: number of ' '
*/
static void addSeparators(const char* line, int& commas, int& semicolons,
- int& pipes, int& blanks) {
+ int& pipes, int& blanks) {
commas += ReStringUtils::countChar(line, ',');
semicolons += ReStringUtils::countChar(line, ';');
pipes += ReStringUtils::countChar(line, '|');
}
} else {
throw ReException("ReStringUtil::lengthOfInt(): wrong radix: %d",
- radix);
+ radix);
}
if (pValue != NULL)
*pValue = value;
static int countChar(const char* line, char cc);
static int count(const char* source, const char* item);
static const QByteArray& cutString(const QByteArray& source, int maxLength,
- QByteArray& buffer, const char* appendix = "...");
+ QByteArray& buffer, const char* appendix = "...");
static const char* fileSeparator();
static char fileSeparatorChar();
static QByteArray hexDump(uint8_t* data, int length, int bytesPerLine = 16);
static QByteArray hexDump(const void* data, int length, int bytesPerLine =
- 16) {
+ 16) {
return hexDump((uint8_t*) data, length, bytesPerLine);
}
static QByteArray read(const char* file, bool removeLastNewline = true);
static QByteArray replaceNode(const char* source, const char* newNode);
static bool write(const char* file, const char* content = NULL,
- const char* mode = "w");
+ const char* mode = "w");
static QList<QByteArray> toArray(const char* source, const char* separator);
static QByteArray toCString(const char* source, int maxLength = -1);
static QByteArray toNumber(int value, const char* format = "%d");
static int lengthOfNumber(const char* text,
- bool skipTrailingSpaces = false);
+ bool skipTrailingSpaces = false);
static char findCsvSeparator(FILE* fp, char* buffer, size_t bufferSize);
static int lengthOfUInt64(const char* text, int radix, quint64* pValue);
static int lengthOfReal(const char* text, qreal* pValue);
+public:
+ static const QByteArray m_empty;
};
#endif // RPLSTRING_HPP
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#ifndef RETRACEACTIVE_HPP
+#define RETRACEACTIVE_HPP
+
+#ifdef WITH_TRACE
+#define TRACE(format) printf(format);
+#define TRACE1(format, a1) printf(format, a1)
+#define TRACE2(format, a1, a2) printf(format, a1, a2)
+#define TRACE_IT(args) printf args
+#define IF_TRACE(statem) statem
+#else
+#define TRACE(m)
+#define TRACE1(format, a1)
+#define TRACE2(format, a1, a2)
+#define TRACE_IT(args)
+#define IF_TRACE(statem)
+#endif
+
+#endif // RETRACEACTIVE_HPP
+
void testReFile();
void testReFileUtils();
void testReMatcher();
+ testReFileUtils();
testReRandomizer();
testReMatcher();
testReQStringUtil();
testReFile();
- testReFileUtils();
if (s_allTest) {
testReRandomizer();
testReByteStorage();
/** @file
* @brief Unit test of the basic exceptions.
*/
-
class TestReFileSystem: public ReTest {
public:
TestReFileSystem() :
struct stat info;
checkEqu(0, stat(path.toUtf8().constData(), &info));
}
- void testCharTables() {
- for (int ix = 0; ix < ReCryptFileSystem::m_countNodeChars; ix++) {
- char cc = ReCryptFileSystem::m_nodeChars[ix];
- int index = ReCryptFileSystem::m_indexOfNodeChar[(int) cc];
- checkEqu(ix, index);
- }
- for (unsigned char cc = 0; cc < 128; cc++) {
- int index = ReCryptFileSystem::m_indexOfNodeChar[cc];
- if (index >= 0) {
- unsigned char cc2 = ReCryptFileSystem::m_nodeChars[index];
- checkEqu(cc, cc2);
- }
- }
- 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();
testSetPropertiesOwner();
class TestReRandomizer: public ReTest {
public:
TestReRandomizer() :
- ReTest("ReRandomizer") {
+ ReTest("ReRandomizer") {
doIt();
}
fclose(fp);
}
}
+ void checkModifySeed(ReRandomizer& rand){
+ rand.reset();
+ QByteArray s1;
+ rand.nextString(10, 10, s1);
+ rand.reset();
+ rand.modifySeed(22);
+ QByteArray s2;
+ rand.nextString(10, 10, s2);
+ checkF(s1 == s2);
+ rand.reset();
+ rand.modifySeed(22);
+ QByteArray s3;
+ rand.nextString(10, 10, s3);
+ checkEqu(s2, s3);
+ }
- void special() {
+ void testModifySeed(){
+ ReCongruentialGenerator rand;
+ checkModifySeed(rand);
+ ReXorShift64Randomizer rand2;
+ checkModifySeed(rand2);
+ ReMultiCongruentialGenerator rand3(2);
+ checkModifySeed(rand3);
+ ReKISSRandomizer rand4;
+ checkModifySeed(rand4);
+ }
+
+ void testWrite1m() {
ReCongruentialGenerator rand;
write1m(rand);
ReXorShift64Randomizer rand2;
write1m(rand3);
ReKISSRandomizer rand4;
write1m(rand4);
+ }
+
+ void testCharTables() {
+ for (int ix = 0; ix < ReNameScrambler::m_countNodeChars; ix++) {
+ char cc = ReNameScrambler::m_nodeChars[ix];
+ int index = ReNameScrambler::m_indexOfNodeChar[(int) cc];
+ checkEqu(ix, index);
+ }
+ for (unsigned char cc = 0; cc < 128; cc++) {
+ int index = ReNameScrambler::m_indexOfNodeChar[cc];
+ if (index >= 0) {
+ unsigned char cc2 = ReNameScrambler::m_nodeChars[index];
+ checkEqu(cc, cc2);
+ }
+ }
+ log("ready");
+ }
+ void checkName(const char* name, ReNameScrambler& scrambler){
+ QByteArray src(name);
+ QByteArray trg;
+ QByteArray trg2;
+ trg = src;
+ scrambler.encodeName(trg);
+ trg2 = trg;
+ scrambler.decodeName(trg2);
+ checkEqu(src, trg2);
+ }
+
+ void testNamesEncoding(){
+ QByteArray dir = ReFileUtils::tempDir("fs");
+ ReKISSRandomizer nameRandom;
+ ReNameScrambler scrambler(nameRandom, &m_logger);
+ checkName("a.b", scrambler);
+ checkName("Ä.txt", scrambler);
+ checkName("Ää", scrambler);
+ checkName(".git", scrambler);
+ }
+ void checkContent(const char* content, ReByteScrambler& scrambler){
+ QByteArray src(content);
+ QByteArray trg;
+ QByteArray trg2;
+ ReKISSRandomizer rand;
+ rand.nearTrueRandom();
+ QByteArray info;
+ rand.nextString(10, 20, info);
+ scrambler.initHeader(info);
+ scrambler.encodeContent(src, trg);
+ QByteArray info2;
+ scrambler.initFromHeader(NULL, info2);
+ scrambler.decodeContent(trg, trg2);
+ checkEqu(src, trg2);
+ checkT(info.startsWith(info2));
+ }
+ void testContentEncoding(){
+ ReKISSRandomizer dataRandom;
+ ReByteScrambler scrambler(dataRandom, 8, 4, &m_logger);
+ checkContent("12345678abc", scrambler);
+ checkContent("8765432112345678ab", scrambler);
+ checkContent("8765432112345678", scrambler);
+ checkContent("", scrambler);
+ ReXorShift64Randomizer rand;
+ QByteArray src;
+ for (int ix = 0; ix < 1000; ix++){
+ rand.nextString(10, 50, src);
+ checkContent(src, scrambler);
+ }
+ for (int ix = 0; ix < 1000; ix++){
+ src.resize(0);
+ for (int ix2 = 0; ix2 < 50; ix2++){
+ int64_t nRand = rand.nextInt64();
+ src.append((const char*) &nRand, sizeof nRand);
+ }
+ checkContent(src, scrambler);
+ }
+ }
+ void special(){
+ ReKISSRandomizer rand;
+ rand.dump();
+ rand.nextSeed64();
+ rand.dump();
log("ready");
}
virtual void run(void) {
special();
+ testContentEncoding();
+ testNamesEncoding();
+ testCharTables();
+ testModifySeed();
testTextToSeed();
+ testWrite1m();
testBasics();
- int ix = 1;
}
};
void testReRandomizer() {
LOC_SET_PROPERTIES_5, // 12017
};
-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, };
-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', };
-const int ReCryptFileSystem::m_countNodeChars =
- sizeof ReCryptFileSystem::m_nodeChars;
+const int ReCryptFileSystem::NODE_LENGHT = 44;
+const int ReCryptFileSystem::MARKER_LENGHT = 4;
+const int ReCryptFileSystem::CHECKSUM_LENGHT = 16;
+const int ReCryptFileSystem::HEADER_LENGTH = sizeof(int64_t)
+ + ReCryptFileSystem::NODE_LENGHT
+ + ReCryptFileSystem::MARKER_LENGHT;
+
+#ifdef WITH_TRACE
+static bool s_trace = true;
+#endif
+
/**
* Constructor.
*
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() {
- m_contentRandom.saveSeed(m_contentSeed);
- m_nameRandom.saveSeed(m_nameSeed);
- m_buffer.reserve(256);
- m_realRandom.nearTrueRandom();
+ ReByteScrambler(contentRandom, NODE_LENGHT, sizeof(int32_t), logger),
+ m_host(hostFileSystem) {
}
/**
ReCryptFileSystem::~ReCryptFileSystem() {
}
-/**
- * Makes a clear text filename.
- *
- * @param name encrypted filename
- * @return the clear text filename
+/** Frees resources like open files.
*/
-QString ReCryptFileSystem::decodeName(const QString& name) {
- QString rc = name;
- return rc;
+void ReCryptFileSystem::close()
+{
}
/**
- * Encodes a block of file content.
+ * Fills a list with the items of the current directory.
*
- * @param first <code>true</code>: this is the first block of the file
- * @param source the source block
- * @param target OUT: the target block<br>
- * Can be identical to <code>source</code> (in place replacement)
+ * @param matcher the matching processor
+ * @return the count of the found entries (<code>list.size()</code>)
*/
-void ReCryptFileSystem::decodeContent(bool first, const QByteArray& source,
- QByteArray& target) {
+int ReCryptFileSystem::listInfos(const ReIncludeExcludeMatcher& matcher,
+ ReFileMetaDataList& list) {
+ return 0;
}
/**
- * Encode a filename.
+ * Creates a directory.
*
- * Method:
- * <ul><li>Invert the name without extension (first char becomes the last),
- * add the extension</li>
- * <li>Replace the "unconvertable" chars (> 127) into "%xx" ('%' with 2 hexdigits)</li>
- * <li>exchange the char with a value generated by the pseudo random generator</li>
- * </ul>
- * @param name clear text filename
- * @return the encrypted filename
- */
-QByteArray& ReCryptFileSystem::encodeName(const QByteArray& node) {
- QByteArray rc;
- int length = node.length();
- int nameLength = rc.lastIndexOf('.');
- if (nameLength < 0)
- nameLength = node.length();
- const char* src = node.constData();
- unsigned char cc;
- int ix2 = nameLength - 1;
- for (int ix = 0; ix < length; ix++) {
- cc = (unsigned char) src[ix >= nameLength ? ix : ix2--];
- if (cc != ESC && cc < 128) {
- m_buffer.append(cc);
- } else {
- m_buffer.append(ESC);
- char hex[3];
- snprintf(hex, sizeof hex, "%02x", cc);
- m_buffer.append(hex, 2);
- }
- }
- m_nameRandom.reset();
- char* trg = m_buffer.data();
- int pred = 0;
- for (int ix = 0; ix < length; ix++) {
- int ix2 = (m_indexOfNodeChar[*trg] + pred
- + m_nameRandom.nextInt(m_countNodeChars - 1)) % m_countNodeChars;
- *trg = m_nodeChars[ix2];
- pred = ix2;
- }
- return m_buffer;
+ * @param node the name without path (in the current directory)
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::makeDir(const QString& node) {
+ return EC_SUCCESS;
}
/**
- * Encodes a buffer of file content.
+ * Reads a part of a file into a buffer.
*
- * @param first <code>true</code>: this is the first block of the file
- * @param source the source buffer
- * @param target OUT: the target buffer
- */
-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<int64_t*>(target.data() + target.length());
- target.resize(target.length() + source.length());
- int count = source.length() / sizeof(int64_t);
- const int64_t* src = reinterpret_cast<const int64_t*>(target.constData());
- int64_t last = 0;
-
- for (int ix = 0; ix < count; ix++) {
- last = *trg++ = *src++ ^ m_contentRandom.nextInt64() ^ last;
- }
- int ixMax = source.length() % sizeof(int64_t);
- if (ixMax != 0){
- char* trg2 = reinterpret_cast<char*>(trg);
- char last2 = (char) last;
- const char* src2 = reinterpret_cast<const char*>(src);
- for (int ix = 0; ix <= ixMax; ix++){
- last2 = *trg2++ = *src2++ ^ m_contentRandom.nextChar() ^ last2;
- }
- }
+ * @param source the file to read (inside the current directory)
+ * @param offset first position to read
+ * @param size number of bytes to read
+ * @param buffer OUT: content of the file
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::read(const ReFileMetaData& source,
+ int64_t offset, int size, QByteArray& buffer) {
+ return EC_SUCCESS;
}
-int ReCryptFileSystem::listInfos(const ReIncludeExcludeMatcher& matcher,
- ReFileMetaDataList& list) {
+/** Removes a file or directory.
+ * @param node the properties ot the node (in the current directory)
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::remove(const ReFileMetaData& node)
+{
+ return EC_SUCCESS;
}
-ReFileSystem::ErrorCode ReCryptFileSystem::makeDir(const QString& node) {
+/**
+ * Sets the current directory.
+ *
+ * @param path relative or absolute path. If absolute it must be part of the
+ * base path
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::setDirectory(const QString& path)
+{
+ return EC_SUCCESS;
}
-ReFileSystem::ErrorCode ReCryptFileSystem::read(const ReFileMetaData& source,
- int64_t offset, int size, QByteArray& buffer) {
+/**
+ * Sets the properties of a file in the current directory.
+ *
+ * @param source the properties to copy
+ * @param target the properties of the file to change
+ * @param force <code>true</code>: try to change rights to enable
+ * other changes<br>
+ * <code>false</code>: current rights will be respected
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReCryptFileSystem::setProperties(const ReFileMetaData& source,
+ ReFileMetaData& target, bool force)
+{
+ return EC_SUCCESS;
}
+/**
+ * Writes a buffer to a file.
+ *
+ * @param node the file to write (without path, inside the current directory)
+ * @param offset first position to write
+ * @param buffer content to write
+ * @return EC_SUCCESS or error code
+ */
ReFileSystem::ErrorCode ReCryptFileSystem::write(const QString& target,
int64_t offset, const QByteArray& buffer) {
+ return EC_SUCCESS;
}
+
EC_ALREADY_EXISTS,
EC_NOT_EXISTS,
EC_RENAME,
+ EC_HEADER_LENGTH,
+ EC_MARKER,
};
public:
* If a file content is copied / moved to the base filesystem the content
* will be encrypted. In the other direction the file content will be decrypted.
*/
-class ReCryptFileSystem: ReFileSystem {
+class ReCryptFileSystem: public ReFileSystem, protected ReByteScrambler {
public:
- static const char ESC;
static const int NODE_LENGHT;
+ static const int HEADER_LENGTH;
+ static const int CHECKSUM_LENGHT;
+ static const int MARKER_LENGHT;
public:
ReCryptFileSystem(ReFileSystem& hostFileSystem, ReRandomizer& nameRandom,
ReRandomizer& contentRandom, ReLogger* logger);
~ReCryptFileSystem();
public:
- QString decodeName(const QString& name);
- void decodeContent(bool first, const QByteArray& source, QByteArray& target);
- QString encodeName(const QString& name);
- QByteArray& encodeName(const QByteArray& name);
- void encodeContent(bool first, const QByteArray& source, QByteArray& target);
+public:
+ virtual void close();
virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
ReFileMetaDataList& list);
virtual ErrorCode makeDir(const QString& node);
virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
int size, QByteArray& buffer);
+ virtual ErrorCode remove(const ReFileMetaData& node);
+ virtual ErrorCode setDirectory(const QString& path);
+ virtual ErrorCode setProperties(const ReFileMetaData& source, ReFileMetaData& target, bool force);
virtual ErrorCode write(const QString& target, int64_t offset,
const QByteArray& buffer);
-
protected:
ReFileSystem& m_host;
- ReRandomizer& m_contentRandom;
- ReRandomizer& m_nameRandom;
- ReKISSRandomizer m_realRandom;
- QByteArray m_contentSeed;
- QByteArray m_nameSeed;
- QByteArray m_buffer;
-public:
- static const int m_indexOfNodeChar[];
- static const char m_nodeChars[];
- static const int m_countNodeChars;
};
#endif /* OS_REFILESYSTEM_HPP_ */
LOC_FILETREE,
LOC_STATESTORAGE, // 120
LOC_FILESYSTEM,
+ LOC_RANDOMIZER,
};
#define LOC_FIRST_OF(moduleNo) (moduleNo*100+1)
class RplModules {