diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index 5faeecf06..1b0803c01 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -177,7 +177,7 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,Pa int i=0 ; while( (keydata = ops_keyring_get_key_by_index(_pubring,i)) != NULL ) { - _public_keyring_map[ PGPIdType(keydata->key_id).toUInt64() ] = i ; + initCertificateInfo(_public_keyring_map[ PGPIdType(keydata->key_id).toStdString() ],keydata,i) ; ++i ; } @@ -189,13 +189,39 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,Pa i=0 ; while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) { - _secret_keyring_map[ PGPIdType(keydata->key_id).toUInt64() ] = i ; + initCertificateInfo(_secret_keyring_map[ PGPIdType(keydata->key_id).toStdString() ],keydata,i) ; ++i ; } std::cerr << "Secring read successfully." << std::endl; } +void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) +{ + // Parse certificate name + // + std::string namestring( (char *)keydata->uids[0].user_id ) ; + + cert._name = "" ; + int i=0; + while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} + + std::string& next = (namestring[i] == '(')?cert._comment:cert._email ; + next = "" ; + while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} + next += namestring[i] ; + + next = (namestring[i] == '(')?cert._comment:cert._email ; + next = "" ; + while(i < namestring.length() && namestring[i] != '(' && namestring[i] != '<') { cert._name += namestring[i] ; ++i ;} + next += namestring[i] ; + + cert._trustLvl = 1 ; // to be setup accordingly + cert._key_index = index ; + + std::cerr << __PRETTY_FUNCTION__ << ": unfinished!!" << std::endl; +} + PGPHandler::~PGPHandler() { std::cerr << "Freeing PGPHandler. Deleting keyrings." << std::endl; @@ -209,13 +235,42 @@ PGPHandler::~PGPHandler() free(_secring) ; } -void PGPHandler::printKeys() const +bool PGPHandler::printKeys() const { - std::cerr << "Public keyring: " << std::endl; - ops_keyring_list(_pubring) ; + for(std::map::const_iterator it(_public_keyring_map.begin()); it != _public_keyring_map.end(); it++) + { + std::cerr << "PGP Key: " << it->first << std::endl; - std::cerr << "Secret keyring: " << std::endl; - ops_keyring_list(_secring) ; + std::cerr << "\tName : " << it->second._name << std::endl; + std::cerr << "\tEmail : " << it->second._email << std::endl; + std::cerr << "\tOwnSign : " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) << std::endl; + std::cerr << "\tAccept Connect: " << (it->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) << std::endl; + std::cerr << "\ttrustLvl : " << it->second._trustLvl << std::endl; + std::cerr << "\tvalidLvl : " << it->second._validLvl << std::endl; + + std::set::const_iterator sit; + for(sit = it->second.signers.begin(); sit != it->second.signers.end(); sit++) + { + std::cerr << "\t\tSigner ID:" << *sit << ", Name: " ; + const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType::fromUserId_hex(*sit)) ; + + if(info != NULL) + std::cerr << info->_name ; + + std::cerr << std::endl ; + } + } + return true ; +} + +const PGPCertificateInfo *PGPHandler::getCertificateInfo(const PGPIdType& id) const +{ + std::map::const_iterator it( _public_keyring_map.find(id.toStdString()) ) ; + + if(it != _public_keyring_map.end()) + return &it->second; + else + return NULL ; } bool PGPHandler::availableGPGCertificatesWithPrivateKeys(std::list& ids) @@ -305,14 +360,14 @@ bool PGPHandler::GeneratePGPCertificate(const std::string& name, const std::stri pgpId = PGPIdType(tmp_keyring->keys[0].key_id) ; addNewKeyToOPSKeyring(_secring,tmp_keyring->keys[0]) ; - _secret_keyring_map[ pgpId.toUInt64() ] = _secring->nkeys-1 ; + initCertificateInfo(_secret_keyring_map[ pgpId.toStdString() ],&tmp_keyring->keys[0],_secring->nkeys-1) ; std::cerr << "Added new secret key with id " << pgpId.toStdString() << " to secret keyring." << std::endl; // 5 - copy the private key to the public keyring addNewKeyToOPSKeyring(_pubring,tmp_keyring->keys[0]) ; - _public_keyring_map[ pgpId.toUInt64() ] = _pubring->nkeys-1 ; + initCertificateInfo(_public_keyring_map[ pgpId.toStdString() ],&tmp_keyring->keys[0],_pubring->nkeys-1) ; std::cerr << "Added new public key with id " << pgpId.toStdString() << " to public keyring." << std::endl; @@ -344,21 +399,21 @@ std::string PGPHandler::makeRadixEncodedPGPKey(const ops_keydata_t *key) const ops_keydata_t *PGPHandler::getSecretKey(const PGPIdType& id) const { - std::map::const_iterator res = _secret_keyring_map.find(id.toUInt64()) ; + std::map::const_iterator res = _secret_keyring_map.find(id.toStdString()) ; if(res == _secret_keyring_map.end()) return NULL ; else - return ops_keyring_get_key_by_index(_secring,res->second) ; + return ops_keyring_get_key_by_index(_secring,res->second._key_index) ; } const ops_keydata_t *PGPHandler::getPublicKey(const PGPIdType& id) const { - std::map::const_iterator res = _public_keyring_map.find(id.toUInt64()) ; + std::map::const_iterator res = _public_keyring_map.find(id.toStdString()) ; if(res == _public_keyring_map.end()) return NULL ; else - return ops_keyring_get_key_by_index(_pubring,res->second) ; + return ops_keyring_get_key_by_index(_pubring,res->second._key_index) ; } std::string PGPHandler::SaveCertificateToString(const PGPIdType& id,bool include_signatures) @@ -414,7 +469,7 @@ bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,PGPIdType id = PGPIdType(keydata->key_id) ; addNewKeyToOPSKeyring(_pubring,*keydata) ; - _public_keyring_map[id.toUInt64()] = _pubring->nkeys-1 ; + initCertificateInfo(_public_keyring_map[id.toStdString()],keydata,_pubring->nkeys-1) ; } std::cerr << "Added the key in the main public keyring." << std::endl; @@ -628,3 +683,42 @@ bool PGPHandler::VerifySignBin(const void *data, uint32_t data_len, unsigned cha return false ; } +void PGPHandler::setAcceptConnexion(const PGPIdType& id,bool b) +{ + std::map::iterator res = _public_keyring_map.find(id.toStdString()) ; + + if(res != _public_keyring_map.end()) + if(b) + res->second._flags |= PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; + else + res->second._flags &= ~PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; +} + +bool PGPHandler::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) const +{ + list.clear() ; + + for(std::map::const_iterator it(_public_keyring_map.begin());it!=_public_keyring_map.end();++it) + if( filter == NULL || (*filter)(it->second) ) + list.push_back(PGPIdType::fromUserId_hex(it->first)) ; + + return true ; +} + +bool PGPHandler::isGPGId(const std::string &id) +{ + return _public_keyring_map.find(id) != _public_keyring_map.end() ; +} + +bool PGPHandler::isGPGSigned(const std::string &id) +{ + std::map::const_iterator res = _public_keyring_map.find(id) ; + return res != _public_keyring_map.end() && (res->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) ; +} + +bool PGPHandler::isGPGAccepted(const std::string &id) +{ + std::map::const_iterator res = _public_keyring_map.find(id) ; + return res != _public_keyring_map.end() && (res->second._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE) ; +} + diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h index 3f1bf4a30..897b83f94 100644 --- a/libretroshare/src/pgp/pgphandler.h +++ b/libretroshare/src/pgp/pgphandler.h @@ -6,6 +6,7 @@ #include #include #include +#include #include extern "C" { @@ -33,6 +34,7 @@ class PGPIdType private: unsigned char bytes[KEY_ID_SIZE] ; + std::string _string_id ; }; class PGPFingerprintType { @@ -60,6 +62,32 @@ class PGPFingerprintType PGPFingerprintType() {} private: unsigned char bytes[KEY_FINGERPRINT_SIZE] ; + std::string _string_id ; +}; + +class PGPCertificateInfo +{ + public: + PGPCertificateInfo() {} + + std::string _name; + std::string _email; + std::string _comment; + + std::set signers; + + uint32_t _trustLvl; + uint32_t _validLvl; + uint32_t _flags ; + + PGPFingerprintType _fpr; /* fingerprint */ + PGPIdType _key_id ; + + uint32_t _key_index ; // index to array of keys in the public keyring + + static const uint32_t PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION = 0x0001 ; + static const uint32_t PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE = 0x0002 ; + static const uint32_t PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME = 0x0004 ; }; class PGPHandler @@ -72,6 +100,7 @@ class PGPHandler /** * @param ids list of gpg certificate ids (note, not the actual certificates) */ + bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) const ; bool availableGPGCertificatesWithPrivateKeys(std::list& ids); bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, PGPIdType& pgpId, std::string& errString) ; @@ -89,14 +118,24 @@ class PGPHandler bool getKeyFingerprint(const PGPIdType& id,PGPFingerprintType& fp) const ; + void setAcceptConnexion(const PGPIdType&,bool) ; + // Debug stuff. - virtual void printKeys() const ; + virtual bool printKeys() const ; + + const PGPCertificateInfo *getCertificateInfo(const PGPIdType& id) const ; + + bool isGPGId(const std::string &id); + bool isGPGSigned(const std::string &id); + bool isGPGAccepted(const std::string &id); private: static std::string makeRadixEncodedPGPKey(const ops_keydata_t *key) ; static ops_keyring_t *allocateOPSKeyring() ; static void addNewKeyToOPSKeyring(ops_keyring_t*, const ops_keydata_t&) ; + void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ; + const ops_keydata_t *getPublicKey(const PGPIdType&) const ; const ops_keydata_t *getSecretKey(const PGPIdType&) const ; @@ -105,8 +144,8 @@ class PGPHandler ops_keyring_t *_pubring ; ops_keyring_t *_secring ; - std::map _public_keyring_map ; // used for fast access to keys. Gives the index in the keyring. - std::map _secret_keyring_map ; + std::map _public_keyring_map ; // used for fast access to keys. Gives the index in the keyring. + std::map _secret_keyring_map ; const std::string _pubring_path ; const std::string _secring_path ; diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 44210e601..36246477a 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -42,6 +42,9 @@ #include "serialiser/rsconfigitems.h" #include "cleanupxpgp.h" +#define LIMIT_CERTIFICATE_SIZE 1 +#define MAX_CERTIFICATE_SIZE 10000 + const time_t STORE_KEY_TIMEOUT = 1 * 60 * 60; //store key is call around every hour AuthGPG *AuthGPG::_instance = NULL ; @@ -59,24 +62,19 @@ static std::string setKeyPairParams(bool useRsa, unsigned int blen, // static gpg_error_t trustCallback(void *, gpgme_status_code_t, const char *, int); // static std::string ProcessPGPmeError(gpgme_error_t ERR); -/* Function to sign X509_REQ via GPGme. - */ - -gpgcert::gpgcert() - : mHaveCachedCert(false) -{ -} +/* Function to sign X509_REQ via GPGme. */ bool AuthGPG::decryptTextFromFile(std::string& text,const std::string& inputfile) { return PGPHandler::decryptTextFromFile(mOwnGpgId,text,inputfile) ; } + bool AuthGPG::encryptTextToFile(const std::string& text,const std::string& outfile) { return PGPHandler::encryptTextToFile(mOwnGpgId,text,outfile) ; } -std::string pgp_pwd_callback(void * /*hook*/, const char *uid_hint, const char */*passphrase_info*/, int prev_was_bad) +std::string pgp_pwd_callback(void * /*hook*/, const char *uid_hint, const char * /*passphrase_info*/, int prev_was_bad) { #define GPG_DEBUG2 #ifdef GPG_DEBUG2 @@ -227,98 +225,61 @@ void AuthGPG::processServices() } AuthGPGOperationLoadOrSave *loadOrSave = dynamic_cast(operation); - if (loadOrSave) { - if (loadOrSave->m_load) { - /* process load operation */ + if (loadOrSave) + { + if (loadOrSave->m_load) + { + /* process load operation */ - /* load the certificate */ + /* load the certificate */ - /* don't bother loading - if we already have the certificate */ - if (isGPGId(loadOrSave->m_certGpgId)) - { + /* don't bother loading - if we already have the certificate */ + if (isGPGId(loadOrSave->m_certGpgId)) + { #ifdef GPG_DEBUG - std::cerr << "AuthGPGimpl::processServices() Skipping load - already have it" << std::endl; + std::cerr << "AuthGPGimpl::processServices() Skipping load - already have it" << std::endl; #endif - } - else - { + } + else + { #ifdef GPG_DEBUG - std::cerr << "AuthGPGimpl::processServices() Process load operation" << std::endl; + std::cerr << "AuthGPGimpl::processServices() Process load operation" << std::endl; #endif - std::string error_string ; - LoadCertificateFromString(loadOrSave->m_certGpg, loadOrSave->m_certGpgId,error_string); - } + std::string error_string ; + LoadCertificateFromString(loadOrSave->m_certGpg, loadOrSave->m_certGpgId,error_string); + } - } else { - /* process save operation */ + } else { + /* process save operation */ #ifdef GPG_DEBUG - std::cerr << "AuthGPGimpl::processServices() Process save operation" << std::endl; + std::cerr << "AuthGPGimpl::processServices() Process save operation" << std::endl; #endif - /* save the certificate to string */ -/***** - * #define DISABLE_CERTIFICATE_SEND 1 - ****/ + /* save the certificate to string */ + /***** + * #define DISABLE_CERTIFICATE_SEND 1 + ****/ -#define LIMIT_CERTIFICATE_SIZE 1 -#define MAX_CERTIFICATE_SIZE 10000 - - if (!getCachedGPGCertificate(loadOrSave->m_certGpgId, loadOrSave->m_certGpg)) - { - - -#ifdef DISABLE_CERTIFICATE_SEND - std::cerr << "AuthGPGimpl::processServices() Certificates Disabled" << std::endl; - loadOrSave->m_certGpg = ""; -#else - loadOrSave->m_certGpg = SaveCertificateToString(loadOrSave->m_certGpgId,true); - std::cerr << "AuthGPGimpl::processServices() Cert for: " << loadOrSave->m_certGpgId; - std::cerr << " is " << loadOrSave->m_certGpg.size() << " bytes"; - std::cerr << std::endl; - - #ifdef LIMIT_CERTIFICATE_SIZE - if (loadOrSave->m_certGpg.size() > MAX_CERTIFICATE_SIZE) - { - std::cerr << "AuthGPGimpl::processServices() Cert for: " << loadOrSave->m_certGpgId; - std::cerr << " is over size limit - switching to a minimal certificate"; - std::cerr << std::endl; - - std::string cleaned_key ; - if(PGPKeyManagement::createMinimalKey(loadOrSave->m_certGpg,cleaned_key)) - { - loadOrSave->m_certGpg = cleaned_key; - std::cerr << "AuthGPGimpl::processServices() Minimal Cert Generation, size"; - std::cerr << " is " << loadOrSave->m_certGpg.size() << " bytes"; - std::cerr << std::endl; - } - else - { - std::cerr << "AuthGPGimpl::processServices() Minimal Cert Generation Failed! removing cert"; - std::cerr << std::endl; - loadOrSave->m_certGpg = ""; - } - } - #endif - cacheGPGCertificate(loadOrSave->m_certGpgId, loadOrSave->m_certGpg); - } -#endif + loadOrSave->m_certGpg = SaveCertificateToString(loadOrSave->m_certGpgId,true); #ifdef GPG_DEBUG - std::cerr << "Certificate for: " << loadOrSave->m_certGpgId << " is: "; - std::cerr << std::endl; - std::cerr << loadOrSave->m_certGpg; - std::cerr << std::endl; + std::cerr << "Certificate for: " << loadOrSave->m_certGpgId << " is: "; + std::cerr << std::endl; + std::cerr << loadOrSave->m_certGpg; + std::cerr << std::endl; #endif - } + } - service->setGPGOperation(loadOrSave); - } else { + service->setGPGOperation(loadOrSave); + } + else + { #ifdef GPG_DEBUG std::cerr << "AuthGPGimpl::processServices() Unknown operation" << std::endl; #endif @@ -568,66 +529,6 @@ bool AuthGPG::storeAllKeys() return true; } -#endif - -bool AuthGPG::printAllKeys_locked() -{ - certmap::const_iterator it; - for(it = mKeyList.begin(); it != mKeyList.end(); it++) - { - std::cerr << "PGP Key: " << it->second.id << std::endl; - - std::cerr << "\tName: " << it->second.name << std::endl; - std::cerr << "\tEmail: " << it->second.email << std::endl; - - std::cerr << "\townsign: " << it->second.ownsign << std::endl; - std::cerr << "\ttrustLvl: " << it->second.trustLvl << std::endl; - std::cerr << "\tvalidLvl: " << it->second.validLvl << std::endl; - std::cerr << "\tEmail: " << it->second.email << std::endl; - - std::list::const_iterator sit; - for(sit = it->second.signers.begin(); - sit != it->second.signers.end(); sit++) - { - std::cerr << "\t\tSigner ID:" << *sit; - - /* do a naughty second search.. should be ok - * as we aren't modifying list. - */ - certmap::const_iterator kit = mKeyList.find(*sit); - if (kit != mKeyList.end()) - { - std::cerr << " Name:" << kit->second.name << std::endl; - } - } - } - return true; -} - -bool AuthGPG::printOwnKeys_locked() -{ - certmap::iterator it; - for(it = mKeyList.begin(); it != mKeyList.end(); it++) - { - if (it->second.ownsign) - { - std::cerr << "Own PGP Key: " << it->second.id << std::endl; - - std::cerr << "\tName: " << it->second.name << std::endl; - std::cerr << "\tEmail: " << it->second.email << std::endl; - } - } - return true; -} - -bool AuthGPG::printKeys() -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - printAllKeys_locked(); - return printOwnKeys_locked(); -} - -#ifdef TO_REMOVE std::string ProcessPGPmeError(gpgme_error_t ERR) { gpgme_err_code_t code = gpgme_err_code(ERR); @@ -713,98 +614,55 @@ bool AuthGPG::GeneratePGPCertificate(const std::string& name, /**** These Two are common */ std::string AuthGPG::getGPGName(const std::string &id) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) - return it->second.name; + const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType::fromUserId_hex(id)) ; - return std::string(); + if(info != NULL) + return info->_name ; + else + return "[Unknown PGP Cert name]" ; } /**** These Two are common */ std::string AuthGPG::getGPGEmail(const std::string &id) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType::fromUserId_hex(id)) ; - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) - return it->second.email; - - return std::string(); + if(info != NULL) + return info->_email ; + else + return "[Unknown PGP Cert email]" ; } /**** GPG versions ***/ std::string AuthGPG::getGPGOwnId() { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - return mOwnGpgId.toStdString(); + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + return mOwnGpgId.toStdString(); } std::string AuthGPG::getGPGOwnName() { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - return mOwnGpgCert.name; + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + return getGPGName(mOwnGpgId.toStdString()) ; } bool AuthGPG::getGPGAllList(std::list &ids) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + + std::list list ; + PGPHandler::getGPGFilteredList(list) ; + + for(std::list::const_iterator it(list.begin());it!=list.end();++it) + ids.push_back( (*it).toStdString() ) ; - /* add an id for each pgp certificate */ - certmap::iterator it; - for(it = mKeyList.begin(); it != mKeyList.end(); it++) - { - ids.push_back(it->first); - } return true; } -bool AuthGPG::getGPGDetails(const std::string &id, RsPeerDetails &d) -{ -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::getPGPDetails() called for : " << id << std::endl; -#endif - - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - - /* add an id for each pgp certificate */ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) - { - gpgcert &cert = it->second; - - d.id = cert.id; //keep, it but can be bug gen - d.gpg_id = cert.id; - d.name = cert.name; - d.email = cert.email; - d.trustLvl = cert.trustLvl; - d.validLvl = cert.validLvl; - d.ownsign = cert.ownsign; - d.gpgSigners = cert.signers; - d.fpr = cert.fpr; - - d.accept_connection = cert.accept_connection; - - //did the peer signed me ? - d.hasSignedMe = false; - std::list::iterator signersIt; - for(signersIt = mOwnGpgCert.signers.begin(); signersIt != mOwnGpgCert.signers.end() ; ++signersIt) - if (*signersIt == d.id) - { - d.hasSignedMe = true; - break; - } - -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::getPGPDetails() Name : " << cert.name << std::endl; -#endif - return true; - } - return false; -} - #ifdef TO_REMOVE bool AuthGPG::decryptText(gpgme_data_t CIPHER, gpgme_data_t PLAIN) { @@ -845,146 +703,80 @@ bool AuthGPG::encryptText(gpgme_data_t PLAIN, gpgme_data_t CIPHER) } #endif +bool AuthGPG::getGPGDetails(const std::string& id, RsPeerDetails &d) +{ + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + + const PGPCertificateInfo *pc = PGPHandler::getCertificateInfo(PGPIdType::fromUserId_hex(id)) ; + + if(pc == NULL) + return false ; + + const PGPCertificateInfo& cert(*pc) ; + + d.id = id ; + d.gpg_id = id ; + d.name = cert._name; + d.email = cert._email; + d.trustLvl = cert._trustLvl; + d.validLvl = cert._validLvl; + d.ownsign = cert._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE; + d.gpgSigners.clear() ; + for(std::set::const_iterator it(cert.signers.begin());it!=cert.signers.end();++it) + d.gpgSigners.push_back( *it ) ; + + d.fpr = cert._fpr.toStdString(); + + d.accept_connection = cert._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION; + d.hasSignedMe = cert._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME; + + return true; +} + +bool AuthGPG::getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&)) +{ + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + std::list ids ; + + PGPHandler::getGPGFilteredList(ids,filter) ; + + for(std::list::const_iterator it(ids.begin());it!=ids.end();++it) + list.push_back( (*it).toStdString() ) ; +} + +static bool filter_Validity(const PGPCertificateInfo& info) { return true ; } //{ return info._validLvl >= PGPCertificateInfo::GPGME_VALIDITY_MARGINAL ; } +static bool filter_Accepted(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; } +static bool filter_OwnSigned(const PGPCertificateInfo& info) { return info._flags & PGPCertificateInfo::PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; } + bool AuthGPG::getGPGValidList(std::list &ids) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - /* add an id for each pgp certificate */ - certmap::iterator it; - for(it = mKeyList.begin(); it != mKeyList.end(); it++) - { - if (it->second.validLvl >= GPGME_VALIDITY_MARGINAL) { - ids.push_back(it->first); - } - } - return true; + return getGPGFilteredList(ids,&filter_Validity); } bool AuthGPG::getGPGAcceptedList(std::list &ids) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - for(it = mKeyList.begin(); it != mKeyList.end(); it++) - { - if (it->second.accept_connection) - { - ids.push_back(it->first); - } - } - return true; + return getGPGFilteredList(ids,&filter_Accepted); } bool AuthGPG::getGPGSignedList(std::list &ids) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - for(it = mKeyList.begin(); it != mKeyList.end(); it++) - { - if (it->second.ownsign) - { - ids.push_back(it->first); - } - } - return true; + return getGPGFilteredList(ids,&filter_OwnSigned); } -bool AuthGPG::isGPGValid(const std::string &id) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) { - return (it->second.validLvl >= GPGME_VALIDITY_MARGINAL); - } else { - return false; - } - -} - -bool AuthGPG::isGPGId(const std::string &id) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) { - return true; - } else { - return false; - } -} - - -bool AuthGPG::isGPGSigned(const std::string &id) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) - { - return (it->second.ownsign); - } - return false; -} - -bool AuthGPG::isGPGAccepted(const std::string &id) -{ - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) - { - return (it->second.accept_connection); - } - return false; -} - - -bool AuthGPG::cacheGPGCertificate(const std::string &id, const std::string &certificate) -{ - - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) - { - it->second.mCachedCert = certificate; - it->second.mHaveCachedCert = true; -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::cacheGPGCertificate() success for: " << id; - std::cerr << std::endl; -#endif - - return true; - } - -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::cacheGPGCertificate() failed for: " << id; - std::cerr << std::endl; -#endif - return false; -} - - bool AuthGPG::getCachedGPGCertificate(const std::string &id, std::string &certificate) { - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(id))) - { - if (it->second.mHaveCachedCert) - { - certificate = it->second.mCachedCert; + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + certificate = PGPHandler::SaveCertificateToString(PGPIdType::fromUserId_hex(id),false) ; -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::getCachedGPGCertificate() success for: " << id; - std::cerr << std::endl; +#ifdef LIMIT_CERTIFICATE_SIZE + std::string cleaned_key ; + if(PGPKeyManagement::createMinimalKey(certificate,cleaned_key)) + certificate = cleaned_key ; #endif - return true; - } - } -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::getCachedGPGCertificate() failed for: " << id; - std::cerr << std::endl; -#endif - return false; + return certificate.length() > 0 ; } - /***************************************************************** * Loading and Saving Certificates - this has to * be able to handle both openpgp and X509 certificates. @@ -1046,7 +838,6 @@ bool AuthGPG::LoadCertificateFromString(const std::string &str, std::string &gpg /* These take PGP Ids */ bool AuthGPG::AllowConnection(const std::string &gpg_id, bool accept) { - #ifdef GPG_DEBUG std::cerr << "AuthGPG::AllowConnection(" << gpg_id << ")" << std::endl; #endif @@ -1054,13 +845,7 @@ bool AuthGPG::AllowConnection(const std::string &gpg_id, bool accept) /* Was a "Reload Certificates" here -> be shouldn't be needed -> and very expensive, try without. */ { RsStackMutex stack(gpgMtxData); - certmap::iterator it; - if (mKeyList.end() == (it = mKeyList.find(gpg_id))) - { - return false; - } - it->second.accept_connection = accept; - mAcceptToConnectMap[gpg_id] = accept; + PGPHandler::setAcceptConnexion(PGPIdType::fromUserId_hex(gpg_id),accept) ; } IndicateConfigChanged(); @@ -1834,28 +1619,22 @@ bool AuthGPG::saveList(bool& cleanup, std::list& lst) // Now save config for network digging strategies RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ; - std::map::iterator mapIt; - for (mapIt = mAcceptToConnectMap.begin(); mapIt != mAcceptToConnectMap.end(); mapIt++) - { - // skip our own id. - if (mapIt->first == mOwnGpgId.toStdString()) - { - continue; - } - // skip if we dont accept them. - if (!(mapIt->second)) - { - continue; - } - RsTlvKeyValue kv; - kv.key = mapIt->first; + std::list ids ; + getGPGAllList(ids) ; + + std::map::iterator mapIt; + for (std::list::const_iterator it(ids.begin()); it != ids.end(); ++it) + if((*it) != mOwnGpgId.toStdString()) // skip our own id. + { + RsTlvKeyValue kv; + kv.key = mapIt->first; #ifdef GPG_DEBUG - std::cerr << "AuthGPG::saveList() called (mapIt->second) : " << (mapIt->second) << std::endl ; + std::cerr << "AuthGPG::saveList() called (mapIt->second) : " << (mapIt->second) << std::endl ; #endif - kv.value = "TRUE"; - vitem->tlvkvs.pairs.push_back(kv) ; - } + kv.value = "TRUE"; + vitem->tlvkvs.pairs.push_back(kv) ; + } lst.push_back(vitem); return true; @@ -1863,17 +1642,14 @@ bool AuthGPG::saveList(bool& cleanup, std::list& lst) bool AuthGPG::loadList(std::list& load) { - #ifdef GPG_DEBUG - std::cerr << "AuthGPG::loadList() Item Count: " << load.size() << std::endl; - #endif +#ifdef GPG_DEBUG + std::cerr << "AuthGPG::loadList() Item Count: " << load.size() << std::endl; +#endif -// already stored in AuthGPG::InitAuth -// storeAllKeys(); - - RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ - /* load the list of accepted gpg keys */ - std::list::iterator it; - for(it = load.begin(); it != load.end(); it++) + RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ + /* load the list of accepted gpg keys */ + std::list::iterator it; + for(it = load.begin(); it != load.end(); it++) { RsConfigKeyValueSet *vitem = dynamic_cast(*it); if(vitem) @@ -1886,44 +1662,28 @@ bool AuthGPG::loadList(std::list& load) std::list::iterator kit; for(kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); kit++) - { - if (kit->key == mOwnGpgId.toStdString()) - { - continue; - } + if (kit->key != mOwnGpgId.toStdString()) + PGPHandler::setAcceptConnexion(PGPIdType::fromUserId_hex(kit->key), (kit->value == "TRUE")); + } + delete (*it); + } + return true; +} - /* only allowed in the map if the gpg certificate exists */ - certmap::iterator it; - if (mKeyList.end() != (it = mKeyList.find(kit->key))) - { -#ifdef GPG_DEBUG - std::cerr << "AuthGPG::loadList() setting accept to : " << (kit->value == "TRUE"); - std::cerr << " for gpg key id : " << kit->key << std::endl; -#endif - mAcceptToConnectMap[kit->key] = (kit->value == "TRUE"); - it->second.accept_connection = (kit->value == "TRUE"); - } - } - } - delete (*it); - } - return true; +bool AuthGPG::addService(AuthGPGService *service) +{ + RsStackMutex stack(gpgMtxService); /********* LOCKED *********/ + + if (std::find(services.begin(), services.end(), service) != services.end()) { + /* it exists already! */ + return false; + } + + services.push_back(service); + return true; } #ifdef TO_REMOVE -bool AuthGPG::addService(AuthGPGService *service) -{ - RsStackMutex stack(gpgMtxService); /********* LOCKED *********/ - - if (std::find(services.begin(), services.end(), service) != services.end()) { - /* it exists already! */ - return false; - } - - services.push_back(service); - return true; -} - /***************************** HACK to Cleanup OSX Zombies *****************************/ diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index c41aab8e6..bb3d1825c 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -58,56 +58,8 @@ class RsPeerDetails; /*! * gpgcert is the identifier for a person. - * It is a wrapper class for a GPGme OpenPGP certificate. + * It is a wrapper class for a OpenPGP certificate. */ -class AuthGPG; - -class gpgcert -{ - public: - gpgcert(); - ~gpgcert() {} - - std::string id; - std::string name; - std::string email; - - std::string fpr; /* fingerprint */ - std::list signers; - - uint32_t trustLvl; - uint32_t validLvl; - - bool ownsign; - - //This is not gpg, but RS data. A gpg peer can be accepted for connecting but not signed. - bool accept_connection; - - PGPIdType key_id ; - - // Cached Certificates... - bool mHaveCachedCert; - std::string mCachedCert; -}; - - -/*! - * The certificate map type - */ -typedef std::map certmap; - -//! provides basic gpg functionality -/*! - * - * This provides retroshare basic gpg functionality and - * key/web-of-trust management, also handle cert intialisation for retroshare - */ - -// extern void AuthGPGInit(); -// extern void AuthGPGExit(); - -/* The real implementation! */ - class AuthGPGOperation { @@ -164,7 +116,6 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler * @param ids list of gpg certificate ids (note, not the actual certificates) */ virtual bool availableGPGCertificatesWithPrivateKeys(std::list &ids); - virtual bool printKeys(); /*********************************************************************************/ /************************* STAGE 1 ***********************************************/ @@ -214,10 +165,6 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler virtual bool getGPGValidList(std::list &ids); virtual bool getGPGAcceptedList(std::list &ids); virtual bool getGPGSignedList(std::list &ids); - virtual bool isGPGValid(const std::string &id); - virtual bool isGPGSigned(const std::string &id); - virtual bool isGPGAccepted(const std::string &id); - virtual bool isGPGId(const std::string &id); /*********************************************************************************/ /************************* STAGE 4 ***********************************************/ @@ -230,7 +177,6 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler virtual std::string SaveCertificateToString(const std::string &id,bool include_signatures) ; // Cached certificates. - bool cacheGPGCertificate(const std::string &id, const std::string &certificate); bool getCachedGPGCertificate(const std::string &id, std::string &certificate); /*********************************************************************************/ @@ -265,10 +211,12 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler virtual bool decryptTextFromFile( std::string& text,const std::string& filename); virtual bool encryptTextToFile (const std::string& text,const std::string& filename); + bool getGPGFilteredList(std::list& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ; + //END of PGP public functions /* GPG service */ - virtual bool addService(AuthGPGService *service) { services.push_back(service) ; return true ;} + virtual bool addService(AuthGPGService *service) ; protected: AuthGPG(const std::string& path_to_pubring, const std::string& path_to_secring); @@ -317,7 +265,9 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler static AuthGPG *instance_gpg; // pointeur vers le singleton + RsMutex gpgMtxService; RsMutex gpgMtxEngine; + /* Below is protected via the mutex */ // gpgme_engine_info_t INFO; @@ -326,18 +276,11 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler RsMutex gpgMtxData; /* Below is protected via the mutex */ - certmap mKeyList; time_t mStoreKeyTime; - // bool gpgmeInit; - PGPIdType mOwnGpgId; - gpgcert mOwnGpgCert; bool gpgKeySelected; - std::map mAcceptToConnectMap; - - RsMutex gpgMtxService; std::list services ; static AuthGPG *_instance ; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index a5912cdf0..e4093687a 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -612,9 +612,8 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck */ /* create singletons */ AuthSSLInit(); - //AuthGPGInit(); - AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL); + AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL); // first check config directories, and set bootstrap values. if(!setupBaseDir()) @@ -622,6 +621,8 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck get_configinit(RsInitConfig::basedir, RsInitConfig::preferedId); + AuthGPG::init(RsInitConfig::basedir + "/pgp/retroshare_public_keyring.gpg",RsInitConfig::basedir + "/pgp/retroshare_secret_keyring.gpg"); + /* Initialize AuthGPG */ // if (AuthGPG::getAuthGPG()->InitAuth() == false) { // std::cerr << "AuthGPG::InitAuth failed" << std::endl;