add createUserDirect and missing functions for that in related classes

This commit is contained in:
Dario 2020-06-09 20:34:27 +02:00
parent 7d826fcacd
commit c009a12f45
12 changed files with 221 additions and 8 deletions

View File

@ -3,6 +3,7 @@
#include "Poco/Types.h"
#include "Poco/Tuple.h"
#include "../SingletonManager/ErrorManager.h"
#include "KeyPairEd25519.h"
@ -163,10 +164,88 @@ Poco::AutoPtr<Passphrase> Passphrase::create(const Poco::UInt16 wordIndices[PHRA
clearPassphrase += word;
clearPassphrase += " ";
}
else {
return nullptr;
}
}
return new Passphrase(clearPassphrase, wordSource);
}
Poco::AutoPtr<Passphrase> Passphrase::generate(const Mnemonic* wordSource)
{
auto em = ErrorManager::getInstance();
auto mm = MemoryManager::getInstance();
auto word_indices = mm->getFreeMemory(PHRASE_WORD_COUNT * sizeof(Poco::UInt16));
Poco::UInt16* word_indices_p = (Poco::UInt16*)word_indices->data();
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
word_indices_p[i] = randombytes_random() % 2048;
}
auto result_passphrase = create(word_indices_p, wordSource);
mm->releaseMemory(word_indices);
return result_passphrase;
/*
unsigned int random_indices[PHRASE_WORD_COUNT];
unsigned int str_sizes[PHRASE_WORD_COUNT];
unsigned int phrase_buffer_size = 0;
static const char* function_name = "Passphrase::generate";
bool error_reloading_mnemonic_word_list = false;
int loop_trys = 0;
Poco::RegularExpression check_valid_word("^[a-zA-ZÄÖÜäöüß&;]*$");
// TODO: make sure words didn't double
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
random_indices[i] = randombytes_random() % 2048;
auto word = wordSource->getWord(random_indices[i]);
if (loop_trys > 10 || error_reloading_mnemonic_word_list) {
return nullptr;
}
if (!word) {
em->addError(new ParamError(function_name, "empty word get for index", random_indices[i]));
em->sendErrorsAsEmail();
random_indices[i] = randombytes_random() % 2048;
word = wordSource->getWord(random_indices[i]);
if (!word) return nullptr;
}
else {
if (!check_valid_word.match(word, 0, Poco::RegularExpression::RE_NOTEMPTY)) {
em->addError(new ParamError(function_name, "invalid word", word));
em->addError(new Error(function_name, "try to reload mnemonic word list, but this error is maybe evidence for a serious memory problem!!!"));
if (!ServerConfig::loadMnemonicWordLists()) {
em->addError(new Error(function_name, "error reloading mnemonic word lists"));
error_reloading_mnemonic_word_list = true;
}
else {
i = 0;
loop_trys++;
}
em->sendErrorsAsEmail();
}
}
str_sizes[i] = strlen(word);
phrase_buffer_size += str_sizes[i];
}
phrase_buffer_size += PHRASE_WORD_COUNT + 1;
std::string phrase_buffer(phrase_buffer_size, '\0');
int phrase_buffer_cursor = 0;
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
memcpy(&phrase_buffer[phrase_buffer_cursor], wordSource->getWord(random_indices[i]), str_sizes[i]);
phrase_buffer_cursor += str_sizes[i];
phrase_buffer[phrase_buffer_cursor++] = ' ';
}
return create(;
*/
}
bool Passphrase::createWordIndices()
{

View File

@ -16,6 +16,8 @@ public:
static Poco::AutoPtr<Passphrase> create(const Poco::UInt16 wordIndices[PHRASE_WORD_COUNT], const Mnemonic* wordSource);
static Poco::AutoPtr<Passphrase> create(const MemoryBin* wordIndices, const Mnemonic* wordSource);
//! \brief generate new passphrase with random
static Poco::AutoPtr<Passphrase> generate(const Mnemonic* wordSource);
static const Mnemonic* detectMnemonic(const std::string& passphrase, const KeyPairEd25519* keyPair = nullptr);
//! \brief transform passphrase into another language/mnemonic source

View File

@ -9,6 +9,13 @@
#include "DRRandom.h"
#include "../SingletonManager/ErrorManager.h"
#include "../ServerConfig.h"
#include "Poco/RegularExpression.h"
static Poco::RegularExpression g_checkValidWord("^[a-zA-ZÄÖÜäöüß&;]*$");
Mnemonic::Mnemonic()
{
memset(mWords, 0, 2048);
@ -180,6 +187,49 @@ bool Mnemonic::isWordExist(const std::string& word) const
}
*/
const char* Mnemonic::getWord(short index) const {
//std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
if (index < 2048 && index >= 0) {
std::string word;
{
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
word = mWords[index];
}
if (!g_checkValidWord.match(word, 0, Poco::RegularExpression::RE_NOTEMPTY)) {
auto em = ErrorManager::getInstance();
const char* function_name = "Mnemonic::getWord";
em->addError(new ParamError(function_name, "invalid word", word));
em->addError(new Error(function_name, "try to reload mnemonic word list, but this error is maybe evidence for a serious memory problem!!!"));
if (!ServerConfig::loadMnemonicWordLists()) {
em->addError(new Error(function_name, "error reloading mnemonic word lists"));
em->sendErrorsAsEmail();
return nullptr;
}
{
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
word = mWords[index];
}
if (!g_checkValidWord.match(word, 0, Poco::RegularExpression::RE_NOTEMPTY)) {
em->addError(new Error(function_name, "word invalid after reload mnemonic word lists"));
em->sendErrorsAsEmail();
return nullptr;
}
em->sendErrorsAsEmail();
}
{
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
return mWords[index];
}
}
return nullptr;
}
void Mnemonic::clear()
{
//Poco::Mutex::ScopedLock _lock(mWorkingMutex, 500);

View File

@ -30,11 +30,7 @@ public:
int init(void(*fill_words_func)(unsigned char*), unsigned int original_size, unsigned int compressed_size);
inline const char* getWord(short index) const {
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);
if (index < 2048 && index >= 0) return mWords[index];
return nullptr;
}
const char* getWord(short index) const;
short getWordIndex(const char* word) const;
inline bool isWordExist(const std::string& word) const {
std::shared_lock<std::shared_mutex> _lock(mWorkingMutex);

View File

@ -26,7 +26,7 @@
#include "TranslatePassphrase.h"
#include "PassphrasedTransaction.h"
#include "AdminUserPasswordReset.h"
#include "RegisterDirectPage.h"
#include "DecodeTransactionPage.h"
#include "RepairDefectPassphrase.h"
@ -119,6 +119,11 @@ Poco::Net::HTTPRequestHandler* PageRequestHandlerFactory::createRequestHandler(c
pageRequestHandler->setProfiler(timeUsed);
return pageRequestHandler;
}
if (url_first_part == "/registerDirect") {
auto pageRequestHandler = new RegisterDirectPage;
pageRequestHandler->setProfiler(timeUsed);
return pageRequestHandler;
}
if (url_first_part == "/resetPassword") {
auto resetPassword = new ResetPassword;
resetPassword->setProfiler(timeUsed);

View File

@ -118,6 +118,7 @@ MemoryManager::MemoryManager()
mMemoryPageStacks[2] = new MemoryPageStack(65); // pubkey hex
mMemoryPageStacks[3] = new MemoryPageStack(96); // privkey encrypted
mMemoryPageStacks[4] = new MemoryPageStack(161); // privkey hex
mMemoryPageStacks[5] = new MemoryPageStack(48); // word indices
}
MemoryManager::~MemoryManager()
@ -135,6 +136,7 @@ Poco::Int8 MemoryManager::getMemoryStackIndex(Poco::UInt16 size)
case 65: return 2;
case 96: return 3;
case 161: return 4;
case 48: return 5;
default: return -1;
}
return -1;

View File

@ -85,7 +85,7 @@ protected:
Poco::Int8 getMemoryStackIndex(Poco::UInt16 size);
MemoryManager();
MemoryPageStack* mMemoryPageStacks[5];
MemoryPageStack* mMemoryPageStacks[6];
};

View File

@ -158,6 +158,15 @@ namespace controller {
return 0;
}
void User::setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair)
{
assert(gradidoKeyPair);
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);
if (mGradidoKeyPair) delete mGradidoKeyPair;
mGradidoKeyPair = gradidoKeyPair;
getModel()->setPublicKey(mGradidoKeyPair->getPublicKey());
}
int User::setPassword(AuthenticatedEncryption* passwd)
{
std::unique_lock<std::shared_mutex> _lock(mSharedMutex);

View File

@ -64,6 +64,10 @@ namespace controller {
std::shared_lock<std::shared_mutex> _lock(mSharedMutex);
return mPassword;
}
//! \brief set key pair, public in model, private with next setPassword call into model
//! \param gradidoKeyPair take owner ship
void setGradidoKeyPair(KeyPairEd25519* gradidoKeyPair);
inline const KeyPairEd25519* getGradidoKeyPair() {
std::shared_lock<std::shared_mutex> _lock(mSharedMutex);
return mGradidoKeyPair;

View File

@ -15,9 +15,13 @@
#include "../tasks/PrepareEmailTask.h"
#include "../tasks/SendEmailTask.h"
#include "../tasks/SigningTransaction.h"
#include "../tasks/AuthenticatedEncryptionCreateKeyTask.h"
#include "../lib/JsonRequest.h"
#include "../Crypto/Passphrase.h"
#include "../controller/User.h"
#include "../controller/UserBackups.h"
#include "../controller/EmailVerificationCode.h"
@ -313,6 +317,65 @@ bool Session::createUser(const std::string& first_name, const std::string& last_
return true;
}
bool Session::createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password)
{
static const char* function_name = "Session::createUserDirect";
auto sm = SessionManager::getInstance();
auto em = ErrorManager::getInstance();
if (!sm->isValid(first_name, VALIDATE_NAME)) {
addError(new Error(gettext("Vorname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false);
return false;
}
if (!sm->isValid(last_name, VALIDATE_NAME)) {
addError(new Error(gettext("Nachname"), gettext("Bitte gebe einen Namen an. Mindestens 3 Zeichen, keines folgender Zeichen <>&;")), false);
return false;
}
if (!sm->isValid(email, VALIDATE_EMAIL)) {
addError(new Error(gettext("E-Mail"), gettext("Bitte gebe eine g&uuml;ltige E-Mail Adresse an.")), false);
return false;
}
if (!sm->checkPwdValidation(password, this)) {
return false;
}
// check if email already exist
auto user = controller::User::create();
if (user->load(email) >= 1) {
addError(new Error(gettext("E-Mail"), gettext("F&uuml;r diese E-Mail Adresse gibt es bereits ein Konto")), false);
return false;
}
mNewUser = controller::User::create(email, first_name, last_name);
auto user_model = mNewUser->getModel();
user_model->insertIntoDB(true);
auto user_id = user_model->getID();
// one retry in case of connection error
if (!user_id) {
user_model->insertIntoDB(true);
auto user_id = user_model->getID();
if (!user_id) {
em->addError(new ParamError(function_name, "error saving new user in db, after one retry with email", email));
em->sendErrorsAsEmail();
addError(new Error(gettext("Server"), gettext("Fehler beim speichen des Kontos bitte versuche es später noch einmal")), false);
return false;
}
}
auto passphrase = Passphrase::generate(&ServerConfig::g_Mnemonic_WordLists[ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES]);
if (passphrase.isNull()) {
em->addError(new ParamError(function_name, "error generating passphrase for", email));
em->sendErrorsAsEmail();
}
auto gradido_key_pair = KeyPairEd25519::create(passphrase);
mNewUser->setGradidoKeyPair(gradido_key_pair);
UniLib::controller::TaskPtr create_authenticated_encrypten_key = new AuthenticatedEncryptionCreateKeyTask(mNewUser, password);
create_authenticated_encrypten_key->scheduleTask(create_authenticated_encrypten_key);
return true;
}
bool Session::ifUserExist(const std::string& email)
{
auto em = ErrorManager::getInstance();

View File

@ -77,6 +77,9 @@ public:
// create User send e-mail activation link
bool createUser(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password);
//! \brief new register function, without showing user pubkeys, using controller/user
bool createUserDirect(const std::string& first_name, const std::string& last_name, const std::string& email, const std::string& password);
// adminRegister without passwort
bool adminCreateUser(const std::string& first_name, const std::string& last_name, const std::string& email);

View File

@ -25,7 +25,7 @@
response.addCookie(session->getLoginCookie());
}
userReturned = session->createUser(
userReturned = session->createUserDirect(
form.get("register-first-name", ""),
form.get("register-last-name", ""),
form.get("register-email", ""),