// This version base64-DECODES the ascii-armored string passed in, // and then sets the decoded plaintext string onto this object. OTString::OTString(const OTASCIIArmor & strValue) : m_lLength(0), m_lPosition(0), m_strBuffer(NULL) { // Initialize(); if (strValue.Exists()) strValue.GetString(*this); }
// This version base64-DECODES the ascii-armored string passed in, // and then sets the decoded plaintext string onto this object. OTString::OTString(const OTASCIIArmor & strValue) { Initialize(); if (strValue.Exists()) strValue.GetString(*this); }
// This version base64-DECODES the ascii-armored string passed in, // and then sets the decoded plaintext string onto this object. String::String(const OTASCIIArmor& strValue) : length_(0) , position_(0) , data_(nullptr) { // Initialize(); if (strValue.Exists()) strValue.GetString(*this); }
int OTSignedFile::ProcessXMLNode(irr::io::IrrXMLReader*& xml) { int nReturnVal = 0; // Here we call the parent class first. // If the node is found there, or there is some error, // then we just return either way. But if it comes back // as '0', then nothing happened, and we'll continue executing. // // -- Note you can choose not to call the parent if // you don't want to use any of those xml tags. // As I do below, in the case of OTAccount. //if (nReturnVal = OTContract::ProcessXMLNode(xml)) // return nReturnVal; if (!strcmp("signedFile", xml->getNodeName())) { m_strVersion = xml->getAttributeValue("version"); m_strPurportedLocalDir = xml->getAttributeValue("localDir"); m_strPurportedFilename = xml->getAttributeValue("filename"); // --------------------- nReturnVal = 1; } else if (!strcmp("filePayload", xml->getNodeName())) { // go to the next node and read the text. xml->read(); if (EXN_TEXT == xml->getNodeType()) { OTString strNodeData = xml->getNodeData(); // Sometimes the XML reads up the data with a prepended newline. // This screws up my own objects which expect a consistent in/out // So I'm checking here for that prepended newline, and removing it. char cNewline; if (strNodeData.At(0, cNewline)) { OTASCIIArmor ascNodeData; if ('\n' == cNewline) { ascNodeData.Set(strNodeData.Get() + 1); ascNodeData.GetString(m_strSignedFilePayload, true); // linebreaks = true } else { ascNodeData.Set(strNodeData.Get()); ascNodeData.GetString(m_strSignedFilePayload, true); // linebreaks = true } } } else { fprintf(stderr, "Error in OTSignedFile::ProcessXMLNode: filePayload field without value.\n"); return (-1); // error condition } return 1; } return nReturnVal; }
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; }
bool MessageProcessor::processMessage(const std::string& messageString, std::string& reply) { if (messageString.size() < 1) return false; // First we grab the client's message OTASCIIArmor ascMessage; ascMessage.MemSet(messageString.data(), messageString.size()); String messageContents; ascMessage.GetString(messageContents); // All decrypted--now let's load the results into an OTMessage. // No need to call message.ParseRawFile() after, since // LoadContractFromString handles it. Message message; if (!messageContents.Exists() || !message.LoadContractFromString(messageContents)) { Log::vError("Error loading message from message " "contents:\n\n%s\n\n", messageContents.Get()); return true; } Message replyMessage; replyMessage.m_strCommand.Format("%sResponse", message.m_strCommand.Get()); // NymID replyMessage.m_strNymID = message.m_strNymID; // NotaryID, a hash of the server contract replyMessage.m_strNotaryID = message.m_strNotaryID; // The default reply. In fact this is probably superfluous replyMessage.m_bSuccess = false; ClientConnection client; Nym nym(message.m_strNymID); bool processedUserCmd = server_->userCommandProcessor_.ProcessUserCommand( message, replyMessage, &client, &nym); // By optionally passing in &client, 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 (!processedUserCmd) { String s1(message); Log::vOutput(0, "Unable to process user command: %s\n ********** " "REQUEST:\n\n%s\n\n", message.m_strCommand.Get(), s1.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. // Since the process call definitely failed, I'm replyMessage.m_bSuccess = false; // making sure this here is definitely set to // false (even though it probably was already.) replyMessage.SignContract(server_->GetServerNym()); replyMessage.SaveContract(); String s2(replyMessage); Log::vOutput(0, " ********** RESPONSE:\n\n%s\n\n", s2.Get()); } else { // At this point the reply is ready to go, and client // has the public key of the recipient... Log::vOutput(1, "Successfully processed user command: %s.\n", message.m_strCommand.Get()); } String replyString(replyMessage); if (!replyString.Exists()) { Log::vOutput(0, "Failed trying to grab the reply " "in OTString form. " "(No reply message will be sent.)\n"); return true; } OTASCIIArmor ascReply(replyString); if (!ascReply.Exists()) { Log::vOutput(0, "Unable to WriteArmoredString from " "OTASCIIArmor object into OTString object. (No reply " "message will be sent.)\n"); return true; } reply.assign(ascReply.Get(), ascReply.GetLength()); return false; }
// LoadContract will call this function at the right time. // return -1 if error, 0 if nothing, and 1 if the node was processed. int OTLedger::ProcessXMLNode(irr::io::IrrXMLReader*& xml) { OTString strKeyName; OTString strKeyValue; OTString strTransaction; OTASCIIArmor ascTransaction; if (!strcmp("accountLedger", xml->getNodeName())) { OTString strType, strLedgerAcctID, strLedgerAcctServerID, strUserID; strType = xml->getAttributeValue("type"); if (strType.Compare("message")) m_Type = OTLedger::message; else if (strType.Compare("inbox")) m_Type = OTLedger::inbox; else if (strType.Compare("outbox")) m_Type = OTLedger::outbox; else if (strType.Compare("nymbox")) m_Type = OTLedger::nymbox; else m_Type = OTLedger::error_state; m_strVersion = xml->getAttributeValue("version"); strLedgerAcctID = xml->getAttributeValue("accountID"); strLedgerAcctServerID = xml->getAttributeValue("serverID"); strUserID = xml->getAttributeValue("userID"); OTIdentifier ACCOUNT_ID(strLedgerAcctID), SERVER_ID(strLedgerAcctServerID), USER_ID(strUserID); SetPurportedAccountID(ACCOUNT_ID); SetPurportedServerID(SERVER_ID); SetUserID(USER_ID); OTLog::vOutput(2, "Loaded account ledger of type \"%s\", version: %s\n", // "accountID:\n%s\n userID:\n%s\n serverID:\n%s\n----------\n", strType.Get(), m_strVersion.Get() // strLedgerAcctID.Get(), strUserID.Get(), strLedgerAcctServerID.Get() ); // Since we just loaded this stuff, let's verify it. // We may have to remove this verification here and do it outside this call. // But for now... if (VerifyContractID()) return 1; else { return -1; } } else if (!strcmp("transaction", xml->getNodeName())) { // go to the next node and read the text. xml->read(); if (EXN_TEXT == xml->getNodeType()) { // the ledger contains a series of transactions. // Each transaction is initially stored as an OTASCIIArmor string. ascTransaction.Set(xml->getNodeData()); // Put the ascii-armored node data into the ascii-armor object ascTransaction.GetString(strTransaction); // Decode that into strTransaction, so we can load the transaction object from that string. OTTransaction * pTransaction = new OTTransaction(GetUserID(), GetPurportedAccountID(), GetPurportedServerID()); // If we're able to successfully base64-decode the string and load it up as // a transaction, then let's add it to the ledger's list of transactions if (pTransaction && pTransaction->LoadContractFromString(strTransaction) && pTransaction->VerifyContractID()) // I responsible here to call pTransaction->VerifyContract() since // I am loading it here and adding it to the ledger. (So I do.) { m_mapTransactions[pTransaction->GetTransactionNum()] = pTransaction; // OTLog::Output(5, "Loaded transaction and adding to m_mapTransactions in OTLedger\n"); } else { OTLog::Error("ERROR: loading transaction in OTLedger::ProcessXMLNode\n"); if (pTransaction) { delete pTransaction; pTransaction = NULL; } return (-1); } } else { OTLog::Error("Error in OTLedger::ProcessXMLNode: transaction without value.\n"); return (-1); // error condition } return 1; } return 0; }