From 33927473adf4bf5c27efd5b57315973cd0e6f627 Mon Sep 17 00:00:00 2001 From: Dario Date: Fri, 10 Jan 2020 17:29:31 +0100 Subject: [PATCH] implement task observer --- src/cpp/Crypto/KeyPair.cpp | 55 ++++- src/cpp/Crypto/KeyPair.h | 1 + src/cpp/Gradido_LoginServer.cpp | 7 + src/cpp/HTTPInterface/ElopageWebhook.cpp | 7 +- .../PageRequestHandlerFactory.cpp | 19 +- src/cpp/HTTPInterface/PassphrasePage.cpp | 76 +++++-- .../HTTPInterface/UpdateUserPasswordPage.cpp | 50 ++++- .../JSONInterface/JsonGetRunningUserTasks.cpp | 47 ++++ .../JSONInterface/JsonGetRunningUserTasks.h | 16 ++ .../JsonRequestHandlerFactory.cpp | 4 + .../SingletonTaskObserver.cpp | 209 ++++++++++++++++++ .../SingletonManager/SingletonTaskObserver.h | 74 +++++++ src/cpp/controller/EmailVerificationCode.h | 2 + src/cpp/main.cpp | 9 +- src/cpp/model/Session.cpp | 130 +++++++---- src/cpp/model/Session.h | 9 + src/cpp/model/User.cpp | 160 ++++++++++++-- src/cpp/model/User.h | 13 +- src/cpp/model/table/ElopageBuy.cpp | 12 + src/cpp/model/table/ElopageBuy.h | 1 + src/cpp/model/table/EmailOptIn.cpp | 16 +- src/cpp/model/table/EmailOptIn.h | 1 + src/cpp/model/table/ModelBase.cpp | 56 ++++- src/cpp/model/table/ModelBase.h | 11 +- src/cpp/model/table/User.cpp | 11 + src/cpp/model/table/User.h | 1 + src/cpp/tasks/ProcessingTransaction.cpp | 15 +- src/cpp/tasks/ProcessingTransaction.h | 3 +- src/cpp/tasks/SigningTransaction.cpp | 11 +- src/cpsp/passphrase.cpsp | 45 +++- src/cpsp/updateUserPassword.cpsp | 37 +++- 31 files changed, 973 insertions(+), 135 deletions(-) create mode 100644 src/cpp/JSONInterface/JsonGetRunningUserTasks.cpp create mode 100644 src/cpp/JSONInterface/JsonGetRunningUserTasks.h create mode 100644 src/cpp/SingletonManager/SingletonTaskObserver.cpp create mode 100644 src/cpp/SingletonManager/SingletonTaskObserver.h diff --git a/src/cpp/Crypto/KeyPair.cpp b/src/cpp/Crypto/KeyPair.cpp index d4570e588..3f7d41fcb 100644 --- a/src/cpp/Crypto/KeyPair.cpp +++ b/src/cpp/Crypto/KeyPair.cpp @@ -47,6 +47,7 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour //DHASH key = DRMakeStringHash(passphrase); size_t pass_phrase_size = strlen(passphrase); + std::string clearPassphrase = ""; char acBuffer[STR_BUFFER_SIZE]; memset(acBuffer, 0, STR_BUFFER_SIZE); size_t buffer_cursor = 0; // get word indices for hmac key @@ -55,6 +56,8 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour if (passphrase[i] == ' ') { if(buffer_cursor < 3) continue; if (word_source->isWordExist(acBuffer)) { + clearPassphrase += acBuffer; + clearPassphrase += " "; word_indices[word_cursor] = word_source->getWordIndex(acBuffer); } else { @@ -80,11 +83,15 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour //crypto_auth_hmacsha512_init(&state, (unsigned char*)word_indices, sizeof(word_indices)); sha512_init(&state); sha512_update(&state, (unsigned char*)word_indices, sizeof(word_indices)); - sha512_update(&state, (unsigned char*)passphrase, pass_phrase_size); + sha512_update(&state, (unsigned char*)clearPassphrase.data(), clearPassphrase.size()); //crypto_auth_hmacsha512_update(&state, (unsigned char*)passphrase, pass_phrase_size); sha512_final(&state, hash); //crypto_auth_hmacsha512_final(&state, hash); + // debug passphrase +// printf("\passsphrase: <%s>\n", passphrase); +// printf("word_indices: \n%s\n", getHex((unsigned char*)word_indices, sizeof(word_indices)).data()); +// printf("passphrase bin: \n%s\n\n", getHex((unsigned char*)passphrase, pass_phrase_size).data()); //ed25519_create_keypair(public_key, private_key, hash); private_key_t prv_key_t; @@ -132,6 +139,52 @@ bool KeyPair::generateFromPassphrase(const char* passphrase, Mnemonic* word_sour return true; } +std::string KeyPair::filterPassphrase(const std::string& passphrase) +{ + std::string filteredPassphrase; + auto passphrase_size = passphrase.size(); + for (int i = 0; i < passphrase_size; i++) { + char c = passphrase.data()[i]; + // asci 128 even by utf8 (hex) + // 0000 0000 – 0000 007F + // utf8 + if (c > 0x0000007F) { + int additionalUtfByteCount = 0; + filteredPassphrase += c; + if ((c & 0x00000080) == 0x00000080) { + additionalUtfByteCount = 1; + } + else if ((c & 0x00000800) == 0x00000800) { + additionalUtfByteCount = 2; + } + else if ((c & 0x00010000) == 0x00010000) { + additionalUtfByteCount = 3; + } + for (int j = 1; j <= additionalUtfByteCount; j++) { + filteredPassphrase += passphrase.data()[i + j]; + i++; + } + } + else { + // 32 = Space + // 65 = A + // 90 = Z + // 97 = a + // 122 = z + if (c == 32 || + (c >= 65 && c <= 90) || + (c >= 97 && c <= 122)) { + filteredPassphrase += c; + } + else if (c == '\n' || c == '\r') { + filteredPassphrase += ' '; + } + } + + } + return filteredPassphrase; +} + std::string KeyPair::getPubkeyHex() { const size_t hexSize = crypto_sign_PUBLICKEYBYTES * 2 + 1; diff --git a/src/cpp/Crypto/KeyPair.h b/src/cpp/Crypto/KeyPair.h index d0b15afc6..07a1de4bf 100644 --- a/src/cpp/Crypto/KeyPair.h +++ b/src/cpp/Crypto/KeyPair.h @@ -22,6 +22,7 @@ public: ~KeyPair(); bool generateFromPassphrase(const char* passphrase, Mnemonic* word_source); + static std::string filterPassphrase(const std::string& passphrase); std::string getPubkeyHex(); bool savePrivKey(int userId); static std::string getHex(const unsigned char* data, Poco::UInt32 size); diff --git a/src/cpp/Gradido_LoginServer.cpp b/src/cpp/Gradido_LoginServer.cpp index 5b689ab4f..d9961d716 100644 --- a/src/cpp/Gradido_LoginServer.cpp +++ b/src/cpp/Gradido_LoginServer.cpp @@ -156,6 +156,13 @@ int Gradido_LoginServer::main(const std::vector& args) return Application::EXIT_CONFIG; } + // first check time for crypto + auto testUser = new User("email@google.de", "Max", "Mustermann"); + Profiler timeUsed; + testUser->validatePwd("haz27Newpassword", nullptr); + ServerConfig::g_FakeLoginSleepTime = (int)std::round(timeUsed.millis()); + delete testUser; + Poco::Int64 i1 = randombytes_random(); Poco::Int64 i2 = randombytes_random(); ServerConfig::g_ServerKeySeed->put(1, i1 | (i2 << 8)); diff --git a/src/cpp/HTTPInterface/ElopageWebhook.cpp b/src/cpp/HTTPInterface/ElopageWebhook.cpp index 68ab7d695..557e92287 100644 --- a/src/cpp/HTTPInterface/ElopageWebhook.cpp +++ b/src/cpp/HTTPInterface/ElopageWebhook.cpp @@ -28,6 +28,9 @@ void ElopageWebhook::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: //ServerConfig::writeToFile(request.stream(), "elopage_webhook_requests.txt"); // empty response, we didn't need to set anything + //response.setStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT); + std::ostream& _responseStream = response.send(); + _responseStream << "200 OK"; std::istream& stream = request.stream(); std::string completeRequest; @@ -234,7 +237,7 @@ int HandleElopageRequestTask::run() if (elopageBuy->errorCount() > 0) { getErrors(elopageBuy); } - UniLib::controller::TaskPtr saveElopageBuy(new model::table::ModelInsertTask(elopageBuy)); + UniLib::controller::TaskPtr saveElopageBuy(new model::table::ModelInsertTask(elopageBuy, false)); saveElopageBuy->scheduleTask(saveElopageBuy); // check product id @@ -342,7 +345,7 @@ int HandleElopageRequestTask::run() } // write email verification code into db - UniLib::controller::TaskPtr saveEmailVerificationCode(new model::table::ModelInsertTask(emailVerification->getModel())); + UniLib::controller::TaskPtr saveEmailVerificationCode(new model::table::ModelInsertTask(emailVerification->getModel(), true)); saveEmailVerificationCode->scheduleTask(saveEmailVerificationCode); int noEMail = 0; diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index 06336635a..6097c6065 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -131,8 +131,15 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c } auto sessionState = s->getSessionState(); printf("session state: %s\n", s->getSessionStateString()); + if (url_first_part == "/updateUserPassword" && sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) { + auto pageRequestHandler = new UpdateUserPasswordPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } + //printf("session state: %s\n", s->getSessionStateString()); if(sessionState == SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED || - sessionState == SESSION_STATE_PASSPHRASE_GENERATED) { + sessionState == SESSION_STATE_PASSPHRASE_GENERATED || + sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) { //if (url_first_part == "/passphrase") { //return handlePassphrase(s, request); auto pageRequestHandler = new PassphrasePage(s); @@ -145,6 +152,12 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + else if (sessionState == SESSION_STATE_RESET_PASSWORD_REQUEST) { + // + auto pageRequestHandler = new UpdateUserPasswordPage(s); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } if (url_first_part == "/checkTransactions") { auto pageRequestHandler = new CheckTransactionPage(s); pageRequestHandler->setProfiler(timeUsed); @@ -267,10 +280,12 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi int retUpdateEmailVerification = session->updateEmailVerification(verificationCode); if (0 == retUpdateEmailVerification) { - printf("[PageRequestHandlerFactory::handleCheckEmail] timeUsed: %s\n", timeUsed.string().data()); + //printf("[PageRequestHandlerFactory::handleCheckEmail] timeUsed: %s\n", timeUsed.string().data()); + auto pageRequestHandler = new PassphrasePage(session); pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; + } else if (1 == retUpdateEmailVerification) { auto user = session->getUser(); diff --git a/src/cpp/HTTPInterface/PassphrasePage.cpp b/src/cpp/HTTPInterface/PassphrasePage.cpp index 1f7b3d171..56a219f91 100644 --- a/src/cpp/HTTPInterface/PassphrasePage.cpp +++ b/src/cpp/HTTPInterface/PassphrasePage.cpp @@ -8,12 +8,14 @@ #line 7 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp" #include "../SingletonManager/SessionManager.h" +#include "../crypto/KeyPair.h" //#include "Poco/Net/HTTPServerParams.h" enum PageState { PAGE_ASK_PASSPHRASE, - PAGE_SHOW_PASSPHRASE + PAGE_SHOW_PASSPHRASE, + PAGE_FORCE_ASK_PASSPHRASE }; #line 1 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" @@ -34,7 +36,7 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: if (_compressResponse) response.set("Content-Encoding", "gzip"); Poco::Net::HTMLForm form(request, request.stream()); -#line 17 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp" +#line 19 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\passphrase.cpsp" const char* pageName = "Passphrase"; PageState state = PAGE_ASK_PASSPHRASE; @@ -46,17 +48,33 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: // save login cookie, because maybe we've get an new session response.addCookie(mSession->getLoginCookie()); + if(mSession->getSessionState() == SESSION_STATE_RESET_PASSWORD_REQUEST) { + state = PAGE_FORCE_ASK_PASSPHRASE; + } + if (!form.empty()) { - auto registerKeyChoice = form.get("passphrase", ""); + auto registerKeyChoice = form.get("passphrase", "no"); std::string oldPassphrase = ""; if (registerKeyChoice == "no") { - auto oldPassphrase = form.get("passphrase-existing", ""); - - if (oldPassphrase != "" && User::validatePassphrase(oldPassphrase)) { + auto oldPassphrase = KeyPair::filterPassphrase(form.get("passphrase-existing", "")); + + Mnemonic* wordSource = nullptr; + if (oldPassphrase != "" && User::validatePassphrase(oldPassphrase, &wordSource)) { // passphrase is valid - mSession->setPassphrase(oldPassphrase); - mSession->updateState(SESSION_STATE_PASSPHRASE_SHOWN); - state = PAGE_SHOW_PASSPHRASE; + if(PAGE_FORCE_ASK_PASSPHRASE == state) { + auto compareResult = mSession->comparePassphraseWithSavedKeys(oldPassphrase, wordSource); + if(-2 == compareResult) { + response.redirect(ServerConfig::g_serverPath + "/error500"); + return; + } else if(1 == compareResult) { + response.redirect(ServerConfig::g_serverPath + "/updateUserPassword"); + return; + } + } else { + mSession->setPassphrase(oldPassphrase); + mSession->updateState(SESSION_STATE_PASSPHRASE_SHOWN); + state = PAGE_SHOW_PASSPHRASE; + } } else { addError(new Error("Passphrase", "Diese Passphrase ist ungültig, bitte überprüfen oder neu generieren (lassen).")); @@ -133,7 +151,10 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco:: responseStream << "\n"; responseStream << "
\n"; responseStream << "\t

Login Server in Entwicklung

\n"; - responseStream << "\t

Alpha 0.8.1

\n"; + responseStream << "\t

Alpha "; +#line 53 "F:\\Gradido\\gradido_login_server\\src\\cpsp\\header_old.cpsp" + responseStream << ( ServerConfig::g_versionString ); + responseStream << "

\n"; responseStream << "
\n"; responseStream << "