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-* {
CONFIG += link_pkgconfig
CONFIG += link_pkgconfig
QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64
QMAKE_CC = $${QMAKE_CXX}
@ -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

@ -60,14 +60,16 @@ const int p3facemsgzone = 11453;
/* RsIface Config */
/* Config */
void RsServer::ConfigFinalSave()
void RsServer::ConfigFinalSave()
{
/* force saving of transfers TODO */
//TODO: force saving of transfers
//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();
}

View File

@ -717,14 +717,17 @@ 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 ;
}
#else
(void) autoLoginNT;
#endif // RS_AUTOLOGIN
/* wipe out password */
@ -737,6 +740,7 @@ int RsInit::LoadCertificates(bool autoLoginNT)
return 1;
}
#ifdef RS_AUTOLOGIN
bool RsInit::RsClearAutoLogin()
{
RsPeerId preferredId;
@ -747,6 +751,7 @@ bool RsInit::RsClearAutoLogin()
}
return RsLoginHandler::clearAutoLogin(preferredId);
}
#endif // RS_AUTOLOGIN
bool RsInit::isPortable()

View File

@ -4,19 +4,103 @@
#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,
{
{ "RetroShare SSL Id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
{ NULL, (GnomeKeyringAttributeType)0 }
},
NULL,
NULL,
NULL
};
GNOME_KEYRING_ITEM_ENCRYPTION_KEY_PASSWORD,
{
{ "RetroShare SSL Id", GNOME_KEYRING_ATTRIBUTE_TYPE_STRING },
{ NULL, (GnomeKeyringAttributeType)0 }
},
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
//
static bool enableAutoLogin(const RsPeerId& ssl_id,const std::string& passwd) ;
#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.
//
static bool clearAutoLogin(const RsPeerId& ssl_id) ;
/// 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

@ -70,7 +70,8 @@ INCLUDEPATH *= retroshare-gui
################################# Linux ##########################################
# Put lib dir in QMAKE_LFLAGS so it appears before -L/usr/lib
linux-* {
CONFIG += link_pkgconfig
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 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)
}