Merge pull request #591 from G10h4ck/split_autologin

Made autologin optional at compile time
This commit is contained in:
csoler 2016-12-14 16:45:45 +01:00 committed by GitHub
commit 81dffbed84
10 changed files with 204 additions and 146 deletions

View File

@ -151,7 +151,7 @@ HEADERS += $$PUBLIC_HEADERS
################################# Linux ########################################## ################################# Linux ##########################################
linux-* { linux-* {
CONFIG += link_pkgconfig CONFIG += link_pkgconfig
QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64 QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64
QMAKE_CC = $${QMAKE_CXX} QMAKE_CC = $${QMAKE_CXX}
@ -191,8 +191,6 @@ linux-* {
DEFINES *= PATCHED_LIBUPNP DEFINES *= PATCHED_LIBUPNP
} }
DEFINES *= HAS_GNOME_KEYRING
PKGCONFIG *= gnome-keyring-1
PKGCONFIG *= libssl libupnp PKGCONFIG *= libssl libupnp
PKGCONFIG *= libcrypto zlib PKGCONFIG *= libcrypto zlib
LIBS *= -lpthread -ldl LIBS *= -lpthread -ldl

View File

@ -60,14 +60,16 @@ const int p3facemsgzone = 11453;
/* RsIface Config */ /* RsIface Config */
/* Config */ /* Config */
void RsServer::ConfigFinalSave() void RsServer::ConfigFinalSave()
{ {
/* force saving of transfers TODO */ //TODO: force saving of transfers
//ftserver->saveFileTransferStatus(); //ftserver->saveFileTransferStatus();
if(!RsInit::getAutoLogin())
RsInit::RsClearAutoLogin();
//AuthSSL::getAuthSSL()->FinalSaveCertificates(); #ifdef RS_AUTOLOGIN
if(!RsInit::getAutoLogin()) RsInit::RsClearAutoLogin();
#endif // RS_AUTOLOGIN
//AuthSSL::getAuthSSL()->FinalSaveCertificates();
mConfigMgr->completeConfiguration(); mConfigMgr->completeConfiguration();
} }

View File

@ -717,14 +717,17 @@ int RsInit::LoadCertificates(bool autoLoginNT)
return 0 ; return 0 ;
} }
#ifdef RS_AUTOLOGIN
if(autoLoginNT) if(autoLoginNT)
{ {
std::cerr << "RetroShare will AutoLogin next time"; std::cerr << "RetroShare will AutoLogin next time" << std::endl;
std::cerr << std::endl;
RsLoginHandler::enableAutoLogin(preferredId,rsInitConfig->passwd); RsLoginHandler::enableAutoLogin(preferredId,rsInitConfig->passwd);
rsInitConfig->autoLogin = true ; rsInitConfig->autoLogin = true ;
} }
#else
(void) autoLoginNT;
#endif // RS_AUTOLOGIN
/* wipe out password */ /* wipe out password */
@ -737,6 +740,7 @@ int RsInit::LoadCertificates(bool autoLoginNT)
return 1; return 1;
} }
#ifdef RS_AUTOLOGIN
bool RsInit::RsClearAutoLogin() bool RsInit::RsClearAutoLogin()
{ {
RsPeerId preferredId; RsPeerId preferredId;
@ -747,6 +751,7 @@ bool RsInit::RsClearAutoLogin()
} }
return RsLoginHandler::clearAutoLogin(preferredId); return RsLoginHandler::clearAutoLogin(preferredId);
} }
#endif // RS_AUTOLOGIN
bool RsInit::isPortable() bool RsInit::isPortable()

View File

@ -4,19 +4,103 @@
#include "rsloginhandler.h" #include "rsloginhandler.h"
#include "util/rsdir.h" #include "util/rsdir.h"
#include "rsaccounts.h" #include "rsaccounts.h"
bool RsLoginHandler::getSSLPassword( const RsPeerId& ssl_id,
bool enable_gpg_ask_passwd,
std::string& ssl_passwd )
{
#ifdef RS_AUTOLOGIN
// First, see if autologin is available
if(tryAutoLogin(ssl_id,ssl_passwd)) return true;
#endif // RS_AUTOLOGIN
// If we're not expecting to enter a passwd (e.g. test for autologin before
// display of the login window), safely respond false.
if(!enable_gpg_ask_passwd) return false;
return getSSLPasswdFromGPGFile(ssl_id,ssl_passwd);
}
bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile(
const RsPeerId& ssl_id, const std::string& ssl_passwd )
{
// We want to pursue login with gpg passwd. Let's do it:
FILE *sslPassphraseFile = RsDirUtil::rs_fopen(
getSSLPasswdFileName(ssl_id).c_str(), "r");
if(sslPassphraseFile != NULL) // already have it.
{
fclose(sslPassphraseFile);
return true ;
}
bool ok = AuthGPG::getAuthGPG()->encryptTextToFile(
ssl_passwd, getSSLPasswdFileName(ssl_id));
if (!ok) std::cerr << "Encrypting went wrong !" << std::endl;
return ok;
}
bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& sslPassword)
{
/* Let's read the password from an encrypted file, before check if there's
* an ssl_passpharese_file that we can decrypt with PGP */
FILE *sslPassphraseFile = RsDirUtil::rs_fopen(
getSSLPasswdFileName(ssl_id).c_str(), "r");
if (sslPassphraseFile == NULL)
{
std::cerr << "No password provided, and no sslPassphraseFile : "
<< getSSLPasswdFileName(ssl_id).c_str() << std::endl;
return 0;
}
fclose(sslPassphraseFile);
std::cerr << "opening sslPassphraseFile : "
<< getSSLPasswdFileName(ssl_id).c_str() << std::endl;
std::string plain;
if ( AuthGPG::getAuthGPG()->decryptTextFromFile(
plain, getSSLPasswdFileName(ssl_id)) )
{
std::cerr << "Decrypting went ok !" << std::endl;
sslPassword = plain;
return sslPassword.length() > 0 ;
}
else
{
sslPassword = "";
std::cerr << "Error : decrypting went wrong !" << std::endl;
return false;
}
}
std::string RsLoginHandler::getSSLPasswdFileName(const RsPeerId& /*ssl_id*/)
{
return rsAccounts->PathAccountKeysDirectory() + "/" + "ssl_passphrase.pgp";
}
#ifdef RS_AUTOLOGIN
#if defined(HAS_GNOME_KEYRING) || defined(__FreeBSD__) || defined(__OpenBSD__) #if defined(HAS_GNOME_KEYRING) || defined(__FreeBSD__) || defined(__OpenBSD__)
#include <gnome-keyring-1/gnome-keyring.h> # include <gnome-keyring-1/gnome-keyring.h>
GnomeKeyringPasswordSchema my_schema = { GnomeKeyringPasswordSchema my_schema = {
GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD, GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD,
{ {
{ "RetroShare SSL Id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING }, { "RetroShare SSL Id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
{ NULL, (GnomeKeyringAttributeType)0 } { NULL, (GnomeKeyringAttributeType)0 }
}, },
NULL, NULL,
NULL, NULL,
NULL NULL
}; };
#endif #endif
@ -99,22 +183,6 @@ extern BOOL WINAPI CryptUnprotectData(
#endif #endif
bool RsLoginHandler::getSSLPassword(const RsPeerId& ssl_id,bool enable_gpg_ask_passwd,std::string& ssl_passwd)
{
// First, see if autologin is available
//
if(tryAutoLogin(ssl_id,ssl_passwd))
return true ;
// If we're not expecting to enter a passwd (e.g. test for autologin before
// display of the login window), safely respond false.
//
if(!enable_gpg_ask_passwd)
return false ;
return getSSLPasswdFromGPGFile(ssl_id,ssl_passwd) ;
}
bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd) bool RsLoginHandler::tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd)
{ {
std::cerr << "RsTryAutoLogin()" << std::endl; std::cerr << "RsTryAutoLogin()" << std::endl;
@ -587,79 +655,9 @@ bool RsLoginHandler::clearAutoLogin(const RsPeerId& ssl_id)
#endif #endif
} }
bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile(const RsPeerId& ssl_id,const std::string& ssl_passwd)
{
// We want to pursue login with gpg passwd. Let's do it:
//
std::cerr << "let's store the ssl Password into a pgp ecrypted file" << std::endl;
FILE *sslPassphraseFile = RsDirUtil::rs_fopen(getSSLPasswdFileName(ssl_id).c_str(), "r");
if(sslPassphraseFile != NULL) // already have it.
{
fclose(sslPassphraseFile) ;
return true ;
}
bool ok ;
std::string cipher ;
if(AuthGPG::getAuthGPG()->encryptTextToFile(ssl_passwd, getSSLPasswdFileName(ssl_id)))
{
std::cerr << "Encrypting went ok !" << std::endl;
ok= true ;
}
else
{
std::cerr << "Encrypting went wrong !" << std::endl;
ok= false ;
}
return ok ;
}
bool RsLoginHandler::getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& sslPassword)
{
// Let's read the password from an encrypted file
// Let's check if there's a ssl_passpharese_file that we can decrypt with PGP
//
FILE *sslPassphraseFile = RsDirUtil::rs_fopen(getSSLPasswdFileName(ssl_id).c_str(), "r");
if (sslPassphraseFile == NULL)
{
std::cerr << "No password provided, and no sslPassphraseFile : " << getSSLPasswdFileName(ssl_id).c_str() << std::endl;
return 0;
}
fclose(sslPassphraseFile);
std::cerr << "opening sslPassphraseFile : " << getSSLPasswdFileName(ssl_id).c_str() << std::endl;
std::string plain ;
if (AuthGPG::getAuthGPG()->decryptTextFromFile(plain,getSSLPasswdFileName(ssl_id)))
{
std::cerr << "Decrypting went ok !" << std::endl;
sslPassword = plain ;
std::cerr << "sslpassword: " << "******************** (length = " << sslPassword.length() << ")" << std::endl;
return sslPassword.length() > 0 ;
}
else
{
sslPassword = "" ;
std::cerr << "Error : decrypting went wrong !" << std::endl;
return false;
}
}
std::string RsLoginHandler::getSSLPasswdFileName(const RsPeerId& /*ssl_id*/)
{
return rsAccounts->PathAccountKeysDirectory() + "/" + "ssl_passphrase.pgp";
}
std::string RsLoginHandler::getAutologinFileName(const RsPeerId& /*ssl_id*/) std::string RsLoginHandler::getAutologinFileName(const RsPeerId& /*ssl_id*/)
{ {
return rsAccounts->PathAccountKeysDirectory() + "/" + "help.dta" ; return rsAccounts->PathAccountKeysDirectory() + "/" + "help.dta" ;
} }
#endif // RS_AUTOLOGIN

View File

@ -2,46 +2,60 @@
#include <string> #include <string>
// This class handles login, meaning that it retrieves the SSL password from either /**
// the keyring or help.dta file, if autologin is enabled, or from the ssl_passphrase.pgp * This class handles login, meaning that it retrieves the SSL password from
// file, asking for the GPG password to decrypt it. * either the keyring or help.dta file, if autologin is enabled, or from the
// * ssl_passphrase.pgp file, asking for the GPG password to decrypt it.
// This class should handle the following scenario: *
// * This class should handle the following scenario:
// Normal login: *
// - SSL key is stored -> do autologin * Normal login:
// - SSL key is not stored * - SSL key is stored -> do autologin
// - if we're actually in the login process, ask for the gpg passwd, and decrypt the key file * - SSL key is not stored
// - if we're just trying for autologin, don't ask for the gpg passwd and return null * - if we're actually in the login process, ask for the gpg passwd, and
// * decrypt the key file
// Key creation: * - if we're just trying for autologin, don't ask for the gpg passwd and
// - the key should be stored in the gpg file. * return null
// *
* Key creation:
* - the key should be stored in the gpg file.
*/
class RsLoginHandler class RsLoginHandler
{ {
public: public:
// Gets the SSL passwd by any means: try autologin, and look into gpg file if enable_gpg_key_callback==true /**
// * Gets the SSL passwd by any means: try autologin, and look into gpg file
static bool getSSLPassword(const RsPeerId& ssl_id,bool enable_gpg_key_callback,std::string& ssl_password) ; * if enable_gpg_key_callback==true
*/
static bool getSSLPassword( const RsPeerId& ssl_id,
bool enable_gpg_key_callback,
std::string& ssl_password);
// Checks whether the ssl passwd is already in the gpg file. If the file's not here, the passwd is stored there, /**
// encrypted with the current GPG key. * Checks whether the ssl passwd is already in the gpg file. If the file's
// * not here, the passwd is stored there, encrypted with the current GPG key.
static bool checkAndStoreSSLPasswdIntoGPGFile(const RsPeerId& ssl_id,const std::string& ssl_passwd) ; */
static bool checkAndStoreSSLPasswdIntoGPGFile(
const RsPeerId& ssl_id, const std::string& ssl_passwd );
// Stores the given ssl_id/passwd pair into the keyring, or by default into a file in /[ssl_id]/keys/help.dta #ifdef RS_AUTOLOGIN
// /**
static bool enableAutoLogin(const RsPeerId& ssl_id,const std::string& passwd) ; * Stores the given ssl_id/passwd pair into the keyring, or by default into
* a file in /[ssl_id]/keys/help.dta
*/
static bool enableAutoLogin(const RsPeerId& ssl_id,const std::string& passwd) ;
// Clears autologin entry. /// Clears autologin entry.
// static bool clearAutoLogin(const RsPeerId& ssl_id) ;
static bool clearAutoLogin(const RsPeerId& ssl_id) ; #endif // RS_AUTOLOGIN
private: private:
static bool tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd) ; static bool getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& sslPassword);
static bool getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& sslPassword) ; static std::string getSSLPasswdFileName(const RsPeerId& ssl_id);
static std::string getSSLPasswdFileName(const RsPeerId& ssl_id) ; #ifdef RS_AUTOLOGIN
static std::string getAutologinFileName(const RsPeerId& ssl_id) ; static bool tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd);
static std::string getAutologinFileName(const RsPeerId& ssl_id);
#endif // RS_AUTOLOGIN
}; };

View File

@ -35,12 +35,17 @@ StartDialog::StartDialog(QWidget *parent)
/* Invoke Qt Designer generated QObject setup routine */ /* Invoke Qt Designer generated QObject setup routine */
ui.setupUi(this); ui.setupUi(this);
#ifdef RS_AUTOLOGIN
connect(ui.autologin_checkbox, SIGNAL(clicked()), this, SLOT(notSecureWarning()));
#else
ui.autologin_checkbox->setHidden(true);
#endif
Settings->loadWidgetInformation(this); Settings->loadWidgetInformation(this);
ui.loadButton->setFocus(); ui.loadButton->setFocus();
connect(ui.loadButton, SIGNAL(clicked()), this, SLOT(loadPerson())); connect(ui.loadButton, SIGNAL(clicked()), this, SLOT(loadPerson()));
connect(ui.autologin_checkbox, SIGNAL(clicked()), this, SLOT(notSecureWarning()));
/* get all available pgp private certificates.... /* get all available pgp private certificates....
* mark last one as default. * mark last one as default.
@ -115,6 +120,7 @@ bool StartDialog::requestedNewCert()
return reqNewCert; return reqNewCert;
} }
#ifdef RS_AUTOLOGIN
void StartDialog::notSecureWarning() void StartDialog::notSecureWarning()
{ {
/* some error msg */ /* some error msg */
@ -130,3 +136,4 @@ void StartDialog::notSecureWarning()
#endif #endif
#endif #endif
} }
#endif // RS_AUTOLOGIN

View File

@ -40,10 +40,12 @@ protected:
private slots: private slots:
void loadPerson(); void loadPerson();
#ifdef RS_AUTOLOGIN
/** /**
* Warns the user that autologin is not secure * Warns the user that autologin is not secure
*/ */
void notSecureWarning(); void notSecureWarning();
#endif // RS_AUTOLOGIN
void on_labelProfile_linkActivated(QString link); void on_labelProfile_linkActivated(QString link);

View File

@ -18,7 +18,16 @@
<normaloff>:/images/logo/logo_32.png</normaloff>:/images/logo/logo_32.png</iconset> <normaloff>:/images/logo/logo_32.png</normaloff>:/images/logo/logo_32.png</iconset>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout_2"> <layout class="QVBoxLayout" name="verticalLayout_2">
<property name="margin"> <property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
@ -198,6 +207,12 @@
<property name="enabled"> <property name="enabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title"> <property name="title">
<string/> <string/>
</property> </property>

View File

@ -70,7 +70,8 @@ INCLUDEPATH *= retroshare-gui
################################# Linux ########################################## ################################# Linux ##########################################
# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib # Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib
linux-* { linux-* {
CONFIG += link_pkgconfig CONFIG += link_pkgconfig
#CONFIG += version_detail_bash_script #CONFIG += version_detail_bash_script
QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64 QMAKE_CXXFLAGS *= -D_FILE_OFFSET_BITS=64
@ -78,7 +79,6 @@ linux-* {
LIBS *= -rdynamic LIBS *= -rdynamic
DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions
DEFINES *= HAS_GNOME_KEYRING
} }
unix { unix {

View File

@ -39,6 +39,12 @@ no_libresapihttpserver:CONFIG -= libresapihttpserver
CONFIG *= sqlcipher CONFIG *= sqlcipher
no_sqlcipher:CONFIG -= sqlcipher no_sqlcipher:CONFIG -= sqlcipher
# To enable autologin (this is higly discouraged as it may compromise your node
# security in multiple ways) append the following assignation to qmake command
# line "CONFIG+=rs_autologin"
CONFIG *= no_rs_autologin
rs_autologin:CONFIG -= no_rs_autologin
# To disable GXS (General eXchange System) append the following # To disable GXS (General eXchange System) append the following
# assignation to qmake command line "CONFIG+=no_rs_gxs" # assignation to qmake command line "CONFIG+=no_rs_gxs"
CONFIG *= rs_gxs CONFIG *= rs_gxs
@ -52,6 +58,13 @@ unix {
isEmpty(LIB_DIR) { LIB_DIR = "$${PREFIX}/lib" } isEmpty(LIB_DIR) { LIB_DIR = "$${PREFIX}/lib" }
isEmpty(DATA_DIR) { DATA_DIR = "$${PREFIX}/share/RetroShare06" } isEmpty(DATA_DIR) { DATA_DIR = "$${PREFIX}/share/RetroShare06" }
isEmpty(PLUGIN_DIR) { PLUGIN_DIR = "$${LIB_DIR}/retroshare/extensions6" } isEmpty(PLUGIN_DIR) { PLUGIN_DIR = "$${LIB_DIR}/retroshare/extensions6" }
rs_autologin {
!macx {
DEFINES *= HAS_GNOME_KEYRING
PKGCONFIG *= gnome-keyring-1
}
}
} }
android-g++ { android-g++ {
@ -136,3 +149,7 @@ libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER
libresapihttpserver:DEFINES *= ENABLE_WEBUI libresapihttpserver:DEFINES *= ENABLE_WEBUI
sqlcipher:DEFINES -= NO_SQLCIPHER sqlcipher:DEFINES -= NO_SQLCIPHER
no_sqlcipher:DEFINES *= NO_SQLCIPHER no_sqlcipher:DEFINES *= NO_SQLCIPHER
rs_autologin {
DEFINES *= RS_AUTOLOGIN
warning(You have enabled RetroShare auto-login, this is discouraged. The usage of auto-login on some linux distributions may allow someone having access to your session to steal the SSL keys of your node location and therefore compromise your security)
}