diff --git a/silentdragon-lite.pro b/silentdragon-lite.pro index da53d6d..56c9e4c 100644 --- a/silentdragon-lite.pro +++ b/silentdragon-lite.pro @@ -79,7 +79,9 @@ SOURCES += \ src/Model/ContactRequestChatItem.cpp \ src/Model/ContactItem.cpp \ src/Chat/Helper/ChatIDGenerator.cpp \ - src/Chat/Chat.cpp + src/Chat/Chat.cpp \ + src/FileSystem/FileSystem.cpp \ + src/Crypto/FileEncryption.cpp HEADERS += \ src/firsttimewizard.h \ diff --git a/src/Crypto/FileEncryption.cpp b/src/Crypto/FileEncryption.cpp new file mode 100644 index 0000000..0100585 --- /dev/null +++ b/src/Crypto/FileEncryption.cpp @@ -0,0 +1,102 @@ +#include "FileEncryption.h" + +void FileEncryption::showConfig() +{ + qInfo() << FILEENCRYPTION_CHUNK_SIZE; +} + +int FileEncryption::encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + unsigned char buf_in[FILEENCRYPTION_CHUNK_SIZE]; + unsigned char buf_out[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + crypto_secretstream_xchacha20poly1305_state st; + FILE *fp_t, *fp_s; + unsigned long long out_len; + size_t rlen; + int eof; + unsigned char tag; + + fp_s = fopen(source_file.toStdString().c_str(), "rb"); + fp_t = fopen(target_file.toStdString().c_str(), "wb"); + crypto_secretstream_xchacha20poly1305_init_push(&st, header, key); + fwrite(header, 1, sizeof header, fp_t); + do + { + rlen = fread(buf_in, 1, sizeof buf_in, fp_s); + eof = feof(fp_s); + tag = eof ? crypto_secretstream_xchacha20poly1305_TAG_FINAL : 0; + crypto_secretstream_xchacha20poly1305_push( + &st, + buf_out, + &out_len, + buf_in, + rlen, + NULL, + 0, + tag + ); + + fwrite(buf_out, 1, (size_t) out_len, fp_t); + } + while (! eof); + + fclose(fp_t); + fclose(fp_s); + return 0; +} + +int FileEncryption::decrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + unsigned char buf_in[FILEENCRYPTION_CHUNK_SIZE + crypto_secretstream_xchacha20poly1305_ABYTES]; + unsigned char buf_out[FILEENCRYPTION_CHUNK_SIZE]; + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + crypto_secretstream_xchacha20poly1305_state st; + FILE *fp_t, *fp_s; + unsigned long long out_len; + size_t rlen; + int eof; + int ret = -1; + unsigned char tag; + + fp_s = fopen(source_file.toStdString().c_str(), "rb"); + fp_t = fopen(target_file.toStdString().c_str(), "wb"); + fread(header, 1, sizeof header, fp_s); + if (crypto_secretstream_xchacha20poly1305_init_pull(&st, header, key) != 0) + { + goto ret; /* incomplete header */ + } + + do + { + rlen = fread(buf_in, 1, sizeof buf_in, fp_s); + eof = feof(fp_s); + if (crypto_secretstream_xchacha20poly1305_pull( + &st, + buf_out, + &out_len, + &tag, + buf_in, + rlen, + NULL, + 0 + ) != 0) + { + goto ret; /* corrupted chunk */ + } + + if (tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL && ! eof) + { + goto ret; /* premature end (end of file reached before the end of the stream) */ + } + + fwrite(buf_out, 1, (size_t) out_len, fp_t); + } + while (! eof); + ret = 0; + +ret: + fclose(fp_t); + fclose(fp_s); + return ret; +} \ No newline at end of file diff --git a/src/Crypto/FileEncryption.h b/src/Crypto/FileEncryption.h new file mode 100644 index 0000000..6db8977 --- /dev/null +++ b/src/Crypto/FileEncryption.h @@ -0,0 +1,18 @@ +#ifndef FILEENCRYPTION_H +#define FILEENCRYPTION_H +#include +#include +#include + +#define FILEENCRYPTION_CHUNK_SIZE 4096 + +class FileEncryption +{ + public: + static void showConfig(); + static int encrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); + static int decrypt(QString target_file, QString source_file, const unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]); +}; + + +#endif \ No newline at end of file diff --git a/src/FileSystem/FileSystem.cpp b/src/FileSystem/FileSystem.cpp new file mode 100644 index 0000000..5ee2fef --- /dev/null +++ b/src/FileSystem/FileSystem.cpp @@ -0,0 +1,82 @@ +#include "FileSystem.h" + +#include +#include + +FileSystem::FileSystem() +{ +} + +FileSystem* FileSystem::getInstance() +{ + if(!FileSystem::instanced) + { + FileSystem::instanced = true; + FileSystem::instance = new FileSystem(); + FileEncryption::showConfig(); + } + + return FileSystem::instance; +} + +QList FileSystem::readContacts(QString file) +{ + QList contacts; + QFile _file(file); + if (_file.exists()) + { + contacts.clear(); + _file.open(QIODevice::ReadOnly); + QDataStream in(&_file); // read the data serialized from the file + QString version; + in >> version; + qDebug() << "Read " << version << " Hush contacts from disk..."; + qDebug() << "Detected old addressbook format"; + QList> stuff; + in >> stuff; + //qDebug() << "Stuff: " << stuff; + for (int i=0; i < stuff.size(); i++) + { + ContactItem contact = ContactItem(stuff[i][0],stuff[i][1], stuff[i][2], stuff[i][3],stuff[i][4]); + contacts.push_back(contact); + } + + _file.close(); + } + else + { + qDebug() << "No Hush contacts found on disk!"; + } + + return contacts; +} + +void FileSystem::writeContacts(QString file, QList contacts) +{ + QFile _file(file); + _file.open(QIODevice::ReadWrite | QIODevice::Truncate); + QDataStream out(&_file); // we will serialize the data into the file + QList> _contacts; + for(auto &item: contacts) + { + QList c; + c.push_back(item.getName()); + c.push_back(item.getPartnerAddress()); + c.push_back(item.getMyAddress()); + c.push_back(item.getCid()); + c.push_back(item.getAvatar()); + _contacts.push_back(c); + } + out << QString("v1") << _contacts; + _file.close(); +} + +FileSystem::~FileSystem() +{ + this->instance = nullptr; + this->instanced = false; + delete this->instance; +} + +FileSystem *FileSystem::instance = nullptr; +bool FileSystem::instanced = false; \ No newline at end of file diff --git a/src/FileSystem/FileSystem.h b/src/FileSystem/FileSystem.h new file mode 100644 index 0000000..995c586 --- /dev/null +++ b/src/FileSystem/FileSystem.h @@ -0,0 +1,24 @@ +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + +#include +#include +#include "../Model/ContactItem.h" +#include "../Crypto/FileEncryption.h" + +class FileSystem +{ + private: + static bool instanced; + static FileSystem* instance; + FileSystem(); + + public: + static FileSystem* getInstance(); + QList readContacts(QString file); + void writeContacts(QString file, QList contacts); + ~FileSystem(); + +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogContext.h b/src/Logger/LogContext.h new file mode 100644 index 0000000..bd8e988 --- /dev/null +++ b/src/Logger/LogContext.h @@ -0,0 +1,11 @@ +#ifndef LOGCONTEXT_H +#define LOGCONTEXT_H + +#include +class LogContext +{ + public: + virtual void log(std::string message) {}; +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogCrtitical.h b/src/Logger/LogCrtitical.h new file mode 100644 index 0000000..cf08849 --- /dev/null +++ b/src/Logger/LogCrtitical.h @@ -0,0 +1,18 @@ +#ifndef LOGCRITICAL_H +#define LOGCRITICAL_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogCritical : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::CRITICAL, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogDebug.h b/src/Logger/LogDebug.h new file mode 100644 index 0000000..e1dd644 --- /dev/null +++ b/src/Logger/LogDebug.h @@ -0,0 +1,18 @@ +#ifndef LOGDEBUG_H +#define LOGDEBUG_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogDebug : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::DEBUG, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogError.h b/src/Logger/LogError.h new file mode 100644 index 0000000..34399c8 --- /dev/null +++ b/src/Logger/LogError.h @@ -0,0 +1,18 @@ +#ifndef LOGERROR_H +#define LOGERROR_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogError : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::ERROR, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogFatal.h b/src/Logger/LogFatal.h new file mode 100644 index 0000000..4b376d3 --- /dev/null +++ b/src/Logger/LogFatal.h @@ -0,0 +1,18 @@ +#ifndef LOGFATAL_H +#define LOGFATAL_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogFatal : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::FATAL, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogInfo.h b/src/Logger/LogInfo.h new file mode 100644 index 0000000..2a876a1 --- /dev/null +++ b/src/Logger/LogInfo.h @@ -0,0 +1,18 @@ +#ifndef LOGINFO_H +#define LOGINFO_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogInfo : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::INFO, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogStrategy.h b/src/Logger/LogStrategy.h new file mode 100644 index 0000000..d619ae0 --- /dev/null +++ b/src/Logger/LogStrategy.h @@ -0,0 +1,11 @@ +#ifndef LOGSTRATEGY_H +#define LOGSTRATEGY_H + +#include +class LogStrategy +{ + public: + virtual void log(std::string message) {}; +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogSuccess.h b/src/Logger/LogSuccess.h new file mode 100644 index 0000000..8dae948 --- /dev/null +++ b/src/Logger/LogSuccess.h @@ -0,0 +1,18 @@ +#ifndef LOGSUCCESS_H +#define LOGSUCCESS_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogSuccess : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::SUCCESS, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogType.h b/src/Logger/LogType.h new file mode 100644 index 0000000..3cb006a --- /dev/null +++ b/src/Logger/LogType.h @@ -0,0 +1,47 @@ +#ifndef LOGTYPE_H +#define LOGTYPE_H + +#include + +class LogType +{ + public: + enum TYPE { + INFO = 0, + DEBUG = 1, + SUCCESS = 2, + WARNING = 3, + ERROR = 4, + FATAL = 5, + CRITICAL = 6 + }; + + static std::string enum2String(int type) + { + switch (type) + { + default: + case 0: + return "INFO"; + + case 1: + return "DEBUG"; + + case 2: + return "SUCCESS"; + + case 3: + return "WARNING"; + + case 4: + return "ERROR"; + + case 5: + return "FATAL"; + + case 6: + return "CRITICAL"; + } + } +}; +#endif \ No newline at end of file diff --git a/src/Logger/LogWarning.h b/src/Logger/LogWarning.h new file mode 100644 index 0000000..58d6222 --- /dev/null +++ b/src/Logger/LogWarning.h @@ -0,0 +1,18 @@ +#ifndef LOGWARNING_H +#define LOGWARNING_H + +#include "LogType.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class LogWarning : public LogStrategy +{ + public: + void log(std::string message) + { + LogWriter* lw = LogWriter::getInstance(); + lw->write(LogType::WARNING, message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/LogWriter.cpp b/src/Logger/LogWriter.cpp new file mode 100644 index 0000000..622de6a --- /dev/null +++ b/src/Logger/LogWriter.cpp @@ -0,0 +1,35 @@ +#include "LogWriter.h" + +LogWriter* LogWriter::getInstance() +{ + if(instance == nullptr) + instance = new LogWriter(); + + return instance; +} + +void LogWriter::setLogFile(std::string file) +{ + this->logfile = file; +} + +void LogWriter::write(LogType::TYPE type, std::string message) +{ + std::ofstream writer(this->logfile, std::ios::out | std::ios::app); + if(writer.good()) + { + time_t now = time(0); + tm *ltm = localtime(&now); + std::stringstream ss; + ss << "[" << LogType::enum2String(type) << "] " << + ltm->tm_mon << "-" << + ltm->tm_mday << "-" << + (1900 + ltm->tm_year) << " " << + ltm->tm_hour << ":" << + ltm->tm_min << ":" << + ltm->tm_sec << " > " << message; + writer << ss.str() << "\n"; + } + + writer.close(); +} \ No newline at end of file diff --git a/src/Logger/LogWriter.h b/src/Logger/LogWriter.h new file mode 100644 index 0000000..f4e9776 --- /dev/null +++ b/src/Logger/LogWriter.h @@ -0,0 +1,22 @@ +#ifndef LOGWRITER_H +#define LOGWRITER_H + +#include +#include +#include +#include +#include "LogType.h" + +class LogWriter +{ + public: + static LogWriter* getInstance(); + std::string logfile = ""; + void setLogFile(std::string file); + void write(LogType::TYPE t, std::string message); + + private: + static LogWriter* instance; +}; + +#endif \ No newline at end of file diff --git a/src/Logger/Logger.h b/src/Logger/Logger.h new file mode 100644 index 0000000..4a307c8 --- /dev/null +++ b/src/Logger/Logger.h @@ -0,0 +1,25 @@ +#ifndef LOGGER_H +#define LOGGER_H + +#include "LogContext.h" +#include "LogStrategy.h" +#include "LogWriter.h" + +class Logger : LogContext +{ + private: + LogStrategy * strategy = nullptr; + + public: + Logger(LogStrategy * strategy) + { + this->strategy = strategy; + } + + void log(std::string message) + { + this->strategy->log(message); + } +}; +LogWriter* LogWriter::instance = nullptr; +#endif \ No newline at end of file diff --git a/src/Logger/SimpleLogger.h b/src/Logger/SimpleLogger.h new file mode 100644 index 0000000..7d18dc3 --- /dev/null +++ b/src/Logger/SimpleLogger.h @@ -0,0 +1,84 @@ +#ifndef SIMPLELOGGER_H +#define SIMPLELOGGER_H + +#include "Logger.h" +#include "LogInfo.h" +#include "LogDebug.h" +#include "LogSuccess.h" +#include "LogWarning.h" +#include "LogError.h" +#include "LogFatal.h" +#include "LogCrtitical.h" +#include "LogWriter.h" + +class SimpleLogger +{ + public: + SimpleLogger() + { + LogWriter::getInstance()->setLogFile("log.txt"); + } + + SimpleLogger(std::string logFile) + { + LogWriter::getInstance()->setLogFile(logFile); + } + + void logInfo(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogInfo(); + logger = new Logger(li); + logger->log(message); + } + + void logDebug(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogDebug(); + logger = new Logger(li); + logger->log(message); + } + + void logSuccess(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogSuccess(); + logger = new Logger(li); + logger->log(message); + } + + void logWarning(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogWarning(); + logger = new Logger(li); + logger->log(message); + } + + void logError(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogError(); + logger = new Logger(li); + logger->log(message); + } + + void logFatal(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogFatal(); + logger = new Logger(li); + logger->log(message); + } + + void logCritical(std::string message) + { + Logger* logger = nullptr; + LogStrategy* li = new LogCritical(); + logger = new Logger(li); + logger->log(message); + } +}; + +#endif \ No newline at end of file diff --git a/src/Logger/test.cpp b/src/Logger/test.cpp new file mode 100644 index 0000000..a717d18 --- /dev/null +++ b/src/Logger/test.cpp @@ -0,0 +1,14 @@ +#include "SimpleLogger.h" + +int main(int argc, char** argv) +{ + SimpleLogger sl = SimpleLogger("/tmp/simplelog.log"); + sl.logInfo("test info"); + sl.logDebug("test debug"); + sl.logSuccess("test success"); + sl.logWarning("test warning"); + sl.logError("test error"); + sl.logFatal("test fatal"); + sl.logCritical("test critical"); + return 0; +} \ No newline at end of file diff --git a/src/addressbook.cpp b/src/addressbook.cpp index 8c4d132..55a3b5e 100644 --- a/src/addressbook.cpp +++ b/src/addressbook.cpp @@ -7,6 +7,7 @@ #include "settings.h" #include "mainwindow.h" #include "controller.h" +#include "FileSystem/FileSystem.h" AddressBookModel::AddressBookModel(QTableView *parent) : QAbstractTableModel(parent) @@ -362,7 +363,7 @@ AddressBook::AddressBook() void AddressBook::readFromStorage() { - QFile file(AddressBook::writeableFile()); + /*QFile file(AddressBook::writeableFile()); if (file.exists()) { @@ -392,15 +393,17 @@ void AddressBook::readFromStorage() file.close(); } }else{ - { - qDebug() << "No Hush contacts found on disk!"; - } -} + { + qDebug() << "No Hush contacts found on disk!"; + } + }*/ + allLabels = FileSystem::getInstance()->readContacts(AddressBook::writeableFile()); } void AddressBook::writeToStorage() { - QFile file(AddressBook::writeableFile()); + FileSystem::getInstance()->writeContacts(AddressBook::writeableFile(), allLabels); + /*QFile file(AddressBook::writeableFile()); file.open(QIODevice::ReadWrite | QIODevice::Truncate); QDataStream out(&file); // we will serialize the data into the file QList> contacts; @@ -415,7 +418,7 @@ void AddressBook::writeToStorage() contacts.push_back(c); } out << QString("v1") << contacts; - file.close(); + file.close();*/ } QString AddressBook::writeableFile() diff --git a/src/addressbook.h b/src/addressbook.h index fee3ac6..8e32fe8 100644 --- a/src/addressbook.h +++ b/src/addressbook.h @@ -3,6 +3,7 @@ #include "precompiled.h" #include "contactmodel.h" +#include "FileSystem/FileSystem.h" class MainWindow;