added hashstream class to hash content of RsIdentityUsage and fix duplication of identity usage statistics

This commit is contained in:
csoler 2017-01-05 23:07:59 +01:00
parent 1a2def70b5
commit d631758e8c
10 changed files with 152 additions and 112 deletions

View File

@ -0,0 +1,79 @@
#include "hashstream.h"
#include <assert.h>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <retroshare/rsids.h>
namespace librs
{
namespace crypto
{
HashStream::HashStream(HashType t)
{
assert(t == SHA1) ;
mdctx = EVP_MD_CTX_create();
EVP_DigestInit_ex(mdctx,EVP_sha1(),NULL);
}
HashStream::~HashStream()
{
if(mdctx)
EVP_MD_CTX_destroy(mdctx) ;
}
Sha1CheckSum HashStream::hash()
{
uint8_t h[EVP_MAX_MD_SIZE] ;
unsigned int len;
EVP_DigestFinal_ex(mdctx,h,&len) ;
EVP_MD_CTX_destroy(mdctx) ;
mdctx=NULL ;
return Sha1CheckSum(h);
}
template<>
HashStream& operator<<(HashStream& u,const std::string& s)
{
EVP_DigestUpdate(u.mdctx,s.c_str(),s.length()) ;
return u;
}
template<>
HashStream& operator<<(HashStream& u,const uint64_t& n)
{
unsigned char mem[8] ;
uint64_t s(n);
for(int i=0;i<8;++i)
{
mem[i] = (uint8_t)s;
s <<= 8 ;
}
EVP_DigestUpdate(u.mdctx,mem,8);
return u;
}
template<>
HashStream& operator<<(HashStream& u,const uint32_t& n)
{
unsigned char mem[4] ;
uint64_t s(n);
for(int i=0;i<4;++i)
{
mem[i] = (uint8_t)s;
s <<= 8 ;
}
EVP_DigestUpdate(u.mdctx,mem,4);
return u;
}
template<>
HashStream& operator<<(HashStream& u,const uint8_t& n)
{
EVP_DigestUpdate(u.mdctx,&n,1);
return u;
}
}
}

View File

@ -0,0 +1,34 @@
#pragma once
#include <openssl/evp.h>
#include <util/rsdir.h>
namespace librs
{
namespace crypto
{
class HashStream
{
public:
enum HashType { UNKNOWN = 0x00,
SHA1 = 0x01
};
HashStream(HashType t);
~HashStream();
Sha1CheckSum hash() ;
template<class T> friend HashStream& operator<<(HashStream& u, const T&) ;
template<uint32_t ID_SIZE_IN_BYTES,bool UPPER_CASE,uint32_t UNIQUE_IDENTIFIER>
friend HashStream& operator<<(HashStream& u,const t_RsGenericIdType<ID_SIZE_IN_BYTES,UPPER_CASE,UNIQUE_IDENTIFIER>& r)
{
EVP_DigestUpdate(u.mdctx,r.toByteArray(),ID_SIZE_IN_BYTES);
return u;
}
private:
EVP_MD_CTX *mdctx ;
};
}
}

View File

@ -172,7 +172,6 @@ class GixsReputation
int score;
};
class RsGixsReputation
{
public:
@ -182,7 +181,6 @@ public:
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep) = 0;
};
/*** This Class pulls all the GXS Interfaces together ****/
class RsGxsIdExchange:

View File

@ -2779,8 +2779,6 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
const RsPeerId peerFrom = tr->mTransaction->PeerId();
MsgAuthorV toVet;
std::list<RsPeerId> peers;
peers.push_back(tr->mTransaction->PeerId());
bool reqListSizeExceeded = false ;
@ -2845,22 +2843,6 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
continue ;
}
#ifdef TO_BE_REMOVED
if(mReputations->haveReputation(syncItem->authorId) || noAuthor)
{
GixsReputation rep;
#ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", author Id=" << syncItem->authorId << ". Reputation: " ;
#endif
if(!noAuthor)
mReputations->getReputation(syncItem->authorId, rep);
// if author is required for this message, it will simply get dropped
// at genexchange side of things
if(rep.score >= (int)grpMeta->mReputationCutOff || noAuthor)
{
#endif
#ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", passed! Adding message to req list." << std::endl;
#endif
@ -2872,28 +2854,6 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
msgItem->PeerId(peerFrom);
reqList.push_back(msgItem);
++reqListSize ;
#ifdef TO_BE_REMOVED
}
#ifdef NXS_NET_DEBUG_1
else
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", failed!" << std::endl;
#endif
}
else
{
#ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << ", no author/no reputation. Pushed to Vetting list." << std::endl;
#endif
// preload for speed
mReputations->loadReputation(syncItem->authorId, peers);
MsgAuthEntry entry;
entry.mAuthorId = syncItem->authorId;
entry.mGrpId = syncItem->grpId;
entry.mMsgId = syncItem->msgId;
toVet.push_back(entry);
}
#endif
}
#ifdef NXS_NET_DEBUG_1
else
@ -2901,15 +2861,6 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
#endif
}
if(!toVet.empty())
{
#ifdef NXS_NET_DEBUG_1
GXSNETDEBUG_PG(item->PeerId(),grpId) << " Vetting list: " << toVet.size() << " elements." << std::endl;
#endif
MsgRespPending* mrp = new MsgRespPending(mReputations, tr->mTransaction->PeerId(), toVet, cutoff);
mPendingResp.push_back(mrp);
}
if(!reqList.empty())
{
#ifdef NXS_NET_DEBUG_1
@ -3046,7 +2997,6 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
uint32_t transN = locked_getTransactionId();
GrpAuthorV toVet;
std::list<RsPeerId> peers;
peers.push_back(tr->mTransaction->PeerId());
@ -3076,55 +3026,8 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
}
if( (mGrpAutoSync && !haveItem) || latestVersion)
{
// determine if you need to check reputation
bool checkRep = !grpSyncItem->authorId.isNull();
// check if you have reputation, if you don't then
// place in holding pen
if(checkRep)
{
if(mReputations->haveReputation(grpSyncItem->authorId))
{
GixsReputation rep;
mReputations->getReputation(grpSyncItem->authorId, rep);
if(rep.score >= (int)GIXS_CUT_OFF)
{
addGroupItemToList(tr, grpId, transN, reqList);
#ifdef NXS_NET_DEBUG_0
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId)<< " reputation cut off: limit=" << GIXS_CUT_OFF << " value=" << rep.score << ": allowed." << std::endl;
#endif
}
#ifdef NXS_NET_DEBUG_0
else
GXSNETDEBUG_PG(tr->mTransaction->PeerId(),grpId)<< " reputation cut off: limit=" << GIXS_CUT_OFF << " value=" << rep.score << ": you shall not pass." << std::endl;
#endif
}
else
{
// preload reputation for later
mReputations->loadReputation(grpSyncItem->authorId, peers);
GrpAuthEntry entry;
entry.mAuthorId = grpSyncItem->authorId;
entry.mGrpId = grpSyncItem->grpId;
toVet.push_back(entry);
}
}
else
{
addGroupItemToList(tr, grpId, transN, reqList);
}
}
}
if(!toVet.empty())
{
RsPeerId peerId = tr->mTransaction->PeerId();
GrpRespPending* grp = new GrpRespPending(mReputations, peerId, toVet);
mPendingResp.push_back(grp);
}
if(!reqList.empty())
locked_pushGrpTransactionFromList(reqList, tr->mTransaction->PeerId(), transN);

View File

@ -47,8 +47,7 @@ bool AuthorPending::expired() const
return time(NULL) > (mTimeStamp + EXPIRY_PERIOD_OFFSET);
}
bool AuthorPending::getAuthorRep(GixsReputation& rep,
const RsGxsId& authorId, const RsPeerId& peerId)
bool AuthorPending::getAuthorRep(GixsReputation& rep, const RsGxsId& authorId, const RsPeerId& peerId)
{
if(mRep->haveReputation(authorId))
{

View File

@ -378,7 +378,8 @@ HEADERS += ft/ftchunkmap.h \
ft/fttransfermodule.h \
ft/ftturtlefiletransferitem.h
HEADERS += crypto/chacha20.h
HEADERS += crypto/chacha20.h \
crypto/hashstream.h
HEADERS += directory_updater.h \
directory_list.h \
@ -539,7 +540,8 @@ SOURCES += ft/ftchunkmap.cc \
ft/fttransfermodule.cc \
ft/ftturtlefiletransferitem.cc
SOURCES += crypto/chacha20.cpp
SOURCES += crypto/chacha20.cpp \
crypto/hashstream.cc
SOURCES += chat/distantchat.cc \
chat/p3chatservice.cc \

View File

@ -206,7 +206,7 @@ public:
explicit RsIdentityUsage(uint16_t service,const RsIdentityUsage::UsageCode& code,const RsGxsGroupId& gid=RsGxsGroupId(),const RsGxsMessageId& mid=RsGxsMessageId(),uint64_t additional_id=0,const std::string& comment = std::string());
uint16_t mServiceId; // Id of the service using that identity
uint16_t mServiceId; // Id of the service using that identity, as understood by rsServiceControl
UsageCode mUsageCode; // Specific code to use. Will allow forming the correct translated message in the GUI if necessary.
RsGxsGroupId mGrpId; // Group ID using the identity

View File

@ -1314,6 +1314,11 @@ int RsServer::StartupRetroShare()
//
mPluginsManager->loadPlugins(programatically_inserted_plugins) ;
/**** Reputation system ****/
p3GxsReputation *mReputations = new p3GxsReputation(mLinkMgr) ;
rsReputations = mReputations ;
#ifdef RS_ENABLE_GXS
std::string currGxsDir = rsAccounts->PathAccountDirectory() + "/gxs";
@ -1384,10 +1389,6 @@ int RsServer::StartupRetroShare()
mPosted->setNetworkExchangeService(posted_ns) ;
/**** Reputation system ****/
p3GxsReputation *mReputations = new p3GxsReputation(mLinkMgr) ;
rsReputations = mReputations ;
/**** Wiki GXS service ****/

View File

@ -959,6 +959,7 @@ bool p3GxsReputation::setOwnOpinion(const RsGxsId& gxsid, const RsReputations::O
if (rit == mReputations.end())
{
#warning we should set the owner node id here.
mReputations[gxsid] = Reputation(gxsid);
rit = mReputations.find(gxsid);
}

View File

@ -34,6 +34,7 @@
#include "util/rsstring.h"
#include "util/radix64.h"
#include "util/rsdir.h"
#include "crypto/hashstream.h"
#include "gxs/gxssecurity.h"
#include "retroshare/rspeers.h"
@ -612,6 +613,7 @@ bool p3IdService::getIdDetails(const RsGxsId &id, RsIdentityDetails &details)
RsReputations::ReputationLevel p3IdService::overallReputationLevel(const RsGxsId &id)
{
#warning some IDs might be deleted but the reputation should still say they are banned.
RsIdentityDetails det ;
getIdDetails(id,det) ;
@ -4122,8 +4124,29 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel*
RsIdentityUsage::RsIdentityUsage(uint16_t service,const RsIdentityUsage::UsageCode& code,const RsGxsGroupId& gid,const RsGxsMessageId& mid,uint64_t additional_id,const std::string& comment)
: mServiceId(service), mUsageCode(code), mGrpId(gid), mMsgId(mid),mAdditionalId(additional_id),mComment(comment)
{
#ifdef DEBUG_IDS
// This is a hack, since it will hash also mHash, but because it is initialized to 0, and only computed in the constructor here, it should be ok.
mHash = RsDirUtil::sha1sum(reinterpret_cast<uint8_t*>(this),sizeof(RsIdentityUsage)) ;
std::cerr << "New identity usage: " << std::endl;
std::cerr << " service=" << std::hex << service << std::endl;
std::cerr << " code =" << std::hex << code << std::endl;
std::cerr << " grpId =" << std::hex << gid << std::endl;
std::cerr << " msgId =" << std::hex << mid << std::endl;
std::cerr << " add id =" << std::hex << additional_id << std::endl;
std::cerr << " commnt =\"" << std::hex << comment << "\"" << std::endl;
#endif
librs::crypto::HashStream hs(librs::crypto::HashStream::SHA1) ;
hs << (uint32_t)service ;
hs << (uint8_t)code ;
hs << gid ;
hs << mid ;
hs << (uint64_t)additional_id ;
hs << comment ;
mHash = hs.hash();
std::cerr << " hash =\"" << std::hex << mHash << "\"" << std::endl;
}