Exemple #1
0
// 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);
}
Exemple #2
0
// 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);
}
Exemple #3
0
// 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;
}