Made autologin optional at compile time

Autologin is disabled by default at compile time, and a warning to
discourage it's usage is printed if it is enabled.
This will make default RetroShare build safer and reduce dependencies as
example we don't depends anymore on gnome keyring is not needed in default
build for linux anymore.
This commit is contained in:
Gio 2016-12-03 20:04:25 +01:00
parent 6890669820
commit 8656452c68
10 changed files with 202 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,15 @@ 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 ;
} }
#endif // RS_AUTOLOGIN
/* wipe out password */ /* wipe out password */
@ -733,10 +734,11 @@ int RsInit::LoadCertificates(bool autoLoginNT)
rsInitConfig->gxs_passwd = rsInitConfig->passwd; rsInitConfig->gxs_passwd = rsInitConfig->passwd;
rsInitConfig->passwd = ""; rsInitConfig->passwd = "";
rsAccounts->storePreferredAccount(); rsAccounts->storePreferredAccount();
return 1; return 1;
} }
#ifdef RS_AUTOLOGIN
bool RsInit::RsClearAutoLogin() bool RsInit::RsClearAutoLogin()
{ {
RsPeerId preferredId; RsPeerId preferredId;
@ -747,6 +749,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 autologin this is strongly discouraged as it may compromise your node security in multiple ways)
}