mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-05-06 16:15:23 -04:00
Merged branch v0.5-OpenPGP into trunk:
User-level changes: ================== - libgpgme is not used anymore; it is replaced by a built-in piece of code called OpenPGP-SDK (http://openpgp.nominet.org.uk/cgi-bin/trac.cgi) that was improved to be used by RetroShare for handling PGP keys. - the gnupg keyring is not used anymore. Now, RetroShare has it's own gpg keyring, shared by all instances. On linux it's located in ~/.retroshare/pgp/. A lock system prevents multiple locations to read/write keyrings simultaneously. - the trust database from gnupg is not documented, so RetroShare cannot import it. This comes from the fact that the GPG standard (RFC4880) asks explicitly not to export trust information. So RetroShare has it's own trust DB shared by locations. This means you need to re-trust people. Sorry for that! - at start, if no keyring is found, RS will propose to copy the gnupg keyring to use your existing keys. Clicking on "OK" will do the copy, and you should find back all existing locations, except for DSA keys. - locations for which the suitable keypair is not in the keyring will not be displayed in the login window - locations for which the suitable keypair is not a RSA/RSA key will not be displayed. RetroShare does not support DSA/Elgamal keypairs yet. - a key import/export exchange function has been added in the certificate creation window (you go there from the login window by clicking on "manage keys/locations". This allows to easily create a new location with the same pgp key on another computer. To obtain a suitable keypair using gnupg, you need to concatenate the encrypted private key and the public key into an ascii file. This can be done using: gpg -a --export-secret-keys [your ID] > mykey.asc gpg -a --export [your ID] >> mykey.asc - importing a key with subkeys in not yet possible. Please remove subkeys before importing. - The code has been tested for a reasonnable amount of time, but it's not possible to prevent some new bugs to appear. Please report them asap supplying: call-stacks if possible, and terminal output. In particular, openpgp has some assert()'s that should not be triggered unless RetroShare is calling it in an improper way. Internal changes ================ - a specific component, PGPHandler, takes care of the interface between openpgp-sdk and RetroShare openpgp-sdk is c-code, with it's own memory management, which has been kept well separated from RetroShare. - GPG Ids are now a specific class (not a std::string anymore) for code consistency reasons. As strings are still used in many places, this requires a few conversions. In particular, AuthGPG takes strings as function params and calls GPGHandler with the proper PGPIdType class. In the future, RetroShare should only use PGPIdType. The same will be done for SSL ids. - signature cleaning is still handled by the Retroshare built-in function, not by openpgp, but we will do this later. Still to do =========== - DSA needs subkey handling, since the encryption is performed by a Elgamal subkey. Not sure this will be done. - GPGIds/SSLIds cleaning (meaning replace strings by appropriate types). Lots of confusion throughout the code in retroshare-gui in particular. - key removal from keyring. This is a challenge to keep locations synchronised. git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@5293 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
commit
fc8dfcf65b
109 changed files with 26549 additions and 2997 deletions
|
@ -176,6 +176,9 @@ linux-* {
|
|||
INCLUDEPATH *= /usr/lib/x86_64-linux-gnu/glib-2.0/include/
|
||||
INCLUDEPATH *= /usr/lib/i386-linux-gnu/glib-2.0/include/
|
||||
|
||||
OPENPGPSDK_DIR = ../../openpgpsdk/src
|
||||
INCLUDEPATH *= $${OPENPGPSDK_DIR}
|
||||
|
||||
DESTDIR = lib
|
||||
QMAKE_CXXFLAGS *= -Wall -D_FILE_OFFSET_BITS=64
|
||||
QMAKE_CC = g++
|
||||
|
@ -293,6 +296,8 @@ win32 {
|
|||
ZLIB_DIR = ../../../zlib-1.2.3
|
||||
SSL_DIR = ../../../../OpenSSL
|
||||
|
||||
OPENPGPSDK_DIR = ../../openpgpsdk/src
|
||||
INCLUDEPATH *= $${OPENPGPSDK_DIR}
|
||||
|
||||
INCLUDEPATH += . $${SSL_DIR}/include $${UPNPC_DIR} $${PTHREADS_DIR} $${ZLIB_DIR} $${GPGME_DIR}/src $${GPG_ERROR_DIR}/src
|
||||
}
|
||||
|
@ -365,6 +370,8 @@ HEADERS += ft/ftchunkmap.h \
|
|||
|
||||
HEADERS += pqi/authssl.h \
|
||||
pqi/authgpg.h \
|
||||
pgp/pgphandler.h \
|
||||
pgp/pgpkeyutil.h \
|
||||
pqi/cleanupxpgp.h \
|
||||
pqi/p3cfgmgr.h \
|
||||
pqi/p3peermgr.h \
|
||||
|
@ -483,7 +490,6 @@ HEADERS += util/folderiterator.h \
|
|||
util/rsrandom.h \
|
||||
util/pugiconfig.h \
|
||||
util/radix64.h \
|
||||
util/pgpkey.h \
|
||||
util/pugixml.h
|
||||
|
||||
SOURCES += dbase/cachestrapper.cc \
|
||||
|
@ -507,6 +513,8 @@ SOURCES += ft/ftchunkmap.cc \
|
|||
|
||||
SOURCES += pqi/authgpg.cc \
|
||||
pqi/authssl.cc \
|
||||
pgp/pgphandler.cc \
|
||||
pgp/pgpkeyutil.cc \
|
||||
pqi/cleanupxpgp.cc \
|
||||
pqi/p3cfgmgr.cc \
|
||||
pqi/p3peermgr.cc \
|
||||
|
@ -626,7 +634,6 @@ SOURCES += util/folderiterator.cc \
|
|||
util/rsversion.cc \
|
||||
util/rswin.cc \
|
||||
util/rsrandom.cc \
|
||||
util/pgpkey.cc \
|
||||
util/pugixml.cc
|
||||
|
||||
zeroconf {
|
||||
|
|
1329
libretroshare/src/pgp/pgphandler.cc
Normal file
1329
libretroshare/src/pgp/pgphandler.cc
Normal file
File diff suppressed because it is too large
Load diff
174
libretroshare/src/pgp/pgphandler.h
Normal file
174
libretroshare/src/pgp/pgphandler.h
Normal file
|
@ -0,0 +1,174 @@
|
|||
#pragma once
|
||||
|
||||
// This class implements an abstract pgp handler to be used in RetroShare.
|
||||
//
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <util/rsthreads.h>
|
||||
#include <util/rsid.h>
|
||||
|
||||
extern "C" {
|
||||
#include <openpgpsdk/types.h>
|
||||
#include <openpgpsdk/keyring.h>
|
||||
#include <openpgpsdk/keyring_local.h>
|
||||
}
|
||||
|
||||
static const int KEY_ID_SIZE = 8 ;
|
||||
static const int KEY_FINGERPRINT_SIZE = 20 ;
|
||||
|
||||
typedef std::string (*PassphraseCallback)(void *data, const char *uid_hint, const char *passphrase_info, int prev_was_bad) ;
|
||||
|
||||
typedef t_RsGenericIdType<KEY_ID_SIZE> PGPIdType;
|
||||
typedef t_RsGenericIdType<KEY_FINGERPRINT_SIZE> PGPFingerprintType ;
|
||||
|
||||
class PGPCertificateInfo
|
||||
{
|
||||
public:
|
||||
PGPCertificateInfo() {}
|
||||
|
||||
std::string _name;
|
||||
std::string _email;
|
||||
std::string _comment;
|
||||
|
||||
std::set<std::string> signers;
|
||||
|
||||
uint32_t _trustLvl;
|
||||
uint32_t _validLvl;
|
||||
uint32_t _flags ;
|
||||
|
||||
PGPFingerprintType _fpr; /* fingerprint */
|
||||
PGPIdType _key_id ;
|
||||
|
||||
uint32_t _key_index ; // index to array of keys in the public keyring
|
||||
|
||||
static const uint32_t PGP_CERTIFICATE_FLAG_ACCEPT_CONNEXION = 0x0001 ;
|
||||
static const uint32_t PGP_CERTIFICATE_FLAG_HAS_OWN_SIGNATURE = 0x0002 ;
|
||||
static const uint32_t PGP_CERTIFICATE_FLAG_HAS_SIGNED_ME = 0x0004 ;
|
||||
static const uint32_t PGP_CERTIFICATE_FLAG_UNSUPPORTED_ALGORITHM = 0x0008 ; // set when the key is not RSA, so that RS avoids to use it.
|
||||
|
||||
static const uint8_t PGP_CERTIFICATE_TRUST_UNDEFINED = 0x00 ;
|
||||
static const uint8_t PGP_CERTIFICATE_TRUST_NEVER = 0x02 ;
|
||||
static const uint8_t PGP_CERTIFICATE_TRUST_MARGINALLY = 0x03 ;
|
||||
static const uint8_t PGP_CERTIFICATE_TRUST_FULLY = 0x04 ;
|
||||
static const uint8_t PGP_CERTIFICATE_TRUST_ULTIMATE = 0x05 ;
|
||||
};
|
||||
|
||||
class PGPHandler
|
||||
{
|
||||
public:
|
||||
PGPHandler( const std::string& path_to_public_keyring,
|
||||
const std::string& path_to_secret_keyring,
|
||||
const std::string& path_to_trust_database,
|
||||
const std::string& pgp_lock_file) ;
|
||||
|
||||
virtual ~PGPHandler() ;
|
||||
|
||||
/**
|
||||
* @param ids list of gpg certificate ids (note, not the actual certificates)
|
||||
*/
|
||||
bool getGPGFilteredList(std::list<PGPIdType>& list,bool (*filter)(const PGPCertificateInfo&) = NULL) const ;
|
||||
bool haveSecretKey(const PGPIdType& id) const ;
|
||||
|
||||
bool importGPGKeyPair(const std::string& filename,PGPIdType& imported_id,std::string& import_error) ;
|
||||
bool exportGPGKeyPair(const std::string& filename,const PGPIdType& exported_id) const ;
|
||||
|
||||
bool availableGPGCertificatesWithPrivateKeys(std::list<PGPIdType>& ids);
|
||||
bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, PGPIdType& pgpId, std::string& errString) ;
|
||||
|
||||
bool LoadCertificateFromString(const std::string& pem, PGPIdType& gpg_id, std::string& error_string);
|
||||
std::string SaveCertificateToString(const PGPIdType& id,bool include_signatures) ;
|
||||
|
||||
bool SignDataBin(const PGPIdType& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen) ;
|
||||
bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) ;
|
||||
bool privateSignCertificate(const PGPIdType& own_id,const PGPIdType& id_of_key_to_sign) ;
|
||||
|
||||
bool encryptTextToFile(const PGPIdType& key_id,const std::string& text,const std::string& outfile) ;
|
||||
bool decryptTextFromFile(const PGPIdType& key_id,std::string& text,const std::string& inputfile) ;
|
||||
|
||||
bool getKeyFingerprint(const PGPIdType& id,PGPFingerprintType& fp) const ;
|
||||
void setAcceptConnexion(const PGPIdType&,bool) ;
|
||||
void updateOwnSignatureFlag(const PGPIdType& ownId) ;
|
||||
|
||||
//bool isKeySupported(const PGPIdType& id) const ;
|
||||
|
||||
bool privateTrustCertificate(const PGPIdType& id,int valid_level) ;
|
||||
|
||||
// Write keyring
|
||||
|
||||
//bool writeSecretKeyring() ;
|
||||
//bool writePublicKeyring() ;
|
||||
|
||||
const PGPCertificateInfo *getCertificateInfo(const PGPIdType& id) const ;
|
||||
|
||||
bool isGPGId(const std::string &id);
|
||||
bool isGPGSigned(const std::string &id);
|
||||
bool isGPGAccepted(const std::string &id);
|
||||
|
||||
static void setPassphraseCallback(PassphraseCallback cb) ;
|
||||
static PassphraseCallback passphraseCallback() { return _passphrase_callback ; }
|
||||
|
||||
// Debug stuff.
|
||||
virtual bool printKeys() const ;
|
||||
|
||||
// Syncs the keyrings and trust database between memory and disk. The algorithm is:
|
||||
// 1 - lock the keyrings
|
||||
// 2 - compare file modification dates with last writing date
|
||||
// - if file is modified, load it, and merge with memory
|
||||
// 3 - look into memory modification flags
|
||||
// - if flag says keyring has changed, write to disk
|
||||
//
|
||||
bool syncDatabase() ;
|
||||
|
||||
private:
|
||||
void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ;
|
||||
|
||||
// Returns true if the signatures have been updated
|
||||
//
|
||||
bool validateAndUpdateSignatures(PGPCertificateInfo& cert,const ops_keydata_t *keydata) ;
|
||||
|
||||
const ops_keydata_t *getPublicKey(const PGPIdType&) const ;
|
||||
const ops_keydata_t *getSecretKey(const PGPIdType&) const ;
|
||||
|
||||
void locked_readPrivateTrustDatabase() ;
|
||||
bool locked_writePrivateTrustDatabase() ;
|
||||
|
||||
bool locked_syncPublicKeyring() ;
|
||||
bool locked_syncTrustDatabase() ;
|
||||
|
||||
void mergeKeyringFromDisk(ops_keyring_t *keyring, std::map<std::string,PGPCertificateInfo>& kmap, const std::string& keyring_file) ;
|
||||
bool addOrMergeKey(ops_keyring_t *keyring,std::map<std::string,PGPCertificateInfo>& kmap,const ops_keydata_t *keydata) ;
|
||||
|
||||
// Members.
|
||||
//
|
||||
mutable RsMutex pgphandlerMtx ;
|
||||
|
||||
ops_keyring_t *_pubring ;
|
||||
ops_keyring_t *_secring ;
|
||||
|
||||
std::map<std::string,PGPCertificateInfo> _public_keyring_map ; // used for fast access to keys. Gives the index in the keyring.
|
||||
std::map<std::string,PGPCertificateInfo> _secret_keyring_map ;
|
||||
|
||||
const std::string _pubring_path ;
|
||||
const std::string _secring_path ;
|
||||
const std::string _trustdb_path ;
|
||||
const std::string _pgp_lock_filename ;
|
||||
|
||||
bool _pubring_changed ;
|
||||
bool _trustdb_changed ;
|
||||
|
||||
time_t _pubring_last_update_time ;
|
||||
time_t _secring_last_update_time ;
|
||||
time_t _trustdb_last_update_time ;
|
||||
|
||||
// Helper functions.
|
||||
//
|
||||
static std::string makeRadixEncodedPGPKey(const ops_keydata_t *key) ;
|
||||
static ops_keyring_t *allocateOPSKeyring() ;
|
||||
static void addNewKeyToOPSKeyring(ops_keyring_t*, const ops_keydata_t&) ;
|
||||
static PassphraseCallback _passphrase_callback ;
|
||||
static bool mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src) ; // returns true if signature lists are different
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include <stdint.h>
|
||||
#include <util/radix64.h>
|
||||
#include "pgpkey.h"
|
||||
#include "pgpkeyutil.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
@ -9,10 +9,6 @@
|
|||
/* #define DEBUG_PGPUTIL 1 */
|
||||
/****************************/
|
||||
|
||||
#define PGP_PACKET_TAG_PUBLIC_KEY 6
|
||||
#define PGP_PACKET_TAG_USER_ID 13
|
||||
#define PGP_PACKET_TAG_SIGNATURE 2
|
||||
|
||||
#define PGP_CRC24_INIT 0xB704CEL
|
||||
#define PGP_CRC24_POLY 0x1864CFBL
|
||||
|
||||
|
@ -85,11 +81,11 @@ bool PGPKeyManagement::createMinimalKey(const std::string& pgp_certificate,std::
|
|||
|
||||
data += packet_length ;
|
||||
|
||||
if(packet_tag == PGP_PACKET_TAG_PUBLIC_KEY)
|
||||
if(packet_tag == PGPKeyParser::PGP_PACKET_TAG_PUBLIC_KEY)
|
||||
public_key = true ;
|
||||
if(packet_tag == PGP_PACKET_TAG_USER_ID)
|
||||
if(packet_tag == PGPKeyParser::PGP_PACKET_TAG_USER_ID)
|
||||
user_id = true ;
|
||||
if(packet_tag == PGP_PACKET_TAG_SIGNATURE)
|
||||
if(packet_tag == PGPKeyParser::PGP_PACKET_TAG_SIGNATURE)
|
||||
own_signature = true ;
|
||||
|
||||
if(public_key && own_signature && user_id)
|
||||
|
@ -99,28 +95,7 @@ bool PGPKeyManagement::createMinimalKey(const std::string& pgp_certificate,std::
|
|||
break ;
|
||||
}
|
||||
|
||||
std::string outstring ;
|
||||
Radix64::encode(keydata,(uint64_t)data - (uint64_t)keydata,outstring) ;
|
||||
|
||||
uint32_t crc = compute24bitsCRC((unsigned char *)keydata,(uint64_t)data - (uint64_t)keydata) ;
|
||||
|
||||
unsigned char tmp[3] = { (crc >> 16) & 0xff, (crc >> 8) & 0xff, crc & 0xff } ;
|
||||
std::string crc_string ;
|
||||
Radix64::encode((const char *)tmp,3,crc_string) ;
|
||||
|
||||
#ifdef DEBUG_PGPUTIL
|
||||
std::cerr << "After signature pruning: " << std::endl;
|
||||
std::cerr << outstring << std::endl;
|
||||
#endif
|
||||
|
||||
cleaned_certificate = std::string(PGP_CERTIFICATE_START_STRING) + "\n" + version_string + "\n\n" ;
|
||||
|
||||
for(uint32_t i=0;i<outstring.length();i+=64)
|
||||
cleaned_certificate += outstring.substr(i,64) + "\n" ;
|
||||
|
||||
cleaned_certificate += "=" + crc_string + "\n" ;
|
||||
cleaned_certificate += std::string(PGP_CERTIFICATE_END_STRING) + "\n" ;
|
||||
|
||||
cleaned_certificate = makeArmouredKey((unsigned char*)keydata,(uint64_t)data - (uint64_t)keydata,version_string) ;
|
||||
return true ;
|
||||
}
|
||||
catch(std::exception& e)
|
||||
|
@ -131,6 +106,33 @@ bool PGPKeyManagement::createMinimalKey(const std::string& pgp_certificate,std::
|
|||
}
|
||||
}
|
||||
|
||||
std::string PGPKeyManagement::makeArmouredKey(const unsigned char *keydata,size_t key_size,const std::string& version_string)
|
||||
{
|
||||
std::string outstring ;
|
||||
Radix64::encode((const char *)keydata,key_size,outstring) ;
|
||||
|
||||
uint32_t crc = compute24bitsCRC((unsigned char *)keydata,key_size) ;
|
||||
|
||||
unsigned char tmp[3] = { (crc >> 16) & 0xff, (crc >> 8) & 0xff, crc & 0xff } ;
|
||||
std::string crc_string ;
|
||||
Radix64::encode((const char *)tmp,3,crc_string) ;
|
||||
|
||||
#ifdef DEBUG_PGPUTIL
|
||||
std::cerr << "After signature pruning: " << std::endl;
|
||||
std::cerr << outstring << std::endl;
|
||||
#endif
|
||||
|
||||
std::string certificate = std::string(PGP_CERTIFICATE_START_STRING) + "\n" + version_string + "\n\n" ;
|
||||
|
||||
for(uint32_t i=0;i<outstring.length();i+=64)
|
||||
certificate += outstring.substr(i,64) + "\n" ;
|
||||
|
||||
certificate += "=" + crc_string + "\n" ;
|
||||
certificate += std::string(PGP_CERTIFICATE_END_STRING) + "\n" ;
|
||||
|
||||
return certificate ;
|
||||
}
|
||||
|
||||
uint32_t PGPKeyManagement::compute24bitsCRC(unsigned char *octets, size_t len)
|
||||
{
|
||||
long crc = PGP_CRC24_INIT;
|
||||
|
@ -171,6 +173,7 @@ uint32_t PGPKeyParser::read_125Size(unsigned char *& data)
|
|||
return b1 ;
|
||||
|
||||
uint8_t b2 = *data ;
|
||||
++data ;
|
||||
|
||||
if(b1 < 224)
|
||||
return ((b1-192) << 8) + b2 + 192 ;
|
|
@ -59,6 +59,7 @@ class PGPKeyManagement
|
|||
//
|
||||
static bool createMinimalKey(const std::string& pgp_certificate,std::string& cleaned_certificate) ;
|
||||
|
||||
static std::string makeArmouredKey(const unsigned char *keydata,size_t key_size,const std::string& version_string) ;
|
||||
private:
|
||||
// Computes the 24 bits CRC checksum necessary to all PGP data.
|
||||
//
|
||||
|
@ -70,6 +71,10 @@ class PGPKeyManagement
|
|||
class PGPKeyParser
|
||||
{
|
||||
public:
|
||||
static const uint8_t PGP_PACKET_TAG_PUBLIC_KEY = 6 ;
|
||||
static const uint8_t PGP_PACKET_TAG_USER_ID = 13 ;
|
||||
static const uint8_t PGP_PACKET_TAG_SIGNATURE = 2 ;
|
||||
|
||||
static uint64_t read_KeyID(unsigned char *& data) ;
|
||||
static uint32_t read_125Size(unsigned char *& data) ;
|
||||
static uint32_t read_partialBodyLength(unsigned char *& data) ;
|
File diff suppressed because it is too large
Load diff
|
@ -50,6 +50,7 @@
|
|||
#include <set>
|
||||
#include <map>
|
||||
#include "pqi/p3cfgmgr.h"
|
||||
#include "pgp/pgphandler.h"
|
||||
|
||||
#define MAX_GPG_SIGNATURE_SIZE 4096
|
||||
|
||||
|
@ -57,39 +58,8 @@ class RsPeerDetails;
|
|||
|
||||
/*!
|
||||
* gpgcert is the identifier for a person.
|
||||
* It is a wrapper class for a GPGme OpenPGP certificate.
|
||||
* It is a wrapper class for a OpenPGP certificate.
|
||||
*/
|
||||
class AuthGPG;
|
||||
|
||||
class gpgcert
|
||||
{
|
||||
public:
|
||||
gpgcert();
|
||||
~gpgcert();
|
||||
|
||||
std::string id;
|
||||
std::string name;
|
||||
std::string email;
|
||||
|
||||
std::string fpr; /* fingerprint */
|
||||
std::list<std::string> signers;
|
||||
|
||||
uint32_t trustLvl;
|
||||
uint32_t validLvl;
|
||||
|
||||
bool ownsign;
|
||||
|
||||
//This is not gpg, but RS data. A gpg peer can be accepted for connecting but not signed.
|
||||
bool accept_connection;
|
||||
|
||||
gpgme_key_t key;
|
||||
|
||||
// Cached Certificates...
|
||||
bool mHaveCachedCert;
|
||||
std::string mCachedCert;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class AuthGPGOperation
|
||||
{
|
||||
|
@ -135,427 +105,289 @@ public:
|
|||
virtual void setGPGOperation(AuthGPGOperation *operation) = 0;
|
||||
};
|
||||
|
||||
/*!
|
||||
* The certificate map type
|
||||
*/
|
||||
typedef std::map<std::string, gpgcert> certmap;
|
||||
|
||||
//! provides basic gpg functionality
|
||||
/*!
|
||||
*
|
||||
* This provides retroshare basic gpg functionality and
|
||||
* key/web-of-trust management, also handle cert intialisation for retroshare
|
||||
*/
|
||||
|
||||
extern void AuthGPGInit();
|
||||
extern void AuthGPGExit();
|
||||
|
||||
class AuthGPG : public RsThread
|
||||
{
|
||||
|
||||
public:
|
||||
//AuthGPG();
|
||||
|
||||
static AuthGPG *getAuthGPG();
|
||||
|
||||
/**
|
||||
* @param ids list of gpg certificate ids (note, not the actual certificates)
|
||||
*/
|
||||
virtual bool availableGPGCertificatesWithPrivateKeys(std::list<std::string> &ids) = 0;
|
||||
virtual bool printKeys() = 0;
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 1 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 1: Initialisation.... As we are switching to OpenPGP the init functions
|
||||
* will be different. Just move the initialisation functions over....
|
||||
*
|
||||
* As GPGMe requires external calls to the GPG executable, which could potentially
|
||||
* be expensive, We'll want to cache the GPG keys in this class.
|
||||
* This should be done at initialisation, and saved in a map.
|
||||
* (see storage at the end of the class)
|
||||
*
|
||||
****/
|
||||
virtual bool active() = 0;
|
||||
|
||||
/* Initialize */
|
||||
virtual bool InitAuth () = 0;
|
||||
|
||||
/* Init by generating new Own PGP Cert, or selecting existing PGP Cert */
|
||||
virtual int GPGInit(const std::string &ownId) = 0;
|
||||
virtual bool CloseAuth() = 0;
|
||||
virtual bool GeneratePGPCertificate(std::string name, std::string email, std::string passwd, std::string &pgpId, std::string &errString) = 0;
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 3 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 3: These are some of the most commonly used functions in Retroshare.
|
||||
*
|
||||
* More commonly used functions.
|
||||
*
|
||||
* provide access to details in cache list.
|
||||
*
|
||||
****/
|
||||
virtual std::string getGPGName(const std::string &pgp_id) = 0;
|
||||
virtual std::string getGPGEmail(const std::string &pgp_id) = 0;
|
||||
|
||||
/* PGP web of trust management */
|
||||
virtual std::string getGPGOwnId() = 0;
|
||||
virtual std::string getGPGOwnName() = 0;
|
||||
|
||||
//virtual std::string getGPGOwnEmail() = 0;
|
||||
virtual bool getGPGDetails(const std::string &id, RsPeerDetails &d) = 0;
|
||||
virtual bool getGPGAllList(std::list<std::string> &ids) = 0;
|
||||
virtual bool getGPGValidList(std::list<std::string> &ids) = 0;
|
||||
virtual bool getGPGAcceptedList(std::list<std::string> &ids) = 0;
|
||||
virtual bool getGPGSignedList(std::list<std::string> &ids) = 0;
|
||||
virtual bool isGPGValid(const std::string &id) = 0;
|
||||
virtual bool isGPGSigned(const std::string &id) = 0;
|
||||
virtual bool isGPGAccepted(const std::string &id) = 0;
|
||||
virtual bool isGPGId(const std::string &id) = 0;
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 4 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 4: Loading and Saving Certificates. (Strings and Files)
|
||||
*
|
||||
****/
|
||||
virtual bool LoadCertificateFromString(const std::string &pem, std::string &gpg_id,std::string& error_string) = 0;
|
||||
virtual std::string SaveCertificateToString(const std::string &id,bool include_signatures) = 0;
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 6 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 6: Authentication, Trust and Signing.
|
||||
*
|
||||
* This is some of the harder functions, but they should have been
|
||||
* done in gpgroot already.
|
||||
*
|
||||
****/
|
||||
|
||||
virtual bool AllowConnection(const std::string &gpg_id, bool accept) = 0;
|
||||
|
||||
virtual bool SignCertificateLevel0(const std::string &id) = 0;
|
||||
virtual bool RevokeCertificate(const std::string &id) = 0; /* Particularly hard - leave for later */
|
||||
//virtual bool TrustCertificateNone(std::string id) = 0;
|
||||
//virtual bool TrustCertificateMarginally(std::string id) = 0;
|
||||
//virtual bool TrustCertificateFully(std::string id) = 0;
|
||||
virtual bool TrustCertificate(const std::string &id, int trustlvl) = 0; //trustlvl is 2 for none, 3 for marginal and 4 for full trust
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 7 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 7: Signing Data.
|
||||
*
|
||||
* There should also be Encryption Functions... (do later).
|
||||
*
|
||||
****/
|
||||
//virtual bool SignData(std::string input, std::string &sign) = 0;
|
||||
//virtual bool SignData(const void *data, const uint32_t len, std::string &sign) = 0;
|
||||
//virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen) = 0;
|
||||
virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen) = 0;
|
||||
virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const std::string &withfingerprint) = 0;
|
||||
virtual bool decryptText(gpgme_data_t CIPHER, gpgme_data_t PLAIN) = 0;
|
||||
virtual bool encryptText(gpgme_data_t PLAIN, gpgme_data_t CIPHER) = 0;
|
||||
//END of PGP public functions
|
||||
|
||||
/* GPG service */
|
||||
virtual bool addService(AuthGPGService *service) = 0;
|
||||
|
||||
};
|
||||
|
||||
/* The real implementation! */
|
||||
|
||||
|
||||
class AuthGPGimpl : public AuthGPG, public p3Config
|
||||
class AuthGPG: public p3Config, public RsThread, public PGPHandler
|
||||
{
|
||||
public:
|
||||
|
||||
AuthGPGimpl();
|
||||
~AuthGPGimpl();
|
||||
static void init( const std::string& path_to_pubring,
|
||||
const std::string& path_to_secring,
|
||||
const std::string& path_to_trustdb,
|
||||
const std::string& pgp_lock_file);
|
||||
|
||||
/**
|
||||
* @param ids list of gpg certificate ids (note, not the actual certificates)
|
||||
*/
|
||||
virtual bool availableGPGCertificatesWithPrivateKeys(std::list<std::string> &ids);
|
||||
static void exit();
|
||||
static AuthGPG *getAuthGPG() { return _instance ; }
|
||||
|
||||
virtual bool printKeys();
|
||||
/**
|
||||
* @param ids list of gpg certificate ids (note, not the actual certificates)
|
||||
*/
|
||||
virtual bool availableGPGCertificatesWithPrivateKeys(std::list<std::string> &ids);
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 1 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 1: Initialisation.... As we are switching to OpenPGP the init functions
|
||||
* will be different. Just move the initialisation functions over....
|
||||
*
|
||||
* As GPGMe requires external calls to the GPG executable, which could potentially
|
||||
* be expensive, We'll want to cache the GPG keys in this class.
|
||||
* This should be done at initialisation, and saved in a map.
|
||||
* (see storage at the end of the class)
|
||||
*
|
||||
****/
|
||||
virtual bool active();
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 1 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 1: Initialisation.... As we are switching to OpenPGP the init functions
|
||||
* will be different. Just move the initialisation functions over....
|
||||
*
|
||||
* As GPGMe requires external calls to the GPG executable, which could potentially
|
||||
* be expensive, We'll want to cache the GPG keys in this class.
|
||||
* This should be done at initialisation, and saved in a map.
|
||||
* (see storage at the end of the class)
|
||||
*
|
||||
****/
|
||||
virtual bool active();
|
||||
|
||||
/* Initialize */
|
||||
virtual bool InitAuth ();
|
||||
// /* Initialize */
|
||||
// virtual bool InitAuth ();
|
||||
// virtual bool CloseAuth();
|
||||
|
||||
/* Init by generating new Own PGP Cert, or selecting existing PGP Cert */
|
||||
virtual int GPGInit(const std::string &ownId);
|
||||
virtual bool CloseAuth();
|
||||
virtual bool GeneratePGPCertificate(std::string name, std::string email, std::string passwd, std::string &pgpId, std::string &errString);
|
||||
/* Init by generating new Own PGP Cert, or selecting existing PGP Cert */
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 3 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 3: These are some of the most commonly used functions in Retroshare.
|
||||
*
|
||||
* More commonly used functions.
|
||||
*
|
||||
* provide access to details in cache list.
|
||||
*
|
||||
****/
|
||||
virtual std::string getGPGName(const std::string &pgp_id);
|
||||
virtual std::string getGPGEmail(const std::string &pgp_id);
|
||||
virtual int GPGInit(const std::string &ownId);
|
||||
virtual bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, std::string &pgpId, std::string &errString);
|
||||
|
||||
/* PGP web of trust management */
|
||||
virtual std::string getGPGOwnId();
|
||||
virtual std::string getGPGOwnName();
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 3 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 3: These are some of the most commonly used functions in Retroshare.
|
||||
*
|
||||
* More commonly used functions.
|
||||
*
|
||||
* provide access to details in cache list.
|
||||
*
|
||||
****/
|
||||
virtual std::string getGPGName(const std::string &pgp_id,bool *success = NULL);
|
||||
virtual std::string getGPGEmail(const std::string &pgp_id,bool *success = NULL);
|
||||
|
||||
//virtual std::string getGPGOwnEmail();
|
||||
virtual bool getGPGDetails(const std::string &id, RsPeerDetails &d);
|
||||
virtual bool getGPGAllList(std::list<std::string> &ids);
|
||||
virtual bool getGPGValidList(std::list<std::string> &ids);
|
||||
virtual bool getGPGAcceptedList(std::list<std::string> &ids);
|
||||
virtual bool getGPGSignedList(std::list<std::string> &ids);
|
||||
virtual bool isGPGValid(const std::string &id);
|
||||
virtual bool isGPGSigned(const std::string &id);
|
||||
virtual bool isGPGAccepted(const std::string &id);
|
||||
virtual bool isGPGId(const std::string &id);
|
||||
/* PGP web of trust management */
|
||||
virtual std::string getGPGOwnId();
|
||||
virtual std::string getGPGOwnName();
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 4 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 4: Loading and Saving Certificates. (Strings and Files)
|
||||
*
|
||||
****/
|
||||
virtual bool LoadCertificateFromString(const std::string &pem, std::string &gpg_id,std::string& error_string);
|
||||
virtual std::string SaveCertificateToString(const std::string &id,bool include_signatures) ;
|
||||
//virtual std::string getGPGOwnEmail();
|
||||
virtual bool isKeySupported(const std::string &id) const ;
|
||||
virtual bool haveSecretKey(const std::string &id) const ;
|
||||
virtual bool getGPGDetails(const std::string &id, RsPeerDetails &d);
|
||||
virtual bool getGPGAllList(std::list<std::string> &ids);
|
||||
virtual bool getGPGValidList(std::list<std::string> &ids);
|
||||
virtual bool getGPGAcceptedList(std::list<std::string> &ids);
|
||||
virtual bool getGPGSignedList(std::list<std::string> &ids);
|
||||
virtual bool importProfile(const std::string& filename,std::string& gpg_id,std::string& import_error) ;
|
||||
virtual bool exportProfile(const std::string& filename,const std::string& gpg_id) ;
|
||||
|
||||
// Cached certificates.
|
||||
bool cacheGPGCertificate(const std::string &id, const std::string &certificate);
|
||||
bool getCachedGPGCertificate(const std::string &id, std::string &certificate);
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 4 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 4: Loading and Saving Certificates. (Strings and Files)
|
||||
*
|
||||
****/
|
||||
virtual bool LoadCertificateFromString(const std::string &pem, std::string &gpg_id,std::string& error_string);
|
||||
virtual std::string SaveCertificateToString(const std::string &id,bool include_signatures) ;
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 6 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 6: Authentication, Trust and Signing.
|
||||
*
|
||||
* This is some of the harder functions, but they should have been
|
||||
* done in gpgroot already.
|
||||
*
|
||||
****/
|
||||
virtual bool AllowConnection(const std::string &gpg_id, bool accept);
|
||||
// Cached certificates.
|
||||
bool getCachedGPGCertificate(const std::string &id, std::string &certificate);
|
||||
|
||||
virtual bool SignCertificateLevel0(const std::string &id);
|
||||
virtual bool RevokeCertificate(const std::string &id); /* Particularly hard - leave for later */
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 6 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 6: Authentication, Trust and Signing.
|
||||
*
|
||||
* This is some of the harder functions, but they should have been
|
||||
* done in gpgroot already.
|
||||
*
|
||||
****/
|
||||
virtual bool AllowConnection(const std::string &gpg_id, bool accept);
|
||||
|
||||
//virtual bool TrustCertificateNone(std::string id);
|
||||
//virtual bool TrustCertificateMarginally(std::string id);
|
||||
//virtual bool TrustCertificateFully(std::string id);
|
||||
virtual bool TrustCertificate(const std::string &id, int trustlvl); //trustlvl is 2 for none, 3 for marginal and 4 for full trust
|
||||
virtual bool SignCertificateLevel0(const std::string &id);
|
||||
virtual bool RevokeCertificate(const std::string &id); /* Particularly hard - leave for later */
|
||||
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 7 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 7: Signing Data.
|
||||
*
|
||||
* There should also be Encryption Functions... (do later).
|
||||
*
|
||||
****/
|
||||
//virtual bool SignData(std::string input, std::string &sign);
|
||||
//virtual bool SignData(const void *data, const uint32_t len, std::string &sign);
|
||||
//virtual bool SignDataBin(std::string input, unsigned char *sign, unsigned int *signlen);
|
||||
virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen);
|
||||
virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const std::string &withfingerprint);
|
||||
virtual bool decryptText(gpgme_data_t CIPHER, gpgme_data_t PLAIN);
|
||||
virtual bool encryptText(gpgme_data_t PLAIN, gpgme_data_t CIPHER);
|
||||
//END of PGP public functions
|
||||
virtual bool TrustCertificate(const std::string &id, int trustlvl); //trustlvl is 2 for none, 3 for marginal and 4 for full trust
|
||||
|
||||
/* GPG service */
|
||||
virtual bool addService(AuthGPGService *service);
|
||||
/*********************************************************************************/
|
||||
/************************* STAGE 7 ***********************************************/
|
||||
/*********************************************************************************/
|
||||
/*****
|
||||
* STAGE 7: Signing Data.
|
||||
*
|
||||
* There should also be Encryption Functions... (do later).
|
||||
*
|
||||
****/
|
||||
virtual bool SignDataBin(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen);
|
||||
virtual bool VerifySignBin(const void*, uint32_t, unsigned char*, unsigned int, const std::string &withfingerprint);
|
||||
|
||||
protected:
|
||||
/*****************************************************************/
|
||||
/*********************** p3config ******************************/
|
||||
/* Key Functions to be overloaded for Full Configuration */
|
||||
virtual RsSerialiser *setupSerialiser();
|
||||
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
|
||||
virtual bool loadList(std::list<RsItem *>& load);
|
||||
/*****************************************************************/
|
||||
virtual bool decryptTextFromFile( std::string& text,const std::string& filename);
|
||||
virtual bool encryptTextToFile (const std::string& text,const std::string& filename);
|
||||
|
||||
bool getGPGFilteredList(std::list<std::string>& list,bool (*filter)(const PGPCertificateInfo&) = NULL) ;
|
||||
|
||||
//END of PGP public functions
|
||||
|
||||
/* GPG service */
|
||||
virtual bool addService(AuthGPGService *service) ;
|
||||
|
||||
protected:
|
||||
AuthGPG(const std::string& path_to_pubring, const std::string& path_to_secring,const std::string& path_to_trustdb,const std::string& pgp_lock_file);
|
||||
virtual ~AuthGPG();
|
||||
|
||||
/*****************************************************************/
|
||||
/*********************** p3config ******************************/
|
||||
/* Key Functions to be overloaded for Full Configuration */
|
||||
virtual RsSerialiser *setupSerialiser();
|
||||
virtual bool saveList(bool &cleanup, std::list<RsItem *>&);
|
||||
virtual bool loadList(std::list<RsItem *>& load);
|
||||
/*****************************************************************/
|
||||
|
||||
private:
|
||||
|
||||
/* SKTAN */
|
||||
//void showData(gpgme_data_t dh);
|
||||
//void createDummyFriends(void); //NYI
|
||||
/* SKTAN */
|
||||
//void showData(gpgme_data_t dh);
|
||||
//void createDummyFriends(void); //NYI
|
||||
|
||||
/* Internal functions */
|
||||
bool DoOwnSignature(const void *, unsigned int, void *, unsigned int *);
|
||||
bool VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const std::string &withfingerprint);
|
||||
|
||||
/* Internal functions */
|
||||
bool DoOwnSignature(const void *, unsigned int, void *, unsigned int *);
|
||||
bool VerifySignature(const void *data, int datalen, const void *sig, unsigned int siglen, const std::string &withfingerprint);
|
||||
/* Sign/Trust stuff */
|
||||
int privateSignCertificate(const std::string &id);
|
||||
int privateRevokeCertificate(const std::string &id); /* revoke the signature on Certificate */
|
||||
int privateTrustCertificate(const std::string &id, int trustlvl);
|
||||
|
||||
/* Sign/Trust stuff */
|
||||
int privateSignCertificate(const std::string &id);
|
||||
int privateRevokeCertificate(const std::string &id); /* revoke the signature on Certificate */
|
||||
int privateTrustCertificate(const std::string &id, int trustlvl);
|
||||
// store all keys in map mKeyList to avoid calling gpgme exe repeatedly
|
||||
//bool storeAllKeys();
|
||||
//bool storeAllKeys_tick();
|
||||
|
||||
// store all keys in map mKeyList to avoid calling gpgme exe repeatedly
|
||||
bool storeAllKeys();
|
||||
bool storeAllKeys_tick();
|
||||
// Not used anymore
|
||||
// bool updateTrustAllKeys_locked();
|
||||
|
||||
// Not used anymore
|
||||
// bool updateTrustAllKeys_locked();
|
||||
/* GPG service */
|
||||
void processServices();
|
||||
|
||||
/* GPG service */
|
||||
void processServices();
|
||||
bool printAllKeys_locked();
|
||||
bool printOwnKeys_locked();
|
||||
|
||||
bool printAllKeys_locked();
|
||||
bool printOwnKeys_locked();
|
||||
/* own thread */
|
||||
virtual void run();
|
||||
|
||||
/* own thread */
|
||||
virtual void run();
|
||||
private:
|
||||
|
||||
private:
|
||||
static AuthGPG *instance_gpg; // pointeur vers le singleton
|
||||
|
||||
static AuthGPG *instance_gpg; // pointeur vers le singleton
|
||||
RsMutex gpgMtxService;
|
||||
RsMutex gpgMtxEngine;
|
||||
|
||||
RsMutex gpgMtxEngine;
|
||||
/* Below is protected via the mutex */
|
||||
/* Below is protected via the mutex */
|
||||
|
||||
gpgme_engine_info_t INFO;
|
||||
gpgme_ctx_t CTX;
|
||||
// gpgme_engine_info_t INFO;
|
||||
// gpgme_ctx_t CTX;
|
||||
|
||||
RsMutex gpgMtxData;
|
||||
/* Below is protected via the mutex */
|
||||
RsMutex gpgMtxData;
|
||||
/* Below is protected via the mutex */
|
||||
|
||||
certmap mKeyList;
|
||||
time_t mStoreKeyTime;
|
||||
time_t mStoreKeyTime;
|
||||
|
||||
bool gpgmeInit;
|
||||
PGPIdType mOwnGpgId;
|
||||
bool gpgKeySelected;
|
||||
bool _force_sync_database ;
|
||||
|
||||
bool gpgmeKeySelected;
|
||||
|
||||
std::string mOwnGpgId;
|
||||
gpgcert mOwnGpgCert;
|
||||
std::list<AuthGPGService*> services ;
|
||||
|
||||
std::map<std::string, bool> mAcceptToConnectMap;
|
||||
|
||||
RsMutex gpgMtxService;
|
||||
/* Below is protected via the mutex */
|
||||
|
||||
std::list<AuthGPGService*> services;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Sign a key
|
||||
**/
|
||||
typedef enum
|
||||
{
|
||||
SIGN_START,
|
||||
SIGN_COMMAND,
|
||||
SIGN_UIDS,
|
||||
SIGN_SET_EXPIRE,
|
||||
SIGN_SET_CHECK_LEVEL,
|
||||
SIGN_ENTER_PASSPHRASE,
|
||||
SIGN_CONFIRM,
|
||||
SIGN_QUIT,
|
||||
SIGN_SAVE,
|
||||
SIGN_ERROR
|
||||
} SignState;
|
||||
|
||||
|
||||
/*!
|
||||
* Change the key ownertrust
|
||||
**/
|
||||
typedef enum
|
||||
{
|
||||
TRUST_START,
|
||||
TRUST_COMMAND,
|
||||
TRUST_VALUE,
|
||||
TRUST_REALLY_ULTIMATE,
|
||||
TRUST_QUIT,
|
||||
TRUST_SAVE,
|
||||
TRUST_ERROR
|
||||
} TrustState;
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* This is the generic data object passed to the
|
||||
* callback function in a gpgme_op_edit operation.
|
||||
* The contents of this object are modified during
|
||||
* each callback, to keep track of states, errors
|
||||
* and other data.
|
||||
*/
|
||||
class EditParams
|
||||
{
|
||||
public:
|
||||
int state;
|
||||
|
||||
/*!
|
||||
* The return code of gpgme_op_edit() is the return value of
|
||||
* the last invocation of the callback. But returning an error
|
||||
* from the callback does not abort the edit operation, so we
|
||||
* must remember any error.
|
||||
*/
|
||||
gpg_error_t err;
|
||||
|
||||
/// Parameters specific to the key operation
|
||||
void *oParams;
|
||||
|
||||
EditParams(int state, void *oParams) {
|
||||
this->state = state;
|
||||
this->err = gpgme_error(GPG_ERR_NO_ERROR);
|
||||
this->oParams = oParams;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
* Data specific to key signing
|
||||
**/
|
||||
class SignParams
|
||||
{
|
||||
public:
|
||||
|
||||
std::string checkLvl;
|
||||
|
||||
SignParams(std::string checkLvl) {
|
||||
this->checkLvl = checkLvl;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Data specific to key signing
|
||||
**/
|
||||
class TrustParams
|
||||
{
|
||||
public:
|
||||
|
||||
std::string trustLvl;
|
||||
|
||||
TrustParams(std::string trustLvl) {
|
||||
this->trustLvl = trustLvl;
|
||||
}
|
||||
static AuthGPG *_instance ;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Sign a key
|
||||
**/
|
||||
typedef enum
|
||||
{
|
||||
SIGN_START,
|
||||
SIGN_COMMAND,
|
||||
SIGN_UIDS,
|
||||
SIGN_SET_EXPIRE,
|
||||
SIGN_SET_CHECK_LEVEL,
|
||||
SIGN_ENTER_PASSPHRASE,
|
||||
SIGN_CONFIRM,
|
||||
SIGN_QUIT,
|
||||
SIGN_SAVE,
|
||||
SIGN_ERROR
|
||||
} SignState;
|
||||
|
||||
|
||||
/*!
|
||||
* Change the key ownertrust
|
||||
**/
|
||||
typedef enum
|
||||
{
|
||||
TRUST_START,
|
||||
TRUST_COMMAND,
|
||||
TRUST_VALUE,
|
||||
TRUST_REALLY_ULTIMATE,
|
||||
TRUST_QUIT,
|
||||
TRUST_SAVE,
|
||||
TRUST_ERROR
|
||||
} TrustState;
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
* This is the generic data object passed to the
|
||||
* callback function in a gpgme_op_edit operation.
|
||||
* The contents of this object are modified during
|
||||
* each callback, to keep track of states, errors
|
||||
* and other data.
|
||||
*/
|
||||
class EditParams
|
||||
{
|
||||
public:
|
||||
int state;
|
||||
|
||||
/*!
|
||||
* The return code of gpgme_op_edit() is the return value of
|
||||
* the last invocation of the callback. But returning an error
|
||||
* from the callback does not abort the edit operation, so we
|
||||
* must remember any error.
|
||||
*/
|
||||
gpg_error_t err;
|
||||
|
||||
/// Parameters specific to the key operation
|
||||
void *oParams;
|
||||
|
||||
EditParams(int state, void *oParams) {
|
||||
this->state = state;
|
||||
this->err = gpgme_error(GPG_ERR_NO_ERROR);
|
||||
this->oParams = oParams;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/*!
|
||||
* Data specific to key signing
|
||||
**/
|
||||
class SignParams
|
||||
{
|
||||
public:
|
||||
|
||||
std::string checkLvl;
|
||||
|
||||
SignParams(std::string checkLvl) {
|
||||
this->checkLvl = checkLvl;
|
||||
}
|
||||
};
|
||||
|
||||
/*!
|
||||
* Data specific to key signing
|
||||
**/
|
||||
class TrustParams
|
||||
{
|
||||
public:
|
||||
|
||||
std::string trustLvl;
|
||||
|
||||
TrustParams(std::string trustLvl) {
|
||||
this->trustLvl = trustLvl;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -204,7 +204,10 @@ void setAuthSSL(AuthSSL *newssl)
|
|||
|
||||
void AuthSSLInit()
|
||||
{
|
||||
instance_ssl = new AuthSSLimpl();
|
||||
if (instance_ssl == NULL)
|
||||
{
|
||||
instance_ssl = new AuthSSLimpl();
|
||||
}
|
||||
}
|
||||
|
||||
AuthSSL *AuthSSL::getAuthSSL()
|
||||
|
|
|
@ -287,7 +287,18 @@ std::string cleanUpCertificate(const std::string& badCertificate,int& error_code
|
|||
while(currBadCertIdx < endCertStartIdx1 && (badCertificate[currBadCertIdx] == '=' || badCertificate[currBadCertIdx] == ' ' || badCertificate[currBadCertIdx] == '\n' ))
|
||||
currBadCertIdx++ ;
|
||||
|
||||
cleanCertificate += "==\n=";
|
||||
switch(cntPerLine % 4)
|
||||
{
|
||||
case 0: break ;
|
||||
case 1: std::cerr<<"Certificate corrupted beyond repair: wrongnumber of chars on last line (n%4=1)"<<std::endl;
|
||||
error_code = RS_PEER_CERT_CLEANING_CODE_WRONG_NUMBER;
|
||||
return badCertificate ;
|
||||
case 2: cleanCertificate += "==" ;
|
||||
break ;
|
||||
case 3: cleanCertificate += "=" ;
|
||||
break ;
|
||||
}
|
||||
cleanCertificate += "\n=";
|
||||
|
||||
// if (badCertificate[currBadCertIdx] == '=')
|
||||
// {
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
// Initialize failed, result < 0
|
||||
#define RS_INIT_AUTH_FAILED -1 // AuthGPG::InitAuth failed
|
||||
#define RS_INIT_BASE_DIR_ERROR -2 // AuthGPG::InitAuth failed
|
||||
#define RS_INIT_NO_KEYRING -3 // Keyring is empty. Need to import it.
|
||||
|
||||
|
||||
/****
|
||||
|
@ -79,6 +80,8 @@ class RsInit
|
|||
|
||||
static bool ValidateCertificate(std::string &userName) ;
|
||||
|
||||
static bool exportIdentity(const std::string& fname,const std::string& pgp_id) ;
|
||||
static bool importIdentity(const std::string& fname,std::string& imported_pgp_id,std::string& import_error) ;
|
||||
|
||||
/*!
|
||||
* Generating GPGme Account
|
||||
|
@ -87,6 +90,9 @@ class RsInit
|
|||
static int GetPGPLoginDetails(const std::string& id, std::string &name, std::string &email);
|
||||
static bool GeneratePGPCertificate(const std::string&, const std::string& email, const std::string& passwd, std::string &pgpId, std::string &errString);
|
||||
|
||||
// copies existing gnupg keyrings to the new place of the OpenPGP-SDK version. Returns true on success.
|
||||
static bool copyGnuPGKeyrings() ;
|
||||
|
||||
/*!
|
||||
* Login GGP
|
||||
*/
|
||||
|
|
|
@ -38,12 +38,14 @@
|
|||
class RsPeers;
|
||||
extern RsPeers *rsPeers;
|
||||
|
||||
/* Trust Levels */
|
||||
const uint32_t RS_TRUST_LVL_NONE = 2;
|
||||
const uint32_t RS_TRUST_LVL_MARGINAL = 3;
|
||||
const uint32_t RS_TRUST_LVL_FULL = 4;
|
||||
const uint32_t RS_TRUST_LVL_ULTIMATE = 5;
|
||||
/* Trust Levels. Should be the same values than what is declared in PGPHandler.h */
|
||||
|
||||
const uint32_t RS_TRUST_LVL_UNDEFINED = 0;
|
||||
const uint32_t RS_TRUST_LVL_UNKNOWN = 1;
|
||||
const uint32_t RS_TRUST_LVL_NEVER = 2;
|
||||
const uint32_t RS_TRUST_LVL_MARGINAL = 3;
|
||||
const uint32_t RS_TRUST_LVL_FULL = 4;
|
||||
const uint32_t RS_TRUST_LVL_ULTIMATE = 5;
|
||||
|
||||
/* Net Mode */
|
||||
const uint32_t RS_NETMODE_UDP = 0x0001;
|
||||
|
@ -76,6 +78,7 @@ const int RS_PEER_CERT_CLEANING_CODE_UNKOWN_ERROR = 0x01 ;
|
|||
const int RS_PEER_CERT_CLEANING_CODE_NO_BEGIN_TAG = 0x02 ;
|
||||
const int RS_PEER_CERT_CLEANING_CODE_NO_END_TAG = 0x03 ;
|
||||
const int RS_PEER_CERT_CLEANING_CODE_NO_CHECKSUM = 0x04 ;
|
||||
const int RS_PEER_CERT_CLEANING_CODE_WRONG_NUMBER = 0x05 ;
|
||||
|
||||
/* LinkType Flags */
|
||||
|
||||
|
@ -231,6 +234,7 @@ virtual bool getPeerDetails(const std::string &ssl_or_gpg_id, RsPeerDetails &d)
|
|||
/* Using PGP Ids */
|
||||
virtual std::string getGPGOwnId() = 0;
|
||||
virtual std::string getGPGId(const std::string &sslid_or_gpgid) = 0; //return the gpg id of the given gpg or ssl id
|
||||
virtual bool isKeySupported(const std::string& gpg_ids) = 0;
|
||||
virtual bool getGPGAcceptedList(std::list<std::string> &gpg_ids) = 0;
|
||||
virtual bool getGPGSignedList(std::list<std::string> &gpg_ids) = 0;//friends that we accpet to connect with but we don't want to sign their gpg key
|
||||
virtual bool getGPGValidList(std::list<std::string> &gpg_ids) = 0;
|
||||
|
|
|
@ -190,5 +190,5 @@ void RsServer::rsGlobalShutDown()
|
|||
mBlogs->join();
|
||||
#endif
|
||||
|
||||
AuthGPGExit();
|
||||
AuthGPG::exit();
|
||||
}
|
||||
|
|
|
@ -595,6 +595,10 @@ bool p3Peers::getPeerDetails(const std::string &id, RsPeerDetails &d)
|
|||
}
|
||||
#endif
|
||||
|
||||
bool p3Peers::isKeySupported(const std::string& id)
|
||||
{
|
||||
return AuthGPG::getAuthGPG()->isKeySupported(id);
|
||||
}
|
||||
|
||||
std::string p3Peers::getGPGName(const std::string &gpg_id)
|
||||
{
|
||||
|
|
|
@ -63,6 +63,7 @@ virtual bool getPeerDetails(const std::string &ssl_or_gpg_id, RsPeerDetails &d);
|
|||
/* Using PGP Ids */
|
||||
virtual std::string getGPGOwnId();
|
||||
virtual std::string getGPGId(const std::string &ssl_id);
|
||||
virtual bool isKeySupported(const std::string& ids);
|
||||
virtual bool getGPGAcceptedList(std::list<std::string> &ids);
|
||||
virtual bool getGPGSignedList(std::list<std::string> &ids);
|
||||
virtual bool getGPGValidList(std::list<std::string> &ids);
|
||||
|
|
|
@ -92,11 +92,7 @@ class RsInitConfig
|
|||
/* for certificate creation */
|
||||
//static std::string gpgPasswd;
|
||||
|
||||
#ifndef WINDOWS_SYS
|
||||
static int lockHandle;
|
||||
#else
|
||||
static HANDLE lockHandle;
|
||||
#endif
|
||||
static rs_lock_handle_t lockHandle;
|
||||
|
||||
/* These fields are needed for login */
|
||||
static std::string loginId;
|
||||
|
@ -151,11 +147,7 @@ static const int SSLPWD_LEN = 64;
|
|||
std::list<accountId> RsInitConfig::accountIds;
|
||||
std::string RsInitConfig::preferedId;
|
||||
|
||||
#ifndef WINDOWS_SYS
|
||||
int RsInitConfig::lockHandle;
|
||||
#else
|
||||
HANDLE RsInitConfig::lockHandle;
|
||||
#endif
|
||||
rs_lock_handle_t RsInitConfig::lockHandle;
|
||||
|
||||
std::string RsInitConfig::configDir;
|
||||
std::string RsInitConfig::load_cert;
|
||||
|
@ -197,7 +189,7 @@ bool RsInitConfig::udpListenerOnly;
|
|||
|
||||
|
||||
/* Uses private class - so must be hidden */
|
||||
static bool getAvailableAccounts(std::list<accountId> &ids);
|
||||
static bool getAvailableAccounts(std::list<accountId> &ids,int& failing_accounts);
|
||||
static bool checkAccount(std::string accountdir, accountId &id);
|
||||
|
||||
static std::string toUpperCase(const std::string& s)
|
||||
|
@ -253,7 +245,7 @@ void RsInit::InitRsConfig()
|
|||
|
||||
#ifdef WINDOWS_SYS
|
||||
// test for portable version
|
||||
if (GetFileAttributes (L"gpg.exe") != (DWORD) -1 && GetFileAttributes (L"gpgme-w32spawn.exe") != (DWORD) -1) {
|
||||
if (GetFileAttributes(L"portable") != (DWORD) -1) {
|
||||
// use portable version
|
||||
RsInitConfig::portable = true;
|
||||
}
|
||||
|
@ -611,9 +603,7 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
|
|||
*/
|
||||
/* create singletons */
|
||||
AuthSSLInit();
|
||||
AuthGPGInit();
|
||||
|
||||
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL);
|
||||
AuthSSL::getAuthSSL() -> InitAuth(NULL, NULL, NULL);
|
||||
|
||||
// first check config directories, and set bootstrap values.
|
||||
if(!setupBaseDir())
|
||||
|
@ -621,17 +611,31 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
|
|||
|
||||
get_configinit(RsInitConfig::basedir, RsInitConfig::preferedId);
|
||||
|
||||
std::string pgp_dir = RsInitConfig::basedir + "/pgp" ;
|
||||
if(!RsDirUtil::checkCreateDirectory(pgp_dir))
|
||||
throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ;
|
||||
|
||||
AuthGPG::init( pgp_dir + "/retroshare_public_keyring.gpg",
|
||||
pgp_dir + "/retroshare_secret_keyring.gpg",
|
||||
pgp_dir + "/retroshare_trustdb.gpg",
|
||||
pgp_dir + "/lock");
|
||||
|
||||
/* Initialize AuthGPG */
|
||||
if (AuthGPG::getAuthGPG()->InitAuth() == false) {
|
||||
std::cerr << "AuthGPG::InitAuth failed" << std::endl;
|
||||
return RS_INIT_AUTH_FAILED;
|
||||
}
|
||||
// if (AuthGPG::getAuthGPG()->InitAuth() == false) {
|
||||
// std::cerr << "AuthGPG::InitAuth failed" << std::endl;
|
||||
// return RS_INIT_AUTH_FAILED;
|
||||
// }
|
||||
|
||||
//std::list<accountId> ids;
|
||||
std::list<accountId>::iterator it;
|
||||
getAvailableAccounts(RsInitConfig::accountIds);
|
||||
int failing_accounts ;
|
||||
|
||||
// if a different user id has been passed to cmd line check for that instead
|
||||
getAvailableAccounts(RsInitConfig::accountIds,failing_accounts);
|
||||
|
||||
if(failing_accounts > 0 && RsInitConfig::accountIds.empty())
|
||||
return RS_INIT_NO_KEYRING ;
|
||||
|
||||
// if a different user id has been passed to cmd line check for that instead
|
||||
|
||||
std::string lower_case_user_string = toLowerCase(prefUserString) ;
|
||||
std::string upper_case_user_string = toUpperCase(prefUserString) ;
|
||||
|
@ -669,8 +673,9 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
|
|||
{
|
||||
std::cerr << " * Preferred * " << std::endl;
|
||||
userId = it->sslId;
|
||||
userName = it->pgpName;
|
||||
userName = it->pgpName;
|
||||
existingUser = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!existingUser)
|
||||
|
@ -702,6 +707,54 @@ int RsInit::InitRetroShare(int argcIgnored, char **argvIgnored, bool strictCheck
|
|||
|
||||
/**************************** Access Functions for Init Data **************************/
|
||||
|
||||
bool RsInit::exportIdentity(const std::string& fname,const std::string& id)
|
||||
{
|
||||
return AuthGPG::getAuthGPG()->exportProfile(fname,id);
|
||||
}
|
||||
|
||||
bool RsInit::importIdentity(const std::string& fname,std::string& id,std::string& import_error)
|
||||
{
|
||||
return AuthGPG::getAuthGPG()->importProfile(fname,id,import_error);
|
||||
}
|
||||
|
||||
bool RsInit::copyGnuPGKeyrings()
|
||||
{
|
||||
std::string pgp_dir = RsInitConfig::basedir + "/pgp" ;
|
||||
if(!RsDirUtil::checkCreateDirectory(pgp_dir))
|
||||
throw std::runtime_error("Cannot create pgp directory " + pgp_dir) ;
|
||||
|
||||
std::string source_public_keyring;
|
||||
std::string source_secret_keyring;
|
||||
|
||||
#ifdef WINDOWS_SYS
|
||||
if (RsInit::isPortable())
|
||||
{
|
||||
source_public_keyring = RsInit::RsConfigDirectory() + "/gnupg/pubring.gpg";
|
||||
source_secret_keyring = RsInit::RsConfigDirectory() + "/gnupg/secring.gpg" ;
|
||||
} else {
|
||||
source_public_keyring = RsInitConfig::basedir + "/../gnupg/pubring.gpg" ;
|
||||
source_secret_keyring = RsInitConfig::basedir + "/../gnupg/secring.gpg" ;
|
||||
}
|
||||
#else
|
||||
// We need a specific part for MacOS and Linux as well
|
||||
source_public_keyring = RsInitConfig::basedir + "/../.gnupg/pubring.gpg" ;
|
||||
source_secret_keyring = RsInitConfig::basedir + "/../.gnupg/secring.gpg" ;
|
||||
#endif
|
||||
|
||||
if(!RsDirUtil::copyFile(source_public_keyring,pgp_dir + "/retroshare_public_keyring.gpg"))
|
||||
{
|
||||
std::cerr << "Cannot copy pub keyring " << source_public_keyring << " to destination file " << pgp_dir + "/retroshare_public_keyring.pgp" << std::endl;
|
||||
return false ;
|
||||
}
|
||||
if(!RsDirUtil::copyFile(source_secret_keyring,pgp_dir + "/retroshare_secret_keyring.gpg"))
|
||||
{
|
||||
std::cerr << "Cannot copy sec keyring " << source_secret_keyring << " to destination file " << pgp_dir + "/retroshare_secret_keyring.pgp" << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
bool RsInit::getPreferedAccountId(std::string &id)
|
||||
{
|
||||
id = RsInitConfig::preferedId;
|
||||
|
@ -939,8 +992,9 @@ std::string RsInit::getRetroshareDataDirectory()
|
|||
|
||||
|
||||
/* directories with valid certificates in the expected location */
|
||||
bool getAvailableAccounts(std::list<accountId> &ids)
|
||||
bool getAvailableAccounts(std::list<accountId> &ids,int& failing_accounts)
|
||||
{
|
||||
failing_accounts = 0 ;
|
||||
/* get the directories */
|
||||
std::list<std::string> directories;
|
||||
std::list<std::string>::iterator it;
|
||||
|
@ -1023,6 +1077,8 @@ bool getAvailableAccounts(std::list<accountId> &ids)
|
|||
#endif
|
||||
ids.push_back(tmpId);
|
||||
}
|
||||
else
|
||||
++failing_accounts ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1046,35 +1102,39 @@ static bool checkAccount(std::string accountdir, accountId &id)
|
|||
std::string cert_name = basename + "_cert.pem";
|
||||
std::string userName, userId;
|
||||
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
std::cerr << "checkAccount() dir: " << accountdir << std::endl;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
bool ret = false;
|
||||
|
||||
/* check against authmanagers private keys */
|
||||
if (LoadCheckX509(cert_name.c_str(), id.pgpId, id.location, id.sslId))
|
||||
{
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
std::cerr << "location: " << id.location << " id: " << id.sslId << std::endl;
|
||||
#endif
|
||||
if (LoadCheckX509(cert_name.c_str(), id.pgpId, id.location, id.sslId))
|
||||
{
|
||||
#ifdef AUTHSSL_DEBUG
|
||||
std::cerr << "location: " << id.location << " id: " << id.sslId << std::endl;
|
||||
std::cerr << "issuerName: " << id.pgpId << " id: " << id.sslId << std::endl;
|
||||
#endif
|
||||
|
||||
if(! RsInit::GetPGPLoginDetails(id.pgpId, id.pgpName, id.pgpEmail))
|
||||
return false ;
|
||||
|
||||
#ifdef GPG_DEBUG
|
||||
std::cerr << "issuerName: " << id.pgpId << " id: " << id.sslId << std::endl;
|
||||
#endif
|
||||
RsInit::GetPGPLoginDetails(id.pgpId, id.pgpName, id.pgpEmail);
|
||||
#ifdef GPG_DEBUG
|
||||
std::cerr << "PGPLoginDetails: " << id.pgpId << " name: " << id.pgpName;
|
||||
std::cerr << " email: " << id.pgpEmail << std::endl;
|
||||
#endif
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "GetIssuerName FAILED!" << std::endl;
|
||||
ret = false;
|
||||
}
|
||||
if(!AuthGPG::getAuthGPG()->isKeySupported(id.pgpId))
|
||||
return false ;
|
||||
|
||||
if(!AuthGPG::getAuthGPG()->haveSecretKey(id.pgpId))
|
||||
return false ;
|
||||
|
||||
#ifdef GPG_DEBUG
|
||||
std::cerr << "PGPLoginDetails: " << id.pgpId << " name: " << id.pgpName;
|
||||
std::cerr << " email: " << id.pgpEmail << std::endl;
|
||||
#endif
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "GetIssuerName FAILED!" << std::endl;
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1101,8 +1161,14 @@ int RsInit::GetPGPLoginDetails(const std::string& id, std::string &name, st
|
|||
std::cerr << "RsInit::GetPGPLoginDetails for \"" << id << "\"" << std::endl;
|
||||
#endif
|
||||
|
||||
name = AuthGPG::getAuthGPG()->getGPGName(id);
|
||||
email = AuthGPG::getAuthGPG()->getGPGEmail(id);
|
||||
bool ok = true ;
|
||||
name = AuthGPG::getAuthGPG()->getGPGName(id,&ok);
|
||||
if(!ok)
|
||||
return 0 ;
|
||||
email = AuthGPG::getAuthGPG()->getGPGEmail(id,&ok);
|
||||
if(!ok)
|
||||
return 0 ;
|
||||
|
||||
if (name != "") {
|
||||
return 1;
|
||||
} else {
|
||||
|
@ -1123,75 +1189,9 @@ int RsInit::GetPGPLoginDetails(const std::string& id, std::string &name, st
|
|||
int RsInit::LockConfigDirectory(const std::string& accountDir, std::string& lockFilePath)
|
||||
{
|
||||
const std::string lockFile = accountDir + "/" + "lock";
|
||||
|
||||
lockFilePath = lockFile;
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
if(RsInitConfig::lockHandle != -1)
|
||||
close(RsInitConfig::lockHandle);
|
||||
|
||||
// open the file in write mode, create it if necessary, truncate it (it should be empty)
|
||||
RsInitConfig::lockHandle = open(lockFile.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
|
||||
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
if(RsInitConfig::lockHandle == -1)
|
||||
{
|
||||
std::cerr << "Could not open lock file " << lockFile.c_str() << std::flush;
|
||||
perror(NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// see "man fcntl" for the details, in short: non blocking lock creation on the whole file contents
|
||||
struct flock lockDetails;
|
||||
lockDetails.l_type = F_WRLCK;
|
||||
lockDetails.l_whence = SEEK_SET;
|
||||
lockDetails.l_start = 0;
|
||||
lockDetails.l_len = 0;
|
||||
|
||||
if(fcntl(RsInitConfig::lockHandle, F_SETLK, &lockDetails) == -1)
|
||||
{
|
||||
int fcntlErr = errno;
|
||||
std::cerr << "Could not request lock on file " << lockFile.c_str() << std::flush;
|
||||
perror(NULL);
|
||||
|
||||
// there's no lock so let's release the file handle immediately
|
||||
close(RsInitConfig::lockHandle);
|
||||
RsInitConfig::lockHandle = -1;
|
||||
|
||||
if(fcntlErr == EACCES || fcntlErr == EAGAIN)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
if (RsInitConfig::lockHandle) {
|
||||
CloseHandle(RsInitConfig::lockHandle);
|
||||
}
|
||||
|
||||
std::wstring wlockFile;
|
||||
librs::util::ConvertUtf8ToUtf16(lockFile, wlockFile);
|
||||
|
||||
// open the file in write mode, create it if necessary
|
||||
RsInitConfig::lockHandle = CreateFile(wlockFile.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
|
||||
if (RsInitConfig::lockHandle == INVALID_HANDLE_VALUE) {
|
||||
DWORD lasterror = GetLastError();
|
||||
|
||||
std::cerr << "Could not open lock file " << lockFile.c_str() << std::endl;
|
||||
std::cerr << "Last error: " << lasterror << std::endl << std::flush;
|
||||
perror(NULL);
|
||||
|
||||
if (lasterror == ERROR_SHARING_VIOLATION || lasterror == ERROR_ACCESS_DENIED) {
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
return RsDirUtil::createLockFile(lockFile,RsInitConfig::lockHandle) ;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1200,21 +1200,7 @@ int RsInit::LockConfigDirectory(const std::string& accountDir, std::string& lock
|
|||
*/
|
||||
void RsInit::UnlockConfigDirectory()
|
||||
{
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
if(RsInitConfig::lockHandle != -1)
|
||||
{
|
||||
close(RsInitConfig::lockHandle);
|
||||
RsInitConfig::lockHandle = -1;
|
||||
}
|
||||
#else
|
||||
if(RsInitConfig::lockHandle)
|
||||
{
|
||||
CloseHandle(RsInitConfig::lockHandle);
|
||||
RsInitConfig::lockHandle = NULL;
|
||||
}
|
||||
#endif
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
RsDirUtil::releaseLockFile(RsInitConfig::lockHandle) ;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2101,7 +2087,7 @@ int RsServer::StartupRetroShare()
|
|||
|
||||
/****** New Ft Server **** !!! */
|
||||
ftserver = new ftServer(mPeerMgr, mLinkMgr);
|
||||
ftserver->setP3Interface(pqih);
|
||||
ftserver->setP3Interface(pqih);
|
||||
ftserver->setConfigDirectory(RsInitConfig::configDir);
|
||||
|
||||
ftserver->SetupFtServer(&(getNotify()));
|
||||
|
@ -2299,7 +2285,7 @@ int RsServer::StartupRetroShare()
|
|||
|
||||
//mConfigMgr->addConfiguration("ftserver.cfg", ftserver);
|
||||
//
|
||||
mConfigMgr->addConfiguration("gpg_prefs.cfg", (AuthGPGimpl *) AuthGPG::getAuthGPG());
|
||||
mConfigMgr->addConfiguration("gpg_prefs.cfg", AuthGPG::getAuthGPG());
|
||||
mConfigMgr->loadConfiguration();
|
||||
|
||||
mConfigMgr->addConfiguration("peers.cfg", mPeerMgr);
|
||||
|
|
|
@ -635,23 +635,25 @@ bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile(const std::string& ssl_id
|
|||
return true ;
|
||||
}
|
||||
|
||||
sslPassphraseFile = RsDirUtil::rs_fopen(getSSLPasswdFileName(ssl_id).c_str(), "w");
|
||||
// sslPassphraseFile = RsDirUtil::rs_fopen(getSSLPasswdFileName(ssl_id).c_str(), "w");
|
||||
|
||||
if(sslPassphraseFile == NULL)
|
||||
{
|
||||
std::cerr << "RsLoginHandler::storeSSLPasswdIntoGPGFile(): could not write to file " << getSSLPasswdFileName(ssl_id) << std::endl;
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
std::cerr << "openned sslPassphraseFile : " << getSSLPasswdFileName(ssl_id) << std::endl;
|
||||
|
||||
gpgme_data_t cipher;
|
||||
gpgme_data_t plain;
|
||||
gpgme_data_new_from_mem(&plain, ssl_passwd.c_str(), ssl_passwd.length(), 1);
|
||||
gpgme_data_new_from_stream (&cipher, sslPassphraseFile);
|
||||
// if(sslPassphraseFile == NULL)
|
||||
// {
|
||||
// std::cerr << "RsLoginHandler::storeSSLPasswdIntoGPGFile(): could not write to file " << getSSLPasswdFileName(ssl_id) << std::endl;
|
||||
// return false ;
|
||||
// }
|
||||
// else
|
||||
// std::cerr << "openned sslPassphraseFile : " << getSSLPasswdFileName(ssl_id) << std::endl;
|
||||
//
|
||||
// gpgme_data_t cipher;
|
||||
// gpgme_data_t plain;
|
||||
// gpgme_data_new_from_mem(&plain, ssl_passwd.c_str(), ssl_passwd.length(), 1);
|
||||
// gpgme_data_new_from_stream (&cipher, sslPassphraseFile);
|
||||
|
||||
bool ok ;
|
||||
if (0 < AuthGPG::getAuthGPG()->encryptText(plain, cipher))
|
||||
std::string cipher ;
|
||||
|
||||
if(AuthGPG::getAuthGPG()->encryptTextToFile(ssl_passwd, getSSLPasswdFileName(ssl_id)))
|
||||
{
|
||||
std::cerr << "Encrypting went ok !" << std::endl;
|
||||
ok= true ;
|
||||
|
@ -662,10 +664,9 @@ bool RsLoginHandler::checkAndStoreSSLPasswdIntoGPGFile(const std::string& ssl_id
|
|||
ok= false ;
|
||||
}
|
||||
|
||||
gpgme_data_release (cipher);
|
||||
gpgme_data_release (plain);
|
||||
|
||||
fclose(sslPassphraseFile);
|
||||
// gpgme_data_release (cipher);
|
||||
// gpgme_data_release (plain);
|
||||
// fclose(sslPassphraseFile);
|
||||
|
||||
return ok ;
|
||||
}
|
||||
|
@ -682,34 +683,40 @@ bool RsLoginHandler::getSSLPasswdFromGPGFile(const std::string& ssl_id,std::stri
|
|||
std::cerr << "No password provided, and no sslPassphraseFile : " << getSSLPasswdFileName(ssl_id).c_str() << std::endl;
|
||||
return 0;
|
||||
}
|
||||
fclose(sslPassphraseFile);
|
||||
|
||||
std::cerr << "opening sslPassphraseFile : " << getSSLPasswdFileName(ssl_id).c_str() << std::endl;
|
||||
|
||||
gpgme_data_t cipher;
|
||||
gpgme_data_t plain;
|
||||
gpgme_data_new (&plain);
|
||||
// gpgme_data_t cipher;
|
||||
// gpgme_data_t plain;
|
||||
// gpgme_data_new (&plain);
|
||||
|
||||
if( gpgme_data_new_from_stream (&cipher, sslPassphraseFile) != GPG_ERR_NO_ERROR)
|
||||
{
|
||||
std::cerr << "Error while creating stream from ssl passwd file." << std::endl ;
|
||||
return 0 ;
|
||||
}
|
||||
if (0 < AuthGPG::getAuthGPG()->decryptText(cipher, plain))
|
||||
// if( gpgme_data_new_from_stream (&cipher, sslPassphraseFile) != GPG_ERR_NO_ERROR)
|
||||
// {
|
||||
// std::cerr << "Error while creating stream from ssl passwd file." << std::endl ;
|
||||
// return 0 ;
|
||||
// }
|
||||
|
||||
std::string plain ;
|
||||
|
||||
if (AuthGPG::getAuthGPG()->decryptTextFromFile(plain,getSSLPasswdFileName(ssl_id)))
|
||||
{
|
||||
std::cerr << "Decrypting went ok !" << std::endl;
|
||||
gpgme_data_write (plain, "", 1);
|
||||
sslPassword = std::string(gpgme_data_release_and_get_mem(plain, NULL));
|
||||
// gpgme_data_write (plain, "", 1);
|
||||
// sslPassword = std::string(gpgme_data_release_and_get_mem(plain, NULL));
|
||||
sslPassword = plain ;
|
||||
std::cerr << "sslpassword: " << "********************" << std::endl;
|
||||
gpgme_data_release (cipher);
|
||||
fclose(sslPassphraseFile);
|
||||
std::cerr << "sslpassword: \"" << sslPassword << "\"" << std::endl;
|
||||
// gpgme_data_release (cipher);
|
||||
// fclose(sslPassphraseFile);
|
||||
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
{
|
||||
gpgme_data_release (plain);
|
||||
gpgme_data_release (cipher);
|
||||
fclose(sslPassphraseFile);
|
||||
// gpgme_data_release (plain);
|
||||
// gpgme_data_release (cipher);
|
||||
// fclose(sslPassphraseFile);
|
||||
sslPassword = "" ;
|
||||
std::cerr << "Error : decrypting went wrong !" << std::endl;
|
||||
|
||||
|
|
|
@ -861,28 +861,6 @@ void p3disc::recvDiscReply(RsDiscReply *dri)
|
|||
|
||||
void p3disc::removeFriend(std::string /*ssl_id*/)
|
||||
{
|
||||
|
||||
// DON'T KNOW WHY SSL IDS were saved -> the results are never used
|
||||
#if 0
|
||||
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "p3disc::removeFriend() called for : " << ssl_id << std::endl;
|
||||
#endif
|
||||
//if we deleted the gpg_id, don't store the friend deletion as if we add back the gpg_id, we won't have the ssl friends back
|
||||
std::string gpg_id = rsPeers->getGPGId(ssl_id);
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "p3disc::removeFriend() gpg_id : " << gpg_id << std::endl;
|
||||
#endif
|
||||
if (gpg_id == AuthGPG::getAuthGPG()->getGPGOwnId() || rsPeers->isGPGAccepted(rsPeers->getGPGId(ssl_id))) {
|
||||
#ifdef P3DISC_DEBUG
|
||||
std::cerr << "p3disc::removeFriend() storing the friend deletion." << ssl_id << std::endl;
|
||||
#endif
|
||||
deletedSSLFriendsIds[ssl_id] = time(NULL);//just keep track of the deleted time
|
||||
IndicateConfigChanged();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*************************************************************************************/
|
||||
|
|
32
libretroshare/src/tests/pgp/Makefile
Normal file
32
libretroshare/src/tests/pgp/Makefile
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
RS_TOP_DIR = ../..
|
||||
DHT_TOP_DIR = ../../../../libbitdht/src
|
||||
OPENPGP_INCLUDE_DIR = ../../../../openpgpsdk/src
|
||||
|
||||
##### Define any flags that are needed for this section #######
|
||||
###############################################################
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/tests/scripts/config.mk
|
||||
###############################################################
|
||||
|
||||
TESTOBJ = test_pgp_handler.o test_pgp_signature_parsing.o test_key_parsing.o
|
||||
TESTS = test_pgp_handler test_pgp_signature_parsing test_key_parsing
|
||||
|
||||
#rsbaseitem_test
|
||||
|
||||
all: tests
|
||||
|
||||
test_pgp_handler : test_pgp_handler.o
|
||||
$(CC) $(CFLAGS) -o test_pgp_handler test_pgp_handler.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2
|
||||
|
||||
test_pgp_signature_parsing : test_pgp_signature_parsing.o
|
||||
$(CC) $(CFLAGS) -o test_pgp_signature_parsing test_pgp_signature_parsing.o $(OBJ) $(LIBS) -L../../../../openpgpsdk/src/lib/ -lops -lbz2
|
||||
|
||||
test_key_parsing : test_key_parsing.o
|
||||
$(CC) $(CFLAGS) -o test_key_parsing test_key_parsing.o ../../../../openpgpsdk/src/lib/libops.a -lssl -lcrypto -lbz2
|
||||
|
||||
###############################################################
|
||||
include $(RS_TOP_DIR)/scripts/rules.mk
|
||||
###############################################################
|
||||
|
814
libretroshare/src/tests/pgp/argstream.h
Normal file
814
libretroshare/src/tests/pgp/argstream.h
Normal file
|
@ -0,0 +1,814 @@
|
|||
/* Copyright (C) 2004 Xavier Décoret <Xavier.Decoret@imag.fr>
|
||||
*
|
||||
* argsteam is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Foobar 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Foobar; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef ARGSTREAM_H
|
||||
#define ARGSTREAM_H
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace
|
||||
{
|
||||
class argstream;
|
||||
|
||||
template<class T>
|
||||
class ValueHolder;
|
||||
|
||||
template <typename T>
|
||||
argstream& operator>> (argstream&, const ValueHolder<T>&);
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of ValueHolder<T>
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
template<class T>
|
||||
class ValueHolder
|
||||
{
|
||||
public:
|
||||
ValueHolder(char s,
|
||||
const char* l,
|
||||
T& b,
|
||||
const char* desc,
|
||||
bool mandatory);
|
||||
ValueHolder(const char* l,
|
||||
T& b,
|
||||
const char* desc,
|
||||
bool mandatory);
|
||||
ValueHolder(char s,
|
||||
T& b,
|
||||
const char* desc,
|
||||
bool mandatory);
|
||||
friend argstream& operator>><>(argstream& s,const ValueHolder<T>& v);
|
||||
std::string name() const;
|
||||
std::string description() const;
|
||||
private:
|
||||
std::string shortName_;
|
||||
std::string longName_;
|
||||
T* value_;
|
||||
T initialValue_;
|
||||
std::string description_;
|
||||
bool mandatory_;
|
||||
};
|
||||
template <class T>
|
||||
inline ValueHolder<T>
|
||||
parameter(char s,
|
||||
const char* l,
|
||||
T& b,
|
||||
const char* desc="",
|
||||
bool mandatory = true)
|
||||
{
|
||||
return ValueHolder<T>(s,l,b,desc,mandatory);
|
||||
}
|
||||
template <class T>
|
||||
inline ValueHolder<T>
|
||||
parameter(char s,
|
||||
T& b,
|
||||
const char* desc="",
|
||||
bool mandatory = true)
|
||||
{
|
||||
return ValueHolder<T>(s,b,desc,mandatory);
|
||||
}
|
||||
template <class T>
|
||||
inline ValueHolder<T>
|
||||
parameter(const char* l,
|
||||
T& b,
|
||||
const char* desc="",
|
||||
bool mandatory = true)
|
||||
{
|
||||
return ValueHolder<T>(l,b,desc,mandatory);
|
||||
}
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of OptionHolder
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
class OptionHolder
|
||||
{
|
||||
public:
|
||||
inline OptionHolder(char s,
|
||||
const char* l,
|
||||
bool& b,
|
||||
const char* desc);
|
||||
inline OptionHolder(const char* l,
|
||||
bool& b,
|
||||
const char* desc);
|
||||
inline OptionHolder(char s,
|
||||
bool& b,
|
||||
const char* desc);
|
||||
friend argstream& operator>>(argstream& s,const OptionHolder& v);
|
||||
inline std::string name() const;
|
||||
inline std::string description() const;
|
||||
protected:
|
||||
inline OptionHolder(char s,
|
||||
const char* l,
|
||||
const char* desc);
|
||||
friend OptionHolder help(char s='h',
|
||||
const char* l="help",
|
||||
const char* desc="Display this help");
|
||||
private:
|
||||
std::string shortName_;
|
||||
std::string longName_;
|
||||
bool* value_;
|
||||
std::string description_;
|
||||
};
|
||||
inline OptionHolder
|
||||
option(char s,
|
||||
const char* l,
|
||||
bool& b,
|
||||
const char* desc="")
|
||||
{
|
||||
return OptionHolder(s,l,b,desc);
|
||||
}
|
||||
inline OptionHolder
|
||||
option(char s,
|
||||
bool& b,
|
||||
const char* desc="")
|
||||
{
|
||||
return OptionHolder(s,b,desc);
|
||||
}
|
||||
inline OptionHolder
|
||||
option(const char* l,
|
||||
bool& b,
|
||||
const char* desc="")
|
||||
{
|
||||
return OptionHolder(l,b,desc);
|
||||
}
|
||||
inline OptionHolder
|
||||
help(char s,
|
||||
const char* l,
|
||||
const char* desc)
|
||||
{
|
||||
return OptionHolder(s,l,desc);
|
||||
}
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of ValuesHolder
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
template<class T,class O>
|
||||
class ValuesHolder
|
||||
{
|
||||
public:
|
||||
ValuesHolder(const O& o,
|
||||
const char* desc,
|
||||
int len);
|
||||
template<class A,class B> friend argstream& operator>>(argstream& s,const ValuesHolder<A,B>& v);
|
||||
std::string name() const;
|
||||
std::string description() const;
|
||||
typedef T value_type;
|
||||
private:
|
||||
mutable O value_;
|
||||
std::string description_;
|
||||
int len_;
|
||||
char letter_;
|
||||
};
|
||||
template<class T,class O>
|
||||
inline ValuesHolder<T,O>
|
||||
values(const O& o,
|
||||
const char* desc="",
|
||||
int len=-1)
|
||||
{
|
||||
return ValuesHolder<T,O>(o,desc,len);
|
||||
}
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of ValueParser
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
template <class T>
|
||||
class ValueParser
|
||||
{
|
||||
public:
|
||||
inline T operator()(const std::string& s) const
|
||||
{
|
||||
std::istringstream is(s);
|
||||
T t;
|
||||
is>>t;
|
||||
return t;
|
||||
}
|
||||
};
|
||||
// We need to specialize for string otherwise parsing of a value that
|
||||
// contains space (for example a string with space passed in quotes on the
|
||||
// command line) would parse only the first element of the value!!!
|
||||
template <>
|
||||
class ValueParser<std::string>
|
||||
{
|
||||
public:
|
||||
inline std::string operator()(const std::string& s) const
|
||||
{
|
||||
return s;
|
||||
}
|
||||
};
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
// Interface of argstream
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
class argstream
|
||||
{
|
||||
public:
|
||||
inline argstream(int argc,char** argv);
|
||||
inline argstream(const char* c);
|
||||
template<class T>
|
||||
friend argstream& operator>>(argstream& s,const ValueHolder<T>& v);
|
||||
friend inline argstream& operator>>(argstream& s,const OptionHolder& v);
|
||||
template<class T,class O>
|
||||
friend argstream& operator>>(argstream& s,const ValuesHolder<T,O>& v);
|
||||
|
||||
inline bool helpRequested() const;
|
||||
inline bool isOk() const;
|
||||
inline std::string errorLog() const;
|
||||
inline std::string usage() const;
|
||||
inline void defaultErrorHandling(bool ignoreUnused=false) const;
|
||||
static inline char uniqueLetter();
|
||||
protected:
|
||||
void parse(int argc,char** argv);
|
||||
private:
|
||||
typedef std::list<std::string>::iterator value_iterator;
|
||||
typedef std::pair<std::string,std::string> help_entry;
|
||||
std::string progName_;
|
||||
std::map<std::string,value_iterator> options_;
|
||||
std::list<std::string> values_;
|
||||
bool minusActive_;
|
||||
bool isOk_;
|
||||
std::deque<help_entry> argHelps_;
|
||||
std::string cmdLine_;
|
||||
std::deque<std::string> errors_;
|
||||
bool helpRequested_;
|
||||
};
|
||||
//************************************************************
|
||||
// Implementation of ValueHolder<T>
|
||||
//************************************************************
|
||||
template<class T>
|
||||
ValueHolder<T>::ValueHolder(char s,
|
||||
const char* l,
|
||||
T& v,
|
||||
const char* desc,
|
||||
bool mandatory)
|
||||
: shortName_(1,s),
|
||||
longName_(l),
|
||||
value_(&v),
|
||||
initialValue_(v),
|
||||
description_(desc),
|
||||
mandatory_(mandatory)
|
||||
{
|
||||
}
|
||||
template<class T>
|
||||
ValueHolder<T>::ValueHolder(const char* l,
|
||||
T& v,
|
||||
const char* desc,
|
||||
bool mandatory)
|
||||
: longName_(l),
|
||||
value_(&v),
|
||||
initialValue_(v),
|
||||
description_(desc),
|
||||
mandatory_(mandatory)
|
||||
{
|
||||
}
|
||||
template<class T>
|
||||
ValueHolder<T>::ValueHolder(char s,
|
||||
T& v,
|
||||
const char* desc,
|
||||
bool mandatory)
|
||||
: shortName_(1,s),
|
||||
value_(&v),
|
||||
initialValue_(v),
|
||||
description_(desc),
|
||||
mandatory_(mandatory)
|
||||
{
|
||||
}
|
||||
template<class T>
|
||||
std::string
|
||||
ValueHolder<T>::name() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
if (!shortName_.empty()) os<<'-'<<shortName_;
|
||||
if (!longName_.empty()) {
|
||||
if (!shortName_.empty()) os<<'/';
|
||||
os<<"--"<<longName_;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
template<class T>
|
||||
std::string
|
||||
ValueHolder<T>::description() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<description_;
|
||||
if (mandatory_)
|
||||
{
|
||||
os<<"(mandatory)";
|
||||
}
|
||||
else
|
||||
{
|
||||
os<<"(default="<<initialValue_<<")";
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
//************************************************************
|
||||
// Implementation of OptionHolder
|
||||
//************************************************************
|
||||
inline OptionHolder::OptionHolder(char s,
|
||||
const char* l,
|
||||
bool& b,
|
||||
const char* desc)
|
||||
: shortName_(1,s),
|
||||
longName_(l),
|
||||
value_(&b),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline OptionHolder::OptionHolder(const char* l,
|
||||
bool& b,
|
||||
const char* desc)
|
||||
: longName_(l),
|
||||
value_(&b),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline OptionHolder::OptionHolder(char s,
|
||||
bool& b,
|
||||
const char* desc)
|
||||
: shortName_(1,s),
|
||||
value_(&b),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline OptionHolder::OptionHolder(char s,
|
||||
const char* l,
|
||||
const char* desc)
|
||||
: shortName_(1,s),
|
||||
longName_(l),
|
||||
value_(NULL),
|
||||
description_(desc)
|
||||
{
|
||||
}
|
||||
inline std::string
|
||||
OptionHolder::name() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
if (!shortName_.empty()) os<<'-'<<shortName_;
|
||||
if (!longName_.empty())
|
||||
{
|
||||
if (!shortName_.empty()) os<<'/';
|
||||
os<<"--"<<longName_;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
inline std::string
|
||||
OptionHolder::description() const
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
//************************************************************
|
||||
// Implementation of ValuesHolder<T,O>
|
||||
//************************************************************
|
||||
template<class T,class O>
|
||||
ValuesHolder<T,O>::ValuesHolder(const O& o,
|
||||
const char* desc,
|
||||
int len)
|
||||
: value_(o),
|
||||
description_(desc),
|
||||
len_(len)
|
||||
{
|
||||
letter_ = argstream::uniqueLetter();
|
||||
}
|
||||
template <class T,class O>
|
||||
std::string
|
||||
ValuesHolder<T,O>::name() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<letter_<<"i";
|
||||
return os.str();
|
||||
}
|
||||
template <class T,class O>
|
||||
std::string
|
||||
ValuesHolder<T,O>::description() const
|
||||
{
|
||||
return description_;
|
||||
}
|
||||
//************************************************************
|
||||
// Implementation of argstream
|
||||
//************************************************************
|
||||
inline
|
||||
argstream::argstream(int argc,char** argv)
|
||||
: progName_(argv[0]),
|
||||
minusActive_(true),
|
||||
isOk_(true)
|
||||
{
|
||||
parse(argc,argv);
|
||||
}
|
||||
inline
|
||||
argstream::argstream(const char* c)
|
||||
: progName_(""),
|
||||
minusActive_(true),
|
||||
isOk_(true)
|
||||
{
|
||||
std::string s(c);
|
||||
// Build argc, argv from s. We must add a dummy first element for
|
||||
// progName because parse() expects it!!
|
||||
std::deque<std::string> args;
|
||||
args.push_back("");
|
||||
std::istringstream is(s);
|
||||
while (is.good())
|
||||
{
|
||||
std::string t;
|
||||
is>>t;
|
||||
args.push_back(t);
|
||||
}
|
||||
char* pargs[args.size()];
|
||||
char** p = pargs;
|
||||
for (std::deque<std::string>::const_iterator
|
||||
iter = args.begin();
|
||||
iter != args.end();++iter)
|
||||
{
|
||||
*p++ = const_cast<char*>(iter->c_str());
|
||||
}
|
||||
parse(args.size(),pargs);
|
||||
}
|
||||
inline void
|
||||
argstream::parse(int argc,char** argv)
|
||||
{
|
||||
// Run thru all arguments.
|
||||
// * it has -- in front : it is a long name option, if remainder is empty,
|
||||
// it is an error
|
||||
// * it has - in front : it is a sequence of short name options, if
|
||||
// remainder is empty, deactivates option (- will
|
||||
// now be considered a char).
|
||||
// * if any other char, or if option was deactivated
|
||||
// : it is a value. Values are split in parameters
|
||||
// (immediately follow an option) and pure values.
|
||||
// Each time a value is parsed, if the previously parsed argument was an
|
||||
// option, then the option is linked to the value in case of it is a
|
||||
// option with parameter. The subtle point is that when several options
|
||||
// are given with short names (ex: -abc equivalent to -a -b -c), the last
|
||||
// parsed option is -c).
|
||||
// Since we use map for option, any successive call overides the previous
|
||||
// one: foo -a -b -a hello is equivalent to foo -b -a hello
|
||||
// For values it is not true since we might have several times the same
|
||||
// value.
|
||||
value_iterator* lastOption = NULL;
|
||||
for (char** a = argv,**astop=a+argc;++a!=astop;)
|
||||
{
|
||||
std::string s(*a);
|
||||
if (minusActive_ && s[0] == '-')
|
||||
{
|
||||
if (s.size() > 1 && s[1] == '-')
|
||||
{
|
||||
if (s.size() == 2)
|
||||
{
|
||||
minusActive_ = false;
|
||||
continue;
|
||||
}
|
||||
lastOption = &(options_[s.substr(2)] = values_.end());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (s.size() > 1)
|
||||
{
|
||||
// Parse all chars, if it is a minus we have an error
|
||||
for (std::string::const_iterator cter = s.begin();
|
||||
++cter != s.end();)
|
||||
{
|
||||
if (*cter == '-')
|
||||
{
|
||||
isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"- in the middle of a switch "<<a;
|
||||
errors_.push_back(os.str());
|
||||
break;
|
||||
}
|
||||
lastOption = &(options_[std::string(1,*cter)] = values_.end());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isOk_ = false;
|
||||
errors_.push_back("Invalid argument -");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
values_.push_back(s);
|
||||
if (lastOption != NULL)
|
||||
{
|
||||
*lastOption = --values_.end();
|
||||
}
|
||||
lastOption = NULL;
|
||||
}
|
||||
}
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
for (std::map<std::string,value_iterator>::const_iterator
|
||||
iter = options_.begin();iter != options_.end();++iter)
|
||||
{
|
||||
std::cout<<"DEBUG: option "<<iter->first;
|
||||
if (iter->second != values_.end())
|
||||
{
|
||||
std::cout<<" -> "<<*(iter->second);
|
||||
}
|
||||
std::cout<<std::endl;
|
||||
}
|
||||
for (std::list<std::string>::const_iterator
|
||||
iter = values_.begin();iter != values_.end();++iter)
|
||||
{
|
||||
std::cout<<"DEBUG: value "<<*iter<<std::endl;
|
||||
}
|
||||
#endif // ARGSTREAM_DEBUG
|
||||
}
|
||||
inline bool
|
||||
argstream::isOk() const
|
||||
{
|
||||
return isOk_;
|
||||
}
|
||||
inline bool
|
||||
argstream::helpRequested() const
|
||||
{
|
||||
return helpRequested_;
|
||||
}
|
||||
inline std::string
|
||||
argstream::usage() const
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<"usage: "<<progName_<<cmdLine_<<'\n';
|
||||
unsigned int lmax = 0;
|
||||
for (std::deque<help_entry>::const_iterator
|
||||
iter = argHelps_.begin();iter != argHelps_.end();++iter)
|
||||
{
|
||||
if (lmax<iter->first.size()) lmax = iter->first.size();
|
||||
}
|
||||
for (std::deque<help_entry>::const_iterator
|
||||
iter = argHelps_.begin();iter != argHelps_.end();++iter)
|
||||
{
|
||||
os<<'\t'<<iter->first<<std::string(lmax-iter->first.size(),' ')
|
||||
<<" : "<<iter->second<<'\n';
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
inline std::string
|
||||
argstream::errorLog() const
|
||||
{
|
||||
std::string s;
|
||||
for(std::deque<std::string>::const_iterator iter = errors_.begin();
|
||||
iter != errors_.end();++iter)
|
||||
{
|
||||
s += *iter;
|
||||
s += '\n';
|
||||
}
|
||||
return s;
|
||||
}
|
||||
inline char
|
||||
argstream::uniqueLetter()
|
||||
{
|
||||
static unsigned int c = 'a';
|
||||
return c++;
|
||||
}
|
||||
template<class T>
|
||||
argstream&
|
||||
operator>>(argstream& s,const ValueHolder<T>& v)
|
||||
{
|
||||
// Search in the options if there is any such option defined either with a
|
||||
// short name or a long name. If both are found, only the last one is
|
||||
// used.
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
std::cout<<"DEBUG: searching "<<v.shortName_<<" "<<v.longName_<<std::endl;
|
||||
#endif
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
if (v.mandatory_)
|
||||
{
|
||||
if (!v.shortName_.empty())
|
||||
{
|
||||
s.cmdLine_ += " -";
|
||||
s.cmdLine_ += v.shortName_;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.cmdLine_ += " --";
|
||||
s.cmdLine_ += v.longName_;
|
||||
}
|
||||
s.cmdLine_ += " value";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!v.shortName_.empty())
|
||||
{
|
||||
s.cmdLine_ += " [-";
|
||||
s.cmdLine_ += v.shortName_;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.cmdLine_ += " [--";
|
||||
s.cmdLine_ += v.longName_;
|
||||
}
|
||||
s.cmdLine_ += " value]";
|
||||
|
||||
}
|
||||
std::map<std::string,argstream::value_iterator>::iterator iter =
|
||||
s.options_.find(v.shortName_);
|
||||
if (iter == s.options_.end())
|
||||
{
|
||||
iter = s.options_.find(v.longName_);
|
||||
}
|
||||
if (iter != s.options_.end())
|
||||
{
|
||||
// If we find counterpart for value holder on command line, either it
|
||||
// has an associated value in which case we assign it, or it has not, in
|
||||
// which case we have an error.
|
||||
if (iter->second != s.values_.end())
|
||||
{
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
std::cout<<"DEBUG: found value "<<*(iter->second)<<std::endl;
|
||||
#endif
|
||||
ValueParser<T> p;
|
||||
*(v.value_) = p(*(iter->second));
|
||||
// The option and its associated value are removed, the subtle thing
|
||||
// is that someother options might have this associated value too,
|
||||
// which we must invalidate.
|
||||
s.values_.erase(iter->second);
|
||||
for (std::map<std::string,argstream::value_iterator>::iterator
|
||||
jter = s.options_.begin();jter != s.options_.end();++jter)
|
||||
{
|
||||
if (jter->second == iter->second)
|
||||
{
|
||||
jter->second = s.values_.end();
|
||||
}
|
||||
}
|
||||
s.options_.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
s.isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"No value following switch "<<iter->first
|
||||
<<" on command line";
|
||||
s.errors_.push_back(os.str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v.mandatory_)
|
||||
{
|
||||
s.isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"Mandatory parameter ";
|
||||
if (!v.shortName_.empty()) os<<'-'<<v.shortName_;
|
||||
if (!v.longName_.empty())
|
||||
{
|
||||
if (!v.shortName_.empty()) os<<'/';
|
||||
os<<"--"<<v.longName_;
|
||||
}
|
||||
os<<" missing";
|
||||
s.errors_.push_back(os.str());
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
inline argstream&
|
||||
operator>>(argstream& s,const OptionHolder& v)
|
||||
{
|
||||
// Search in the options if there is any such option defined either with a
|
||||
// short name or a long name. If both are found, only the last one is
|
||||
// used.
|
||||
#ifdef ARGSTREAM_DEBUG
|
||||
std::cout<<"DEBUG: searching "<<v.shortName_<<" "<<v.longName_<<std::endl;
|
||||
#endif
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
{
|
||||
std::string c;
|
||||
if (!v.shortName_.empty())
|
||||
{
|
||||
c += " [-";
|
||||
c += v.shortName_;
|
||||
}
|
||||
else
|
||||
{
|
||||
c += " [--";
|
||||
c += v.longName_;
|
||||
}
|
||||
c += "]";
|
||||
s.cmdLine_ = c+s.cmdLine_;
|
||||
}
|
||||
std::map<std::string,argstream::value_iterator>::iterator iter =
|
||||
s.options_.find(v.shortName_);
|
||||
if (iter == s.options_.end())
|
||||
{
|
||||
iter = s.options_.find(v.longName_);
|
||||
}
|
||||
if (iter != s.options_.end())
|
||||
{
|
||||
// If we find counterpart for value holder on command line then the
|
||||
// option is true and if an associated value was found, it is ignored
|
||||
if (v.value_ != NULL)
|
||||
{
|
||||
*(v.value_) = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.helpRequested_ = true;
|
||||
}
|
||||
// The option only is removed
|
||||
s.options_.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v.value_ != NULL)
|
||||
{
|
||||
*(v.value_) = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.helpRequested_ = false;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
template<class T,class O>
|
||||
argstream&
|
||||
operator>>(argstream& s,const ValuesHolder<T,O>& v)
|
||||
{
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
{
|
||||
std::ostringstream os;
|
||||
os<<' '<<v.letter_<<'1';
|
||||
switch (v.len_)
|
||||
{
|
||||
case -1:
|
||||
os<<"...";
|
||||
break;
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
os<<"..."<<v.letter_<<v.len_;
|
||||
break;
|
||||
}
|
||||
s.cmdLine_ += os.str();
|
||||
}
|
||||
std::list<std::string>::iterator first = s.values_.begin();
|
||||
// We add to the iterator as much values as we can, limited to the length
|
||||
// specified (if different of -1)
|
||||
int n = v.len_ != -1?v.len_:s.values_.size();
|
||||
while (first != s.values_.end() && n-->0)
|
||||
{
|
||||
// Read the value from the string *first
|
||||
ValueParser<T> p;
|
||||
*(v.value_++) = p(*first );
|
||||
s.argHelps_.push_back(argstream::help_entry(v.name(),v.description()));
|
||||
// The value we just removed was maybe "remembered" by an option so we
|
||||
// remove it now.
|
||||
for (std::map<std::string,argstream::value_iterator>::iterator
|
||||
jter = s.options_.begin();jter != s.options_.end();++jter)
|
||||
{
|
||||
if (jter->second == first)
|
||||
{
|
||||
jter->second = s.values_.end();
|
||||
}
|
||||
}
|
||||
++first;
|
||||
}
|
||||
// Check if we have enough values
|
||||
if (n != 0)
|
||||
{
|
||||
s.isOk_ = false;
|
||||
std::ostringstream os;
|
||||
os<<"Expecting "<<v.len_<<" values";
|
||||
s.errors_.push_back(os.str());
|
||||
}
|
||||
// Erase the values parsed
|
||||
s.values_.erase(s.values_.begin(),first);
|
||||
return s;
|
||||
}
|
||||
inline void
|
||||
argstream::defaultErrorHandling(bool ignoreUnused) const
|
||||
{
|
||||
if (helpRequested_)
|
||||
{
|
||||
std::cout<<usage();
|
||||
exit(1);
|
||||
}
|
||||
if (!isOk_)
|
||||
{
|
||||
std::cerr<<errorLog();
|
||||
exit(1);
|
||||
}
|
||||
if (!ignoreUnused &&
|
||||
(!values_.empty() || !options_.empty()))
|
||||
{
|
||||
std::cerr<<"Unused arguments"<<std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // ARGSTREAM_H
|
||||
|
60
libretroshare/src/tests/pgp/test_key_parsing.cc
Normal file
60
libretroshare/src/tests/pgp/test_key_parsing.cc
Normal file
|
@ -0,0 +1,60 @@
|
|||
// COMPILE_LINE: g++ -o test_key_parsing test_key_parsing.cc -g -I../../../openpgpsdk/include -I../ -L../lib ../../../openpgpsdk/src/lib/libops.a -lssl -lcrypto -lbz2
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <openpgpsdk/std_print.h>
|
||||
#include <openpgpsdk/keyring_local.h>
|
||||
#include <openpgpsdk/util.h>
|
||||
}
|
||||
|
||||
#include "argstream.h"
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
try
|
||||
{
|
||||
// test PGPHandler
|
||||
//
|
||||
// 0 - init
|
||||
|
||||
bool armoured = false ;
|
||||
std::string keyfile ;
|
||||
|
||||
argstream as(argc,argv) ;
|
||||
|
||||
as >> parameter('i',"input-key",keyfile,"input key file.",true)
|
||||
>> option('a',"armoured",armoured,"input is armoured")
|
||||
>> help() ;
|
||||
|
||||
as.defaultErrorHandling() ;
|
||||
|
||||
ops_keyring_t *kr = (ops_keyring_t*)malloc(sizeof(ops_keyring_t)) ;
|
||||
kr->nkeys = 0 ;
|
||||
kr->nkeys_allocated = 0 ;
|
||||
kr->keys = 0 ;
|
||||
|
||||
if(ops_false == ops_keyring_read_from_file(kr,armoured, keyfile.c_str()))
|
||||
throw std::runtime_error("PGPHandler::readKeyRing(): cannot read key file. File corrupted, or missing/superfluous armour parameter.") ;
|
||||
|
||||
for(int i=0;i<kr->nkeys;++i)
|
||||
{
|
||||
ops_print_public_keydata(&kr->keys[i]) ;
|
||||
ops_print_public_keydata_verbose(&kr->keys[i]) ;
|
||||
ops_print_public_key(&kr->keys[i].key.pkey) ;
|
||||
}
|
||||
|
||||
ops_list_packets(const_cast<char *>(keyfile.c_str()),armoured,kr,NULL) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
catch(std::exception& e)
|
||||
{
|
||||
std::cerr << "Caught exception: " << e.what() << std::endl;
|
||||
return 1 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
155
libretroshare/src/tests/pgp/test_pgp_handler.cc
Normal file
155
libretroshare/src/tests/pgp/test_pgp_handler.cc
Normal file
|
@ -0,0 +1,155 @@
|
|||
// COMPILE_LINE: g++ -o test_pgp_handler test_pgp_handler.cc -I../../../openpgpsdk/include -I../ -L../lib -lretroshare ../../../libbitdht/src/lib/libbitdht.a ../../../openpgpsdk/lib/libops.a -lgnome-keyring -lupnp -lssl -lcrypto -lbz2
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <pgp/pgphandler.h>
|
||||
|
||||
static std::string passphrase_callback(void *data,const char *uid_info,const char *what,int prev_was_bad)
|
||||
{
|
||||
return std::string(getpass(what)) ;
|
||||
}
|
||||
|
||||
static std::string stringFromBytes(unsigned char *bytes,size_t len)
|
||||
{
|
||||
static const char out[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
|
||||
|
||||
std::string res ;
|
||||
|
||||
for(int j = 0; j < len; j++)
|
||||
{
|
||||
res += out[ (bytes[j]>>4) ] ;
|
||||
res += out[ bytes[j] & 0xf ] ;
|
||||
}
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
// test pgp ids.
|
||||
//
|
||||
PGPIdType id = PGPIdType(std::string("3e5b22140ef56abb")) ;
|
||||
|
||||
//std::cerr << "Id is : " << std::hex << id.toUInt64() << std::endl;
|
||||
std::cerr << "Id st : " << id.toStdString() << std::endl;
|
||||
|
||||
// test PGPHandler
|
||||
//
|
||||
// 0 - init
|
||||
|
||||
static const std::string pubring = "pubring.gpg" ;
|
||||
static const std::string secring = "secring.gpg" ;
|
||||
static const std::string trustdb = "trustdb.gpg" ;
|
||||
static const std::string lockfile = "lock" ;
|
||||
|
||||
PGPHandler::setPassphraseCallback(&passphrase_callback) ;
|
||||
PGPHandler pgph(pubring,secring,trustdb,lockfile) ;
|
||||
|
||||
// std::cerr << "Writing public keyring to file tmp_keyring.asc" << std::endl;
|
||||
// pgph.writePublicKeyring("tmp_keyring.asc") ;
|
||||
|
||||
pgph.printKeys() ;
|
||||
|
||||
std::cerr << std::endl ;
|
||||
std::cerr << std::endl ;
|
||||
|
||||
std::cerr << "Looking for keys with complete secret/public key pair: " << std::endl;
|
||||
|
||||
std::list<PGPIdType> lst ;
|
||||
pgph.availableGPGCertificatesWithPrivateKeys(lst) ;
|
||||
|
||||
for(std::list<PGPIdType>::const_iterator it(lst.begin());it!=lst.end();++it)
|
||||
std::cerr << "Found id : " << (*it).toStdString() << std::endl;
|
||||
|
||||
std::string email_str("test@gmail.com") ;
|
||||
std::string name_str("test") ;
|
||||
std::string passw_str("test00") ;
|
||||
|
||||
std::cerr << "Now generating a new PGP certificate: " << std::endl;
|
||||
std::cerr << " email: " << email_str << std::endl;
|
||||
std::cerr << " passw: " << passw_str << std::endl;
|
||||
std::cerr << " name : " << name_str << std::endl;
|
||||
|
||||
PGPIdType newid ;
|
||||
std::string errString ;
|
||||
|
||||
if(!pgph.GeneratePGPCertificate(name_str, email_str, passw_str, newid, errString))
|
||||
std::cerr << "Generation of certificate returned error: " << errString << std::endl;
|
||||
else
|
||||
std::cerr << "Certificate generation success. New id = " << newid.toStdString() << std::endl;
|
||||
|
||||
PGPIdType id2 = PGPIdType(std::string("618E54CF7670FF5E")) ;
|
||||
std::cerr << "Now extracting key " << id2.toStdString() << " from keyring:" << std::endl ;
|
||||
std::string cert = pgph.SaveCertificateToString(id2,false) ;
|
||||
|
||||
std::cerr << "Now, trying to re-read this cert from the string:" << std::endl;
|
||||
|
||||
PGPIdType id3 ;
|
||||
std::string error_string ;
|
||||
pgph.LoadCertificateFromString(cert,id3,error_string) ;
|
||||
|
||||
std::cerr << "Loaded cert id: " << id3.toStdString() << ", Error string=\"" << error_string << "\"" << std::endl;
|
||||
|
||||
std::cerr << cert << std::endl;
|
||||
|
||||
std::cerr << "Testing password callback: " << std::endl;
|
||||
|
||||
std::string pass = passphrase_callback(NULL,newid.toStdString().c_str(),"Please enter password: ",false) ;
|
||||
|
||||
std::cerr << "Password = \"" << pass << "\"" << std::endl;
|
||||
|
||||
std::cerr << "Testing signature with keypair " << newid.toStdString() << std::endl;
|
||||
|
||||
static const size_t BUFF_LEN = 25 ;
|
||||
unsigned char *test_bin = new unsigned char[BUFF_LEN] ;
|
||||
for(size_t i=0;i<BUFF_LEN;++i)
|
||||
test_bin[i] = rand()%26 + 'a' ;
|
||||
|
||||
std::cerr << "Text = \"" << std::string((char *)test_bin,BUFF_LEN) << "\"" << std::endl;
|
||||
|
||||
unsigned char sign[1000] ;
|
||||
uint32_t signlen = 1000 ;
|
||||
|
||||
if(!pgph.SignDataBin(newid,test_bin,BUFF_LEN,sign,&signlen))
|
||||
std::cerr << "Signature error." << std::endl;
|
||||
else
|
||||
std::cerr << "Signature success." << std::endl;
|
||||
|
||||
std::cerr << "Signature length: " << signlen << std::endl;
|
||||
std::cerr << "Signature: " << stringFromBytes(sign,signlen) << std::endl;
|
||||
std::cerr << "Now verifying signature..." << std::endl;
|
||||
|
||||
PGPFingerprintType fingerprint ;
|
||||
if(!pgph.getKeyFingerprint(newid,fingerprint) )
|
||||
std::cerr << "Cannot find fingerprint of key id " << newid.toStdString() << std::endl;
|
||||
|
||||
if(!pgph.VerifySignBin(test_bin,BUFF_LEN,sign,signlen,fingerprint))
|
||||
std::cerr << "Signature verification failed." << std::endl;
|
||||
else
|
||||
std::cerr << "Signature verification worked!" << std::endl;
|
||||
|
||||
delete[] test_bin ;
|
||||
|
||||
std::string outfile = "crypted_toto.pgp" ;
|
||||
std::string text_to_encrypt = "this is a secret message" ;
|
||||
|
||||
std::cerr << "Checking encrypted file creation: streaming chain \"" << text_to_encrypt << "\" to file " << outfile << " with key " << id2.toStdString() << std::endl;
|
||||
|
||||
if(!pgph.encryptTextToFile(id2,text_to_encrypt,outfile))
|
||||
std::cerr << "Encryption failed" << std::endl;
|
||||
else
|
||||
std::cerr << "Encryption success" << std::endl;
|
||||
|
||||
std::string decrypted_text = "" ;
|
||||
outfile = "crypted_toto2.pgp" ;
|
||||
|
||||
if(!pgph.decryptTextFromFile(id2,decrypted_text,outfile))
|
||||
std::cerr << "Decryption failed" << std::endl;
|
||||
else
|
||||
std::cerr << "Decryption success" << std::endl;
|
||||
|
||||
std::cerr << "Decrypted text: \"" << decrypted_text << "\"" << std::endl;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
49
libretroshare/src/tests/pgp/test_pgp_signature_parsing.cc
Normal file
49
libretroshare/src/tests/pgp/test_pgp_signature_parsing.cc
Normal file
|
@ -0,0 +1,49 @@
|
|||
// COMPILE_LINE: g++ -o test_pgp_signature_parsing test_pgp_signature_parsing.cc -g -I../../../openpgpsdk/include -I../ -L../lib -lretroshare ../../../libbitdht/src/lib/libbitdht.a ../../../openpgpsdk/lib/libops.a -lgnome-keyring -lupnp -lssl -lcrypto -lbz2
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <pgp/pgphandler.h>
|
||||
|
||||
static std::string passphrase_callback(void *data,const char *uid_info,const char *what,int prev_was_bad)
|
||||
{
|
||||
return std::string(getpass(what)) ;
|
||||
}
|
||||
|
||||
static std::string stringFromBytes(unsigned char *bytes,size_t len)
|
||||
{
|
||||
static const char out[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
|
||||
|
||||
std::string res ;
|
||||
|
||||
for(int j = 0; j < len; j++)
|
||||
{
|
||||
res += out[ (bytes[j]>>4) ] ;
|
||||
res += out[ bytes[j] & 0xf ] ;
|
||||
}
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
int main(int argc,char *argv[])
|
||||
{
|
||||
// test pgp ids.
|
||||
//
|
||||
PGPIdType id("3e5b22140ef56abb") ;
|
||||
|
||||
std::cerr << "Id st : " << id.toStdString() << std::endl;
|
||||
|
||||
// test PGPHandler
|
||||
//
|
||||
// 0 - init
|
||||
|
||||
static const std::string pubring = "pubring.gpg" ;
|
||||
static const std::string secring = "secring.gpg" ;
|
||||
static const std::string trustdb = "trustdb.gpg" ;
|
||||
static const std::string lockfil = "lock" ;
|
||||
|
||||
PGPHandler::setPassphraseCallback(&passphrase_callback) ;
|
||||
PGPHandler pgph(pubring,secring,trustdb,lockfil) ;
|
||||
|
||||
pgph.printKeys() ;
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ BITDIR = $(DHT_TOP_DIR)/lib
|
|||
LIBRS = $(LIBDIR)/libretroshare.a
|
||||
BITDHT = $(BITDIR)/libbitdht.a
|
||||
# Unix: Linux/Cygwin
|
||||
INCLUDE = -I $(RS_TOP_DIR)
|
||||
INCLUDE = -I $(RS_TOP_DIR) -I$(OPENPGP_INCLUDE_DIR)
|
||||
CFLAGS = -Wall -g $(INCLUDE)
|
||||
#CFLAGS += -fprofile-arcs -ftest-coverage
|
||||
CFLAGS += ${DEFINES}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
// Includes for directory creation.
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "util/rsdir.h"
|
||||
|
@ -848,6 +849,118 @@ std::string RsDirUtil::makePath(const std::string &path1, const std::string &pat
|
|||
return path;
|
||||
}
|
||||
|
||||
int RsDirUtil::createLockFile(const std::string& lock_file_path, rs_lock_handle_t &lock_handle)
|
||||
{
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
// Suspended. The user should make sure he's not already using the file descriptor.
|
||||
// if(lock_handle != -1)
|
||||
// close(lock_handle);
|
||||
|
||||
// open the file in write mode, create it if necessary, truncate it (it should be empty)
|
||||
lock_handle = open(lock_file_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
|
||||
if(lock_handle == -1)
|
||||
{
|
||||
std::cerr << "Could not open lock file " << lock_file_path.c_str() << std::flush;
|
||||
perror(NULL);
|
||||
return 2;
|
||||
}
|
||||
|
||||
// see "man fcntl" for the details, in short: non blocking lock creation on the whole file contents
|
||||
struct flock lockDetails;
|
||||
lockDetails.l_type = F_WRLCK;
|
||||
lockDetails.l_whence = SEEK_SET;
|
||||
lockDetails.l_start = 0;
|
||||
lockDetails.l_len = 0;
|
||||
|
||||
if(fcntl(lock_handle, F_SETLK, &lockDetails) == -1)
|
||||
{
|
||||
int fcntlErr = errno;
|
||||
std::cerr << "Could not request lock on file " << lock_file_path.c_str() << std::flush;
|
||||
perror(NULL);
|
||||
|
||||
// there's no lock so let's release the file handle immediately
|
||||
close(lock_handle);
|
||||
lock_handle = -1;
|
||||
|
||||
if(fcntlErr == EACCES || fcntlErr == EAGAIN)
|
||||
return 1;
|
||||
else
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
// Suspended. The user should make sure he's not already using the file descriptor.
|
||||
//
|
||||
// if (lock_handle) {
|
||||
// CloseHandle(lock_handle);
|
||||
// }
|
||||
|
||||
std::wstring wlockFile;
|
||||
librs::util::ConvertUtf8ToUtf16(lock_file_path, wlockFile);
|
||||
|
||||
// open the file in write mode, create it if necessary
|
||||
lock_handle = CreateFile(wlockFile.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
|
||||
if (lock_handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD lasterror = GetLastError();
|
||||
|
||||
std::cerr << "Could not open lock file " << lock_file_path.c_str() << std::endl;
|
||||
std::cerr << "Last error: " << lasterror << std::endl << std::flush;
|
||||
perror(NULL);
|
||||
|
||||
if (lasterror == ERROR_SHARING_VIOLATION || lasterror == ERROR_ACCESS_DENIED)
|
||||
return 1;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
}
|
||||
|
||||
void RsDirUtil::releaseLockFile(rs_lock_handle_t lockHandle)
|
||||
{
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
#ifndef WINDOWS_SYS
|
||||
if(lockHandle != -1)
|
||||
{
|
||||
close(lockHandle);
|
||||
lockHandle = -1;
|
||||
}
|
||||
#else
|
||||
if(lockHandle)
|
||||
{
|
||||
CloseHandle(lockHandle);
|
||||
lockHandle = 0;
|
||||
}
|
||||
#endif
|
||||
/******************************** WINDOWS/UNIX SPECIFIC PART ******************/
|
||||
}
|
||||
|
||||
RsStackFileLock::RsStackFileLock(const std::string& file_path)
|
||||
{
|
||||
while(RsDirUtil::createLockFile(file_path,_file_handle))
|
||||
{
|
||||
std::cerr << "Cannot acquire file lock " << file_path << ", waiting 1 sec." << std::endl;
|
||||
#ifdef WINDOWS_SYS
|
||||
Sleep(1000) ;
|
||||
#else
|
||||
sleep(1) ;
|
||||
#endif
|
||||
}
|
||||
std::cerr << "Acquired file handle " << _file_handle << ", lock file:" << file_path << std::endl;
|
||||
}
|
||||
RsStackFileLock::~RsStackFileLock()
|
||||
{
|
||||
RsDirUtil::releaseLockFile(_file_handle) ;
|
||||
std::cerr << "Released file lock with handle " << _file_handle << std::endl;
|
||||
}
|
||||
|
||||
#if 0 // NOT ENABLED YET!
|
||||
/************************* WIDE STRING ***************************/
|
||||
/************************* WIDE STRING ***************************/
|
||||
|
|
|
@ -36,6 +36,27 @@ class RsThread;
|
|||
|
||||
#include <retroshare/rstypes.h>
|
||||
|
||||
#ifndef WINDOWS_SYS
|
||||
typedef int rs_lock_handle_t;
|
||||
#else
|
||||
typedef /*HANDLE*/ void *rs_lock_handle_t;
|
||||
#endif
|
||||
|
||||
// This is a scope guard on a given file. Works like a mutex. Is blocking.
|
||||
// We could do that in another way: derive RsMutex into RsLockFileMutex, and
|
||||
// use RsStackMutex on it transparently. Only issue: this will cost little more
|
||||
// because of the multiple inheritance.
|
||||
//
|
||||
class RsStackFileLock
|
||||
{
|
||||
public:
|
||||
RsStackFileLock(const std::string& file_path) ;
|
||||
~RsStackFileLock() ;
|
||||
|
||||
private:
|
||||
rs_lock_handle_t _file_handle ;
|
||||
};
|
||||
|
||||
namespace RsDirUtil {
|
||||
|
||||
std::string getTopDir(const std::string&);
|
||||
|
@ -70,6 +91,15 @@ bool getFileHash(const std::string& filepath,std::string &hash, uint64_t &size
|
|||
|
||||
Sha1CheckSum sha1sum(uint8_t *data,uint32_t size) ;
|
||||
|
||||
// Creates a lock file with given path, and returns the lock handle
|
||||
// returns:
|
||||
// 0: Success
|
||||
// 1: Another instance already has the lock
|
||||
// 2 : Unexpected error
|
||||
int createLockFile(const std::string& lock_file_path, rs_lock_handle_t& lock_handle) ;
|
||||
|
||||
// Removes the lock file with specified handle.
|
||||
void releaseLockFile(rs_lock_handle_t lockHandle) ;
|
||||
|
||||
std::wstring getWideTopDir(std::wstring);
|
||||
std::wstring getWideRootDir(std::wstring);
|
||||
|
|
112
libretroshare/src/util/rsid.h
Normal file
112
libretroshare/src/util/rsid.h
Normal file
|
@ -0,0 +1,112 @@
|
|||
// This class aims at defining a generic ID type that is a list of bytes. It
|
||||
// can be converted into a hexadecial string for printing, mainly) or for
|
||||
// compatibility with old methods.
|
||||
//
|
||||
// To use this class, derive your own ID type from it. Examples include:
|
||||
//
|
||||
// class PGPIdType: public t_RsGenericIdType<8>
|
||||
// {
|
||||
// [..]
|
||||
// };
|
||||
//
|
||||
// class PGPFingerprintType: public t_RsGenericIdType<20>
|
||||
// {
|
||||
// [..]
|
||||
// };
|
||||
//
|
||||
// With this, there is no implicit conversion between subtypes, and therefore ID mixup
|
||||
// is impossible.
|
||||
//
|
||||
// A simpler way to make ID types is to
|
||||
// typedef t_RsGenericIdType<MySize> MyType ;
|
||||
//
|
||||
// ID Types with different lengths will be incompatible on compilation.
|
||||
//
|
||||
// Warning: never store references to a t_RsGenericIdType accross threads, since the
|
||||
// cached string convertion is not thread safe.
|
||||
//
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
template<uint32_t ID_SIZE_IN_BYTES> class t_RsGenericIdType
|
||||
{
|
||||
public:
|
||||
t_RsGenericIdType() {}
|
||||
virtual ~t_RsGenericIdType() {}
|
||||
|
||||
// Explicit constructor from a hexadecimal string
|
||||
//
|
||||
explicit t_RsGenericIdType(const std::string& hex_string) ;
|
||||
|
||||
// Explicit constructor from a byte array. The array should have size at least ID_SIZE_IN_BYTES
|
||||
//
|
||||
explicit t_RsGenericIdType(const unsigned char bytes[]) ;
|
||||
|
||||
// Converts to a std::string using cached value.
|
||||
//
|
||||
std::string toStdString() const ;
|
||||
const unsigned char *toByteArray() const { return &bytes[0] ; }
|
||||
static const uint32_t SIZE_IN_BYTES = ID_SIZE_IN_BYTES ;
|
||||
|
||||
bool operator==(const t_RsGenericIdType<ID_SIZE_IN_BYTES>& fp) const
|
||||
{
|
||||
for(uint32_t i=0;i<ID_SIZE_IN_BYTES;++i)
|
||||
if(fp.bytes[i] != bytes[i])
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
bool operator!=(const t_RsGenericIdType<ID_SIZE_IN_BYTES>& fp) const
|
||||
{
|
||||
return !operator==(fp) ;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char bytes[ID_SIZE_IN_BYTES] ;
|
||||
};
|
||||
|
||||
template<uint32_t ID_SIZE_IN_BYTES> std::string t_RsGenericIdType<ID_SIZE_IN_BYTES>::toStdString() const
|
||||
{
|
||||
static const char out[16] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' } ;
|
||||
|
||||
std::string res(ID_SIZE_IN_BYTES*2,' ') ;
|
||||
|
||||
for(uint32_t j = 0; j < ID_SIZE_IN_BYTES; j++)
|
||||
{
|
||||
res[2*j ] = out[ (bytes[j]>>4) ] ;
|
||||
res[2*j+1] = out[ bytes[j] & 0xf ] ;
|
||||
}
|
||||
|
||||
return res ;
|
||||
}
|
||||
|
||||
template<uint32_t ID_SIZE_IN_BYTES> t_RsGenericIdType<ID_SIZE_IN_BYTES>::t_RsGenericIdType(const std::string& s)
|
||||
{
|
||||
int n=0;
|
||||
if(s.length() != ID_SIZE_IN_BYTES*2)
|
||||
throw std::runtime_error("t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string in constructor has wrong size.") ;
|
||||
|
||||
for(uint32_t i = 0; i < ID_SIZE_IN_BYTES; ++i)
|
||||
{
|
||||
bytes[i] = 0 ;
|
||||
|
||||
for(int k=0;k<2;++k)
|
||||
{
|
||||
char b = s[n++] ;
|
||||
|
||||
if(b >= 'A' && b <= 'F')
|
||||
bytes[i] += (b-'A'+10) << 4*(1-k) ;
|
||||
else if(b >= 'a' && b <= 'f')
|
||||
bytes[i] += (b-'a'+10) << 4*(1-k) ;
|
||||
else if(b >= '0' && b <= '9')
|
||||
bytes[i] += (b-'0') << 4*(1-k) ;
|
||||
else
|
||||
throw std::runtime_error("t_RsGenericIdType<>::t_RsGenericIdType(std::string&): supplied string is not purely hexadecimal") ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<uint32_t ID_SIZE_IN_BYTES> t_RsGenericIdType<ID_SIZE_IN_BYTES>::t_RsGenericIdType(const unsigned char *mem)
|
||||
{
|
||||
memcpy(bytes,mem,ID_SIZE_IN_BYTES) ;
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue