diff --git a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp index b8391d1fd..de55e529e 100644 --- a/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp +++ b/src/cpp/HTTPInterface/PageRequestHandlerFactory.cpp @@ -23,6 +23,7 @@ #include "DebugPassphrasePage.h" #include "AdminCheckUserBackup.h" #include "TranslatePassphrase.h" +#include "PassphrasedTransaction.h" #include "DecodeTransactionPage.h" @@ -128,6 +129,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c pageRequestHandler->setProfiler(timeUsed); return pageRequestHandler; } + if (url_first_part == "/passphrased_transaction") { + auto pageRequestHandler = new PassphrasedTransaction(); + pageRequestHandler->setProfiler(timeUsed); + return pageRequestHandler; + } if (s) { if (externReferer != "") { s->setLastReferer(externReferer); diff --git a/src/cpp/JSONInterface/JsonGetUserInfos.cpp b/src/cpp/JSONInterface/JsonGetUserInfos.cpp index acb24194c..46fb6e400 100644 --- a/src/cpp/JSONInterface/JsonGetUserInfos.cpp +++ b/src/cpp/JSONInterface/JsonGetUserInfos.cpp @@ -91,6 +91,9 @@ Poco::JSON::Object* JsonGetUserInfos::handle(Poco::Dynamic::Var params) else if (parameterString == "loginServer.path") { jsonServer.set("loginServer.path", ServerConfig::g_serverPath); } + else if (parameterString == "user.pubkeyhex") { + jsonUser.set("pubkeyhex", userModel->getPublicKeyHex()); + } } catch (Poco::Exception& ex) { jsonErrorsArray.add("ask parameter invalid"); diff --git a/src/cpp/JSONInterface/JsonRequestHandler.cpp b/src/cpp/JSONInterface/JsonRequestHandler.cpp index 1b1e73837..123c36268 100644 --- a/src/cpp/JSONInterface/JsonRequestHandler.cpp +++ b/src/cpp/JSONInterface/JsonRequestHandler.cpp @@ -70,7 +70,7 @@ Poco::Dynamic::Var JsonRequestHandler::parseJsonWithErrorPrintFile(std::istream& errorHandler->addError(new ParamError(functionName, "error parsing request answer", ex.displayText().data())); errorHandler->sendErrorsAsEmail(responseStringStream.str()); } - std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d.%m.%y %H:%M:%S"); + std::string dateTimeString = Poco::DateTimeFormatter::format(Poco::DateTime(), "%d_%m_%yT%H_%M_%S"); std::string filename = dateTimeString + "_response.html"; FILE* f = fopen(filename.data(), "wt"); std::string responseString = responseStringStream.str(); diff --git a/src/cpp/model/table/User.cpp b/src/cpp/model/table/User.cpp index d27df7073..ddc4b6c8c 100644 --- a/src/cpp/model/table/User.cpp +++ b/src/cpp/model/table/User.cpp @@ -235,6 +235,21 @@ namespace model { return ss.str(); } + std::string User::getPublicKeyHex() const + { + auto mm = MemoryManager::getInstance(); + auto pubkeyHex = mm->getFreeMemory(65); + + memset(*pubkeyHex, 0, 65); + + if (!mPublicKey.isNull()) { + sodium_bin2hex(*pubkeyHex, 65, mPublicKey.value().content().data(), mPublicKey.value().content().size()); + } + std::string pubkeyHexString((const char*)pubkeyHex->data(), pubkeyHex->size()-1); + mm->releaseMemory(pubkeyHex); + return pubkeyHexString; + } + Poco::JSON::Object User::getJson() { @@ -262,5 +277,7 @@ namespace model { return userObj; } + + } } \ No newline at end of file diff --git a/src/cpp/model/table/User.h b/src/cpp/model/table/User.h index 024ffbcea..d9f1bd10f 100644 --- a/src/cpp/model/table/User.h +++ b/src/cpp/model/table/User.h @@ -54,6 +54,8 @@ namespace model { inline const Poco::UInt64& getPasswordHashed() const { return mPasswordHashed; } inline RoleType getRole() const { if (mRole.isNull()) return ROLE_NONE; return static_cast(mRole.value()); } inline const unsigned char* getPublicKey() const { if (mPublicKey.isNull()) return nullptr; return mPublicKey.value().content().data(); } + std::string getPublicKeyHex() const; + inline bool existPrivateKeyCrypted() const { return !mPrivateKey.isNull(); } inline const std::vector& getPrivateKeyCrypted() const { return mPrivateKey.value().content(); } inline bool isEmailChecked() const { return mEmailChecked; } diff --git a/src/cpsp/PassphrasedTransaction.cpsp b/src/cpsp/PassphrasedTransaction.cpsp new file mode 100644 index 000000000..5f7e4b8a0 --- /dev/null +++ b/src/cpsp/PassphrasedTransaction.cpsp @@ -0,0 +1,161 @@ +<%@ page class="PassphrasedTransaction" %> +<%@ page form="true" %> +<%@ page compressed="true" %> +<%@ page baseClass="PageRequestMessagedHandler" %> +<%@ header include="PageRequestMessagedHandler.h" %> +<%! +#include "../SingletonManager/MemoryManager.h" +#include "../SingletonManager/SessionManager.h" +#include "../Crypto/KeyPair.h" +#include "../ServerConfig.h" + +#include "Poco/JSON/Object.h" +#include "Poco/JSON/Parser.h" +#include "Poco/Net/HTTPSClientSession.h" +#include "Poco/Net/HTTPRequest.h" +#include "Poco/Net/HTTPResponse.h" + +enum PageState { + PAGE_STATE_INPUT, + PAGE_STATE_SUCCESS +}; +%> +<%% + std::string pageName = "Gradidos mit Passphrase überweisen"; + PageState state = PAGE_STATE_INPUT; + Mnemonic* wordSource = &ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER]; + auto sm = SessionManager::getInstance(); + auto mm = MemoryManager::getInstance(); + std::string errorString =""; + + if(!form.empty()) { + auto passphrase = form.get("passphrase", ""); + bool passphraseValid = User::validatePassphrase(passphrase, &wordSource); + bool keysGenerated = false; + KeyPair keys; + if(!passphraseValid) + { + addError(new Error("Passphrase", "Fehler beim validieren der Passphrase")); + } + else + { + keysGenerated = keys.generateFromPassphrase(passphrase.data(), wordSource); + if(!keysGenerated) + { + addError(new Error("Passphrase", "Konnte keine Keys aus der Passphrase generieren")); + } + } + if(passphraseValid && keysGenerated) + { + // create session only for transaction + int session_id = 0; + auto session = sm->getNewSession(&session_id); + // create payload + Poco::JSON::Object requestJson; + Poco::JSON::Object pubkeys; + pubkeys.set("sender", keys.getPubkeyHex()); + pubkeys.set("receiver", form.get("recevier", "")); + requestJson.set("method", "moveTransaction"); + requestJson.set("pubkeys", pubkeys); + requestJson.set("memo", form.get("memo", "")); + requestJson.set("session_id", session_id); + + printf("[PassphrasedTransaction] prepare request\n"); + + // send to php server + Poco::Net::HTTPSClientSession httpsClientSession(ServerConfig::g_php_serverHost, 443); + Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, "/JsonRequestHandler"); + + request.setChunkedTransferEncoding(true); + std::ostream& requestStream = httpsClientSession.sendRequest(request); + requestJson.stringify(requestStream); + + Poco::Net::HTTPResponse response; + std::istream& request_stream = httpsClientSession.receiveResponse(response); + + std::stringstream responseStringStream; + for (std::string line; std::getline(request_stream, line); ) { + responseStringStream << line << std::endl; + } + + // extract parameter from request + Poco::JSON::Parser jsonParser; + Poco::Dynamic::Var parsedJson; + + printf("[PassphrasedTransaction] parse request result\n"); + try { + parsedJson = jsonParser.parse(responseStringStream); + + Poco::JSON::Object object = *parsedJson.extract(); + auto jsonState = object.get("state"); + std::string stateString = jsonState.convert(); + if (stateString == "error") { + addError(new Error("Transfer", "php server return error")); + if (!object.isNull("msg")) { + addError(new ParamError("php server", "msg:", object.get("msg").convert().data())); + } + if (!object.isNull("details")) { + addError(new ParamError("php server", "details:", object.get("details").convert().data())); + } + } else if(stateString == "success") { + printf("[PassphrasedTransaction] request success, wait on transaction ready\n"); + auto currentActiveTransaction = session->getNextReadyTransaction(); + while(currentActiveTransaction.isNull()) { + Poco::Thread::sleep(10); + currentActiveTransaction = session->getNextReadyTransaction(); + } + if(!currentActiveTransaction->isTransfer()) { + addError(new Error("Transaction", "Falsche Transaktion, bitte erst alle anderen Transaktionen abschließen und dann Seite neuladen")); + } else { + //auto signing = new SigningTransaction(currentActiveTransaction, user); + printf("[PassphrasedTransaction] cannot sign, implementation missing\n"); + /*if(!signing->run()) { + + } else { + addError(new Error("Transaction", "Fehler beim signieren, bitter erneut versuchen")); + }*/ + // remove transaction from list + //mSession->finalizeTransaction(true, true); + } + } + } + catch (Poco::Exception& ex) { + //printf("[JsonRequestHandler::handleRequest] Exception: %s\n", ex.displayText().data()); + addError(new ParamError("Transfer", "Fehler beim erstellen der Transaktion, bitte erneut versuchen", ex.displayText().data())); + errorString = responseStringStream.str(); + sm->releaseSession(session); + session = nullptr; + } + if(session) { + sm->releaseSession(session); + } + } + } + + +%><%@ include file="header_old.cpsp" %> +<% if("" == errorString) { %> + <%= errorString %> +<% } %> +
+ <%= getErrorsHtml() %> + <% if(PAGE_STATE_INPUT == state) { %> + +
+
+

+

+

+

+

+ + "/> +

+

+
+ <% } else if(PAGE_STATE_SUCCESS == state) { %> +

Gradidos wurden erfolgreich überwiesen.

+ Weitere Gradidos überweisen + <% } %> +
+<%@ include file="footer.cpsp" %>