Если есть возможность, то нужно регистрировать пользователя МС при запуске МС с указанными в конфиге bitcoin и PGP ключами.
This commit is contained in:
@@ -90,14 +90,15 @@ namespace Apostol {
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebSocketModule::InitServerList() {
|
||||
m_DefaultServer.Value().Name() = m_DefaultServer.Name();
|
||||
m_DefaultServer.Value().PGP().Name = "PUBLIC";
|
||||
m_DefaultServer.Value().PGP().Add(CKeyContext(CString("PUBLIC"), CString()));
|
||||
m_DefaultServer.Value().PGP().Add(CKeyContext(m_DefaultServer.Name(), CString()));
|
||||
|
||||
if (m_Servers.Count() == 0) {
|
||||
#ifdef _DEBUG
|
||||
int index = m_Servers.AddPair(BPS_BM_DEBUG_ADDRESS, CClientContext(CLocation(BPS_SERVER_URL)));
|
||||
m_Servers[index].Value().Name() = m_Servers[index].Name();
|
||||
m_Servers[index].Value().PGP().Name = "PUBLIC";
|
||||
int index = m_Servers.AddPair(BPS_BM_DEBUG_ADDRESS, CClientContext(BPS_BM_DEBUG_ADDRESS, CLocation(BPS_SERVER_URL)));
|
||||
auto &Keys = m_Servers[index].Value().PGP();
|
||||
Keys.Add(CKeyContext(CString("PUBLIC"), CString()));
|
||||
Keys.Add(CKeyContext(CString(BPS_BM_DEBUG_ADDRESS), CString()));
|
||||
#else
|
||||
m_Servers.Add(m_DefaultServer);
|
||||
#endif
|
||||
@@ -116,14 +117,23 @@ namespace Apostol {
|
||||
CStringPairs::ConstEnumerator em(ServerList);
|
||||
while (em.MoveNext()) {
|
||||
const auto &caCurrent = em.Current();
|
||||
#ifndef _DEBUG
|
||||
if (caCurrent.Name() == BPS_BM_DEBUG_ADDRESS)
|
||||
continue;
|
||||
#endif
|
||||
index = m_Servers.IndexOfName(caCurrent.Name());
|
||||
if (index == -1) {
|
||||
index = m_Servers.AddPair(caCurrent.Name(), CClientContext(CLocation(caCurrent.Value())));
|
||||
index = m_Servers.AddPair(caCurrent.Name(), CClientContext(caCurrent.Name(), CLocation(caCurrent.Value())));
|
||||
auto &Context = m_Servers[index].Value();
|
||||
Context.PGP().Add(CKeyContext(CString("PUBLIC"), Key));
|
||||
Context.PGP().Add(CKeyContext(caCurrent.Name(), CString()));
|
||||
} else {
|
||||
auto &Context = m_Servers[index].Value();
|
||||
Context.URL() = caCurrent.Value();
|
||||
Context.PGP().First().Key = Key;
|
||||
}
|
||||
|
||||
auto &Context = m_Servers[index].Value();
|
||||
Context.Name() = caCurrent.Name();
|
||||
Context.PGP().Name = "PUBLIC";
|
||||
Context.PGP().Key = Key;
|
||||
Context.BTCKeys() = Keys;
|
||||
|
||||
UpdateOAuth2(Context, m_OAuth2.Object());
|
||||
@@ -471,6 +481,37 @@ namespace Apostol {
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool CWebSocketModule::CheckVerifyPGPSignature(int VerifyPGPSignature, CString &Message) {
|
||||
if (VerifyPGPSignature == -2) {
|
||||
Message = "PGP public key is not meaningful.";
|
||||
} else if (VerifyPGPSignature == -1) {
|
||||
Message = "PGP signature not valid.";
|
||||
} else if (VerifyPGPSignature == 0) {
|
||||
Message = "PGP signature not found.";
|
||||
} else if (VerifyPGPSignature > 1) {
|
||||
Message = "PGP signature status: Unknown.";
|
||||
}
|
||||
return VerifyPGPSignature == 1;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
int CWebSocketModule::VerifyPGPSignature(const CString &Text, const CString &Key, CString &Message) {
|
||||
const OpenPGP::Key signer(Key.c_str());
|
||||
const OpenPGP::CleartextSignature cleartext(Text.c_str());
|
||||
|
||||
if (!cleartext.meaningful())
|
||||
return -2;
|
||||
|
||||
const int verified = OpenPGP::Verify::cleartext_signature(signer, cleartext);
|
||||
|
||||
if (verified == 1) {
|
||||
Message = cleartext.get_message().c_str();
|
||||
}
|
||||
|
||||
return verified;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool CWebSocketModule::FindURLInLine(const CString &Line, CStringList &List) {
|
||||
CString URL;
|
||||
|
||||
@@ -857,12 +898,26 @@ namespace Apostol {
|
||||
auto pContext = pClient->Context();
|
||||
chASSERT(pContext);
|
||||
|
||||
pContext->PGP().StatusTime = Now();
|
||||
pContext->PGP().Status = CKeyContext::ksSuccess;
|
||||
pContext->PGP().RunTime = GetRandomDate(10 * 60, m_SyncPeriod * 60, pContext->PGP().StatusTime); // 10..m_SyncPeriod min
|
||||
auto &Keys = pContext->PGP();
|
||||
|
||||
if (Response.Payload.HasOwnProperty("data")) {
|
||||
UpdateServerList(Response.Payload["data"].AsString());
|
||||
for (int i = 0; i < Keys.Count(); i++ ) {
|
||||
auto &Key = Keys[i];
|
||||
|
||||
Key.StatusTime = Now();
|
||||
Key.Status = CKeyContext::ksSuccess;
|
||||
Key.RunTime = GetRandomDate(10 * 60, m_SyncPeriod * 60, Key.StatusTime); // 10..m_SyncPeriod min
|
||||
|
||||
if (Response.Payload.HasOwnProperty("data")) {
|
||||
if (Response.Payload.HasOwnProperty("code")) {
|
||||
if (Response.Payload["code"].AsString() == Key.Name) {
|
||||
if (Key.Name == "PUBLIC") {
|
||||
UpdateServerList(Response.Payload["data"].AsString());
|
||||
} else {
|
||||
Key.Key = Response.Payload["data"].AsString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
@@ -1527,7 +1582,79 @@ namespace Apostol {
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void CWebSocketModule::DoSignature(CHTTPServerConnection *AConnection) {
|
||||
auto pRequest = AConnection->Request();
|
||||
auto pReply = AConnection->Reply();
|
||||
|
||||
if (pRequest->Content.IsEmpty()) {
|
||||
AConnection->SendStockReply(CHTTPReply::no_content);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto &caServerParam = pRequest->Params["server"];
|
||||
|
||||
int index = CurrentContextIndex(caServerParam);
|
||||
if (index == -1) {
|
||||
throw Delphi::Exception::Exception(NOT_FOUND_ACTIVE_CONNECTION);
|
||||
}
|
||||
|
||||
const auto &caContext = m_Servers[index].Value();
|
||||
auto &Keys = caContext.PGP();
|
||||
|
||||
index = 0;
|
||||
while (index < Keys.Count() && Keys[index].Name != caContext.Name()) {
|
||||
index++;
|
||||
}
|
||||
|
||||
if (index == Keys.Count())
|
||||
throw ExceptionFrm("PGP key not found.");
|
||||
|
||||
const auto& caServerKey = Keys[index].Key;
|
||||
|
||||
if (caServerKey.IsEmpty())
|
||||
throw ExceptionFrm("Server PGP key not added.");
|
||||
|
||||
CString message;
|
||||
CJSON Json(jvtObject);
|
||||
|
||||
const auto& caContentType = pRequest->Headers["content-type"];
|
||||
|
||||
if (caContentType.Find("application/x-www-form-urlencoded") == 0) {
|
||||
const CStringList &FormData = pRequest->FormData;
|
||||
|
||||
const auto& caClearText = FormData["message"];
|
||||
CheckKeyForNull("message", caClearText.c_str());
|
||||
|
||||
const auto bVerified = CheckVerifyPGPSignature(VerifyPGPSignature(caClearText, caServerKey, message), message);
|
||||
Json.Object().AddPair("verified", bVerified);
|
||||
} else if (caContentType.Find("multipart/form-data") == 0) {
|
||||
CFormData FormData;
|
||||
CHTTPRequestParser::ParseFormData(pRequest, FormData);
|
||||
|
||||
const auto& caClearText = FormData.Data("message");
|
||||
CheckKeyForNull("message", caClearText.c_str());
|
||||
|
||||
const auto bVerified = CheckVerifyPGPSignature(VerifyPGPSignature(caClearText, caServerKey, message), message);
|
||||
Json.Object().AddPair("verified", bVerified);
|
||||
} else if (caContentType.Find("application/json") == 0) {
|
||||
const CJSON jsonData(pRequest->Content);
|
||||
|
||||
const auto& caClearText = jsonData["message"].AsString();
|
||||
CheckKeyForNull("message", caClearText.c_str());
|
||||
|
||||
const auto bVerified = CheckVerifyPGPSignature(VerifyPGPSignature(caClearText, caServerKey, message), message);
|
||||
Json.Object().AddPair("verified", bVerified);
|
||||
} else {
|
||||
const auto& caClearText = pRequest->Content;
|
||||
const auto bVerified = CheckVerifyPGPSignature(VerifyPGPSignature(caClearText, caServerKey, message), message);
|
||||
Json.Object().AddPair("verified", bVerified);
|
||||
}
|
||||
|
||||
Json.Object().AddPair("message", message);
|
||||
|
||||
AConnection->CloseConnection(true);
|
||||
pReply->Content << Json;
|
||||
|
||||
AConnection->SendReply(CHTTPReply::ok);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user