mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
complete session timeout, found bug with session manager mutex and fix, found bug with long email verification code and fixed
This commit is contained in:
parent
3de1e21259
commit
cb47fe568e
@ -36,6 +36,12 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::
|
|||||||
response.redirect(uri_start + "/");
|
response.redirect(uri_start + "/");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// remove old cookies if exist
|
||||||
|
auto keks = Poco::Net::HTTPCookie("GRADIDO_LOGIN", std::to_string(mHandleId))
|
||||||
|
// max age of 0 delete cookie
|
||||||
|
keks.setMaxAge(0);
|
||||||
|
response.addCookie(keks);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& _responseStream = response.send();
|
std::ostream& _responseStream = response.send();
|
||||||
@ -72,7 +78,7 @@ void LoginPage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::Net::
|
|||||||
responseStream << "\t<div class=\"grd_container\">\n";
|
responseStream << "\t<div class=\"grd_container\">\n";
|
||||||
responseStream << "\t\t<h1>Login</h1>\n";
|
responseStream << "\t\t<h1>Login</h1>\n";
|
||||||
responseStream << "\t\t";
|
responseStream << "\t\t";
|
||||||
#line 56 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\login.cpsp"
|
#line 62 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\login.cpsp"
|
||||||
responseStream << ( session->getErrorsHtml() );
|
responseStream << ( session->getErrorsHtml() );
|
||||||
responseStream << "\n";
|
responseStream << "\n";
|
||||||
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
|
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
|
||||||
|
|||||||
@ -28,10 +28,12 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
|||||||
std::string url_first_part;
|
std::string url_first_part;
|
||||||
mRemoveGETParameters.extract(uri, url_first_part);
|
mRemoveGETParameters.extract(uri, url_first_part);
|
||||||
|
|
||||||
printf("[PageRequestHandlerFactory] uri: %s, first part: %s\n", uri.data(), url_first_part.data());
|
if (uri != "/favicon.ico") {
|
||||||
auto referer = request.find("Referer");
|
printf("[PageRequestHandlerFactory] uri: %s, first part: %s\n", uri.data(), url_first_part.data());
|
||||||
if (referer != request.end()) {
|
auto referer = request.find("Referer");
|
||||||
printf("referer: %s\n", referer->second.data());
|
if (referer != request.end()) {
|
||||||
|
printf("referer: %s\n", referer->second.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if user has valid session
|
// check if user has valid session
|
||||||
@ -41,18 +43,25 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
|
|||||||
int session_id = 0;
|
int session_id = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
session_id = atoi(cookies.get("user").data());
|
session_id = atoi(cookies.get("GRADIDO_LOGIN").data());
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
auto sm = SessionManager::getInstance();
|
auto sm = SessionManager::getInstance();
|
||||||
auto s = sm->getSession(session_id);
|
auto s = sm->getSession(session_id);
|
||||||
|
|
||||||
|
// TODO: count invalid session requests from IP and block IP for some time to prevent brute force session hijacking
|
||||||
|
// or use log file and configure fail2ban for this to do
|
||||||
|
|
||||||
if (url_first_part == "/checkEmail") {
|
if (url_first_part == "/checkEmail") {
|
||||||
//return new CheckEmailPage(s);
|
//return new CheckEmailPage(s);
|
||||||
return handleCheckEmail(s, uri, request);
|
if (!s || s->getSessionState() < SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED) {
|
||||||
|
return handleCheckEmail(s, uri, request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (s) {
|
if (s) {
|
||||||
if(url_first_part == "/logout") {
|
if(url_first_part == "/logout") {
|
||||||
sm->releseSession(s);
|
sm->releseSession(s);
|
||||||
|
// remove cookie
|
||||||
|
|
||||||
printf("session released\n");
|
printf("session released\n");
|
||||||
return new LoginPage;
|
return new LoginPage;
|
||||||
}
|
}
|
||||||
@ -97,15 +106,26 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
|||||||
// try to get code from form get parameter
|
// try to get code from form get parameter
|
||||||
if (!form.empty()) {
|
if (!form.empty()) {
|
||||||
try {
|
try {
|
||||||
verificationCode = stoll(form.get("email-verification-code", "0"));
|
verificationCode = stoull(form.get("email-verification-code", "0"));
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
}
|
}
|
||||||
// try to get code from uri parameter
|
// try to get code from uri parameter
|
||||||
if (!verificationCode) {
|
if (!verificationCode) {
|
||||||
size_t pos = uri.find_last_of("/");
|
size_t pos = uri.find_last_of("/");
|
||||||
try {
|
try {
|
||||||
verificationCode = stoll(uri.substr(pos + 1));
|
auto str = uri.substr(pos + 1);
|
||||||
} catch (...) {}
|
verificationCode = stoull(uri.substr(pos + 1));
|
||||||
|
} catch (const std::invalid_argument& ia) {
|
||||||
|
std::cerr << "Invalid argument: " << ia.what() << '\n';
|
||||||
|
} catch (const std::out_of_range& oor) {
|
||||||
|
std::cerr << "Out of Range error: " << oor.what() << '\n';
|
||||||
|
}
|
||||||
|
catch (const std::logic_error & ler) {
|
||||||
|
std::cerr << "Logical error: " << ler.what() << '\n';
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
std::cerr << "Unknown error" << '\n';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no verification code given or error with given code, show form
|
// if no verification code given or error with given code, show form
|
||||||
@ -138,6 +158,9 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::handleCheckEmail(Sessi
|
|||||||
}
|
}
|
||||||
// suitable session found or created
|
// suitable session found or created
|
||||||
if (session) {
|
if (session) {
|
||||||
|
auto user_host = request.clientAddress().host();
|
||||||
|
session->setClientIp(user_host);
|
||||||
|
|
||||||
// update session, mark as verified
|
// update session, mark as verified
|
||||||
if (session->updateEmailVerification(verificationCode)) {
|
if (session->updateEmailVerification(verificationCode)) {
|
||||||
return new PassphrasePage(session);
|
return new PassphrasePage(session);
|
||||||
|
|||||||
@ -35,10 +35,7 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
|
|||||||
bool hasErrors = mSession->errorCount() > 0;
|
bool hasErrors = mSession->errorCount() > 0;
|
||||||
|
|
||||||
// save login cookie, because maybe we've get an new session
|
// save login cookie, because maybe we've get an new session
|
||||||
auto cookie_id = mSession->getHandle();
|
response.addCookie(mSession->getLoginCookie());
|
||||||
auto user_host = request.clientAddress().host();
|
|
||||||
mSession->setClientIp(user_host);
|
|
||||||
response.addCookie(Poco::Net::HTTPCookie("user", std::to_string(cookie_id)));
|
|
||||||
|
|
||||||
if (!form.empty()) {
|
if (!form.empty()) {
|
||||||
auto registerKeyChoice = form.get("passphrase", "");
|
auto registerKeyChoice = form.get("passphrase", "");
|
||||||
@ -97,18 +94,18 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
|
|||||||
responseStream << "<body>\n";
|
responseStream << "<body>\n";
|
||||||
responseStream << "<div class=\"grd_container\">\n";
|
responseStream << "<div class=\"grd_container\">\n";
|
||||||
responseStream << "\t";
|
responseStream << "\t";
|
||||||
#line 78 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 75 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
if(mSession && hasErrors) { responseStream << "\n";
|
if(mSession && hasErrors) { responseStream << "\n";
|
||||||
responseStream << "\t\t";
|
responseStream << "\t\t";
|
||||||
#line 79 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 76 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
responseStream << ( mSession->getErrorsHtml() );
|
responseStream << ( mSession->getErrorsHtml() );
|
||||||
responseStream << "\n";
|
responseStream << "\n";
|
||||||
responseStream << "\t";
|
responseStream << "\t";
|
||||||
#line 80 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 77 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
} responseStream << "\n";
|
} responseStream << "\n";
|
||||||
responseStream << "\t<h1>Einen neuen Account anlegen</h1>\n";
|
responseStream << "\t<h1>Einen neuen Account anlegen</h1>\n";
|
||||||
responseStream << "\t";
|
responseStream << "\t";
|
||||||
#line 82 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 79 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
if(state == PAGE_SHOW_PASSPHRASE) { responseStream << "\n";
|
if(state == PAGE_SHOW_PASSPHRASE) { responseStream << "\n";
|
||||||
responseStream << "\t\t<div class=\"grd_text-max-width\">\n";
|
responseStream << "\t\t<div class=\"grd_text-max-width\">\n";
|
||||||
responseStream << "\t\t\t<div class=\"grd_text\">\n";
|
responseStream << "\t\t\t<div class=\"grd_text\">\n";
|
||||||
@ -116,16 +113,16 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
|
|||||||
responseStream << "\t\t\t</div>\n";
|
responseStream << "\t\t\t</div>\n";
|
||||||
responseStream << "\t\t\t<div class=\"grd_textarea\">\n";
|
responseStream << "\t\t\t<div class=\"grd_textarea\">\n";
|
||||||
responseStream << "\t\t\t\t";
|
responseStream << "\t\t\t\t";
|
||||||
#line 88 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 85 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
responseStream << ( mSession->getPassphrase() );
|
responseStream << ( mSession->getPassphrase() );
|
||||||
responseStream << "\n";
|
responseStream << "\n";
|
||||||
responseStream << "\t\t\t</div>\n";
|
responseStream << "\t\t\t</div>\n";
|
||||||
responseStream << "\t\t\t<a href=\"/saveKeys\">Weiter</a>\n";
|
responseStream << "\t\t\t<a href=\"/saveKeys\">Weiter</a>\n";
|
||||||
responseStream << "\t\t</div>\n";
|
responseStream << "\t\t</div>\n";
|
||||||
responseStream << "\t";
|
responseStream << "\t";
|
||||||
#line 92 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 89 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
} else if(state == PAGE_ASK_PASSPHRASE) { responseStream << "\n";
|
} else if(state == PAGE_ASK_PASSPHRASE) { responseStream << "\n";
|
||||||
responseStream << "\t<form method=\"POST\">\n";
|
responseStream << "\t<form method=\"POST\" action=\"/passphrase\">\n";
|
||||||
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
|
responseStream << "\t\t<fieldset class=\"grd_container_small\">\n";
|
||||||
responseStream << "\t\t\t<legend>Neue Gradido Adresse anlegen / wiederherstellen</legend>\n";
|
responseStream << "\t\t\t<legend>Neue Gradido Adresse anlegen / wiederherstellen</legend>\n";
|
||||||
responseStream << "\t\t\t<p>Hast du schonmal ein Gradido Konto besessen?</p>\n";
|
responseStream << "\t\t\t<p>Hast du schonmal ein Gradido Konto besessen?</p>\n";
|
||||||
@ -138,7 +135,7 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
|
|||||||
responseStream << "\t\t\t\t<label class=\"grd_radio_label\" for=\"passphrase-new-no\">Ja, bitte wiederherstellen!</label>\n";
|
responseStream << "\t\t\t\t<label class=\"grd_radio_label\" for=\"passphrase-new-no\">Ja, bitte wiederherstellen!</label>\n";
|
||||||
responseStream << "\t\t\t</p>\n";
|
responseStream << "\t\t\t</p>\n";
|
||||||
responseStream << "\t\t\t<textarea style=\"width:100%;height:100px\" name=\"passphrase-existing\">";
|
responseStream << "\t\t\t<textarea style=\"width:100%;height:100px\" name=\"passphrase-existing\">";
|
||||||
#line 105 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 102 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
responseStream << ( !form.empty() ? form.get("passphrase-existing", "") : "" );
|
responseStream << ( !form.empty() ? form.get("passphrase-existing", "") : "" );
|
||||||
responseStream << "</textarea>\n";
|
responseStream << "</textarea>\n";
|
||||||
responseStream << "\t\t</fieldset>\n";
|
responseStream << "\t\t</fieldset>\n";
|
||||||
@ -146,13 +143,13 @@ void PassphrasePage::handleRequest(Poco::Net::HTTPServerRequest& request, Poco::
|
|||||||
responseStream << "\t\t\n";
|
responseStream << "\t\t\n";
|
||||||
responseStream << "\t</form>\n";
|
responseStream << "\t</form>\n";
|
||||||
responseStream << "\t";
|
responseStream << "\t";
|
||||||
#line 110 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 107 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
} else { responseStream << "\n";
|
} else { responseStream << "\n";
|
||||||
responseStream << "\t\t<div class=\"grd_text\">\n";
|
responseStream << "\t\t<div class=\"grd_text\">\n";
|
||||||
responseStream << "\t\t\tUngültige Seite, wenn du das siehst stimmt hier etwas nicht. Bitte wende dich an den Server-Admin. \n";
|
responseStream << "\t\t\tUngültige Seite, wenn du das siehst stimmt hier etwas nicht. Bitte wende dich an den Server-Admin. \n";
|
||||||
responseStream << "\t\t</div>\n";
|
responseStream << "\t\t</div>\n";
|
||||||
responseStream << "\t";
|
responseStream << "\t";
|
||||||
#line 114 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
#line 111 "I:\\Code\\C++\\Eigene_Projekte\\Gradido_LoginServer\\src\\cpsp\\passphrase.cpsp"
|
||||||
} responseStream << "\n";
|
} responseStream << "\n";
|
||||||
responseStream << "</div>\n";
|
responseStream << "</div>\n";
|
||||||
responseStream << "</body>\n";
|
responseStream << "</body>\n";
|
||||||
|
|||||||
@ -17,12 +17,16 @@ using Poco::Net::ConsoleCertificateHandler;
|
|||||||
using Poco::SharedPtr;
|
using Poco::SharedPtr;
|
||||||
|
|
||||||
namespace ServerConfig {
|
namespace ServerConfig {
|
||||||
|
|
||||||
|
#define SESSION_TIMEOUT_DEFAULT 10
|
||||||
|
|
||||||
Mnemonic g_Mnemonic_WordLists[MNEMONIC_MAX];
|
Mnemonic g_Mnemonic_WordLists[MNEMONIC_MAX];
|
||||||
ObfusArray* g_ServerCryptoKey = nullptr;
|
ObfusArray* g_ServerCryptoKey = nullptr;
|
||||||
// std::string g_ServerAdminPublic;
|
// std::string g_ServerAdminPublic;
|
||||||
UniLib::controller::CPUSheduler* g_CPUScheduler = nullptr;
|
UniLib::controller::CPUSheduler* g_CPUScheduler = nullptr;
|
||||||
Context::Ptr g_SSL_CLient_Context = nullptr;
|
Context::Ptr g_SSL_CLient_Context = nullptr;
|
||||||
EmailAccount g_EmailAccount;
|
EmailAccount g_EmailAccount;
|
||||||
|
int g_SessionTimeout = SESSION_TIMEOUT_DEFAULT;
|
||||||
|
|
||||||
bool loadMnemonicWordLists()
|
bool loadMnemonicWordLists()
|
||||||
{
|
{
|
||||||
@ -66,6 +70,8 @@ namespace ServerConfig {
|
|||||||
g_ServerCryptoKey = new ObfusArray(realBinSize, key);
|
g_ServerCryptoKey = new ObfusArray(realBinSize, key);
|
||||||
|
|
||||||
//g_ServerAdminPublic = cfg.getString("crypto.server_admin_public");
|
//g_ServerAdminPublic = cfg.getString("crypto.server_admin_public");
|
||||||
|
|
||||||
|
g_SessionTimeout = cfg.getInt("session.timeout", SESSION_TIMEOUT_DEFAULT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,7 @@ namespace ServerConfig {
|
|||||||
extern UniLib::controller::CPUSheduler* g_CPUScheduler;
|
extern UniLib::controller::CPUSheduler* g_CPUScheduler;
|
||||||
extern Poco::Net::Context::Ptr g_SSL_CLient_Context;
|
extern Poco::Net::Context::Ptr g_SSL_CLient_Context;
|
||||||
extern EmailAccount g_EmailAccount;
|
extern EmailAccount g_EmailAccount;
|
||||||
|
extern int g_SessionTimeout;
|
||||||
|
|
||||||
bool loadMnemonicWordLists();
|
bool loadMnemonicWordLists();
|
||||||
bool initServerCrypto(const Poco::Util::LayeredConfiguration& cfg);
|
bool initServerCrypto(const Poco::Util::LayeredConfiguration& cfg);
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
#include "SessionManager.h"
|
#include "SessionManager.h"
|
||||||
|
#include "ErrorManager.h"
|
||||||
|
#include "../ServerConfig.h"
|
||||||
|
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
|
||||||
@ -33,10 +35,10 @@ bool SessionManager::init()
|
|||||||
case VALIDATE_EMAIL: mValidations[i] = new Poco::RegularExpression("^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"); break;
|
case VALIDATE_EMAIL: mValidations[i] = new Poco::RegularExpression("^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$"); break;
|
||||||
case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-])[A-Za-z0-9@$!%*?&+-]{8,}$"); break;
|
case VALIDATE_PASSWORD: mValidations[i] = new Poco::RegularExpression("^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[@$!%*?&+-])[A-Za-z0-9@$!%*?&+-]{8,}$"); break;
|
||||||
case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break;
|
case VALIDATE_PASSPHRASE: mValidations[i] = new Poco::RegularExpression("^(?:[a-z]* ){23}[a-z]*\s*$"); break;
|
||||||
case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression("[0-9]"); break;
|
case VALIDATE_HAS_NUMBER: mValidations[i] = new Poco::RegularExpression(".*[0-9].*"); break;
|
||||||
case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression("[@$!%*?&+-]"); break;
|
case VALIDATE_HAS_SPECIAL_CHARACTER: mValidations[i] = new Poco::RegularExpression(".*[@$!%*?&+-].*"); break;
|
||||||
case VALIDATE_HAS_UPPERCASE_LETTER: mValidations[i] = new Poco::RegularExpression("[A-Z]"); break;
|
case VALIDATE_HAS_UPPERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[A-Z].*"); break;
|
||||||
case VALIDATE_HAS_LOWERCASE_LETTER: mValidations[i] = new Poco::RegularExpression("[a-z]"); break;
|
case VALIDATE_HAS_LOWERCASE_LETTER: mValidations[i] = new Poco::RegularExpression(".*[a-z].*"); break;
|
||||||
default: printf("[SessionManager::%s] unknown validation type\n", __FUNCTION__);
|
default: printf("[SessionManager::%s] unknown validation type\n", __FUNCTION__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,6 +79,25 @@ bool SessionManager::isValid(const std::string& subject, SessionValidationTypes
|
|||||||
return *mValidations[validationType] == subject;
|
return *mValidations[validationType] == subject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SessionManager::generateNewUnusedHandle()
|
||||||
|
{
|
||||||
|
int newHandle = 0;
|
||||||
|
int maxTrys = 0;
|
||||||
|
do {
|
||||||
|
newHandle = randombytes_random();
|
||||||
|
maxTrys++;
|
||||||
|
} while (mRequestSessionMap.find(newHandle) != mRequestSessionMap.end() && maxTrys < 100);
|
||||||
|
|
||||||
|
if (maxTrys >= 100 || 0 == newHandle) {
|
||||||
|
auto em = ErrorManager::getInstance();
|
||||||
|
em->addError(new ParamError("SessionManager::generateNewUnusedHandle", "can't find new handle, have already ", std::to_string(mRequestSessionMap.size())));
|
||||||
|
em->sendErrorsAsEmail();
|
||||||
|
//printf("[SessionManager::%s] can't find new handle, have already: %d",
|
||||||
|
//__FUNCTION__, mRequestSessionMap.size());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return newHandle;
|
||||||
|
}
|
||||||
|
|
||||||
Session* SessionManager::getNewSession(int* handle)
|
Session* SessionManager::getNewSession(int* handle)
|
||||||
{
|
{
|
||||||
@ -84,15 +105,22 @@ Session* SessionManager::getNewSession(int* handle)
|
|||||||
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
printf("[SessionManager::%s] not initialized any more\n", __FUNCTION__);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// first check if we have any timeouted session to directly reuse it
|
||||||
|
checkTimeoutSession();
|
||||||
|
|
||||||
// lock
|
// lock
|
||||||
mWorkingMutex.lock();
|
mWorkingMutex.lock();
|
||||||
|
|
||||||
|
//UniLib::controller::TaskPtr checkSessionTimeout(new CheckSessionTimeouted);
|
||||||
|
//checkSessionTimeout->scheduleTask(checkSessionTimeout);
|
||||||
|
|
||||||
// check if we have an existing session ready to use
|
// check if we have an existing session ready to use
|
||||||
if (mEmptyRequestStack.size() > 0) {
|
while (mEmptyRequestStack.size() > 0) {
|
||||||
int local_handle = mEmptyRequestStack.top();
|
int local_handle = mEmptyRequestStack.top();
|
||||||
mEmptyRequestStack.pop();
|
mEmptyRequestStack.pop();
|
||||||
auto resultIt = mRequestSessionMap.find(local_handle);
|
auto resultIt = mRequestSessionMap.find(local_handle);
|
||||||
if (resultIt != mRequestSessionMap.end()) {
|
if (resultIt != mRequestSessionMap.end() && !resultIt->second->isActive()) {
|
||||||
Session* result = resultIt->second;
|
Session* result = resultIt->second;
|
||||||
result->reset();
|
result->reset();
|
||||||
mWorkingMutex.unlock();
|
mWorkingMutex.unlock();
|
||||||
@ -100,38 +128,34 @@ Session* SessionManager::getNewSession(int* handle)
|
|||||||
if (handle) {
|
if (handle) {
|
||||||
*handle = local_handle;
|
*handle = local_handle;
|
||||||
}
|
}
|
||||||
|
result->setActive(true);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// else create new RequestSession Object
|
// else create new RequestSession Object
|
||||||
// calculate random handle
|
// calculate random handle
|
||||||
// check if already exist, if get new
|
// check if already exist, if get new
|
||||||
int newHandle = 0;
|
int newHandle = generateNewUnusedHandle();
|
||||||
int maxTrys = 0;
|
if (!newHandle) {
|
||||||
do {
|
|
||||||
newHandle = randombytes_random();
|
|
||||||
maxTrys++;
|
|
||||||
} while (mRequestSessionMap.find(newHandle) != mRequestSessionMap.end() && maxTrys < 100);
|
|
||||||
|
|
||||||
if (maxTrys >= 100 || 0 == newHandle) {
|
|
||||||
printf("[SessionManager::%s] can't find new handle, have already: %d",
|
|
||||||
__FUNCTION__, mRequestSessionMap.size());
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto requestSession = new Session(newHandle);
|
|
||||||
mRequestSessionMap.insert(std::pair<int, Session*>(newHandle, requestSession));
|
|
||||||
mWorkingMutex.unlock();
|
mWorkingMutex.unlock();
|
||||||
|
return nullptr;
|
||||||
if (handle) {
|
|
||||||
*handle = newHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return requestSession;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
auto requestSession = new Session(newHandle);
|
||||||
|
mRequestSessionMap.insert(std::pair<int, Session*>(newHandle, requestSession));
|
||||||
|
|
||||||
|
requestSession->setActive(true);
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
|
||||||
|
if (handle) {
|
||||||
|
*handle = newHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return requestSession;
|
||||||
|
|
||||||
|
|
||||||
|
//return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SessionManager::releseSession(int requestHandleSession)
|
bool SessionManager::releseSession(int requestHandleSession)
|
||||||
@ -147,8 +171,25 @@ bool SessionManager::releseSession(int requestHandleSession)
|
|||||||
mWorkingMutex.unlock();
|
mWorkingMutex.unlock();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
it->second->reset();
|
Session* session = it->second;
|
||||||
mEmptyRequestStack.push(requestHandleSession);
|
session->reset();
|
||||||
|
session->setActive(false);
|
||||||
|
// change request handle we don't want session hijacking
|
||||||
|
|
||||||
|
int newHandle = generateNewUnusedHandle();
|
||||||
|
// erase after generating new number to prevent to getting the same number again
|
||||||
|
mRequestSessionMap.erase(requestHandleSession);
|
||||||
|
|
||||||
|
if (!newHandle) {
|
||||||
|
delete session;
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->setHandle(newHandle);
|
||||||
|
mRequestSessionMap.insert(std::pair<int, Session*>(newHandle, session));
|
||||||
|
mEmptyRequestStack.push(newHandle);
|
||||||
|
|
||||||
mWorkingMutex.unlock();
|
mWorkingMutex.unlock();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -181,6 +222,8 @@ Session* SessionManager::getSession(int handle)
|
|||||||
auto it = mRequestSessionMap.find(handle);
|
auto it = mRequestSessionMap.find(handle);
|
||||||
if (it != mRequestSessionMap.end()) {
|
if (it != mRequestSessionMap.end()) {
|
||||||
result = it->second;
|
result = it->second;
|
||||||
|
result->setActive(true);
|
||||||
|
result->updateTimeout();
|
||||||
}
|
}
|
||||||
mWorkingMutex.unlock();
|
mWorkingMutex.unlock();
|
||||||
return result;
|
return result;
|
||||||
@ -188,11 +231,47 @@ Session* SessionManager::getSession(int handle)
|
|||||||
|
|
||||||
Session* SessionManager::findByEmailVerificationCode(long long emailVerificationCode)
|
Session* SessionManager::findByEmailVerificationCode(long long emailVerificationCode)
|
||||||
{
|
{
|
||||||
|
Session* result = nullptr;
|
||||||
|
mWorkingMutex.lock();
|
||||||
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
||||||
if (it->second->getEmailVerificationCode() == emailVerificationCode) {
|
if (it->second->getEmailVerificationCode() == emailVerificationCode) {
|
||||||
return it->second;
|
result = it->second;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
|
||||||
return nullptr;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionManager::checkTimeoutSession()
|
||||||
|
{
|
||||||
|
mWorkingMutex.lock();
|
||||||
|
auto now = Poco::DateTime();
|
||||||
|
// random variance within 10 seconds for timeout to make it harder to get information and hack the server
|
||||||
|
auto timeout = Poco::Timespan(ServerConfig::g_SessionTimeout * 60, randombytes_random() % 10000000);
|
||||||
|
std::stack<int> toRemove;
|
||||||
|
for (auto it = mRequestSessionMap.begin(); it != mRequestSessionMap.end(); it++) {
|
||||||
|
if (!it->second->isActive()) continue;
|
||||||
|
Poco::Timespan timeElapsed(now - it->second->getLastActivity());
|
||||||
|
if (timeElapsed > timeout) {
|
||||||
|
toRemove.push(it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mWorkingMutex.unlock();
|
||||||
|
|
||||||
|
while (toRemove.size() > 0) {
|
||||||
|
int handle = toRemove.top();
|
||||||
|
toRemove.pop();
|
||||||
|
releseSession(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int CheckSessionTimeouted::run()
|
||||||
|
{
|
||||||
|
SessionManager::getInstance()->checkTimeoutSession();
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@ -46,6 +46,7 @@ public:
|
|||||||
}
|
}
|
||||||
bool releseSession(int requestHandleSession);
|
bool releseSession(int requestHandleSession);
|
||||||
bool isExist(int requestHandleSession);
|
bool isExist(int requestHandleSession);
|
||||||
|
// try to find existing session, return nullptr if not found
|
||||||
Session* getSession(int handle);
|
Session* getSession(int handle);
|
||||||
Session* findByEmailVerificationCode(long long emailVerificationCode);
|
Session* findByEmailVerificationCode(long long emailVerificationCode);
|
||||||
|
|
||||||
@ -54,9 +55,12 @@ public:
|
|||||||
|
|
||||||
bool isValid(const std::string& subject, SessionValidationTypes validationType);
|
bool isValid(const std::string& subject, SessionValidationTypes validationType);
|
||||||
|
|
||||||
|
void checkTimeoutSession();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SessionManager();
|
SessionManager();
|
||||||
|
|
||||||
|
int generateNewUnusedHandle();
|
||||||
|
|
||||||
// access mutex
|
// access mutex
|
||||||
std::mutex mWorkingMutex;
|
std::mutex mWorkingMutex;
|
||||||
@ -71,4 +75,11 @@ protected:
|
|||||||
Poco::RegularExpression* mValidations[VALIDATE_MAX];
|
Poco::RegularExpression* mValidations[VALIDATE_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CheckSessionTimeouted : public UniLib::controller::CPUTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual int run();
|
||||||
|
virtual const char* getResourceType() const { return "CheckSessionTimeouted"; };
|
||||||
|
};
|
||||||
|
|
||||||
#endif //DR_LUA_WEB_MODULE_SESSION_MANAGER_H
|
#endif //DR_LUA_WEB_MODULE_SESSION_MANAGER_H
|
||||||
@ -20,7 +20,7 @@ int WriteEmailVerification::run()
|
|||||||
{
|
{
|
||||||
Profiler timeUsed;
|
Profiler timeUsed;
|
||||||
auto verificationCode = mSession->getEmailVerificationCode();
|
auto verificationCode = mSession->getEmailVerificationCode();
|
||||||
printf("{[WriteEmailVerification::run] E-Mail Verification Code: %llu\n", verificationCode);
|
//printf("[WriteEmailVerification::run] E-Mail Verification Code: %llu\n", verificationCode);
|
||||||
auto dbSession = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
auto dbSession = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
|
||||||
int user_id = mUser->getDBId();
|
int user_id = mUser->getDBId();
|
||||||
Poco::Data::Statement insert(dbSession);
|
Poco::Data::Statement insert(dbSession);
|
||||||
@ -30,7 +30,7 @@ int WriteEmailVerification::run()
|
|||||||
mSession->addError(new Error("WriteEmailVerification", "error inserting email verification code"));
|
mSession->addError(new Error("WriteEmailVerification", "error inserting email verification code"));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
printf("[WriteEmailVerification::run] timeUsed: %s\n", timeUsed.string().data());
|
printf("[WriteEmailVerification] timeUsed: %s\n", timeUsed.string().data());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ int WritePassphraseIntoDB::run()
|
|||||||
em->sendErrorsAsEmail();
|
em->sendErrorsAsEmail();
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("[WritePassphraseIntoDB::run] timeUsed: %s\n", timeUsed.string().data());
|
printf("[WritePassphraseIntoDB] timeUsed: %s\n", timeUsed.string().data());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ int WritePassphraseIntoDB::run()
|
|||||||
// --------------------------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
Session::Session(int handle)
|
Session::Session(int handle)
|
||||||
: mHandleId(handle), mSessionUser(nullptr), mEmailVerificationCode(0), mState(SESSION_STATE_EMPTY)
|
: mHandleId(handle), mSessionUser(nullptr), mEmailVerificationCode(0), mState(SESSION_STATE_EMPTY), mActive(false)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -90,7 +90,10 @@ void Session::reset()
|
|||||||
mSessionUser = nullptr;
|
mSessionUser = nullptr;
|
||||||
}
|
}
|
||||||
updateTimeout();
|
updateTimeout();
|
||||||
|
updateState(SESSION_STATE_EMPTY);
|
||||||
|
mPassphrase = "";
|
||||||
mClientLoginIP = Poco::Net::IPAddress();
|
mClientLoginIP = Poco::Net::IPAddress();
|
||||||
|
mEmailVerificationCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::updateTimeout()
|
void Session::updateTimeout()
|
||||||
@ -111,6 +114,8 @@ bool Session::createUser(const std::string& name, const std::string& email, cons
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!sm->isValid(password, VALIDATE_PASSWORD)) {
|
if (!sm->isValid(password, VALIDATE_PASSWORD)) {
|
||||||
|
addError(new Error("Passwort", "Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen ein!"));
|
||||||
|
|
||||||
// @$!%*?&+-
|
// @$!%*?&+-
|
||||||
if (password.size() < 8) {
|
if (password.size() < 8) {
|
||||||
addError(new Error("Passwort", "Dein Passwort ist zu kurz!"));
|
addError(new Error("Passwort", "Dein Passwort ist zu kurz!"));
|
||||||
@ -127,7 +132,7 @@ bool Session::createUser(const std::string& name, const std::string& email, cons
|
|||||||
else if (!sm->isValid(password, VALIDATE_HAS_SPECIAL_CHARACTER)) {
|
else if (!sm->isValid(password, VALIDATE_HAS_SPECIAL_CHARACTER)) {
|
||||||
addError(new Error("Passwort", "Dein Passwort enthält keine Sonderzeichen (@$!%*?&+-)!"));
|
addError(new Error("Passwort", "Dein Passwort enthält keine Sonderzeichen (@$!%*?&+-)!"));
|
||||||
}
|
}
|
||||||
addError(new Error("Passwort", "Bitte gebe ein gültiges Password ein mit mindestens 8 Zeichen, Groß- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen"));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/*if (passphrase.size() > 0 && !sm->isValid(passphrase, VALIDATE_PASSPHRASE)) {
|
/*if (passphrase.size() > 0 && !sm->isValid(passphrase, VALIDATE_PASSPHRASE)) {
|
||||||
@ -215,6 +220,7 @@ bool Session::createUser(const std::string& name, const std::string& email, cons
|
|||||||
|
|
||||||
bool Session::updateEmailVerification(unsigned long long emailVerificationCode)
|
bool Session::updateEmailVerification(unsigned long long emailVerificationCode)
|
||||||
{
|
{
|
||||||
|
|
||||||
Profiler usedTime;
|
Profiler usedTime;
|
||||||
const static char* funcName = "Session::updateEmailVerification";
|
const static char* funcName = "Session::updateEmailVerification";
|
||||||
auto em = ErrorManager::getInstance();
|
auto em = ErrorManager::getInstance();
|
||||||
@ -243,6 +249,7 @@ bool Session::updateEmailVerification(unsigned long long emailVerificationCode)
|
|||||||
}
|
}
|
||||||
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
|
updateState(SESSION_STATE_EMAIL_VERIFICATION_CODE_CHECKED);
|
||||||
printf("[%s] time: %s\n", funcName, usedTime.string().data());
|
printf("[%s] time: %s\n", funcName, usedTime.string().data());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -347,8 +354,12 @@ void Session::detectSessionState()
|
|||||||
|
|
||||||
Poco::Net::HTTPCookie Session::getLoginCookie()
|
Poco::Net::HTTPCookie Session::getLoginCookie()
|
||||||
{
|
{
|
||||||
auto keks = Poco::Net::HTTPCookie("user", std::to_string(mHandleId));
|
auto keks = Poco::Net::HTTPCookie("GRADIDO_LOGIN", std::to_string(mHandleId));
|
||||||
// TODO: additional config, like js permit
|
// prevent reading or changing cookie with js
|
||||||
|
keks.setHttpOnly();
|
||||||
|
// send cookie only via https
|
||||||
|
keks.setSecure(true);
|
||||||
|
|
||||||
return keks;
|
return keks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +418,8 @@ bool Session::loadFromEmailVerificationCode(unsigned long long emailVerification
|
|||||||
void Session::updateState(SessionStates newState)
|
void Session::updateState(SessionStates newState)
|
||||||
{
|
{
|
||||||
lock();
|
lock();
|
||||||
printf("[Session::%s] newState: %s\n", __FUNCTION__, translateSessionStateToString(newState));
|
updateTimeout();
|
||||||
|
printf("[%s] newState: %s\n", __FUNCTION__, translateSessionStateToString(newState));
|
||||||
if (newState > mState) {
|
if (newState > mState) {
|
||||||
mState = newState;
|
mState = newState;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,11 +39,12 @@ enum SessionStates {
|
|||||||
SESSION_STATE_COUNT
|
SESSION_STATE_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SessionManager;
|
||||||
|
|
||||||
class Session : public ErrorList, public UniLib::lib::MultithreadContainer
|
class Session : public ErrorList, public UniLib::lib::MultithreadContainer
|
||||||
{
|
{
|
||||||
friend WriteEmailVerification;
|
friend WriteEmailVerification;
|
||||||
|
friend SessionManager;
|
||||||
public:
|
public:
|
||||||
Session(int handle);
|
Session(int handle);
|
||||||
~Session();
|
~Session();
|
||||||
@ -63,6 +64,7 @@ public:
|
|||||||
inline User* getUser() { return mSessionUser; }
|
inline User* getUser() { return mSessionUser; }
|
||||||
|
|
||||||
inline int getHandle() { return mHandleId; }
|
inline int getHandle() { return mHandleId; }
|
||||||
|
|
||||||
inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; }
|
inline void setPassphrase(const std::string& passphrase) { mPassphrase = passphrase; }
|
||||||
inline const std::string& getPassphrase() { return mPassphrase; }
|
inline const std::string& getPassphrase() { return mPassphrase; }
|
||||||
bool generatePassphrase();
|
bool generatePassphrase();
|
||||||
@ -81,14 +83,21 @@ public:
|
|||||||
|
|
||||||
inline unsigned long long getEmailVerificationCode() { return mEmailVerificationCode; }
|
inline unsigned long long getEmailVerificationCode() { return mEmailVerificationCode; }
|
||||||
|
|
||||||
|
inline bool isActive() const { return mActive; }
|
||||||
|
inline void setActive(bool active) { mActive = active; }
|
||||||
|
|
||||||
|
inline Poco::DateTime getLastActivity() { return mLastActivity; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void updateTimeout();
|
void updateTimeout();
|
||||||
|
inline void setHandle(int newHandle) { mHandleId = newHandle; }
|
||||||
|
|
||||||
void createEmailVerificationCode();
|
void createEmailVerificationCode();
|
||||||
|
|
||||||
void detectSessionState();
|
void detectSessionState();
|
||||||
static const char* translateSessionStateToString(SessionStates state);
|
static const char* translateSessionStateToString(SessionStates state);
|
||||||
|
|
||||||
|
private:
|
||||||
int mHandleId;
|
int mHandleId;
|
||||||
User* mSessionUser;
|
User* mSessionUser;
|
||||||
std::string mPassphrase;
|
std::string mPassphrase;
|
||||||
@ -97,6 +106,8 @@ protected:
|
|||||||
unsigned long long mEmailVerificationCode;
|
unsigned long long mEmailVerificationCode;
|
||||||
|
|
||||||
SessionStates mState;
|
SessionStates mState;
|
||||||
|
|
||||||
|
bool mActive;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
57
src/cpp/tasks/PrepareEmailTask.cpp
Normal file
57
src/cpp/tasks/PrepareEmailTask.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "PrepareEmailTask.h"
|
||||||
|
#include "../model/Profiler.h"
|
||||||
|
#include "../ServerConfig.h"
|
||||||
|
#include "../SingletonManager/ErrorManager.h"
|
||||||
|
|
||||||
|
PrepareEmailTask::PrepareEmailTask(UniLib::controller::CPUSheduler* cpuScheduler)
|
||||||
|
: UniLib::controller::CPUTask(cpuScheduler), mMailClientSession(nullptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PrepareEmailTask::~PrepareEmailTask()
|
||||||
|
{
|
||||||
|
if (mMailClientSession) {
|
||||||
|
delete mMailClientSession;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PrepareEmailTask::run()
|
||||||
|
{
|
||||||
|
Profiler timeUsed;
|
||||||
|
mMailClientSession = new Poco::Net::SecureSMTPClientSession(ServerConfig::g_EmailAccount.url, ServerConfig::g_EmailAccount.port);
|
||||||
|
mMailClientSession->login();
|
||||||
|
mMailClientSession->startTLS(ServerConfig::g_SSL_CLient_Context);
|
||||||
|
|
||||||
|
|
||||||
|
mMailClientSession->login(Poco::Net::SMTPClientSession::AUTH_LOGIN, ServerConfig::g_EmailAccount.username, ServerConfig::g_EmailAccount.password);
|
||||||
|
|
||||||
|
printf("[PrepareEmailTask] time: %s\n", timeUsed.string().data());
|
||||||
|
/*
|
||||||
|
session.login();
|
||||||
|
session.startTLS(pContext);
|
||||||
|
if (!username.empty())
|
||||||
|
{
|
||||||
|
session.login(SMTPClientSession::AUTH_LOGIN, username, password);
|
||||||
|
}
|
||||||
|
session.sendMessage(message);
|
||||||
|
session.close();
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int PrepareEmailTask::send(Poco::Net::MailMessage* message)
|
||||||
|
{
|
||||||
|
auto er = ErrorManager::getInstance();
|
||||||
|
try {
|
||||||
|
mMailClientSession->sendMessage(*message);
|
||||||
|
mMailClientSession->close();
|
||||||
|
}
|
||||||
|
catch (Poco::Exception& exc) {
|
||||||
|
er->addError(new ParamError("PrepareEmailTask::send", "error sending email", exc.displayText().data()));
|
||||||
|
printf("[PrepareEmailTask::%s] error sending email: %s\n", __FUNCTION__, exc.displayText().data());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
23
src/cpp/tasks/PrepareEmailTask.h
Normal file
23
src/cpp/tasks/PrepareEmailTask.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef GRADIDO_LOGIN_SERVER_TASKS_PREPAIRE_EMAIL_TASK_INCLUDE
|
||||||
|
#define GRADIDO_LOGIN_SERVER_TASKS_PREPAIRE_EMAIL_TASK_INCLUDE
|
||||||
|
|
||||||
|
#include "CPUTask.h"
|
||||||
|
#include "Poco/Net/SecureSMTPClientSession.h"
|
||||||
|
|
||||||
|
class PrepareEmailTask : public UniLib::controller::CPUTask
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PrepareEmailTask(UniLib::controller::CPUSheduler* cpuScheduler);
|
||||||
|
virtual ~PrepareEmailTask();
|
||||||
|
|
||||||
|
virtual int run();
|
||||||
|
int send(Poco::Net::MailMessage* message);
|
||||||
|
virtual const char* getResourceType() const { return "PrepareEmailTask"; };
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
Poco::Net::SecureSMTPClientSession* mMailClientSession;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //GRADIDO_LOGIN_SERVER_TASKS_PREPAIRE_EMAIL_TASK_INCLUDE
|
||||||
@ -1,5 +1,6 @@
|
|||||||
#include "SendEmailTask.h"
|
#include "SendEmailTask.h"
|
||||||
#include "PrepareEmailTask.h"
|
#include "PrepareEmailTask.h"
|
||||||
|
#include "../model/Profiler.h"
|
||||||
#include "../SingletonManager/ErrorManager.h"
|
#include "../SingletonManager/ErrorManager.h"
|
||||||
#include "../ServerConfig.h"
|
#include "../ServerConfig.h"
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ SendEmailTask::~SendEmailTask()
|
|||||||
|
|
||||||
int SendEmailTask::run()
|
int SendEmailTask::run()
|
||||||
{
|
{
|
||||||
|
Profiler timeUsed;
|
||||||
auto er = ErrorManager::getInstance();
|
auto er = ErrorManager::getInstance();
|
||||||
auto parent = getParent(0);
|
auto parent = getParent(0);
|
||||||
|
|
||||||
@ -31,5 +33,6 @@ int SendEmailTask::run()
|
|||||||
if (prepare->send(mMailMessage)) {
|
if (prepare->send(mMailMessage)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
printf("[SendEmailTask] time: %s\n", timeUsed.string().data());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -21,6 +21,12 @@
|
|||||||
response.redirect(uri_start + "/");
|
response.redirect(uri_start + "/");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// remove old cookies if exist
|
||||||
|
auto keks = Poco::Net::HTTPCookie("GRADIDO_LOGIN", std::to_string(mHandleId))
|
||||||
|
// max age of 0 delete cookie
|
||||||
|
keks.setMaxAge(0);
|
||||||
|
response.addCookie(keks);
|
||||||
}
|
}
|
||||||
|
|
||||||
%>
|
%>
|
||||||
|
|||||||
@ -17,10 +17,7 @@ enum PageState
|
|||||||
bool hasErrors = mSession->errorCount() > 0;
|
bool hasErrors = mSession->errorCount() > 0;
|
||||||
|
|
||||||
// save login cookie, because maybe we've get an new session
|
// save login cookie, because maybe we've get an new session
|
||||||
auto cookie_id = mSession->getHandle();
|
response.addCookie(mSession->getLoginCookie());
|
||||||
auto user_host = request.clientAddress().host();
|
|
||||||
mSession->setClientIp(user_host);
|
|
||||||
response.addCookie(Poco::Net::HTTPCookie("user", std::to_string(cookie_id)));
|
|
||||||
|
|
||||||
if (!form.empty()) {
|
if (!form.empty()) {
|
||||||
auto registerKeyChoice = form.get("passphrase", "");
|
auto registerKeyChoice = form.get("passphrase", "");
|
||||||
@ -90,7 +87,7 @@ label:not(.grd_radio_label) {
|
|||||||
<a href="/saveKeys">Weiter</a>
|
<a href="/saveKeys">Weiter</a>
|
||||||
</div>
|
</div>
|
||||||
<% } else if(state == PAGE_ASK_PASSPHRASE) { %>
|
<% } else if(state == PAGE_ASK_PASSPHRASE) { %>
|
||||||
<form method="POST">
|
<form method="POST" action="/passphrase">
|
||||||
<fieldset class="grd_container_small">
|
<fieldset class="grd_container_small">
|
||||||
<legend>Neue Gradido Adresse anlegen / wiederherstellen</legend>
|
<legend>Neue Gradido Adresse anlegen / wiederherstellen</legend>
|
||||||
<p>Hast du schonmal ein Gradido Konto besessen?</p>
|
<p>Hast du schonmal ein Gradido Konto besessen?</p>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user