Added PGP GxsId signature creation

group creation operates on a 10 second timeout rather than number of attempts

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@6205 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2013-03-11 16:04:25 +00:00
parent 7c0fb5eced
commit 12172e3acc
4 changed files with 194 additions and 132 deletions

View File

@ -309,8 +309,6 @@ uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKe
}else{
return CREATE_FAIL;
}
}
int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& grpData,
@ -871,31 +869,34 @@ void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
void RsGenExchange::msgsChanged(std::map<RsGxsGroupId,
std::vector<RsGxsMessageId> >& msgs)
{
RsStackMutex stack(mGenMtx);
while(!mMsgChange.empty())
if(mGenMtx.trylock())
{
RsGxsMsgChange* mc = mMsgChange.back();
msgs = mc->msgChangeMap;
mMsgChange.pop_back();
delete mc;
while(!mMsgChange.empty())
{
RsGxsMsgChange* mc = mMsgChange.back();
msgs = mc->msgChangeMap;
mMsgChange.pop_back();
delete mc;
}
}
}
void RsGenExchange::groupsChanged(std::list<RsGxsGroupId>& grpIds)
{
RsStackMutex stack(mGenMtx);
while(!mGroupChange.empty())
if(mGenMtx.trylock())
{
RsGxsGroupChange* gc = mGroupChange.back();
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
std::list<RsGxsGroupId>::iterator lit = gList.begin();
for(; lit != gList.end(); lit++)
grpIds.push_back(*lit);
while(!mGroupChange.empty())
{
RsGxsGroupChange* gc = mGroupChange.back();
std::list<RsGxsGroupId>& gList = gc->mGrpIdList;
std::list<RsGxsGroupId>::iterator lit = gList.begin();
for(; lit != gList.end(); lit++)
grpIds.push_back(*lit);
mGroupChange.pop_back();
delete gc;
mGroupChange.pop_back();
delete gc;
}
}
}
@ -911,23 +912,34 @@ bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId,
bool RsGenExchange::updated(bool willCallGrpChanged, bool willCallMsgChanged)
{
bool changed = false;
{
RsStackMutex stack(mGenMtx);
if(mGenMtx.trylock())
{
changed = (!mGroupChange.empty() || !mMsgChange.empty());
if(!willCallGrpChanged)
{
while(!mGroupChange.empty())
{
RsGxsGroupChange* gc = mGroupChange.back();
mGroupChange.pop_back();
delete gc;
}
}
if(!willCallMsgChanged)
{
while(!mMsgChange.empty())
{
RsGxsMsgChange* mc = mMsgChange.back();
mMsgChange.pop_back();
delete mc;
}
}
mGenMtx.unlock();
}
if(!willCallGrpChanged)
{
std::list<RsGxsGroupId> grpIds;
groupsChanged(grpIds);
}
if(!willCallMsgChanged)
{
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgs;
msgsChanged(msgs);
}
return changed;
}
@ -1232,7 +1244,7 @@ void RsGenExchange::notifyNewGroups(std::vector<RsNxsGrp *> &groups)
// TODO: move this to nxs layer to save bandwidth
if(received == mReceivedGrps.end())
{
GxsPendingSignItem<RsNxsGrp*, RsGxsGroupId> gpsi(grp, grp->grpId);
GxsPendingItem<RsNxsGrp*, RsGxsGroupId> gpsi(grp, grp->grpId);
mReceivedGrps.push_back(gpsi);
}
else
@ -1272,7 +1284,8 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
RsStackMutex stack(mGenMtx);
token = mDataAccess->generatePublicToken();
mGrpsToPublish.insert(std::make_pair(token, grpItem));
GxsGrpPendingSign ggps(grpItem, token);
mGrpsToPublish.push_back(ggps);
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishGroup() token: " << token;
@ -1507,13 +1520,13 @@ void RsGenExchange::publishMsgs()
RsStackMutex stack(mGenMtx);
// stick back msgs pending signature
typedef std::map<uint32_t, GxsPendingSignItem<RsGxsMsgItem*, uint32_t> > PendSignMap;
typedef std::map<uint32_t, GxsPendingItem<RsGxsMsgItem*, uint32_t> > PendSignMap;
PendSignMap::iterator sign_it = mMsgPendingSign.begin();
for(; sign_it != mMsgPendingSign.end(); sign_it++)
{
GxsPendingSignItem<RsGxsMsgItem*, uint32_t>& item = sign_it->second;
GxsPendingItem<RsGxsMsgItem*, uint32_t>& item = sign_it->second;
mMsgsToPublish.insert(std::make_pair(sign_it->first, item.mItem));
}
@ -1570,7 +1583,7 @@ void RsGenExchange::publishMsgs()
// sign attempt
if(pit == mMsgPendingSign.end())
{
GxsPendingSignItem<RsGxsMsgItem*, uint32_t> gsi(msgItem, token);
GxsPendingItem<RsGxsMsgItem*, uint32_t> gsi(msgItem, token);
mMsgPendingSign.insert(std::make_pair(token, gsi));
}
else
@ -1672,7 +1685,8 @@ void RsGenExchange::publishMsgs()
mMsgsToPublish.clear();
}
RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet)
RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */,
RsTlvSecurityKeySet& /* keySet */)
{
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::service_CreateGroup(): Does nothing"
@ -1682,49 +1696,56 @@ RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpI
}
#define GEN_EXCH_GRP_CHUNK 30
#define PENDING_SIGN_TIMEOUT 10 // 5 seconds
void RsGenExchange::publishGrps()
{
RsStackMutex stack(mGenMtx);
NxsGrpSignPendVect::iterator vit = mGrpsToPublish.begin();
NxsGrpSignPendVect::iterator pend_it = mGrpPendingSign.begin();
typedef std::pair<bool, RsGxsGroupId> GrpNote;
std::map<uint32_t, GrpNote> toNotify;
for(; pend_it != mGrpPendingSign.end();)
while( vit != mGrpsToPublish.end() )
{
GxsPendingSignItem<RsGxsGrpItem*, uint32_t>& gpsi = *pend_it;
GxsGrpPendingSign& ggps = *vit;
if(gpsi.mAttempts == SIGN_MAX_ATTEMPTS)
/* do intial checks to see if this entry has expired */
time_t now = time(NULL) ;
uint32_t token = ggps.mToken;
if(now > (ggps.mStartTS + PENDING_SIGN_TIMEOUT) )
{
pend_it = mGrpPendingSign.erase(pend_it);
// timed out
toNotify.insert(std::make_pair(
token, GrpNote(false, "")));
delete ggps.mItem;
vit = mGrpsToPublish.erase(vit);
continue;
}
else
{
gpsi.mAttempts++;
mGrpsToPublish.insert(std::make_pair(gpsi.mId, gpsi.mItem));
pend_it++;
}
}
std::map<uint32_t, RsGxsGrpItem*>::iterator mit = mGrpsToPublish.begin();
std::vector<uint32_t> toRemove;
int i = 0;
for(; mit != mGrpsToPublish.end(); mit++)
{
if(i > GEN_EXCH_GRP_CHUNK-1) break;
uint32_t token = mit->first;
toRemove.push_back(token);
i++;
RsGxsGroupId grpId;
RsNxsGrp* grp = new RsNxsGrp(mServType);
RsGxsGrpItem* grpItem = mit->second;
RsGxsGrpItem* grpItem = ggps.mItem;
RsTlvSecurityKeySet privatekeySet, publicKeySet, tempKeySet;
generateGroupKeys(privatekeySet, publicKeySet,
!(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC));
RsTlvSecurityKeySet privatekeySet, publicKeySet;
// find private admin key
if(!(ggps.mHaveKeys))
{
generateGroupKeys(privatekeySet, publicKeySet, true);
ggps.mHaveKeys = true;
ggps.mPrivateKeys = privatekeySet;
ggps.mPublicKeys = publicKeySet;
}
else
{
privatekeySet = ggps.mPrivateKeys;
publicKeySet = ggps.mPublicKeys;
}
// find private admin key
RsTlvSecurityKey privAdminKey;
std::map<std::string, RsTlvSecurityKey>::iterator mit_keys = privatekeySet.keys.begin();
@ -1747,20 +1768,30 @@ void RsGenExchange::publishGrps()
// get group id from private admin key id
grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId;
// what!? this will remove the private keys!
privatekeySet.keys.insert(publicKeySet.keys.begin(),
publicKeySet.keys.end());
ServiceCreate_Return ret = service_CreateGroup(grpItem, privatekeySet);
uint32_t size = mSerialiser->size(grpItem);
char *gData = new char[size];
bool serialOk = mSerialiser->serialise(grpItem, gData, &size);
grp->grp.setBinData(gData, size);
bool serialOk = false, servCreateOk;
delete[] gData;
if(ret == SERVICE_CREATE_SUCCESS)
{
uint32_t size = mSerialiser->size(grpItem);
char *gData = new char[size];
serialOk = mSerialiser->serialise(grpItem, gData, &size);
grp->grp.setBinData(gData, size);
delete[] gData;
servCreateOk = true;
if(serialOk)
}else
{
servCreateOk = false;
}
if(serialOk && servCreateOk)
{
grp->metaData = new RsGxsGrpMetaData();
grpItem->meta.mPublishTs = time(NULL);
@ -1783,17 +1814,8 @@ void RsGenExchange::publishGrps()
if(mDataStore->validSize(grp) && serialOk)
{
RsGxsGroupId grpId = grp->grpId;
grpId = grp->grpId;
mDataAccess->addGroupData(grp);
std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl;
// add to published to allow acknowledgement
mGrpNotify.insert(std::make_pair(mit->first, grpId));
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
}
else
{
@ -1801,6 +1823,10 @@ void RsGenExchange::publishGrps()
}
}
}
else if(ret == SERVICE_CREATE_FAIL_TRY_LATER)
{
create = CREATE_FAIL_TRY_LATER;
}
}
else
{
@ -1815,56 +1841,49 @@ void RsGenExchange::publishGrps()
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl;
#endif
delete grp;
delete grpItem;
// add to published to allow acknowledgement, grpid is empty as grp creation failed
mGrpNotify.insert(std::make_pair(token, RsGxsGroupId("")));
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
vit = mGrpsToPublish.erase(vit);
toNotify.insert(std::make_pair(
token, GrpNote(false, grpId)));
}
else if(create == CREATE_FAIL_TRY_LATER)
{
delete grp;
NxsGrpSignPendVect::iterator vit = std::find(mGrpPendingSign.begin(),
mGrpPendingSign.end(), token);
if(vit == mGrpPendingSign.end())
{
GxsPendingSignItem<RsGxsGrpItem*, uint32_t> gpsi(grpItem, token);
mGrpPendingSign.push_back(gpsi);
}else
{
if(vit->mAttempts == SIGN_MAX_ATTEMPTS)
{
delete vit->mItem;
}
}
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishGrps() failed grp, trying again " << std::endl;
#endif
ggps.mLastAttemptTS = time(NULL);
vit++;
}
else if(create == CREATE_SUCCESS)
{
delete grpItem;
}
vit = mGrpsToPublish.erase(vit);
if((create == CREATE_SUCCESS) || (create == CREATE_FAIL))
{
NxsGrpSignPendVect::iterator vit = std::find(mGrpPendingSign.begin(),
mGrpPendingSign.end(), token);
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies"
<< std::endl;
#endif
// set to max attempts so entry removed in next publish pass
if(vit != mGrpPendingSign.end())
{
vit->mAttempts = SIGN_MAX_ATTEMPTS;
}
// add to published to allow acknowledgement
toNotify.insert(std::make_pair(token,
GrpNote(true,grpId)));
}
}
// clear grp list as we're done publishing them and entries
// are invalid
for(std::vector<uint32_t>::size_type i = 0; i < toRemove.size(); i++)
mGrpsToPublish.erase(toRemove[i]);
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
for(; mit != toNotify.end(); mit++)
{
GrpNote& note = mit->second;
uint8_t status = note.first ? RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE
: RsTokenService::GXS_REQUEST_V2_STATUS_FAILED;
mGrpNotify.insert(std::make_pair(mit->first, note.second));
mDataAccess->updatePublicRequestStatus(mit->first, status);
}
}
@ -1997,7 +2016,7 @@ void RsGenExchange::processRecvdMessages()
for(; pend_it != mMsgPendingValidate.end();)
{
GxsPendingSignItem<RsNxsMsg*, RsGxsGrpMsgIdPair>& gpsi = *pend_it;
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair>& gpsi = *pend_it;
if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS)
{
@ -2093,7 +2112,7 @@ void RsGenExchange::processRecvdMessages()
if(vit == mMsgPendingValidate.end())
{
GxsPendingSignItem<RsNxsMsg*, RsGxsGrpMsgIdPair> item(msg, id);
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair> item(msg, id);
mMsgPendingValidate.push_back(item);
}else
{
@ -2128,7 +2147,7 @@ void RsGenExchange::processRecvdGroups()
while( vit != mReceivedGrps.end())
{
GxsPendingSignItem<RsNxsGrp*, RsGxsGroupId>& gpsi = *vit;
GxsPendingItem<RsNxsGrp*, RsGxsGroupId>& gpsi = *vit;
RsNxsGrp* grp = gpsi.mItem;
RsGxsGrpMetaData* meta = new RsGxsGrpMetaData();
bool deserialOk = meta->deserialise(grp->meta.bin_data, grp->meta.bin_len);

View File

@ -39,14 +39,14 @@
#include "serialiser/rsnxsitems.h"
template<class GxsItem, typename Identity = std::string>
class GxsPendingSignItem
class GxsPendingItem
{
public:
GxsPendingSignItem(GxsItem item, Identity id) :
GxsPendingItem(GxsItem item, Identity id) :
mItem(item), mId(id), mAttempts(0)
{}
GxsPendingSignItem(const GxsPendingSignItem& gpsi)
GxsPendingItem(const GxsPendingItem& gpsi)
{
this->mItem = gpsi.mItem;
this->mId = gpsi.mId;
@ -63,6 +63,22 @@ public:
uint8_t mAttempts;
};
class GxsGrpPendingSign
{
public:
GxsGrpPendingSign(RsGxsGrpItem* item, uint32_t token): mLastAttemptTS(0), mStartTS(time(NULL)), mToken(token),
mItem(item), mHaveKeys(false)
{}
time_t mLastAttemptTS, mStartTS;
uint32_t mToken;
RsGxsGrpItem* mItem;
bool mHaveKeys; // mKeys->first == true if key present
RsTlvSecurityKeySet mPrivateKeys;
RsTlvSecurityKeySet mPublicKeys;
};
typedef std::map<RsGxsGroupId, std::vector<RsGxsMsgItem*> > GxsMsgDataMap;
typedef std::map<RsGxsGroupId, RsGxsGrpItem*> GxsGroupDataMap;
typedef std::map<RsGxsGrpMsgIdPair, std::vector<RsGxsMsgItem*> > GxsMsgRelatedDataMap;
@ -94,7 +110,7 @@ class RsGenExchange : public RsNxsObserver, public RsThread, public RsGxsIface
public:
/// used by class derived for RsGenExchange to indicate if service create passed or not
enum ServiceCreate_Return { SERVICE_CREATE_SUCCESS, SERVICE_CREATE_FAIL, SERVICE_FAIL_TRY_LATER } ;
enum ServiceCreate_Return { SERVICE_CREATE_SUCCESS, SERVICE_CREATE_FAIL, SERVICE_CREATE_FAIL_TRY_LATER } ;
/*!
* Constructs a RsGenExchange object, the owner ship of gds, ns, and serviceserialiser passes \n
@ -646,10 +662,12 @@ private:
std::vector<RsNxsMsg*> mReceivedMsgs;
typedef std::vector<GxsPendingSignItem<RsNxsGrp*, RsGxsGroupId> > NxsGrpPendValidVect;
typedef std::vector<GxsPendingItem<RsNxsGrp*, RsGxsGroupId> > NxsGrpPendValidVect;
NxsGrpPendValidVect mReceivedGrps;
std::map<uint32_t, RsGxsGrpItem*> mGrpsToPublish;
std::vector<GxsGrpPendingSign> mGrpsToPublish;
typedef std::vector<GxsGrpPendingSign> NxsGrpSignPendVect;
std::map<uint32_t, RsGxsMsgItem*> mMsgsToPublish;
std::map<uint32_t, RsGxsGrpMsgIdPair > mMsgNotify;
@ -666,14 +684,13 @@ private:
/// authentication policy
uint32_t mAuthenPolicy;
std::map<uint32_t, GxsPendingSignItem<RsGxsMsgItem*, uint32_t> >
std::map<uint32_t, GxsPendingItem<RsGxsMsgItem*, uint32_t> >
mMsgPendingSign;
std::vector<GxsPendingSignItem<RsNxsMsg*, RsGxsGrpMsgIdPair> > mMsgPendingValidate;
typedef std::vector<GxsPendingSignItem<RsNxsMsg*, RsGxsGrpMsgIdPair> > NxsMsgPendingVect;
std::vector<GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair> > mMsgPendingValidate;
typedef std::vector<GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair> > NxsMsgPendingVect;
std::vector<GxsPendingSignItem<RsGxsGrpItem*, uint32_t> > mGrpPendingSign;
typedef std::vector<GxsPendingSignItem<RsGxsGrpItem*, uint32_t> > NxsGrpSignPendVect;
private:

View File

@ -1231,6 +1231,7 @@ static void calcPGPHash(const RsGxsId &id, const PGPFingerprintType &pgp, GxsIdP
// Must Use meta.
RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& keySet)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::service_CreateGroup()";
std::cerr << std::endl;
@ -1304,6 +1305,8 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
std::cerr << std::endl;
#endif // DEBUG_IDS
ServiceCreate_Return createStatus;
if (item->group.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID)
{
/* create the hash */
@ -1320,6 +1323,8 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
}
#endif
if (!AuthGPG::getAuthGPG()->getKeyFingerprint(ownId,ownFinger))
{
std::cerr << "p3IdService::service_CreateGroup() ERROR Own Finger is stuck";
@ -1337,6 +1342,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
/* do signature */
#if ENABLE_PGP_SIGNATURES
#define MAX_SIGN_SIZE 2048
uint8_t signarray[MAX_SIGN_SIZE];
@ -1348,6 +1354,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
/* error */
std::cerr << "p3IdService::service_CreateGroup() ERROR Signing stuff";
std::cerr << std::endl;
createStatus = SERVICE_CREATE_FAIL_TRY_LATER;
}
else
{
@ -1357,6 +1364,7 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
{
item->group.mPgpIdSign += signarray[i];
}
createStatus = SERVICE_CREATE_SUCCESS;
}
/* done! */
#else
@ -1364,6 +1372,10 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
#endif
}
else
{
createStatus = SERVICE_CREATE_SUCCESS;
}
// Enforce no AuthorId.
item->meta.mAuthorId = "";
@ -1374,7 +1386,8 @@ RsGenExchange::ServiceCreate_Return p3IdService::service_CreateGroup(RsGxsGrpIte
// Reload in a little bit.
// HACK to get it to work.
RsTickEvent::schedule_in(GXSID_EVENT_CACHEOWNIDS, OWNID_RELOAD_DELAY);
return SERVICE_CREATE_SUCCESS;
return createStatus;
}

View File

@ -194,6 +194,7 @@ bool NotifyQt::askForDeferredSelfSignature(const void *data, const uint32_t len,
std::map<std::string,SignatureEventData*>::iterator it = _deferred_signature_queue.find(chksum.toStdString()) ;
if(it != _deferred_signature_queue.end())
{
if(it->second->signature_result != 0) // found it. Copy the result, and remove from the queue.
{
// We should check for the exact data match, for the sake of being totally secure.
@ -211,6 +212,7 @@ bool NotifyQt::askForDeferredSelfSignature(const void *data, const uint32_t len,
}
else
return false ; // already registered, but not done yet.
}
// Not found. Store in the queue and emit a signal.
//
@ -228,10 +230,21 @@ void NotifyQt::handleSignatureEvent()
{
std::cerr << "NotifyQt:: performing a deferred signature in the main GUI thread." << std::endl;
static bool working = false ;
if(!working)
{
working = true ;
for(std::map<std::string,SignatureEventData*>::const_iterator it(_deferred_signature_queue.begin());it!=_deferred_signature_queue.end();++it)
it->second->performSignature() ;
working = false ;
}
}
bool NotifyQt::askForPassword(const std::string& key_details, bool prev_is_bad, std::string& password)
{
RsAutoUpdatePage::lockAllEvents() ;