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

@ -191,8 +191,6 @@ linux-* {
DEFINES *= PATCHED_LIBUPNP
}
DEFINES *= HAS_GNOME_KEYRING
PKGCONFIG *= gnome-keyring-1
PKGCONFIG *= libssl libupnp
PKGCONFIG *= libcrypto zlib
LIBS *= -lpthread -ldl

View File

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

View File

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

View File

@ -4,8 +4,92 @@
#include "rsloginhandler.h"
#include "util/rsdir.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__)
#include <gnome-keyring-1/gnome-keyring.h>
# include <gnome-keyring-1/gnome-keyring.h>
GnomeKeyringPasswordSchema my_schema = {
GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD,
@ -16,7 +100,7 @@ GnomeKeyringPasswordSchema my_schema = {
NULL,
NULL,
NULL
};
};
#endif
@ -99,22 +183,6 @@ extern BOOL WINAPI CryptUnprotectData(
#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)
{
std::cerr << "RsTryAutoLogin()" << std::endl;
@ -587,79 +655,9 @@ bool RsLoginHandler::clearAutoLogin(const RsPeerId& ssl_id)
#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*/)
{
return rsAccounts->PathAccountKeysDirectory() + "/" + "help.dta" ;
}
#endif // RS_AUTOLOGIN

View File

@ -2,46 +2,60 @@
#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
// file, asking for the GPG password to decrypt it.
//
// This class should handle the following scenario:
//
// Normal login:
// - SSL key is stored -> do autologin
// - SSL key is not stored
// - if we're actually in the login process, ask for the gpg passwd, and decrypt the key file
// - if we're just trying for autologin, don't ask for the gpg passwd and return null
//
// Key creation:
// - the key should be stored in the gpg file.
//
/**
* 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 file, asking for the GPG password to decrypt it.
*
* This class should handle the following scenario:
*
* Normal login:
* - SSL key is stored -> do autologin
* - SSL key is not stored
* - if we're actually in the login process, ask for the gpg passwd, and
* decrypt the key file
* - if we're just trying for autologin, don't ask for the gpg passwd and
* return null
*
* Key creation:
* - the key should be stored in the gpg file.
*/
class RsLoginHandler
{
public:
// Gets the SSL passwd by any means: try autologin, and look into gpg file if enable_gpg_key_callback==true
//
static bool getSSLPassword(const RsPeerId& ssl_id,bool enable_gpg_key_callback,std::string& ssl_password) ;
public:
/**
* Gets the SSL passwd by any means: try autologin, and look into gpg file
* 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.
//
static bool checkAndStoreSSLPasswdIntoGPGFile(const RsPeerId& ssl_id,const std::string& ssl_passwd) ;
/**
* 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 );
// 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
/**
* 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) ;
#endif // RS_AUTOLOGIN
private:
static bool tryAutoLogin(const RsPeerId& ssl_id,std::string& ssl_passwd) ;
static bool getSSLPasswdFromGPGFile(const RsPeerId& ssl_id,std::string& sslPassword) ;
private:
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) ;
static std::string getAutologinFileName(const RsPeerId& ssl_id) ;
#ifdef RS_AUTOLOGIN
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 */
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);
ui.loadButton->setFocus();
connect(ui.loadButton, SIGNAL(clicked()), this, SLOT(loadPerson()));
connect(ui.autologin_checkbox, SIGNAL(clicked()), this, SLOT(notSecureWarning()));
/* get all available pgp private certificates....
* mark last one as default.
@ -115,6 +120,7 @@ bool StartDialog::requestedNewCert()
return reqNewCert;
}
#ifdef RS_AUTOLOGIN
void StartDialog::notSecureWarning()
{
/* some error msg */
@ -130,3 +136,4 @@ void StartDialog::notSecureWarning()
#endif
#endif
}
#endif // RS_AUTOLOGIN

View File

@ -40,10 +40,12 @@ protected:
private slots:
void loadPerson();
#ifdef RS_AUTOLOGIN
/**
* Warns the user that autologin is not secure
*/
void notSecureWarning();
#endif // RS_AUTOLOGIN
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>
</property>
<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>
</property>
<item>
@ -198,6 +207,12 @@
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string/>
</property>

View File

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

View File

@ -39,6 +39,12 @@ no_libresapihttpserver:CONFIG -= libresapihttpserver
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
# assignation to qmake command line "CONFIG+=no_rs_gxs"
CONFIG *= rs_gxs
@ -52,6 +58,13 @@ unix {
isEmpty(LIB_DIR) { LIB_DIR = "$${PREFIX}/lib" }
isEmpty(DATA_DIR) { DATA_DIR = "$${PREFIX}/share/RetroShare06" }
isEmpty(PLUGIN_DIR) { PLUGIN_DIR = "$${LIB_DIR}/retroshare/extensions6" }
rs_autologin {
!macx {
DEFINES *= HAS_GNOME_KEYRING
PKGCONFIG *= gnome-keyring-1
}
}
}
android-g++ {
@ -136,3 +149,7 @@ libresapilocalserver:DEFINES *= LIBRESAPI_LOCAL_SERVER
libresapihttpserver:DEFINES *= ENABLE_WEBUI
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)
}