mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-15 02:44:20 -05:00
added key sharing facility for distrib groups
- not yet complete, clients not receiving key git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3004 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
f44de1146a
commit
cf785bb8a3
@ -186,6 +186,13 @@ virtual bool channelExtraFileRemove(std::string hash, std::string chId) = 0;
|
||||
*/
|
||||
virtual bool channelRestoreKeys(std::string chId) = 0;
|
||||
|
||||
/*!
|
||||
* shares keys with peers
|
||||
*@param chId the channel for which private publish keys will be shared
|
||||
*@param peers peers in this list will be sent keys
|
||||
*
|
||||
*/
|
||||
virtual bool channelShareKeys(std::string chId, std::list<std::string>& peers) = 0;
|
||||
/****************************************/
|
||||
|
||||
};
|
||||
|
@ -87,6 +87,7 @@ const uint16_t RS_SERVICE_TYPE_PHOTO = 0xf040;
|
||||
const uint16_t RS_SERVICE_TYPE_DISTRIB = 0xf110;
|
||||
const uint16_t RS_SERVICE_TYPE_FORUM = 0xf120;
|
||||
const uint16_t RS_SERVICE_TYPE_CHANNEL = 0xf130;
|
||||
const uint16_t RS_SERVICE_TYPE_CHANNEL_SOCKET = 0xf140;
|
||||
|
||||
/* Games/External Apps - Service Only */
|
||||
const uint16_t RS_SERVICE_TYPE_GAME_LAUNCHER = 0xf200;
|
||||
|
@ -437,6 +437,16 @@ bool p3Channels::channelSubscribe(std::string cId, bool subscribe)
|
||||
return subscribeToGroup(cId, subscribe);
|
||||
}
|
||||
|
||||
bool p3Channels::channelShareKeys(std::string chId, std::list<std::string>& peers){
|
||||
|
||||
#ifdef CHANNEL_DEBUG
|
||||
std::cerr << "p3Channels::channelShareKeys() " << chId << std::endl;
|
||||
#endif
|
||||
|
||||
return sharePubKey(chId, peers);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
|
@ -72,7 +72,7 @@ virtual bool channelSubscribe(std::string cId, bool subscribe);
|
||||
virtual bool channelExtraFileHash(std::string path, std::string chId, FileInfo& fInfo);
|
||||
virtual bool channelExtraFileRemove(std::string hash, std::string chId);
|
||||
virtual bool channelRestoreKeys(std::string chId);
|
||||
|
||||
virtual bool channelShareKeys(std::string chId, std::list<std::string>& peers);
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
/***************************************************************************************/
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "rsiface/rsdistrib.h"
|
||||
#include "services/p3distrib.h"
|
||||
@ -56,12 +57,12 @@ p3GroupDistrib::p3GroupDistrib(uint16_t subtype,
|
||||
|
||||
:CacheSource(subtype, true, cs, sourcedir),
|
||||
CacheStore(subtype, true, cs, cft, storedir),
|
||||
p3Config(configId), nullService(subtype),
|
||||
p3Config(configId), p3Service(RS_SERVICE_TYPE_DISTRIB),
|
||||
mStorePeriod(storePeriod),
|
||||
mPubPeriod(pubPeriod),
|
||||
mLastPublishTime(0),
|
||||
mMaxCacheSubId(1),
|
||||
mKeyBackUpDir(keyBackUpDir), BACKUP_KEY_FILE("key.log")
|
||||
mKeyBackUpDir(keyBackUpDir), BACKUP_KEY_FILE("key.log"), mLastKeyPublishTime(0)
|
||||
{
|
||||
/* not much yet */
|
||||
time_t now = time(NULL);
|
||||
@ -70,6 +71,8 @@ p3GroupDistrib::p3GroupDistrib(uint16_t subtype,
|
||||
mGroupsRepublish = true;
|
||||
|
||||
mOwnId = AuthSSL::getAuthSSL()->OwnId();
|
||||
|
||||
addSerialType(new RsDistribSerialiser());
|
||||
return;
|
||||
}
|
||||
|
||||
@ -88,6 +91,7 @@ int p3GroupDistrib::tick()
|
||||
{
|
||||
RsStackMutex stack(distribMtx); /**** STACK LOCKED MUTEX ****/
|
||||
toPublish = (mPendingPublish.size() > 0) && (now > mPubPeriod + mLastPublishTime);
|
||||
|
||||
}
|
||||
|
||||
if (toPublish)
|
||||
@ -113,6 +117,32 @@ int p3GroupDistrib::tick()
|
||||
mGroupsRepublish = false;
|
||||
}
|
||||
|
||||
{
|
||||
RsStackMutex stack(distribMtx);
|
||||
toPublish = (mPendingPubKeyRecipients.size() > 0) && (now > 5 + mLastKeyPublishTime);
|
||||
}
|
||||
|
||||
if(toPublish){
|
||||
RsStackMutex stack(distribMtx);
|
||||
locked_sharePubKey();
|
||||
}
|
||||
|
||||
bool toReceive = receivedItems();
|
||||
|
||||
if(toReceive){
|
||||
RsStackMutex stack(distribMtx);
|
||||
locked_receivePubKeys();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
RsStackMutex stack(distribMtx);
|
||||
|
||||
if(mPubKeysRecvd){
|
||||
locked_loadRecvdPubKeys();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1767,12 +1797,16 @@ bool p3GroupDistrib::restoreGrpKeys(std::string grpId){
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ok &= itemAttempted;
|
||||
|
||||
if(ok){
|
||||
gi->flags |= RS_DISTRIB_SUBSCRIBED;
|
||||
locked_notifyGroupChanged(*gi, GRP_SUBSCRIBED);
|
||||
IndicateConfigChanged();
|
||||
mGroupsRepublish = true;
|
||||
|
||||
ok &= itemAttempted;
|
||||
}
|
||||
|
||||
#ifdef DISTRIB_DEBUG
|
||||
if(!ok){
|
||||
@ -1785,6 +1819,201 @@ bool p3GroupDistrib::restoreGrpKeys(std::string grpId){
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool p3GroupDistrib::sharePubKey(std::string grpId, std::list<std::string>& peers){
|
||||
|
||||
RsStackMutex stack(distribMtx);
|
||||
|
||||
// first check that group actually exists
|
||||
if(mGroups.find(grpId) == mGroups.end()){
|
||||
#ifdef DISTRIB_DEBUG
|
||||
std::cerr << "p3GroupDistrib::sharePubKey(): Group does not exist" << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// add to pending list to be sent
|
||||
mPendingPubKeyRecipients[grpId] = peers;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void p3GroupDistrib::locked_sharePubKey(){
|
||||
|
||||
|
||||
#ifdef DISTRIB_DEBUG
|
||||
std::cerr << "p3GroupDistrib::locked_sharePubKey() " << std::endl;
|
||||
#endif
|
||||
|
||||
std::map<std::string, std::list<std::string> >::iterator mit;
|
||||
std::list<std::string>::iterator lit;
|
||||
|
||||
// get list of peers that are online
|
||||
std::list<std::string> peersOnline;
|
||||
rsPeers->getOnlineList(peersOnline);
|
||||
std::list<std::string> toDelete;
|
||||
|
||||
/* send public key to peers online */
|
||||
|
||||
for(mit = mPendingPubKeyRecipients.begin(); mit != mPendingPubKeyRecipients.end(); mit++){
|
||||
|
||||
GroupInfo *gi = locked_getGroupInfo(mit->first);
|
||||
|
||||
if(gi == NULL){
|
||||
toDelete.push_back(mit->first); // grp does not exist, stop attempting to share key for dead group
|
||||
continue;
|
||||
}
|
||||
|
||||
// find full public key, and send to given peers
|
||||
std::map<std::string, GroupKey>::iterator kit;
|
||||
for(kit = gi->publishKeys.begin();
|
||||
kit != gi->publishKeys.end(); kit++)
|
||||
{
|
||||
if (kit->second.type & RSTLV_KEY_TYPE_FULL)
|
||||
{
|
||||
#ifdef DISTRIB_DEBUG
|
||||
std::cerr << "p3GroupDistrib::locked_sharePubKey() Sharing Key: " << kit->first;
|
||||
std::cerr << std::endl;
|
||||
#endif
|
||||
|
||||
// send keys to peers who are online
|
||||
for(lit = mit->second.begin() ; lit != mit->second.end(); lit++){
|
||||
|
||||
if(std::find(peersOnline.begin(), peersOnline.end(), *lit) != peersOnline.end()){
|
||||
|
||||
/* create Key for sharing */
|
||||
RsDistribGrpKey* pubKey = new RsDistribGrpKey();
|
||||
|
||||
|
||||
pubKey->clear();
|
||||
pubKey->grpId = mit->first;
|
||||
|
||||
RSA *rsa_priv = EVP_PKEY_get1_RSA(kit->second.key);
|
||||
setRSAPrivateKey(pubKey->key, rsa_priv);
|
||||
RSA_free(rsa_priv);
|
||||
|
||||
pubKey->key.keyFlags = kit->second.type;
|
||||
pubKey->key.startTS = kit->second.startTS;
|
||||
pubKey->key.endTS = kit->second.endTS;
|
||||
pubKey->PeerId(*lit);
|
||||
std::cout << *lit << std::endl;
|
||||
sendItem(pubKey);
|
||||
|
||||
// remove peer from list
|
||||
lit = mit->second.erase(lit); // no need to send to peer anymore
|
||||
lit--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if given peers have all received key(s) then stop sending for group
|
||||
if(mit->second.empty())
|
||||
toDelete.push_back(mit->first);
|
||||
}
|
||||
|
||||
// delete pending peer list which are done with
|
||||
for(lit = toDelete.begin(); lit != toDelete.end(); lit++)
|
||||
mPendingPubKeyRecipients.erase(*lit);
|
||||
|
||||
mLastKeyPublishTime = time(NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void p3GroupDistrib::locked_receivePubKeys(){
|
||||
|
||||
|
||||
RsItem* item;
|
||||
|
||||
while(NULL != (item = recvItem())){
|
||||
|
||||
RsDistribGrpKey* key_item = dynamic_cast<RsDistribGrpKey*>(item);
|
||||
|
||||
if(key_item != NULL){
|
||||
|
||||
|
||||
#ifdef STATUS_DEBUG
|
||||
std::cerr << "p3GroupDistrib::locked_receiveKeys()" << std::endl;
|
||||
std::cerr << "PeerId : " << key_item->PeerId() << std::endl;
|
||||
std::cerr << "GrpId: " << key_item->grpId << std::endl;
|
||||
std::cerr << "Got key Item" << std::endl;
|
||||
#endif
|
||||
if(key_item->key.keyFlags == RSTLV_KEY_TYPE_FULL){
|
||||
mRecvdPubKeys[key_item->grpId] = key_item;
|
||||
}
|
||||
else{
|
||||
std::cerr << "p3GroupDistrib::locked_receiveKeys():" << "Not full public key"
|
||||
<< "Deleting item"<< std::endl;
|
||||
delete key_item;
|
||||
}
|
||||
}else{
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
|
||||
if(mRecvdPubKeys.size() != 0){
|
||||
mPubKeysRecvd = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void p3GroupDistrib::locked_loadRecvdPubKeys(){
|
||||
|
||||
std::map<std::string, RsDistribGrpKey* >::iterator mit;
|
||||
GroupInfo *gi;
|
||||
std::list<std::string> toDelete;
|
||||
|
||||
#ifdef DISTRIB_DEBUG
|
||||
std::cerr << "p3GroupDistrib::locked_loadRecvdPubKeys() " << std::endl;
|
||||
#endif
|
||||
|
||||
bool ok = false;
|
||||
|
||||
// load received keys
|
||||
for(mit = mRecvdPubKeys.begin(); mit != mRecvdPubKeys.end(); mit++ ){
|
||||
|
||||
gi = locked_getGroupInfo(mit->second->grpId);
|
||||
|
||||
if(gi != NULL){
|
||||
|
||||
|
||||
|
||||
if(locked_updateGroupPublishKey(*gi, mit->second)){
|
||||
toDelete.push_back(mit->first);
|
||||
gi->flags |= RS_DISTRIB_SUBSCRIBED;
|
||||
locked_notifyGroupChanged(*gi, GRP_SUBSCRIBED);
|
||||
ok |= true;
|
||||
}
|
||||
else
|
||||
std::cerr << "p3GroupDistrib::locked_loadRecvdPubKeys(): Failed to load" << std::endl;
|
||||
|
||||
}else{
|
||||
|
||||
std::cerr << "p3GroupDistrib::locked_loadRecvdPubKeys(): group does not exist" << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(mRecvdPubKeys.size() == 0)
|
||||
mPubKeysRecvd = false;
|
||||
|
||||
|
||||
if(ok)
|
||||
IndicateConfigChanged();
|
||||
|
||||
std::list<std::string >::iterator lit;
|
||||
|
||||
// delete keys that have been loaded to groups
|
||||
for(lit = toDelete.begin(); lit != toDelete.end(); lit++)
|
||||
mRecvdPubKeys.erase(*lit);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string p3GroupDistrib::publishMsg(RsDistribMsg *msg, bool personalSign)
|
||||
{
|
||||
|
||||
|
@ -236,7 +236,7 @@ const uint32_t GRP_UNSUBSCRIBED = 0x0006;
|
||||
*
|
||||
* Create a Signing structure for Messages in general.
|
||||
*/
|
||||
class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, public nullService
|
||||
class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, public p3Service
|
||||
{
|
||||
public:
|
||||
|
||||
@ -256,12 +256,6 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
|
||||
virtual bool loadLocalCache(const CacheData &data); /// overloaded from Cache Source
|
||||
virtual int loadCache(const CacheData &data); /// overloaded from Cache Store
|
||||
|
||||
/**
|
||||
* @param grpId the grpId id for which backup keys should be restored
|
||||
* @return false if failed and vice versa
|
||||
*/
|
||||
virtual bool restoreGrpKeys(std::string grpId); /// restores a group keys from backup
|
||||
|
||||
private:
|
||||
/* top level load */
|
||||
int loadAnyCache(const CacheData &data, bool local);
|
||||
@ -270,6 +264,7 @@ int loadAnyCache(const CacheData &data, bool local);
|
||||
void loadFileGroups(std::string filename, std::string src, bool local);
|
||||
void loadFileMsgs(std::string filename, uint16_t cacheSubId, std::string src, uint32_t ts, bool local);
|
||||
bool backUpKeys(const std::list<RsDistribGrpKey* > &keysToBackUp, std::string grpId);
|
||||
void locked_sharePubKey();
|
||||
|
||||
protected:
|
||||
/* load cache msgs */
|
||||
@ -368,6 +363,28 @@ void clear_local_caches(time_t now);
|
||||
void locked_publishPendingMsgs();
|
||||
uint16_t locked_determineCacheSubId();
|
||||
|
||||
/**
|
||||
* @param grpId the grpId id for which backup keys should be restored
|
||||
* @return false if failed and vice versa
|
||||
*/
|
||||
virtual bool restoreGrpKeys(std::string grpId); /// restores a group keys from backup
|
||||
|
||||
/**
|
||||
* @param grpId the group for which to share public keys
|
||||
* @param peers The peers to which public keys should be sent
|
||||
*/
|
||||
virtual bool sharePubKey(std::string grpId, std::list<std::string>& peers);
|
||||
|
||||
/**
|
||||
* attempts to receive publication keys
|
||||
*/
|
||||
virtual void locked_receivePubKeys();
|
||||
|
||||
/**
|
||||
* this load received pub keys, useful in the case that publish keys have been received
|
||||
* but group info hasn't
|
||||
*/
|
||||
virtual void locked_loadRecvdPubKeys();
|
||||
|
||||
|
||||
/***************************************************************************************/
|
||||
@ -449,11 +466,17 @@ bool groupsChanged(std::list<std::string> &groupIds);
|
||||
|
||||
bool mGroupsChanged;
|
||||
bool mGroupsRepublish;
|
||||
bool mPubKeysRecvd;
|
||||
|
||||
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
|
||||
std::string mKeyBackUpDir;
|
||||
const std::string BACKUP_KEY_FILE;
|
||||
|
||||
std::map<std::string, RsDistribGrpKey* > mRecvdPubKeys; /// full publishing keys received from users
|
||||
std::map<std::string, std::list<std::string> > mPendingPubKeyRecipients; /// peers to receive publics key for a given grp
|
||||
time_t mLastKeyPublishTime;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user