From d3b9352d517493f9cc143c7ac4b870f1b4633400 Mon Sep 17 00:00:00 2001 From: Dario Date: Sat, 28 Sep 2019 13:33:30 +0200 Subject: [PATCH] created crypto key in separate thread --- src/cpp/Crypto/Obfus_array.cpp | 2 +- src/cpp/MySQL/MysqlTable.h | 7 +++++ src/cpp/model/Session.cpp | 13 ++++++++-- src/cpp/model/User.cpp | 40 +++++++++++++++++------------ src/cpp/model/User.h | 38 ++++++++++++++++++++++++--- src/cpp/tasks/CPUShedulerThread.cpp | 4 ++- src/cpp/tasks/CPUTask.h | 2 +- src/cpp/tasks/Task.cpp | 8 ++---- src/cpp/tasks/Task.h | 7 ++++- src/cpp/tasks/Thread.cpp | 15 +++++------ src/cpp/tasks/WriteIntoDBTask.cpp | 15 ++++++----- src/cpp/tasks/WriteIntoDBTask.h | 10 ++++---- 12 files changed, 111 insertions(+), 50 deletions(-) diff --git a/src/cpp/Crypto/Obfus_array.cpp b/src/cpp/Crypto/Obfus_array.cpp index 36d3a9d95..8b5c0f7a0 100644 --- a/src/cpp/Crypto/Obfus_array.cpp +++ b/src/cpp/Crypto/Obfus_array.cpp @@ -6,7 +6,7 @@ ObfusArray::ObfusArray(size_t size, const unsigned char * data) : m_arraySize(0), m_offsetSize(0), m_dataSize(size), m_Data(nullptr) { - m_arraySize = size + randombytes_random() % (int)roundf(size*0.25f); + m_arraySize = size + 2 + randombytes_random() % (int)roundf(size*0.25f); m_Data = (unsigned char*)malloc(m_arraySize); m_offsetSize = randombytes_random() % (int)roundf((m_arraySize - m_dataSize) * 0.8f); diff --git a/src/cpp/MySQL/MysqlTable.h b/src/cpp/MySQL/MysqlTable.h index 113a1603f..5f0af54c6 100644 --- a/src/cpp/MySQL/MysqlTable.h +++ b/src/cpp/MySQL/MysqlTable.h @@ -160,6 +160,13 @@ public: addError(new ParamError(__FUNCTION__, "invalid field index:", index)); return MYSQL_ROW_TYPE_NONE; } + inline const char* getHeaderName(int index) { + if (index > 0 && index < mFieldCount) { + return mHeader[index].name.data(); + } + addError(new ParamError(__FUNCTION__, "invalid field index:", index)); + return nullptr; + } inline bool addCellToCurrentRow(long value) { return addCellToCurrentRow(new MysqlTableCellInt(value)); } inline bool addCellToCurrentRow(const long long& value) { return addCellToCurrentRow(new MysqlTableCellLong(value)); } inline bool addCellToCurrentRow(const char* string) { return addCellToCurrentRow(new MysqlTableCellString(string)); } diff --git a/src/cpp/model/Session.cpp b/src/cpp/model/Session.cpp index bc057a2d0..be7728694 100644 --- a/src/cpp/model/Session.cpp +++ b/src/cpp/model/Session.cpp @@ -6,7 +6,7 @@ #include "sodium.h" Session::Session(int handle) - : mHandleId(handle) + : mHandleId(handle), mSessionUser(nullptr) { } @@ -60,9 +60,18 @@ bool Session::createUser(const std::string& name, const std::string& email, cons //mPassphrase = passphrase; }*/ - //mSessionUser = new User(email.data(), name.data(), password.data(), passphrase.size() ? passphrase.data() : mPassphrase.data()); + mSessionUser = new User(email.data(), name.data()); updateTimeout(); + // create user crypto key + UniLib::controller::TaskPtr cryptoKeyTask(new UserCreateCryptoKey(mSessionUser, password, ServerConfig::g_CPUScheduler)); + //cryptoKeyTask->scheduleTask(cryptoKeyTask); + + // depends on crypto key + UniLib::controller::TaskPtr writeUserIntoDB(new UserWriteIntoDB(mSessionUser, ServerConfig::g_CPUScheduler, 1)); + writeUserIntoDB->setParentTaskPtrInArray(cryptoKeyTask, 0); + writeUserIntoDB->scheduleTask(writeUserIntoDB); + // write user into db // generate and write email verification into db // send email diff --git a/src/cpp/model/User.cpp b/src/cpp/model/User.cpp index 0b32cf1ad..a604f5a49 100644 --- a/src/cpp/model/User.cpp +++ b/src/cpp/model/User.cpp @@ -20,7 +20,7 @@ void NewUser::run() { // create crypto key if (!mUser->hasCryptoKey()) { - mUser->createCryptoKey(mUser->getEmail(), mPassword.data()); + mUser->createCryptoKey(mPassword.data()); } // generate @@ -45,20 +45,30 @@ void LoginUser::run() } -// ******************************************************************************* +// ------------------------------------------------------------------------------------------------- -User::User(const char* email, const char* name, const char* password) - : mEmail(email), mFirstName(name), mCryptoKey(nullptr) +int UserCreateCryptoKey::run() { - //crypto_shorthash_KEYBYTES - //mPasswordHashed = - crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); + mUser->createCryptoKey(mPassword); + printf("crypto key created\n"); + return 0; } -User::User(const char* email, const char* password) - : mEmail(email) +// ----------------------------------------------------------------------------------------------------- + +int UserWriteIntoDB::run() { - crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); + return 0; +} + +// ******************************************************************************* + + +User::User(const char* email, const char* name) + : mEmail(email), mFirstName(name), mCryptoKey(nullptr) +{ + //crypto_shorthash(mPasswordHashed, (const unsigned char*)password, strlen(password), *ServerConfig::g_ServerCryptoKey); + memset(mPasswordHashed, 0, crypto_shorthash_BYTES); } @@ -97,14 +107,12 @@ std::string User::generateNewPassphrase(Mnemonic* word_source) return phrase_buffer; } -void User::createCryptoKey(const char* username, const char* password) +void User::createCryptoKey(const std::string& password) { // TODO: put it in secure location static const unsigned char app_secret[] = { 0x21, 0xff, 0xbb, 0xc6, 0x16, 0xfe }; - size_t username_size = strlen(username); - size_t password_size = strlen(password); sha_context context_sha512; //unsigned char* hash512 = (unsigned char*)malloc(SHA_512_SIZE); if (SHA_512_SIZE < crypto_pwhash_SALTBYTES) { @@ -113,21 +121,21 @@ void User::createCryptoKey(const char* username, const char* password) } - unsigned char hash512_salt[SHA_512_SIZE]; // need at least crypto_pwhash_SALTBYTES 16U sha512_init(&context_sha512); - sha512_update(&context_sha512, (const unsigned char*)username, username_size); + sha512_update(&context_sha512, (const unsigned char*)mEmail.data(), mEmail.size()); sha512_update(&context_sha512, app_secret, 6); sha512_final(&context_sha512, hash512_salt); unsigned char* key = (unsigned char *)malloc(crypto_box_SEEDBYTES); // 32U - if (crypto_pwhash(key, crypto_box_SEEDBYTES, password, password_size, hash512_salt, 2U, 8388608, 2) != 0) { + if (crypto_pwhash(key, crypto_box_SEEDBYTES, password.data(), password.size(), hash512_salt, 10U, 33554432, 2) != 0) { addError(new ParamError(__FUNCTION__, " error creating pwd hash, maybe to much memory requestet? error:", strerror(errno))); //printf("[User::%s] error creating pwd hash, maybe to much memory requestet? error: %s\n", __FUNCTION__, strerror(errno)); //printf("pwd: %s\n", pwd); return ; } + crypto_shorthash(mPasswordHashed, key, crypto_box_SEEDBYTES, *ServerConfig::g_ServerCryptoKey); lock(); mCryptoKey = new ObfusArray(crypto_box_SEEDBYTES, key); unlock(); diff --git a/src/cpp/model/User.h b/src/cpp/model/User.h index 4216dd0f4..f3b1d1c2c 100644 --- a/src/cpp/model/User.h +++ b/src/cpp/model/User.h @@ -5,17 +5,20 @@ #include #include "ErrorList.h" #include "Poco/Thread.h" +#include "../tasks/CPUTask.h" class NewUser; +class UserCreateCryptoKey; class User : public ErrorList { friend NewUser; + friend UserCreateCryptoKey; public: // new user - User(const char* email, const char* name, const char* password); + //User(const char* email, const char* name, const char* password); // existing user - User(const char* email, const char* password); + User(const char* email, const char* name); ~User(); @@ -24,9 +27,11 @@ public: inline bool hasCryptoKey() { lock(); bool bRet = mCryptoKey != nullptr; unlock(); return bRet; } inline const char* getEmail() { return mEmail.data(); } inline const char* getName() { return mFirstName.data(); } + + protected: - void createCryptoKey(const char* email, const char* password); + void createCryptoKey(const std::string& password); inline void lock() { mWorkingMutex.lock(); } inline void unlock() { mWorkingMutex.unlock(); } @@ -42,6 +47,33 @@ private: }; +class UserCreateCryptoKey : public UniLib::controller::CPUTask +{ +public: + UserCreateCryptoKey(User* user, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler) + : UniLib::controller::CPUTask(cpuScheduler), mUser(user), mPassword(password) {} + + virtual int run(); + virtual const char* getResourceType() const { return "UserCreateCryptoKey"; }; + +private: + User* mUser; + std::string mPassword; +}; + +class UserWriteIntoDB : public UniLib::controller::CPUTask +{ +public: + UserWriteIntoDB(User* user, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0) + : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user) {} + + virtual int run(); + virtual const char* getResourceType() const { return "UserWriteIntoDB"; }; +private: + User* mUser; +}; + + class NewUser : public Poco::Runnable { public: diff --git a/src/cpp/tasks/CPUShedulerThread.cpp b/src/cpp/tasks/CPUShedulerThread.cpp index 9f11c3ade..44ebeed42 100644 --- a/src/cpp/tasks/CPUShedulerThread.cpp +++ b/src/cpp/tasks/CPUShedulerThread.cpp @@ -35,7 +35,9 @@ namespace UniLib { const char* name = mWaitingTask->getName(); l->addTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder(), mWaitingTask->getResourceType(), mName.data(), name); #endif - mWaitingTask->run(); + if (!mWaitingTask->run()) { + mWaitingTask->setTaskFinished(); + } #ifdef _UNI_LIB_DEBUG l->removeTaskLogEntry((HASH)mWaitingTask.getResourcePtrHolder()); SpeedLog.writeToLog("%s used on thread: %s by Task: %s of: %s", diff --git a/src/cpp/tasks/CPUTask.h b/src/cpp/tasks/CPUTask.h index d8762703c..b643767e5 100644 --- a/src/cpp/tasks/CPUTask.h +++ b/src/cpp/tasks/CPUTask.h @@ -55,7 +55,7 @@ namespace UniLib { virtual const char* getResourceType() const {return "CPUTask";}; //! \brief return true if task has finished, else false //! automatic scheduling of task if he isn't finished and sheduled yet - virtual bool isTaskFinished() { return true; } + virtual void scheduleTask(TaskPtr own); protected: diff --git a/src/cpp/tasks/Task.cpp b/src/cpp/tasks/Task.cpp index 8daf26ef8..925a9bb67 100644 --- a/src/cpp/tasks/Task.cpp +++ b/src/cpp/tasks/Task.cpp @@ -5,7 +5,7 @@ namespace UniLib { namespace controller { Task::Task() : mTaskScheduled(false), mFinishCommand(nullptr), mParentTaskPtrArray(nullptr), - mParentTaskPtrArraySize(0), mDeleted(false), mReferenceCount(1) + mParentTaskPtrArraySize(0), mDeleted(false), mFinished(false), mReferenceCount(1) { } @@ -32,11 +32,7 @@ namespace UniLib { lock(); for(size_t i = 0; i < mParentTaskPtrArraySize; i++) { TaskPtr task = mParentTaskPtrArray[i]; - if (!task.isNull()) { - allFinished = false; - continue; - } - if(!task->isTaskFinished()) { + if (!task.isNull() && !task->isTaskFinished()) { allFinished = false; if(!task->isTaskSheduled()) mParentTaskPtrArray[i]->scheduleTask(mParentTaskPtrArray[i]); diff --git a/src/cpp/tasks/Task.h b/src/cpp/tasks/Task.h index 98dc0d6f2..1c45a98f2 100644 --- a/src/cpp/tasks/Task.h +++ b/src/cpp/tasks/Task.h @@ -65,8 +65,9 @@ namespace UniLib { bool isAllParentsReady(); //! \brief return true if task has finished, else false //! automatic scheduling of task if he isn't finished and sheduled yet - virtual bool isTaskFinished() { return false; } + virtual bool isTaskFinished() { lock(); bool ret = mFinished; unlock(); return ret; } //! \brief called from task scheduler, maybe from another thread + //! \return if return 0, mark task as finished virtual int run() = 0; @@ -102,11 +103,14 @@ namespace UniLib { // for poco auto ptr void duplicate(); void release(); + + inline void setTaskFinished() { lock(); mFinished = true; unlock(); } protected: // scheduling only once inline bool isTaskSheduled() {return mTaskScheduled;} inline void taskScheduled() {mTaskScheduled = true;} + bool mTaskScheduled; Command* mFinishCommand; private: @@ -114,6 +118,7 @@ namespace UniLib { size_t mParentTaskPtrArraySize; Poco::Mutex mWorkingMutex; bool mDeleted; + bool mFinished; // for poco auto ptr int mReferenceCount; #ifdef _UNI_LIB_DEBUG diff --git a/src/cpp/tasks/Thread.cpp b/src/cpp/tasks/Thread.cpp index 7898233bc..3a877929f 100644 --- a/src/cpp/tasks/Thread.cpp +++ b/src/cpp/tasks/Thread.cpp @@ -55,10 +55,8 @@ namespace UniLib { while (true) { try { semaphore.tryWait(100); - printf("[Thread::%s] end worker thread\n", __FUNCTION__); - break; - } catch (Poco::TimeoutException& e) { - + //printf("[Thread::%s] end worker thread\n", __FUNCTION__); + //break; if (exitCalled) return; // Lock work mutex threadLock(); @@ -81,10 +79,11 @@ namespace UniLib { //LOG_ERROR("Fehler in Thread, exit", -1); printf("[Thread::%s] exception: %s\n", __FUNCTION__, e.message().data()); return; - } - - } - catch (Poco::Exception& e) { + } + + } catch (Poco::TimeoutException& e) { + printf("[Thread::%s] timeout exception\n", __FUNCTION__); + } catch (Poco::Exception& e) { printf("[Thread::%s] exception: %s\n", __FUNCTION__, e.message().data()); return; } diff --git a/src/cpp/tasks/WriteIntoDBTask.cpp b/src/cpp/tasks/WriteIntoDBTask.cpp index b8d6e5d20..ae6d92828 100644 --- a/src/cpp/tasks/WriteIntoDBTask.cpp +++ b/src/cpp/tasks/WriteIntoDBTask.cpp @@ -1,7 +1,7 @@ #include "WriteIntoDBTask.h" -WriteIntoDBTask::WriteIntoDBTask(ConnectionType type, std::vector multipleData) - : mFinished(false), mConnectionType(type), mDataToInsert(multipleData) +WriteIntoDBTask::WriteIntoDBTask(ConnectionType type, std::vector multipleData, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount/* = 0*/) + : UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mConnectionType(type), mDataToInsert(multipleData) { } @@ -26,7 +26,12 @@ int WriteIntoDBTask::run() use(person.name), use(person.address), use(person.age);*/ - insert << "INSERT INTO " << tableName << "VALUES("; + insert << "INSERT INTO " << tableName << " ("; + for (int iField = 0; iField < (*it)->getFieldCount(); iField++) { + if (iField > 0) insert << ","; + insert << (*it)->getHeaderName(iField); + } + insert << ") VALUES("; for (int iCell = 0; iCell < (*it)->getFieldCount(); iCell++) { if (iCell > 0) insert << ","; insert << "?"; @@ -34,10 +39,8 @@ int WriteIntoDBTask::run() insert << ")"; (*it)->connectToStatement(&insert); insert.execute(); + } - lock(); - mFinished = true; - unlock(); return 0; } \ No newline at end of file diff --git a/src/cpp/tasks/WriteIntoDBTask.h b/src/cpp/tasks/WriteIntoDBTask.h index e220d3e0b..cafa84570 100644 --- a/src/cpp/tasks/WriteIntoDBTask.h +++ b/src/cpp/tasks/WriteIntoDBTask.h @@ -1,29 +1,29 @@ #ifndef GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE #define GRADIDO_LOGIN_SERVER_TASKS_WRITE_INTO_DB_TASK_INCLUDE -#include "Task.h" +#include "CPUTask.h" #include "../SingletonManager/ConnectionManager.h" #include "../MySQL/MysqlTable.h" #include "Poco/Tuple.h" -class WriteIntoDBTask : public UniLib::controller::Task +class WriteIntoDBTask : public UniLib::controller::CPUTask { public: //! \param multipleData clear table in deconstruction, call delete for every entry - WriteIntoDBTask(ConnectionType type, std::vector multipleData); + WriteIntoDBTask(ConnectionType type, std::vector multipleData, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0); virtual ~WriteIntoDBTask(); virtual int run(); virtual const char* getResourceType() const { return "WriteIntoDBTask"; }; - virtual bool isTaskFinished() { return true; } + protected: private: - bool mFinished; ConnectionType mConnectionType; std::vector mDataToInsert; + };