OTMessage * OTClientConnection::GetNextOutputMessage() { //#if !defined(OT_ZMQ_MODE) // return m_listOut.Pop(); //#else // OT_FAIL_MSG("OTClientConnection::GetNextOutputMessage: ASSERT: Should not be calling this..."); //#endif OT_FAIL_MSG("OTClientConnection::GetNextOutputMessage: ASSERT: Should not be calling this..."); }
bool OTPassword::ot_unlockPage(void* addr, size_t len) { #ifdef _WIN32 // return VirtualUnlock(addr, len); #elif defined(PREDEF_PLATFORM_UNIX) static bool bWarned = false; if (munlock(addr, len) && !bWarned) { bWarned = true; otErr << "ot_unlockPage: WARNING: unable to unlock memory used for " "storing secrets.\n"; } return true; #else OT_FAIL_MSG("ASSERT: ot_unlockPage unable to unlock secret memory."); #endif return false; }
// THE PURPOSE OF LOCKING A PAGE: // // "So that it won't get swapped to disk, where the secret // could be recovered maliciously from the swap file." // bool OTPassword::ot_lockPage(void* addr, size_t len) { #ifdef _WIN32 // return VirtualLock(addr, len); #elif defined(PREDEF_PLATFORM_UNIX) static bool bWarned = false; if (mlock(addr, len) && !bWarned) { bWarned = true; otErr << "ot_lockPage: WARNING: unable to lock memory. \n" " (Passwords / secret keys may be swapped to disk!)\n"; } return true; #else OT_FAIL_MSG("ASSERT: ot_lockPage unable to lock memory."); #endif return false; }
//static // This is the thread itself. // void OTCachedKey::ThreadTimeout(void * pArg) { // TODO: Save a copy of pArg, in the cached key object, and delete it whenever LowLevelRemoveThread // is called. Otherwise it's a memory leak. // _SharedPtr<OTCachedKey> * pthreadSharedPtr = static_cast<_SharedPtr<OTCachedKey> *>(pArg); _SharedPtr<OTCachedKey> pMyself = *pthreadSharedPtr; if (!pMyself) { OT_FAIL_MSG("OTCachedKey::ThreadTimeout: Need ptr to master key here, that activated this thread.\n"); } // -------------------------------------- // tthread::lock_guard<tthread::mutex> lock(*(pMyself->GetMutex())); // Multiple threads can't get inside here at the same time. // -------------------------------------- int32_t nTimeoutSeconds = 0; { tthread::lock_guard<tthread::mutex> lock(OTCachedKey::s_mutexThreadTimeout); if (pMyself) { nTimeoutSeconds = pMyself->GetTimeoutSeconds(); // locks mutex internally. } } // -------------------------------------- if (nTimeoutSeconds > 0) { if (pMyself) tthread::this_thread::sleep_for(tthread::chrono::seconds(nTimeoutSeconds)); // <===== ASLEEP! } // -------------------------------------- { tthread::lock_guard<tthread::mutex> lock(OTCachedKey::s_mutexThreadTimeout); if (pMyself && (nTimeoutSeconds != (-1))) { pMyself->DestroyMasterPassword(); // locks mutex internally. } } }
/// This function first Packs the incoming string, using whatever is the default packer. (MsgPack or Protobuf). /// Then it Compresses the packed binary data using zlib. (ezcompress.) /// Then it Base64-Encodes the compressed binary and sets it as a string on THIS OBJECT. /// /// I added these pieces 1-by-1 over time. At first the messages were too long, so I started compressing them. /// Then they were not binary compatible across various platforms, so I added the packing. // bool OTASCIIArmor::SetAndPackString(const OTString & strData, bool bLineBreaks) //=true { Release(); if (strData.GetLength() < 1) return true; // -------------------------------------------------------- OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. // Here I use the default storage context to create the object (the blob.) // I also originally created OTASCIIArmor::GetPacker() using OTDB_DEFAULT_PACKER, // so I know everything is compatible. // OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING)); OT_ASSERT(NULL != pOTDBString); // Beyond this point, responsible to delete pString. OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // make sure memory is cleaned up. // ----------------------------- const uint32_t theStringSize32 = strData.GetLength(); const size_t theStringSize = theStringSize32; // might need a cast here. // todo make sure this will handle sizes as big as I need. pOTDBString->m_string.assign(strData.Get(), // const char * theStringSize); OTDB::PackedBuffer * pBuffer = pPacker->Pack(*pOTDBString); // Now we PACK our string before compressing/encoding it. if (NULL == pBuffer) { OTLog::Error("Failed packing string in OTASCIIArmor::SetAndPackString. \n"); return false; } OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // make sure memory is cleaned up. // -------------------------------------------------------- const uint8_t* pUint = static_cast<const uint8_t*>(pBuffer->GetData()); const size_t theSize = pBuffer->GetSize(); // -------------------------------------------------------- char * pString = NULL; // Set up source buffer and destination buffer long nDestLen = DEFAULT_BUFFER_SIZE_EASYZLIB; // todo stop hardcoding numbers (but this one is OK I think.) const long lSourcelen = static_cast<long> (theSize); unsigned char* pSource = new unsigned char[lSourcelen+10]; // for safety unsigned char* pDest = new unsigned char[nDestLen +10]; // for safety OT_ASSERT(NULL != pSource); OT_ASSERT(NULL != pDest); OTPassword::zeroMemory(pSource, lSourcelen+10); OTPassword::zeroMemory(pDest, nDestLen +10); // void * OTPassword::safe_memcpy(void * dest, // uint32_t dest_size, // const // void * src, // uint32_t src_length, // bool bZeroSource/*=false*/) // if true, sets the source buffer to zero after copying is done. OTPassword::safe_memcpy(pSource, lSourcelen, pUint, static_cast<uint32_t>(theSize)); // Now we are compressing first before base64-encoding (for strings, anyway) int nErr = ezcompress( pDest, &nDestLen, pSource, lSourcelen ); // If the destination buffer wasn't the right size the first time around, // then we re-allocate it to the right size (which we now know) and try again... if ( nErr == EZ_BUF_ERROR ) { delete [] pDest; pDest = new unsigned char [nDestLen+10]; // enough room now OT_ASSERT(NULL != pDest); OTPassword::zeroMemory(pDest, nDestLen+10); nErr = ezcompress( pDest, &nDestLen, pSource, lSourcelen ); } // Clean this up... delete [] pSource; pSource = NULL; // Still errors? if ( nErr == EZ_BUF_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("Error allocating memory in OTASCIIArmor::SetAndPackString\n"); } else if ( nErr == EZ_STREAM_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG( "pDest is NULL in OTASCIIArmor::SetAndPackString\n"); } else if ( nErr == EZ_DATA_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("corrupted pSrc passed to ezuncompress OTASCIIArmor::SetAndPackString\n"); } else if ( nErr == EZ_MEM_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("Out of memory in OTASCIIArmor::SetAndPackString\n"); } OT_ASSERT_MSG(pDest != NULL, "pDest NULL in OTASCIIArmor::SetAndPackString\n"); // Success if (0 < nDestLen) { // Now let's base-64 encode it... pString = OTCrypto::It()->Base64Encode((const uint8_t*)pDest, nDestLen, bLineBreaks); // pString = OT_base64_encode((const uint8_t*)pDest, nDestLen, (bLineBreaks ? 1 : 0)); delete [] pDest; pDest = NULL; if (pString) { Set(pString); delete [] pString; pString=NULL; return true; } else { OTLog::Error("pString NULL in OTASCIIArmor::SetAndPackString\n"); } } else { OTLog::Error("nDestLen 0 in OTASCIIArmor::SetAndPackString\n"); } if (pDest) delete [] pDest; pDest = NULL; return false; }
/// if we pack, compress, encode on the way in, that means, therefore, we /// need to decode, uncompress, then unpack on our way out. Right? /// /// This function will base64-DECODE the string contents, then uncompress them using /// zlib, and then unpack the result using whatever is the default packer (MsgPack, Protobuf, etc). /// /// I originally added compression because message sizes were too big. Now I'm adding packing, /// to solve any issues of binary compatibility across various platforms. // bool OTASCIIArmor::GetAndUnpackString(OTString & strData, bool bLineBreaks) const //bLineBreaks=true { size_t outSize = 0; uint8_t * pData = NULL; strData.Release(); if (GetLength() < 1) { return true; } // -------------------------------------------------------------- pData = OTCrypto::It()->Base64Decode(this->Get(), &outSize, bLineBreaks); // pData = OT_base64_decode(Get(), &outSize, (bLineBreaks ? 1 : 0)); if (pData) { // ------------------------------------------- // EASY ZLIB // long nDestLen = DEFAULT_BUFFER_SIZE_EASYZLIB; // todo stop hardcoding numbers (but this one is OK I think.) unsigned char* pDest = new unsigned char [nDestLen+10]; // For safety. OT_ASSERT(NULL != pDest); int nErr = ezuncompress( pDest, &nDestLen, pData, static_cast<long> (outSize) ); if ( nErr == EZ_BUF_ERROR ) { delete [] pDest; pDest = new unsigned char [nDestLen]; // enough room now OT_ASSERT(NULL != pDest); nErr = ezuncompress( pDest, &nDestLen, pData, static_cast<long> (outSize) ); } // Now we're done with this memory, let's free it. delete [] pData; pData=NULL; // ---------------------------------------- if ( nErr == EZ_BUF_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("Buffer error in OTASCIIArmor::GetAndUnpackString\n"); } else if ( nErr == EZ_STREAM_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("pDest is NULL in OTASCIIArmor::GetAndUnpackString\n"); } else if ( nErr == EZ_DATA_ERROR ) { delete [] pDest; pDest = NULL; OTLog::vError("corrupted pSrc passed to ezuncompress OTASCIIArmor::GetAndUnpackString, size: %d\n", outSize); OT_FAIL; } else if ( nErr == EZ_MEM_ERROR ) { delete [] pDest; pDest = NULL; OT_FAIL_MSG("Out of memory in OTASCIIArmor::GetAndUnpackString\n"); } // --------------------------------------- // PUT THE PACKED BUFFER HERE, AND UNPACK INTO strData // -------------------------------------------------------- OTDB::OTPacker * pPacker = OTASCIIArmor::GetPacker(); // No need to check for failure, since this already ASSERTS. No need to cleanup either. OTDB::PackedBuffer * pBuffer = pPacker->CreateBuffer(); // Need to clean this up. OT_ASSERT(NULL != pBuffer); OTCleanup<OTDB::PackedBuffer> theBufferAngel(*pBuffer); // This will make sure buffer is deleted later. const size_t theDestLen = nDestLen; pBuffer->SetData(pDest, // const unsigned char * theDestLen); delete [] pDest; pDest=NULL; // ----------------------------- OTDB::OTDBString * pOTDBString = dynamic_cast<OTDB::OTDBString *>(OTDB::CreateObject(OTDB::STORED_OBJ_STRING)); OT_ASSERT(NULL != pOTDBString); OTCleanup<OTDB::OTDBString> theStringAngel(*pOTDBString); // clean up this string. bool bUnpacked = pPacker->Unpack(*pBuffer, *pOTDBString); // ---------------------- if (false == bUnpacked) { OTLog::Error("Failed unpacking string in OTASCIIArmor::GetAndUnpackString.\n"); return false; } // -------------------------------------------------------- // This enforces the null termination. (using the 2nd parameter as nEnforcedMaxLength) strData.Set(pOTDBString->m_string.c_str(), static_cast<uint32_t> (pOTDBString->m_string.length())); return true; } else { OTLog::Error("OTASCIIArmor::GetAndUnpackString: NULL pData while base64-decoding pData.\n"); return false; } }
bool OTAcctFunctor::Trigger(OTAccount & theAccount) { OT_FAIL_MSG("OTAcctFunctor::Trigger: You need to override the Trigger method in your subclass. (It's missing.)"); }
// Asks for password twice. (For confirmation when changing password or creating nym.) // void OTCallback::runTwo(const char * szDisplay, OTPassword & theOutput) // child class will override. { OT_FAIL_MSG("OTCallback::runTwo: ASSERT (The child class was supposed to override this method.)\n"); }