added dialog box to import existing keyrings when starting the new pgp version for the first time

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-OpenPGP@5210 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2012-06-09 21:01:22 +00:00
parent 2e05d0ef01
commit a91e859b66
6 changed files with 145 additions and 28 deletions

View File

@ -81,10 +81,27 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring)
_pubring = allocateOPSKeyring() ; _pubring = allocateOPSKeyring() ;
_secring = allocateOPSKeyring() ; _secring = allocateOPSKeyring() ;
// Check that the file exists. If not, create a void keyring.
FILE *ftest ;
ftest = fopen(pubring.c_str(),"rb") ;
bool pubring_exist = (ftest != NULL) ;
if(ftest != NULL)
fclose(ftest) ;
ftest = fopen(secring.c_str(),"rb") ;
bool secring_exist = (ftest != NULL) ;
if(ftest != NULL)
fclose(ftest) ;
// Read public and secret keyrings from supplied files. // Read public and secret keyrings from supplied files.
// //
if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str())) if(pubring_exist)
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read pubring.") ; {
if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str()))
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read pubring. File corrupted.") ;
}
else
std::cerr << "pubring file \"" << pubring << "\" not found. Creating a void keyring." << std::endl;
const ops_keydata_t *keydata ; const ops_keydata_t *keydata ;
int i=0 ; int i=0 ;
@ -104,8 +121,13 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring)
} }
std::cerr << "Pubring read successfully." << std::endl; std::cerr << "Pubring read successfully." << std::endl;
if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str())) if(secring_exist)
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read secring.") ; {
if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str()))
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read secring. File corrupted.") ;
}
else
std::cerr << "secring file \"" << secring << "\" not found. Creating a void keyring." << std::endl;
i=0 ; i=0 ;
while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL ) while( (keydata = ops_keyring_get_key_by_index(_secring,i)) != NULL )

View File

@ -89,7 +89,10 @@ std::string pgp_pwd_callback(void * /*hook*/, const char *uid_hint, const char *
void AuthGPG::init(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring) void AuthGPG::init(const std::string& path_to_public_keyring,const std::string& path_to_secret_keyring)
{ {
if(_instance != NULL) if(_instance != NULL)
throw std::runtime_error("AuthGPG::init() called twice!") ; {
delete _instance ;
std::cerr << "AuthGPG::init() called twice!" << std::endl ;
}
PGPHandler::setPassphraseCallback(pgp_pwd_callback) ; PGPHandler::setPassphraseCallback(pgp_pwd_callback) ;
_instance = new AuthGPG(path_to_public_keyring,path_to_secret_keyring) ; _instance = new AuthGPG(path_to_public_keyring,path_to_secret_keyring) ;
@ -598,7 +601,7 @@ bool AuthGPG::GeneratePGPCertificate(const std::string& name,
} }
/**** These Two are common */ /**** These Two are common */
std::string AuthGPG::getGPGName(const std::string &id) std::string AuthGPG::getGPGName(const std::string &id,bool *success)
{ {
if(id.length() != 16) if(id.length() != 16)
{ {
@ -610,21 +613,33 @@ std::string AuthGPG::getGPGName(const std::string &id)
const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType(id)) ; const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType(id)) ;
if(info != NULL) if(info != NULL)
{
if(success != NULL) *success = true ;
return info->_name ; return info->_name ;
}
else else
{
if(success != NULL) *success = false ;
return "[Unknown PGP Cert name]" ; return "[Unknown PGP Cert name]" ;
}
} }
/**** These Two are common */ /**** These Two are common */
std::string AuthGPG::getGPGEmail(const std::string &id) std::string AuthGPG::getGPGEmail(const std::string &id,bool *success)
{ {
RsStackMutex stack(gpgMtxData); /******* LOCKED ******/ RsStackMutex stack(gpgMtxData); /******* LOCKED ******/
const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType(id)) ; const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType(id)) ;
if(info != NULL) if(info != NULL)
{
if(success != NULL) *success = true ;
return info->_email ; return info->_email ;
}
else else
{
if(success != NULL) *success = false ;
return "[Unknown PGP Cert email]" ; return "[Unknown PGP Cert email]" ;
}
} }
/**** GPG versions ***/ /**** GPG versions ***/

View File

@ -152,8 +152,8 @@ class AuthGPG: public p3Config, public RsThread, public PGPHandler
* provide access to details in cache list. * provide access to details in cache list.
* *
****/ ****/
virtual std::string getGPGName(const std::string &pgp_id); virtual std::string getGPGName(const std::string &pgp_id,bool *success = NULL);
virtual std::string getGPGEmail(const std::string &pgp_id); virtual std::string getGPGEmail(const std::string &pgp_id,bool *success = NULL);
/* PGP web of trust management */ /* PGP web of trust management */
virtual std::string getGPGOwnId(); virtual std::string getGPGOwnId();

View File

@ -32,6 +32,7 @@
// Initialize failed, result < 0 // Initialize failed, result < 0
#define RS_INIT_AUTH_FAILED -1 // AuthGPG::InitAuth failed #define RS_INIT_AUTH_FAILED -1 // AuthGPG::InitAuth failed
#define RS_INIT_BASE_DIR_ERROR -2 // AuthGPG::InitAuth failed #define RS_INIT_BASE_DIR_ERROR -2 // AuthGPG::InitAuth failed
#define RS_INIT_NO_KEYRING -3 // Keyring is empty. Need to import it.
/**** /****
@ -87,6 +88,9 @@ class RsInit
static int GetPGPLoginDetails(const std::string& id, std::string &name, std::string &email); static int GetPGPLoginDetails(const std::string& id, std::string &name, std::string &email);
static bool GeneratePGPCertificate(const std::string&, const std::string& email, const std::string& passwd, std::string &pgpId, std::string &errString); static bool GeneratePGPCertificate(const std::string&, const std::string& email, const std::string& passwd, std::string &pgpId, std::string &errString);
// copies existing gnupg keyrings to the new place of the OpenPGP-SDK version. Returns true on success.
static bool copyGnuPGKeyrings() ;
/*! /*!
* Login GGP * Login GGP
*/ */

View File

@ -198,7 +198,7 @@ bool RsInitConfig::udpListenerOnly;
/* Uses private class - so must be hidden */ /* Uses private class - so must be hidden */
static bool getAvailableAccounts(std::list<accountId> &ids); static bool getAvailableAccounts(std::list<accountId> &ids,int& failing_accounts);
static bool checkAccount(std::string accountdir, accountId &id); static bool checkAccount(std::string accountdir, accountId &id);
static std::string toUpperCase(const std::string& s) static std::string toUpperCase(const std::string& s)
@ -612,7 +612,6 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
*/ */
/* create singletons */ /* create singletons */
AuthSSLInit(); AuthSSLInit();
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL); AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL);
// first check config directories, and set bootstrap values. // first check config directories, and set bootstrap values.
@ -621,7 +620,11 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
get_configinit(RsInitConfig::basedir, RsInitConfig::preferedId); get_configinit(RsInitConfig::basedir, RsInitConfig::preferedId);
AuthGPG::init(RsInitConfig::basedir + "/pgp/retroshare_public_keyring.gpg",RsInitConfig::basedir + "/pgp/retroshare_secret_keyring.gpg"); std::string pgp_dir = RsInitConfig::basedir + "/pgp" ;
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");
/* Initialize AuthGPG */ /* Initialize AuthGPG */
// if (AuthGPG::getAuthGPG()->InitAuth() == false) { // if (AuthGPG::getAuthGPG()->InitAuth() == false) {
@ -631,9 +634,14 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
//std::list<accountId> ids; //std::list<accountId> ids;
std::list<accountId>::iterator it; std::list<accountId>::iterator it;
getAvailableAccounts(RsInitConfig::accountIds); int failing_accounts ;
// if a different user id has been passed to cmd line check for that instead getAvailableAccounts(RsInitConfig::accountIds,failing_accounts);
if(failing_accounts > 0 && RsInitConfig::accountIds.empty())
return RS_INIT_NO_KEYRING ;
// if a different user id has been passed to cmd line check for that instead
std::string lower_case_user_string = toLowerCase(prefUserString) ; std::string lower_case_user_string = toLowerCase(prefUserString) ;
std::string upper_case_user_string = toUpperCase(prefUserString) ; std::string upper_case_user_string = toUpperCase(prefUserString) ;
@ -704,6 +712,36 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
/**************************** Access Functions for Init Data **************************/ /**************************** Access Functions for Init Data **************************/
bool RsInit::copyGnuPGKeyrings()
{
std::string pgp_dir = RsInitConfig::basedir + "/pgp" ;
if(!RsDirUtil::checkCreateDirectory(pgp_dir))
throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ;
#ifdef WINDOWS_SYS
std::cerr << "CRITICAL: UNIMPLEMENTED SECTION FOR WINDOWS - Press ^C to abort" << std::endl;
while(true)
Sleep(10000) ;
#else
// We need a specific part for MacOS and Linux as well
std::string source_public_keyring = RsInitConfig::basedir + "/../.gnupg/pubring.gpg" ;
std::string source_secret_keyring = RsInitConfig::basedir + "/../.gnupg/secring.gpg" ;
#endif
if(!RsDirUtil::copyFile(source_public_keyring,pgp_dir + "/retroshare_public_keyring.gpg"))
{
std::cerr << "Cannot copy pub keyring " << source_public_keyring << " to destination file " << pgp_dir + "/retroshare_public_keyring.pgp" << std::endl;
return false ;
}
if(!RsDirUtil::copyFile(source_secret_keyring,pgp_dir + "/retroshare_secret_keyring.gpg"))
{
std::cerr << "Cannot copy sec keyring " << source_secret_keyring << " to destination file " << pgp_dir + "/retroshare_secret_keyring.pgp" << std::endl;
return false ;
}
return true ;
}
bool RsInit::getPreferedAccountId(std::string &id) bool RsInit::getPreferedAccountId(std::string &id)
{ {
id = RsInitConfig::preferedId; id = RsInitConfig::preferedId;
@ -941,8 +979,9 @@ std::string RsInit::getRetroshareDataDirectory()
/* directories with valid certificates in the expected location */ /* directories with valid certificates in the expected location */
bool getAvailableAccounts(std::list<accountId> &ids) bool getAvailableAccounts(std::list<accountId> &ids,int& failing_accounts)
{ {
failing_accounts = 0 ;
/* get the directories */ /* get the directories */
std::list<std::string> directories; std::list<std::string> directories;
std::list<std::string>::iterator it; std::list<std::string>::iterator it;
@ -1025,6 +1064,8 @@ bool getAvailableAccounts(std::list<accountId> &ids)
#endif #endif
ids.push_back(tmpId); ids.push_back(tmpId);
} }
else
++failing_accounts ;
} }
return true; return true;
} }
@ -1065,7 +1106,10 @@ static bool checkAccount(std::string accountdir, accountId &id)
#ifdef GPG_DEBUG #ifdef GPG_DEBUG
std::cerr << "issuerName: " << id.pgpId << " id: " << id.sslId << std::endl; std::cerr << "issuerName: " << id.pgpId << " id: " << id.sslId << std::endl;
#endif #endif
RsInit::GetPGPLoginDetails(id.pgpId, id.pgpName, id.pgpEmail);
if(! RsInit::GetPGPLoginDetails(id.pgpId, id.pgpName, id.pgpEmail))
return false ;
#ifdef GPG_DEBUG #ifdef GPG_DEBUG
std::cerr << "PGPLoginDetails: " << id.pgpId << " name: " << id.pgpName; std::cerr << "PGPLoginDetails: " << id.pgpId << " name: " << id.pgpName;
std::cerr << " email: " << id.pgpEmail << std::endl; std::cerr << " email: " << id.pgpEmail << std::endl;
@ -1103,8 +1147,14 @@ int RsInit::GetPGPLoginDetails(const std::string& id, std::string &name, st
std::cerr << "RsInit::GetPGPLoginDetails for \"" << id << "\"" << std::endl; std::cerr << "RsInit::GetPGPLoginDetails for \"" << id << "\"" << std::endl;
#endif #endif
name = AuthGPG::getAuthGPG()->getGPGName(id); bool ok = true ;
email = AuthGPG::getAuthGPG()->getGPGEmail(id); name = AuthGPG::getAuthGPG()->getGPGName(id,&ok);
if(!ok)
return 0 ;
email = AuthGPG::getAuthGPG()->getGPGEmail(id,&ok);
if(!ok)
return 0 ;
if (name != "") { if (name != "") {
return 1; return 1;
} else { } else {

View File

@ -80,22 +80,48 @@ int main(int argc, char *argv[])
RsInit::InitRsConfig(); RsInit::InitRsConfig();
int initResult = RsInit::InitRetroShare(argc, argv); int initResult = RsInit::InitRetroShare(argc, argv);
if(initResult == RS_INIT_NO_KEYRING) // happens when we already have accounts, but no pgp key. This is when switching to the openpgp-sdk version.
{
QApplication dummyApp (argc, argv); // needed for QMessageBox
QMessageBox msgBox;
msgBox.setText(QObject::tr("This version of RetroShare is using OpenPGP-SDK. As a side effect, it's not using the system shared PGP keyring, but has its own keyring shared by all RetroShare instances. <br/><br/>You do not appear to have such a keyring, although GPG keys are mentionned by existing RetroShare accounts, probably because you just changed to this new version of the software."));
msgBox.setInformativeText(QObject::tr("Choose between:<Br/><ul><li>Ok to copy the existing keyring from gnupg (safest bet), or </li><li>Discard to start fresh with an empty keyring (you will be asked to create a new PGP key to work with RetroShare). </li><li>Cancel to quit and forge a keyring by yourself (needs some PGP skills)</li></ul>"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
int ret = msgBox.exec();
if(ret == QMessageBox::Cancel)
return 0 ;
if(ret == QMessageBox::Ok)
{
if(!RsInit::copyGnuPGKeyrings())
return 0 ;
initResult = RsInit::InitRetroShare(argc, argv);
}
else
initResult = RS_INIT_OK ;
}
if (initResult < 0) { if (initResult < 0) {
/* Error occured */ /* Error occured */
QApplication dummyApp (argc, argv); // needed for QMessageBox QApplication dummyApp (argc, argv); // needed for QMessageBox
QMessageBox mb(QMessageBox::Critical, QObject::tr("RetroShare"), "", QMessageBox::Ok); QMessageBox mb(QMessageBox::Critical, QObject::tr("RetroShare"), "", QMessageBox::Ok);
mb.setWindowIcon(QIcon(":/images/rstray3.png")); mb.setWindowIcon(QIcon(":/images/rstray3.png"));
switch (initResult) { switch (initResult)
case RS_INIT_AUTH_FAILED: {
std::cerr << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl; case RS_INIT_AUTH_FAILED:
mb.setText(QObject::tr("Inititialize failed. Wrong or missing installation of gpg.")); std::cerr << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl;
break; mb.setText(QObject::tr("Inititialize failed. Wrong or missing installation of gpg."));
default: break;
/* Unexpected return code */ default:
std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl; /* Unexpected return code */
mb.setText(QObject::tr("An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult)); std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl;
break; mb.setText(QObject::tr("An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult));
break;
} }
mb.exec(); mb.exec();
return 1; return 1;