exposed un-verified PGP signatures on GXS ids in GUI. Added auto-ban of GXS ids signed by a PGP ids that has already signed a large enough set of GXS ids. Still needs some GUI to change the threshold.

This commit is contained in:
csoler 2016-04-02 14:04:08 -04:00
parent 9a6bcf81d7
commit 9d9b790a3e
13 changed files with 336 additions and 74 deletions

View File

@ -66,6 +66,11 @@ bool PgpAuxUtilsImpl::getGPGAllList(std::list<RsPgpId> &ids)
return AuthGPG::getAuthGPG()->getGPGAllList(ids);
}
bool PgpAuxUtilsImpl::parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const
{
return AuthGPG::getAuthGPG()->parseSignature(sign,signlen,issuer);
}
bool PgpAuxUtilsImpl::askForDeferredSelfSignature(const void *data,
const uint32_t len,
unsigned char *sign,

View File

@ -41,10 +41,9 @@ class PgpAuxUtils
virtual bool getGPGAllList(std::list<RsPgpId> &ids) = 0;
virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const = 0;
virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const =0;
virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint) = 0;
virtual bool askForDeferredSelfSignature(const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,int& signature_result ) = 0;
};
class PgpAuxUtilsImpl: public PgpAuxUtils
@ -55,6 +54,7 @@ public:
virtual const RsPgpId &getPGPOwnId();
virtual RsPgpId getPGPId(const RsPeerId& sslid);
virtual bool parseSignature(unsigned char *sign, unsigned int signlen, RsPgpId& issuer) const ;
virtual bool getKeyFingerprint(const RsPgpId& id,PGPFingerprintType& fp) const;
virtual bool VerifySignBin(const void *data, uint32_t len, unsigned char *sign, unsigned int signlen, const PGPFingerprintType& withfingerprint);
virtual bool getGPGAllList(std::list<RsPgpId> &ids);

View File

@ -1692,6 +1692,24 @@ bool PGPHandler::mergeKeySignatures(ops_keydata_t *dst,const ops_keydata_t *src)
return to_add.size() > 0 ;
}
bool PGPHandler::parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id)
{
uint64_t issuer ;
if(!PGPKeyManagement::parseSignature(sign,signlen,issuer))
return false ;
unsigned char bytes[8] ;
for(int i=0;i<8;++i)
{
bytes[7-i] = issuer & 0xff ;
issuer >>= 8 ;
}
issuer_id = RsPgpId(bytes) ;
return true ;
}
bool PGPHandler::privateTrustCertificate(const RsPgpId& id,int trustlvl)
{
if(trustlvl < 0 || trustlvl >= 6 || trustlvl == 1)

View File

@ -74,7 +74,7 @@ class PGPHandler
bool haveSecretKey(const RsPgpId& id) const ;
bool importGPGKeyPair(const std::string& filename,RsPgpId& imported_id,std::string& import_error) ;
bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) ;
bool importGPGKeyPairFromString(const std::string& data,RsPgpId& imported_id,std::string& import_error) ;
bool exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_id) const ;
bool availableGPGCertificatesWithPrivateKeys(std::list<RsPgpId>& ids);
@ -85,6 +85,7 @@ class PGPHandler
std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ;
bool exportPublicKey(const RsPgpId& id,unsigned char *& mem,size_t& mem_size,bool armoured,bool include_signatures) const ;
bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ;
bool SignDataBin(const RsPgpId& id,const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen,bool make_raw_signature=false) ;
bool VerifySignBin(const void *data, uint32_t data_len, unsigned char *sign, unsigned int sign_len, const PGPFingerprintType& withfingerprint) ;
bool privateSignCertificate(const RsPgpId& own_id,const RsPgpId& id_of_key_to_sign) ;
@ -110,7 +111,7 @@ class PGPHandler
// Removes the given keys from the keyring. Also backup the keyring to a file which name is automatically generated
// and given pack for proper display.
//
bool removeKeysFromPGPKeyring(const std::set<RsPgpId>& key_ids,std::string& backup_file,uint32_t& error_code) ;
bool removeKeysFromPGPKeyring(const std::set<RsPgpId>& key_ids,std::string& backup_file,uint32_t& error_code) ;
//bool isKeySupported(const RsPgpId& id) const ;

View File

@ -157,7 +157,75 @@ uint32_t PGPKeyManagement::compute24bitsCRC(unsigned char *octets, size_t len)
crc ^= PGP_CRC24_POLY;
}
}
return crc & 0xFFFFFFL;
return crc & 0xFFFFFFL;
}
bool PGPKeyManagement::parseSignature(const unsigned char *signature, size_t sign_len, uint64_t& issuer)
{
unsigned char *data = (unsigned char *)signature ;
#ifdef DEBUG_PGPUTIL
std::cerr << "Total size: " << len << std::endl;
#endif
uint8_t packet_tag;
uint32_t packet_length ;
PGPKeyParser::read_packetHeader(data,packet_tag,packet_length) ;
std::cerr << "Packet tag : " << (int)packet_tag << ", length=" << packet_length << std::endl;
// 2 - parse key data, only keep public key data, user id and self-signature.
bool issuer_found=false ;
if(sign_len < 12) // conservative check to allow the explicit reads below, until header of first sub-packet
return false ;
unsigned char signature_type = data[0] ;
if(signature_type != 4)
return false ;
data += 1 ; // skip version number
data += 1 ; // skip signature type
data += 1 ; // skip public key algorithm
data += 1 ; // skip hash algorithm
uint32_t hashed_size = 256u*data[0] + data[1] ;
data += 2 ;
// now read hashed sub-packets
uint8_t *start_hashed_data = data ;
while(true)
{
int subpacket_size = PGPKeyParser::read_125Size(data) ; // following RFC4880
uint8_t subpacket_type = data[0] ; data+=1 ;
#ifdef DEBUG_PGPUTIL
std::cerr << " SubPacket tag: " << (int)subpacket_type << std::endl;
std::cerr << " SubPacket length: " << subpacket_size << std::endl;
#endif
if(subpacket_type == PGPKeyParser::PGP_PACKET_TAG_ISSUER && subpacket_size == 9)
{
issuer_found = true ;
issuer = PGPKeyParser::read_KeyID(data) ;
}
else
data += subpacket_size-1 ; // we remove the size of subpacket type
if(issuer_found)
break ;
if( (uint64_t)data - (uint64_t)start_hashed_data >= hashed_size )
break ;
}
// non hashed sub-packets are ignored for now.
return issuer_found ;
}
uint64_t PGPKeyParser::read_KeyID(unsigned char *& data)

View File

@ -65,6 +65,8 @@ class PGPKeyManagement
// Computes the 24 bits CRC checksum necessary to all PGP data.
//
static uint32_t compute24bitsCRC(unsigned char *data,size_t len) ;
static bool parseSignature(const unsigned char *signature, size_t sign_len, uint64_t &issuer) ;
};
// This class handles the parsing of PGP packet headers under various (old and new) formats.
@ -75,6 +77,7 @@ class PGPKeyParser
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 const uint8_t PGP_PACKET_TAG_ISSUER = 16 ;
// These functions read and move the data pointer to the next byte after the read section.
//

View File

@ -308,6 +308,11 @@ bool AuthGPG::VerifySignature(const void *data, int datalen, const void *sig, un
return PGPHandler::VerifySignBin((unsigned char*)data,datalen,(unsigned char*)sig,siglen,withfingerprint) ;
}
bool AuthGPG::parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id)
{
return PGPHandler::parseSignature((unsigned char*)sig,siglen,issuer_id) ;
}
bool AuthGPG::exportProfile(const std::string& fname,const RsPgpId& exported_id)
{
return PGPHandler::exportGPGKeyPair(fname,exported_id) ;

View File

@ -210,6 +210,7 @@ class AuthGPG: public p3Config, public RsTickingThread, public PGPHandler
****/
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 PGPFingerprintType& withfingerprint);
virtual bool parseSignature(const void *sig, unsigned int siglen, RsPgpId& issuer_id);
virtual bool encryptDataBin(const RsPgpId& pgp_id,const void *data, const uint32_t len, unsigned char *encr, unsigned int *encrlen);
virtual bool decryptDataBin(const void *data, const uint32_t len, unsigned char *decr, unsigned int *decrlen);

View File

@ -30,6 +30,7 @@
#include "services/p3gxsreputation.h"
#include "serialiser/rsgxsreputationitems.h"
#include "serialiser/rsconfigitems.h"
#include <sys/time.h>
@ -38,6 +39,7 @@
/****
* #define DEBUG_REPUTATION 1
****/
#define DEBUG_REPUTATION 1
/************ IMPLEMENTATION NOTES *********************************
*
@ -134,7 +136,9 @@ static const int ACTIVE_FRIENDS_ONLINE_DELAY = 86400*7 ; // 1 week.
static const int kReputationRequestPeriod = 600; // 10 mins
static const int kReputationStoreWait = 180; // 3 minutes.
static const float REPUTATION_ASSESSMENT_THRESHOLD_X1 = 0.5f ; // reputation under which the peer gets killed
static const uint32_t PGP_AUTO_BAN_THRESHOLD_DEFAULT = 2 ; // above this, auto ban any GXS id signed by this node
static const uint32_t IDENTITY_FLAGS_UPDATE_DELAY = 100 ; //
static const uint32_t BANNED_NODES_UPDATE_DELAY = 613 ; // update approx every 10 mins. Chosen to not be a multiple of IDENTITY_FLAGS_UPDATE_DELAY
p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
:p3Service(), p3Config(),
@ -142,11 +146,13 @@ p3GxsReputation::p3GxsReputation(p3LinkMgr *lm)
{
addSerialType(new RsGxsReputationSerialiser());
mPgpAutoBanThreshold = PGP_AUTO_BAN_THRESHOLD_DEFAULT ;
mRequestTime = 0;
mStoreTime = 0;
mReputationsUpdated = false;
mLastActiveFriendsUpdate = 0 ;
mAverageActiveFriends = 0 ;
mLastBannedNodesUpdate = 0 ;
}
const std::string GXS_REPUTATION_APP_NAME = "gxsreputation";
@ -181,15 +187,22 @@ int p3GxsReputation::tick()
}
static time_t last_identity_flags_update = 0 ;
static time_t last_banned_nodes_update = 0 ;
// no more than once per 5 second chunk.
if(now > 100+last_identity_flags_update)
if(now > IDENTITY_FLAGS_UPDATE_DELAY+last_identity_flags_update)
{
last_identity_flags_update = now ;
updateIdentityFlags() ;
}
if(now > BANNED_NODES_UPDATE_DELAY+mLastBannedNodesUpdate) // 613 is not a multiple of 100, to avoid piling up work
{
mLastBannedNodesUpdate = now ;
updateBannedNodesList();
}
#ifdef DEBUG_REPUTATION
static time_t last_debug_print = time(NULL) ;
@ -203,10 +216,64 @@ int p3GxsReputation::tick()
return 0;
}
void p3GxsReputation::setNodeAutoBanThreshold(uint32_t n)
{
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
if(n != mPgpAutoBanThreshold)
{
mLastBannedNodesUpdate = 0 ;
mPgpAutoBanThreshold = n ;
IndicateConfigChanged() ;
}
}
uint32_t p3GxsReputation::nodeAutoBanThreshold()
{
return mPgpAutoBanThreshold ;
}
int p3GxsReputation::status()
{
return 1;
}
class ZeroInitCnt
{
public:
ZeroInitCnt(): cnt(0) {}
uint32_t cnt ;
operator uint32_t& () { return cnt ; }
operator uint32_t() const { return cnt ; }
};
void p3GxsReputation::updateBannedNodesList()
{
#ifdef DEBUG_REPUTATION
std::cerr << "Updating PGP ban list based on signed GxsIds to ban" << std::endl;
#endif
std::map<RsGxsId, Reputation> tmpreps ;
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
tmpreps = mReputations ;
std::map<RsPgpId,ZeroInitCnt> pgp_ids_to_ban ;
for( std::map<RsGxsId, Reputation>::iterator rit = tmpreps.begin();rit!=tmpreps.end();++rit)
if((rit->second.mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) && rit->second.mOwnOpinion == p3GxsReputation::OPINION_NEGATIVE)
++pgp_ids_to_ban[rit->second.mOwnerNode] ;
mBannedPgpIds.clear() ;
if(mPgpAutoBanThreshold > 0)
for(std::map<RsPgpId,ZeroInitCnt>::const_iterator it(pgp_ids_to_ban.begin());it!=pgp_ids_to_ban.end();++it)
{
#ifdef DEBUG_REPUTATION
std::cerr << "PGP Id: " << it->first << ". Ban count=" << it->second << " - " << (( it->second >= mPgpAutoBanThreshold)?"Banned!":"OK" ) << std::endl;
#endif
if(it->second >= mPgpAutoBanThreshold)
mBannedPgpIds.insert(it->first) ;
}
}
void p3GxsReputation::updateIdentityFlags()
{
@ -248,7 +315,11 @@ void p3GxsReputation::updateIdentityFlags()
}
it->second.mIdentityFlags = 0 ;
if(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ;
if(details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)
{
it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_LINKED ;
it->second.mOwnerNode = details.mPgpId ;
}
if(details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN ) it->second.mIdentityFlags |= REPUTATION_IDENTITY_FLAG_PGP_KNOWN ;
#ifdef DEBUG_REPUTATION
@ -614,6 +685,13 @@ bool p3GxsReputation::getReputationInfo(const RsGxsId& gxsid, RsReputations::Rep
info.mOverallReputationScore = rep.mReputation ;
info.mFriendAverage = rep.mFriendAverage ;
if( (rep.mIdentityFlags & REPUTATION_IDENTITY_FLAG_PGP_LINKED) && (mBannedPgpIds.find(rep.mOwnerNode) != mBannedPgpIds.end()))
{
info.mAssessment = RsReputations::ASSESSMENT_BAD ;
std::cerr << "p3GxsReputations: identity " << gxsid << " is banned because owner node ID " << rep.mOwnerNode << " is banned." << std::endl;
return true;
}
if(info.mOverallReputationScore > REPUTATION_ASSESSMENT_THRESHOLD_X1)
info.mAssessment = RsReputations::ASSESSMENT_OK ;
else
@ -693,6 +771,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
mUpdated.insert(std::make_pair(now, gxsid));
mUpdatedReputations.insert(gxsid);
mReputationsUpdated = true;
mLastBannedNodesUpdate = 0 ; // for update of banned nodes
// Switched to periodic save due to scale of data.
IndicateConfigChanged();
@ -709,6 +788,7 @@ RsSerialiser *p3GxsReputation::setupSerialiser()
{
RsSerialiser *rss = new RsSerialiser ;
rss->addSerialType(new RsGxsReputationSerialiser());
rss->addSerialType(new RsGeneralConfigSerialiser());
return rss ;
}
@ -757,6 +837,15 @@ bool p3GxsReputation::saveList(bool& cleanup, std::list<RsItem*> &savelist)
savelist.push_back(item);
count++;
}
RsConfigKeyValueSet *vitem = new RsConfigKeyValueSet ;
RsTlvKeyValue kv;
kv.key = "AUTO_BAN_NODES_THRESHOLD" ;
rs_sprintf(kv.value, "%d", mPgpAutoBanThreshold);
vitem->tlvkvs.pairs.push_back(kv) ;
savelist.push_back(vitem) ;
return true;
}
@ -770,35 +859,52 @@ bool p3GxsReputation::loadList(std::list<RsItem *>& loadList)
#ifdef DEBUG_REPUTATION
std::cerr << "p3GxsReputation::saveList()" << std::endl;
#endif
std::list<RsItem *>::iterator it;
std::set<RsPeerId> peerSet;
std::list<RsItem *>::iterator it;
std::set<RsPeerId> peerSet;
for(it = loadList.begin(); it != loadList.end(); ++it)
{
RsGxsReputationConfigItem *item = dynamic_cast<RsGxsReputationConfigItem *>(*it);
for(it = loadList.begin(); it != loadList.end(); ++it)
{
RsGxsReputationConfigItem *item = dynamic_cast<RsGxsReputationConfigItem *>(*it);
// Configurations are loaded first. (to establish peerSet).
if (item)
{
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
RsPeerId peerId(item->mPeerId);
ReputationConfig &config = mConfig[peerId];
config.mPeerId = peerId;
config.mLatestUpdate = item->mLatestUpdate;
config.mLastQuery = 0;
// Configurations are loaded first. (to establish peerSet).
if (item)
{
RsStackMutex stack(mReputationMtx); /****** LOCKED MUTEX *******/
RsPeerId peerId(item->mPeerId);
ReputationConfig &config = mConfig[peerId];
config.mPeerId = peerId;
config.mLatestUpdate = item->mLatestUpdate;
config.mLastQuery = 0;
peerSet.insert(peerId);
}
peerSet.insert(peerId);
}
RsGxsReputationSetItem *set = dynamic_cast<RsGxsReputationSetItem *>(*it);
if (set)
loadReputationSet(set, peerSet);
RsGxsReputationSetItem *set = dynamic_cast<RsGxsReputationSetItem *>(*it);
if (set)
loadReputationSet(set, peerSet);
delete (*it);
}
RsConfigKeyValueSet *vitem = dynamic_cast<RsConfigKeyValueSet *>(*it);
if(vitem)
for(std::list<RsTlvKeyValue>::const_iterator kit = vitem->tlvkvs.pairs.begin(); kit != vitem->tlvkvs.pairs.end(); ++kit)
{
if(kit->key == "AUTO_BAN_NODES_THRESHOLD")
{
int val ;
if (sscanf(kit->value.c_str(), "%d", &val) == 1)
{
mPgpAutoBanThreshold = val ;
std::cerr << "Setting AutoBanNode threshold to " << val << std::endl ;
mLastBannedNodesUpdate = 0 ; // force update
}
};
}
delete (*it);
}
loadList.clear() ;
return true;
return true;
}
bool p3GxsReputation::loadReputationSet(RsGxsReputationSetItem *item, const std::set<RsPeerId> &peerSet)

View File

@ -76,6 +76,8 @@ public:
float mFriendAverage ;
float mReputation;
RsPgpId mOwnerNode;
uint32_t mIdentityFlags;
};
@ -97,6 +99,9 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations /
virtual bool setOwnOpinion(const RsGxsId& key_id, const Opinion& op) ;
virtual bool getReputationInfo(const RsGxsId& id,ReputationInfo& info) ;
virtual bool isIdentityBanned(const RsGxsId& id) ;
virtual void setNodeAutoBanThreshold(uint32_t n) ;
virtual uint32_t nodeAutoBanThreshold() ;
/***** overloaded from p3Service *****/
virtual int tick();
@ -111,8 +116,8 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations /
virtual bool saveList(bool& cleanup, std::list<RsItem*>&) ;
virtual void saveDone();
virtual bool loadList(std::list<RsItem*>& load) ;
private:
private:
bool processIncoming();
@ -120,6 +125,7 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations /
bool RecvReputations(RsGxsReputationUpdateItem *item);
bool updateLatestUpdate(RsPeerId peerid, time_t latest_update);
void updateActiveFriends() ;
void updateBannedNodesList();
// internal update of data. Takes care of cleaning empty boxes.
void locked_updateOpinion(const RsPeerId &from, const RsGxsId &about, RsReputations::Opinion op);
@ -138,6 +144,7 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations /
time_t mLastActiveFriendsUpdate;
time_t mRequestTime;
time_t mStoreTime;
time_t mLastBannedNodesUpdate ;
bool mReputationsUpdated;
uint32_t mAverageActiveFriends ;
@ -149,7 +156,11 @@ class p3GxsReputation: public p3Service, public p3Config, public RsReputations /
std::multimap<time_t, RsGxsId> mUpdated;
// set of Reputations to send to p3IdService.
std::set<RsGxsId> mUpdatedReputations;
std::set<RsGxsId> mUpdatedReputations;
// PGP Ids auto-banned. This is updated regularly.
std::set<RsPgpId> mBannedPgpIds ;
uint32_t mPgpAutoBanThreshold ;
};
#endif //SERVICE_RSGXSREPUTATION_HEADER

View File

@ -59,6 +59,7 @@
#define GXSID_MAX_CACHE_SIZE 5000
static const uint32_t MAX_KEEP_UNUSED_KEYS = 30*86400 ; // remove unused keys after 30 days
static const uint32_t MAX_KEEP_BANNED_KEYS = 30*86400 ; // remove banned keys after 5 days
static const uint32_t MAX_DELAY_BEFORE_CLEANING = 601 ; // clean old keys every 10 mins
RsIdentity *rsIdentity = NULL;
@ -312,21 +313,25 @@ void p3IdService::cleanUnusedKeys()
// we need to stash all ids to delete into an off-mutex structure since deleteIdentity() will trigger the lock
{
RS_STACK_MUTEX(mIdMtx) ;
RS_STACK_MUTEX(mIdMtx) ;
if(!mOwnIdsLoaded)
{
std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl;
return ;
}
if(!mOwnIdsLoaded)
{
std::cerr << "(EE) Own ids not loaded. Cannot clean unused keys." << std::endl;
return ;
}
// grab at most 10 identities to delete. No need to send too many requests to the token queue at once.
time_t now = time(NULL) ;
int n=0 ;
// grab at most 10 identities to delete. No need to send too many requests to the token queue at once.
time_t now = time(NULL) ;
int n=0 ;
for(std::map<RsGxsId,time_t>::iterator it(mKeysTS.begin());it!=mKeysTS.end() && n < 10;++it)
if(it->second + MAX_KEEP_UNUSED_KEYS < now && std::find(mOwnIds.begin(),mOwnIds.end(),it->first) == mOwnIds.end())
ids_to_delete.push_back(it->first),++n ;
for(std::map<RsGxsId,time_t>::iterator it(mKeysTS.begin());it!=mKeysTS.end() && n < 10;++it)
{
if(it->second + MAX_KEEP_UNUSED_KEYS < now && std::find(mOwnIds.begin(),mOwnIds.end(),it->first) == mOwnIds.end())
ids_to_delete.push_back(it->first),++n ;
else if(it->second + MAX_KEEP_BANNED_KEYS < now && rsReputations->isIdentityBanned(it->first))
ids_to_delete.push_back(it->first),++n ;
}
}
for(std::list<RsGxsId>::const_iterator it(ids_to_delete.begin());it!=ids_to_delete.end();++it)
@ -1023,7 +1028,7 @@ bool p3IdService::opinion_handlerequest(uint32_t token)
// update IdScore too.
bool pgpId = (meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.idKnown);
ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.validatedSignature);
ssdata.score.rep.update();
/* save string */
@ -1089,7 +1094,7 @@ bool p3IdService::getGroupData(const uint32_t &token, std::vector<RsGxsIdGroup>
SSGxsIdGroup ssdata;
if (ssdata.load(group.mMeta.mServiceString))
{
group.mPgpKnown = ssdata.pgp.idKnown;
group.mPgpKnown = ssdata.pgp.validatedSignature;
group.mPgpId = ssdata.pgp.pgpId;
group.mReputation = ssdata.score.rep;
#ifdef DEBUG_IDS
@ -1282,7 +1287,16 @@ bool SSGxsIdPgp::load(const std::string &input)
uint32_t attempts = 0;
if (1 == sscanf(input.c_str(), "K:1 I:%[^)]", pgpline))
{
idKnown = true;
validatedSignature = true;
std::string str_line = pgpline;
pgpId = RsPgpId(str_line);
return true;
}
else if (3 == sscanf(input.c_str(), "K:0 T:%d C:%d I:%[^)]", &timestamp, &attempts,pgpline))
{
lastCheckTs = timestamp;
checkAttempts = attempts;
validatedSignature = false;
std::string str_line = pgpline;
pgpId = RsPgpId(str_line);
return true;
@ -1291,21 +1305,21 @@ bool SSGxsIdPgp::load(const std::string &input)
{
lastCheckTs = timestamp;
checkAttempts = attempts;
idKnown = false;
validatedSignature = false;
return true;
}
else if (1 == sscanf(input.c_str(), "K:0 T:%d", &timestamp))
{
lastCheckTs = timestamp;
checkAttempts = 0;
idKnown = false;
validatedSignature = false;
return true;
}
else
{
lastCheckTs = 0;
checkAttempts = 0;
idKnown = false;
validatedSignature = false;
return false;
}
}
@ -1313,7 +1327,7 @@ bool SSGxsIdPgp::load(const std::string &input)
std::string SSGxsIdPgp::save() const
{
std::string output;
if (idKnown)
if (validatedSignature)
{
output += "K:1 I:";
output += pgpId.toStdString();
@ -1321,6 +1335,9 @@ std::string SSGxsIdPgp::save() const
else
{
rs_sprintf(output, "K:0 T:%d C:%d", lastCheckTs, checkAttempts);
if(!pgpId.isNull())
output += " I:"+pgpId.toStdString();
}
return output;
}
@ -1663,9 +1680,9 @@ void RsGxsIdCache::updateServiceString(std::string serviceString)
{
if (details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)
{
if(ssdata.pgp.idKnown) details.mFlags |= RS_IDENTITY_FLAGS_PGP_KNOWN ;
if(ssdata.pgp.validatedSignature) details.mFlags |= RS_IDENTITY_FLAGS_PGP_KNOWN ;
if (details.mFlags & RS_IDENTITY_FLAGS_PGP_KNOWN)
if (details.mFlags & RS_IDENTITY_FLAGS_PGP_LINKED)
details.mPgpId = ssdata.pgp.pgpId;
else
details.mPgpId.clear();
@ -2800,7 +2817,7 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
SSGxsIdGroup ssdata;
if (ssdata.load(vit->mMeta.mServiceString))
{
if (ssdata.pgp.idKnown)
if (ssdata.pgp.validatedSignature)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() discarding Already Known";
@ -2919,7 +2936,7 @@ bool p3IdService::pgphash_process()
#endif // DEBUG_IDS
/* update */
ssdata.pgp.idKnown = true;
ssdata.pgp.validatedSignature = true;
ssdata.pgp.pgpId = pgpId;
}
@ -2939,12 +2956,13 @@ bool p3IdService::pgphash_process()
ssdata.pgp.lastCheckTs = time(NULL);
ssdata.pgp.checkAttempts++;
ssdata.pgp.pgpId = pgpId; // read from the signature, but not verified
}
if(!error)
{
// update IdScore too.
ssdata.score.rep.updateIdScore(true, ssdata.pgp.idKnown);
ssdata.score.rep.updateIdScore(true, ssdata.pgp.validatedSignature);
ssdata.score.rep.update();
/* set new Group ServiceString */
@ -2981,6 +2999,24 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, RsPgpId &pgpId,bool& error)
/* iterate through and check hash */
Sha1CheckSum ans = grp.mPgpIdHash;
#ifdef DEBUG_IDS
std::string esign ;
Radix64::encode((char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),esign) ;
std::cerr << "Checking group signature " << esign << std::endl;
#endif
RsPgpId issuer_id ;
if(mPgpUtils->parseSignature((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),issuer_id))
{
std::cerr << "Issuer found: " << issuer_id << std::endl;
pgpId = issuer_id ;
}
else
{
std::cerr << "Signature parsing failed!!" << std::endl;
pgpId.clear() ;
}
#ifdef DEBUG_IDS
std::cerr << "\tExpected Answer: " << ans.toStdString();
@ -2995,6 +3031,7 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, RsPgpId &pgpId,bool& error)
Sha1CheckSum hash;
calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash);
if (ans == hash)
{
#ifdef DEBUG_IDS
@ -3342,7 +3379,7 @@ bool p3IdService::recogn_process()
// update IdScore too.
bool pgpId = (item->meta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.idKnown);
ssdata.score.rep.updateIdScore(pgpId, ssdata.pgp.validatedSignature);
ssdata.score.rep.update();
/* set new Group ServiceString */

View File

@ -100,12 +100,12 @@ class SSGxsIdPgp: public SSBit
{
public:
SSGxsIdPgp()
:idKnown(false), lastCheckTs(0), checkAttempts(0) { return; }
:validatedSignature(false), lastCheckTs(0), checkAttempts(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
bool idKnown;
bool validatedSignature;
time_t lastCheckTs;
uint32_t checkAttempts;
RsPgpId pgpId;

View File

@ -901,12 +901,13 @@ bool IdDialog::fillIdListItem(const RsGxsIdGroup& data, QTreeWidgetItem *&item,
tooltip += tr("Node Id :")+" " + QString::fromStdString(data.mPgpId.toStdString()) ;
item->setToolTip(RSID_COL_KEYID,tooltip) ;
}
else
else
{
item->setText(RSID_COL_IDTYPE, tr("Unknown PGP key"));
item->setToolTip(RSID_COL_IDTYPE,tr("Unknown key ID")) ;
item->setToolTip(RSID_COL_KEYID,tr("Unknown key ID")) ;
QString txt = tr("[Unknown node]");
item->setText(RSID_COL_IDTYPE, txt);
item->setToolTip(RSID_COL_IDTYPE,tr("Unverified signature from ")+QString::fromStdString(data.mPgpId.toStdString())) ;
item->setToolTip(RSID_COL_KEYID,tr("Unverified signature from ")+QString::fromStdString(data.mPgpId.toStdString())) ;
}
}
else
@ -1081,7 +1082,10 @@ void IdDialog::insertIdDetails(uint32_t token)
ui->lineEdit_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()).left(RSID_MAXIMUM_NICKNAME_SIZE));
ui->lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId.toStdString()));
//ui->lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash.toStdString()));
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()));
if(data.mPgpKnown)
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()));
else
ui->lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId.toStdString()) + tr(" [unverified]"));
time_t now = time(NULL) ;
ui->lineEdit_LastUsed->setText(getHumanReadableDuration(now - data.mLastUsageTS)) ;
@ -1109,29 +1113,32 @@ void IdDialog::insertIdDetails(uint32_t token)
else
{
if (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
{
ui->lineEdit_GpgName->setText(tr("Unknown real name"));
}
ui->lineEdit_GpgName->setText(tr("[Unknown node]"));
else
{
ui->lineEdit_GpgName->setText(tr("Anonymous Id"));
}
}
if(data.mPgpId.isNull())
{
ui->lineEdit_GpgId->hide() ;
ui->lineEdit_GpgName->hide() ;
ui->PgpId_LB->hide() ;
ui->PgpName_LB->hide() ;
}
else
{
ui->lineEdit_GpgId->show() ;
ui->lineEdit_GpgName->show() ;
ui->PgpId_LB->show() ;
ui->PgpName_LB->show() ;
}
if(data.mPgpKnown)
{
ui->lineEdit_GpgName->show() ;
ui->PgpName_LB->show() ;
}
else
{
ui->lineEdit_GpgName->hide() ;
ui->PgpName_LB->hide() ;
}
bool isLinkedToOwnPgpId = (data.mPgpKnown && (data.mPgpId == ownPgpId)) ;
bool isOwnId = (data.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);