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() ;
_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.
//
if(ops_false == ops_keyring_read_from_file(_pubring, false, pubring.c_str()))
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read pubring.") ;
if(pubring_exist)
{
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 ;
int i=0 ;
@ -104,8 +121,13 @@ PGPHandler::PGPHandler(const std::string& pubring, const std::string& secring)
}
std::cerr << "Pubring read successfully." << std::endl;
if(ops_false == ops_keyring_read_from_file(_secring, false, secring.c_str()))
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read secring.") ;
if(secring_exist)
{
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 ;
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)
{
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) ;
_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 */
std::string AuthGPG::getGPGName(const std::string &id)
std::string AuthGPG::getGPGName(const std::string &id,bool *success)
{
if(id.length() != 16)
{
@ -610,21 +613,33 @@ std::string AuthGPG::getGPGName(const std::string &id)
const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType(id)) ;
if(info != NULL)
{
if(success != NULL) *success = true ;
return info->_name ;
}
else
{
if(success != NULL) *success = false ;
return "[Unknown PGP Cert name]" ;
}
}
/**** 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 ******/
const PGPCertificateInfo *info = PGPHandler::getCertificateInfo(PGPIdType(id)) ;
if(info != NULL)
{
if(success != NULL) *success = true ;
return info->_email ;
}
else
{
if(success != NULL) *success = false ;
return "[Unknown PGP Cert email]" ;
}
}
/**** GPG versions ***/

View File

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

View File

@ -32,6 +32,7 @@
// Initialize failed, result < 0
#define RS_INIT_AUTH_FAILED -1 // 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 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
*/

View File

@ -198,7 +198,7 @@ bool RsInitConfig::udpListenerOnly;
/* 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 std::string toUpperCase(const std::string& s)
@ -612,7 +612,6 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
*/
/* create singletons */
AuthSSLInit();
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL);
// 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);
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 */
// 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>::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 upper_case_user_string = toUpperCase(prefUserString) ;
@ -704,6 +712,36 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
/**************************** 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)
{
id = RsInitConfig::preferedId;
@ -941,8 +979,9 @@ std::string RsInit::getRetroshareDataDirectory()
/* 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 */
std::list<std::string> directories;
std::list<std::string>::iterator it;
@ -1025,6 +1064,8 @@ bool getAvailableAccounts(std::list<accountId> &ids)
#endif
ids.push_back(tmpId);
}
else
++failing_accounts ;
}
return true;
}
@ -1065,7 +1106,10 @@ static bool checkAccount(std::string accountdir, accountId &id)
#ifdef GPG_DEBUG
std::cerr << "issuerName: " << id.pgpId << " id: " << id.sslId << std::endl;
#endif
RsInit::GetPGPLoginDetails(id.pgpId, id.pgpName, id.pgpEmail);
if(! RsInit::GetPGPLoginDetails(id.pgpId, id.pgpName, id.pgpEmail))
return false ;
#ifdef GPG_DEBUG
std::cerr << "PGPLoginDetails: " << id.pgpId << " name: " << id.pgpName;
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;
#endif
name = AuthGPG::getAuthGPG()->getGPGName(id);
email = AuthGPG::getAuthGPG()->getGPGEmail(id);
bool ok = true ;
name = AuthGPG::getAuthGPG()->getGPGName(id,&ok);
if(!ok)
return 0 ;
email = AuthGPG::getAuthGPG()->getGPGEmail(id,&ok);
if(!ok)
return 0 ;
if (name != "") {
return 1;
} else {

View File

@ -80,22 +80,48 @@ int main(int argc, char *argv[])
RsInit::InitRsConfig();
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) {
/* Error occured */
QApplication dummyApp (argc, argv); // needed for QMessageBox
QMessageBox mb(QMessageBox::Critical, QObject::tr("RetroShare"), "", QMessageBox::Ok);
mb.setWindowIcon(QIcon(":/images/rstray3.png"));
switch (initResult) {
case RS_INIT_AUTH_FAILED:
std::cerr << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl;
mb.setText(QObject::tr("Inititialize failed. Wrong or missing installation of gpg."));
break;
default:
/* Unexpected return code */
std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl;
mb.setText(QObject::tr("An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult));
break;
switch (initResult)
{
case RS_INIT_AUTH_FAILED:
std::cerr << "RsInit::InitRetroShare AuthGPG::InitAuth failed" << std::endl;
mb.setText(QObject::tr("Inititialize failed. Wrong or missing installation of gpg."));
break;
default:
/* Unexpected return code */
std::cerr << "RsInit::InitRetroShare unexpected return code " << initResult << std::endl;
mb.setText(QObject::tr("An unexpected error occured. Please report 'RsInit::InitRetroShare unexpected return code %1'.").arg(initResult));
break;
}
mb.exec();
return 1;