mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
make it more modular
This commit is contained in:
parent
80cd472597
commit
1aeb506cd3
@ -12,15 +12,8 @@
|
||||
|
||||
using namespace Poco::Data::Keywords;
|
||||
|
||||
|
||||
#define STR_BUFFER_SIZE 25
|
||||
|
||||
static std::vector<Poco::Tuple<int, std::string>> g_specialChars = {
|
||||
{ 0xa4, "auml" },{ 0x84, "Auml" },
|
||||
{ 0xbc, "uuml" },{ 0x9c, "Uuml" },
|
||||
{ 0xb6, "ouml" },{ 0x96, "Ouml" },
|
||||
{ 0x9f, "szlig" }
|
||||
};
|
||||
|
||||
|
||||
KeyPair::KeyPair()
|
||||
|
||||
@ -52,12 +52,19 @@ protected:
|
||||
|
||||
private:
|
||||
// 32 Byte
|
||||
//! \brief ed25519 ref10 private key
|
||||
MemoryBin* mPrivateKey;
|
||||
|
||||
// 64 Byte
|
||||
//! \brief ed25519 libsodium private key
|
||||
MemoryBin* mSodiumSecret;
|
||||
|
||||
// 32 Byte
|
||||
//! \brief ed25519 ref10 public key
|
||||
unsigned char mPublicKey[ed25519_pubkey_SIZE];
|
||||
|
||||
// 32 Byte
|
||||
//! \brief ed25519 libsodium public key
|
||||
unsigned char mSodiumPublic[crypto_sign_PUBLICKEYBYTES];
|
||||
};
|
||||
|
||||
|
||||
240
src/cpp/Crypto/Passphrase.cpp
Normal file
240
src/cpp/Crypto/Passphrase.cpp
Normal file
@ -0,0 +1,240 @@
|
||||
#include "Passphrase.h"
|
||||
|
||||
#include "Poco/Types.h"
|
||||
#include "Poco/Tuple.h"
|
||||
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
|
||||
#include "../ServerConfig.h"
|
||||
|
||||
#define STR_BUFFER_SIZE 25
|
||||
|
||||
static std::vector<Poco::Tuple<int, std::string>> g_specialChars = {
|
||||
{ 0xa4, "auml" },{ 0x84, "Auml" },
|
||||
{ 0xbc, "uuml" },{ 0x9c, "Uuml" },
|
||||
{ 0xb6, "ouml" },{ 0x96, "Ouml" },
|
||||
{ 0x9f, "szlig" }
|
||||
};
|
||||
|
||||
Passphrase::Passphrase(const std::string& passphrase, const Mnemonic* wordSource)
|
||||
: mPassphraseString(filter(passphrase)), mWordSource(wordSource)
|
||||
{
|
||||
memset(mWordIndices, 0, PHRASE_WORD_COUNT * sizeof(Poco::UInt16));
|
||||
}
|
||||
|
||||
|
||||
std::string Passphrase::filter(const std::string& passphrase)
|
||||
{
|
||||
std::string filteredPassphrase;
|
||||
auto passphrase_size = passphrase.size();
|
||||
|
||||
for (int i = 0; i < passphrase_size; i++) {
|
||||
unsigned 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) {
|
||||
// c3 a4 => ä
|
||||
// c3 bc => ü
|
||||
// c3 b6 => ö
|
||||
// c3 84 => Ä
|
||||
// c3 96 => Ö
|
||||
// c3 9c => Ü
|
||||
// c3 9f => ß
|
||||
|
||||
|
||||
|
||||
unsigned char c2 = passphrase.data()[i + 1];
|
||||
bool insertedHtmlEntitie = false;
|
||||
for (auto it = g_specialChars.begin(); it != g_specialChars.end(); it++) {
|
||||
if (c2 == it->get<0>()) {
|
||||
auto htmlEntitie = it->get<1>();
|
||||
filteredPassphrase += "&";
|
||||
filteredPassphrase += htmlEntitie;
|
||||
filteredPassphrase += ";";
|
||||
i++;
|
||||
insertedHtmlEntitie = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (insertedHtmlEntitie) continue;
|
||||
additionalUtfByteCount = 1;
|
||||
}
|
||||
else if ((c & 0x00000800) == 0x00000800) {
|
||||
additionalUtfByteCount = 2;
|
||||
}
|
||||
else if ((c & 0x00010000) == 0x00010000) {
|
||||
additionalUtfByteCount = 3;
|
||||
}
|
||||
for (int j = 0; j <= additionalUtfByteCount; j++) {
|
||||
filteredPassphrase += passphrase.data()[i + j];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 32 = Space
|
||||
// 65 = A
|
||||
// 90 = Z
|
||||
// 97 = a
|
||||
// 122 = z
|
||||
// 59 = ;
|
||||
// 38 = &
|
||||
if (c == 32 || c == 59 || c == 38 ||
|
||||
(c >= 65 && c <= 90) ||
|
||||
(c >= 97 && c <= 122)) {
|
||||
filteredPassphrase += c;
|
||||
}
|
||||
else if (c == '\n' || c == '\r') {
|
||||
filteredPassphrase += ' ';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return filteredPassphrase;
|
||||
}
|
||||
|
||||
Poco::SharedPtr<Passphrase> Passphrase::transform(const Mnemonic* targetWordSource)
|
||||
{
|
||||
/*
|
||||
if (!currentWordSource || !targetWordSource) {
|
||||
return "";
|
||||
}
|
||||
if (targetWordSource == currentWordSource) {
|
||||
return passphrase;
|
||||
}
|
||||
auto word_indices = createWordIndices(passphrase, currentWordSource);
|
||||
if (!word_indices) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return createClearPassphraseFromWordIndices(word_indices, targetWordSource);*/
|
||||
// Poco::SharedPtr<Passphrase> transformedPassphrase = new Passphrase()
|
||||
}
|
||||
|
||||
Poco::SharedPtr<Passphrase> Passphrase::create(const MemoryBin* wordIndices, const Mnemonic* wordSource)
|
||||
{
|
||||
//Poco::SharedPtr<Passphrase> passphrase = new Passphrase()
|
||||
const Poco::UInt64* word_indices_p = (const Poco::UInt64*)wordIndices->data();
|
||||
std::string clearPassphrase;
|
||||
for (int i = 0; i < PHRASE_WORD_COUNT; i++) {
|
||||
if (i * sizeof(Poco::UInt64) >= wordIndices->size()) break;
|
||||
auto word = wordSource->getWord(word_indices_p[i]);
|
||||
if (word) {
|
||||
clearPassphrase += word;
|
||||
clearPassphrase += " ";
|
||||
}
|
||||
}
|
||||
return new Passphrase(clearPassphrase, wordSource);
|
||||
}
|
||||
|
||||
|
||||
bool Passphrase::createWordIndices()
|
||||
{
|
||||
auto er = ErrorManager::getInstance();
|
||||
auto mm = MemoryManager::getInstance();
|
||||
const char* functionName = "Passphrase::createWordIndices";
|
||||
|
||||
if (!mWordSource) {
|
||||
er->addError(new Error(functionName, "word source is empty"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//DHASH key = DRMakeStringHash(passphrase);
|
||||
size_t pass_phrase_size = mPassphraseString.size();
|
||||
|
||||
char acBuffer[STR_BUFFER_SIZE]; memset(acBuffer, 0, STR_BUFFER_SIZE);
|
||||
size_t buffer_cursor = 0;
|
||||
|
||||
// get word indices for hmac key
|
||||
unsigned char word_cursor = 0;
|
||||
for (auto it = mPassphraseString.begin(); it != mPassphraseString.end(); it++)
|
||||
{
|
||||
if (*it == ' ') {
|
||||
if (buffer_cursor < 3) {
|
||||
continue;
|
||||
}
|
||||
if (PHRASE_WORD_COUNT > word_cursor && mWordSource->isWordExist(acBuffer)) {
|
||||
mWordIndices[word_cursor] = mWordSource->getWordIndex(acBuffer);
|
||||
//word_indices_old[word_cursor] = word_source->getWordIndex(acBuffer);
|
||||
}
|
||||
else {
|
||||
er->addError(new ParamError(functionName, "word didn't exist", acBuffer));
|
||||
er->sendErrorsAsEmail();
|
||||
return false;
|
||||
}
|
||||
word_cursor++;
|
||||
memset(acBuffer, 0, STR_BUFFER_SIZE);
|
||||
buffer_cursor = 0;
|
||||
|
||||
}
|
||||
else {
|
||||
acBuffer[buffer_cursor++] = *it;
|
||||
}
|
||||
}
|
||||
if (PHRASE_WORD_COUNT > word_cursor && mWordSource->isWordExist(acBuffer)) {
|
||||
mWordIndices[word_cursor] = mWordSource->getWordIndex(acBuffer);
|
||||
//word_indices_old[word_cursor] = word_source->getWordIndex(acBuffer);
|
||||
word_cursor++;
|
||||
}
|
||||
//printf("word cursor: %d\n", word_cursor);
|
||||
/*if (memcmp(word_indices_p, word_indices_old, word_indices->size()) != 0) {
|
||||
|
||||
printf("not identical\n");
|
||||
memcpy(word_indices_p, word_indices_old, word_indices->size());
|
||||
}*/
|
||||
return true;
|
||||
}
|
||||
|
||||
const Poco::UInt16* Passphrase::getWordIndices()
|
||||
{
|
||||
if (!(mWordIndices[0] | mWordIndices[1] | mWordIndices[2] | mWordIndices[3])) {
|
||||
if (createWordIndices()) return mWordIndices;
|
||||
}
|
||||
return mWordIndices;
|
||||
}
|
||||
|
||||
bool Passphrase::checkIfValid()
|
||||
{
|
||||
std::istringstream iss(mPassphraseString);
|
||||
std::vector<std::string> results(std::istream_iterator<std::string>{iss},
|
||||
std::istream_iterator<std::string>());
|
||||
|
||||
bool existAll = true;
|
||||
for (auto it = results.begin(); it != results.end(); it++) {
|
||||
if (*it == "\0" || *it == "" || it->size() < 3) continue;
|
||||
if (!mWordSource->isWordExist(*it)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
const Mnemonic* Passphrase::detectMnemonic(const std::string& passphrase, const MemoryBin* publicKey /* = nullptr*/)
|
||||
{
|
||||
std::istringstream iss(passphrase);
|
||||
std::vector<std::string> results(std::istream_iterator<std::string>{iss},
|
||||
std::istream_iterator<std::string>());
|
||||
|
||||
for (int i = 0; i < ServerConfig::Mnemonic_Types::MNEMONIC_MAX; i++) {
|
||||
Mnemonic& m = ServerConfig::g_Mnemonic_WordLists[i];
|
||||
bool existAll = true;
|
||||
for (auto it = results.begin(); it != results.end(); it++) {
|
||||
if (*it == "\0" || *it == "" || it->size() < 3) continue;
|
||||
if (!m.isWordExist(*it)) {
|
||||
existAll = false;
|
||||
// leave inner for-loop
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (existAll) {
|
||||
if (publicKey) {
|
||||
|
||||
}
|
||||
return &ServerConfig::g_Mnemonic_WordLists[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
37
src/cpp/Crypto/Passphrase.h
Normal file
37
src/cpp/Crypto/Passphrase.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_CRYPTO_PASSPHRASE_H
|
||||
#define __GRADIDO_LOGIN_SERVER_CRYPTO_PASSPHRASE_H
|
||||
|
||||
//#include <string>
|
||||
#include "mnemonic.h"
|
||||
#include "../SingletonManager/MemoryManager.h"
|
||||
|
||||
class Passphrase
|
||||
{
|
||||
public:
|
||||
Passphrase(const std::string& passphrase, const Mnemonic* wordSource);
|
||||
|
||||
static Poco::SharedPtr<Passphrase> create(const MemoryBin* wordIndices, const Mnemonic* wordSource);
|
||||
static const Mnemonic* detectMnemonic(const std::string& passphrase, const MemoryBin* publicKey = nullptr);
|
||||
|
||||
//! \brief transform passphrase into another language/mnemonic source
|
||||
Poco::SharedPtr<Passphrase> transform(const Mnemonic* targetWordSource);
|
||||
|
||||
//! \brief replace utf8 characters with html special character encoding
|
||||
//!
|
||||
//! TODO: add more utf8 chars for other languages as they needed
|
||||
static std::string filter(const std::string& passphrase);
|
||||
|
||||
bool checkIfValid();
|
||||
|
||||
const Poco::UInt16* getWordIndices();
|
||||
|
||||
protected:
|
||||
bool createWordIndices();
|
||||
|
||||
std::string mPassphraseString;
|
||||
const Mnemonic* mWordSource;
|
||||
Poco::UInt16 mWordIndices[PHRASE_WORD_COUNT];
|
||||
};
|
||||
|
||||
#endif // __GRADIDO_LOGIN_SERVER_CRYPTO_PASSPHRASE
|
||||
|
||||
@ -39,6 +39,7 @@ public:
|
||||
inline operator size_t() const { return static_cast<size_t>(mSize); }
|
||||
|
||||
inline unsigned char* data() { return mData; }
|
||||
inline const unsigned char* data() const { return mData; }
|
||||
|
||||
protected:
|
||||
MemoryBin(Poco::UInt32 size);
|
||||
|
||||
@ -73,8 +73,8 @@ public:
|
||||
inline Poco::AutoPtr<controller::User> getNewUser() { return mNewUser; }
|
||||
|
||||
// ---------------- User functions ----------------------------
|
||||
// TODO: automatic redirect after some time, median profiled time for register
|
||||
// TODO: register state: written into db, mails sended, update state only if new state is higher as old state
|
||||
// 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);
|
||||
|
||||
// adminRegister without passwort
|
||||
|
||||
@ -33,6 +33,7 @@
|
||||
{
|
||||
switch(type) {
|
||||
case ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER: return "de";
|
||||
case ServerConfig::MNEMONIC_GRADIDO_BOOK_GERMAN_RANDOM_ORDER_FIXED_CASES: return "de";
|
||||
case ServerConfig::MNEMONIC_BIP0039_SORTED_ORDER: return "en";
|
||||
}
|
||||
return "unknown";
|
||||
|
||||
85
src/cpsp/registerDirect.cpsp
Normal file
85
src/cpsp/registerDirect.cpsp
Normal file
@ -0,0 +1,85 @@
|
||||
<%@ page class="RegisterDirectPage" %>
|
||||
<%@ page form="true" %>
|
||||
<%@ page compressed="true" %>
|
||||
<%@ page baseClass="PageRequestMessagedHandler" %>
|
||||
<%@ header include="PageRequestMessagedHandler.h" %>
|
||||
<%!
|
||||
#include "../SingletonManager/SessionManager.h"
|
||||
#include "Poco/Net/HTTPCookie.h"
|
||||
%>
|
||||
<%%
|
||||
const char* pageName = "Registrieren";
|
||||
auto sm = SessionManager::getInstance();
|
||||
|
||||
bool userReturned = false;
|
||||
|
||||
if(!form.empty()) {
|
||||
if(form.get("register-password2", "") != form.get("register-password", "")) {
|
||||
addError(new Error("Passwort", "Passwörter sind nicht identisch."), false);
|
||||
} else {
|
||||
auto session = sm->getSession(request);
|
||||
if(!session) {
|
||||
session = sm->getNewSession();
|
||||
auto user_host = request.clientAddress().host();
|
||||
session->setClientIp(user_host);
|
||||
response.addCookie(session->getLoginCookie());
|
||||
}
|
||||
|
||||
userReturned = session->createUser(
|
||||
form.get("register-first-name", ""),
|
||||
form.get("register-last-name", ""),
|
||||
form.get("register-email", ""),
|
||||
form.get("register-password", "")
|
||||
);
|
||||
getErrors(session);
|
||||
}
|
||||
|
||||
} else {
|
||||
// on enter login page with empty form
|
||||
// remove old cookies if exist
|
||||
sm->deleteLoginCookies(request, response);
|
||||
}
|
||||
%><%@ include file="header_old.cpsp" %>
|
||||
<div class="grd_container">
|
||||
<h1>Einen neuen Account anlegen</h1>
|
||||
<%= getErrorsHtml() %>
|
||||
<% if(!form.empty() && userReturned) {%>
|
||||
<div class="grd_text-max-width">
|
||||
<div class="grd_text">
|
||||
Deine Anmeldung wird verarbeitet und es wird dir eine E-Mail zugeschickt.
|
||||
Wenn sie da ist, befolge ihren Anweisungen.
|
||||
</div>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<form method="POST">
|
||||
|
||||
<fieldset class="grd_container_small">
|
||||
<legend>Account anlegen</legend>
|
||||
<p>Bitte gebe deine Daten um einen Account anzulegen</p>
|
||||
<p class="grd_small">
|
||||
<label for="register-first-name">Vorname</label>
|
||||
<input id="register-first-name" type="text" name="register-first-name" value="<%= !form.empty() ? form.get("register-first-name") : "" %>"/>
|
||||
</p>
|
||||
<p class="grd_small">
|
||||
<label for="register-last-name">Nachname</label>
|
||||
<input id="register-last-name" type="text" name="register-last-name" value="<%= !form.empty() ? form.get("register-last-name") : "" %>"/>
|
||||
</p>
|
||||
<p class="grd_small">
|
||||
<label for="register-email">E-Mail</label>
|
||||
<input id="register-email" type="email" name="register-email" value="<%= !form.empty() ? form.get("register-email") : "" %>"/>
|
||||
</p>
|
||||
<p class="grd_small">
|
||||
<label for="register-password">Passwort</label>
|
||||
<input id="register-password" type="password" name="register-password"/>
|
||||
</p>
|
||||
<p class="grd_small">
|
||||
<label for="register-password">Passwort Bestätigung</label>
|
||||
<input id="register-password2" type="password" name="register-password2"/>
|
||||
</p>
|
||||
</fieldset>
|
||||
<input class="grd-form-bn grd-form-bn-succeed" type="submit" name="submit" value="Anmelden">
|
||||
|
||||
</form>
|
||||
<% } %>
|
||||
</div>
|
||||
<%@ include file="footer.cpsp" %>
|
||||
Loading…
x
Reference in New Issue
Block a user