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:
chrisparker126 2010-05-19 22:40:53 +00:00
parent 3e1c18fac3
commit e48ede4841
9 changed files with 167 additions and 12 deletions

View File

@ -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;
/****************************************/
};

View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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) *************************/

View File

@ -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)
{

View File

@ -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;
};

View 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;
}

View File

@ -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;
};