diff --git a/libretroshare/src/gxs/rsdataservice.cc b/libretroshare/src/gxs/rsdataservice.cc index 5d09fee5d..10b73fd39 100644 --- a/libretroshare/src/gxs/rsdataservice.cc +++ b/libretroshare/src/gxs/rsdataservice.cc @@ -1149,9 +1149,11 @@ void RsDataService::locked_retrieveGroups(RetroCursor* c, std::vector // only add the latest grp info if(g) { - if (metaOffset) { + if (metaOffset) g->metaData = locked_getGrpMeta(*c, metaOffset,false); - } + else + g->metaData = nullptr; + grps.push_back(g); } valid = c->moveToNext(); @@ -1235,9 +1237,11 @@ void RsDataService::locked_retrieveMessages(RetroCursor *c, std::vectormetaData = locked_getMsgMeta(*c, metaOffset,false); - } + else + m->metaData = nullptr; + msgs.push_back(m); } diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 4ef9ae9d7..28fa40a30 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -1436,6 +1436,24 @@ bool RsGenExchange::getSerializedGroupData(uint32_t token, RsGxsGroupId& id, return RsNxsSerialiser(mServType).serialise(nxs_grp,data,&size) ; } +bool RsGenExchange::retrieveNxsIdentity(const RsGxsGroupId& group_id,RsNxsGrp *& identity_grp) +{ + RS_STACK_MUTEX(mGenMtx) ; + + std::map grp; + grp[group_id]=nullptr; + std::map::const_iterator grp_it; + + if(! mDataStore->retrieveNxsGrps(grp, true,true) || grp.end()==(grp_it=grp.find(group_id)) || !grp_it->second) + { + std::cerr << "(EE) Cannot retrieve group data for group " << group_id << " in service " << mServType << std::endl; + return false; + } + + identity_grp = grp_it->second; + return true; +} + bool RsGenExchange::deserializeGroupData(unsigned char *data, uint32_t size, RsGxsGroupId* gId /*= nullptr*/) { @@ -1685,11 +1703,11 @@ bool RsGenExchange::setAuthenPolicyFlag(const uint8_t &msgFlag, uint32_t& authen return true; } -void RsGenExchange::receiveNewGroups(std::vector &groups) +void RsGenExchange::receiveNewGroups(const std::vector &groups) { RS_STACK_MUTEX(mGenMtx) ; - std::vector::iterator vit = groups.begin(); + auto vit = groups.begin(); // store these for tick() to pick them up for(; vit != groups.end(); ++vit) @@ -1717,7 +1735,7 @@ void RsGenExchange::receiveNewGroups(std::vector &groups) } -void RsGenExchange::receiveNewMessages(std::vector& messages) +void RsGenExchange::receiveNewMessages(const std::vector& messages) { RS_STACK_MUTEX(mGenMtx) ; diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 55a1f5055..9551cc652 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -133,12 +133,12 @@ public: /*! * @param messages messages are deleted after function returns */ - virtual void receiveNewMessages(std::vector& messages) override; + virtual void receiveNewMessages(const std::vector &messages) override; /*! * @param groups groups are deleted after function returns */ - virtual void receiveNewGroups(std::vector& groups) override; + virtual void receiveNewGroups(const std::vector &groups) override; /*! * @param grpId group id @@ -376,6 +376,12 @@ protected: bool deserializeGroupData(unsigned char *data, uint32_t size, RsGxsGroupId* gId = nullptr); + /*! + * \brief retrieveNxsIdentity + * Sync version of the previous method. Might take some time, so should be used carefully. + */ + bool retrieveNxsIdentity(const RsGxsGroupId& group_id,RsNxsGrp *& identity_grp); + template bool getGroupDataT(const uint32_t &token, std::vector& grpItem) { diff --git a/libretroshare/src/gxs/rsgixs.h b/libretroshare/src/gxs/rsgixs.h index a7ab1db82..955aea673 100644 --- a/libretroshare/src/gxs/rsgixs.h +++ b/libretroshare/src/gxs/rsgixs.h @@ -155,6 +155,12 @@ public: virtual bool requestKey(const RsGxsId &id, const std::list &peers,const RsIdentityUsage& info) = 0; virtual bool requestPrivateKey(const RsGxsId &id) = 0; + /*! + * \brief receiveNewIdentity + * Receives a new identity. This is a facility offerred to RsGxsNetService when identities are sent/received by turtle tunnels + */ + virtual bool receiveNewIdentity(RsNxsGrp *identity_grp)=0; + virtual bool retrieveNxsIdentity(const RsGxsId& group_id,RsNxsGrp *& identity_grp)=0; /*! * Retrieves a key identity diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index 23f364510..a288b2e8c 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -283,7 +283,7 @@ //#define NXS_NET_DEBUG_5 1 //#define NXS_NET_DEBUG_6 1 //#define NXS_NET_DEBUG_7 1 -//#define NXS_NET_DEBUG_8 1 +#define NXS_NET_DEBUG_8 1 //#define NXS_NET_DEBUG_9 1 //#define NXS_FRAG @@ -5366,7 +5366,23 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsig #ifdef NXS_NET_DEBUG_8 GXSNETDEBUG___ << " successfuly decrypted data : " << RsUtil::BinToHex(clear_group_data,clear_group_data_len,50) << std::endl; #endif - RsItem *item = RsNxsSerialiser(mServType).deserialise(clear_group_data,&clear_group_data_len) ; + uint32_t used_size = clear_group_data_len; + RsItem *item = RsNxsSerialiser(mServType).deserialise(clear_group_data,&used_size) ; + RsNxsGrp *nxs_identity_grp=nullptr; + + if(used_size < clear_group_data_len) + { + uint32_t remaining_size = clear_group_data_len-used_size ; + RsItem *item2 = RsNxsSerialiser(RS_SERVICE_GXS_TYPE_GXSID).deserialise(clear_group_data+used_size,&remaining_size) ; + + nxs_identity_grp = dynamic_cast(item2); + + if(!nxs_identity_grp) + std::cerr << "(EE) decrypted item contains more data that cannot be deserialized as a GxsId. Unexpected!" << std::endl; + +#warning We should probably check that the identity that is sent corresponds to the group author and don't add it otherwise. + } + free(clear_group_data); clear_group_data = NULL ; @@ -5377,6 +5393,14 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsig std::cerr << "(EE) decrypted item is not a RsNxsGrp. Weird!" << std::endl; return ; } + +#ifdef NXS_NET_DEBUG_8 + if(nxs_identity_grp) + GXSNETDEBUG___ << " Serialized clear data contains a group " << nxs_grp->grpId << " in service " << std::hex << mServType << std::dec << " and a second identity item for an identity." << nxs_identity_grp->grpId << std::endl; + else + GXSNETDEBUG___ << " Serialized clear data contains a single GXS group for Grp Id " << nxs_grp->grpId << " in service " << std::hex << mServType << std::dec << std::endl; +#endif + std::vector new_grps(1,nxs_grp); GroupRequestRecord& rec(mSearchedGroups[nxs_grp->grpId]) ; @@ -5387,6 +5411,9 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsig #endif mObserver->receiveNewGroups(new_grps); mObserver->receiveDistantSearchResults(req, grpId); + + if(nxs_identity_grp) + mGixs->receiveNewIdentity(nxs_identity_grp); } bool RsGxsNetService::search( const std::string& substring, @@ -5504,8 +5531,7 @@ bool RsGxsNetService::search(const Sha1CheckSum& hashed_group_id,unsigned char * if(it->second->metaData->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED ) // only cache subscribed groups { RsNxsGrp *grp = it->second ; - delete grp->metaData ; // clean private keys - grp->metaData = NULL ; + grp->metaData->keys.TlvClear() ;// clean private keys. This technically not needed, since metaData is not serialized, but I still prefer. Sha1CheckSum hash(RsDirUtil::sha1sum(it->first.toByteArray(),it->first.SIZE_IN_BYTES)); @@ -5531,9 +5557,41 @@ bool RsGxsNetService::search(const Sha1CheckSum& hashed_group_id,unsigned char * // Finally, serialize and encrypt the grp data uint32_t size = RsNxsSerialiser(mServType).size(grp_data); - RsTemporaryMemory mem(size) ; + RsNxsGrp *author_group=nullptr; - RsNxsSerialiser(mServType).serialise(grp_data,mem,&size) ; + if(!grp_data->metaData->mAuthorId.isNull()) + { +#ifdef NXS_NET_DEBUG_8 + GXSNETDEBUG___ << " this group has an author identity " << grp_data->metaData->mAuthorId << " that we need to send at the same time." << std::endl; +#endif + mGixs->retrieveNxsIdentity(grp_data->metaData->mAuthorId,author_group); // whatever gets the data + + if(!author_group) + { + std::cerr << "(EE) Cannot retrieve author group data " << grp_data->metaData->mAuthorId << " for GXS group " << grp_data->grpId << std::endl; + return false; + } + + delete author_group->metaData; // delete private information, just in case, but normally it is not serialized. + author_group->metaData = NULL ; + + size += RsNxsSerialiser(RS_SERVICE_GXS_TYPE_GXSID).size(author_group); + } + + RsTemporaryMemory mem(size) ; + uint32_t used_size=size; + + RsNxsSerialiser(mServType).serialise(grp_data,mem,&used_size) ; + + uint32_t remaining_size=size-used_size; + + if(author_group) + { +#ifdef NXS_NET_DEBUG_8 + GXSNETDEBUG___ << " Serializing author group data..." << std::endl; +#endif + RsNxsSerialiser(RS_SERVICE_GXS_TYPE_GXSID).serialise(author_group,mem+used_size,&remaining_size); + } uint8_t encryption_master_key[32]; Sha256CheckSum s = RsDirUtil::sha256sum(grp_data->grpId.toByteArray(),grp_data->grpId.SIZE_IN_BYTES); diff --git a/libretroshare/src/gxs/rsnxsobserver.h b/libretroshare/src/gxs/rsnxsobserver.h index 83db62e16..2da5067a4 100644 --- a/libretroshare/src/gxs/rsnxsobserver.h +++ b/libretroshare/src/gxs/rsnxsobserver.h @@ -39,12 +39,12 @@ public: /*! * @param messages messages are deleted after function returns */ - virtual void receiveNewMessages(std::vector& messages) = 0; + virtual void receiveNewMessages(const std::vector& messages) = 0; /*! * @param groups groups are deleted after function returns */ - virtual void receiveNewGroups(std::vector& groups) = 0; + virtual void receiveNewGroups(const std::vector& groups) = 0; /*! * \brief receiveDistantSearchResults diff --git a/libretroshare/src/services/p3idservice.cc b/libretroshare/src/services/p3idservice.cc index 609dd8ad6..b48a25abd 100644 --- a/libretroshare/src/services/p3idservice.cc +++ b/libretroshare/src/services/p3idservice.cc @@ -262,6 +262,17 @@ bool p3IdService::isARegularContact(const RsGxsId& id) return mContacts.find(id) != mContacts.end() ; } +bool p3IdService::receiveNewIdentity(RsNxsGrp *identity_grp) +{ + receiveNewGroups(std::vector{ identity_grp }); + return true; +} + +bool p3IdService::retrieveNxsIdentity(const RsGxsId& group_id,RsNxsGrp *& identity_grp) +{ + return RsGenExchange::retrieveNxsIdentity(RsGxsGroupId(group_id),identity_grp); +} + bool p3IdService::setAsRegularContact(const RsGxsId& id,bool b) { RsStackMutex stack(mIdMtx); diff --git a/libretroshare/src/services/p3idservice.h b/libretroshare/src/services/p3idservice.h index 3c6b6677c..9f9e03d17 100644 --- a/libretroshare/src/services/p3idservice.h +++ b/libretroshare/src/services/p3idservice.h @@ -198,10 +198,10 @@ class p3IdService: public RsGxsIdExchange, public RsIdentity, public GxsTokenQu public: p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes, PgpAuxUtils *pgpUtils); - virtual RsServiceInfo getServiceInfo(); + virtual RsServiceInfo getServiceInfo()override; static uint32_t idAuthenPolicy(); - virtual void service_tick(); // needed for background processing. + virtual void service_tick()override; // needed for background processing. /*! @@ -222,8 +222,8 @@ public: bool getIdentitiesSummaries(std::list& ids) override; // These are exposed via RsIdentity. - virtual bool getGroupData(const uint32_t &token, std::vector &groups); - virtual bool getGroupSerializedData(const uint32_t &token, std::map& serialized_groups); + virtual bool getGroupData(const uint32_t &token, std::vector &groups) override; + virtual bool getGroupSerializedData(const uint32_t &token, std::map& serialized_groups) override; //virtual bool getMsgData(const uint32_t &token, std::vector &opinions); @@ -233,7 +233,10 @@ public: virtual bool deleteGroup(uint32_t& token, RsGxsGroupId& group); //virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion); - /**************** RsIdentity External Interface. + virtual bool receiveNewIdentity(RsNxsGrp *identity_grp) override; + virtual bool retrieveNxsIdentity(const RsGxsId& group_id,RsNxsGrp *& identity_grp)override; + + /**************** RsIdentity External Interface. * Notes: * * All the data is cached together for the moment - We should probably @@ -243,11 +246,11 @@ public: * */ //virtual bool getNickname(const RsGxsId &id, std::string &nickname); - virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details); + virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details) override; RS_DEPRECATED_FOR(RsReputations) virtual bool submitOpinion(uint32_t& token, const RsGxsId &id, - bool absOpinion, int score); + bool absOpinion, int score) override; /// @see RsIdentity virtual bool createIdentity( @@ -255,35 +258,35 @@ public: const std::string& name, const RsGxsImage& avatar = RsGxsImage(), bool pseudonimous = true, const std::string& pgpPassword = "" ) override; - virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms); + virtual bool createIdentity(uint32_t& token, RsIdentityParameters ¶ms) override; /// @see RsIdentity bool updateIdentity(RsGxsIdGroup& identityData) override; RS_DEPRECATED - virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group); + virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group) override; /// @see RsIdentity bool deleteIdentity(RsGxsId& id) override; RS_DEPRECATED - virtual bool deleteIdentity(uint32_t& token, RsGxsIdGroup &group); + virtual bool deleteIdentity(uint32_t& token, RsGxsIdGroup &group) override; - virtual void setDeleteBannedNodesThreshold(uint32_t days) ; - virtual uint32_t deleteBannedNodesThreshold() ; + virtual void setDeleteBannedNodesThreshold(uint32_t days) override; + virtual uint32_t deleteBannedNodesThreshold() override; virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname, - const std::string &tag, RsRecognTagDetails &details); + const std::string &tag, RsRecognTagDetails &details) override; virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment, - uint16_t tag_class, uint16_t tag_type, std::string &tag); + uint16_t tag_class, uint16_t tag_type, std::string &tag) override; virtual bool setAsRegularContact(const RsGxsId& id,bool is_a_contact) override; virtual bool isARegularContact(const RsGxsId& id) override; virtual void setAutoAddFriendIdsAsContact(bool b) override; virtual bool autoAddFriendIdsAsContact() override; - virtual uint32_t nbRegularContacts() ; - virtual rstime_t getLastUsageTS(const RsGxsId &id) ; + virtual uint32_t nbRegularContacts() override; + virtual rstime_t getLastUsageTS(const RsGxsId &id) override ; /**************** RsGixs Implementation ***************/ @@ -323,12 +326,12 @@ public: uint32_t data_size, const RsGxsId& signer_id, RsTlvKeySignature& signature, - uint32_t& signing_error); + uint32_t& signing_error)override; virtual bool validateData( const uint8_t *data, uint32_t data_size, const RsTlvKeySignature& signature, bool force_load, const RsIdentityUsage &info, - uint32_t& signing_error ); + uint32_t& signing_error )override; virtual bool encryptData( const uint8_t* decrypted_data, uint32_t decrypted_data_size, @@ -336,7 +339,7 @@ public: uint32_t& encrypted_data_size, const RsGxsId& encryption_key_id, uint32_t& error_status, - bool force_load = true ); + bool force_load = true )override; bool encryptData( const uint8_t* decrypted_data, uint32_t decrypted_data_size, @@ -351,7 +354,7 @@ public: uint32_t& decrypted_data_size, const RsGxsId& decryption_key_id, uint32_t& error_status, - bool force_load = true ); + bool force_load = true )override; virtual bool decryptData(const uint8_t* encrypted_data, uint32_t encrypted_data_size, @@ -359,26 +362,24 @@ public: uint32_t& decrypted_data_size, const std::set& decrypt_ids, uint32_t& error_status, - bool force_load = true ); + bool force_load = true ); - virtual bool haveKey(const RsGxsId &id); - virtual bool havePrivateKey(const RsGxsId &id); + virtual bool haveKey(const RsGxsId &id)override; + virtual bool havePrivateKey(const RsGxsId &id)override; - virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey &key); - virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey &key); + virtual bool getKey(const RsGxsId &id, RsTlvPublicRSAKey &key)override; + virtual bool getPrivateKey(const RsGxsId &id, RsTlvPrivateRSAKey &key)override; virtual bool requestKey( const RsGxsId &id, const std::list &peers, - const RsIdentityUsage &use_info ); - virtual bool requestPrivateKey(const RsGxsId &id); + const RsIdentityUsage &use_info )override; + virtual bool requestPrivateKey(const RsGxsId &id)override; RS_DEPRECATED_FOR(exportIdentityLink) - virtual bool serialiseIdentityToMemory(const RsGxsId& id, - std::string& radix_string); + virtual bool serialiseIdentityToMemory(const RsGxsId& id, std::string& radix_string) override; RS_DEPRECATED_FOR(importIdentityLink) - virtual bool deserialiseIdentityFromMemory(const std::string& radix_string, - RsGxsId* id = nullptr); + virtual bool deserialiseIdentityFromMemory(const std::string& radix_string, RsGxsId* id = nullptr) override; /// @see RsIdentity bool requestIdentity( @@ -398,19 +399,19 @@ public: protected: /** Notifications **/ - virtual void notifyChanges(std::vector& changes); + virtual void notifyChanges(std::vector& changes) override; /** Overloaded to add PgpIdHash to Group Definition **/ - virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet); + virtual ServiceCreate_Return service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet) override; // Overloads RsGxsGenExchange - virtual bool acceptNewGroup(const RsGxsGrpMetaData *grpMeta) ; + virtual bool acceptNewGroup(const RsGxsGrpMetaData *grpMeta) override ; // Overloaded from GxsTokenQueue for Request callbacks. - virtual void handleResponse(uint32_t token, uint32_t req_type); + virtual void handleResponse(uint32_t token, uint32_t req_type) override; // Overloaded from RsTickEvent. - virtual void handle_event(uint32_t event_type, const std::string &elabel); + virtual void handle_event(uint32_t event_type, const std::string &elabel) override; //===================================================// // p3Config methods // @@ -418,10 +419,10 @@ protected: // Load/save the routing info, the pending items in transit, and the config variables. // - virtual bool loadList(std::list& items) ; - virtual bool saveList(bool& cleanup,std::list& items) ; + virtual bool loadList(std::list& items) override ; + virtual bool saveList(bool& cleanup,std::list& items) override ; - virtual RsSerialiser *setupSerialiser() ; + virtual RsSerialiser *setupSerialiser() override ; private: