mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
added key backup and restore to p3distrib service
git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@2957 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
parent
3e1c18fac3
commit
e48ede4841
@ -180,6 +180,12 @@ virtual bool channelExtraFileHash(std::string path, std::string chId, FileInfo&
|
||||
*/
|
||||
virtual bool channelExtraFileRemove(std::string hash, std::string chId) = 0;
|
||||
|
||||
/*!
|
||||
* Restores channel private keys for channel in the event keys stored in configuration files are lost
|
||||
* @param chId channel id to restore keys for
|
||||
*/
|
||||
virtual bool channelRestoreKeys(std::string chId) = 0;
|
||||
|
||||
/****************************************/
|
||||
|
||||
};
|
||||
|
@ -2042,6 +2042,7 @@ int RsServer::StartupRetroShare()
|
||||
std::string remotecachedir = config_dir + "/cache/remote";
|
||||
std::string channelsdir = config_dir + "/channels";
|
||||
std::string blogsdir = config_dir + "/blogs";
|
||||
std::string forumdir = config_dir + "/forums";
|
||||
|
||||
|
||||
//mRanking = NULL;
|
||||
@ -2054,7 +2055,7 @@ int RsServer::StartupRetroShare()
|
||||
|
||||
p3Forums *mForums = new p3Forums(RS_SERVICE_TYPE_FORUM,
|
||||
mCacheStrapper, mCacheTransfer,
|
||||
localcachedir, remotecachedir);
|
||||
localcachedir, remotecachedir, forumdir);
|
||||
|
||||
CachePair cp4(mForums, mForums, CacheId(RS_SERVICE_TYPE_FORUM, 0));
|
||||
mCacheStrapper -> addCachePair(cp4);
|
||||
|
@ -74,7 +74,7 @@ RsBlogs *rsBlogs = NULL;
|
||||
p3Blogs::p3Blogs(uint16_t type, CacheStrapper *cs,
|
||||
CacheTransfer *cft, RsFiles *files,
|
||||
std::string srcdir, std::string storedir, std::string blogDir)
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir,
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir, blogDir,
|
||||
CONFIG_TYPE_QBLOG, BLOG_STOREPERIOD, BLOG_PUBPERIOD),
|
||||
mRsFiles(files),
|
||||
mBlogsDir(blogDir)
|
||||
|
@ -71,7 +71,7 @@ RsChannels *rsChannels = NULL;
|
||||
p3Channels::p3Channels(uint16_t type, CacheStrapper *cs,
|
||||
CacheTransfer *cft, RsFiles *files,
|
||||
std::string srcdir, std::string storedir, std::string chanDir)
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir,
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir, chanDir,
|
||||
CONFIG_TYPE_CHANNELS, CHANNEL_STOREPERIOD, CHANNEL_PUBPERIOD),
|
||||
mRsFiles(files),
|
||||
mChannelsDir(chanDir)
|
||||
@ -224,6 +224,11 @@ bool p3Channels::getChannelMessage(std::string fId, std::string mId, ChannelMsgI
|
||||
return true;
|
||||
}
|
||||
|
||||
bool p3Channels::channelRestoreKeys(std::string chId){
|
||||
|
||||
return p3GroupDistrib::restoreGrpKeys(chId);
|
||||
}
|
||||
|
||||
bool p3Channels::ChannelMessageSend(ChannelMsgInfo &info)
|
||||
{
|
||||
|
||||
|
@ -71,6 +71,7 @@ virtual bool ChannelMessageSend(ChannelMsgInfo &info);
|
||||
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);
|
||||
|
||||
/***************************************************************************************/
|
||||
/****************** Event Feedback (Overloaded form p3distrib) *************************/
|
||||
|
@ -51,7 +51,7 @@ void setRSAPrivateKey(RsTlvSecurityKey &key, RSA *rsa_priv);
|
||||
p3GroupDistrib::p3GroupDistrib(uint16_t subtype,
|
||||
CacheStrapper *cs, CacheTransfer *cft,
|
||||
std::string sourcedir, std::string storedir,
|
||||
uint32_t configId,
|
||||
std::string keyBackUpDir, uint32_t configId,
|
||||
uint32_t storePeriod, uint32_t pubPeriod)
|
||||
|
||||
:CacheSource(subtype, true, cs, sourcedir),
|
||||
@ -60,7 +60,8 @@ p3GroupDistrib::p3GroupDistrib(uint16_t subtype,
|
||||
mStorePeriod(storePeriod),
|
||||
mPubPeriod(pubPeriod),
|
||||
mLastPublishTime(0),
|
||||
mMaxCacheSubId(1)
|
||||
mMaxCacheSubId(1),
|
||||
mKeyBackUpDir(keyBackUpDir), BACKUP_KEY_FILE("key.log")
|
||||
{
|
||||
/* not much yet */
|
||||
time_t now = time(NULL);
|
||||
@ -1499,6 +1500,9 @@ std::string p3GroupDistrib::createGroup(std::wstring name, std::wstring desc, ui
|
||||
std::string grpId;
|
||||
time_t now = time(NULL);
|
||||
|
||||
/* for backup */
|
||||
std::list<RsDistribGrpKey* > grpKeySet;
|
||||
|
||||
/* create Keys */
|
||||
RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL);
|
||||
RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin);
|
||||
@ -1533,13 +1537,16 @@ std::string p3GroupDistrib::createGroup(std::wstring name, std::wstring desc, ui
|
||||
|
||||
|
||||
|
||||
|
||||
/* set keys */
|
||||
setRSAPublicKey(newGrp->adminKey, rsa_admin_pub);
|
||||
newGrp->adminKey.keyFlags = RSTLV_KEY_TYPE_PUBLIC_ONLY | RSTLV_KEY_DISTRIB_ADMIN;
|
||||
newGrp->adminKey.startTS = now;
|
||||
newGrp->adminKey.endTS = 0; /* no end */
|
||||
|
||||
|
||||
RsTlvSecurityKey publish_key;
|
||||
|
||||
setRSAPublicKey(publish_key, rsa_publish_pub);
|
||||
|
||||
publish_key.keyFlags = RSTLV_KEY_TYPE_PUBLIC_ONLY;
|
||||
@ -1568,6 +1575,7 @@ std::string p3GroupDistrib::createGroup(std::wstring name, std::wstring desc, ui
|
||||
adKey->key.startTS = newGrp->adminKey.startTS;
|
||||
adKey->key.endTS = newGrp->adminKey.endTS;
|
||||
|
||||
|
||||
RsDistribGrpKey *pubKey = new RsDistribGrpKey();
|
||||
pubKey->grpId = grpId;
|
||||
|
||||
@ -1596,6 +1604,13 @@ std::string p3GroupDistrib::createGroup(std::wstring name, std::wstring desc, ui
|
||||
grpId = newGrp->adminKey.keyId;
|
||||
newGrp->grpId = grpId;
|
||||
|
||||
/************* Back up Keys *********************/
|
||||
|
||||
grpKeySet.push_back(adKey);
|
||||
grpKeySet.push_back(pubKey);
|
||||
|
||||
backUpKeys(grpKeySet, grpId);
|
||||
|
||||
/************** Serialise and sign **************************************/
|
||||
EVP_PKEY *key_admin = EVP_PKEY_new();
|
||||
EVP_PKEY_assign_RSA(key_admin, rsa_admin);
|
||||
@ -1660,6 +1675,114 @@ std::string p3GroupDistrib::createGroup(std::wstring name, std::wstring desc, ui
|
||||
}
|
||||
|
||||
|
||||
bool p3GroupDistrib::backUpKeys(const std::list<RsDistribGrpKey* >& keysToBackUp, std::string grpId){
|
||||
|
||||
#ifdef DISTRIB_DEBUG
|
||||
std::cerr << "P3Distrib::backUpKeys() Backing up keys for grpId: " << grpId << std::endl;
|
||||
#endif
|
||||
|
||||
std::string filename = mKeyBackUpDir + "/" + grpId + "_" + BACKUP_KEY_FILE;
|
||||
std::string filenametmp = filename + ".tmp";
|
||||
|
||||
BinInterface *bio = new BinFileInterface(filenametmp.c_str(), BIN_FLAGS_WRITEABLE);
|
||||
pqistore *store = createStore(bio, mOwnId, BIN_FLAGS_NO_DELETE | BIN_FLAGS_WRITEABLE);
|
||||
|
||||
std::list<RsDistribGrpKey* >::const_iterator it;
|
||||
bool ok = true;
|
||||
|
||||
for(it=keysToBackUp.begin(); it != keysToBackUp.end(); it++){
|
||||
|
||||
ok &= store->SendItem(*it);
|
||||
|
||||
}
|
||||
|
||||
if(!RsDirUtil::renameFile(filenametmp,filename))
|
||||
{
|
||||
std::ostringstream errlog;
|
||||
#ifdef WIN32
|
||||
errlog << "Error " << GetLastError() ;
|
||||
#else
|
||||
errlog << "Error " << errno ;
|
||||
#endif
|
||||
getPqiNotify()->AddSysMessage(0, RS_SYS_WARNING, "File rename error", "Error while renaming file " + filename + ": got error "+errlog.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
delete store;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool p3GroupDistrib::restoreGrpKeys(std::string grpId){
|
||||
|
||||
|
||||
#ifdef DISTRIB_DEBUG
|
||||
std::cerr << "p3Distrib::restoreGrpKeys() Attempting to restore private keys for grp: "
|
||||
<< grpId << std::endl;
|
||||
#endif
|
||||
|
||||
// build key directory name
|
||||
std::string filename = mKeyBackUpDir + "/"+ grpId + "_" + BACKUP_KEY_FILE;
|
||||
|
||||
|
||||
/* create the serialiser to load keys */
|
||||
BinInterface *bio = new BinFileInterface(filename.c_str(), BIN_FLAGS_READABLE);
|
||||
pqistore *store = createStore(bio, mOwnId, BIN_FLAGS_READABLE);
|
||||
|
||||
RsItem* item;
|
||||
bool ok = true;
|
||||
bool itemAttempted = false;
|
||||
|
||||
RsStackMutex stack(distribMtx);
|
||||
|
||||
GroupInfo* gi = locked_getGroupInfo(grpId);
|
||||
|
||||
//retrieve keys from file and load to appropriate grp
|
||||
while(NULL != (item = store->GetItem())){
|
||||
|
||||
itemAttempted = true;
|
||||
RsDistribGrpKey* key = dynamic_cast<RsDistribGrpKey* >(item);
|
||||
|
||||
if(key == NULL){
|
||||
#ifdef DISTRIB_DEBUG
|
||||
std::cerr << "p3groupDistrib::restoreGrpKey() Key file / grp key item not Valid, grp: "
|
||||
"\ngrpId: " << grpId << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
if(key->key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN){
|
||||
|
||||
ok &= locked_updateGroupAdminKey(*gi, key);
|
||||
|
||||
}else
|
||||
if((key->key.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)){
|
||||
|
||||
ok &= locked_updateGroupPublishKey(*gi, key);
|
||||
|
||||
}else{
|
||||
|
||||
ok &= false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
locked_notifyGroupChanged(*gi, GRP_SUBSCRIBED);
|
||||
mGroupsRepublish = true;
|
||||
|
||||
ok &= itemAttempted;
|
||||
|
||||
#ifdef DISTRIB_DEBUG
|
||||
if(!ok){
|
||||
std::cerr << "p3Distrib::restoreGrpKeys() Failed to restore private keys for grp "
|
||||
<< "\ngrpId: " << grpId << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
delete store;
|
||||
|
||||
return ok;
|
||||
}
|
||||
std::string p3GroupDistrib::publishMsg(RsDistribMsg *msg, bool personalSign)
|
||||
{
|
||||
|
||||
|
@ -232,6 +232,8 @@ const uint32_t GRP_UNSUBSCRIBED = 0x0006;
|
||||
* - Channels only some get publish key.
|
||||
* - Forums everyone gets publish private key.
|
||||
*
|
||||
* Group id is the public admin keys id
|
||||
*
|
||||
* Create a Signing structure for Messages in general.
|
||||
*/
|
||||
class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, public nullService
|
||||
@ -240,7 +242,7 @@ class p3GroupDistrib: public CacheSource, public CacheStore, public p3Config, pu
|
||||
|
||||
p3GroupDistrib(uint16_t subtype,
|
||||
CacheStrapper *cs, CacheTransfer *cft,
|
||||
std::string sourcedir, std::string storedir,
|
||||
std::string sourcedir, std::string storedir, std::string keyBackUpDir,
|
||||
uint32_t configId,
|
||||
uint32_t storePeriod, uint32_t pubPeriod);
|
||||
|
||||
@ -254,6 +256,12 @@ 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);
|
||||
@ -261,6 +269,7 @@ int loadAnyCache(const CacheData &data, bool local);
|
||||
/* load cache files */
|
||||
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);
|
||||
|
||||
protected:
|
||||
/* load cache msgs */
|
||||
@ -442,6 +451,8 @@ bool groupsChanged(std::list<std::string> &groupIds);
|
||||
bool mGroupsRepublish;
|
||||
|
||||
std::list<RsItem *> saveCleanupList; /* TEMPORARY LIST WHEN SAVING */
|
||||
std::string mKeyBackUpDir;
|
||||
const std::string BACKUP_KEY_FILE;
|
||||
|
||||
};
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "services/p3forums.h"
|
||||
#include "pqi/authssl.h"
|
||||
#include "util/rsdir.h"
|
||||
|
||||
uint32_t convertToInternalFlags(uint32_t extFlags);
|
||||
uint32_t convertToExternalFlags(uint32_t intFlags);
|
||||
@ -77,12 +78,17 @@ RsForums *rsForums = NULL;
|
||||
#define FORUM_PUBPERIOD 600 /* 10 minutes ... (max = 455 days) */
|
||||
|
||||
p3Forums::p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
|
||||
std::string srcdir, std::string storedir)
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir,
|
||||
std::string srcdir, std::string storedir, std::string forumDir)
|
||||
:p3GroupDistrib(type, cs, cft, srcdir, storedir, forumDir,
|
||||
CONFIG_TYPE_FORUMS, FORUM_STOREPERIOD, FORUM_PUBPERIOD),
|
||||
mForumsChanged(false)
|
||||
mForumsChanged(false), mForumsDir(forumDir)
|
||||
{
|
||||
//loadDummyData();
|
||||
|
||||
/* create chanDir */
|
||||
if (!RsDirUtil::checkCreateDirectory(mForumsDir)) {
|
||||
std::cerr << "p3Channels() Failed to create forums Directory: " << mForumsDir << std::endl;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ class p3Forums: public p3GroupDistrib, public RsForums
|
||||
public:
|
||||
|
||||
p3Forums(uint16_t type, CacheStrapper *cs, CacheTransfer *cft,
|
||||
std::string srcdir, std::string storedir);
|
||||
std::string srcdir, std::string storedir, std::string forumdir);
|
||||
virtual ~p3Forums();
|
||||
|
||||
void loadDummyData();
|
||||
@ -127,6 +127,8 @@ std::string createForumMsg(std::string fId, std::string pId,
|
||||
|
||||
|
||||
bool mForumsChanged;
|
||||
std::string mForumsDir;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user