fix bug which crashed server after to fast logout

This commit is contained in:
Dario 2019-10-08 11:34:14 +02:00
parent e4ffe57750
commit 9177398f48
7 changed files with 76 additions and 33 deletions

View File

@ -46,6 +46,7 @@ conan_basic_setup()
add_executable(Gradido_LoginServer ${LOCAL_SRCS})
#SUBDIRS("src/test")
if(WIN32)
@ -62,6 +63,7 @@ set(INSTALL_BINDIR "bin")
set(INSTALL_PLUGINDIR "bin")
add_subdirectory("dependencies/mariadb-connector-c")
include_directories(
"dependencies/mariadb-connector-c/include"
"build/dependencies/mariadb-connector-c/include"

@ -1 +1 @@
Subproject commit a0977c22d23f7e8cb596f1d9d812de74115f407b
Subproject commit 7307ffb8a89d2459f0c07ea5cab27c0d3496df00

View File

@ -19,16 +19,24 @@ using namespace Poco::Data::Keywords;
int WriteEmailVerification::run()
{
Profiler timeUsed;
Poco::UInt64 verificationCode = mSession->getEmailVerificationCode();
auto em = ErrorManager::getInstance();
//printf("[WriteEmailVerification::run] E-Mail Verification Code: %llu\n", verificationCode);
auto dbSession = ConnectionManager::getInstance()->getConnection(CONNECTION_MYSQL_LOGIN_SERVER);
//int user_id = mUser->getDBId();
Poco::Data::Statement insert(dbSession);
insert << "INSERT INTO email_opt_in (user_id, verification_code) VALUES(?,?);",
bind(mUser->getDBId()), use(verificationCode);
if (1 != insert.execute()) {
mSession->addError(new Error("WriteEmailVerification", "error inserting email verification code"));
return -1;
bind(mUser->getDBId()), use(mEmailVerificationCode);
try {
if (1 != insert.execute()) {
em->addError(new Error("[WriteEmailVerification]", "error inserting email verification code"));
em->sendErrorsAsEmail();
return -1;
}
} catch (Poco::Exception& ex) {
em->addError(new ParamError("[WriteEmailVerification]", "error inserting email verification code", ex.displayText().data()));
em->sendErrorsAsEmail();
return -2;
}
printf("[WriteEmailVerification] timeUsed: %s\n", timeUsed.string().data());
return 0;
@ -85,20 +93,27 @@ Session::~Session()
void Session::reset()
{
if (mSessionUser) {
delete mSessionUser;
mSessionUser = nullptr;
}
updateTimeout();
updateState(SESSION_STATE_EMPTY);
lock();
mSessionUser = nullptr;
// watch out
//updateTimeout();
mLastActivity = Poco::DateTime();
mState = SESSION_STATE_EMPTY;
mPassphrase = "";
mClientLoginIP = Poco::Net::IPAddress();
mEmailVerificationCode = 0;
unlock();
}
void Session::updateTimeout()
{
lock();
mLastActivity = Poco::DateTime();
unlock();
}
bool Session::createUser(const std::string& name, const std::string& email, const std::string& password)
@ -114,7 +129,7 @@ bool Session::createUser(const std::string& name, const std::string& email, cons
return false;
}
if (!sm->isValid(password, VALIDATE_PASSWORD)) {
addError(new Error("Passwort", "Bitte gebe ein g&uuml;ltiges Password ein mit mindestens 8 Zeichen, Gro&szlig;- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen ein!"));
addError(new Error("Passwort", "Bitte gebe ein g&uuml;ltiges Password ein mit mindestens 8 Zeichen, Gro&szlig;- und Kleinbuchstaben, mindestens einer Zahl und einem Sonderzeichen (@$!%*?&+-) ein!"));
// @$!%*?&+-
if (password.size() < 8) {
@ -181,7 +196,7 @@ bool Session::createUser(const std::string& name, const std::string& email, cons
createEmailVerificationCode();
UniLib::controller::TaskPtr writeEmailVerification(new WriteEmailVerification(mSessionUser, this, ServerConfig::g_CPUScheduler, 1));
UniLib::controller::TaskPtr writeEmailVerification(new WriteEmailVerification(mSessionUser, mEmailVerificationCode, ServerConfig::g_CPUScheduler, 1));
writeEmailVerification->setParentTaskPtrInArray(writeUserIntoDB, 0);
writeEmailVerification->setFinishCommand(new SessionStateUpdateCommand(SESSION_STATE_EMAIL_VERIFICATION_WRITTEN, this));
writeEmailVerification->scheduleTask(writeEmailVerification);
@ -419,6 +434,7 @@ bool Session::loadFromEmailVerificationCode(Poco::UInt64 emailVerificationCode)
void Session::updateState(SessionStates newState)
{
lock();
if (!mActive) return;
updateTimeout();
printf("[%s] newState: %s\n", __FUNCTION__, translateSessionStateToString(newState));
if (newState > mState) {
@ -516,4 +532,4 @@ bool Session::generateKeys(bool savePrivkey, bool savePassphrase)
mPassphrase.clear();
return true;
}
}

View File

@ -62,7 +62,7 @@ public:
Poco::Net::HTTPCookie getLoginCookie();
inline User* getUser() { return mSessionUser; }
inline Poco::AutoPtr<User> getUser() { return mSessionUser; }
inline int getHandle() { return mHandleId; }
@ -82,13 +82,14 @@ public:
const char* getSessionStateString();
inline SessionStates getSessionState() { SessionStates s; lock(); s = mState; unlock(); return s; }
inline unsigned long long getEmailVerificationCode() { return mEmailVerificationCode; }
inline Poco::UInt64 getEmailVerificationCode() { return mEmailVerificationCode; }
inline bool isActive() const { return mActive; }
inline void setActive(bool active) { mActive = active; }
inline Poco::DateTime getLastActivity() { return mLastActivity; }
protected:
void updateTimeout();
inline void setHandle(int newHandle) { mHandleId = newHandle; }
@ -100,30 +101,31 @@ protected:
private:
int mHandleId;
User* mSessionUser;
Poco::AutoPtr<User> mSessionUser;
std::string mPassphrase;
Poco::DateTime mLastActivity;
Poco::Net::IPAddress mClientLoginIP;
unsigned long long mEmailVerificationCode;
Poco::UInt64 mEmailVerificationCode;
SessionStates mState;
bool mActive;
};
class WriteEmailVerification : public UniLib::controller::CPUTask
{
public:
WriteEmailVerification(User* user, Session* session, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0)
: UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mSession(session) {}
WriteEmailVerification(Poco::AutoPtr<User> user, Poco::UInt64 emailVerificationCode, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0)
: UniLib::controller::CPUTask(cpuScheduler, taskDependenceCount), mUser(user), mEmailVerificationCode(emailVerificationCode) {}
virtual const char* getResourceType() const { return "WriteEmailVerification"; };
virtual int run();
private:
User* mUser;
Session* mSession;
Poco::AutoPtr<User> mUser;
Poco::UInt64 mEmailVerificationCode;
};

View File

@ -76,7 +76,7 @@ int UserWriteIntoDB::run()
// --------------------------------------------------------------------------------------------------------
UserWriteKeysIntoDB::UserWriteKeysIntoDB(UniLib::controller::TaskPtr parent, User* user, bool savePrivKey)
UserWriteKeysIntoDB::UserWriteKeysIntoDB(UniLib::controller::TaskPtr parent, Poco::AutoPtr<User> user, bool savePrivKey)
: UniLib::controller::CPUTask(1), mUser(user), mSavePrivKey(savePrivKey)
{
if (strcmp(parent->getResourceType(), "UserGenerateKeys") != 0) {
@ -201,6 +201,7 @@ std::string User::generateNewPassphrase(Mnemonic* word_source)
unsigned int str_sizes[PHRASE_WORD_COUNT];
unsigned int phrase_buffer_size = 0;
// TODO: make sure words didn't double
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
random_indices[i] = randombytes_random() % 2048;
auto word = word_source->getWord(random_indices[i]);
@ -271,6 +272,20 @@ bool User::validatePwd(const std::string& pwd)
return false;
}
void User::duplicate()
{
mReferenceCount++;
}
void User::release()
{
mReferenceCount--;
if (0 == mReferenceCount) {
delete this;
}
}
ObfusArray* User::createCryptoKey(const std::string& password)
{

View File

@ -51,6 +51,10 @@ public:
bool validatePwd(const std::string& pwd);
Poco::Data::BLOB* encrypt(const ObfusArray* data);
// for poco auto ptr
void duplicate();
void release();
protected:
typedef Poco::UInt64 passwordHashed;
@ -66,6 +70,8 @@ protected:
inline void lock() { mWorkingMutex.lock(); }
inline void unlock() { mWorkingMutex.unlock(); }
private:
int mDBId;
std::string mEmail;
@ -78,26 +84,28 @@ private:
std::string mPublicHex;
Poco::Mutex mWorkingMutex;
// for poco auto ptr
int mReferenceCount;
};
class UserCreateCryptoKey : public UniLib::controller::CPUTask
{
public:
UserCreateCryptoKey(User* user, const std::string& password, UniLib::controller::CPUSheduler* cpuScheduler)
UserCreateCryptoKey(Poco::AutoPtr<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;
Poco::AutoPtr<User> mUser;
std::string mPassword;
};
class UserGenerateKeys : public UniLib::controller::CPUTask
{
public:
UserGenerateKeys(User* user, const std::string& passphrase)
UserGenerateKeys(Poco::AutoPtr<User> user, const std::string& passphrase)
: mUser(user), mPassphrase(passphrase) {}
~UserGenerateKeys() {
@ -108,7 +116,7 @@ public:
virtual const char* getResourceType() const { return "UserGenerateKeys"; };
protected:
User* mUser;
Poco::AutoPtr<User> mUser;
std::string mPassphrase;
KeyPair mKeys;
};
@ -116,25 +124,25 @@ protected:
class UserWriteIntoDB : public UniLib::controller::CPUTask
{
public:
UserWriteIntoDB(User* user, UniLib::controller::CPUSheduler* cpuScheduler, size_t taskDependenceCount = 0)
UserWriteIntoDB(Poco::AutoPtr<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;
Poco::AutoPtr<User> mUser;
};
class UserWriteKeysIntoDB : public UniLib::controller::CPUTask
{
public:
UserWriteKeysIntoDB(UniLib::controller::TaskPtr parent, User* user, bool savePrivKey);
UserWriteKeysIntoDB(UniLib::controller::TaskPtr parent, Poco::AutoPtr<User> user, bool savePrivKey);
virtual int run();
virtual const char* getResourceType() const { return "UserWriteKeysIntoDB"; };
protected:
User* mUser;
Poco::AutoPtr<User> mUser;
bool mSavePrivKey;
};

View File

@ -79,7 +79,7 @@ label:not(.grd_radio_label) {
<% if(state == PAGE_SHOW_PASSPHRASE) {%>
<div class="grd_text-max-width">
<div class="grd_text">
Schreibe dir den Merkspruch auf und packe ihn gut weg. Du brauchst ihn um deine Adresse wiederherzustellen. Wenn du ihn verlierst, sind auch deine Gradidos verloren.
Schreibe dir die Passphrase auf und packe sie gut weg. Du brauchst sie um deine Adresse wiederherzustellen. Wenn du ihn verlierst, sind auch deine Gradidos verloren.
</div>
<div class="grd_textarea">
<%= mSession->getPassphrase() %>