From 9357a228a614dbe21a667303eaf11d10b5ac7b76 Mon Sep 17 00:00:00 2001 From: csoler Date: Wed, 20 Jun 2012 21:59:04 +0000 Subject: [PATCH] added read/write of trust database in private format git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-OpenPGP@5237 b45a01b8-16f6-495d-af2f-9b41ad6348cc --- libretroshare/src/pgp/pgphandler.cc | 100 ++++++++++++++++++++++++++- libretroshare/src/pgp/pgphandler.h | 12 +++- libretroshare/src/pqi/authgpg.cc | 10 +-- libretroshare/src/pqi/authgpg.h | 8 ++- libretroshare/src/rsserver/rsinit.cc | 5 +- 5 files changed, 125 insertions(+), 10 deletions(-) diff --git a/libretroshare/src/pgp/pgphandler.cc b/libretroshare/src/pgp/pgphandler.cc index 07121766d..6b12e91ac 100644 --- a/libretroshare/src/pgp/pgphandler.cc +++ b/libretroshare/src/pgp/pgphandler.cc @@ -69,11 +69,12 @@ void PGPHandler::setPassphraseCallback(PassphraseCallback cb) _passphrase_callback = cb ; } -PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,const std::string& pgp_lock_filename) - : pgphandlerMtx(std::string("PGPHandler")), _pubring_path(pubring),_secring_path(secring),_pgp_lock_filename(pgp_lock_filename) +PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,const std::string& trustdb,const std::string& pgp_lock_filename) + : pgphandlerMtx(std::string("PGPHandler")), _pubring_path(pubring),_secring_path(secring),_trustdb_path(trustdb),_pgp_lock_filename(pgp_lock_filename) { _pubring_changed = false ; _secring_changed = false ; + _trustdb_changed = false ; RsStackFileLock flck(_pgp_lock_filename) ; // lock access to PGP directory. @@ -144,6 +145,8 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring,co } std::cerr << "Secring read successfully." << std::endl; + + locked_readPrivateTrustDatabase() ; } void PGPHandler::initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t index) @@ -728,4 +731,97 @@ bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) return to_add.size() > 0 ; } +void PGPHandler::privateTrustCertificate(const PGPIdType& id,int trustlvl) +{ + if(trustlvl < 0 || trustlvl > 6) + { + std::cerr << "Invalid trust level " << trustlvl << " passed to privateTrustCertificate." << std::endl; + return ; + } + + std::map::iterator it = _public_keyring_map.find(id.toStdString()); + + if(it == _public_keyring_map.end()) + { + std::cerr << "(EE) Key id " << id.toStdString() << " not in the keyring. Can't setup trust level." << std::endl; + return ; + } + + if( it->second._validLvl != trustlvl ) + _trustdb_changed = true ; + + it->second._validLvl = trustlvl ; +} + +struct PrivateTrustPacket +{ + unsigned char user_id[KEY_ID_SIZE] ; // pgp id in unsigned char format. + uint8_t trust_level ; // trust level. From 0 to 6. + uint32_t flags ; // not used yet, but who knows? +}; + +void PGPHandler::locked_readPrivateTrustDatabase() +{ + FILE *fdb = fopen(_trustdb_path.c_str(),"rb") ; + std::cerr << "PGPHandler: Reading private trust database." << std::endl; + + if(fdb == NULL) + { + std::cerr << " private trust database not found. No trust info loaded." << std::endl ; + return ; + } + std::map::iterator it ; + PrivateTrustPacket trustpacket; + + while(fread((void*)&trustpacket,sizeof(PrivateTrustPacket),1,fdb) == 1) + { + it = _public_keyring_map.find(PGPIdType(trustpacket.user_id).toStdString()) ; + + if(it == _public_keyring_map.end()) + { + std::cerr << " (WW) Trust packet found for unknown key id " << PGPIdType(trustpacket.user_id).toStdString() << std::endl; + continue ; + } + if(trustpacket.trust_level > 6) + { + std::cerr << " (WW) Trust packet found with unexpected trust level " << trustpacket.trust_level << std::endl; + continue ; + } + + it->second._validLvl = trustpacket.trust_level ; + } + + fclose(fdb) ; +} + +void PGPHandler::locked_writePrivateTrustDatabase() +{ + FILE *fdb = fopen((_trustdb_path+".tmp").c_str(),"wb") ; + std::cerr << "PGPHandler: Reading private trust database." << std::endl; + + if(fdb == NULL) + { + std::cerr << " (EE) Can't open private trust database file " << _trustdb_path << " for write. Giving up!" << std::endl ; + return ; + } + PrivateTrustPacket trustpacket ; + + for(std::map::iterator it = _public_keyring_map.begin();it!=_public_keyring_map.end() ;++it) + { + memcpy(&trustpacket.user_id,PGPIdType(it->first).toByteArray(),KEY_ID_SIZE) ; + trustpacket.trust_level = it->second._validLvl ; + + if(fwrite((void*)&trustpacket,sizeof(PrivateTrustPacket),1,fdb) != 1) + { + std::cerr << " (EE) Cannot write to trust database " << _trustdb_path << ". Disc full, or quota exceeded ? Leaving database untouched." << std::endl; + fclose(fdb) ; + return ; + } + } + + fclose(fdb) ; + + if(!RsDirUtil::renameFile(_trustdb_path+".tmp",_trustdb_path)) + std::cerr << " (EE) Cannot move temp file " << _trustdb_path+".tmp" << ". Bad write permissions?" << std::endl; +} diff --git a/libretroshare/src/pgp/pgphandler.h b/libretroshare/src/pgp/pgphandler.h index 5dd4e8f4a..9d767442c 100644 --- a/libretroshare/src/pgp/pgphandler.h +++ b/libretroshare/src/pgp/pgphandler.h @@ -53,7 +53,10 @@ class PGPCertificateInfo class PGPHandler { public: - PGPHandler(const std::string& path_to_public_keyring, const std::string& path_to_secret_keyring, const std::string& pgp_lock_file) ; + PGPHandler( const std::string& path_to_public_keyring, + const std::string& path_to_secret_keyring, + const std::string& path_to_trust_database, + const std::string& pgp_lock_file) ; virtual ~PGPHandler() ; @@ -81,6 +84,8 @@ class PGPHandler bool isKeySupported(const PGPIdType& id) const ; + void privateTrustCertificate(const PGPIdType& id,int valid_level) ; + // Write keyring bool publicKeyringChanged() const { return _pubring_changed ; } bool secretKeyringChanged() const { return _secring_changed ; } @@ -107,6 +112,9 @@ class PGPHandler const ops_keydata_t *getPublicKey(const PGPIdType&) const ; const ops_keydata_t *getSecretKey(const PGPIdType&) const ; + void locked_readPrivateTrustDatabase() ; + void locked_writePrivateTrustDatabase() ; + // Members. // RsMutex pgphandlerMtx ; @@ -119,10 +127,12 @@ class PGPHandler const std::string _pubring_path ; const std::string _secring_path ; + const std::string _trustdb_path ; const std::string _pgp_lock_filename ; bool _pubring_changed ; bool _secring_changed ; + bool _trustdb_changed ; // Helper functions. // diff --git a/libretroshare/src/pqi/authgpg.cc b/libretroshare/src/pqi/authgpg.cc index 84af2f2df..5f5a04d04 100644 --- a/libretroshare/src/pqi/authgpg.cc +++ b/libretroshare/src/pqi/authgpg.cc @@ -86,7 +86,7 @@ std::string pgp_pwd_callback(void * /*hook*/, const char *uid_hint, const char * return password ; } -void AuthGPG::init(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& pgp_lock_file) +void AuthGPG::init(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) { if(_instance != NULL) { @@ -95,7 +95,7 @@ void AuthGPG::init(const std::string& path_to_public_keyring,const std::string& } PGPHandler::setPassphraseCallback(pgp_pwd_callback) ; - _instance = new AuthGPG(path_to_public_keyring,path_to_secret_keyring,pgp_lock_file) ; + _instance = new AuthGPG(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file) ; } void AuthGPG::exit() @@ -108,9 +108,9 @@ void AuthGPG::exit() } } -AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& pgp_lock_file) +AuthGPG::AuthGPG(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring,const std::string& path_to_trustdb,const std::string& pgp_lock_file) :p3Config(CONFIG_TYPE_AUTHGPG), - PGPHandler(path_to_public_keyring,path_to_secret_keyring,pgp_lock_file), + PGPHandler(path_to_public_keyring,path_to_secret_keyring,path_to_trustdb,pgp_lock_file), gpgMtxEngine("AuthGPG-engine"), gpgMtxData("AuthGPG-data"), gpgKeySelected(false), @@ -1048,6 +1048,8 @@ int AuthGPG::privateTrustCertificate(const std::string &id, int trustlvl) std::cerr << __PRETTY_FUNCTION__ << ": to be implemented!" << std::endl; + PGPHandler::privateTrustCertificate(PGPIdType(id),trustlvl) ; + // { // gpgcert trustCert; // { diff --git a/libretroshare/src/pqi/authgpg.h b/libretroshare/src/pqi/authgpg.h index f5d047c8c..2e9d7780f 100644 --- a/libretroshare/src/pqi/authgpg.h +++ b/libretroshare/src/pqi/authgpg.h @@ -109,7 +109,11 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler { public: - static void init(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& pgp_lock_file); + static void init( const std::string& path_to_pubring, + const std::string& path_to_secring, + const std::string& path_to_trustdb, + const std::string& pgp_lock_file); + static void exit(); static AuthGPG *getAuthGPG() { return _instance ; } @@ -221,7 +225,7 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler virtual bool addService(AuthGPGService *service) ; protected: - AuthGPG(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& pgp_lock_file); + AuthGPG(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& path_to_trustdb,const std::string& pgp_lock_file); virtual ~AuthGPG(); /*****************************************************************/ diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 4d9883836..ec326b393 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -616,7 +616,10 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck if(!RsDirUtil::checkCreateDirectory(pgp_dir)) throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ; - AuthGPG::init(pgp_dir + "/retroshare_public_keyring.gpg",pgp_dir + "/retroshare_secret_keyring.gpg",pgp_dir + "/lock"); + AuthGPG::init( pgp_dir + "/retroshare_public_keyring.gpg", + pgp_dir + "/retroshare_secret_keyring.gpg", + pgp_dir + "/retroshare_trustdb.gpg", + pgp_dir + "/lock"); /* Initialize AuthGPG */ // if (AuthGPG::getAuthGPG()->InitAuth() == false) {