bool OTAccount::SaveContractWallet(OTString & strContents) const { const OTString strAccountID(GetPurportedAccountID()), strServerID(GetPurportedServerID()), strUserID(GetUserID()), strAssetTypeID(m_AcctAssetTypeID); OTString strAcctType; TranslateAccountTypeToString(m_AcctType, strAcctType); OTASCIIArmor ascName; if (m_strName.Exists()) // name is in the clear in memory, and base64 in storage. { ascName.SetString(m_strName, false); // linebreaks == false } strContents.Concatenate("<!-- Last retrieved balance: %s on date: %s -->\n" "<!-- Account type: %s --><assetAccount name=\"%s\"\n" " accountID=\"%s\"\n" " userID=\"%s\"\n" " serverID=\"%s\" />\n" "<!-- assetTypeID: %s -->\n\n", m_BalanceAmount.Get(), m_BalanceDate.Get(), strAcctType.Get(), m_strName.Exists() ? ascName.Get() : "", strAccountID.Get(), strUserID.Get(), strServerID.Get(), strAssetTypeID.Get()); return true; }
void OTSubkey::UpdateContents() { m_xmlUnsigned.Release(); Tag tag("keyCredential"); // a hash of the nymIDSource tag.add_attribute("nymID", GetNymID().Get()); // Hash of the master credential that signed this subcredential. tag.add_attribute("masterID", GetMasterCredID().Get()); if (GetNymIDSource().Exists()) { OTASCIIArmor ascSource; // A nym should always verify through its own // source. (Whatever that may be.) ascSource.SetString(GetNymIDSource()); tag.add_tag("nymIDSource", ascSource.Get()); } // MASTER-SIGNED INFO if (OTSubcredential::credMasterSigned == m_StoreAs || OTSubcredential::credPrivateInfo == m_StoreAs) { UpdatePublicContentsToTag(tag); } // PUBLIC INFO (signed by subkey, contains master signed info.) if (OTSubcredential::credPublicInfo == m_StoreAs || OTSubcredential::credPrivateInfo == m_StoreAs) { // GetMasterSigned() returns the contract // containing the master-signed contents // from the above block. OTASCIIArmor ascMasterSigned(GetMasterSigned()); // Contains all the public info, signed by the master key. // Packaged up here inside a final, subkey-signed credential. tag.add_tag("masterSigned", ascMasterSigned.Get()); } // PRIVATE INFO // // If we're saving the private credential info... if (OTSubcredential::credPrivateInfo == m_StoreAs) { UpdatePublicCredentialToTag(tag); UpdatePrivateContentsToTag(tag); } // <=== SET IT BACK TO DEFAULT BEHAVIOR. Any other state // processes ONCE, and then goes back to this again. m_StoreAs = OTSubcredential::credPrivateInfo; std::string str_result; tag.output(str_result); m_xmlUnsigned.Concatenate("%s", str_result.c_str()); }
// SignContract will call this function at the right time. void OTLedger::UpdateContents() // Before transmission or serialization, this is where the ledger saves its contents { // Notice I use the PURPORTED Account ID and Server ID to create the output. That's because // I don't want to inadvertantly substitute the real ID for a bad one and then sign it. // So if there's a bad one in there when I read it, THAT's the one that I write as well! OTString strType, strLedgerAcctID(GetPurportedAccountID()), strLedgerAcctServerID(GetPurportedServerID()), strUserID(GetUserID()); switch (m_Type) { case OTLedger::message: strType.Set("message"); break; case OTLedger::inbox: strType.Set("inbox"); break; case OTLedger::outbox: strType.Set("outbox"); break; default: strType.Set("error-unknown"); break; } // I release this because I'm about to repopulate it. m_xmlUnsigned.Release(); // m_xmlUnsigned.Concatenate("<?xml version=\"%s\"?>\n\n", "1.0"); m_xmlUnsigned.Concatenate("<accountLedger version=\"%s\"\n type=\"%s\"\n accountID=\"%s\"\n userID=\"%s\"\n" "serverID=\"%s\" >\n\n", m_strVersion.Get(), strType.Get(), strLedgerAcctID.Get(), strUserID.Get(), strLedgerAcctServerID.Get()); // loop through the transactions and print them out here. OTTransaction * pTransaction = NULL; for (mapOfTransactions::iterator ii = m_mapTransactions.begin(); ii != m_mapTransactions.end(); ++ii) { if ((pTransaction = (*ii).second)) // if pointer not null { OTString strTransaction; pTransaction->SaveContract(strTransaction); OTASCIIArmor ascTransaction; ascTransaction.SetString(strTransaction, true); // linebreaks = true m_xmlUnsigned.Concatenate("<transaction>\n%s</transaction>\n\n", ascTransaction.Get()); } } m_xmlUnsigned.Concatenate("</accountLedger>\n"); }
void OTSubkey::UpdateContents() { m_xmlUnsigned.Release(); m_xmlUnsigned.Concatenate("<keyCredential nymID=\"%s\"\n" // a hash of the nymIDSource " masterCredentialID=\"%s\" >\n\n", // Hash of the master credential that signed this subcredential. this->GetNymID().Get(), this->GetMasterCredID().Get()); if (this->GetNymIDSource().Exists()) { OTASCIIArmor ascSource; ascSource.SetString(this->GetNymIDSource()); // A nym should always verify through its own source. (Whatever that may be.) m_xmlUnsigned.Concatenate("<nymIDSource>\n%s</nymIDSource>\n\n", ascSource.Get()); } // -------------------------------------------- // MASTER-SIGNED INFO // if ((OTSubcredential::credMasterSigned == m_StoreAs) || // MASTER-SIGNED INFO (OTSubcredential::credPrivateInfo == m_StoreAs)) { // -------------------------------------------- this->UpdateMasterPublicToString(m_xmlUnsigned); // -------------------------------------------- this->UpdatePublicContentsToString(m_xmlUnsigned); } // -------------------------------------------- // PUBLIC INFO // if ((OTSubcredential::credPublicInfo == m_StoreAs) || // PUBLIC INFO (signed by subkey, contains master signed info.) (OTSubcredential::credPrivateInfo == m_StoreAs)) { OTASCIIArmor ascMasterSigned(this->GetMasterSigned()); // GetMasterSigned() returns the contract containing the master-signed contents from the above block. m_xmlUnsigned.Concatenate("<masterSigned>\n%s</masterSigned>\n\n", // Contains all the public info, signed by the master key. ascMasterSigned.Get()); // Packaged up here inside a final, subkey-signed credential. } // ------------------------------------------------- // PRIVATE INFO // // If we're saving the private credential info... // if (OTSubcredential::credPrivateInfo == m_StoreAs) // PRIVATE INFO { this->UpdatePublicCredentialToString(m_xmlUnsigned); // ------------------------------------- this->UpdatePrivateContentsToString(m_xmlUnsigned); } // ------------------------------------------------- m_xmlUnsigned.Concatenate("</keyCredential>\n"); // -------------------------------------------- m_StoreAs = OTSubcredential::credPrivateInfo; // <=== SET IT BACK TO DEFAULT BEHAVIOR. Any other state processes ONCE, and then goes back to this again. }
void OTClause::Serialize(Tag& parent) const { OTASCIIArmor ascCode; if (m_strCode.GetLength() > 2) ascCode.SetString(m_strCode); else otErr << "Empty script code in OTClause::Serialize()\n"; TagPtr pTag(new Tag("clause", ascCode.Get())); pTag->add_attribute("name", m_strName.Get()); parent.add_tag(pTag); }
bool OTServerContract::SaveContractWallet(OTString & strContents) const { const OTString strID(m_ID); OTASCIIArmor ascName; if (m_strName.Exists()) // name is in the clear in memory, and base64 in storage. { ascName.SetString(m_strName, false); // linebreaks == false } strContents.Concatenate("<notaryProvider name=\"%s\"\n" " serverID=\"%s\" />\n\n", m_strName.Exists() ? ascName.Get() : "", strID.Get()); return true; }
void OTMasterkey::UpdateContents() { m_xmlUnsigned.Release(); Tag tag("masterCredential"); // a hash of the nymIDSource tag.add_attribute("nymID", GetNymID().Get()); if (GetNymIDSource().Exists()) { OTASCIIArmor ascSource; ascSource.SetString(GetNymIDSource()); // A nym should always // verify through its own // source. (Whatever that // may be.) tag.add_tag("nymIDSource", ascSource.Get()); } // PUBLIC INFO // // if (OTSubcredential::credPublicInfo == m_StoreAs) // PUBLIC INFO // (Always save this in every state.) { UpdatePublicContentsToTag(tag); } // PRIVATE INFO // // If we're saving the private credential info... // if (OTSubcredential::credPrivateInfo == m_StoreAs) // PRIVATE INFO { UpdatePublicCredentialToTag(tag); UpdatePrivateContentsToTag(tag); } // ------------------------------------------------- std::string str_result; tag.output(str_result); m_xmlUnsigned.Concatenate("%s", str_result.c_str()); m_StoreAs = OTSubcredential::credPrivateInfo; // <=== SET IT BACK TO DEFAULT // BEHAVIOR. Any other state // processes ONCE, and then // goes back to this again. }
bool AssetContract::SaveContractWallet(Tag& parent) const { const String strID(m_ID); // Name is in the clear in memory, // and base64 in storage. OTASCIIArmor ascName; if (m_strName.Exists()) { ascName.SetString(m_strName, false); // linebreaks == false } TagPtr pTag(new Tag("assetType")); pTag->add_attribute("name", m_strName.Exists() ? ascName.Get() : ""); pTag->add_attribute("instrumentDefinitionID", strID.Get()); parent.add_tag(pTag); return true; }
// Envelope copied into payload to prepare for sending. bool OTPayload::SetEnvelope(const OTEnvelope & theEnvelope) { OTASCIIArmor theArmor; if (theEnvelope.GetAsciiArmoredData(theArmor)) { uint32_t lSize = theArmor.GetLength()+1; //+1 for the null terminater if (theArmor.GetLength()) { SetPayloadSize(lSize + 1); // +1 for the checksum byte. // Copy it in. memcpy((void *)GetPointer(), theArmor.Get(), lSize); // Add the checksum, success. AppendChecksum( (OT_BYTE*)GetPointer(), lSize ); return true; } } return false; }
void OTMasterkey::UpdateContents() { m_xmlUnsigned.Release(); m_xmlUnsigned.Concatenate("<masterCredential nymID=\"%s\" >\n\n", // a hash of the nymIDSource this->GetNymID().Get()); if (this->GetNymIDSource().Exists()) { OTASCIIArmor ascSource; ascSource.SetString(this->GetNymIDSource()); // A nym should always verify through its own source. (Whatever that may be.) m_xmlUnsigned.Concatenate("<nymIDSource>\n%s</nymIDSource>\n\n", ascSource.Get()); } // -------------------------------------------- // PUBLIC INFO // // if (OTSubcredential::credPublicInfo == m_StoreAs) // PUBLIC INFO (Always save this in every state.) { this->UpdatePublicContentsToString(m_xmlUnsigned); } // ------------------------------------------------- // PRIVATE INFO // // If we're saving the private credential info... // if (OTSubcredential::credPrivateInfo == m_StoreAs) // PRIVATE INFO { this->UpdatePublicCredentialToString(m_xmlUnsigned); // ------------------------------------- this->UpdatePrivateContentsToString(m_xmlUnsigned); } // ------------------------------------------------- m_xmlUnsigned.Concatenate("</masterCredential>\n"); // -------------------------------------------- m_StoreAs = OTSubcredential::credPrivateInfo; // <=== SET IT BACK TO DEFAULT BEHAVIOR. Any other state processes ONCE, and then goes back to this again. }
bool OTSocket_ZMQ_4::Send(const OTASCIIArmor & ascEnvelope) { if (!m_bInitialized) { OT_FAIL; } if (0 >= ascEnvelope.GetLength()) { OTLog::vError("%s: Error: %s is zero length!\n", __FUNCTION__, "ascEnvelope"); OT_FAIL; } m_ascLastMsgSent.Set(ascEnvelope); // In case we need to re-send. if (!m_HasContext) { OT_FAIL; } if (NULL == m_pzmq->context_zmq) { OTLog::vError("%s: Error: %s must exist to Send!\n", __FUNCTION__, "m_pzmq->context_zmq"); OT_FAIL; } if (!m_bConnected && !m_bListening) return false; if (m_bConnected && m_bListening) return false; if (NULL == m_pzmq->socket_zmq) { OTLog::vError("%s: Error: %s must exist to Send!\n", __FUNCTION__, "m_pzmq->socket_zmq"); OT_FAIL; } // ----------------------------------- const int64_t lLatencySendMilliSec = m_lLatencySendMs; zmq::message_t zmq_message(ascEnvelope.GetLength()); memcpy((void*)zmq_message.data(), ascEnvelope.Get(), ascEnvelope.GetLength()); bool bSuccessSending = false; if (m_bIsBlocking) { try { bSuccessSending = m_pzmq->socket_zmq->send(zmq_message); // Blocking. } catch (std::exception& e) { OTLog::vError("%s: Exception Caught: %s \n", __FUNCTION__, e.what()); OT_FAIL; } } else // not blocking { int32_t nSendTries = m_nLatencySendNoTries; int64_t lDoubling = lLatencySendMilliSec; bool bKeepTrying = true; while (bKeepTrying && (nSendTries > 0)) { zmq::pollitem_t items[] = { { (*m_pzmq->socket_zmq), 0, ZMQ_POLLOUT, 0 } }; int nPoll = 0; try { nPoll = zmq::poll(&items[0], 1, static_cast<long>(lDoubling)); // ZMQ_POLLOUT, 1 item, timeout (milliseconds) } catch (std::exception& e) { OTLog::vError("%s: Exception Caught: %s \n", __FUNCTION__, e.what()); OT_FAIL; } lDoubling *= 2; if (items[0].revents & ZMQ_POLLOUT) { try { bSuccessSending = m_pzmq->socket_zmq->send(zmq_message, ZMQ_NOBLOCK); // <=========== SEND =============== } catch (std::exception& e) { OTLog::vError("%s: Exception Caught: %s \n", __FUNCTION__, e.what()); OT_FAIL; } OTLog::SleepMilliseconds(1); if (!bSuccessSending) { if (false == HandleSendingError()) bKeepTrying = false; } else break; // (Success -- we're done in this loop.) } else if ((-1) == nPoll) // error. { if (false == HandlePollingError()) bKeepTrying = false; } --nSendTries; } } /* Normally, we try to send... If the send fails, we wait X ms and then try again (Y times). BUT -- what if the failure was an errno==EAGAIN ? In that case, it's not a REAL failure, but rather, a "failure right now, try again in a sec." */ // *********************************** if (bSuccessSending) OTLog::SleepMilliseconds(m_lLatencyDelayAfter > 0 ? m_lLatencyDelayAfter : 1); return bSuccessSending; }
bool MainFile::SaveMainFileToString(String& strMainFile) { Tag tag("notaryServer"); // We're on version 2.0 since adding the master key. tag.add_attribute("version", OTCachedKey::It()->IsGenerated() ? "2.0" : version_); tag.add_attribute("notaryID", server_->m_strNotaryID.Get()); tag.add_attribute("serverNymID", server_->m_strServerNymID.Get()); tag.add_attribute("transactionNum", formatLong(server_->transactor_.transactionNumber())); if (OTCachedKey::It()->IsGenerated()) // If it exists, then serialize it. { OTASCIIArmor ascMasterContents; if (OTCachedKey::It()->SerializeTo(ascMasterContents)) { tag.add_tag("cachedKey", ascMasterContents.Get()); } else Log::vError( "%s: Failed trying to write master key to notary file.\n", __FUNCTION__); } for (auto& it : server_->transactor_.contractsMap_) { Contract* pContract = it.second; OT_ASSERT_MSG(nullptr != pContract, "nullptr contract pointer in MainFile::SaveMainFile.\n"); // This is like the Server's wallet. pContract->SaveContractWallet(tag); } // Save the basket account information for (auto& it : server_->transactor_.idToBasketMap_) { String strBasketID = it.first.c_str(); String strBasketAcctID = it.second.c_str(); const Identifier BASKET_ACCOUNT_ID(strBasketAcctID); Identifier BASKET_CONTRACT_ID; bool bContractID = server_->transactor_.lookupBasketContractIDByAccountID( BASKET_ACCOUNT_ID, BASKET_CONTRACT_ID); if (!bContractID) { Log::vError("%s: Error: Missing Contract ID for basket ID %s\n", __FUNCTION__, strBasketID.Get()); break; } String strBasketContractID(BASKET_CONTRACT_ID); TagPtr pTag(new Tag("basketInfo")); pTag->add_attribute("basketID", strBasketID.Get()); pTag->add_attribute("basketAcctID", strBasketAcctID.Get()); pTag->add_attribute("basketContractID", strBasketContractID.Get()); tag.add_tag(pTag); } server_->transactor_.voucherAccounts_.Serialize(tag); std::string str_result; tag.output(str_result); strMainFile.Concatenate("%s", str_result.c_str()); return true; }
bool MainFile::LoadMainFile(bool bReadOnly) { if (!OTDB::Exists(".", server_->m_strWalletFilename.Get())) { Log::vError("%s: Error finding file: %s\n", __FUNCTION__, server_->m_strWalletFilename.Get()); return false; } String strFileContents(OTDB::QueryPlainString( ".", server_->m_strWalletFilename.Get())); // <=== LOADING FROM DATA STORE. if (!strFileContents.Exists()) { Log::vError("%s: Unable to read main file: %s\n", __FUNCTION__, server_->m_strWalletFilename.Get()); return false; } bool bNeedToSaveAgain = false; bool bFailure = false; { OTStringXML xmlFileContents(strFileContents); if (false == xmlFileContents.DecodeIfArmored()) // bEscapedIsAllowed=true by // default. { Log::vError("%s: Notary server file apparently was encoded and " "then failed decoding. Filename: %s \n" "Contents: \n%s\n", __FUNCTION__, server_->m_strWalletFilename.Get(), strFileContents.Get()); return false; } irr::io::IrrXMLReader* xml = irr::io::createIrrXMLReader(xmlFileContents); std::unique_ptr<irr::io::IrrXMLReader> theXMLGuardian(xml); while (xml && xml->read()) { // strings for storing the data that we want to read out of the file String AssetName; String InstrumentDefinitionID; const String strNodeName(xml->getNodeName()); switch (xml->getNodeType()) { case irr::io::EXN_TEXT: // in this xml file, the only text which occurs is the // messageText // messageText = xml->getNodeData(); break; case irr::io::EXN_ELEMENT: { if (strNodeName.Compare("notaryServer")) { version_ = xml->getAttributeValue("version"); server_->m_strNotaryID = xml->getAttributeValue("notaryID"); server_->m_strServerNymID = xml->getAttributeValue("serverNymID"); String strTransactionNumber; // The server issues // transaction numbers and // stores the counter here // for the latest one. strTransactionNumber = xml->getAttributeValue("transactionNum"); server_->transactor_.transactionNumber( strTransactionNumber.ToLong()); Log::vOutput( 0, "\nLoading Open Transactions server. File version: %s\n" " Last Issued Transaction Number: %" PRId64 "\n Notary ID: " " %s\n Server Nym ID: %s\n", version_.c_str(), server_->transactor_.transactionNumber(), server_->m_strNotaryID.Get(), server_->m_strServerNymID.Get()); } // todo in the future just remove masterkey. I'm leaving it for // now so people's // data files can get converted over. After a while just remove // it. // else if (strNodeName.Compare("masterKey") || strNodeName.Compare("cachedKey")) { OTASCIIArmor ascCachedKey; if (Contract::LoadEncodedTextField(xml, ascCachedKey)) { // We successfully loaded the masterKey from file, so // let's SET it // as the master key globally... // OTCachedKey::It()->SetCachedKey(ascCachedKey); if (!OTCachedKey::It()->HasHashCheck()) { OTPassword tempPassword; tempPassword.zeroMemory(); std::shared_ptr<OTCachedKey> sharedPtr( OTCachedKey::It()); bNeedToSaveAgain = sharedPtr->GetMasterPassword( sharedPtr, tempPassword, "We do not have a check hash yet for this " "password, " "please enter your password", true); } } Log::vOutput(0, "\nLoading cachedKey:\n%s\n", ascCachedKey.Get()); // // It's only here, AFTER the master key has been loaded, // that we can // go ahead and load the server user, the server contract, // cron, etc. // (It wasn't that way in version 1, before we had master // keys.) // // This is, for example, 2.0 if (version_ != "1.0") { if (!LoadServerUserAndContract()) { Log::vError("%s: Failed calling " "LoadServerUserAndContract.\n", __FUNCTION__); bFailure = true; } } } else if (strNodeName.Compare("accountList")) // the voucher // reserve // account IDs. { const String strAcctType = xml->getAttributeValue("type"); const String strAcctCount = xml->getAttributeValue("count"); if ((-1) == server_->transactor_.voucherAccounts_.ReadFromXMLNode( xml, strAcctType, strAcctCount)) Log::vError("%s: Error loading voucher accountList.\n", __FUNCTION__); } else if (strNodeName.Compare("basketInfo")) { String strBasketID = xml->getAttributeValue("basketID"); String strBasketAcctID = xml->getAttributeValue("basketAcctID"); String strBasketContractID = xml->getAttributeValue("basketContractID"); const Identifier BASKET_ID(strBasketID), BASKET_ACCT_ID(strBasketAcctID), BASKET_CONTRACT_ID(strBasketContractID); if (server_->transactor_.addBasketAccountID( BASKET_ID, BASKET_ACCT_ID, BASKET_CONTRACT_ID)) Log::vOutput(0, "Loading basket currency info...\n " "Basket ID: %s\n Basket Acct ID: " "%s\n Basket Contract ID: %s\n", strBasketID.Get(), strBasketAcctID.Get(), strBasketContractID.Get()); else Log::vError("Error adding basket currency info...\n " "Basket ID: %s\n Basket Acct ID: %s\n", strBasketID.Get(), strBasketAcctID.Get()); } // Create an OTAssetContract and load them from file, (for each // instrument definition), // and add them to the internal map. else if (strNodeName.Compare("assetType")) { OTASCIIArmor ascAssetName = xml->getAttributeValue("name"); if (ascAssetName.Exists()) ascAssetName.GetString(AssetName, false); // linebreaks == false InstrumentDefinitionID = xml->getAttributeValue( "instrumentDefinitionID"); // hash of contract itself Log::vOutput(0, "\n\n****Asset Contract**** (server " "listing)\n Name: %s\n Contract ID: %s\n", AssetName.Get(), InstrumentDefinitionID.Get()); String strContractPath; strContractPath = OTFolders::Contract().Get(); AssetContract* pContract = new AssetContract( AssetName, strContractPath, InstrumentDefinitionID, InstrumentDefinitionID); OT_ASSERT_MSG(nullptr != pContract, "ASSERT: allocating memory for Asset " "Contract in MainFile::LoadMainFile\n"); if (pContract->LoadContract()) { if (pContract->VerifyContract()) { Log::Output(0, "** Asset Contract Verified **\n"); pContract->SetName(AssetName); server_->transactor_ .contractsMap_[InstrumentDefinitionID.Get()] = pContract; App::Me().DHT().Insert( InstrumentDefinitionID.Get(), *pContract); } else { delete pContract; pContract = nullptr; Log::Output(0, "Asset Contract FAILED to verify.\n"); } } else { delete pContract; pContract = nullptr; Log::vOutput( 0, "%s: Failed reading file for Asset Contract.\n", __FUNCTION__); } } else { // unknown element type Log::vError("%s: Unknown element type: %s\n", __FUNCTION__, xml->getNodeName()); } } break; default: break; } } } if (!bReadOnly) { { if (bNeedToSaveAgain) SaveMainFile(); } } return !bFailure; }
void OTToken::UpdateContents() { if (m_State == OTToken::spendableToken) m_strContractType.Set("CASH"); OTString ASSET_TYPE_ID(m_AssetTypeID), SERVER_ID(m_ServerID); OTString strState; switch (m_State) { case OTToken::blankToken: strState.Set("blankToken"); break; case OTToken::protoToken: strState.Set("protoToken"); break; case OTToken::signedToken: strState.Set("signedToken"); break; case OTToken::spendableToken: strState.Set("spendableToken"); break; case OTToken::verifiedToken: strState.Set("verifiedToken"); break; default: strState.Set("errorToken"); break; } long lFrom = m_VALID_FROM, lTo = m_VALID_TO; // I release this because I'm about to repopulate it. m_xmlUnsigned.Release(); m_xmlUnsigned.Concatenate("<?xml version=\"%s\"?>\n\n", "1.0"); m_xmlUnsigned.Concatenate("<token\n version=\"%s\"\n state=\"%s\"\n denomination=\"%ld\"\n" " assetTypeID=\"%s\"\n" " serverID=\"%s\"\n" " series=\"%d\"\n" " validFrom=\"%ld\"\n" " validTo=\"%ld\"" " >\n\n", m_strVersion.Get(), strState.Get(), GetDenomination(), ASSET_TYPE_ID.Get(), SERVER_ID.Get(), m_nSeries, lFrom, lTo ); // signed tokens, as well as spendable tokens, both carry a TokenID // (The spendable token contains the unblinded version.) if (OTToken::signedToken == m_State || OTToken::spendableToken == m_State) { m_xmlUnsigned.Concatenate("<tokenID>\n%s</tokenID>\n\n", m_ascSpendable.Get()); } // Only signedTokens carry the signature, which is discarded in spendable tokens. // (Because it is not used past the unblinding stage anyway, and because it could // be used to track the token.) if (OTToken::signedToken == m_State) { m_xmlUnsigned.Concatenate("<tokenSignature>\n%s</tokenSignature>\n\n", m_Signature.Get()); } if ((OTToken::protoToken == m_State || OTToken::signedToken == m_State) && m_nTokenCount) { m_xmlUnsigned.Concatenate("<protopurse count=\"%d\" chosenIndex=\"%d\">\n\n", m_nTokenCount, m_nChosenIndex); OTASCIIArmor * pPrototoken = NULL; for (mapOfPrototokens::iterator ii = m_mapPublic.begin(); ii != m_mapPublic.end(); ++ii) { pPrototoken = (*ii).second; OT_ASSERT(NULL != pPrototoken); m_xmlUnsigned.Concatenate("<prototoken>\n%s</prototoken>\n\n", pPrototoken->Get()); } m_xmlUnsigned.Concatenate("</protopurse>\n\n"); } if (m_bSavePrivateKeys) { m_bSavePrivateKeys = false; // set it back to false; m_xmlUnsigned.Concatenate("<privateProtopurse>\n\n"); OTASCIIArmor * pPrototoken = NULL; for (mapOfPrototokens::iterator ii = m_mapPrivate.begin(); ii != m_mapPrivate.end(); ++ii) { pPrototoken = (*ii).second; OT_ASSERT(NULL != pPrototoken); m_xmlUnsigned.Concatenate("<privatePrototoken>\n%s</privatePrototoken>\n\n", pPrototoken->Get()); } m_xmlUnsigned.Concatenate("</privateProtopurse>\n\n"); } m_xmlUnsigned.Concatenate("</token>\n"); }
void ProcessMessage_ZMQ(const std::string & str_Message, std::string & str_Reply) { OT_ASSERT(NULL != g_pServer); if (str_Message.size() < 1) return; // -------------------- // return value. std::string resultString = ""; // Whatever we put in this string is what will get returned. // First we grab the client's message OTASCIIArmor ascMessage; ascMessage.MemSet(str_Message.data(), str_Message.size()); // ------------------ // // OTPayload thePayload; // thePayload.SetPayloadSize(str_Message.size()); // memcpy((void*)thePayload.GetPayloadPointer(), str_Message.data(), str_Message.size()); // ---------------------------------------------------------------------- // OTLog::vError("Envelope: \n%s\n Size: %ld\n", ascMessage.Get(), ascMessage.GetLength()); OTMessage theMsg, theReply; // we'll need these in a sec... // OTEnvelope theEnvelope(ascMessage); // Now the base64 is decoded and unpacked, and the envelope is in binary form again. OTEnvelope theEnvelope; // Now the base64 is decoded and the envelope is in binary form again. if (theEnvelope.SetAsciiArmoredData(ascMessage)) { OTLog::Output(2, "Successfully retrieved envelope from ZMQ message...\n"); OTString strEnvelopeContents; // OTString strPubkeyPath("TESTPUBKEY.txt"); // g_pServer->GetServerNym().SavePublicKey(strPubkeyPath); // Decrypt the Envelope. if (theEnvelope.Open(g_pServer->GetServerNym(), strEnvelopeContents)) // now strEnvelopeContents contains the decoded message. { // All decrypted--now let's load the results into an OTMessage. // No need to call theMsg.ParseRawFile() after, since // LoadContractFromString handles it. // if (strEnvelopeContents.Exists() && theMsg.LoadContractFromString(strEnvelopeContents)) { // In case you want to see all the incoming messages... // OTLog::vOutput(0, "%s\n\n", strEnvelopeContents.Get()); // By constructing this without a socket, I put it in XmlRpc/http mode, instead of tcp/ssl. OTClientConnection theClient(*g_pServer); // By optionally passing in &theClient, the client Nym's public key will be // set on it whenever verification is complete. (So for the reply, I'll // have the key and thus I'll be able to encrypt reply to the recipient.) if (g_pServer->ProcessUserCommand(theMsg, theReply, &theClient)) { // At this point the reply is ready to go, and theClient has the public key of the recipient... OTLog::vOutput(1, "Successfully processed user command: %s.\n", theMsg.m_strCommand.Get()); // The transaction is now processed, and the server's reply message is in theReply. // Let's seal it up to the recipient's nym (in an envelope) and send back to the user... OTEnvelope theRecipientEnvelope; bool bSealed = theClient.SealMessageForRecipient(theReply, theRecipientEnvelope); if (bSealed) { // OTPayload theReplyPayload; // theReplyPayload.SetEnvelope(theRecipientEnvelope); // // resultString = ascReply.Get(); // resultString.assign(theReplyPayload.GetPayloadPointer(), theReplyPayload.GetPayloadSize()); OTASCIIArmor ascReply; if (theRecipientEnvelope.GetAsciiArmoredData(ascReply)); resultString.assign(ascReply.Get(), ascReply.GetLength()); } else OTLog::Output(0, "Unable to seal envelope in ProcessMessage_ZMQ.\n"); } else OTLog::Output(0, "Unable to process user command in ProcessMessage_ZMQ.\n"); } else OTLog::Error("Error loading message from envelope contents. ProcessMessage_ZMQ.\n"); } else OTLog::Error("Unable to open envelope. ProcessMessage_ZMQ.\n"); } else OTLog::Error("Error retrieving envelope from ProcessMessage_ZMQ.\n"); // ---------------------------------------------------------------------- str_Reply = resultString; }
// true == YES, DISCONNECT m_pSocket, something must have gone wrong. // false == NO, do NOT disconnect m_pSocket, everything went wonderfully! // bool ProcessMessage_ZMQ(OTServer & theServer, const std::string & str_Message, std::string & str_Reply) { if (str_Message.size() < 1) return false; const char * szFunc = "ProcessMessage_ZMQ"; // -------------------- // return value. std::string resultString = ""; // Whatever we put in this string is what will get returned. // First we grab the client's message OTASCIIArmor ascMessage; ascMessage.MemSet(str_Message.data(), str_Message.size()); // ------------------ // // OTPayload thePayload; // thePayload.SetPayloadSize(str_Message.size()); // memcpy((void*)thePayload.GetPayloadPointer(), str_Message.data(), str_Message.size()); // ---------------------------------------------------------------------- // OTLog::vError("Envelope: \n%s\n Size: %ld\n", ascMessage.Get(), ascMessage.GetLength()); bool bReturnVal = false; // "false" == no, do NOT disconnect. No errors. ("True" means YES, DISCONNECT!) OTMessage theMsg, theReply; // we'll need these in a sec... // OTEnvelope theEnvelope(ascMessage); OTEnvelope theEnvelope; if (false == theEnvelope.SetAsciiArmoredData(ascMessage)) { OTLog::vError("%s: Error retrieving envelope.\n", szFunc); bReturnVal = true; // disconnect the socket! } else { // Now the base64 is decoded and the envelope is in binary form again. OTLog::vOutput(2, "%s: Successfully retrieved envelope from ZMQ message...\n", szFunc); OTString strEnvelopeContents; // OTString strPubkeyPath("TESTPUBKEY.txt"); // theServer.GetServerNym().SavePublicKey(strPubkeyPath); // Decrypt the Envelope. if (false == theEnvelope.Open(theServer.GetServerNym(), strEnvelopeContents)) // now strEnvelopeContents contains the decoded message. { OTLog::vError("%s: Unable to open envelope.\n", szFunc); bReturnVal = true; // disconnect the socket! } else { // All decrypted--now let's load the results into an OTMessage. // No need to call theMsg.ParseRawFile() after, since // LoadContractFromString handles it. // if (strEnvelopeContents.Exists() && theMsg.LoadContractFromString(strEnvelopeContents)) { theReply.m_strCommand.Format("@%s", theMsg.m_strCommand.Get()); theReply.m_strNymID = theMsg.m_strNymID; // UserID theReply.m_strServerID = theMsg.m_strServerID; // ServerID, a hash of the server contract. theReply.m_bSuccess = false; // The default reply. In fact this is probably superfluous. // In case you want to see all the incoming messages... // OTLog::vOutput(0, "%s\n\n", strEnvelopeContents.Get()); // By constructing this without a socket, I put it in ZMQ mode, instead of tcp/ssl. OTClientConnection theClient(theServer); // By optionally passing in &theClient, the client Nym's public key will be // set on it whenever verification is complete. (So for the reply, I'll // have the key and thus I'll be able to encrypt reply to the recipient.) if (false == theServer.ProcessUserCommand(theMsg, theReply, &theClient)) { const OTString s1(theMsg), s2(theReply); OTLog::vOutput(0, "%s: Unable to process user command.\n\n ********** " "REQUEST:\n\n%s\n\n ********** RESPONSE:\n\n%s\n\n", szFunc, s1.Get(), s2.Get()); // NOTE: normally you would even HAVE a true or false if we're in this block. ProcessUserCommand() // is what tries to process a command and then sets false if/when it fails. Until that point, you // wouldn't get any server reply. I'm now changing this slightly, so you still get a reply (defaulted // to success==false.) That way if a client needs to re-sync his request number, he will get the false // and therefore know to resync the # as his next move, vs being stuck with no server reply (and thus // stuck with a bad socket.) // We sign the reply here, but not in the else block, since it's already signed in cases where // ProcessUserCommand() is a success, by the time that call returns. theReply.m_bSuccess = false; // Since the process call definitely failed, I'm making sure this here is definitely set to false (even though it probably was already.) theReply.SignContract(theServer.GetServerNym()); theReply.SaveContract(); } else // At this point the reply is ready to go, and theClient has the public key of the recipient... OTLog::vOutput(1, "%s: Successfully processed user command: %s.\n", szFunc, theMsg.m_strCommand.Get()); // ------------------------------------------------- // The transaction is now processed (or not), and the server's reply message is in theReply. // Let's seal it up to the recipient's nym (in an envelope) and send back to the user... // OTEnvelope theRecipientEnvelope; bool bSealed = theClient.SealMessageForRecipient(theReply, theRecipientEnvelope); if (false == bSealed) { OTLog::vOutput(0, "%s: Unable to seal envelope. (No reply will be sent.)\n", szFunc); bReturnVal = true; // disconnect the socket! } else { // OTPayload theReplyPayload; // theReplyPayload.SetEnvelope(theRecipientEnvelope); // resultString = ascReply.Get(); // resultString.assign(theReplyPayload.GetPayloadPointer(), theReplyPayload.GetPayloadSize()); OTASCIIArmor ascReply; if (theRecipientEnvelope.GetAsciiArmoredData(ascReply)) resultString.assign(ascReply.Get(), ascReply.GetLength()); } } else { OTLog::vError("%s: Error loading message from envelope contents:\n\n%s\n\n", szFunc, strEnvelopeContents.Get()); bReturnVal = true; // disconnect the socket! } } } // ---------------------------------------------------------------------- str_Reply = resultString; return bReturnVal; } // ProcessMessage_ZMQ