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"
2009-11-05 14:38:10 -05:00
# include <rsiface/rsiface.h>
2009-05-23 13:40:35 -04:00
# include <iostream>
# 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
2009-07-30 17:27:47 -04:00
2010-01-13 16:05:38 -05:00
// initialisation du pointeur de singleton à zéro
AuthGPG * AuthGPG : : instance_gpg = new AuthGPG ( ) ;
2009-05-23 13:40:35 -04:00
/* Turn a set of parameters into a string */
static std : : string setKeyPairParams ( bool useRsa , unsigned int blen ,
2010-01-13 16:06:53 -05:00
std : : string name , std : : string comment , std : : string email ) ;
2010-01-18 07:30:54 -05:00
static std : : string setKeyPairParams ( bool useRsa , unsigned int blen ,
std : : string name , std : : string comment , std : : string email ,
std : : string inPassphrase ) ;
2009-05-23 13:40:35 -04:00
static gpgme_key_t getKey ( gpgme_ctx_t , std : : string , std : : string , std : : string ) ;
static gpg_error_t keySignCallback ( void * , gpgme_status_code_t , \
const char * , int ) ;
static gpg_error_t trustCallback ( void * , gpgme_status_code_t , \
const char * , int ) ;
static void ProcessPGPmeError ( gpgme_error_t ERR ) ;
/* Function to sign X509_REQ via GPGme.
*/
2009-05-25 07:38:47 -04:00
gpgcert : : gpgcert ( )
: key ( NULL )
{
return ;
}
2009-05-23 13:40:35 -04:00
2009-05-25 07:38:47 -04:00
gpgcert : : ~ gpgcert ( )
{
if ( key )
{
2010-01-13 16:14:49 -05:00
gpgme_key_unref ( key ) ;
2009-05-25 07:38:47 -04:00
}
}
2009-05-24 06:33:08 -04:00
2009-05-23 13:40:35 -04:00
gpg_error_t pgp_pwd_callback ( void * hook , const char * uid_hint , const char * passphrase_info , int prev_was_bad , int fd )
{
2010-01-16 17:03:33 -05:00
static std : : string sp = " " ;
2009-11-05 14:38:10 -05:00
2010-01-16 17:03:33 -05:00
std : : string text ;
2009-10-30 17:26:35 -04:00
2010-01-16 17:03:33 -05:00
if ( sp = = " " | | prev_was_bad )
{
if ( prev_was_bad )
text = rsicontrol - > getNotify ( ) . askForPassword ( " GPG key passphrase " , std : : string ( " Wrong password ! \n \n Please enter the password to unlock the following GPG key: \n \n " ) + uid_hint + " \n " ) ;
else
text = rsicontrol - > getNotify ( ) . askForPassword ( " GPG key passphrase " , std : : string ( " Please enter the password to unlock the following GPG key: \n \n " ) + uid_hint + " \n " ) ;
sp = text ;
}
else
text = sp ;
2009-05-24 06:33:08 -04:00
fprintf ( stderr , " pgp_pwd_callback() Set Password \n " ) ;
2009-07-30 10:36:42 -04:00
# ifndef WINDOWS_SYS
2009-11-05 14:38:10 -05:00
write ( fd , text . c_str ( ) , text . size ( ) ) ;
2009-05-24 06:33:08 -04:00
write ( fd , " \n " , 1 ) ; /* needs a new line? */
2009-07-30 10:36:42 -04:00
# else
DWORD written = 0 ;
HANDLE winFd = ( HANDLE ) fd ;
2009-11-05 14:38:10 -05:00
WriteFile ( winFd , text . c_str ( ) , text . size ( ) , & written , NULL ) ;
2009-07-30 10:36:42 -04:00
WriteFile ( winFd , " \n " , 1 , & written , NULL ) ;
# endif
2009-05-23 13:40:35 -04:00
return 0 ;
}
2009-05-24 06:33:08 -04:00
static char * PgpPassword = NULL ;
2010-01-13 16:06:53 -05:00
//bool AuthGPG::setPGPPassword_locked(std::string pwd)
//{
// /* reset it while we change it */
// gpgme_set_passphrase_cb(CTX, NULL, NULL);
//
// if (PgpPassword)
// free(PgpPassword);
// PgpPassword = (char *) malloc(pwd.length() + 1);
// memcpy(PgpPassword, pwd.c_str(), pwd.length());
// PgpPassword[pwd.length()] = '\0';
//
// fprintf(stderr, "AuthGPG::setPGPPassword_locked() called\n");
// gpgme_set_passphrase_cb(CTX, pgp_pwd_callback, (void *) PgpPassword);
//
// return true;
//}
2009-05-24 06:33:08 -04:00
2009-05-23 13:40:35 -04:00
2010-01-13 15:58:58 -05:00
AuthGPG : : AuthGPG ( )
2010-01-13 16:26:30 -05:00
: gpgmeInit ( false ) , p3Config ( CONFIG_TYPE_AUTHGPG )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-23 13:40:35 -04:00
setlocale ( LC_ALL , " " ) ;
gpgme_check_version ( NULL ) ;
gpgme_set_locale ( NULL , LC_CTYPE , setlocale ( LC_CTYPE , NULL ) ) ;
2009-07-30 10:36:42 -04:00
# ifdef LC_MESSAGES
2009-05-23 13:40:35 -04:00
gpgme_set_locale ( NULL , LC_MESSAGES , setlocale ( LC_MESSAGES , NULL ) ) ;
# endif
2009-10-27 16:46:56 -04:00
# ifndef WINDOWS_SYS
/* setup the engine (gpg2) */
2009-10-27 16:50:30 -04:00
// if (GPG_ERR_NO_ERROR != gpgme_set_engine_info(GPGME_PROTOCOL_OpenPGP, "/usr/bin/gpg2", NULL))
// {
// std::cerr << "Error creating Setting engine";
// std::cerr << std::endl;
// return;
// }
2009-10-27 16:46:56 -04:00
# endif
2009-05-23 13:40:35 -04:00
if ( GPG_ERR_NO_ERROR ! = gpgme_engine_check_version ( GPGME_PROTOCOL_OpenPGP ) )
{
std : : cerr < < " Error check engine version " ;
std : : cerr < < std : : endl ;
return ;
}
if ( GPG_ERR_NO_ERROR ! = gpgme_get_engine_info ( & INFO ) )
{
std : : cerr < < " Error getting engine info " ;
std : : cerr < < std : : endl ;
2009-10-27 16:50:30 -04:00
while ( INFO & & INFO - > protocol ! = GPGME_PROTOCOL_OpenPGP ) {
INFO = INFO - > next ;
}
if ( ! INFO ) {
fprintf ( stderr , " GPGME compiled without support for protocol %s " ,
gpgme_get_protocol_name ( INFO - > protocol ) ) ;
} else if ( INFO - > file_name & & ! INFO - > version ) {
fprintf ( stderr , " Engine %s not installed properly " ,
INFO - > file_name ) ;
} else if ( INFO - > file_name & & INFO - > version & & INFO - > req_version ) {
fprintf ( stderr , " Engine %s version %s installed, "
" but at least version %s required " , INFO - > file_name ,
INFO - > version , INFO - > req_version ) ;
} else {
fprintf ( stderr , " Unknown problem with engine for protocol %s " ,
gpgme_get_protocol_name ( INFO - > protocol ) ) ;
}
return ;
2009-05-23 13:40:35 -04:00
}
/* Create New Contexts */
if ( GPG_ERR_NO_ERROR ! = gpgme_new ( & CTX ) )
{
std : : cerr < < " Error creating GPGME Context " ;
std : : cerr < < std : : endl ;
return ;
}
/* setup the protocol */
if ( GPG_ERR_NO_ERROR ! = gpgme_set_protocol ( CTX , GPGME_PROTOCOL_OpenPGP ) )
{
std : : cerr < < " Error creating Setting Protocol " ;
std : : cerr < < std : : endl ;
return ;
}
/* if we get to here -> we have inited okay */
gpgmeInit = true ;
2010-01-13 16:05:38 -05:00
storeAllKeys_locked ( ) ;
printAllKeys_locked ( ) ;
//updateTrustAllKeys_locked();
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 .
*/
2010-01-13 16:22:52 -05:00
bool AuthGPG : : availableGPGCertificatesWithPrivateKeys ( std : : list < std : : string > & ids )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
int i = 0 ;
gpgme_key_t KEY = NULL ;
gpg_error_t ERR ;
/* XXX should check that CTX is valid */
if ( ! gpgmeInit )
{
return false ;
}
/* Initiates a key listing */
if ( GPG_ERR_NO_ERROR ! = gpgme_op_keylist_start ( CTX , " " , 1 ) )
{
std : : cerr < < " Error iterating through KeyList " ;
std : : cerr < < std : : endl ;
return false ;
}
/* Loop until end of key */
for ( i = 0 ; ( GPG_ERR_NO_ERROR = = ( ERR = gpgme_op_keylist_next ( CTX , & KEY ) ) ) ; i + + )
{
2010-01-13 16:16:18 -05:00
if ( KEY - > subkeys )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:16:18 -05:00
ids . push_back ( KEY - > subkeys - > keyid ) ;
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::availablePGPCertificates() Added: "
2009-05-23 13:40:35 -04:00
< < KEY - > subkeys - > keyid < < std : : endl ;
}
else
{
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::availablePGPCertificates() Missing subkey "
2009-05-23 13:40:35 -04:00
< < std : : endl ;
}
}
if ( GPG_ERR_NO_ERROR ! = gpgme_op_keylist_end ( CTX ) )
{
std : : cerr < < " Error ending KeyList " ;
std : : cerr < < std : : endl ;
return false ;
}
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::availablePGPCertificates() Secret Key Count: " < < i < < std : : endl ;
2009-05-23 13:40:35 -04:00
/* return false if there are no private keys */
return ( i > 0 ) ;
}
/* 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 ) .
*/
2010-01-13 15:58:58 -05:00
int AuthGPG : : GPGInit ( std : : string ownId )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2010-01-18 07:30:54 -05:00
std : : cerr < < " AuthGPG::GPGInit() called with own gpg id : " < < ownId < < std : : endl ;
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
gpgme_key_t newKey ;
gpg_error_t ERR ;
if ( ! gpgmeInit ) {
return 0 ;
}
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_get_key ( CTX , ownId . c_str ( ) , & newKey , 1 ) ) ) {
std : : cerr < < " Error reading the key from keyring " < < std : : endl ;
return 0 ;
}
2010-01-13 15:56:55 -05:00
mOwnGpgCert . name = newKey - > uids - > name ;
mOwnGpgCert . email = newKey - > uids - > email ;
mOwnGpgCert . fpr = newKey - > subkeys - > fpr ;
mOwnGpgCert . id = ownId ;
2009-05-23 13:40:35 -04:00
mOwnGpgCert . key = newKey ;
2010-01-13 16:05:38 -05:00
mOwnGpgId = ownId ;
2010-01-13 16:22:52 -05:00
mOwnGpgName = newKey - > uids - > name ;
mOwnGpgEmail = newKey - > uids - > email ;
2009-05-23 13:40:35 -04:00
gpgmeKeySelected = true ;
2010-01-13 16:05:38 -05:00
storeAllKeys_locked ( ) ;
printAllKeys_locked ( ) ;
2009-05-25 07:38:47 -04:00
2010-01-13 16:06:53 -05:00
gpgme_set_passphrase_cb ( CTX , pgp_pwd_callback , ( void * ) NULL ) ;
2010-01-13 16:05:38 -05:00
std : : cerr < < " AuthGPG::GPGInit finished. " < < std : : endl ;
2009-05-25 07:38:47 -04:00
2010-01-13 16:05:38 -05:00
return true ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 15:58:58 -05:00
AuthGPG : : ~ AuthGPG ( )
2009-05-23 13:40:35 -04:00
{
}
// store all keys in map mKeyList to avoid callin gpgme exe repeatedly
2010-01-13 15:58:58 -05:00
bool AuthGPG : : storeAllKeys_locked ( )
2009-05-23 13:40:35 -04:00
{
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::storeAllKeys_locked() " ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
gpg_error_t ERR ;
if ( ! gpgmeInit )
{
std : : cerr < < " Error since GPG is not initialised " ;
std : : cerr < < std : : endl ;
return false ;
}
2009-05-25 07:38:47 -04:00
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::storeAllKeys_locked() clearing existing ones " ;
2009-05-25 07:38:47 -04:00
std : : cerr < < std : : endl ;
2010-01-13 16:14:49 -05:00
mKeyList . clear ( ) ;
2009-05-23 13:40:35 -04:00
/* enable SIG mode */
gpgme_keylist_mode_t origmode = gpgme_get_keylist_mode ( CTX ) ;
gpgme_keylist_mode_t mode = origmode | GPGME_KEYLIST_MODE_SIGS ;
gpgme_set_keylist_mode ( CTX , mode ) ;
/* store keys */
gpgme_key_t KEY = NULL ;
/* Initiates a key listing 0 = All Keys */
if ( GPG_ERR_NO_ERROR ! = gpgme_op_keylist_start ( CTX , " " , 0 ) )
{
std : : cerr < < " Error iterating through KeyList " ;
std : : cerr < < std : : endl ;
gpgme_set_keylist_mode ( CTX , origmode ) ;
return false ;
}
/* Loop until end of key */
for ( int i = 0 ; ( GPG_ERR_NO_ERROR = = ( ERR = gpgme_op_keylist_next ( CTX , & KEY ) ) ) ; i + + )
{
/* store in pqiAuthDetails */
gpgcert nu ;
/* NB subkeys is a linked list and can contain multiple keys.
* first key is primary .
*/
if ( ( ! KEY - > subkeys ) | | ( ! KEY - > uids ) )
{
std : : cerr < < " Invalid Key in List... skipping " ;
std : : cerr < < std : : endl ;
continue ;
}
/* In general MainSubKey is used to sign all others!
* Don ' t really need to worry about other ids either .
*/
gpgme_subkey_t mainsubkey = KEY - > subkeys ;
2010-01-13 15:56:55 -05:00
nu . id = mainsubkey - > keyid ;
nu . fpr = mainsubkey - > fpr ;
2009-05-23 13:40:35 -04:00
2010-01-13 15:56:55 -05:00
std : : cerr < < " MAIN KEYID: " < < nu . id ;
std : : cerr < < " FPR: " < < nu . fpr ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
gpgme_subkey_t subkeylist = KEY - > subkeys ;
while ( subkeylist ! = NULL )
{
std : : cerr < < " \t KEYID: " < < subkeylist - > keyid ;
std : : cerr < < " FPR: " < < subkeylist - > fpr ;
std : : cerr < < std : : endl ;
subkeylist = subkeylist - > next ;
}
/* NB uids is a linked list and can contain multiple ids.
* first id is primary .
*/
gpgme_user_id_t mainuid = KEY - > uids ;
2010-01-13 15:56:55 -05:00
nu . name = mainuid - > name ;
nu . email = mainuid - > email ;
2009-05-23 13:40:35 -04:00
gpgme_key_sig_t mainsiglist = mainuid - > signatures ;
2010-01-13 16:22:52 -05:00
std : : map < std : : string , bool > : : iterator itAccept ;
if ( mAcceptToConnectMap . end ( ) ! = ( itAccept = mAcceptToConnectMap . find ( nu . id ) ) ) {
nu . accept_connection = itAccept - > second ;
} else {
nu . accept_connection = false ;
mAcceptToConnectMap [ nu . id ] = false ;
}
2010-01-13 16:05:38 -05:00
nu . ownsign = false ;
2009-05-23 13:40:35 -04:00
while ( mainsiglist ! = NULL )
{
if ( mainsiglist - > status = = GPG_ERR_NO_ERROR )
{
/* add as a signature ... even if the
* we haven ' t go the peer yet .
* ( might be yet to come ) .
*/
std : : string keyid = mainsiglist - > keyid ;
2010-01-13 15:56:55 -05:00
if ( nu . signers . end ( ) = = std : : find (
nu . signers . begin ( ) ,
nu . signers . end ( ) , keyid ) )
2009-05-23 13:40:35 -04:00
{
2010-01-13 15:56:55 -05:00
nu . signers . push_back ( keyid ) ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 16:14:49 -05:00
if ( keyid = = mOwnGpgId ) {
2010-01-13 16:05:38 -05:00
nu . ownsign = true ;
}
2009-05-23 13:40:35 -04:00
}
mainsiglist = mainsiglist - > next ;
}
gpgme_user_id_t uidlist = KEY - > uids ;
while ( uidlist ! = NULL )
{
std : : cerr < < " \t UID: " < < uidlist - > uid ;
std : : cerr < < " NAME: " < < uidlist - > name ;
std : : cerr < < " EMAIL: " < < uidlist - > email ;
std : : cerr < < " VALIDITY: " < < uidlist - > validity ;
std : : cerr < < std : : endl ;
gpgme_key_sig_t usiglist = uidlist - > signatures ;
while ( usiglist ! = NULL )
{
std : : cerr < < " \t \t SIG KEYID: " < < usiglist - > keyid ;
std : : cerr < < " UID: " < < usiglist - > uid ;
std : : cerr < < " NAME: " < < usiglist - > name ;
std : : cerr < < " EMAIL: " < < usiglist - > email ;
std : : cerr < < " VALIDITY: " < < ( usiglist - > status = = GPG_ERR_NO_ERROR ) ;
std : : cerr < < std : : endl ;
usiglist = usiglist - > next ;
}
uidlist = uidlist - > next ;
}
/* signatures are attached to uids... but only supplied
* if GPGME_KEYLIST_MODE_SIGS is on .
* signature notation supplied is GPGME_KEYLIST_MODE_SIG_NOTATION is on
*/
2010-01-13 15:56:55 -05:00
nu . trustLvl = KEY - > owner_trust ;
nu . validLvl = mainuid - > validity ;
2009-05-23 13:40:35 -04:00
2009-05-25 07:38:47 -04:00
/* grab a reference, so the key remains */
gpgme_key_ref ( KEY ) ;
2009-05-23 13:40:35 -04:00
nu . key = KEY ;
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
/* store in map */
2010-01-13 15:56:55 -05:00
mKeyList [ nu . id ] = nu ;
2010-01-13 16:12:56 -05:00
//store own key
if ( nu . id = = mOwnGpgId ) {
mOwnGpgCert = nu ;
}
2009-05-23 13:40:35 -04:00
}
if ( GPG_ERR_NO_ERROR ! = gpgme_op_keylist_end ( CTX ) )
{
std : : cerr < < " Error ending KeyList " ;
std : : cerr < < std : : endl ;
gpgme_set_keylist_mode ( CTX , origmode ) ;
return false ;
}
gpgme_set_keylist_mode ( CTX , origmode ) ;
return true ;
}
// update trust on all available keys.
2010-01-13 15:58:58 -05:00
bool AuthGPG : : updateTrustAllKeys_locked ( )
2009-05-23 13:40:35 -04:00
{
gpg_error_t ERR ;
if ( ! gpgmeInit )
{
std : : cerr < < " Error since GPG is not initialised " ;
std : : cerr < < std : : endl ;
return false ;
}
/* have to do this the hard way! */
gpgme_trust_item_t ti = NULL ;
std : : map < std : : string , gpgcert > : : iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
/* check for trust items associated with key */
2010-01-13 15:56:55 -05:00
std : : string peerid = it - > second . email ;
2009-05-23 13:40:35 -04:00
std : : cerr < < " Searching GPGme for TrustInfo on: " < < peerid ;
std : : cerr < < std : : endl ;
/* Initiates a key listing. NB: maxlevel is ignored!*/
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_trustlist_start ( CTX , peerid . c_str ( ) , 0 ) ) )
{
std : : cerr < < " Error Starting Trust List " ;
std : : cerr < < std : : endl ;
ProcessPGPmeError ( ERR ) ;
continue ;
}
/* Loop until end of key */
for ( int i = 0 ; ( GPG_ERR_NO_ERROR = = ( ERR =
gpgme_op_trustlist_next ( CTX , & ti ) ) ) ; i + + )
{
std : : string keyid = ti - > keyid ;
int type = ti - > type ;
int level = ti - > level ;
/* identify the peers, and add trust level */
std : : cerr < < " GPGme Trust Item for: " < < keyid ;
std : : cerr < < std : : endl ;
std : : cerr < < " \t Type: " < < type ;
std : : cerr < < " Level: " < < level ;
std : : cerr < < std : : endl ;
std : : cerr < < " \t Owner Trust: " < < ti - > owner_trust ;
std : : cerr < < " Validity: " < < ti - > validity ;
std : : cerr < < " Name: " < < ti - > name ;
std : : cerr < < std : : endl ;
}
std : : cerr < < " End of TrustList Iteration. " ;
std : : cerr < < std : : endl ;
ProcessPGPmeError ( ERR ) ;
if ( GPG_ERR_NO_ERROR ! = gpgme_op_trustlist_end ( CTX ) )
{
std : : cerr < < " Error ending TrustList " ;
std : : cerr < < std : : endl ;
ProcessPGPmeError ( ERR ) ;
}
}
return true ;
}
2010-01-13 16:05:38 -05:00
2010-01-13 15:58:58 -05:00
bool AuthGPG : : printAllKeys_locked ( )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
certmap : : const_iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
2010-01-13 15:56:55 -05:00
std : : cerr < < " PGP Key: " < < it - > second . id ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 15:56:55 -05:00
std : : cerr < < " \t Name: " < < it - > second . name ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 15:56:55 -05:00
std : : cerr < < " \t Email: " < < it - > second . email ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 16:05:38 -05:00
std : : cerr < < " \t ownsign: " < < it - > second . ownsign ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 16:05:38 -05:00
std : : cerr < < " \t trustLvl: " < < it - > second . trustLvl ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 16:05:38 -05:00
std : : cerr < < " \t validLvl: " < < it - > second . validLvl ;
std : : cerr < < std : : endl ;
2010-01-13 15:56:55 -05:00
std : : cerr < < " \t Email: " < < it - > second . email ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
std : : list < std : : string > : : const_iterator sit ;
2010-01-13 15:56:55 -05:00
for ( sit = it - > second . signers . begin ( ) ;
sit ! = it - > second . signers . end ( ) ; sit + + )
2009-05-23 13:40:35 -04:00
{
std : : cerr < < " \t \t Signer ID: " < < * sit ;
/* do a naughty second search.. should be ok
* as we aren ' t modifying list .
*/
certmap : : const_iterator kit = mKeyList . find ( * sit ) ;
if ( kit ! = mKeyList . end ( ) )
{
2010-01-13 15:56:55 -05:00
std : : cerr < < " Name: " < < kit - > second . name ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
}
}
}
return true ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : printOwnKeys_locked ( )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
certmap : : iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
2010-01-13 15:56:55 -05:00
if ( it - > second . ownsign )
2009-05-23 13:40:35 -04:00
{
2010-01-13 15:56:55 -05:00
std : : cerr < < " Own PGP Key: " < < it - > second . id ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 15:56:55 -05:00
std : : cerr < < " \t Name: " < < it - > second . name ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 15:56:55 -05:00
std : : cerr < < " \t Email: " < < it - > second . email ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
}
}
return true ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : printKeys ( )
2009-07-30 17:27:47 -04:00
{
2010-01-13 16:14:49 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-07-30 17:27:47 -04:00
printAllKeys_locked ( ) ;
return printOwnKeys_locked ( ) ;
}
2009-05-23 13:40:35 -04:00
#if 0
int ASN1_sign ( int ( * i2d ) ( ) , X509_ALGOR * algor1 , X509_ALGOR * algor2 ,
ASN1_BIT_STRING * signature , char * data , EVP_PKEY * pkey ,
const EVP_MD * type )
# define X509_sign(x,pkey,md) \
ASN1_sign ( ( int ( * ) ( ) ) i2d_X509_CINF , x - > cert_info - > signature , \
x - > sig_alg , x - > signature , ( char * ) x - > cert_info , pkey , md )
return NULL ;
}
# endif
void ProcessPGPmeError ( gpgme_error_t ERR )
{
gpgme_err_code_t code = gpgme_err_code ( ERR ) ;
gpgme_err_source_t src = gpgme_err_source ( ERR ) ;
std : : cerr < < " GPGme ERROR: Code: " < < code < < " Source: " < < src < < std : : endl ;
std : : cerr < < " GPGme ERROR: " < < gpgme_strerror ( ERR ) < < std : : endl ;
}
void print_pgpme_verify_summary ( unsigned int summary )
{
std : : cerr < < " \t FLAGS: " ;
if ( summary & GPGME_SIGSUM_VALID )
std : : cerr < < " VALID " ;
if ( summary & GPGME_SIGSUM_GREEN )
std : : cerr < < " GREEN " ;
if ( summary & GPGME_SIGSUM_RED )
std : : cerr < < " RED " ;
if ( summary & GPGME_SIGSUM_KEY_REVOKED )
std : : cerr < < " KEY_REVOKED " ;
if ( summary & GPGME_SIGSUM_KEY_EXPIRED )
std : : cerr < < " KEY_EXPIRED " ;
2010-01-13 19:36:02 -05:00
if ( summary & GPGME_SIGSUM_SIG_EXPIRED )
std : : cerr < < " SIG_EXPIRED " ;
if ( summary & GPGME_SIGSUM_KEY_MISSING )
2009-05-23 13:40:35 -04:00
std : : cerr < < " KEY_MISSING " ;
if ( summary & GPGME_SIGSUM_CRL_MISSING )
std : : cerr < < " CRL_MISSING " ;
if ( summary & GPGME_SIGSUM_CRL_TOO_OLD )
std : : cerr < < " CRL_TOO_OLD " ;
if ( summary & GPGME_SIGSUM_BAD_POLICY )
std : : cerr < < " BAD_POLICY " ;
if ( summary & GPGME_SIGSUM_SYS_ERROR )
std : : cerr < < " SYS_ERROR " ;
std : : cerr < < std : : endl ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : DoOwnSignature_locked ( const void * data , unsigned int datalen , void * buf_sigout , unsigned int * outl )
2009-05-23 13:40:35 -04:00
{
/* setup signers */
gpgme_signers_clear ( CTX ) ;
if ( GPG_ERR_NO_ERROR ! = gpgme_signers_add ( CTX , mOwnGpgCert . key ) )
{
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::DoOwnSignature() Error Adding Signer " ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
}
gpgme_data_t gpgmeData ;
gpgme_data_t gpgmeSig ;
if ( GPG_ERR_NO_ERROR ! = gpgme_data_new_from_mem ( & gpgmeData , ( const char * ) data , datalen , 1 ) )
{
std : : cerr < < " Error create Data " ;
std : : cerr < < std : : endl ;
}
if ( GPG_ERR_NO_ERROR ! = gpgme_data_new ( & gpgmeSig ) )
{
std : : cerr < < " Error create Sig " ;
std : : cerr < < std : : endl ;
}
/* move string data to gpgmeData */
gpgme_set_armor ( CTX , 0 ) ;
gpgme_sig_mode_t mode = GPGME_SIG_MODE_DETACH ;
gpg_error_t ERR ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_sign ( CTX , gpgmeData , gpgmeSig , mode ) ) )
{
ProcessPGPmeError ( ERR ) ;
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::Sign FAILED ERR: " < < ERR ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2009-08-18 08:44:54 -04:00
return false ;
2009-05-23 13:40:35 -04:00
}
gpgme_sign_result_t res = gpgme_op_sign_result ( CTX ) ;
if ( res )
{
fprintf ( stderr , " Sign Got Result \n " ) ;
}
else
{
fprintf ( stderr , " Sign Failed to get Result \n " ) ;
}
gpgme_invalid_key_t ik = res - > invalid_signers ;
gpgme_new_signature_t sg = res - > signatures ;
while ( ik ! = NULL )
{
2010-01-13 15:58:58 -05:00
fprintf ( stderr , " AuthGPG::Sign, Invalid by: %s \n " , ik - > fpr ) ;
2009-05-23 13:40:35 -04:00
ik = ik - > next ;
}
while ( sg ! = NULL )
{
2010-01-13 15:58:58 -05:00
fprintf ( stderr , " AuthGPG::Signed by: %s \n " , sg - > fpr ) ;
2009-05-23 13:40:35 -04:00
sg = sg - > next ;
}
/* now extract the data from gpgmeSig */
size_t len = 0 ;
2009-05-25 07:38:47 -04:00
int len2 = len ;
2010-01-18 17:44:18 -05:00
// gpgme_data_write (gpgmeSig, "", 1); // to be able to convert it into a string
2009-05-23 13:40:35 -04:00
char * export_sig = gpgme_data_release_and_get_mem ( gpgmeSig , & len ) ;
2010-01-18 17:44:18 -05:00
fprintf ( stderr , " AuthGPG::Signature len: %d \n " , len ) ;
if ( len < * outl ) // -1 because we added a 0 at the end.
2009-05-23 13:40:35 -04:00
{
* outl = len ;
}
memmove ( buf_sigout , export_sig , * outl ) ;
gpgme_free ( export_sig ) ;
gpgme_data_release ( gpgmeData ) ;
/* extract id(s)! */
return true ;
}
/* import to GnuPG and other Certificates */
2010-01-13 16:22:52 -05:00
bool AuthGPG : : VerifySignature_locked ( const void * data , int datalen , const void * sig , unsigned int siglen , std : : string withfingerprint )
2009-05-23 13:40:35 -04:00
{
gpgme_data_t gpgmeSig ;
gpgme_data_t gpgmeData ;
std : : cerr < < " VerifySignature: datalen: " < < datalen < < " siglen: " < < siglen ;
std : : cerr < < std : : endl ;
2010-01-18 17:44:18 -05:00
if ( siglen = = 73 )
{
std : : cerr < < " Reducing to 72 to overcome an old bug. " < < std : : endl ;
siglen = 72 ;
}
2009-05-23 13:40:35 -04:00
if ( GPG_ERR_NO_ERROR ! = gpgme_data_new_from_mem ( & gpgmeData , ( const char * ) data , datalen , 1 ) )
{
std : : cerr < < " Error create Data " ;
std : : cerr < < std : : endl ;
}
2010-01-18 17:44:18 -05:00
if ( siglen ! = 0 & & GPG_ERR_NO_ERROR ! = gpgme_data_new_from_mem ( & gpgmeSig , ( const char * ) sig , siglen , 1 ) )
2009-05-23 13:40:35 -04:00
{
std : : cerr < < " Error create Sig " ;
std : : cerr < < std : : endl ;
}
/* move string data to gpgmeData */
gpgme_set_armor ( CTX , 0 ) ;
gpgme_error_t ERR ;
2009-12-22 07:30:13 -05:00
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_verify ( CTX , gpgmeSig , gpgmeData , NULL ) ) )
{
ProcessPGPmeError ( ERR ) ;
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::Verify FAILED " ;
2009-10-27 16:50:30 -04:00
std : : cerr < < std : : endl ;
}
2009-05-23 13:40:35 -04:00
gpgme_verify_result_t res = gpgme_op_verify_result ( CTX ) ;
if ( res )
{
fprintf ( stderr , " VerifySignature Got Result \n " ) ;
}
else
{
fprintf ( stderr , " VerifySignature Failed to get Result \n " ) ;
2009-10-05 16:16:37 -04:00
return false ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 19:36:02 -05:00
gpgme_signature_t sg = res - > signatures ;
2009-05-23 13:40:35 -04:00
bool valid = false ;
while ( sg ! = NULL )
{
2010-01-13 15:58:58 -05:00
fprintf ( stderr , " AuthGPG::Verify Sig by: %s, Result: %d \n " , sg - > fpr , sg - > summary ) ;
2009-05-23 13:40:35 -04:00
print_pgpme_verify_summary ( sg - > summary ) ;
if ( sg - > summary & GPGME_SIGSUM_VALID )
{
2010-01-13 15:58:58 -05:00
fprintf ( stderr , " AuthGPG::VerifySignature() OK \n " ) ;
2010-01-13 16:22:52 -05:00
if ( withfingerprint ! = " " & & withfingerprint = = std : : string ( sg - > fpr ) ) {
fprintf ( stderr , " AuthGPG::VerifySignature() for the fingerprint key : " ) ;
std : : cerr < < withfingerprint ;
fprintf ( stderr , " \n " ) ;
valid = true ;
}
2009-05-23 13:40:35 -04:00
}
sg = sg - > next ;
}
gpgme_data_release ( gpgmeData ) ;
gpgme_data_release ( gpgmeSig ) ;
/* extract id(s)! */
if ( ! valid )
{
2010-01-13 15:58:58 -05:00
fprintf ( stderr , " AuthGPG::VerifySignature() FAILED \n " ) ;
2009-05-23 13:40:35 -04:00
}
return valid ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : active ( )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2009-05-25 07:38:47 -04:00
2010-01-18 07:30:54 -05:00
return ( ( gpgmeInit ) & & ( gpgmeKeySelected ) ) ;
2009-05-23 13:40:35 -04:00
}
2010-01-18 07:30:54 -05:00
bool AuthGPG : : GeneratePGPCertificate ( std : : string name , std : : string email , std : : string passwd , std : : string & pgpId , std : : string & errString ) {
gpgme_key_t newKey ;
gpgme_genkey_result_t result ;
gpg_error_t ERR ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_genkey ( CTX , setKeyPairParams ( true , 2048 , name , " generated by Retroshare " , email , \
passwd ) . c_str ( ) , NULL , NULL ) ) ) {
ProcessPGPmeError ( ERR ) ;
std : : cerr < < " Error generating the key " < < std : : endl ;
return 0 ;
}
if ( ( result = gpgme_op_genkey_result ( CTX ) ) = = NULL )
return 0 ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_get_key ( CTX , result - > fpr , & newKey , 1 ) ) ) {
std : : cerr < < " Error reading own key " < < std : : endl ;
return 0 ;
}
pgpId = newKey - > subkeys - > keyid ;
return true ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : CloseAuth ( )
2009-05-23 13:40:35 -04:00
{
return true ;
}
#if 0 /**** no saving here! let AuthSSL store directories! ****/
2010-01-13 15:58:58 -05:00
int AuthGPG : : setConfigDirectories ( std : : string confFile , std : : string neighDir )
2009-05-23 13:40:35 -04:00
{
return 1 ;
}
# endif
/**** These Two are common */
2010-01-13 16:22:52 -05:00
std : : string AuthGPG : : getGPGName ( GPG_id id )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:14:49 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-25 07:38:47 -04:00
2009-11-14 15:20:33 -05:00
certmap : : iterator it ;
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( id ) ) )
2010-01-13 15:56:55 -05:00
return it - > second . name ;
2009-11-14 15:20:33 -05:00
return std : : string ( ) ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 15:56:55 -05:00
/**** These Two are common */
2010-01-13 16:22:52 -05:00
std : : string AuthGPG : : getGPGEmail ( GPG_id id )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:14:49 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-23 13:40:35 -04:00
2010-01-13 15:56:55 -05:00
certmap : : iterator it ;
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( id ) ) )
return it - > second . email ;
return std : : string ( ) ;
}
2009-05-23 13:40:35 -04:00
/**** GPG versions ***/
2010-01-13 16:22:52 -05:00
std : : string AuthGPG : : getGPGOwnId ( )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2010-01-13 16:05:38 -05:00
return mOwnGpgId ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 16:22:52 -05:00
std : : string AuthGPG : : getGPGOwnName ( )
{
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
return mOwnGpgName ;
}
bool AuthGPG : : getGPGAllList ( std : : list < std : : string > & ids )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:14:49 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
/* add an id for each pgp certificate */
certmap : : iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
ids . push_back ( it - > first ) ;
}
return true ;
}
2010-01-13 16:22:52 -05:00
bool AuthGPG : : getGPGDetails ( std : : string id , RsPeerDetails & d )
2010-01-13 16:08:46 -05:00
{
2010-01-13 16:14:49 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2010-01-13 16:08:46 -05:00
/* add an id for each pgp certificate */
certmap : : iterator it ;
2010-01-13 16:22:52 -05:00
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( id ) ) ) {
d . id = it - > second . id ; //keep, it but can be bug gen
d . gpg_id = it - > second . id ;
2010-01-13 16:08:46 -05:00
d . name = it - > second . name ;
d . email = it - > second . email ;
d . trustLvl = it - > second . trustLvl ;
d . validLvl = it - > second . validLvl ;
d . ownsign = it - > second . ownsign ;
2010-01-13 16:11:02 -05:00
d . gpgSigners = it - > second . signers ;
2010-01-13 16:22:52 -05:00
d . fpr = it - > second . fpr ;
d . accept_connection = it - > second . accept_connection ;
2010-01-13 16:12:56 -05:00
//did the peer signed me ?
d . hasSignedMe = false ;
std : : list < std : : string > : : iterator signersIt ;
for ( signersIt = mOwnGpgCert . signers . begin ( ) ; signersIt ! = mOwnGpgCert . signers . end ( ) ; + + signersIt ) {
if ( * signersIt = = d . id ) {
d . hasSignedMe = true ;
break ;
}
}
2010-01-13 16:11:02 -05:00
std : : cerr < < " AuthGPG::getPGPDetails() get details for : " < < id < < std : : endl ;
std : : cerr < < " AuthGPG::getPGPDetails() Name : " < < it - > second . name < < std : : endl ;
2010-01-13 16:08:46 -05:00
return true ;
} else {
return false ;
}
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : decryptText ( gpgme_data_t CIPHER , gpgme_data_t PLAIN ) {
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2009-10-29 20:46:58 -04:00
gpgme_set_armor ( CTX , 1 ) ;
2009-10-27 16:48:11 -04:00
gpg_error_t ERR ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_decrypt ( CTX , CIPHER , PLAIN ) ) )
2009-08-18 08:43:19 -04:00
{
2009-10-27 16:48:11 -04:00
ProcessPGPmeError ( ERR ) ;
2010-01-13 16:11:02 -05:00
std : : cerr < < " AuthGPG::decryptText() Error decrypting text. " < < std : : endl ;
2009-08-18 08:43:19 -04:00
return false ;
}
return true ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : encryptText ( gpgme_data_t PLAIN , gpgme_data_t CIPHER ) {
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2009-08-18 08:43:19 -04:00
gpgme_encrypt_flags_t * flags = new gpgme_encrypt_flags_t ( ) ;
2009-10-27 16:48:11 -04:00
gpgme_key_t keys [ 2 ] = { mOwnGpgCert . key , NULL } ;
2009-10-29 20:46:58 -04:00
gpgme_set_armor ( CTX , 1 ) ;
2009-10-27 16:48:11 -04:00
gpg_error_t ERR ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_encrypt ( CTX , keys , * flags , PLAIN , CIPHER ) ) )
2009-08-18 08:43:19 -04:00
{
2009-10-27 16:48:11 -04:00
ProcessPGPmeError ( ERR ) ;
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::encryptText() Error encrypting text. " ;
2009-08-18 08:43:19 -04:00
std : : cerr < < std : : endl ;
return false ;
}
return true ;
}
2010-01-13 16:22:52 -05:00
bool AuthGPG : : getGPGValidList ( std : : list < std : : string > & ids )
2010-01-13 16:16:18 -05:00
{
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2010-01-13 16:22:52 -05:00
/* add an id for each pgp certificate */
certmap : : iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
if ( it - > second . validLvl > = GPGME_VALIDITY_MARGINAL ) {
ids . push_back ( it - > first ) ;
}
}
return true ;
2010-01-13 16:16:18 -05:00
}
2010-01-13 16:22:52 -05:00
bool AuthGPG : : getGPGAcceptedList ( std : : list < std : : string > & ids )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2010-01-13 16:22:52 -05:00
certmap : : iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
if ( it - > second . accept_connection )
{
ids . push_back ( it - > first ) ;
}
}
return true ;
}
2009-05-25 07:38:47 -04:00
2010-01-13 16:22:52 -05:00
bool AuthGPG : : getGPGSignedList ( std : : list < std : : string > & ids )
{
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2009-05-23 13:40:35 -04:00
certmap : : iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
2010-01-13 16:05:38 -05:00
if ( it - > second . ownsign )
2009-05-23 13:40:35 -04:00
{
ids . push_back ( it - > first ) ;
}
}
return true ;
}
2010-01-13 16:22:52 -05:00
bool AuthGPG : : isGPGValid ( GPG_id id )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2010-01-13 16:05:38 -05:00
certmap : : iterator it ;
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( id ) ) ) {
return ( it - > second . validLvl > = GPGME_VALIDITY_MARGINAL ) ;
} else {
return false ;
}
2009-05-23 13:40:35 -04:00
}
2010-01-13 16:25:18 -05:00
bool AuthGPG : : isGPGId ( GPG_id id )
{
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
storeAllKeys_locked ( ) ;
certmap : : iterator it ;
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( id ) ) ) {
return true ;
} else {
return false ;
}
}
2009-05-23 13:40:35 -04:00
2010-01-13 16:22:52 -05:00
bool AuthGPG : : isGPGSigned ( GPG_id id )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:08:46 -05:00
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
2010-01-13 16:05:38 -05:00
certmap : : iterator it ;
2009-05-23 13:40:35 -04:00
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( id ) ) )
{
2010-01-13 16:05:38 -05:00
return ( it - > second . ownsign ) ;
2009-05-23 13:40:35 -04:00
}
return false ;
}
2010-01-13 16:22:52 -05:00
bool AuthGPG : : isGPGAccepted ( GPG_id id )
{
//RsStackMutex stack(pgpMtx); /******* LOCKED ******/
certmap : : iterator it ;
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( id ) ) )
{
return ( it - > second . accept_connection ) ;
}
return false ;
}
2009-05-23 13:40:35 -04:00
/****** Large Parts of the p3AuthMgr is provided by AuthSSL ******
* As the majority of functions require SSL Certs
*
* We don ' t need to save / load openpgp certificates , as the gpgme
* handles this .
*
*/
#if 0
2010-01-13 15:58:58 -05:00
bool AuthGPG : : FinalSaveCertificates ( )
2009-05-23 13:40:35 -04:00
{
return false ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : CheckSaveCertificates ( )
2009-05-23 13:40:35 -04:00
{
return false ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : saveCertificates ( )
2009-05-23 13:40:35 -04:00
{
return false ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : loadCertificates ( )
2009-05-23 13:40:35 -04:00
{
return false ;
}
# endif
/*****************************************************************
* 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 .
*
*/
/* SKTAN : do not know how to use std::string id */
2010-01-13 15:58:58 -05:00
std : : string AuthGPG : : SaveCertificateToString ( std : : string id )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
2010-01-13 16:22:52 -05:00
if ( ! isGPGValid ( id ) ) {
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::SaveCertificateToString() unknown ID " < < std : : endl ;
2009-05-23 13:40:35 -04:00
std : : string emptystr ;
return emptystr ;
}
2009-05-25 07:38:47 -04:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-23 13:40:35 -04:00
std : : string tmp ;
const char * pattern [ ] = { NULL , NULL } ;
pattern [ 0 ] = id . c_str ( ) ;
gpgme_data_t gpgmeData ;
if ( GPG_ERR_NO_ERROR ! = gpgme_data_new ( & gpgmeData ) )
{
std : : cerr < < " Error create Data " ;
std : : cerr < < std : : endl ;
}
gpgme_set_armor ( CTX , 1 ) ;
if ( GPG_ERR_NO_ERROR ! = gpgme_op_export_ext ( CTX , pattern , 0 , gpgmeData ) )
{
std : : cerr < < " Error export Data " ;
std : : cerr < < std : : endl ;
}
2009-08-14 03:28:58 -04:00
gpgme_data_write ( gpgmeData , " " , 1 ) ; // to be able to convert it into a string
2009-05-23 13:40:35 -04:00
fflush ( NULL ) ;
fputs ( " Begin Result: \n " , stdout ) ;
showData ( gpgmeData ) ;
fputs ( " End Result. \n " , stdout ) ;
2009-08-14 03:28:58 -04:00
2009-05-23 13:40:35 -04:00
size_t len = 0 ;
char * export_txt = gpgme_data_release_and_get_mem ( gpgmeData , & len ) ;
tmp = std : : string ( export_txt ) ;
2009-07-21 17:25:39 -04:00
std : : cerr < < " Exported Certificate: " ;
std : : cerr < < std : : endl ;
std : : cerr < < tmp ;
std : : cerr < < std : : endl ;
2009-05-23 13:40:35 -04:00
gpgme_free ( export_txt ) ;
return tmp ;
}
/* import to GnuPG and other Certificates */
2010-01-13 16:22:52 -05:00
bool AuthGPG : : LoadCertificateFromString ( std : : string str , std : : string & gpg_id )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-23 13:40:35 -04:00
gpgme_data_t gpgmeData ;
if ( GPG_ERR_NO_ERROR ! = gpgme_data_new_from_mem ( & gpgmeData , str . c_str ( ) , str . length ( ) , 1 ) )
{
std : : cerr < < " Error create Data " ;
std : : cerr < < std : : endl ;
}
/* move string data to gpgmeData */
gpgme_set_armor ( CTX , 1 ) ;
if ( GPG_ERR_NO_ERROR ! = gpgme_op_import ( CTX , gpgmeData ) )
{
2010-01-13 16:22:52 -05:00
std : : cerr < < " AuthGPG::LoadCertificateFromString() Error Importing Certificate " ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2009-09-01 15:48:18 -04:00
return false ;
2009-05-23 13:40:35 -04:00
}
gpgme_import_result_t res = gpgme_op_import_result ( CTX ) ;
2010-01-13 16:22:52 -05:00
std : : string fingerprint = std : : string ( res - > imports - > fpr ) ;
std : : cerr < < " AuthGPG::LoadCertificateFromString() Importing considered folowing fpr : " < < fingerprint < < std : : endl ;
2009-05-23 13:40:35 -04:00
2009-05-25 07:38:47 -04:00
int imported = res - > imported ;
2009-05-23 13:40:35 -04:00
fprintf ( stderr , " ImportCertificate(Considered: %d Imported: %d) \n " ,
res - > considered , res - > imported ) ;
2009-05-25 07:38:47 -04:00
/* do we need to delete res??? */
2009-05-23 13:40:35 -04:00
gpgme_data_release ( gpgmeData ) ;
2009-05-25 07:38:47 -04:00
/* extract id(s)! (only if we actually imported one) */
if ( imported )
{
storeAllKeys_locked ( ) ;
}
2010-01-13 16:22:52 -05:00
//retrieve the id of the key
certmap : : iterator it ;
for ( it = mKeyList . begin ( ) ; it ! = mKeyList . end ( ) ; it + + )
{
if ( it - > second . fpr = = fingerprint )
{
gpg_id = it - > second . id ;
break ;
}
}
std : : cerr < < " AuthGPG::LoadCertificateFromString() returning with gpg_id : " < < gpg_id < < std : : endl ;
2009-05-23 13:40:35 -04:00
return true ;
}
/*****************************************************************
* 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 */
bool AuthGPG : : setAcceptToConnectGPGCertificate ( std : : string gpg_id , bool acceptance )
{
std : : cerr < < " AuthGPG::markGPGCertificateAsFriends( " < < gpg_id < < " ) " ;
std : : cerr < < std : : endl ;
/* reload stuff now ... */
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
certmap : : iterator it ;
if ( mKeyList . end ( ) = = ( it = mKeyList . find ( gpg_id ) ) ) {
return false ;
}
it - > second . accept_connection = acceptance ;
mAcceptToConnectMap [ gpg_id ] = acceptance ;
2010-01-13 16:26:30 -05:00
IndicateConfigChanged ( ) ;
2010-01-13 16:22:52 -05:00
return true ;
}
2009-05-23 13:40:35 -04:00
/* These take PGP Ids */
2010-01-13 16:05:38 -05:00
bool AuthGPG : : SignCertificateLevel0 ( GPG_id id )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
2010-01-13 16:05:38 -05:00
std : : cerr < < " AuthGPG::SignCertificat( " < < id < < " ) " ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2009-05-25 07:38:47 -04:00
2010-01-13 15:52:31 -05:00
if ( 1 ! = privateSignCertificate ( id ) )
2009-05-25 07:38:47 -04:00
{
return false ;
}
/* reload stuff now ... */
2010-01-13 16:08:46 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-25 07:38:47 -04:00
storeAllKeys_locked ( ) ;
return true ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : RevokeCertificate ( std : : string id )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2010-01-13 15:58:58 -05:00
std : : cerr < < " AuthGPG::RevokeCertificate( " < < id < < " ) " ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
return false ;
}
2010-01-13 16:05:38 -05:00
bool AuthGPG : : TrustCertificateMarginally ( std : : string id )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:05:38 -05:00
std : : cerr < < " AuthGPG::TrustCertificateMarginally( " < < id < < " ) " ;
2009-05-23 13:40:35 -04:00
std : : cerr < < std : : endl ;
2010-01-13 16:05:38 -05:00
//TODO implement it
2009-05-23 13:40:35 -04:00
return false ;
}
2010-01-13 16:14:49 -05:00
bool AuthGPG : : TrustCertificate ( std : : string id , int trustlvl )
{
std : : cerr < < " AuthGPG::TrustCertificate( " < < id < < " , " < < trustlvl < < " ) " < < std : : endl ;
return this - > privateTrustCertificate ( id , trustlvl ) ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : SignData ( std : : string input , std : : string & sign )
2009-05-23 13:40:35 -04:00
{
return false ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : SignData ( const void * data , const uint32_t len , std : : string & sign )
2009-05-23 13:40:35 -04:00
{
return false ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : SignDataBin ( std : : string input , unsigned char * sign , unsigned int * signlen )
2009-05-23 13:40:35 -04:00
{
return false ;
}
2010-01-13 15:58:58 -05:00
bool AuthGPG : : SignDataBin ( const void * data , unsigned int datalen , unsigned char * sign , unsigned int * signlen ) {
2010-01-13 15:52:31 -05:00
return DoOwnSignature_locked ( data , datalen ,
sign , signlen ) ;
2009-05-23 13:40:35 -04:00
}
2010-01-13 16:22:52 -05:00
bool AuthGPG : : VerifySignBin ( const void * data , uint32_t datalen , unsigned char * sign , unsigned int signlen , std : : string withfingerprint ) {
2010-01-13 15:52:31 -05:00
return VerifySignature_locked ( data , datalen ,
2010-01-13 16:22:52 -05:00
sign , signlen , withfingerprint ) ;
2009-05-23 13:40:35 -04:00
}
/* Sign/Trust stuff */
2010-01-13 15:58:58 -05:00
int AuthGPG : : privateSignCertificate ( std : : string id )
2009-05-23 13:40:35 -04:00
{
/* The key should be in Others list and not in Peers list ??
* Once the key is signed , it moves from Others to Peers list ? ? ?
*/
certmap : : iterator it ;
if ( mKeyList . end ( ) = = ( it = mKeyList . find ( id ) ) )
{
return false ;
}
gpgme_key_t signKey = it - > second . key ;
2009-10-27 16:39:47 -04:00
gpgme_key_t ownKey = mOwnGpgCert . key ;
2009-05-23 13:40:35 -04:00
2010-01-13 16:06:53 -05:00
class SignParams sparams ( " 0 " ) ;
2009-05-23 13:40:35 -04:00
class EditParams params ( SIGN_START , & sparams ) ;
gpgme_data_t out ;
gpg_error_t ERR ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_data_new ( & out ) ) ) {
return 0 ;
}
gpgme_signers_clear ( CTX ) ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_signers_add ( CTX , ownKey ) ) ) {
return 0 ;
}
2010-01-13 16:14:49 -05:00
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_edit ( CTX , signKey , keySignCallback , & params , out ) ) ) {
2009-05-23 13:40:35 -04:00
return 0 ;
}
2010-01-13 16:34:47 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
storeAllKeys_locked ( ) ;
2009-05-23 13:40:35 -04:00
return 1 ;
}
/* revoke the signature on Certificate */
2010-01-13 15:58:58 -05:00
int AuthGPG : : privateRevokeCertificate ( std : : string id )
2009-05-23 13:40:35 -04:00
{
2009-05-25 07:38:47 -04:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2009-05-23 13:40:35 -04:00
return 0 ;
}
2010-01-13 15:58:58 -05:00
int AuthGPG : : privateTrustCertificate ( std : : string id , int trustlvl )
2009-05-23 13:40:35 -04:00
{
2010-01-13 16:34:47 -05:00
/* The certificate should be in Peers list ??? */
2010-01-13 16:22:52 -05:00
if ( ! isGPGSigned ( id ) ) {
2009-05-23 13:40:35 -04:00
std : : cerr < < " Invalid Certificate " < < std : : endl ;
return 0 ;
}
gpgcert trustCert = mKeyList . find ( id ) - > second ;
gpgme_key_t trustKey = trustCert . key ;
2010-01-13 19:35:16 -05:00
std : : string trustString ;
std : : ostringstream trustStrOut ;
trustStrOut < < trustlvl ;
class TrustParams sparams ( trustStrOut . str ( ) ) ;
2010-01-13 16:14:49 -05:00
class EditParams params ( TRUST_START , & sparams ) ;
2009-05-23 13:40:35 -04:00
gpgme_data_t out ;
gpg_error_t ERR ;
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_data_new ( & out ) ) ) {
return 0 ;
}
if ( GPG_ERR_NO_ERROR ! = ( ERR = gpgme_op_edit ( CTX , trustKey , trustCallback , & params , out ) ) )
return 0 ;
2010-01-13 16:14:49 -05:00
//the key ref has changed, we got to get rid of the old reference.
trustCert . key = NULL ;
2010-01-13 16:34:47 -05:00
RsStackMutex stack ( pgpMtx ) ; /******* LOCKED ******/
2010-01-13 16:14:49 -05:00
storeAllKeys_locked ( ) ;
2009-05-23 13:40:35 -04:00
return 1 ;
}
/* This function to print Data */
2010-01-13 15:58:58 -05:00
void AuthGPG : : showData ( gpgme_data_t dh )
2009-05-23 13:40:35 -04:00
{
# define BUF_SIZE 512
char buf [ BUF_SIZE + 1 ] ;
int ret ;
ret = gpgme_data_seek ( dh , 0 , SEEK_SET ) ;
if ( ret )
{
std : : cerr < < " Fail data seek " ;
std : : cerr < < std : : endl ;
// fail_if_err (gpgme_err_code_from_errno (errno));
}
while ( ( ret = gpgme_data_read ( dh , buf , BUF_SIZE ) ) > 0 )
fwrite ( buf , ret , 1 , stdout ) ;
if ( ret < 0 )
{
std : : cerr < < " Fail data seek " ;
std : : cerr < < std : : endl ;
//fail_if_err (gpgme_err_code_from_errno (errno));
}
}
/******************************************************************************/
/* TEST/DEBUG */
/******************************************************************************/
/*
* Create a number of friends and add them to the Map of peers .
* Create a number of friends and add them to the Map of " others " - - people who
* are known but are not allowed to access retroshare
*/
2010-01-13 15:58:58 -05:00
void AuthGPG : : createDummyFriends ( )
2009-05-23 13:40:35 -04:00
{
const unsigned int DUMMY_KEY_LEN = 2048 ;
// create key params for a few dummies
std : : string friend1 = setKeyPairParams ( true , DUMMY_KEY_LEN , " friend89 " ,
2010-01-13 16:06:53 -05:00
" I am your first friend " , " friend1@friend.com " ) ;
2009-05-23 13:40:35 -04:00
std : : string friend2 = setKeyPairParams ( true , DUMMY_KEY_LEN , " friend2 " ,
2010-01-13 16:06:53 -05:00
" I am your second friend " , " friend2@friend.com " ) ;
2009-05-23 13:40:35 -04:00
std : : string friend3 = setKeyPairParams ( true , DUMMY_KEY_LEN , " friend3 " ,
2010-01-13 16:06:53 -05:00
" I am your third friend " , " friend3@friend.com " ) ;
2009-05-23 13:40:35 -04:00
// params for others
std : : string other1 = setKeyPairParams ( true , DUMMY_KEY_LEN , " other89 " ,
2010-01-13 16:06:53 -05:00
" I am your first other " , " other@other.com " ) ;
2009-05-23 13:40:35 -04:00
std : : string other2 = setKeyPairParams ( true , DUMMY_KEY_LEN , " other2 " ,
2010-01-13 16:06:53 -05:00
" I am your second other " , " other2@other.com " ) ;
2009-05-23 13:40:35 -04:00
std : : string other3 = setKeyPairParams ( true , DUMMY_KEY_LEN , " other3 " ,
2010-01-13 16:06:53 -05:00
" I am your third other " , " other3@other.com " ) ;
2009-05-23 13:40:35 -04:00
gpgme_error_t rc = GPG_ERR_NO_ERROR ; // assume OK
rc = gpgme_op_genkey ( CTX , friend1 . c_str ( ) , NULL , NULL ) ;
rc = gpgme_op_genkey ( CTX , friend2 . c_str ( ) , NULL , NULL ) ;
rc = gpgme_op_genkey ( CTX , friend3 . c_str ( ) , NULL , NULL ) ;
rc = gpgme_op_genkey ( CTX , other1 . c_str ( ) , NULL , NULL ) ;
rc = gpgme_op_genkey ( CTX , other2 . c_str ( ) , NULL , NULL ) ;
rc = gpgme_op_genkey ( CTX , other3 . c_str ( ) , NULL , NULL ) ;
std : : cout < < " createDummyFriends(): exit " < < std : : endl ;
return ;
}
static std : : string setKeyPairParams ( bool useRsa , unsigned int blen ,
2010-01-13 16:06:53 -05:00
std : : string name , std : : string comment , std : : string email )
2009-05-23 13:40:35 -04:00
{
std : : ostringstream params ;
params < < " <GnupgKeyParms format= \" internal \" > " < < std : : endl ;
if ( useRsa )
{
params < < " Key-Type: RSA " < < std : : endl ;
if ( blen < 1024 )
{
std : : cerr < < " Weak Key... strengthing... " < < std : : endl ;
blen = 1024 ;
}
blen = ( ( blen / 512 ) * 512 ) ; /* make multiple of 512 */
params < < " Key-Length: " < < blen < < std : : endl ;
}
else
{
params < < " Key-Type: DSA " < < std : : endl ;
params < < " Key-Length: 1024 " < < std : : endl ;
params < < " Subkey-Type: ELG-E " < < std : : endl ;
params < < " Subkey-Length: 1024 " < < std : : endl ;
}
params < < " Name-Real: " < < name < < std : : endl ;
params < < " Name-Comment: " < < comment < < std : : endl ;
params < < " Name-Email: " < < email < < std : : endl ;
2010-01-13 16:06:53 -05:00
params < < " Expire-Date: 0 " < < std : : endl ;
2009-05-23 13:40:35 -04:00
params < < " </GnupgKeyParms> " < < std : : endl ;
return params . str ( ) ;
}
2010-01-18 07:30:54 -05:00
static std : : string setKeyPairParams ( bool useRsa , unsigned int blen ,
std : : string name , std : : string comment , std : : string email ,
std : : string inPassphrase )
{
std : : ostringstream params ;
params < < " <GnupgKeyParms format= \" internal \" > " < < std : : endl ;
if ( useRsa )
{
params < < " Key-Type: RSA " < < std : : endl ;
if ( blen < 1024 )
{
std : : cerr < < " Weak Key... strengthing... " < < std : : endl ;
blen = 1024 ;
}
blen = ( ( blen / 512 ) * 512 ) ; /* make multiple of 512 */
params < < " Key-Length: " < < blen < < std : : endl ;
}
else
{
params < < " Key-Type: DSA " < < std : : endl ;
params < < " Key-Length: 1024 " < < std : : endl ;
params < < " Subkey-Type: ELG-E " < < std : : endl ;
params < < " Subkey-Length: 1024 " < < std : : endl ;
}
params < < " Name-Real: " < < name < < std : : endl ;
params < < " Name-Comment: " < < comment < < std : : endl ;
params < < " Name-Email: " < < email < < std : : endl ;
params < < " Expire-Date: 0 " < < std : : endl ;
params < < " Passphrase: " < < inPassphrase < < std : : endl ;
params < < " </GnupgKeyParms> " < < std : : endl ;
return params . str ( ) ;
}
2009-05-23 13:40:35 -04:00
/* Author: Shiva
* This function returns the key macthing the user parameters
* from the keyring
*/
static gpgme_key_t getKey ( gpgme_ctx_t CTX , std : : string name , std : : string comment , std : : string email ) {
gpgme_key_t key ;
gpgme_user_id_t user ;
/* Initiates a key listing */
if ( GPG_ERR_NO_ERROR ! = gpgme_op_keylist_start ( CTX , " " , 0 ) )
{
std : : cerr < < " Error iterating through KeyList " ;
std : : cerr < < std : : endl ;
return false ;
}
/* Loop until end of key */
for ( int i = 0 ; ( GPG_ERR_NO_ERROR = = gpgme_op_keylist_next ( CTX , & key ) ) ; i + + )
{
user = key - > uids ;
while ( user ! = NULL ) {
if ( ( name . size ( ) & & name = = user - > name ) & & ( comment . size ( ) & & comment = = user - > comment ) & & \
2009-05-25 07:38:47 -04:00
( email . size ( ) & & email = = user - > email ) )
{
/* grab a reference to the key */
gpgme_op_keylist_end ( CTX ) ;
if ( GPG_ERR_NO_ERROR ! = gpgme_op_keylist_end ( CTX ) )
{
std : : cerr < < " Error ending KeyList " ;
std : : cerr < < std : : endl ;
}
gpgme_key_ref ( key ) ;
2009-05-23 13:40:35 -04:00
return key ;
}
user = user - > next ;
}
}
2009-05-25 07:38:47 -04:00
if ( GPG_ERR_NO_ERROR ! = gpgme_op_keylist_end ( CTX ) )
{
std : : cerr < < " Error ending KeyList " ;
std : : cerr < < std : : endl ;
}
2009-05-23 13:40:35 -04:00
return NULL ;
}
/* Callback function for key signing */
static gpg_error_t keySignCallback ( void * opaque , gpgme_status_code_t status , \
const char * args , int fd ) {
class EditParams * params = ( class EditParams * ) opaque ;
class SignParams * sparams = ( class SignParams * ) params - > oParams ;
const char * result = NULL ;
2010-01-13 16:08:46 -05:00
fprintf ( stderr , " keySignCallback status: %d args: %s, params->state: %d \n " , status , args , params - > state ) ;
2009-05-25 07:38:47 -04:00
/* printf stuff out */
if ( status = = GPGME_STATUS_EOF )
fprintf ( stderr , " keySignCallback GPGME_STATUS_EOF \n " ) ;
if ( status = = GPGME_STATUS_GOT_IT )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GOT_IT \n " ) ;
if ( status = = GPGME_STATUS_USERID_HINT )
fprintf ( stderr , " keySignCallback GPGME_STATUS_USERID_HINT \n " ) ;
if ( status = = GPGME_STATUS_NEED_PASSPHRASE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_NEED_PASSPHRASE \n " ) ;
if ( status = = GPGME_STATUS_GOOD_PASSPHRASE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GOOD_PASSPHRASE \n " ) ;
if ( status = = GPGME_STATUS_BAD_PASSPHRASE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_BAD_PASSPHRASE \n " ) ;
if ( status = = GPGME_STATUS_GET_LINE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GET_LINE \n " ) ;
if ( status = = GPGME_STATUS_GET_BOOL )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GET_BOOL \n " ) ;
if ( status = = GPGME_STATUS_ALREADY_SIGNED )
fprintf ( stderr , " keySignCallback GPGME_STATUS_ALREADY_SIGNED \n " ) ;
2010-01-13 16:08:46 -05:00
/* printf stuff out */
if ( params - > state = = SIGN_START )
fprintf ( stderr , " keySignCallback params->state SIGN_START \n " ) ;
if ( params - > state = = SIGN_COMMAND )
fprintf ( stderr , " keySignCallback params->state SIGN_COMMAND \n " ) ;
if ( params - > state = = SIGN_UIDS )
fprintf ( stderr , " keySignCallback params->state SIGN_UIDS \n " ) ;
if ( params - > state = = SIGN_SET_EXPIRE )
fprintf ( stderr , " keySignCallback params->state SIGN_SET_EXPIRE \n " ) ;
if ( params - > state = = SIGN_SET_CHECK_LEVEL )
fprintf ( stderr , " keySignCallback params->state SIGN_SET_CHECK_LEVEL \n " ) ;
if ( params - > state = = SIGN_CONFIRM )
fprintf ( stderr , " keySignCallback params->state SIGN_CONFIRM \n " ) ;
if ( params - > state = = SIGN_QUIT )
fprintf ( stderr , " keySignCallback params->state SIGN_QUIT \n " ) ;
if ( params - > state = = SIGN_ENTER_PASSPHRASE )
fprintf ( stderr , " keySignCallback params->state SIGN_ENTER_PASSPHRASE \n " ) ;
if ( params - > state = = SIGN_ERROR )
fprintf ( stderr , " keySignCallback params->state SIGN_ERROR " ) ;
2009-05-25 07:38:47 -04:00
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_EOF | |
status = = GPGME_STATUS_GOT_IT | |
status = = GPGME_STATUS_USERID_HINT | |
status = = GPGME_STATUS_NEED_PASSPHRASE | |
2009-05-25 07:38:47 -04:00
// status == GPGME_STATUS_GOOD_PASSPHRASE ||
2009-05-23 13:40:35 -04:00
status = = GPGME_STATUS_BAD_PASSPHRASE ) {
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback Error status \n " ) ;
ProcessPGPmeError ( params - > err ) ;
2009-05-23 13:40:35 -04:00
return params - > err ;
}
switch ( params - > state )
{
case SIGN_START :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_START \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) )
{
params - > state = SIGN_COMMAND ;
result = " sign " ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case SIGN_COMMAND :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_COMMAND \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_BOOL & &
( ! std : : string ( " keyedit.sign_all.okay " ) . compare ( args ) ) )
{
params - > state = SIGN_UIDS ;
result = " Y " ;
}
else if ( status = = GPGME_STATUS_GET_BOOL & &
( ! std : : string ( " sign_uid.okay " ) . compare ( args ) ) )
{
params - > state = SIGN_ENTER_PASSPHRASE ;
result = " Y " ;
}
else if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " sign_uid.expire " ) . compare ( args ) ) )
{
params - > state = SIGN_SET_EXPIRE ;
result = " Y " ;
}
else if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " sign_uid.class " ) . compare ( args ) ) )
{
params - > state = SIGN_SET_CHECK_LEVEL ;
result = sparams - > checkLvl . c_str ( ) ;
}
else if ( status = = GPGME_STATUS_ALREADY_SIGNED )
{
/* The key has already been signed with this key */
2010-01-13 16:25:18 -05:00
params - > state = SIGN_QUIT ;
result = " quit " ;
2009-05-23 13:40:35 -04:00
}
else if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) )
{
/* Failed sign: expired key */
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_UNUSABLE_PUBKEY ) ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case SIGN_UIDS :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_UIDS \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " sign_uid.expire " ) . compare ( args ) ) )
{
params - > state = SIGN_SET_EXPIRE ;
result = " Y " ;
}
else if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " sign_uid.class " ) . compare ( args ) ) )
{
params - > state = SIGN_SET_CHECK_LEVEL ;
result = sparams - > checkLvl . c_str ( ) ;
}
else if ( status = = GPGME_STATUS_GET_BOOL & &
( ! std : : string ( " sign_uid.okay " ) . compare ( args ) ) )
{
params - > state = SIGN_ENTER_PASSPHRASE ;
result = " Y " ;
}
else if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) )
{
/* Failed sign: expired key */
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_UNUSABLE_PUBKEY ) ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case SIGN_SET_EXPIRE :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_SET_EXPIRE \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " sign_uid.class " ) . compare ( args ) ) )
{
params - > state = SIGN_SET_CHECK_LEVEL ;
result = sparams - > checkLvl . c_str ( ) ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case SIGN_SET_CHECK_LEVEL :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_SET_CHECK_LEVEL \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_BOOL & &
( ! std : : string ( " sign_uid.okay " ) . compare ( args ) ) )
{
params - > state = SIGN_ENTER_PASSPHRASE ;
result = " Y " ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
2010-01-13 16:08:46 -05:00
case SIGN_ENTER_PASSPHRASE :
fprintf ( stderr , " keySignCallback SIGN_ENTER_PASSPHRASE \n " ) ;
if ( status = = GPGME_STATUS_GOOD_PASSPHRASE )
{
params - > state = SIGN_CONFIRM ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
2009-05-23 13:40:35 -04:00
case SIGN_CONFIRM :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_CONFIRM \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) )
{
params - > state = SIGN_QUIT ;
result = " quit " ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case SIGN_QUIT :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_QUIT \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_BOOL & &
( ! std : : string ( " keyedit.save.okay " ) . compare ( args ) ) )
{
params - > state = SIGN_SAVE ;
result = " Y " ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case SIGN_ERROR :
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback SIGN_ERROR \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) )
{
/* Go to quit operation state */
params - > state = SIGN_QUIT ;
result = " quit " ;
}
else
{
params - > state = SIGN_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
2009-05-25 07:38:47 -04:00
default :
fprintf ( stderr , " keySignCallback UNKNOWN state \n " ) ;
break ;
2009-05-23 13:40:35 -04:00
}
if ( result )
{
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback result:%s \n " , result ) ;
2009-07-30 10:36:42 -04:00
# ifndef WINDOWS_SYS
2009-05-23 13:40:35 -04:00
if ( * result )
write ( fd , result , strlen ( result ) ) ;
write ( fd , " \n " , 1 ) ;
2009-07-30 10:36:42 -04:00
# else
DWORD written = 0 ;
HANDLE winFd = ( HANDLE ) fd ;
if ( * result )
WriteFile ( winFd , result , strlen ( result ) , & written , NULL ) ;
WriteFile ( winFd , " \n " , 1 , & written , NULL ) ;
# endif
2009-05-23 13:40:35 -04:00
}
2009-05-25 07:38:47 -04:00
fprintf ( stderr , " keySignCallback Error status \n " ) ;
ProcessPGPmeError ( params - > err ) ;
2009-05-23 13:40:35 -04:00
return params - > err ;
}
/* Callback function for assigning trust level */
static gpgme_error_t trustCallback ( void * opaque , gpgme_status_code_t status , \
const char * args , int fd ) {
2010-01-13 16:14:49 -05:00
class EditParams * params = ( class EditParams * ) opaque ;
class TrustParams * tparams = ( class TrustParams * ) params - > oParams ;
const char * result = NULL ;
/* printf stuff out */
if ( status = = GPGME_STATUS_EOF )
fprintf ( stderr , " keySignCallback GPGME_STATUS_EOF \n " ) ;
if ( status = = GPGME_STATUS_GOT_IT )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GOT_IT \n " ) ;
if ( status = = GPGME_STATUS_USERID_HINT )
fprintf ( stderr , " keySignCallback GPGME_STATUS_USERID_HINT \n " ) ;
if ( status = = GPGME_STATUS_NEED_PASSPHRASE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_NEED_PASSPHRASE \n " ) ;
if ( status = = GPGME_STATUS_GOOD_PASSPHRASE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GOOD_PASSPHRASE \n " ) ;
if ( status = = GPGME_STATUS_BAD_PASSPHRASE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_BAD_PASSPHRASE \n " ) ;
if ( status = = GPGME_STATUS_GET_LINE )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GET_LINE \n " ) ;
if ( status = = GPGME_STATUS_GET_BOOL )
fprintf ( stderr , " keySignCallback GPGME_STATUS_GET_BOOL \n " ) ;
if ( status = = GPGME_STATUS_ALREADY_SIGNED )
fprintf ( stderr , " keySignCallback GPGME_STATUS_ALREADY_SIGNED \n " ) ;
/* printf stuff out */
if ( params - > state = = TRUST_START )
fprintf ( stderr , " keySignCallback params->state TRUST_START \n " ) ;
if ( params - > state = = TRUST_COMMAND )
fprintf ( stderr , " keySignCallback params->state TRUST_COMMAND \n " ) ;
if ( params - > state = = TRUST_VALUE )
fprintf ( stderr , " keySignCallback params->state TRUST_VALUE \n " ) ;
if ( params - > state = = TRUST_REALLY_ULTIMATE )
fprintf ( stderr , " keySignCallback params->state TRUST_REALLY_ULTIMATE \n " ) ;
if ( params - > state = = TRUST_QUIT )
fprintf ( stderr , " keySignCallback params->state TRUST_QUIT \n " ) ;
if ( params - > state = = TRUST_ERROR )
fprintf ( stderr , " keySignCallback params->state TRUST_ERROR \n " ) ;
2009-05-23 13:40:35 -04:00
if ( status = = GPGME_STATUS_EOF | |
status = = GPGME_STATUS_GOT_IT ) {
return params - > err ;
}
switch ( params - > state )
{
case TRUST_START :
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) ) {
params - > state = TRUST_COMMAND ;
result = " trust " ;
} else {
params - > state = TRUST_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case TRUST_COMMAND :
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " edit_ownertrust.value " ) . compare ( args ) ) ) {
params - > state = TRUST_VALUE ;
2010-01-13 16:14:49 -05:00
result = tparams - > trustLvl . c_str ( ) ; ;
2009-05-23 13:40:35 -04:00
} else {
params - > state = TRUST_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case TRUST_VALUE :
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) ) {
params - > state = TRUST_QUIT ;
result = " quit " ;
}
else if ( status = = GPGME_STATUS_GET_BOOL & &
( ! std : : string ( " edit_ownertrust.set_ultimate.okay " ) . compare ( args ) ) ) {
params - > state = TRUST_REALLY_ULTIMATE ;
result = " Y " ;
}
else {
params - > state = TRUST_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case TRUST_REALLY_ULTIMATE :
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) ) {
params - > state = TRUST_QUIT ;
result = " quit " ;
} else {
params - > state = TRUST_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case TRUST_QUIT :
if ( status = = GPGME_STATUS_GET_BOOL & &
( ! std : : string ( " keyedit.save.okay " ) . compare ( args ) ) ) {
params - > state = TRUST_SAVE ;
result = " Y " ;
} else {
params - > state = TRUST_ERROR ;
params - > err = gpg_error ( GPG_ERR_GENERAL ) ;
}
break ;
case TRUST_ERROR :
if ( status = = GPGME_STATUS_GET_LINE & &
( ! std : : string ( " keyedit.prompt " ) . compare ( args ) ) ) {
/* Go to quit operation state */
params - > state = TRUST_QUIT ;
result = " quit " ;
} else {
params - > state = TRUST_ERROR ;
}
break ;
}
if ( result )
{
2009-07-30 10:36:42 -04:00
# ifndef WINDOWS_SYS
2009-05-23 13:40:35 -04:00
if ( * result )
write ( fd , result , strlen ( result ) ) ;
write ( fd , " \n " , 1 ) ;
2009-07-30 10:36:42 -04:00
# else
DWORD written = 0 ;
HANDLE winFd = ( HANDLE ) fd ;
if ( * result )
WriteFile ( winFd , result , strlen ( result ) , & written , NULL ) ;
WriteFile ( winFd , " \n " , 1 , & written , NULL ) ;
# endif
2010-01-13 16:14:49 -05:00
std : : cerr < < " trustCallback() result : " < < result < < std : : endl ;
2009-05-23 13:40:35 -04:00
}
return params - > err ;
}
2010-01-13 16:26:30 -05:00
// -----------------------------------------------------------------------------------//
// -------------------------------- Config functions ------------------------------ //
// -----------------------------------------------------------------------------------//
//
RsSerialiser * AuthGPG : : setupSerialiser ( )
{
RsSerialiser * rss = new RsSerialiser ;
rss - > addSerialType ( new RsGeneralConfigSerialiser ( ) ) ;
return rss ;
}
std : : list < RsItem * > AuthGPG : : saveList ( bool & cleanup )
{
std : : cerr < < " AuthGPG::saveList() called " < < std : : endl ;
cleanup = true ;
std : : list < RsItem * > lst ;
// Now save config for network digging strategies
RsConfigKeyValueSet * vitem = new RsConfigKeyValueSet ;
std : : map < std : : string , bool > : : iterator mapIt ;
for ( mapIt = mAcceptToConnectMap . begin ( ) ; mapIt ! = mAcceptToConnectMap . end ( ) ; mapIt + + ) {
2010-01-19 08:09:11 -05:00
if ( mapIt - > first = = getGPGOwnId ( ) ) {
continue ;
}
2010-01-13 16:26:30 -05:00
RsTlvKeyValue kv ;
kv . key = mapIt - > first ;
std : : cerr < < " AuthGPG::saveList() called (mapIt->second) : " < < ( mapIt - > second ) < < std : : endl ;
kv . value = ( mapIt - > second ) ? " TRUE " : " FALSE " ;
vitem - > tlvkvs . pairs . push_back ( kv ) ;
}
lst . push_back ( vitem ) ;
return lst ;
}
bool AuthGPG : : loadList ( std : : list < RsItem * > load )
{
std : : cerr < < " AuthGPG::loadList() Item Count: " < < load . size ( ) < < std : : endl ;
RsStackMutex stack ( pgpMtx ) ; /****** STACK LOCK MUTEX *******/
storeAllKeys_locked ( ) ;
/* load the list of accepted gpg keys */
std : : list < RsItem * > : : iterator it ;
for ( it = load . begin ( ) ; it ! = load . end ( ) ; it + + ) {
RsConfigKeyValueSet * vitem = dynamic_cast < RsConfigKeyValueSet * > ( * it ) ;
if ( vitem ) {
std : : cerr < < " AuthGPG::loadList() General Variable Config Item: " < < std : : endl ;
vitem - > print ( std : : cerr , 10 ) ;
std : : cerr < < std : : endl ;
std : : list < RsTlvKeyValue > : : iterator kit ;
for ( kit = vitem - > tlvkvs . pairs . begin ( ) ; kit ! = vitem - > tlvkvs . pairs . end ( ) ; kit + + ) {
2010-01-19 08:09:11 -05:00
if ( kit - > key = = getGPGOwnId ( ) ) {
continue ;
}
2010-01-13 16:26:30 -05:00
mAcceptToConnectMap [ kit - > key ] = ( kit - > value = = " TRUE " ) ;
//set the gpg key
certmap : : iterator it ;
if ( mKeyList . end ( ) ! = ( it = mKeyList . find ( kit - > key ) ) ) {
std : : cerr < < " AuthGPG::loadList() setting accept to : " < < ( kit - > value = = " TRUE " ) ;
std : : cerr < < " for gpg key id : " < < kit - > key < < std : : endl ;
it - > second . accept_connection = ( kit - > value = = " TRUE " ) ;
}
}
}
delete ( * it ) ;
}
return true ;
}