mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
added secure retrieval of distant groups
This commit is contained in:
parent
db06c32e80
commit
80a43fe3d5
@ -1807,6 +1807,23 @@ bool RsGxsDataAccess::updateGroupData(RsNxsGrp* grp) {
|
||||
return mDataStore->updateGroup(grpM);
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::getGroupData(const RsGxsGroupId& grpId, RsNxsGrp *& grp_data)
|
||||
{
|
||||
RsStackMutex stack(mDataMutex);
|
||||
|
||||
std::map<RsGxsGroupId, RsNxsGrp*> grps ;
|
||||
|
||||
grps[grpId] = NULL ;
|
||||
|
||||
if(mDataStore->retrieveNxsGrps(grps, false, true)) // the false here is very important: it removes the private key parts.
|
||||
{
|
||||
grp_data = grps.begin()->second;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
|
||||
bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) {
|
||||
|
||||
RsStackMutex stack(mDataMutex);
|
||||
|
@ -156,6 +156,14 @@ public:
|
||||
*/
|
||||
bool addMsgData(RsNxsMsg* msg);
|
||||
|
||||
/*!
|
||||
* This retrieves a group from the gxs data base, this is a blocking call \n
|
||||
* @param grp the group to add, memory ownership passed to the callee
|
||||
* @return false if group cound not be retrieved
|
||||
*/
|
||||
bool getGroupData(const RsGxsGroupId& grpId,RsNxsGrp *& grp_data);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
@ -254,6 +254,7 @@
|
||||
#include "retroshare/rsgxscircles.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
#include "pgp/pgpauxutils.h"
|
||||
#include "crypto/rscrypto.h"
|
||||
#include "util/rsdir.h"
|
||||
#include "util/rstime.h"
|
||||
#include "util/rsmemory.h"
|
||||
@ -5105,7 +5106,10 @@ bool RsGxsNetService::locked_stampMsgServerUpdateTS(const RsGxsGroupId& gid)
|
||||
|
||||
TurtleRequestId RsGxsNetService::turtleGroupRequest(const RsGxsGroupId& group_id)
|
||||
{
|
||||
return mGxsNetTunnel->turtleGroupRequest(group_id,this) ;
|
||||
TurtleRequestId req = mGxsNetTunnel->turtleGroupRequest(group_id,this) ;
|
||||
mSearchRequests[req] = group_id;
|
||||
|
||||
return req;
|
||||
}
|
||||
TurtleRequestId RsGxsNetService::turtleSearchRequest(const std::string& match_string)
|
||||
{
|
||||
@ -5192,6 +5196,58 @@ void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req, const std:
|
||||
}
|
||||
}
|
||||
|
||||
void RsGxsNetService::receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " received encrypted group data for turtle search request " << std::hex << req << std::dec << ": " << RsUtil::BinToHex(encrypted_group_data,encrypted_group_data_len,50) << std::endl;
|
||||
#endif
|
||||
auto it = mSearchRequests.find(req);
|
||||
|
||||
if(mSearchRequests.end() == it)
|
||||
{
|
||||
std::cerr << "(EE) received search results for unknown request " << std::hex << req << std::dec ;
|
||||
return;
|
||||
}
|
||||
RsGxsGroupId grpId = it->second;
|
||||
|
||||
uint8_t encryption_master_key[32];
|
||||
Sha256CheckSum s = RsDirUtil::sha256sum(grpId.toByteArray(),grpId.SIZE_IN_BYTES);
|
||||
memcpy(encryption_master_key,s.toByteArray(),32);
|
||||
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " attempting data decryption with master key " << RsUtil::BinToHex(encryption_master_key,32) << std::endl;
|
||||
#endif
|
||||
unsigned char *clear_group_data = NULL;
|
||||
uint32_t clear_group_data_len ;
|
||||
|
||||
if(!librs::crypto::decryptAuthenticateData(encrypted_group_data,encrypted_group_data_len,encryption_master_key,clear_group_data,clear_group_data_len))
|
||||
{
|
||||
std::cerr << "(EE) Could not decrypt data. Something went wrong. Wrong key??" << std::endl;
|
||||
return ;
|
||||
}
|
||||
|
||||
#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) ;
|
||||
free(clear_group_data);
|
||||
clear_group_data = NULL ;
|
||||
|
||||
RsNxsGrp *nxs_grp = dynamic_cast<RsNxsGrp*>(item) ;
|
||||
|
||||
if(nxs_grp == NULL)
|
||||
{
|
||||
std::cerr << "(EE) decrypted item is not a RsNxsGrp. Weird!" << std::endl;
|
||||
return ;
|
||||
}
|
||||
std::vector<RsNxsGrp*> new_grps(1,nxs_grp);
|
||||
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " passing the grp data to observer." << std::endl;
|
||||
#endif
|
||||
mObserver->receiveNewGroups(new_grps);
|
||||
}
|
||||
|
||||
bool RsGxsNetService::search(const std::string& substring,std::list<RsGxsGroupSummary>& group_infos)
|
||||
{
|
||||
RsGxsGrpMetaTemporaryMap grpMetaMap;
|
||||
@ -5228,4 +5284,80 @@ bool RsGxsNetService::search(const std::string& substring,std::list<RsGxsGroupSu
|
||||
return !group_infos.empty();
|
||||
}
|
||||
|
||||
bool RsGxsNetService::search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)
|
||||
{
|
||||
// First look into the grp hash cache
|
||||
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " Received group data request for hash " << hashed_group_id << std::endl;
|
||||
#endif
|
||||
auto it = mGroupHashCache.find(hashed_group_id) ;
|
||||
RsNxsGrp *grp_data = NULL ;
|
||||
|
||||
if(mGroupHashCache.end() != it)
|
||||
{
|
||||
grp_data = it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Now check if the last request was too close in time, in which case, we dont retrieve data.
|
||||
|
||||
if(mLastCacheReloadTS + 60 < time(NULL))
|
||||
{
|
||||
std::cerr << "(WW) Not found in cache, and last cache reload less than 60 secs ago. Returning false. " << std::endl;
|
||||
return false ;
|
||||
}
|
||||
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " reloading group cache information" << std::endl;
|
||||
#endif
|
||||
RsNxsGrpDataTemporaryMap grpDataMap;
|
||||
{
|
||||
RS_STACK_MUTEX(mNxsMutex) ;
|
||||
mDataStore->retrieveNxsGrps(grpDataMap, true, true);
|
||||
}
|
||||
|
||||
for(auto it(grpDataMap.begin());it!=grpDataMap.end();++it)
|
||||
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 ;
|
||||
|
||||
Sha1CheckSum hash(RsDirUtil::sha1sum(it->first.toByteArray(),it->first.SIZE_IN_BYTES));
|
||||
|
||||
mGroupHashCache[hash] = grp ;
|
||||
|
||||
if(hash == hashed_group_id)
|
||||
grp_data = grp ;
|
||||
}
|
||||
}
|
||||
|
||||
if(!grp_data)
|
||||
{
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " no group found for hash " << hashed_group_id << ": returning false." << std::endl;
|
||||
#endif
|
||||
return false ;
|
||||
}
|
||||
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " found corresponding group data group id in cache group_id=" << grp_data->grpId << std::endl;
|
||||
#endif
|
||||
// Finally, serialize and encrypt the grp data
|
||||
|
||||
uint32_t size = RsNxsSerialiser(mServType).size(grp_data);
|
||||
RsTemporaryMemory mem(size) ;
|
||||
|
||||
RsNxsSerialiser(mServType).serialise(grp_data,mem,&size) ;
|
||||
|
||||
uint8_t encryption_master_key[32];
|
||||
Sha256CheckSum s = RsDirUtil::sha256sum(grp_data->grpId.toByteArray(),grp_data->grpId.SIZE_IN_BYTES);
|
||||
memcpy(encryption_master_key,s.toByteArray(),32);
|
||||
|
||||
#ifdef NXS_NET_DEBUG_8
|
||||
GXSNETDEBUG___ << " sending data encrypted with master key " << RsUtil::BinToHex(encryption_master_key,32) << std::endl;
|
||||
#endif
|
||||
return librs::crypto::encryptAuthenticateData(mem,size,encryption_master_key,encrypted_group_data,encrypted_group_data_len);
|
||||
}
|
||||
|
||||
|
@ -131,7 +131,10 @@ public:
|
||||
virtual TurtleRequestId turtleSearchRequest(const std::string& match_string);
|
||||
|
||||
virtual bool search(const std::string& substring,std::list<RsGxsGroupSummary>& group_infos) ;
|
||||
virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len);
|
||||
virtual void receiveTurtleSearchResults(TurtleRequestId req,const std::list<RsGxsGroupSummary>& group_infos);
|
||||
virtual void receiveTurtleSearchResults(TurtleRequestId req,const unsigned char *encrypted_group_data,uint32_t encrypted_group_data_len);
|
||||
|
||||
virtual bool retrieveDistantSearchResults(TurtleRequestId req, std::map<RsGxsGroupId, RsGxsGroupSummary> &group_infos);
|
||||
virtual bool clearDistantSearchResults(const TurtleRequestId& id);
|
||||
virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&,RsGxsGroupSummary&);
|
||||
@ -609,6 +612,10 @@ private:
|
||||
|
||||
uint32_t mDefaultMsgStorePeriod ;
|
||||
uint32_t mDefaultMsgSyncPeriod ;
|
||||
|
||||
std::map<Sha1CheckSum, RsNxsGrp*> mGroupHashCache;
|
||||
std::map<TurtleRequestId,RsGxsGroupId> mSearchRequests;
|
||||
time_t mLastCacheReloadTS ;
|
||||
};
|
||||
|
||||
#endif // RSGXSNETSERVICE_H
|
||||
|
@ -163,6 +163,27 @@ public:
|
||||
RsTypeSerializer::serial_process(j,ctx,group_infos,"group_infos") ;
|
||||
}
|
||||
};
|
||||
class RsGxsNetTunnelTurtleSearchGroupDataItem: public RsGxsNetTunnelItem
|
||||
{
|
||||
public:
|
||||
explicit RsGxsNetTunnelTurtleSearchGroupDataItem(): RsGxsNetTunnelItem(RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA) {}
|
||||
virtual ~RsGxsNetTunnelTurtleSearchGroupDataItem() {}
|
||||
|
||||
uint16_t service ;
|
||||
unsigned char *encrypted_group_data ;
|
||||
uint32_t encrypted_group_data_len ;
|
||||
|
||||
virtual void clear() { free(encrypted_group_data);encrypted_group_data=NULL;encrypted_group_data_len=0; }
|
||||
|
||||
virtual void serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||
{
|
||||
RsTypeSerializer::serial_process<uint16_t>(j,ctx,service,"service") ;
|
||||
|
||||
RsTypeSerializer::TlvMemBlock_proxy prox(encrypted_group_data,encrypted_group_data_len) ;
|
||||
RsTypeSerializer::serial_process(j,ctx,prox,"encrypted_group_data") ;
|
||||
}
|
||||
};
|
||||
|
||||
class RsGxsNetTunnelSerializer: public RsServiceSerializer
|
||||
{
|
||||
public:
|
||||
@ -184,7 +205,7 @@ public:
|
||||
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_SUBSTRING : return new RsGxsNetTunnelTurtleSearchSubstringItem;
|
||||
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_REQUEST : return new RsGxsNetTunnelTurtleSearchGroupRequestItem;
|
||||
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_SUMMARY : return new RsGxsNetTunnelTurtleSearchGroupSummaryItem;
|
||||
//case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA : return new RsGxsNetTunnelTurtleSearchGroupDataItem;
|
||||
case RS_PKT_SUBTYPE_GXS_NET_TUNNEL_TURTLE_SEARCH_GROUP_DATA : return new RsGxsNetTunnelTurtleSearchGroupDataItem;
|
||||
default:
|
||||
GXS_NET_TUNNEL_ERROR() << "type ID " << std::hex << (int)item_subtype << std::dec << " is not handled!" << std::endl;
|
||||
return NULL ;
|
||||
@ -1033,20 +1054,22 @@ bool RsGxsNetTunnelService::receiveSearchRequest(unsigned char *search_request_d
|
||||
|
||||
if(substring_gr != NULL)
|
||||
{
|
||||
#ifdef TODO
|
||||
auto it = mSearchableGxsServices.find(substring_sr->service) ;
|
||||
RS_STACK_MUTEX(mGxsNetTunnelMtx);
|
||||
auto it = mSearchableServices.find(substring_gr->service) ;
|
||||
|
||||
RsNxsGrp *grp = NULL ;
|
||||
unsigned char *encrypted_group_data = NULL ;
|
||||
uint32_t encrypted_group_data_len = 0 ;
|
||||
|
||||
if(it != mSearchableGxsServices.end() && it->second.search(substring_sr->group_id,grp))
|
||||
if(it != mSearchableServices.end() && it->second->search(substring_gr->hashed_group_id,encrypted_group_data,encrypted_group_data_len))
|
||||
{
|
||||
RsGxsNetTunnelTurtleSearchGroupDataItem search_result_item ;
|
||||
|
||||
search_result_item.service = substring_sr->service ;
|
||||
search_result_item.group_infos = results ;
|
||||
search_result_item.encrypted_group_data = encrypted_group_data ;
|
||||
search_result_item.encrypted_group_data_len = encrypted_group_data_len;
|
||||
|
||||
search_result_data_size = RsGxsNetTunnelSerializer().size(&search_result_item) ;
|
||||
search_result_data = (unsigned char*)rs_malloc(size) ;
|
||||
search_result_data = (unsigned char*)rs_malloc(search_result_data_size) ;
|
||||
|
||||
if(search_result_data == NULL)
|
||||
return false ;
|
||||
@ -1055,7 +1078,6 @@ bool RsGxsNetTunnelService::receiveSearchRequest(unsigned char *search_request_d
|
||||
|
||||
return true ;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return false ;
|
||||
|
@ -133,6 +133,7 @@ public:
|
||||
virtual bool retrieveDistantGroupSummary(const RsGxsGroupId&,RsGxsGroupSummary&)=0;
|
||||
|
||||
virtual bool search(const std::string& substring,std::list<RsGxsGroupSummary>& group_infos) =0;
|
||||
virtual bool search(const Sha1CheckSum& hashed_group_id,unsigned char *& encrypted_group_data,uint32_t& encrypted_group_data_len)=0;
|
||||
|
||||
/*!
|
||||
* Initiates a search through the network
|
||||
@ -152,6 +153,9 @@ public:
|
||||
*/
|
||||
//virtual int searchGrps(RsGxsSearch* search, uint8_t hops = 1, bool retrieve = 0) = 0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// DATA ACCESS FUNCTIONS ///
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/*!
|
||||
* pauses synchronisation of subscribed groups and request for group id
|
||||
|
Loading…
Reference in New Issue
Block a user