From ef0850e65b997dd0e0968e9725d6773bb54a26b8 Mon Sep 17 00:00:00 2001 From: csoler Date: Mon, 19 Dec 2016 20:44:15 +0100 Subject: [PATCH] added recording system for usage cases of GXS ids --- libretroshare/src/gxs/rsgenexchange.cc | 12 ++--- libretroshare/src/gxs/rsgixs.h | 2 +- libretroshare/src/gxs/rsgxsutil.cc | 2 +- libretroshare/src/gxstunnel/p3gxstunnel.cc | 2 +- libretroshare/src/services/p3idservice.cc | 53 ++++++++++++++-------- libretroshare/src/services/p3idservice.h | 13 +++++- 6 files changed, 54 insertions(+), 30 deletions(-) diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 46d0fd98a..3d1f2e109 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -470,8 +470,8 @@ 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) ; - signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; + mGixs->timeStampKey(grpMeta.mAuthorId,"Creation of group author signature for GrpId" + grpMeta.mGroupId.toStdString()) ; + signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; } else id_ret = SIGN_FAIL; @@ -638,7 +638,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) ; + mGixs->timeStampKey(msgMeta.mAuthorId,"Creating author signature in group " + msgMeta.mGroupId.toStdString() + ", msg " + msgMeta.mMsgId.toStdString()) ; signSet.keySignSet[INDEX_AUTHEN_IDENTITY] = sign; } else @@ -855,7 +855,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) ; + mGixs->timeStampKey(metaData.mAuthorId,"Validation of author signature. Grp="+metaData.mGroupId.toStdString()+", msg="+metaData.mMsgId.toStdString()) ; } else { @@ -986,7 +986,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp) #ifdef GEN_EXCH_DEBUG std::cerr << " key ID validation result: " << idValidate << std::endl; #endif - mGixs->timeStampKey(metaData.mAuthorId) ; + mGixs->timeStampKey(metaData.mAuthorId,"Group author signature validation. GrpId=" + metaData.mGroupId.toStdString()) ; } else { @@ -3145,7 +3145,7 @@ 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) ; + mGixs->timeStampKey(newGrp.metaData->mAuthorId,"Validation of signature for updated grp " + oldGrpMeta.mGroupId.toStdString()) ; return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest; } diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index 5b12aa873..21c46d04d 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) = 0 ; + virtual void timeStampKey(const RsGxsId& key_id,const std::string& reason) = 0 ; // Key related interface - used for validating msgs and groups. /*! diff --git a/libretroshare/src/gxs/rsgxsutil.cc b/libretroshare/src/gxs/rsgxsutil.cc index 29c9ae337..0b679fd41 100644 --- a/libretroshare/src/gxs/rsgxsutil.cc +++ b/libretroshare/src/gxs/rsgxsutil.cc @@ -339,7 +339,7 @@ bool RsGxsIntegrityCheck::check() // Note: we could time_stamp even in the case where the id is not cached. Anyway, it's not really a problem here, since IDs have a high chance of // behing eventually stamped. - mGixs->timeStampKey(gxs_ids[n]) ; + mGixs->timeStampKey(gxs_ids[n],"Used in service (Integrity check)") ; } gxs_ids[n] = gxs_ids[gxs_ids.size()-1] ; diff --git a/libretroshare/src/gxstunnel/p3gxstunnel.cc b/libretroshare/src/gxstunnel/p3gxstunnel.cc index 0838bef50..c64cf6572 100644 --- a/libretroshare/src/gxstunnel/p3gxstunnel.cc +++ b/libretroshare/src/gxstunnel/p3gxstunnel.cc @@ -937,7 +937,7 @@ void p3GxsTunnelService::handleRecvDHPublicKey(RsGxsTunnelDHPublicKeyItem *item) std::cerr << "(SS) Signature was verified and it doesn't check! This is a security issue!" << std::endl; return ; } - mGixs->timeStampKey(item->signature.keyId) ; + mGixs->timeStampKey(item->signature.keyId,"Used to validate GXS tunnel DH half-key.") ; #ifdef DEBUG_GXS_TUNNEL std::cerr << " Signature checks! Sender's ID = " << senders_id << std::endl; diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 6914ebaa5..c4ae86f52 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -128,8 +128,9 @@ RsIdentity *rsIdentity = NULL; /* delays */ -#define CACHETEST_PERIOD 60 +#define CACHETEST_PERIOD 60 #define DELAY_BETWEEN_CONFIG_UPDATES 300 +#define GXS_MAX_KEY_TS_USAGE_MAP_SIZE 5 #define OWNID_RELOAD_DELAY 10 @@ -255,23 +256,33 @@ void p3IdService::slowIndicateConfigChanged() } time_t p3IdService::locked_getLastUsageTS(const RsGxsId& gxs_id) { - std::map::const_iterator it = mKeysTS.find(gxs_id) ; + std::map::const_iterator it = mKeysTS.find(gxs_id) ; if(it == mKeysTS.end()) return 0 ; else - return it->second ; + return it->second.TS ; } -void p3IdService::timeStampKey(const RsGxsId& gxs_id) +void p3IdService::timeStampKey(const RsGxsId& gxs_id, const std::string& 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 ; } + std::cerr << "(II) time stamping key " << gxs_id << " for the following reason: " << reason << std::endl; RS_STACK_MUTEX(mIdMtx) ; - mKeysTS[gxs_id] = time(NULL) ; + + time_t now = time(NULL) ; + + keyTSInfo& info(mKeysTS[gxs_id]) ; + + info.TS = now ; + info.usage_map[now] = reason ; + + while(info.usage_map.size() > GXS_MAX_KEY_TS_USAGE_MAP_SIZE) + info.usage_map.erase(info.usage_map.begin()); slowIndicateConfigChanged() ; } @@ -286,7 +297,7 @@ bool p3IdService::loadList(std::list& items) if( (lii = dynamic_cast(*it)) != NULL) { for(std::map::const_iterator it2 = lii->mTimeStamps.begin();it2!=lii->mTimeStamps.end();++it2) - mKeysTS.insert(*it2) ; + mKeysTS[it2->first].TS = it2->second; mContacts = lii->mContacts ; } @@ -307,7 +318,10 @@ bool p3IdService::saveList(bool& cleanup,std::list& items) RS_STACK_MUTEX(mIdMtx) ; cleanup = true ; RsGxsIdLocalInfoItem *item = new RsGxsIdLocalInfoItem ; - item->mTimeStamps = mKeysTS ; + + for(std::map::const_iterator it(mKeysTS.begin());it!=mKeysTS.end();++it) + item->mTimeStamps[it->first] = it->second.TS; + item->mContacts = mContacts ; items.push_back(item) ; @@ -317,7 +331,7 @@ bool p3IdService::saveList(bool& cleanup,std::list& items) class IdCacheEntryCleaner { public: - IdCacheEntryCleaner(const std::map& last_usage_TSs) : mLastUsageTS(last_usage_TSs) {} + IdCacheEntryCleaner(const std::map& last_usage_TSs) : mLastUsageTS(last_usage_TSs) {} bool processEntry(RsGxsIdCache& entry) { @@ -338,11 +352,11 @@ public: return true ; } - std::map::const_iterator it = mLastUsageTS.find(gxs_id) ; + std::map::const_iterator it = mLastUsageTS.find(gxs_id) ; bool no_ts = (it == mLastUsageTS.end()) ; - time_t last_usage_ts = no_ts?0:(it->second); + time_t last_usage_ts = no_ts?0:(it->second.TS); time_t max_keep_time ; if(no_ts) @@ -370,7 +384,7 @@ public: } std::list ids_to_delete ; - const std::map& mLastUsageTS; + const std::map& mLastUsageTS; }; void p3IdService::cleanUnusedKeys() @@ -495,7 +509,7 @@ void p3IdService::notifyChanges(std::vector &changes) // also time_stamp the key that this group represents - timeStampKey(RsGxsId(*git)) ; + timeStampKey(RsGxsId(*git),"Group info changed") ; ++git; } @@ -892,7 +906,7 @@ bool p3IdService::signData(const uint8_t *data,uint32_t data_size,const RsGxsId& return false ; } error_status = RS_GIXS_ERROR_NO_ERROR ; - timeStampKey(own_gxs_id) ; + timeStampKey(own_gxs_id,"own GXS id") ; return true ; } bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTlvKeySignature& signature,bool force_load,uint32_t& signing_error) @@ -929,7 +943,7 @@ bool p3IdService::validateData(const uint8_t *data,uint32_t data_size,const RsTl } signing_error = RS_GIXS_ERROR_NO_ERROR ; - timeStampKey(signature.keyId) ; + timeStampKey(signature.keyId,"Used in signature checking." ) ; return true ; } bool p3IdService::encryptData(const uint8_t *decrypted_data,uint32_t decrypted_data_size,uint8_t *& encrypted_data,uint32_t& encrypted_data_size,const RsGxsId& encryption_key_id,bool force_load,uint32_t& error_status) @@ -957,7 +971,7 @@ bool p3IdService::encryptData(const uint8_t *decrypted_data,uint32_t decrypted_d return false ; } error_status = RS_GIXS_ERROR_NO_ERROR ; - timeStampKey(encryption_key_id) ; + timeStampKey(encryption_key_id,"Used to encrypt data") ; return true ; } @@ -989,7 +1003,7 @@ bool p3IdService::decryptData(const uint8_t *encrypted_data,uint32_t encrypted_d return false ; } error_status = RS_GIXS_ERROR_NO_ERROR ; - timeStampKey(key_id) ; + timeStampKey(key_id,"Used to decrypt data") ; return true ; } @@ -2399,7 +2413,8 @@ bool p3IdService::cache_load_ownids(uint32_t token) // This prevents automatic deletion to get rid of them. // In other words, own ids are always used. - mKeysTS[RsGxsId(item->meta.mGroupId)] = time(NULL) ; + + mKeysTS[RsGxsId(item->meta.mGroupId)].TS = time(NULL) ; } delete item ; } @@ -2691,7 +2706,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte std::cerr << std::endl; return SERVICE_CREATE_FAIL; } - mKeysTS[RsGxsId(item->meta.mGroupId)] = time(NULL) ; + mKeysTS[RsGxsId(item->meta.mGroupId)].TS = time(NULL) ; /********************* TEMP HACK UNTIL GXS FILLS IN GROUP_ID *****************/ @@ -2851,7 +2866,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte if (std::find(mOwnIds.begin(), mOwnIds.end(), gxsId) == mOwnIds.end()) { mOwnIds.push_back(gxsId); - mKeysTS[gxsId] = time(NULL) ; + mKeysTS[gxsId].TS = time(NULL) ; } } diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index f31bbaf50..f06042172 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -467,7 +467,7 @@ private: void cleanUnusedKeys() ; void slowIndicateConfigChanged() ; - virtual void timeStampKey(const RsGxsId& id) ; + virtual void timeStampKey(const RsGxsId& id,const std::string& reason) ; time_t locked_getLastUsageTS(const RsGxsId& gxs_id); std::string genRandomId(int len = 20); @@ -507,10 +507,19 @@ private: private: + struct keyTSInfo + { + keyTSInfo() : TS(0) {} + + time_t TS ; + std::map usage_map ; + }; + friend class IdCacheEntryCleaner; + std::map > mIdsPendingCache; std::map > mGroupNotPresent; std::map > mIdsNotPresent; - std::map mKeysTS ; + std::map mKeysTS ; // keep a list of regular contacts. This is useful to sort IDs, and allow some services to priviledged ids only. std::set mContacts;