ad a read / write lock and refactor authgpg with it

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2695 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
joss17 2010-04-08 19:07:40 +00:00
parent a2a567851e
commit 0f5214ff76
3 changed files with 209 additions and 159 deletions

View File

@ -126,72 +126,73 @@ static char *PgpPassword = NULL;
AuthGPG::AuthGPG()
:gpgmeInit(false),gpgmeKeySelected(false),p3Config(CONFIG_TYPE_AUTHGPG)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
{
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
setlocale(LC_ALL, "");
gpgme_check_version(NULL);
gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
setlocale(LC_ALL, "");
gpgme_check_version(NULL);
gpgme_set_locale(NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
#ifdef LC_MESSAGES
gpgme_set_locale(NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
#endif
#ifndef WINDOWS_SYS
/* setup the engine (gpg2) */
// if (GPG_ERR_NO_ERROR != gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, "/usr/bin/gpg2", NULL))
// {
// std::cerr << "Error creating Setting engine" << std::endl;
// return;
// }
#endif
#ifdef LC_MESSAGES
gpgme_set_locale(NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
#endif
if (GPG_ERR_NO_ERROR != gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP))
{
std::cerr << "Error check engine version" << std::endl;
return;
}
#ifndef WINDOWS_SYS
/* setup the engine (gpg2) */
// if (GPG_ERR_NO_ERROR != gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, "/usr/bin/gpg2", NULL))
// {
// std::cerr << "Error creating Setting engine" << std::endl;
// return;
// }
#endif
if (GPG_ERR_NO_ERROR != gpgme_get_engine_info(&INFO))
{
std::cerr << "Error getting engine info" << std::endl;
while (INFO && INFO->protocol != GPGME_PROTOCOL_OpenPGP) {
INFO = INFO->next;
}
if (!INFO) {
fprintf (stderr, "GPGME compiled without support for protocol %s",
gpgme_get_protocol_name (INFO->protocol));
} else if (INFO->file_name && !INFO->version) {
fprintf (stderr, "Engine %s not installed properly",
INFO->file_name);
} else if (INFO->file_name && INFO->version && INFO->req_version) {
fprintf (stderr, "Engine %s version %s installed, "
"but at least version %s required", INFO->file_name,
INFO->version, INFO->req_version);
} else {
fprintf (stderr, "Unknown problem with engine for protocol %s",
gpgme_get_protocol_name (INFO->protocol));
}
return;
}
if (GPG_ERR_NO_ERROR != gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP))
{
std::cerr << "Error check engine version" << std::endl;
return;
}
/* Create New Contexts */
if (GPG_ERR_NO_ERROR != gpgme_new(&CTX))
{
std::cerr << "Error creating GPGME Context" << std::endl;
return;
}
if (GPG_ERR_NO_ERROR != gpgme_get_engine_info(&INFO))
{
std::cerr << "Error getting engine info" << std::endl;
while (INFO && INFO->protocol != GPGME_PROTOCOL_OpenPGP) {
INFO = INFO->next;
}
if (!INFO) {
fprintf (stderr, "GPGME compiled without support for protocol %s",
gpgme_get_protocol_name (INFO->protocol));
} else if (INFO->file_name && !INFO->version) {
fprintf (stderr, "Engine %s not installed properly",
INFO->file_name);
} else if (INFO->file_name && INFO->version && INFO->req_version) {
fprintf (stderr, "Engine %s version %s installed, "
"but at least version %s required", INFO->file_name,
INFO->version, INFO->req_version);
} else {
fprintf (stderr, "Unknown problem with engine for protocol %s",
gpgme_get_protocol_name (INFO->protocol));
}
return;
}
/* setup the protocol */
if (GPG_ERR_NO_ERROR != gpgme_set_protocol(CTX, GPGME_PROTOCOL_OpenPGP))
{
std::cerr << "Error creating Setting Protocol" << std::endl;
return;
}
/* Create New Contexts */
if (GPG_ERR_NO_ERROR != gpgme_new(&CTX))
{
std::cerr << "Error creating GPGME Context" << std::endl;
return;
}
gpgme_set_passphrase_cb(CTX, pgp_pwd_callback, (void *) NULL);
/* setup the protocol */
if (GPG_ERR_NO_ERROR != gpgme_set_protocol(CTX, GPGME_PROTOCOL_OpenPGP))
{
std::cerr << "Error creating Setting Protocol" << std::endl;
return;
}
/* if we get to here -> we have inited okay */
gpgmeInit = true;
gpgme_set_passphrase_cb(CTX, pgp_pwd_callback, (void *) NULL);
gpgmeInit = true;
}
storeAllKeys_locked();
#ifdef GPG_DEBUG
@ -209,17 +210,17 @@ AuthGPG::AuthGPG()
*/
bool AuthGPG::availableGPGCertificatesWithPrivateKeys(std::list<std::string> &ids)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
int i = 0;
gpgme_key_t KEY = NULL;
gpg_error_t ERR;
/* XXX should check that CTX is valid */
if (!gpgmeInit)
{
return false;
}
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
if (!gpgmeInit)
{
return false;
}
/* Initiates a key listing */
@ -269,36 +270,43 @@ bool AuthGPG::availableGPGCertificatesWithPrivateKeys(std::list<std::string> &id
*/
int AuthGPG::GPGInit(std::string ownId)
{
is_set_gpg_password_static= false;
std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId << std::endl;
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
std::cerr << "AuthGPG::GPGInit() called with own gpg id : " << ownId << std::endl;
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
is_set_gpg_password_static= false;
if (!gpgmeInit) {
return 0;
}
mOwnGpgId = ownId;
storeAllKeys_locked();
}
storeAllKeys_locked();
int lvl = 0;
{
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
if (mOwnGpgCert.id != mOwnGpgId) {
std::cerr << "AuthGPG::GPGInit() failed to find your id." << std::endl;
return 0;
}
gpgmeKeySelected = true;
lvl = mOwnGpgCert.validLvl;
}
//check the validity of the private key. When set to unknown, it caused signature and text encryptions bugs
if (mOwnGpgCert.validLvl < 2) {
if (lvl < 2) {
std::cerr << "AuthGPG::GPGInit() abnormal validity set to private key. Switch it to none by default." << std::endl;
privateTrustCertificate(mOwnGpgId, 4);
}
gpgmeKeySelected = true;
//printAllKeys_locked();
std::cerr << "AuthGPG::GPGInit finished." << std::endl;
return true;
@ -313,10 +321,9 @@ bool AuthGPG::storeAllKeys_timed() {
std::cerr << "AuthGPG::storeAllKeys_timed() called." << std::endl;
#endif
if ((time(NULL) - mStoreKeyTime) > STORE_KEY_TIMEOUT) {
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
storeAllKeys_locked();
}
return true ;
return true ;
}
// store all keys in map mKeyList to avoid callin gpgme exe repeatedly
@ -325,9 +332,10 @@ bool AuthGPG::storeAllKeys_locked()
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::storeAllKeys_locked()" << std::endl;
#endif
mStoreKeyTime = time(NULL);
gpg_error_t ERR;
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
gpg_error_t ERR;
if (!gpgmeInit)
{
std::cerr << "AuthGPG::storeAllKeys_locked() Error since GPG is not initialised" << std::endl;
@ -358,7 +366,8 @@ bool AuthGPG::storeAllKeys_locked()
return false;
}
/* Loop until end of key */
/* Loop until end of key */
mStoreKeyTime = time(NULL);
ERR = gpgme_op_keylist_next (CTX, &KEY);
if (GPG_ERR_NO_ERROR != ERR) {
std::cerr << "AuthGPG::storeAllKeys_locked() didn't find any gpg key in the keyring" << std::endl;
@ -408,7 +417,6 @@ bool AuthGPG::storeAllKeys_locked()
/* NB uids is a linked list and can contain multiple ids.
* first id is primary.
*/
gpgme_user_id_t mainuid = KEY->uids;
nu.name = mainuid->name;
nu.email = mainuid->email;
@ -503,7 +511,7 @@ bool AuthGPG::storeAllKeys_locked()
}
// update trust on all available keys.
// update trust on all available keys. Not used anymore
bool AuthGPG::updateTrustAllKeys_locked()
{
gpg_error_t ERR;
@ -624,7 +632,7 @@ bool AuthGPG::printOwnKeys_locked()
bool AuthGPG::printKeys()
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
printAllKeys_locked();
return printOwnKeys_locked();
}
@ -672,6 +680,7 @@ void print_pgpme_verify_summary(unsigned int summary)
bool AuthGPG::DoOwnSignature_locked(const void *data, unsigned int datalen, void *buf_sigout, unsigned int *outl)
{
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
/* setup signers */
gpgme_signers_clear(CTX);
if (GPG_ERR_NO_ERROR != gpgme_signers_add(CTX, mOwnGpgCert.key))
@ -763,7 +772,8 @@ bool AuthGPG::VerifySignature_locked(const void *data, int datalen, const void *
#ifdef GPG_DEBUG
std::cerr << "VerifySignature: datalen: " << datalen << " siglen: " << siglen << std::endl;
#endif
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
if(!(gpgmeInit || gpgmeKeySelected))
return false ;
@ -846,7 +856,6 @@ bool AuthGPG::VerifySignature_locked(const void *data, int datalen, const void *
{
fprintf(stderr, "AuthGPG::VerifySignature() FAILED\n");
}
return valid;
}
@ -856,12 +865,15 @@ bool AuthGPG::VerifySignature_locked(const void *data, int datalen, const void *
bool AuthGPG::active()
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
return ((gpgmeInit) && (gpgmeKeySelected));
}
bool AuthGPG::GeneratePGPCertificate(std::string name, std::string email, std::string passwd, std::string &pgpId, std::string &errString) {
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
gpgme_key_t newKey;
gpgme_genkey_result_t result;
gpg_error_t ERR;
@ -895,7 +907,8 @@ bool AuthGPG::CloseAuth()
std::string AuthGPG::getGPGName(GPG_id id)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id)))
@ -908,7 +921,8 @@ std::string AuthGPG::getGPGName(GPG_id id)
std::string AuthGPG::getGPGEmail(GPG_id id)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id)))
@ -921,20 +935,20 @@ std::string AuthGPG::getGPGEmail(GPG_id id)
std::string AuthGPG::getGPGOwnId()
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
return mOwnGpgId;
}
std::string AuthGPG::getGPGOwnName()
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
return mOwnGpgCert.name;
}
bool AuthGPG::getGPGAllList(std::list<std::string> &ids)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
/* add an id for each pgp certificate */
certmap::iterator it;
@ -952,7 +966,7 @@ bool AuthGPG::getGPGDetails(std::string id, RsPeerDetails &d)
#endif
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
/* add an id for each pgp certificate */
certmap::iterator it;
@ -989,7 +1003,7 @@ bool AuthGPG::getGPGDetails(std::string id, RsPeerDetails &d)
}
bool AuthGPG::decryptText(gpgme_data_t CIPHER, gpgme_data_t PLAIN) {
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
gpgme_set_armor (CTX, 1);
gpg_error_t ERR;
if (GPG_ERR_NO_ERROR != (ERR = gpgme_op_decrypt (CTX, CIPHER, PLAIN)))
@ -1003,7 +1017,7 @@ bool AuthGPG::decryptText(gpgme_data_t CIPHER, gpgme_data_t PLAIN) {
}
bool AuthGPG::encryptText(gpgme_data_t PLAIN, gpgme_data_t CIPHER) {
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
gpgme_encrypt_flags_t* flags = new gpgme_encrypt_flags_t();
gpgme_key_t keys[2] = {mOwnGpgCert.key, NULL};
gpgme_set_armor (CTX, 1);
@ -1021,7 +1035,7 @@ bool AuthGPG::encryptText(gpgme_data_t PLAIN, gpgme_data_t CIPHER) {
bool AuthGPG::getGPGValidList(std::list<std::string> &ids)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
/* add an id for each pgp certificate */
certmap::iterator it;
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
@ -1036,7 +1050,7 @@ bool AuthGPG::getGPGValidList(std::list<std::string> &ids)
bool AuthGPG::getGPGAcceptedList(std::list<std::string> &ids)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
{
@ -1051,7 +1065,7 @@ bool AuthGPG::getGPGAcceptedList(std::list<std::string> &ids)
bool AuthGPG::getGPGSignedList(std::list<std::string> &ids)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
{
@ -1066,7 +1080,7 @@ bool AuthGPG::getGPGSignedList(std::list<std::string> &ids)
bool AuthGPG::isGPGValid(GPG_id id)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id))) {
return (it->second.validLvl >= GPGME_VALIDITY_MARGINAL);
@ -1079,7 +1093,7 @@ bool AuthGPG::isGPGValid(GPG_id id)
bool AuthGPG::isGPGId(GPG_id id)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id))) {
return true;
@ -1092,7 +1106,7 @@ bool AuthGPG::isGPGId(GPG_id id)
bool AuthGPG::isGPGSigned(GPG_id id)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id)))
{
@ -1104,7 +1118,7 @@ bool AuthGPG::isGPGSigned(GPG_id id)
bool AuthGPG::isGPGAccepted(GPG_id id)
{
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() != (it = mKeyList.find(id)))
{
@ -1132,7 +1146,7 @@ std::string AuthGPG::SaveCertificateToString(std::string id)
}
storeAllKeys_timed();
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
std::string tmp;
const char *pattern[] = { NULL, NULL };
@ -1176,60 +1190,61 @@ std::string AuthGPG::SaveCertificateToString(std::string id)
/* import to GnuPG and other Certificates */
bool AuthGPG::LoadCertificateFromString(std::string str, std::string &gpg_id)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
if (str == "") {
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::LoadCertificateFromString() cert is empty string, returning false." << std::endl;
#endif
return false;
}
int imported = 0;
std::string fingerprint;
//std::string cleancert = cleanUpCertificate(str); disable for p3disc message on windows system. Move the clean cert in p3peers
std::string cleancert = str;
{
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
//std::string cleancert = cleanUpCertificate(str); disable for p3disc message on windows system. Move the clean cert in p3peers
std::string cleancert = str;
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::LoadCertificateFromString() cleancert : " << cleancert;
#endif
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::LoadCertificateFromString() cleancert : " << cleancert;
#endif
gpgme_data_t gpgmeData;
if (GPG_ERR_NO_ERROR != gpgme_data_new_from_mem(&gpgmeData, cleancert.c_str(), cleancert.length(), 1))
{
std::cerr << "Error create Data" << std::endl;
return false;
}
gpgme_data_t gpgmeData;
if (GPG_ERR_NO_ERROR != gpgme_data_new_from_mem(&gpgmeData, cleancert.c_str(), cleancert.length(), 1))
{
std::cerr << "Error create Data" << std::endl;
return false;
}
/* move string data to gpgmeData */
/* move string data to gpgmeData */
gpgme_set_armor (CTX, 1);
if (GPG_ERR_NO_ERROR != gpgme_op_import (CTX,gpgmeData))
{
std::cerr << "AuthGPG::LoadCertificateFromString() Error Importing Certificate" << std::endl;
return false ;
}
gpgme_set_armor (CTX, 1);
if (GPG_ERR_NO_ERROR != gpgme_op_import (CTX,gpgmeData))
{
std::cerr << "AuthGPG::LoadCertificateFromString() Error Importing Certificate" << std::endl;
return false ;
}
gpgme_import_result_t res = gpgme_op_import_result(CTX);
gpgme_import_result_t res = gpgme_op_import_result(CTX);
if(res->imports == NULL)
return false ;
if(res == NULL || res->imports == NULL)
return false ;
std::string fingerprint = std::string(res->imports->fpr);
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::LoadCertificateFromString() Importing considered folowing fpr : " << fingerprint << std::endl;
#endif
std::string fingerprint = std::string(res->imports->fpr);
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::LoadCertificateFromString() Importing considered folowing fpr : " << fingerprint << std::endl;
#endif
int imported = res->imported;
imported = res->imported;
#ifdef GPG_DEBUG
fprintf(stderr, "ImportCertificate(Considered: %d Imported: %d)\n",
res->considered, res->imported);
#endif
#ifdef GPG_DEBUG
fprintf(stderr, "ImportCertificate(Considered: %d Imported: %d)\n",
res->considered, res->imported);
#endif
/* do we need to delete res??? */
gpgme_data_release (gpgmeData);
/* do we need to delete res??? */
gpgme_data_release (gpgmeData);
}
/* extract id(s)! (only if we actually imported one) */
if (imported) {
@ -1237,6 +1252,7 @@ bool AuthGPG::LoadCertificateFromString(std::string str, std::string &gpg_id)
}
//retrieve the id of the key
certmap::iterator it;
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
for(it = mKeyList.begin(); it != mKeyList.end(); it++)
{
if (it->second.fpr == fingerprint)
@ -1273,10 +1289,9 @@ bool AuthGPG::setAcceptToConnectGPGCertificate(std::string gpg_id, bool acceptan
std::cerr << "AuthGPG::markGPGCertificateAsFriends(" << gpg_id << ")" << std::endl;
#endif
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
/* reload stuff now ... */
storeAllKeys_locked();
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() == (it = mKeyList.find(gpg_id))) {
return false;
@ -1297,22 +1312,20 @@ bool AuthGPG::SignCertificateLevel0(GPG_id id)
std::cerr << "AuthGPG::SignCertificat(" << id << ")" << std::endl;
#endif
if (1 != privateSignCertificate(id))
{
storeAllKeys_locked();
return false;
}
/* reload stuff now ... */
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
/* reload stuff now ... */
storeAllKeys_locked();
return true;
}
bool AuthGPG::RevokeCertificate(std::string id)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
//RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::RevokeCertificate(" << id << ") not implemented yet" << std::endl;
@ -1326,7 +1339,15 @@ bool AuthGPG::TrustCertificate(std::string id, int trustlvl)
#ifdef GPG_DEBUG
std::cerr << "AuthGPG::TrustCertificate(" << id << ", " << trustlvl << ")" << std::endl;
#endif
return this->privateTrustCertificate(id, trustlvl);
if (1 != privateTrustCertificate(id, trustlvl))
{
storeAllKeys_locked();
return false;
}
/* reload stuff now ... */
storeAllKeys_locked();
return true;
}
bool AuthGPG::SignData(std::string input, std::string &sign)
@ -1346,13 +1367,11 @@ bool AuthGPG::SignDataBin(std::string input, unsigned char *sign, unsigned int *
}
bool AuthGPG::SignDataBin(const void *data, unsigned int datalen, unsigned char *sign, unsigned int *signlen) {
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
return DoOwnSignature_locked(data, datalen,
sign, signlen);
}
bool AuthGPG::VerifySignBin(const void *data, uint32_t datalen, unsigned char *sign, unsigned int signlen, std::string withfingerprint) {
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
return VerifySignature_locked(data, datalen,
sign, signlen, withfingerprint);
}
@ -1362,12 +1381,12 @@ bool AuthGPG::VerifySignBin(const void *data, uint32_t datalen, unsigned char *s
int AuthGPG::privateSignCertificate(std::string id)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
/* The key should be in Others list and not in Peers list ??
* Once the key is signed, it moves from Others to Peers list ???
*/
certmap::iterator it;
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
certmap::iterator it;
if (mKeyList.end() == (it = mKeyList.find(id)))
{
return false;
@ -1390,7 +1409,7 @@ int AuthGPG::privateSignCertificate(std::string id)
return 0;
}
delete &stack;
if(GPG_ERR_NO_ERROR != (ERR = gpgme_op_edit(CTX, signKey, keySignCallback, &params, out))) {
return 0;
}
@ -1401,7 +1420,7 @@ int AuthGPG::privateSignCertificate(std::string id)
/* revoke the signature on Certificate */
int AuthGPG::privateRevokeCertificate(std::string id)
{
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
//RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
return 0;
}
@ -1414,7 +1433,8 @@ int AuthGPG::privateTrustCertificate(std::string id, int trustlvl)
return 0;
}
gpgcert trustCert = mKeyList.find(id)->second;
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
gpgcert trustCert = mKeyList.find(id)->second;
gpgme_key_t trustKey = trustCert.key;
std::string trustString;
std::ostringstream trustStrOut;
@ -1434,9 +1454,6 @@ int AuthGPG::privateTrustCertificate(std::string id, int trustlvl)
//the key ref has changed, we got to get rid of the old reference.
trustCert.key = NULL;
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
storeAllKeys_locked();
return 1;
}
@ -2073,7 +2090,7 @@ std::list<RsItem*> AuthGPG::saveList(bool& cleanup)
std::cerr << "AuthGPG::saveList() called" << std::endl ;
#endif
RsStackMutex stack(pgpMtx); /******* LOCKED ******/
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::READ_LOCK); /******* LOCKED ******/
cleanup = true ;
std::list<RsItem*> lst ;
@ -2105,10 +2122,9 @@ bool AuthGPG::loadList(std::list<RsItem*> load)
std::cerr << "AuthGPG::loadList() Item Count: " << load.size() << std::endl;
#endif
RsStackMutex stack(pgpMtx); /****** STACK LOCK MUTEX *******/
storeAllKeys_locked();
RsStackReadWriteMutex stack(pgpMtx, RsReadWriteMutex::WRITE_LOCK); /******* LOCKED ******/
/* load the list of accepted gpg keys */
std::list<RsItem *>::iterator it;
for(it = load.begin(); it != load.end(); it++) {

View File

@ -230,7 +230,7 @@ private:
static AuthGPG *instance_gpg; // pointeur vers le singleton
RsMutex pgpMtx;
RsReadWriteMutex pgpMtx;
/* Below is protected via the mutex */
certmap mKeyList;

View File

@ -39,7 +39,7 @@ class RsMutex
public:
RsMutex()
{
{
pthread_mutex_init(&realMutex, NULL);
#ifdef RSTHREAD_SELF_LOCKING_GUARD
_thread_id = 0 ;
@ -98,6 +98,40 @@ class RsStackMutex
RsMutex &mMtx;
};
class RsReadWriteMutex: public RsMutex
{
public:
RsReadWriteMutex(): readLocks(0) { }
void readLock() { if (readLocks == 0) {lock();} ; readLocks++;}
void readUnlock() { if (readLocks == 1) {unlock();} if (readLocks != 0) {readLocks--;} }
void writeLock() {lock();}
void writeUnlock() {unlock();}
void rwlock(uint32_t type) { if (type & READ_LOCK) {readLock();} else {writeLock();} }
void rwunlock(uint32_t type) { if (type & READ_LOCK) {readUnlock();} else {writeUnlock();} }
const static uint32_t READ_LOCK = 0x0001;
const static uint32_t WRITE_LOCK = 0x0002;
private:
int readLocks;
};
class RsStackReadWriteMutex
{
public:
RsStackReadWriteMutex(RsReadWriteMutex &mtx): mMtx(mtx) { mMtx.writeLock(); writeLock = true;}
RsStackReadWriteMutex(RsReadWriteMutex &mtx, uint32_t type): mMtx(mtx) { if (type == RsReadWriteMutex::READ_LOCK) {mMtx.readLock(); writeLock = false;} else {mMtx.writeLock(); writeLock = true;} }
~RsStackReadWriteMutex() { if(writeLock) {mMtx.writeUnlock();} else {mMtx.readUnlock();} }
private:
RsReadWriteMutex &mMtx;
bool writeLock;
};
class RsThread;
/* to create a thread! */