2009-05-23 13:40:35 -04:00
/*
2010-01-13 15:58:58 -05:00
* libretroshare / src AuthGPG . cc
2009-05-23 13:40:35 -04:00
*
* GnuPG / GPGme interface for RetroShare .
*
* Copyright 2008 - 2009 by Robert Fernie , Retroshare Team .
*
* This library is free software ; you can redistribute it and / or
* modify it under the termsf the GNU Library General Public
* License Version 2 as published by the Free Software Foundation .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Library General Public License for more details .
*
* You should have received a copy of the GNU Library General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307
* USA .
*
* Please report all bugs and problems to " retroshare@lunamutt.com " .
*
*
*/
# include "authgpg.h"
2011-08-07 17:11:00 -04:00
# include "retroshare/rsiface.h" // For rsicontrol.
# include "retroshare/rspeers.h" // For RsPeerDetails.
2011-08-07 18:23:53 -04:00
# ifdef WINDOWS_SYS
# include "retroshare/rsinit.h"
# endif
2011-08-21 18:28:19 -04:00
# include "pqi/pqinotify.h"
2012-04-08 10:52:01 -04:00
# include "pgp/pgphandler.h"
2011-08-07 17:11:00 -04:00
2010-04-30 10:34:48 -04:00
# include <util/rsdir.h>
2012-07-13 07:08:13 -04:00
# include <pgp/pgpkeyutil.h>
2012-04-12 19:29:39 -04:00
# include <unistd.h> /* for (u)sleep() */
2009-05-23 13:40:35 -04:00
# include <iostream>
2012-04-08 10:52:01 -04:00
# include <stdexcept>
2009-05-23 13:40:35 -04:00
# include <sstream>
2010-01-13 15:52:31 -05:00
# include <algorithm>
2010-01-13 16:26:30 -05:00
# include "serialiser/rsconfigitems.h"
2010-01-13 16:14:49 -05:00
2012-04-09 13:03:47 -04:00
# define LIMIT_CERTIFICATE_SIZE 1
# define MAX_CERTIFICATE_SIZE 10000
2010-09-30 15:05:43 -04:00
const time_t STORE_KEY_TIMEOUT = 1 * 60 * 60 ; //store key is call around every hour
2012-04-08 10:52:01 -04:00
AuthGPG * AuthGPG : : _instance = NULL ;
2011-01-23 06:57:09 -05:00
void cleanupZombies ( int numkill ) ; // function to cleanup zombies under OSX.
2010-01-21 18:01:48 -05:00
//#define GPG_DEBUG 1
2009-07-30 17:27:47 -04:00
2012-04-09 13:03:47 -04:00
/* Function to sign X509_REQ via GPGme. */
2011-06-22 17:44:40 -04:00
2012-04-08 10:52:01 -04:00
bool AuthGPG : : decryptTextFromFile ( std : : string & text , const std : : string & inputfile )
2010-07-04 06:35:38 -04:00
{
2012-04-08 10:52:01 -04:00
return PGPHandler : : decryptTextFromFile ( mOwnGpgId , text , inputfile ) ;
2010-07-04 06:35:38 -04:00
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : encryptTextToFile ( const std : : string & text , const std : : string & outfile )
2009-05-25 07:38:47 -04:00
{
2012-04-08 10:52:01 -04:00
return PGPHandler : : encryptTextToFile ( mOwnGpgId , text , outfile ) ;
2009-05-25 07:38:47 -04:00
}
2009-05-23 13:40:35 -04:00
2012-04-09 13:03:47 -04:00
std : : string pgp_pwd_callback ( void * /*hook*/ , const char * uid_hint , const char * /*passphrase_info*/ , int prev_was_bad )
2009-05-25 07:38:47 -04:00
{
2010-04-20 08:08:25 -04:00
# define GPG_DEBUG2
# ifdef GPG_DEBUG2
fprintf ( stderr , " pgp_pwd_callback() called. \n " ) ;
# endif
2011-08-05 16:45:09 -04:00
std : : string password ;
2012-04-08 10:52:01 -04:00
rsicontrol - > getNotify ( ) . askForPassword ( uid_hint , prev_was_bad , password ) ;
2009-05-24 06:33:08 -04:00
2012-04-08 10:52:01 -04:00
return password ;
}
2009-05-24 06:33:08 -04:00
2012-06-20 17:59:04 -04:00
void AuthGPG : : init ( const std : : string & path_to_public_keyring , const std : : string & path_to_secret_keyring , const std : : string & path_to_trustdb , const std : : string & pgp_lock_file )
2009-05-23 13:40:35 -04:00
{
2012-04-08 10:52:01 -04:00
if ( _instance ! = NULL )
2010-04-20 08:08:25 -04:00
{
2012-06-09 20:29:46 -04:00
exit ( ) ;
2012-06-09 17:01:22 -04:00
std : : cerr < < " AuthGPG::init() called twice! " < < std : : endl ;
2010-04-20 08:08:25 -04:00
}
2009-05-23 13:40:35 -04:00
2012-05-01 04:53:32 -04:00
PGPHandler : : setPassphraseCallback ( pgp_pwd_callback ) ;
2012-06-20 17:59:04 -04:00
_instance = new AuthGPG ( path_to_public_keyring , path_to_secret_keyring , path_to_trustdb , pgp_lock_file ) ;
2009-05-23 13:40:35 -04:00
}
2012-06-09 20:29:46 -04:00
void AuthGPG : : exit ( )
2009-05-23 13:40:35 -04:00
{
2012-06-09 20:29:46 -04:00
if ( _instance ! = NULL )
{
_instance - > join ( ) ;
delete _instance ;
_instance = NULL ;
}
2010-04-30 10:34:48 -04:00
}
2010-04-08 15:07:40 -04:00
2012-06-20 17:59:04 -04:00
AuthGPG : : AuthGPG ( const std : : string & path_to_public_keyring , const std : : string & path_to_secret_keyring , const std : : string & path_to_trustdb , const std : : string & pgp_lock_file )
2012-04-08 10:52:01 -04:00
: p3Config ( CONFIG_TYPE_AUTHGPG ) ,
2012-06-20 17:59:04 -04:00
PGPHandler ( path_to_public_keyring , path_to_secret_keyring , path_to_trustdb , pgp_lock_file ) ,
2012-06-29 15:38:19 -04:00
gpgMtxService ( " AuthGPG-service " ) ,
2012-04-08 10:52:01 -04:00
gpgMtxEngine ( " AuthGPG-engine " ) ,
gpgMtxData ( " AuthGPG-data " ) ,
2012-06-29 15:38:19 -04:00
gpgKeySelected ( false )
2010-04-30 10:34:48 -04:00
{
2012-07-07 12:26:54 -04:00
_force_sync_database = false ;
2012-04-08 10:52:01 -04:00
start ( ) ;
2009-10-27 16:50:30 -04:00
}
2009-05-23 13:40:35 -04:00
/* This function is called when retroshare is first started
* to get the list of available GPG certificates .
* This function should only return certs for which
* the private ( secret ) keys are available .
*
* returns false if GnuPG is not available .
*/
2012-04-08 10:52:01 -04:00
bool AuthGPG : : availableGPGCertificatesWithPrivateKeys ( std : : list < std : : string > & ids )
2009-05-23 13:40:35 -04:00
{
2012-04-08 10:52:01 -04:00
std : : list < PGPIdType > pids ;
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
PGPHandler : : availableGPGCertificatesWithPrivateKeys ( pids ) ;
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
for ( std : : list < PGPIdType > : : const_iterator it ( pids . begin ( ) ) ; it ! = pids . end ( ) ; + + it )
ids . push_back ( ( * it ) . toStdString ( ) ) ;
2009-05-23 13:40:35 -04:00
/* return false if there are no private keys */
2012-04-08 10:52:01 -04:00
return ! ids . empty ( ) ;
2009-05-23 13:40:35 -04:00
}
/* You can initialise Retroshare with
* ( a ) load existing certificate .
* ( b ) a new certificate .
*
* This function must be called successfully ( return = = 1 )
* before anything else can be done . ( except above fn ) .
*/
2012-04-08 10:52:01 -04:00
int AuthGPG : : GPGInit ( const std : : string & ownId )
2009-05-23 13:40:35 -04:00
{
2012-04-08 10:52:01 -04:00
std : : cerr < < " AuthGPG::GPGInit() called with own gpg id : " < < ownId < < std : : endl ;
2010-02-09 14:10:15 -05:00
2012-06-09 14:45:35 -04:00
mOwnGpgId = PGPIdType ( ownId ) ;
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
//force the validity of the private key. When set to unknown, it caused signature and text encryptions bugs
privateTrustCertificate ( ownId , 5 ) ;
2012-07-13 08:20:44 -04:00
updateOwnSignatureFlag ( mOwnGpgId ) ;
2009-05-25 07:38:47 -04:00
2012-04-08 10:52:01 -04:00
std : : cerr < < " AuthGPG::GPGInit finished. " < < std : : endl ;
2009-05-25 07:38:47 -04:00
2012-04-08 10:52:01 -04:00
return 1 ;
2009-05-23 13:40:35 -04:00
}
2012-04-08 10:52:01 -04:00
AuthGPG : : ~ AuthGPG ( )
2009-05-23 13:40:35 -04:00
{
}
2012-04-08 10:52:01 -04:00
void AuthGPG : : run ( )
2010-09-30 15:05:43 -04:00
{
int count = 0 ;
2011-03-03 18:30:08 -05:00
while ( isRunning ( ) )
2010-09-30 15:05:43 -04:00
{
# ifdef WIN32
2011-01-09 07:31:41 -05:00
Sleep ( 100 ) ;
2010-09-30 15:05:43 -04:00
# else
2011-01-09 07:31:41 -05:00
usleep ( 100000 ) ;
2010-09-30 15:05:43 -04:00
# endif
2011-01-09 07:31:41 -05:00
/* every 100 milliseconds */
2010-10-13 12:15:26 -04:00
processServices ( ) ;
2012-06-29 15:38:19 -04:00
/* every ten seconds */
2012-07-07 12:26:54 -04:00
if ( + + count > = 100 | | _force_sync_database )
2012-06-29 15:38:19 -04:00
{
RsStackMutex stack ( gpgMtxService ) ; /******* LOCKED ******/
// The call does multiple things at once:
// - checks whether the keyring has changed in memory
// - checks whether the keyring has changed on disk.
// - merges/updates according to status.
//
PGPHandler : : syncDatabase ( ) ;
count = 0 ;
2012-07-07 12:26:54 -04:00
_force_sync_database = false ;
2010-09-30 15:05:43 -04:00
}
}
}
2012-04-08 10:52:01 -04:00
void AuthGPG : : processServices ( )
2010-10-13 12:15:26 -04:00
{
AuthGPGOperation * operation = NULL ;
AuthGPGService * service = NULL ;
{
RsStackMutex stack ( gpgMtxService ) ; /******* LOCKED ******/
std : : list < AuthGPGService * > : : iterator serviceIt ;
for ( serviceIt = services . begin ( ) ; serviceIt ! = services . end ( ) ; serviceIt + + ) {
operation = ( * serviceIt ) - > getGPGOperation ( ) ;
if ( operation ) {
service = * serviceIt ;
break ;
}
}
} /******* UNLOCKED ******/
if ( operation = = NULL ) {
/* nothing to do */
return ;
}
if ( service = = NULL ) {
/* huh ? */
delete operation ;
return ;
}
AuthGPGOperationLoadOrSave * loadOrSave = dynamic_cast < AuthGPGOperationLoadOrSave * > ( operation ) ;
2012-04-09 13:03:47 -04:00
if ( loadOrSave )
{
if ( loadOrSave - > m_load )
{
/* process load operation */
2010-10-13 12:15:26 -04:00
2012-02-15 11:44:45 -05:00
2012-04-09 13:03:47 -04:00
/* load the certificate */
2012-02-15 11:44:45 -05:00
2012-04-09 13:03:47 -04:00
/* don't bother loading - if we already have the certificate */
if ( isGPGId ( loadOrSave - > m_certGpgId ) )
{
2012-02-17 15:28:59 -05:00
# ifdef GPG_DEBUG
2012-04-09 13:03:47 -04:00
std : : cerr < < " AuthGPGimpl::processServices() Skipping load - already have it " < < std : : endl ;
2012-02-17 15:28:59 -05:00
# endif
2012-04-09 13:03:47 -04:00
}
else
{
2010-10-13 12:15:26 -04:00
# ifdef GPG_DEBUG
2012-04-09 13:03:47 -04:00
std : : cerr < < " AuthGPGimpl::processServices() Process load operation " < < std : : endl ;
2010-10-13 12:15:26 -04:00
# endif
2012-04-09 13:03:47 -04:00
std : : string error_string ;
2013-01-19 08:43:35 -05:00
PGPIdType pgp_id ;
LoadCertificateFromString ( loadOrSave - > m_certGpg , pgp_id , error_string ) ;
loadOrSave - > m_certGpgId = pgp_id . toStdString ( ) ;
2012-04-09 13:03:47 -04:00
}
2012-02-15 11:44:45 -05:00
2010-10-13 12:15:26 -04:00
2012-04-09 13:03:47 -04:00
} else {
/* process save operation */
2010-10-13 12:15:26 -04:00
# ifdef GPG_DEBUG
2012-04-09 13:03:47 -04:00
std : : cerr < < " AuthGPGimpl::processServices() Process save operation " < < std : : endl ;
2010-10-13 12:15:26 -04:00
# endif
2012-04-09 13:03:47 -04:00
/* save the certificate to string */
/*****
* # define DISABLE_CERTIFICATE_SEND 1
* * * */
2012-01-20 09:41:45 -05:00
2012-04-09 13:03:47 -04:00
loadOrSave - > m_certGpg = SaveCertificateToString ( loadOrSave - > m_certGpgId , true ) ;
2012-01-20 09:41:45 -05:00
2012-02-17 15:28:59 -05:00
# ifdef GPG_DEBUG
2012-04-09 13:03:47 -04:00
std : : cerr < < " Certificate for: " < < loadOrSave - > m_certGpgId < < " is: " ;
std : : cerr < < std : : endl ;
std : : cerr < < loadOrSave - > m_certGpg ;
std : : cerr < < std : : endl ;
2012-01-19 20:05:46 -05:00
# endif
2012-02-17 15:28:59 -05:00
2012-04-09 13:03:47 -04:00
}
2010-10-13 12:15:26 -04:00
2012-04-09 13:03:47 -04:00
service - > setGPGOperation ( loadOrSave ) ;
}
else
{
2010-10-13 12:15:26 -04:00
# ifdef GPG_DEBUG
std : : cerr < < " AuthGPGimpl::processServices() Unknown operation " < < std : : endl ;
# endif
}
delete operation ;
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : DoOwnSignature ( const void * data , unsigned int datalen , void * buf_sigout , unsigned int * outl )
2009-05-23 13:40:35 -04:00
{
2012-04-08 10:52:01 -04:00
return PGPHandler : : SignDataBin ( mOwnGpgId , data , datalen , ( unsigned char * ) buf_sigout , outl ) ;
2009-05-23 13:40:35 -04:00
}
2010-09-28 18:30:57 -04:00
2009-05-23 13:40:35 -04:00
/* import to GnuPG and other Certificates */
2012-04-08 10:52:01 -04:00
bool AuthGPG : : VerifySignature ( const void * data , int datalen , const void * sig , unsigned int siglen , const std : : string & withfingerprint )
2009-05-23 13:40:35 -04:00
{
2012-12-11 17:16:40 -05:00
if ( withfingerprint . length ( ) ! = 40 )
2009-05-23 13:40:35 -04:00
{
2012-12-11 17:16:40 -05:00
static bool already_reported = false ;
if ( ! already_reported )
{
std : : cerr < < " AuthGPG::VerifySignature(): no (or dammaged) fingerprint. Nor verifying signature. This is likely to be an unknown peer. fingerprint= \" " < < withfingerprint < < " \" . Not reporting other errors. " < < std : : endl ;
already_reported = true ;
}
2012-04-26 17:39:45 -04:00
return false ;
}
2010-04-25 15:26:37 -04:00
2012-06-09 14:45:35 -04:00
return PGPHandler : : VerifySignBin ( ( unsigned char * ) data , datalen , ( unsigned char * ) sig , siglen , PGPFingerprintType ( withfingerprint ) ) ;
2009-05-23 13:40:35 -04:00
}
2010-04-25 15:26:37 -04:00
2012-07-10 17:40:53 -04:00
bool AuthGPG : : exportProfile ( const std : : string & fname , const std : : string & exported_id )
{
return PGPHandler : : exportGPGKeyPair ( fname , PGPIdType ( exported_id ) ) ;
}
2010-09-28 18:30:57 -04:00
2012-07-12 15:20:31 -04:00
bool AuthGPG : : importProfile ( const std : : string & fname , std : : string & imported_id , std : : string & import_error )
2012-07-10 17:40:53 -04:00
{
PGPIdType id ;
2010-09-28 18:30:57 -04:00
2012-07-12 15:20:31 -04:00
if ( PGPHandler : : importGPGKeyPair ( fname , id , import_error ) )
2010-09-28 18:30:57 -04:00
{
2012-07-10 17:40:53 -04:00
imported_id = id . toStdString ( ) ;
return true ;
}
else
return false ;
}
2010-09-28 18:30:57 -04:00
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
bool AuthGPG : : active ( )
2010-01-21 18:01:48 -05:00
{
2010-09-30 15:05:43 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2010-09-28 18:30:57 -04:00
2012-04-08 10:52:01 -04:00
return gpgKeySelected ;
2009-05-23 13:40:35 -04:00
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : GeneratePGPCertificate ( const std : : string & name ,
const std : : string & email , const std : : string & passwd , std : : string & pgpId , std : : string & errString )
2012-01-27 08:03:59 -05:00
{
2012-04-08 10:52:01 -04:00
RsStackMutex stack ( gpgMtxEngine ) ; /******* LOCKED ******/
2012-01-27 08:03:59 -05:00
2012-04-08 10:52:01 -04:00
PGPIdType id ;
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
bool res = PGPHandler : : GeneratePGPCertificate ( name , email , passwd , id , errString ) ;
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
pgpId = id . toStdString ( ) ;
return res ;
2009-05-23 13:40:35 -04:00
}
/**** These Two are common */
2012-06-09 17:01:22 -04:00
std : : string AuthGPG : : getGPGName ( const std : : string & id , bool * success )
2009-05-23 13:40:35 -04:00
{
2012-04-26 17:39:45 -04:00
if ( id . length ( ) ! = 16 )
{
2012-09-26 15:28:32 -04:00
static int already = 0 ;
if ( already < 10 )
{
std : : cerr < < " Wrong string passed to getGPGDetails: \" " < < id < < " \" " < < std : : endl ;
already + + ;
}
2012-04-26 17:39:45 -04:00
return std : : string ( ) ;
}
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2010-04-25 13:06:48 -04:00
2012-06-09 14:45:35 -04:00
const PGPCertificateInfo * info = PGPHandler : : getCertificateInfo ( PGPIdType ( id ) ) ;
2009-05-23 13:40:35 -04:00
2012-04-09 13:03:47 -04:00
if ( info ! = NULL )
2012-06-09 17:01:22 -04:00
{
if ( success ! = NULL ) * success = true ;
2012-04-09 13:03:47 -04:00
return info - > _name ;
2012-06-09 17:01:22 -04:00
}
2012-04-09 13:03:47 -04:00
else
2012-06-09 17:01:22 -04:00
{
if ( success ! = NULL ) * success = false ;
2012-04-09 13:03:47 -04:00
return " [Unknown PGP Cert name] " ;
2012-06-09 17:01:22 -04:00
}
2009-05-23 13:40:35 -04:00
}
2010-01-13 15:56:55 -05:00
/**** These Two are common */
2012-06-09 17:01:22 -04:00
std : : string AuthGPG : : getGPGEmail ( const std : : string & id , bool * success )
2009-05-23 13:40:35 -04:00
{
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2012-06-09 14:45:35 -04:00
const PGPCertificateInfo * info = PGPHandler : : getCertificateInfo ( PGPIdType ( id ) ) ;
2009-05-23 13:40:35 -04:00
2012-04-09 13:03:47 -04:00
if ( info ! = NULL )
2012-06-09 17:01:22 -04:00
{
if ( success ! = NULL ) * success = true ;
2012-04-09 13:03:47 -04:00
return info - > _email ;
2012-06-09 17:01:22 -04:00
}
2012-04-09 13:03:47 -04:00
else
2012-06-09 17:01:22 -04:00
{
if ( success ! = NULL ) * success = false ;
2012-04-09 13:03:47 -04:00
return " [Unknown PGP Cert email] " ;
2012-06-09 17:01:22 -04:00
}
2010-01-13 15:56:55 -05:00
}
2009-05-23 13:40:35 -04:00
/**** GPG versions ***/
2012-04-08 10:52:01 -04:00
std : : string AuthGPG : : getGPGOwnId ( )
2009-05-23 13:40:35 -04:00
{
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
return mOwnGpgId . toStdString ( ) ;
2009-05-23 13:40:35 -04:00
}
2012-04-08 10:52:01 -04:00
std : : string AuthGPG : : getGPGOwnName ( )
2010-01-13 16:22:52 -05:00
{
2012-04-09 13:03:47 -04:00
return getGPGName ( mOwnGpgId . toStdString ( ) ) ;
2010-01-13 16:22:52 -05:00
}
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
bool AuthGPG : : getGPGAllList ( std : : list < std : : string > & ids )
2009-05-23 13:40:35 -04:00
{
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2010-04-25 15:26:37 -04:00
2012-04-09 13:03:47 -04:00
std : : list < PGPIdType > list ;
PGPHandler : : getGPGFilteredList ( list ) ;
2010-04-25 15:26:37 -04:00
2012-04-09 13:03:47 -04:00
for ( std : : list < PGPIdType > : : const_iterator it ( list . begin ( ) ) ; it ! = list . end ( ) ; + + it )
ids . push_back ( ( * it ) . toStdString ( ) ) ;
2010-01-13 16:12:56 -05:00
2012-04-09 13:03:47 -04:00
return true ;
2010-01-13 16:08:46 -05:00
}
2012-07-08 17:06:41 -04:00
bool AuthGPG : : haveSecretKey ( const std : : string & id ) const
{
return PGPHandler : : haveSecretKey ( PGPIdType ( id ) ) ;
}
2012-06-14 16:13:31 -04:00
bool AuthGPG : : isKeySupported ( const std : : string & id ) const
{
const PGPCertificateInfo * pc = PGPHandler : : getCertificateInfo ( PGPIdType ( id ) ) ;
2010-03-02 17:35:49 -05:00
2012-06-14 16:13:31 -04:00
if ( pc = = NULL )
return false ;
2009-05-23 13:40:35 -04:00
2012-06-14 16:13:31 -04:00
return ! ( pc - > _flags & PGPCertificateInfo : : PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM ) ;
}
2010-04-25 13:06:48 -04:00
2012-04-09 13:03:47 -04:00
bool AuthGPG : : getGPGDetails ( const std : : string & id , RsPeerDetails & d )
2010-01-13 16:16:18 -05:00
{
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2010-09-28 18:30:57 -04:00
2012-04-26 17:39:45 -04:00
if ( id . length ( ) ! = 16 )
2010-09-28 18:30:57 -04:00
{
2013-03-19 16:21:20 -04:00
static int already = 0 ;
if ( already < 10 )
{
std : : cerr < < " Wrong string passed to getGPGDetails: \" " < < id < < " \" " < < std : : endl ;
+ + already ;
}
2012-04-26 17:39:45 -04:00
return false ;
}
2010-09-28 18:30:57 -04:00
2012-06-09 14:45:35 -04:00
const PGPCertificateInfo * pc = PGPHandler : : getCertificateInfo ( PGPIdType ( id ) ) ;
2010-09-28 18:30:57 -04:00
2012-04-09 13:03:47 -04:00
if ( pc = = NULL )
return false ;
2010-09-28 18:30:57 -04:00
2012-04-09 13:03:47 -04:00
const PGPCertificateInfo & cert ( * pc ) ;
2010-09-28 18:30:57 -04:00
2012-04-09 13:03:47 -04:00
d . id = id ;
d . gpg_id = id ;
d . name = cert . _name ;
2013-05-21 18:38:00 -04:00
d . lastUsed = cert . _time_stamp ;
2012-04-09 13:03:47 -04:00
d . email = cert . _email ;
d . trustLvl = cert . _trustLvl ;
2012-07-07 12:26:54 -04:00
d . validLvl = cert . _trustLvl ;
2012-04-09 13:03:47 -04:00
d . ownsign = cert . _flags & PGPCertificateInfo : : PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ;
d . gpgSigners . clear ( ) ;
for ( std : : set < std : : string > : : const_iterator it ( cert . signers . begin ( ) ) ; it ! = cert . signers . end ( ) ; + + it )
d . gpgSigners . push_back ( * it ) ;
2010-09-28 18:30:57 -04:00
2012-04-09 13:03:47 -04:00
d . fpr = cert . _fpr . toStdString ( ) ;
2010-09-28 18:30:57 -04:00
2012-04-09 13:03:47 -04:00
d . accept_connection = cert . _flags & PGPCertificateInfo : : PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ;
d . hasSignedMe = cert . _flags & PGPCertificateInfo : : PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME ;
2010-04-25 13:06:48 -04:00
2009-05-23 13:40:35 -04:00
return true ;
}
2012-04-09 13:03:47 -04:00
bool AuthGPG : : getGPGFilteredList ( std : : list < std : : string > & list , bool ( * filter ) ( const PGPCertificateInfo & ) )
2009-05-23 13:40:35 -04:00
{
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
std : : list < PGPIdType > ids ;
2009-05-23 13:40:35 -04:00
2012-04-09 13:03:47 -04:00
PGPHandler : : getGPGFilteredList ( ids , filter ) ;
2009-05-23 13:40:35 -04:00
2012-04-09 13:03:47 -04:00
for ( std : : list < PGPIdType > : : const_iterator it ( ids . begin ( ) ) ; it ! = ids . end ( ) ; + + it )
list . push_back ( ( * it ) . toStdString ( ) ) ;
2009-05-23 13:40:35 -04:00
2012-05-01 04:53:32 -04:00
return true ;
2009-05-23 13:40:35 -04:00
}
2012-04-09 13:03:47 -04:00
static bool filter_Validity ( const PGPCertificateInfo & info ) { return true ; } //{ return info._validLvl >= PGPCertificateInfo::GPGME_VALIDITY_MARGINAL ; }
static bool filter_Accepted ( const PGPCertificateInfo & info ) { return info . _flags & PGPCertificateInfo : : PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION ; }
static bool filter_OwnSigned ( const PGPCertificateInfo & info ) { return info . _flags & PGPCertificateInfo : : PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE ; }
2009-05-23 13:40:35 -04:00
2012-04-09 13:03:47 -04:00
bool AuthGPG : : getGPGValidList ( std : : list < std : : string > & ids )
2009-07-30 17:27:47 -04:00
{
2012-04-09 13:03:47 -04:00
return getGPGFilteredList ( ids , & filter_Validity ) ;
2009-07-30 17:27:47 -04:00
}
2009-05-23 13:40:35 -04:00
2012-04-09 13:03:47 -04:00
bool AuthGPG : : getGPGAcceptedList ( std : : list < std : : string > & ids )
2009-05-23 13:40:35 -04:00
{
2012-04-09 13:03:47 -04:00
return getGPGFilteredList ( ids , & filter_Accepted ) ;
2009-05-23 13:40:35 -04:00
}
2012-04-09 13:03:47 -04:00
bool AuthGPG : : getGPGSignedList ( std : : list < std : : string > & ids )
2009-05-23 13:40:35 -04:00
{
2012-04-09 13:03:47 -04:00
return getGPGFilteredList ( ids , & filter_OwnSigned ) ;
2009-05-23 13:40:35 -04:00
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : getCachedGPGCertificate ( const std : : string & id , std : : string & certificate )
2009-05-23 13:40:35 -04:00
{
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
# ifdef LIMIT_CERTIFICATE_SIZE
2012-08-13 15:37:50 -04:00
certificate = PGPHandler : : SaveCertificateToString ( PGPIdType ( id ) , false ) ;
# else
certificate = PGPHandler : : SaveCertificateToString ( PGPIdType ( id ) , true ) ;
2012-02-17 15:28:59 -05:00
# endif
2012-02-15 11:44:45 -05:00
2012-08-13 15:37:50 -04:00
// #ifdef LIMIT_CERTIFICATE_SIZE
// std::string cleaned_key ;
// if(PGPKeyManagement::createMinimalKey(certificate,cleaned_key))
// certificate = cleaned_key ;
// #endif
2012-04-09 13:03:47 -04:00
return certificate . length ( ) > 0 ;
2012-02-15 11:44:45 -05:00
}
2009-05-23 13:40:35 -04:00
/*****************************************************************
* Loading and Saving Certificates - this has to
* be able to handle both openpgp and X509 certificates .
*
* X509 are passed onto AuthSSL , OpenPGP are passed to gpgme .
*
*/
2011-08-12 09:42:30 -04:00
2011-07-01 16:47:58 -04:00
2009-05-23 13:40:35 -04:00
/* SKTAN : do not know how to use std::string id */
2012-04-08 10:52:01 -04:00
std : : string AuthGPG : : SaveCertificateToString ( const std : : string & id , bool include_signatures )
2009-05-23 13:40:35 -04:00
{
2012-01-23 15:55:08 -05:00
if ( ! isGPGId ( id ) ) {
2012-04-08 10:52:01 -04:00
std : : cerr < < " AuthGPG::SaveCertificateToString() unknown ID " < < std : : endl ;
2012-01-23 15:55:08 -05:00
return " " ;
2009-05-23 13:40:35 -04:00
}
2012-01-23 15:55:08 -05:00
RsStackMutex stack ( gpgMtxEngine ) ; /******* LOCKED ******/
2009-07-21 17:25:39 -04:00
2012-06-09 14:45:35 -04:00
std : : string tmp = PGPHandler : : SaveCertificateToString ( PGPIdType ( id ) , include_signatures ) ;
2009-05-23 13:40:35 -04:00
2012-08-13 15:37:50 -04:00
// // Try to remove signatures manually.
// //
// std::string cleaned_key ;
//
// if( (!include_signatures) && PGPKeyManagement::createMinimalKey(tmp,cleaned_key))
// return cleaned_key ;
// else
2012-01-23 15:55:08 -05:00
2012-08-13 15:37:50 -04:00
return tmp ;
2009-05-23 13:40:35 -04:00
}
/* import to GnuPG and other Certificates */
2013-01-19 08:43:35 -05:00
bool AuthGPG : : LoadCertificateFromString ( const std : : string & str , PGPIdType & gpg_id , std : : string & error_string )
2009-05-23 13:40:35 -04:00
{
2012-04-08 10:52:01 -04:00
RsStackMutex stack ( gpgMtxEngine ) ; /******* LOCKED ******/
2009-05-25 07:38:47 -04:00
2013-01-19 08:43:35 -05:00
return PGPHandler : : LoadCertificateFromString ( str , gpg_id , error_string ) ;
2009-05-23 13:40:35 -04:00
}
/*****************************************************************
* Auth . . . ? Signing , Revoke , Trust are all done at
* the PGP level . . . .
*
* Only Signing of SSL is done at setup .
* Auth should be done . . . ? ? not sure
* maybe
*
*/
/*************************************/
2010-01-13 16:22:52 -05:00
/* These take PGP Ids */
2012-04-08 10:52:01 -04:00
bool AuthGPG : : AllowConnection ( const std : : string & gpg_id , bool accept )
2010-01-13 16:22:52 -05:00
{
2010-01-21 18:01:48 -05:00
# ifdef GPG_DEBUG
2012-04-08 10:52:01 -04:00
std : : cerr < < " AuthGPG::AllowConnection( " < < gpg_id < < " ) " < < std : : endl ;
2010-01-21 18:01:48 -05:00
# endif
2010-01-13 16:22:52 -05:00
2011-08-07 17:11:00 -04:00
/* Was a "Reload Certificates" here -> be shouldn't be needed -> and very expensive, try without. */
{
RsStackMutex stack ( gpgMtxData ) ;
2012-06-09 14:45:35 -04:00
PGPHandler : : setAcceptConnexion ( PGPIdType ( gpg_id ) , accept ) ;
2011-08-07 17:11:00 -04:00
}
2010-04-25 13:06:48 -04:00
2011-08-21 18:28:19 -04:00
IndicateConfigChanged ( ) ;
2010-01-13 16:26:30 -05:00
2011-08-21 18:28:19 -04:00
rsicontrol - > getNotify ( ) . notifyListChange ( NOTIFY_LIST_FRIENDS , accept ? NOTIFY_TYPE_ADD : NOTIFY_TYPE_DEL ) ;
return true ;
2010-01-13 16:22:52 -05:00
}
2009-05-23 13:40:35 -04:00
/* These take PGP Ids */
2012-04-08 10:52:01 -04:00
bool AuthGPG : : SignCertificateLevel0 ( const std : : string & id )
2009-05-23 13:40:35 -04:00
{
2010-01-21 18:01:48 -05:00
# ifdef GPG_DEBUG
2012-04-08 10:52:01 -04:00
std : : cerr < < " AuthGPG::SignCertificat( " < < id < < " ) " < < std : : endl ;
2010-01-21 18:01:48 -05:00
# endif
2009-05-23 13:40:35 -04:00
2012-07-07 12:26:54 -04:00
return privateSignCertificate ( id ) ;
2009-05-23 13:40:35 -04:00
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : RevokeCertificate ( const std : : string & id )
2009-05-23 13:40:35 -04:00
{
2011-08-12 09:42:30 -04:00
/* remove unused parameter warnings */
( void ) id ;
2009-05-25 07:38:47 -04:00
2010-01-21 18:01:48 -05:00
# ifdef GPG_DEBUG
2012-04-08 10:52:01 -04:00
std : : cerr < < " AuthGPG::RevokeCertificate( " < < id < < " ) not implemented yet " < < std : : endl ;
2010-01-21 18:01:48 -05:00
# endif
2009-05-23 13:40:35 -04:00
return false ;
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : TrustCertificate ( const std : : string & id , int trustlvl )
2010-01-13 16:14:49 -05:00
{
2010-01-21 18:01:48 -05:00
# ifdef GPG_DEBUG
2012-07-07 12:26:54 -04:00
std : : cerr < < " AuthGPG::TrustCertificate( " < < id < < " , " < < trustlvl < < " ) " < < std : : endl ;
2010-01-21 18:01:48 -05:00
# endif
2012-07-07 12:26:54 -04:00
return privateTrustCertificate ( id , trustlvl ) ;
2009-05-23 13:40:35 -04:00
}
2012-07-07 12:26:54 -04:00
bool AuthGPG : : SignDataBin ( const void * data , unsigned int datalen , unsigned char * sign , unsigned int * signlen )
2009-05-23 13:40:35 -04:00
{
2012-07-07 12:26:54 -04:00
return DoOwnSignature ( data , datalen , sign , signlen ) ;
2009-05-23 13:40:35 -04:00
}
2012-07-07 12:26:54 -04:00
bool AuthGPG : : VerifySignBin ( const void * data , uint32_t datalen , unsigned char * sign , unsigned int signlen , const std : : string & withfingerprint )
2009-05-23 13:40:35 -04:00
{
2012-07-07 12:26:54 -04:00
return VerifySignature ( data , datalen , sign , signlen , withfingerprint ) ;
2009-05-23 13:40:35 -04:00
}
2012-07-07 12:26:54 -04:00
/* Sign/Trust stuff */
2009-05-23 13:40:35 -04:00
2012-04-08 10:52:01 -04:00
int AuthGPG : : privateSignCertificate ( const std : : string & id )
2009-05-23 13:40:35 -04:00
{
2012-07-07 12:26:54 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2009-05-23 13:40:35 -04:00
2012-07-07 12:26:54 -04:00
int ret = PGPHandler : : privateSignCertificate ( mOwnGpgId , PGPIdType ( id ) ) ;
_force_sync_database = true ;
return ret ;
2009-05-23 13:40:35 -04:00
}
/* revoke the signature on Certificate */
2012-04-08 10:52:01 -04:00
int AuthGPG : : privateRevokeCertificate ( const std : : string & /*id*/ )
2009-05-23 13:40:35 -04:00
{
2011-08-12 09:42:30 -04:00
//RsStackMutex stack(gpgMtx); /******* LOCKED ******/
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
return 0 ;
}
2012-04-08 10:52:01 -04:00
int AuthGPG : : privateTrustCertificate ( const std : : string & id , int trustlvl )
2009-05-23 13:40:35 -04:00
{
2012-07-07 12:26:54 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2010-01-13 16:34:47 -05:00
/* The certificate should be in Peers list ??? */
2012-06-29 15:38:19 -04:00
if ( ! isGPGAccepted ( id ) )
{
2009-05-23 13:40:35 -04:00
std : : cerr < < " Invalid Certificate " < < std : : endl ;
return 0 ;
}
2012-07-07 12:26:54 -04:00
int res = PGPHandler : : privateTrustCertificate ( PGPIdType ( id ) , trustlvl ) ;
_force_sync_database = true ;
return res ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 16:26:30 -05:00
// -----------------------------------------------------------------------------------//
// -------------------------------- Config functions ------------------------------ //
// -----------------------------------------------------------------------------------//
//
2012-04-08 10:52:01 -04:00
RsSerialiser * AuthGPG : : setupSerialiser ( )
2010-01-13 16:26:30 -05:00
{
RsSerialiser * rss = new RsSerialiser ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : saveList ( bool & cleanup , std : : list < RsItem * > & lst )
2010-01-13 16:26:30 -05:00
{
2012-04-08 10:52:01 -04:00
# ifdef GPG_DEBUG
std : : cerr < < " AuthGPG::saveList() called " < < std : : endl ;
# endif
2012-06-12 17:19:38 -04:00
std : : list < std : : string > ids ;
getGPGAcceptedList ( ids ) ; // needs to be done before the lock
2010-01-21 17:04:20 -05:00
2012-04-08 10:52:01 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
2010-01-21 17:04:20 -05:00
2012-04-08 10:52:01 -04:00
cleanup = true ;
2010-01-21 17:04:20 -05:00
2012-04-08 10:52:01 -04:00
// Now save config for network digging strategies
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
2011-08-07 17:11:00 -04:00
2012-04-09 13:03:47 -04:00
for ( std : : list < std : : string > : : const_iterator it ( ids . begin ( ) ) ; it ! = ids . end ( ) ; + + it )
if ( ( * it ) ! = mOwnGpgId . toStdString ( ) ) // skip our own id.
2011-08-07 17:11:00 -04:00
{
2012-04-09 13:03:47 -04:00
RsTlvKeyValue kv ;
2012-06-12 17:19:38 -04:00
kv . key = * it ;
2011-08-07 17:11:00 -04:00
# ifdef GPG_DEBUG
2012-06-12 17:19:38 -04:00
std : : cerr < < " AuthGPG::saveList() called (it->second) : " < < ( it - > second ) < < std : : endl ;
2011-08-07 17:11:00 -04:00
# endif
2012-04-09 13:03:47 -04:00
kv . value = " TRUE " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
}
2012-04-08 10:52:01 -04:00
lst . push_back ( vitem ) ;
2010-01-13 16:26:30 -05:00
2012-04-08 10:52:01 -04:00
return true ;
2010-01-13 16:26:30 -05:00
}
2012-04-08 10:52:01 -04:00
bool AuthGPG : : loadList ( std : : list < RsItem * > & load )
2010-01-13 16:26:30 -05:00
{
2012-04-09 13:03:47 -04:00
# ifdef GPG_DEBUG
std : : cerr < < " AuthGPG::loadList() Item Count: " < < load . size ( ) < < std : : endl ;
# endif
2010-01-13 16:26:30 -05:00
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxData ) ; /******* LOCKED ******/
/* load the list of accepted gpg keys */
std : : list < RsItem * > : : iterator it ;
for ( it = load . begin ( ) ; it ! = load . end ( ) ; it + + )
2011-08-07 17:11:00 -04:00
{
RsConfigKeyValueSet * vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ;
if ( vitem )
{
# ifdef GPG_DEBUG
2012-04-08 10:52:01 -04:00
std : : cerr < < " AuthGPG::loadList() General Variable Config Item: " < < std : : endl ;
2011-08-07 17:11:00 -04:00
vitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
# endif
std : : list < RsTlvKeyValue > : : iterator kit ;
for ( kit = vitem - > tlvkvs . pairs . begin ( ) ; kit ! = vitem - > tlvkvs . pairs . end ( ) ; kit + + )
2012-04-09 13:03:47 -04:00
if ( kit - > key ! = mOwnGpgId . toStdString ( ) )
2012-06-09 14:45:35 -04:00
PGPHandler : : setAcceptConnexion ( PGPIdType ( kit - > key ) , ( kit - > value = = " TRUE " ) ) ;
2012-04-09 13:03:47 -04:00
}
delete ( * it ) ;
}
return true ;
2010-01-13 16:26:30 -05:00
}
2010-04-08 15:08:41 -04:00
2012-04-08 10:52:01 -04:00
bool AuthGPG : : addService ( AuthGPGService * service )
2010-10-13 12:15:26 -04:00
{
2012-04-09 13:03:47 -04:00
RsStackMutex stack ( gpgMtxService ) ; /********* LOCKED *********/
2010-10-13 12:15:26 -04:00
2012-04-09 13:03:47 -04:00
if ( std : : find ( services . begin ( ) , services . end ( ) , service ) ! = services . end ( ) ) {
/* it exists already! */
return false ;
}
2010-10-13 12:15:26 -04:00
2012-04-09 13:03:47 -04:00
services . push_back ( service ) ;
return true ;
2010-10-13 12:15:26 -04:00
}
2011-01-23 06:57:09 -05:00