Permalink
Browse files

FINALLY fixed the password-thread-timeout-crash!!

(So far tested on Mac only.)

Signed-off-by: FellowTraveler <F3llowTraveler@gmail.com>
  • Loading branch information...
FellowTraveler committed Dec 25, 2013
1 parent ae8ff7d commit 5600378ea85e291b41a87efef8536d1799bef771
View
@@ -1 +1 @@
-0.90.b
+0.90.c
@@ -160,11 +160,15 @@
//using namespace tthread; // in the C++ file
// --------------------------------------
+#include "stdafx.h"
+
+
class OTString;
class OTASCIIArmor;
class OTSymmetricKey;
class OTCachedKey;
class OTPassword;
+class OTIdentifier;
// ------------------------------------------------------------------------
@@ -270,9 +274,19 @@ class OTPassword;
//
#define OT_MASTER_KEY_TIMEOUT 300
-typedef std::map<std::string, OTCachedKey*> mapOfCachedKeys;
+// ------------------------------------------------------------------
+#ifndef OT_USE_TR1
+typedef std::shared_ptr <OTCachedKey> OTCachedKey_SharedPtr;
+typedef std::weak_ptr <OTCachedKey> OTCachedKey_WeakPtr;
+#else
+typedef std::tr1::shared_ptr <OTCachedKey> OTCachedKey_SharedPtr;
+typedef std::tr1::weak_ptr <OTCachedKey> OTCachedKey_WeakPtr;
+#endif
+typedef std::map<std::string, OTCachedKey_SharedPtr> mapOfCachedKeys;
+
+// ------------------------------------------------------------------
class OTCachedKey
{
private:
@@ -288,6 +302,8 @@ class OTCachedKey
// -----------------------------------------------------------
OTCachedKey(int nTimeoutSeconds=OT_MASTER_KEY_TIMEOUT);
// -----------------------------------------------------------
+ static tthread::mutex s_mutexThreadTimeout;
+ // -----------------------------------------------------------
static tthread::mutex s_mutexCachedKeys;
static mapOfCachedKeys s_mapCachedKeys; // Now we have many "master keys," mapped by their symmetric key ID. These are actually temps, just so we can safely cache the passphrases for various symmetric keys, between uses of that symmetric key. Such as Pop'ing tokens off of a purse, over and over again. Normally in the API, this would have to load the key each time. By caching here, we can exploit all the cool master key code, with its security, and threads, and timeouts, etc for every symmetric key we use. Just pass an ID into It() and if it's on the map, a pointer will be returned. Pass NULL into It() (no arguments) to get a pointer to the global Master Key (for Nyms.)
public:
@@ -296,9 +312,9 @@ class OTCachedKey
EXPORT OTCachedKey(const OTASCIIArmor & ascCachedKey);
EXPORT ~OTCachedKey();
// -----------------------------------------------------------
- EXPORT static OTCachedKey * It(OTIdentifier * pIdentifier=NULL); // if you pass in a master key ID, it will look it up on an existing cached map of master keys. Otherwise it will use "the" global Master Key (the one used for the Nyms.)
+ EXPORT static OTCachedKey_SharedPtr It(OTIdentifier * pIdentifier=NULL); // if you pass in a master key ID, it will look it up on an existing cached map of master keys. Otherwise it will use "the" global Master Key (the one used for the Nyms.)
- EXPORT static OTCachedKey * It(OTCachedKey & theSourceKey); // if you pass in a master key, it will look it up on an existing cached map of master keys, based on the ID of the master key passed in. If not there, it copies the one passed in, and returns a pointer to the copy. (Do NOT delete it.)
+ EXPORT static OTCachedKey_SharedPtr It(OTCachedKey & theSourceKey); // if you pass in a master key, it will look it up on an existing cached map of master keys, based on the ID of the master key passed in. If not there, it copies the one passed in, and returns a pointer to the copy. (Do NOT delete it.)
EXPORT static void Cleanup(); // Call on application shutdown. Called in CleanupOTAPI and also in OTServer wherever it cleans up.
// ------------------------------------------------------------------------
@@ -340,13 +356,14 @@ class OTCachedKey
// master key to get the passphrase, (which _would_ happen if the purse is encrypted to a nym) will
// instead use its own internal master key to get its passphrase (also retrieving from the user if
// necessary.)
- EXPORT bool GetMasterPassword( OTPassword & theOutput,
- const char * szDisplay=NULL,
- bool bVerifyTwice=false);
+ EXPORT bool GetMasterPassword(OTCachedKey_SharedPtr & mySharedPtr,
+ OTPassword & theOutput,
+ const char * szDisplay=NULL,
+ bool bVerifyTwice=false);
// Caller must delete!
- EXPORT static OTCachedKey * CreateMasterPassword(OTPassword & theOutput,
- const char * szDisplay=NULL,
- int nTimeoutSeconds=OT_MASTER_KEY_TIMEOUT);
+ EXPORT static OTCachedKey_SharedPtr CreateMasterPassword(OTPassword & theOutput,
+ const char * szDisplay=NULL,
+ int nTimeoutSeconds=OT_MASTER_KEY_TIMEOUT);
// --------------------------------
EXPORT void DestroyMasterPassword(); // The thread, when the time comes, calls this method using the instance pointer that was passed into the thread originally. The actual encrypted version is kept -- only the temporary cleartext version is destroyed.
View
@@ -145,6 +145,8 @@ extern "C" {
}
// ------------------------------------------------------------------------
+#include "OTCachedKey.h"
+
/*
To use:
@@ -355,17 +357,14 @@ class OTString;
class OTPassword;
-class OTCachedKey;
-
-
class OTPasswordData
{
private:
- OTPassword * m_pMasterPW; // Used only when isForCachedKey is true, for output. Points to output value from original caller (not owned.)
- const std::string m_strDisplay;
- bool m_bUsingOldSystem; // "Do NOT use CachedKey if this is true."
+ OTPassword * m_pMasterPW; // Used only when isForCachedKey is true, for output. Points to output value from original caller (not owned.)
+ const std::string m_strDisplay;
+ bool m_bUsingOldSystem; // "Do NOT use CachedKey if this is true."
- OTCachedKey * m_pCachedKey; // If m_pMasterPW is set, this must be set as well.
+ OTCachedKey_SharedPtr m_pCachedKey; // If m_pMasterPW is set, this must be set as well.
public:
// --------------------------------
EXPORT bool isForNormalNym() const;
@@ -376,12 +375,12 @@ EXPORT const char * GetDisplayString() const;
EXPORT bool isUsingOldSystem() const;
EXPORT void setUsingOldSystem(bool bUsing=true);
// --------------------------------
- OTPassword * GetMasterPW () { return m_pMasterPW; }
- OTCachedKey * GetCachedKey() { return m_pCachedKey; }
+ OTPassword * GetMasterPW () { return m_pMasterPW; }
+ OTCachedKey_SharedPtr GetCachedKey() { return m_pCachedKey; }
// --------------------------------
-EXPORT OTPasswordData(const char * szDisplay, OTPassword * pMasterPW=NULL, OTCachedKey * pCachedKey=NULL);
-EXPORT OTPasswordData(const std::string & str_Display, OTPassword * pMasterPW=NULL, OTCachedKey * pCachedKey=NULL);
-EXPORT OTPasswordData(const OTString & strDisplay, OTPassword * pMasterPW=NULL, OTCachedKey * pCachedKey=NULL);
+EXPORT OTPasswordData(const char * szDisplay, OTPassword * pMasterPW=NULL, OTCachedKey_SharedPtr pCachedKey=OTCachedKey_SharedPtr());
+EXPORT OTPasswordData(const std::string & str_Display, OTPassword * pMasterPW=NULL, OTCachedKey_SharedPtr pCachedKey=OTCachedKey_SharedPtr());
+EXPORT OTPasswordData(const OTString & strDisplay, OTPassword * pMasterPW=NULL, OTCachedKey_SharedPtr pCachedKey=OTCachedKey_SharedPtr());
EXPORT ~OTPasswordData();
};
View
@@ -148,6 +148,7 @@
#include "OTContract.h"
#include "OTToken.h"
#include "OTASCIIArmor.h"
+#include "OTCachedKey.h"
class OTPurse;
class OTPseudonym;
@@ -202,8 +203,8 @@ class OTPurse : public OTContract
// ----------------------------------------------
bool m_bIsNymIDIncluded; // It's possible to use a purse WITHOUT attaching the relevant NymID. (The holder of the purse just has to "know" what the correct NymID is, or it won't work.) This bool tells us whether the ID is attached, or not.
// ----------------------------------------------
- OTSymmetricKey * m_pSymmetricKey; // If this purse contains its own symmetric key (instead of using an owner Nym)...
- OTCachedKey * m_pCachedKey; // ...then it will have a master key as well, for unlocking that symmetric key, and managing timeouts, etc.
+ OTSymmetricKey * m_pSymmetricKey; // If this purse contains its own symmetric key (instead of using an owner Nym)...
+ OTCachedKey_SharedPtr m_pCachedKey; // ...then it will have a master key as well, for unlocking that symmetric key, and managing timeouts, etc.
// ----------------------------------------------
time_t m_tLatestValidFrom; // The tokens in the purse may become valid on different dates. This stores the latest one.
time_t m_tEarliestValidTo; // The tokens in the purse may have different expirations. This stores the earliest one.
@@ -231,10 +232,10 @@ class OTPurse : public OTContract
// You set the passphrase for the internal key, and thereafter
// your experience is one of a password-protected purse.
//
- EXPORT bool GenerateInternalKey(); // Create internal symmetric key for password-protected purse.
- EXPORT OTSymmetricKey * GetInternalKey() { return m_pSymmetricKey; } // symmetric key for this purse.
- EXPORT OTCachedKey * GetInternalMaster(); // stores the passphrase for the symmetric key.
- EXPORT bool GetPassphrase(OTPassword & theOutput, const char * szDisplay=NULL); // Retrieves the passphrase for this purse (which is cached by the master key.) Prompts the user to enter his actual passphrase, if necessary to unlock it. (May not need unlocking yet -- there is a timeout.)
+ EXPORT bool GenerateInternalKey(); // Create internal symmetric key for password-protected purse.
+ EXPORT OTSymmetricKey * GetInternalKey() { return m_pSymmetricKey; } // symmetric key for this purse.
+ EXPORT OTCachedKey_SharedPtr GetInternalMaster(); // stores the passphrase for the symmetric key.
+ EXPORT bool GetPassphrase(OTPassword & theOutput, const char * szDisplay=NULL); // Retrieves the passphrase for this purse (which is cached by the master key.) Prompts the user to enter his actual passphrase, if necessary to unlock it. (May not need unlocking yet -- there is a timeout.)
// ----------------------------------------------
EXPORT bool IsNymIDIncluded() const { return m_bIsNymIDIncluded; } // NymID may be left blank, with user left guessing.
// ----------------------------------------------
@@ -15,11 +15,11 @@
// Global
#ifndef OT_VERSION
-#define OT_VERSION "0.90.b"
+#define OT_VERSION "0.90.c"
#endif
#ifndef OT_PRODUCTVERSION
-#define OT_PRODUCTVERSION 0,90,2,0
+#define OT_PRODUCTVERSION 0,90,3,0
#endif
#ifndef OT_API_NAME
@@ -2219,7 +2219,9 @@ bool OT_API::Wallet_ChangePassphrase()
// to make sure it happens, even if there are no Nyms to save below this point.
//
OTPassword temp_password;
- const bool bRegenerate = OTCachedKey::It()->GetMasterPassword(temp_password, strReason.Get(), true); //bVerifyTwice=false by default.
+ OTCachedKey_SharedPtr sharedPtr(OTCachedKey::It());
+ const bool bRegenerate = sharedPtr->GetMasterPassword(sharedPtr, temp_password, strReason.Get(),
+ true); //bVerifyTwice=false by default.
// ----------------------------------------------------
if (!bRegenerate) // Failure generating new master key.
{
@@ -2216,13 +2216,14 @@ OPENSSL_CALLBACK_FUNC(souped_up_pass_cb)
OTPassword thePassword;
bool bGotPassword = false;
// -------------------------------------
- OTCachedKey * pCachedKey = pPWData->GetCachedKey(); // Sometimes it's passed in, otherwise we use the global one.
- if (NULL == pCachedKey)
+ OTCachedKey_SharedPtr pCachedKey(pPWData->GetCachedKey()); // Sometimes it's passed in, otherwise we use the global one.
+
+ if (!pCachedKey)
{
// Global one.
pCachedKey = OTCachedKey::It(); // Used to only use this one (global one) but now I allow pPWData to contain a pointer to the exact instance. (To enable multiple instances...) If that's not found then here we set it to the global one.
}
- OT_ASSERT(NULL != pCachedKey);
+ OT_ASSERT(pCachedKey);
// -------------------------------------
const bool b1 = pPWData->isForNormalNym();
const bool b3 = !(pCachedKey->isPaused());
@@ -2269,7 +2270,7 @@ OPENSSL_CALLBACK_FUNC(souped_up_pass_cb)
//
OTLog::vOutput(3, "%s: Using GetMasterPassword() call. \n", __FUNCTION__);
- bGotPassword = pCachedKey->GetMasterPassword(thePassword, str_userdata.c_str());//bool bVerifyTwice=false
+ bGotPassword = pCachedKey->GetMasterPassword(pCachedKey, thePassword, str_userdata.c_str());//bool bVerifyTwice=false
// NOTE: shouldn't the above call to GetMasterPassword be passing the rwflag as the final parameter?
// Just as we see below with the call to GetPasswordFromConsole. Right? Of course, it DOES generate internally,
Oops, something went wrong.

0 comments on commit 5600378

Please sign in to comment.