From 17fc89e3c0f7bf37e99e7b637a5d810a608c937b Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 2 Jan 2017 15:58:37 +0100 Subject: [PATCH] First stage in abstracting GXS identities usage cases (half done) --- libretroshare/src/chat/distributedchat.cc | 2 +- libretroshare/src/gxs/rsgenexchange.cc | 11 +++++---- libretroshare/src/gxs/rsgixs.h | 4 ++-- libretroshare/src/gxs/rsgxsutil.cc | 14 ++++++------ libretroshare/src/retroshare/rsidentity.h | 28 +++++++++++++++++++++++ libretroshare/src/services/p3idservice.cc | 9 ++++++-- libretroshare/src/services/p3idservice.h | 7 +++--- 7 files changed, 54 insertions(+), 21 deletions(-) diff --git a/libretroshare/src/chat/distributedchat.cc b/libretroshare/src/chat/distributedchat.cc index 8fbc8f624..6124aedd4 100644 --- a/libretroshare/src/chat/distributedchat.cc +++ b/libretroshare/src/chat/distributedchat.cc @@ -220,7 +220,7 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const // network pre-request key to allow message authentication. - mGixs->requestKey(obj->signature.keyId,peer_list,"Needed for chat lobby "+RsUtil::NumberToString(obj->lobby_id,true)); + mGixs->requestKey(obj->signature.keyId,peer_list,RsIdentityUsage(RS_SERVICE_TYPE_CHAT,RsIdentityUsage::CHAT_LOBBY_MSG_VALIDATION,RsGxsGroupId(),RsGxsMessageId(),obj->lobby_id)); uint32_t size = obj->signed_serial_size() ; RsTemporaryMemory memory(size) ; diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 7e1331396..e86a21253 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -472,7 +472,7 @@ int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBin if(GxsSecurity::getSignature((char*)grpData.bin_data, grpData.bin_len, authorKey, sign)) { id_ret = SIGN_SUCCESS; - mGixs->timeStampKey(grpMeta.mAuthorId,"Creation of group author signature for GrpId" + grpMeta.mGroupId.toStdString()) ; + mGixs->timeStampKey(grpMeta.mAuthorId,RsIdentityUsage(mServType,RsIdentityUsage::GROUP_AUTHOR_SIGNATURE_CREATION,grpMeta.mGroupId)) ; signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; } else @@ -640,7 +640,7 @@ int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinar if(GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, authorKey, sign)) { id_ret = SIGN_SUCCESS; - mGixs->timeStampKey(msgMeta.mAuthorId,"Creating author signature in group " + msgMeta.mGroupId.toStdString() + ", msg " + msgMeta.mMsgId.toStdString()) ; + mGixs->timeStampKey(msgMeta.mAuthorId,RsIdentityUsage(mServType,RsIdentityUsage::MESSAGE_AUTHOR_SIGNATURE_CREATION,msgMeta.mGroupId,msgMeta.mMsgId)) ; signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; } else @@ -857,7 +857,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, const uin { RsTlvKeySignature sign = metaData.signSet.keySignSet[INDEX_AUTHEN_IDENTITY]; idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); - mGixs->timeStampKey(metaData.mAuthorId,"Validation of author signature, service: " + rsServiceControl->getServiceName(serviceFullType()) + ". Grp="+metaData.mGroupId.toStdString()+", msg="+metaData.mMsgId.toStdString()) ; + mGixs->timeStampKey(metaData.mAuthorId,RsIdentityUsage(mServType,RsIdentityUsage::MESSAGE_AUTHOR_SIGNATURE_VALIDATION,metaData.mGroupId,metaData.mMsgId)) ; } else { @@ -981,7 +981,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp) #ifdef GEN_EXCH_DEBUG std::cerr << " key ID validation result: " << idValidate << std::endl; #endif - mGixs->timeStampKey(metaData.mAuthorId,"Group author signature validation. GrpId=" + metaData.mGroupId.toStdString()) ; + mGixs->timeStampKey(metaData.mAuthorId,RsIdentityUsage(mServType,RsIdentityUsage::GROUP_AUTHOR_SIGNATURE_VALIDATION,metaData.mGroupId)); } else { @@ -3132,7 +3132,8 @@ bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) // also check this is the latest published group bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs; - mGixs->timeStampKey(newGrp.metaData->mAuthorId,"Validation of signature for updated grp " + oldGrpMeta.mGroupId.toStdString()) ; + mGixs->timeStampKey(newGrp.metaData->mAuthorId, RsIdentityUsage(mServType,RsIdentityUsage::GROUP_ADMIN_SIGNATURE_CREATION, oldGrpMeta.mGroupId)) ; + return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest; } diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index a210064c2..6ce361f60 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -125,7 +125,7 @@ public: virtual bool getOwnIds(std::list& ids) = 0; virtual bool isOwnId(const RsGxsId& key_id) = 0 ; - virtual void timeStampKey(const RsGxsId& key_id,const std::string& reason) = 0 ; + virtual void timeStampKey(const RsGxsId& key_id,const RsIdentityUsage& reason) = 0 ; // Key related interface - used for validating msgs and groups. /*! @@ -149,7 +149,7 @@ public: * @param keyref the KeyRef of the key being requested * @return will */ - virtual bool requestKey(const RsGxsId &id, const std::list &peers,const std::string& info) = 0; + virtual bool requestKey(const RsGxsId &id, const std::list &peers,const RsIdentityUsage& info) = 0; virtual bool requestPrivateKey(const RsGxsId &id) = 0; diff --git a/libretroshare/src/gxs/rsgxsutil.cc b/libretroshare/src/gxs/rsgxsutil.cc index 694f34972..3f9396779 100644 --- a/libretroshare/src/gxs/rsgxsutil.cc +++ b/libretroshare/src/gxs/rsgxsutil.cc @@ -139,7 +139,7 @@ bool RsGxsIntegrityCheck::check() GxsMsgReq msgIds; GxsMsgReq grps; - std::map used_gxs_ids ; + std::map used_gxs_ids ; std::set subscribed_groups ; // compute hash and compare to stored value, if it fails then simply add it @@ -172,7 +172,7 @@ bool RsGxsIntegrityCheck::check() #endif if(rsIdentity!=NULL && rsIdentity->overallReputationLevel(grp->metaData->mAuthorId) > RsReputations::REPUTATION_LOCALLY_NEGATIVE) - used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId,grp->grpId)) ; + used_gxs_ids.insert(std::make_pair(grp->metaData->mAuthorId,RsIdentityUsage(mGenExchangeClient->serviceType(),RsIdentityUsage::GROUP_AUTHOR_KEEP_ALIVE,grp->grpId))) ; } } } @@ -270,7 +270,7 @@ bool RsGxsIntegrityCheck::check() GXSUTIL_DEBUG() << "TimeStamping message authors' key ID " << msg->metaData->mAuthorId << " in message " << msg->msgId << ", group ID " << msg->grpId<< std::endl; #endif if(rsIdentity!=NULL && rsIdentity->overallReputationLevel(msg->metaData->mAuthorId) > RsReputations::REPUTATION_LOCALLY_NEGATIVE) - used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,msg->metaData->mGroupId)) ; + used_gxs_ids.insert(std::make_pair(msg->metaData->mAuthorId,std::make_pair(msg->metaData->mGroupId,msg->metaData->mMsgId))) ; } delete msg; @@ -297,9 +297,9 @@ bool RsGxsIntegrityCheck::check() std::list connected_friends ; rsPeers->getOnlineList(connected_friends) ; - std::vector > gxs_ids ; + std::vector > gxs_ids ; - for(std::map::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it) + for(std::map::const_iterator it(used_gxs_ids.begin());it!=used_gxs_ids.end();++it) { gxs_ids.push_back(*it) ; #ifdef DEBUG_GXSUTIL @@ -323,7 +323,7 @@ bool RsGxsIntegrityCheck::check() if(!mGixs->haveKey(gxs_ids[n].first)) // checks if we have it already in the cache (conservative way to ensure that we atually have it) { - mGixs->requestKey(gxs_ids[n].first,connected_friends,"Author in service \"" + rsServiceControl->getServiceName(mGenExchangeClient->serviceFullType())+"\" (group ID " + gxs_ids[n].second.toStdString() + ")" ) ; + mGixs->requestKey(gxs_ids[n].first,connected_friends,gxs_ids[n].second); ++nb_requested_not_in_cache ; #ifdef DEBUG_GXSUTIL @@ -336,7 +336,7 @@ bool RsGxsIntegrityCheck::check() GXSUTIL_DEBUG() << " ... already in cache" << std::endl; #endif } - mGixs->timeStampKey(gxs_ids[n].first,"Author in service \"" + rsServiceControl->getServiceName(mGenExchangeClient->serviceFullType())+"\" (group ID " + gxs_ids[n].second.toStdString() + ")"); + mGixs->timeStampKey(gxs_ids[n].first,gxs_ids[n].second); gxs_ids[n] = gxs_ids[gxs_ids.size()-1] ; gxs_ids.pop_back() ; diff --git a/libretroshare/src/retroshare/rsidentity.h b/libretroshare/src/retroshare/rsidentity.h index dff973204..9fce700e8 100644 --- a/libretroshare/src/retroshare/rsidentity.h +++ b/libretroshare/src/retroshare/rsidentity.h @@ -212,6 +212,34 @@ class RsIdentityParameters RsGxsImage mImage ; }; +class RsIdentityUsage +{ +public: + enum UsageCode { UNKNOWN_USAGE = 0x00, + GROUP_ADMIN_SIGNATURE_CREATION = 0x01, // These 2 are normally not normal GXS identities, but nothing prevents it to happen either. + GROUP_ADMIN_SIGNATURE_VALIDATION = 0x02, + GROUP_AUTHOR_SIGNATURE_CREATION = 0x03, // not typically used, since most services do not require group author signatures + GROUP_AUTHOR_SIGNATURE_VALIDATION = 0x04, + MESSAGE_AUTHOR_SIGNATURE_CREATION = 0x05, // most common use case. Messages are signed by authors in e.g. forums. + MESSAGE_AUTHOR_SIGNATURE_VALIDATION = 0x06, + GROUP_AUTHOR_KEEP_ALIVE = 0x07, // Identities are stamped regularly by crawlign the set of messages for all groups. That helps keepign the useful identities in hand. + MESSAGE_AUTHOR_KEEP_ALIVE = 0x08, // Identities are stamped regularly by crawlign the set of messages for all groups. That helps keepign the useful identities in hand. + CHAT_LOBBY_MSG_VALIDATION = 0x09 // Chat lobby msgs are signed, so each time one comes, or a chat lobby event comes, a signature verificaiton happens. + } ; + + RsIdentityUsage(uint16_t service,const RsIdentityUsage::UsageCode& code,const RsGxsGroupId& gid,const RsGxsMessageId& mid=RsGxsMessageId(),uint64_t additional_id=0,const std::string& comment = std::string()) + : mServiceId(service), mUsageCode(code), mGrpId(gid), mMsgId(mid),mAdditionalId(additional_id),mComment(comment) {} + + uint16_t mServiceId; // Id of the service using that identity + 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 + + RsGxsMessageId mMsgId; // Message ID using the identity + uint64_t mAdditionalId; // Some additional ID. Can be used for e.g. chat lobbies. + std::string mComment ; // additional comment to be used mainly for debugging, but not GUI display +}; + + class RsIdentity: public RsGxsIfaceHelper { diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index d0154be6e..9adc18847 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -263,14 +263,16 @@ time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id) else return it->second.TS ; } -void p3IdService::timeStampKey(const RsGxsId& gxs_id, const std::string& reason) +void p3IdService::timeStampKey(const RsGxsId& gxs_id, const RsIdentityUsage& reason) { if(rsReputations->isIdentityBanned(gxs_id) ) { std::cerr << "(II) p3IdService:timeStampKey(): refusing to time stamp key " << gxs_id << " because it is banned." << std::endl; return ; } +#ifdef DEBUG_IDS std::cerr << "(II) time stamping key " << gxs_id << " for the following reason: " << reason << std::endl; +#endif RS_STACK_MUTEX(mIdMtx) ; @@ -786,7 +788,7 @@ static void mergeIds(std::map >& idmap,const RsGxsId old_peers.push_back(*it) ; } -bool p3IdService::requestKey(const RsGxsId &id, const std::list& peers,const std::string& info) +bool p3IdService::requestKey(const RsGxsId &id, const std::list& peers,const RsIdentityUsage& info) { if(id.isNull()) { @@ -2262,6 +2264,9 @@ bool p3IdService::cache_load_for_token(uint32_t token) for(std::map >::const_iterator itt(mPendingCache.begin());itt!=mPendingCache.end();++itt) if(!itt->second.empty()) mergeIds(mIdsNotPresent,itt->first,itt->second) ; + else + std::cerr << "(WW) empty list of peers to request ID " << itt->first << ": cannot request" << std::endl; + mPendingCache.clear(); diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 638a9d2e0..8154bf372 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -212,7 +212,6 @@ private: void init(const RsGxsIdGroupItem *item, const RsTlvPublicRSAKey& in_pub_key, const RsTlvPrivateRSAKey& in_priv_key,const std::list &tagList); }; - // Not sure exactly what should be inherited here? // Chris - please correct as necessary. @@ -298,7 +297,7 @@ public: virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey &key); virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey &key); - virtual bool requestKey(const RsGxsId &id, const std::list &peers, const std::string &info); + virtual bool requestKey(const RsGxsId &id, const std::list &peers, const RsIdentityUsage &info); virtual bool requestPrivateKey(const RsGxsId &id); @@ -467,7 +466,7 @@ private: void cleanUnusedKeys() ; void slowIndicateConfigChanged() ; - virtual void timeStampKey(const RsGxsId& id,const std::string& reason) ; + virtual void timeStampKey(const RsGxsId& id, const RsIdentityUsage& reason) ; time_t locked_getLastUsageTS(const RsGxsId& gxs_id); std::string genRandomId(int len = 20); @@ -512,7 +511,7 @@ private: keyTSInfo() : TS(0) {} time_t TS ; - std::map usage_map ; + std::map usage_map ; }; friend class IdCacheEntryCleaner;