diff --git a/libretroshare/src/rsiface/rschannels.h b/libretroshare/src/rsiface/rschannels.h index 293896b30..9253f0066 100644 --- a/libretroshare/src/rsiface/rschannels.h +++ b/libretroshare/src/rsiface/rschannels.h @@ -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; + /****************************************/ }; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 4f40156a4..569fb6e5e 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -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); diff --git a/libretroshare/src/services/p3blogs.cc b/libretroshare/src/services/p3blogs.cc index 5c58017c1..c2d896173 100644 --- a/libretroshare/src/services/p3blogs.cc +++ b/libretroshare/src/services/p3blogs.cc @@ -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) diff --git a/libretroshare/src/services/p3channels.cc b/libretroshare/src/services/p3channels.cc index b9dd761ff..ec0f81df8 100644 --- a/libretroshare/src/services/p3channels.cc +++ b/libretroshare/src/services/p3channels.cc @@ -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) { diff --git a/libretroshare/src/services/p3channels.h b/libretroshare/src/services/p3channels.h index 02e3fdfd7..5af285a01 100644 --- a/libretroshare/src/services/p3channels.h +++ b/libretroshare/src/services/p3channels.h @@ -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) *************************/ diff --git a/libretroshare/src/services/p3distrib.cc b/libretroshare/src/services/p3distrib.cc index 7d99f7371..6a4949153 100644 --- a/libretroshare/src/services/p3distrib.cc +++ b/libretroshare/src/services/p3distrib.cc @@ -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 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& 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::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(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) { diff --git a/libretroshare/src/services/p3distrib.h b/libretroshare/src/services/p3distrib.h index 8d82a8037..b6defdbb8 100644 --- a/libretroshare/src/services/p3distrib.h +++ b/libretroshare/src/services/p3distrib.h @@ -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 &keysToBackUp, std::string grpId); protected: /* load cache msgs */ @@ -441,7 +450,9 @@ bool groupsChanged(std::list &groupIds); bool mGroupsChanged; bool mGroupsRepublish; - std::list saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ + std::list saveCleanupList; /* TEMPORARY LIST WHEN SAVING */ + std::string mKeyBackUpDir; + const std::string BACKUP_KEY_FILE; }; diff --git a/libretroshare/src/services/p3forums.cc b/libretroshare/src/services/p3forums.cc index 9da97e6bb..c59c064c8 100644 --- a/libretroshare/src/services/p3forums.cc +++ b/libretroshare/src/services/p3forums.cc @@ -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; } diff --git a/libretroshare/src/services/p3forums.h b/libretroshare/src/services/p3forums.h index 197bf5b09..0041f5454 100644 --- a/libretroshare/src/services/p3forums.h +++ b/libretroshare/src/services/p3forums.h @@ -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; + };