2012-08-06 17:00:38 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* libretroshare/src/gxs: rsgenexchange.cc
|
|
|
|
*
|
|
|
|
* RetroShare Gxs exchange interface.
|
|
|
|
*
|
|
|
|
* Copyright 2012-2012 by Christopher Evi-Parker, Robert Fernie
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License Version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2012-12-16 16:12:26 -05:00
|
|
|
#include <unistd.h>
|
|
|
|
|
2012-08-12 16:46:21 -04:00
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
#include <openssl/evp.h>
|
2012-08-19 18:15:37 -04:00
|
|
|
#include <openssl/rsa.h>
|
2012-08-12 16:46:21 -04:00
|
|
|
|
2012-10-01 16:57:56 -04:00
|
|
|
#include "pqi/pqihash.h"
|
2012-05-21 18:07:43 -04:00
|
|
|
#include "rsgenexchange.h"
|
2012-08-12 16:46:21 -04:00
|
|
|
#include "gxssecurity.h"
|
2012-08-21 17:32:07 -04:00
|
|
|
#include "util/contentvalue.h"
|
2013-02-28 16:58:38 -05:00
|
|
|
#include "retroshare/rsgxsflags.h"
|
2013-06-04 17:00:43 -04:00
|
|
|
#include "retroshare/rsgxscircles.h"
|
2012-11-10 18:42:38 -05:00
|
|
|
#include "rsgixs.h"
|
2013-03-06 18:33:23 -05:00
|
|
|
#include "rsgxsutil.h"
|
2012-05-21 18:07:43 -04:00
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
|
|
|
|
#define PUB_GRP_MASK 0x000f
|
|
|
|
#define RESTR_GRP_MASK 0x00f0
|
|
|
|
#define PRIV_GRP_MASK 0x0f00
|
|
|
|
#define GRP_OPTIONS_MASK 0xf000
|
|
|
|
|
|
|
|
#define PUB_GRP_OFFSET 0
|
|
|
|
#define RESTR_GRP_OFFSET 8
|
2013-02-27 17:51:58 -05:00
|
|
|
#define PRIV_GRP_OFFSET 16
|
|
|
|
#define GRP_OPTIONS_OFFSET 24
|
2012-11-10 18:42:38 -05:00
|
|
|
|
2012-11-17 09:35:21 -05:00
|
|
|
#define GXS_MASK "GXS_MASK_HACK"
|
|
|
|
|
2012-11-15 18:50:54 -05:00
|
|
|
#define GEN_EXCH_DEBUG 1
|
|
|
|
|
2013-03-23 10:13:15 -04:00
|
|
|
#define MSG_CLEANUP_PERIOD 60*5 // 5 minutes
|
2013-06-04 17:00:43 -04:00
|
|
|
#define INTEGRITY_CHECK_PERIOD 60*30 // 30 minutes
|
2013-03-21 19:17:24 -04:00
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
RsGenExchange::RsGenExchange(RsGeneralDataService *gds, RsNetworkExchangeService *ns,
|
2013-03-20 18:26:24 -04:00
|
|
|
RsSerialType *serviceSerialiser, uint16_t servType, RsGixs* gixs,
|
|
|
|
uint32_t authenPolicy, uint32_t messageStorePeriod)
|
2012-11-10 18:42:38 -05:00
|
|
|
: mGenMtx("GenExchange"), mDataStore(gds), mNetService(ns), mSerialiser(serviceSerialiser),
|
2013-03-20 18:26:24 -04:00
|
|
|
mServType(servType), mGixs(gixs), mAuthenPolicy(authenPolicy), MESSAGE_STORE_PERIOD(messageStorePeriod),
|
2013-03-06 18:33:23 -05:00
|
|
|
CREATE_FAIL(0), CREATE_SUCCESS(1), CREATE_FAIL_TRY_LATER(2), SIGN_MAX_ATTEMPTS(5),
|
|
|
|
SIGN_FAIL(0), SIGN_SUCCESS(1), SIGN_FAIL_TRY_LATER(2),
|
2013-03-21 19:17:24 -04:00
|
|
|
VALIDATE_FAIL(0), VALIDATE_SUCCESS(1), VALIDATE_FAIL_TRY_LATER(2), VALIDATE_MAX_ATTEMPTS(5),
|
2013-06-04 17:00:43 -04:00
|
|
|
mCleaning(false), mLastClean(time(NULL)), mMsgCleanUp(NULL), mChecking(false), mIntegrityCheck(NULL),
|
|
|
|
mLastCheck(time(NULL))
|
2012-05-21 18:07:43 -04:00
|
|
|
{
|
2012-07-05 17:26:14 -04:00
|
|
|
|
2012-07-18 17:35:41 -04:00
|
|
|
mDataAccess = new RsGxsDataAccess(gds);
|
2012-07-05 17:26:14 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
RsGenExchange::~RsGenExchange()
|
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
// need to destruct in a certain order (bad thing, TODO: put down instance ownership rules!)
|
2012-07-05 17:26:14 -04:00
|
|
|
delete mNetService;
|
|
|
|
|
|
|
|
delete mDataAccess;
|
|
|
|
mDataAccess = NULL;
|
|
|
|
|
|
|
|
delete mDataStore;
|
|
|
|
mDataStore = NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-11-03 21:38:48 -04:00
|
|
|
void RsGenExchange::run()
|
|
|
|
{
|
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
double timeDelta = 0.1; // slow tick
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2012-11-13 17:36:06 -05:00
|
|
|
while(isRunning())
|
2012-11-03 21:38:48 -04:00
|
|
|
{
|
|
|
|
tick();
|
|
|
|
|
|
|
|
#ifndef WINDOWS_SYS
|
|
|
|
usleep((int) (timeDelta * 1000000));
|
|
|
|
#else
|
|
|
|
Sleep((int) (timeDelta * 1000));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2012-07-05 17:26:14 -04:00
|
|
|
|
|
|
|
void RsGenExchange::tick()
|
|
|
|
{
|
2013-03-16 08:31:31 -04:00
|
|
|
// Meta Changes should happen first.
|
|
|
|
// This is important, as services want to change Meta, then get results.
|
|
|
|
// Services shouldn't rely on this ordering - but some do.
|
|
|
|
processGrpMetaChanges();
|
|
|
|
processMsgMetaChanges();
|
|
|
|
|
2012-07-18 17:35:41 -04:00
|
|
|
mDataAccess->processRequests();
|
2012-07-26 17:48:54 -04:00
|
|
|
|
|
|
|
publishGrps();
|
|
|
|
|
|
|
|
publishMsgs();
|
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
processGroupUpdatePublish();
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
processRecvdData();
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
if(!mNotifications.empty())
|
|
|
|
{
|
|
|
|
notifyChanges(mNotifications);
|
|
|
|
mNotifications.clear();
|
|
|
|
}
|
2012-08-06 17:00:38 -04:00
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
// implemented service tick function
|
|
|
|
service_tick();
|
2013-03-21 19:17:24 -04:00
|
|
|
|
|
|
|
time_t now = time(NULL);
|
|
|
|
|
|
|
|
if((mLastClean + MSG_CLEANUP_PERIOD < now) || mCleaning)
|
|
|
|
{
|
|
|
|
if(mMsgCleanUp)
|
|
|
|
{
|
|
|
|
if(mMsgCleanUp->clean())
|
|
|
|
{
|
|
|
|
mCleaning = false;
|
|
|
|
delete mMsgCleanUp;
|
|
|
|
mMsgCleanUp = NULL;
|
|
|
|
mLastClean = time(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
mMsgCleanUp = new RsGxsMessageCleanUp(mDataStore, MESSAGE_STORE_PERIOD, 1);
|
|
|
|
mCleaning = true;
|
|
|
|
}
|
|
|
|
}
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
now = time(NULL);
|
|
|
|
if(mChecking || (mLastCheck + INTEGRITY_CHECK_PERIOD < now))
|
|
|
|
{
|
|
|
|
if(mIntegrityCheck)
|
|
|
|
{
|
|
|
|
if(mIntegrityCheck->isDone())
|
|
|
|
{
|
|
|
|
mIntegrityCheck->join();
|
|
|
|
delete mIntegrityCheck;
|
|
|
|
mIntegrityCheck = NULL;
|
|
|
|
mLastCheck = time(NULL);
|
|
|
|
mChecking = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mIntegrityCheck = new RsGxsIntegrityCheck(mDataStore);
|
|
|
|
mIntegrityCheck->start();
|
|
|
|
mChecking = true;
|
|
|
|
}
|
|
|
|
}
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
2012-08-18 06:01:35 -04:00
|
|
|
bool RsGenExchange::acknowledgeTokenMsg(const uint32_t& token,
|
2012-08-21 17:32:07 -04:00
|
|
|
RsGxsGrpMsgIdPair& msgId)
|
2012-08-18 06:01:35 -04:00
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
std::map<uint32_t, RsGxsGrpMsgIdPair >::iterator mit =
|
|
|
|
mMsgNotify.find(token);
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
if(mit == mMsgNotify.end())
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2012-08-18 06:01:35 -04:00
|
|
|
|
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
msgId = mit->second;
|
|
|
|
|
|
|
|
// no dump token as client has ackowledged its completion
|
|
|
|
mDataAccess->disposeOfPublicToken(token);
|
2012-08-18 06:01:35 -04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token,
|
|
|
|
RsGxsGroupId& grpId)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
|
|
|
std::map<uint32_t, RsGxsGroupId >::iterator mit =
|
2012-08-21 17:32:07 -04:00
|
|
|
mGrpNotify.find(token);
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
if(mit == mGrpNotify.end())
|
2012-08-18 06:01:35 -04:00
|
|
|
return false;
|
|
|
|
|
|
|
|
grpId = mit->second;
|
|
|
|
|
|
|
|
// no dump token as client has ackowledged its completion
|
|
|
|
mDataAccess->disposeOfPublicToken(token);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
|
|
|
|
RsTlvSecurityKeySet& publickeySet, bool genPublishKeys)
|
2012-08-12 16:46:21 -04:00
|
|
|
{
|
|
|
|
/* create Keys */
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
// admin keys
|
2012-08-12 16:46:21 -04:00
|
|
|
RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL);
|
|
|
|
RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin);
|
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
/* set admin keys */
|
2012-08-18 06:01:35 -04:00
|
|
|
RsTlvSecurityKey adminKey, privAdminKey;
|
|
|
|
|
2012-08-12 16:46:21 -04:00
|
|
|
GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub);
|
2012-08-18 06:01:35 -04:00
|
|
|
GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin);
|
|
|
|
|
2012-11-03 21:38:48 -04:00
|
|
|
adminKey.startTS = time(NULL);
|
2013-02-07 18:04:16 -05:00
|
|
|
adminKey.endTS = adminKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
privAdminKey.startTS = adminKey.startTS;
|
2012-11-03 21:38:48 -04:00
|
|
|
privAdminKey.endTS = 0; /* no end */
|
|
|
|
|
2012-08-18 06:01:35 -04:00
|
|
|
// for now all public
|
|
|
|
adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
|
|
|
|
privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL;
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
publickeySet.keys[adminKey.keyId] = adminKey;
|
|
|
|
privatekeySet.keys[privAdminKey.keyId] = privAdminKey;
|
2012-11-03 21:38:48 -04:00
|
|
|
|
|
|
|
// clean up
|
|
|
|
RSA_free(rsa_admin);
|
|
|
|
RSA_free(rsa_admin_pub);
|
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
if(genPublishKeys)
|
|
|
|
{
|
|
|
|
// publish keys
|
|
|
|
RSA *rsa_publish = RSA_generate_key(2048, 65537, NULL, NULL);
|
|
|
|
RSA *rsa_publish_pub = RSAPublicKey_dup(rsa_publish);
|
|
|
|
|
|
|
|
/* set publish keys */
|
|
|
|
RsTlvSecurityKey pubKey, privPubKey;
|
|
|
|
|
|
|
|
GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub);
|
|
|
|
GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish);
|
|
|
|
|
|
|
|
pubKey.startTS = adminKey.startTS;
|
|
|
|
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
|
|
|
|
|
|
|
|
privPubKey.startTS = adminKey.startTS;
|
|
|
|
privPubKey.endTS = 0; /* no end */
|
|
|
|
|
|
|
|
// for now all public
|
|
|
|
pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY;
|
|
|
|
privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL;
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
publickeySet.keys[pubKey.keyId] = pubKey;
|
|
|
|
privatekeySet.keys[privPubKey.keyId] = privPubKey;
|
2012-11-11 18:45:22 -05:00
|
|
|
|
|
|
|
RSA_free(rsa_publish);
|
|
|
|
RSA_free(rsa_publish_pub);
|
|
|
|
}
|
2012-11-03 21:38:48 -04:00
|
|
|
}
|
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
void RsGenExchange::generatePublicFromPrivateKeys(const RsTlvSecurityKeySet &privatekeySet,
|
|
|
|
RsTlvSecurityKeySet &publickeySet)
|
|
|
|
{
|
|
|
|
|
|
|
|
// actually just copy settings of one key except mark its key flags public
|
|
|
|
|
|
|
|
typedef std::map<std::string, RsTlvSecurityKey> keyMap;
|
|
|
|
const keyMap& allKeys = privatekeySet.keys;
|
|
|
|
keyMap::const_iterator cit = allKeys.begin();
|
|
|
|
bool adminFound = false, publishFound = false;
|
|
|
|
for(; cit != allKeys.end(); cit++)
|
|
|
|
{
|
|
|
|
const RsTlvSecurityKey& privKey = cit->second;
|
|
|
|
if(privKey.keyFlags & RSTLV_KEY_TYPE_FULL)
|
|
|
|
{
|
|
|
|
RsTlvSecurityKey pubKey;
|
|
|
|
|
|
|
|
pubKey = privKey;
|
|
|
|
|
|
|
|
RSA *rsaPrivKey = NULL, *rsaPubKey = NULL;
|
|
|
|
|
|
|
|
rsaPrivKey = GxsSecurity::extractPrivateKey(privKey);
|
|
|
|
|
|
|
|
if(rsaPrivKey)
|
|
|
|
rsaPubKey = RSAPublicKey_dup(rsaPrivKey);
|
|
|
|
|
|
|
|
if(rsaPrivKey && rsaPubKey)
|
|
|
|
{
|
|
|
|
GxsSecurity::setRSAPublicKey(pubKey, rsaPubKey);
|
|
|
|
|
|
|
|
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
|
|
|
|
pubKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY;
|
|
|
|
|
|
|
|
if(pubKey.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)
|
|
|
|
pubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_PUBLIC_ONLY;
|
|
|
|
|
2013-10-13 17:49:17 -04:00
|
|
|
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
|
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
publickeySet.keys.insert(std::make_pair(pubKey.keyId, pubKey));
|
|
|
|
}
|
|
|
|
|
|
|
|
if(rsaPrivKey)
|
|
|
|
RSA_free(rsaPrivKey);
|
|
|
|
|
|
|
|
if(rsaPubKey)
|
|
|
|
RSA_free(rsaPubKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet)
|
2012-11-03 21:38:48 -04:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
std::cerr << "RsGenExchange::createGroup()";
|
|
|
|
std::cerr << std::endl;
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2012-08-12 16:46:21 -04:00
|
|
|
RsGxsGrpMetaData* meta = grp->metaData;
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
/* add public admin and publish keys to grp */
|
2012-11-03 21:38:48 -04:00
|
|
|
|
|
|
|
// find private admin key
|
|
|
|
RsTlvSecurityKey privAdminKey;
|
2013-02-07 18:04:16 -05:00
|
|
|
std::map<std::string, RsTlvSecurityKey>::iterator mit = privateKeySet.keys.begin();
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
bool privKeyFound = false; // private admin key
|
|
|
|
for(; mit != privateKeySet.keys.end(); mit++)
|
2012-11-03 21:38:48 -04:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
RsTlvSecurityKey& key = mit->second;
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
if((key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN) && (key.keyFlags & RSTLV_KEY_TYPE_FULL))
|
2012-11-03 21:38:48 -04:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
privAdminKey = key;
|
|
|
|
privKeyFound = true;
|
2012-11-03 21:38:48 -04:00
|
|
|
}
|
|
|
|
}
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
if(!privKeyFound)
|
2012-11-08 19:56:07 -05:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
std::cerr << "RsGenExchange::createGroup() Missing private ADMIN Key";
|
2012-11-08 19:56:07 -05:00
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-03 21:38:48 -04:00
|
|
|
return false;
|
2012-11-08 19:56:07 -05:00
|
|
|
}
|
2012-11-02 19:35:10 -04:00
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
meta->keys = publicKeySet; // only public keys are included to be transported
|
|
|
|
|
2012-11-02 19:35:10 -04:00
|
|
|
// group is self signing
|
|
|
|
// for the creation of group signature
|
2012-11-11 18:45:22 -05:00
|
|
|
// only public admin and publish keys are present in meta
|
2012-11-02 19:35:10 -04:00
|
|
|
uint32_t metaDataLen = meta->serial_size();
|
2012-11-03 21:38:48 -04:00
|
|
|
uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len;
|
|
|
|
char* metaData = new char[metaDataLen];
|
|
|
|
char* allGrpData = new char[allGrpDataLen]; // msgData + metaData
|
2012-11-02 19:35:10 -04:00
|
|
|
|
2012-11-03 21:38:48 -04:00
|
|
|
meta->serialise(metaData, metaDataLen);
|
2012-11-02 19:35:10 -04:00
|
|
|
|
2012-11-03 21:38:48 -04:00
|
|
|
// copy msg data and meta in allMsgData buffer
|
|
|
|
memcpy(allGrpData, grp->grp.bin_data, grp->grp.bin_len);
|
|
|
|
memcpy(allGrpData+(grp->grp.bin_len), metaData, metaDataLen);
|
2012-11-02 19:35:10 -04:00
|
|
|
|
2012-11-03 21:38:48 -04:00
|
|
|
RsTlvKeySignature adminSign;
|
|
|
|
bool ok = GxsSecurity::getSignature(allGrpData, allGrpDataLen, &privAdminKey, adminSign);
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2012-11-02 19:35:10 -04:00
|
|
|
// add admin sign to grpMeta
|
|
|
|
meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign;
|
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
RsTlvBinaryData grpData(mServType);
|
|
|
|
grpData.setBinData(allGrpData, allGrpDataLen);
|
|
|
|
|
|
|
|
uint8_t ret = createGroupSignatures(meta->signSet, grpData, *(grp->metaData));
|
|
|
|
|
2012-11-02 19:35:10 -04:00
|
|
|
// clean up
|
|
|
|
delete[] allGrpData;
|
|
|
|
delete[] metaData;
|
|
|
|
|
2012-11-08 19:56:07 -05:00
|
|
|
if (!ok)
|
|
|
|
{
|
2013-03-08 14:55:59 -05:00
|
|
|
std::cerr << "RsGenExchange::createGroup() ERROR !okay (getSignature error)";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
return CREATE_FAIL;
|
2012-11-08 19:56:07 -05:00
|
|
|
}
|
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
if(ret == SIGN_FAIL)
|
|
|
|
{
|
|
|
|
return CREATE_FAIL;
|
|
|
|
}else if(ret == SIGN_FAIL_TRY_LATER)
|
|
|
|
{
|
|
|
|
return CREATE_FAIL_TRY_LATER;
|
|
|
|
}else if(ret == SIGN_SUCCESS)
|
|
|
|
{
|
|
|
|
return CREATE_SUCCESS;
|
|
|
|
}else{
|
|
|
|
return CREATE_FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int RsGenExchange::createGroupSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& grpData,
|
|
|
|
RsGxsGrpMetaData& grpMeta)
|
|
|
|
{
|
|
|
|
bool needIdentitySign = false;
|
|
|
|
int id_ret;
|
|
|
|
|
|
|
|
uint8_t author_flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
|
|
|
|
|
|
|
|
PrivacyBitPos pos = GRP_OPTION_BITS;
|
|
|
|
|
|
|
|
// Check required permissions, and allow them to sign it - if they want too - as well!
|
2013-03-10 11:08:04 -04:00
|
|
|
if ((!grpMeta.mAuthorId.empty()) || checkAuthenFlag(pos, author_flag))
|
2013-03-08 14:55:59 -05:00
|
|
|
{
|
|
|
|
needIdentitySign = true;
|
|
|
|
std::cerr << "Needs Identity sign! (Service Flags)";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (needIdentitySign)
|
|
|
|
{
|
|
|
|
if(mGixs)
|
|
|
|
{
|
|
|
|
bool haveKey = mGixs->havePrivateKey(grpMeta.mAuthorId);
|
|
|
|
|
|
|
|
if(haveKey)
|
|
|
|
{
|
|
|
|
RsTlvSecurityKey authorKey;
|
|
|
|
mGixs->getPrivateKey(grpMeta.mAuthorId, authorKey);
|
|
|
|
RsTlvKeySignature sign;
|
|
|
|
|
|
|
|
if(GxsSecurity::getSignature((char*)grpData.bin_data, grpData.bin_len,
|
|
|
|
&authorKey, sign))
|
|
|
|
{
|
|
|
|
id_ret = SIGN_SUCCESS;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
id_ret = SIGN_FAIL;
|
|
|
|
}
|
|
|
|
|
|
|
|
signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mGixs->requestPrivateKey(grpMeta.mAuthorId);
|
|
|
|
|
|
|
|
std::cerr << "RsGenExchange::createGroupSignatures(): ";
|
|
|
|
std::cerr << " ERROR AUTHOR KEY: " << grpMeta.mAuthorId
|
|
|
|
<< " is not Cached / available for Message Signing\n";
|
|
|
|
std::cerr << "RsGenExchange::createGroupSignatures(): Requestiong AUTHOR KEY";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
id_ret = SIGN_FAIL_TRY_LATER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "RsGenExchange::createGroupSignatures()";
|
|
|
|
std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl;
|
|
|
|
id_ret = SIGN_FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
id_ret = SIGN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return id_ret;
|
2012-08-18 06:01:35 -04:00
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
int RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData,
|
2012-11-11 18:45:22 -05:00
|
|
|
const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta)
|
|
|
|
{
|
2012-11-13 17:36:06 -05:00
|
|
|
bool needPublishSign = false, needIdentitySign = false;
|
2012-11-11 18:45:22 -05:00
|
|
|
uint32_t grpFlag = grpMeta.mGroupFlags;
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
bool publishSignSuccess = false;
|
|
|
|
|
2013-02-27 17:51:58 -05:00
|
|
|
std::cerr << "RsGenExchange::createMsgSignatures() for Msg.mMsgName: " << msgMeta.mMsgName;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
// publish signature is determined by whether group is public or not
|
|
|
|
// for private group signature is not needed as it needs decrypting with
|
|
|
|
// the private publish key anyways
|
|
|
|
|
|
|
|
// restricted is a special case which heeds whether publish sign needs to be checked or not
|
|
|
|
// one may or may not want
|
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
uint8_t author_flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN;
|
|
|
|
uint8_t publish_flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN;
|
|
|
|
|
|
|
|
if(!msgMeta.mParentId.empty())
|
2012-11-11 18:45:22 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
// Child Message.
|
|
|
|
author_flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
|
|
|
|
publish_flag = GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
PrivacyBitPos pos = PUBLIC_GRP_BITS;
|
|
|
|
if (grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
2012-11-11 18:45:22 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
pos = RESTRICTED_GRP_BITS;
|
|
|
|
}
|
|
|
|
else if (grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
2012-11-11 18:45:22 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
pos = PRIVATE_GRP_BITS;
|
|
|
|
}
|
|
|
|
|
|
|
|
needIdentitySign = false;
|
|
|
|
needPublishSign = false;
|
2013-03-08 14:55:59 -05:00
|
|
|
if (checkAuthenFlag(pos, publish_flag))
|
2013-02-27 17:51:58 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
needPublishSign = true;
|
2013-02-27 17:51:58 -05:00
|
|
|
std::cerr << "Needs Publish sign! (Service Flags)";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
// Check required permissions, and allow them to sign it - if they want too - as well!
|
2013-03-08 14:55:59 -05:00
|
|
|
if (checkAuthenFlag(pos, author_flag))
|
2013-02-27 17:51:58 -05:00
|
|
|
{
|
|
|
|
needIdentitySign = true;
|
|
|
|
std::cerr << "Needs Identity sign! (Service Flags)";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!msgMeta.mAuthorId.empty())
|
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
needIdentitySign = true;
|
2013-02-27 17:51:58 -05:00
|
|
|
std::cerr << "Needs Identity sign! (AuthorId Exists)";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2012-11-11 18:45:22 -05:00
|
|
|
|
|
|
|
if(needPublishSign)
|
|
|
|
{
|
|
|
|
// public and shared is publish key
|
|
|
|
RsTlvSecurityKeySet& keys = grpMeta.keys;
|
|
|
|
RsTlvSecurityKey* pubKey;
|
|
|
|
|
|
|
|
std::map<std::string, RsTlvSecurityKey>::iterator mit =
|
|
|
|
keys.keys.begin(), mit_end = keys.keys.end();
|
|
|
|
bool pub_key_found = false;
|
|
|
|
for(; mit != mit_end; mit++)
|
|
|
|
{
|
|
|
|
|
2012-11-19 17:00:05 -05:00
|
|
|
pub_key_found = mit->second.keyFlags == (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL);
|
2012-11-11 18:45:22 -05:00
|
|
|
if(pub_key_found)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if (pub_key_found)
|
2013-02-27 16:20:00 -05:00
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
// private publish key
|
|
|
|
pubKey = &(mit->second);
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
publishSignSuccess = GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, pubKey, pubSign);
|
|
|
|
|
|
|
|
//place signature in msg meta
|
|
|
|
signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = pubSign;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
std::cerr << "RsGenExchange::createMsgSignatures()";
|
|
|
|
std::cerr << " ERROR Cannot find PUBLISH KEY for Message Signing!";
|
|
|
|
std::cerr << " ERROR Publish Sign failed!";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
}
|
|
|
|
else // publish sign not needed so set as successful
|
|
|
|
{
|
|
|
|
publishSignSuccess = true;
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
int id_ret;
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
if (needIdentitySign)
|
2012-11-11 18:45:22 -05:00
|
|
|
{
|
|
|
|
if(mGixs)
|
|
|
|
{
|
|
|
|
bool haveKey = mGixs->havePrivateKey(msgMeta.mAuthorId);
|
|
|
|
|
|
|
|
if(haveKey)
|
|
|
|
{
|
|
|
|
RsTlvSecurityKey authorKey;
|
2013-03-06 18:33:23 -05:00
|
|
|
mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey);
|
|
|
|
RsTlvKeySignature sign;
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if(GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len,
|
|
|
|
&authorKey, sign))
|
|
|
|
{
|
|
|
|
id_ret = SIGN_SUCCESS;
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
else
|
|
|
|
{
|
|
|
|
id_ret = SIGN_FAIL;
|
2013-02-27 16:20:00 -05:00
|
|
|
}
|
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign;
|
2013-02-27 17:51:58 -05:00
|
|
|
}
|
|
|
|
else
|
2012-11-11 18:45:22 -05:00
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
mGixs->requestPrivateKey(msgMeta.mAuthorId);
|
|
|
|
|
|
|
|
std::cerr << "RsGenExchange::createMsgSignatures(): ";
|
|
|
|
std::cerr << " ERROR AUTHOR KEY: " << msgMeta.mAuthorId
|
|
|
|
<< " is not Cached / available for Message Signing\n";
|
|
|
|
std::cerr << "RsGenExchange::createMsgSignatures(): Requestiong AUTHOR KEY";
|
2013-02-27 17:51:58 -05:00
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
id_ret = SIGN_FAIL_TRY_LATER;
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-02-27 17:51:58 -05:00
|
|
|
std::cerr << "RsGenExchange::createMsgSignatures()";
|
2012-11-11 18:45:22 -05:00
|
|
|
std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl;
|
2013-03-06 18:33:23 -05:00
|
|
|
id_ret = SIGN_FAIL;
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
else
|
|
|
|
{
|
|
|
|
id_ret = SIGN_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(publishSignSuccess)
|
|
|
|
{
|
|
|
|
return id_ret;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return SIGN_FAIL;
|
|
|
|
}
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
int RsGenExchange::createMessage(RsNxsMsg* msg)
|
2012-08-18 06:01:35 -04:00
|
|
|
{
|
|
|
|
const RsGxsGroupId& id = msg->grpId;
|
|
|
|
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> metaMap;
|
|
|
|
|
|
|
|
metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL)));
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(metaMap);
|
2013-03-06 18:33:23 -05:00
|
|
|
|
|
|
|
RsGxsMsgMetaData &meta = *(msg->metaData);
|
|
|
|
|
|
|
|
int ret_val;
|
2012-08-18 06:01:35 -04:00
|
|
|
|
|
|
|
if(!metaMap[id])
|
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
return CREATE_FAIL;
|
2012-08-18 06:01:35 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-03-10 11:08:04 -04:00
|
|
|
// get publish key
|
2013-03-06 18:33:23 -05:00
|
|
|
RsGxsGrpMetaData* grpMeta = metaMap[id];
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
uint32_t metaDataLen = meta.serial_size();
|
|
|
|
uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len;
|
|
|
|
char* metaData = new char[metaDataLen];
|
|
|
|
char* allMsgData = new char[allMsgDataLen]; // msgData + metaData
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
meta.serialise(metaData, &metaDataLen);
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
// copy msg data and meta in allmsgData buffer
|
|
|
|
memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len);
|
|
|
|
memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen);
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
RsTlvBinaryData msgData(0);
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
msgData.setBinData(allMsgData, allMsgDataLen);
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
// create signatures
|
|
|
|
ret_val = createMsgSignatures(meta.signSet, msgData, meta, *grpMeta);
|
2013-03-06 18:33:23 -05:00
|
|
|
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
// get hash of msg data to create msg id
|
|
|
|
pqihash hash;
|
|
|
|
hash.addData(allMsgData, allMsgDataLen);
|
|
|
|
hash.Complete(msg->msgId);
|
2012-10-01 16:57:56 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
// assign msg id to msg meta
|
|
|
|
msg->metaData->mMsgId = msg->msgId;
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
delete[] metaData;
|
|
|
|
delete[] allMsgData;
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
delete grpMeta;
|
2012-08-18 06:01:35 -04:00
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if(ret_val == SIGN_FAIL)
|
|
|
|
return CREATE_FAIL;
|
|
|
|
else if(ret_val == SIGN_FAIL_TRY_LATER)
|
|
|
|
return CREATE_FAIL_TRY_LATER;
|
|
|
|
else if(ret_val == SIGN_SUCCESS)
|
|
|
|
return CREATE_SUCCESS;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "Unknown return value from signature attempt!";
|
|
|
|
return CREATE_FAIL;
|
|
|
|
}
|
2012-08-12 16:46:21 -04:00
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
bool needIdentitySign = false;
|
|
|
|
bool needPublishSign = false;
|
2013-03-06 18:33:23 -05:00
|
|
|
bool publishValidate = true, idValidate = true;
|
2012-11-10 18:42:38 -05:00
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
uint8_t author_flag = GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN;
|
|
|
|
uint8_t publish_flag = GXS_SERV::MSG_AUTHEN_ROOT_PUBLISH_SIGN;
|
2012-11-10 18:42:38 -05:00
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
if(!msg->metaData->mParentId.empty())
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
// Child Message.
|
|
|
|
author_flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN;
|
|
|
|
publish_flag = GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN;
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
PrivacyBitPos pos = PUBLIC_GRP_BITS;
|
|
|
|
if (grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
pos = RESTRICTED_GRP_BITS;
|
|
|
|
}
|
|
|
|
else if (grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
pos = PRIVATE_GRP_BITS;
|
|
|
|
}
|
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
if (checkAuthenFlag(pos, publish_flag))
|
2013-02-27 16:20:00 -05:00
|
|
|
needPublishSign = true;
|
2012-11-10 18:42:38 -05:00
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
// Check required permissions, if they have signed it anyway - we need to validate it.
|
2013-03-08 14:55:59 -05:00
|
|
|
if ((checkAuthenFlag(pos, author_flag)) || (!msg->metaData->mAuthorId.empty()))
|
2013-02-27 16:20:00 -05:00
|
|
|
needIdentitySign = true;
|
2012-11-10 18:42:38 -05:00
|
|
|
|
|
|
|
|
|
|
|
RsGxsMsgMetaData& metaData = *(msg->metaData);
|
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
if(needPublishSign)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
|
|
|
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH];
|
|
|
|
|
2013-02-07 18:04:16 -05:00
|
|
|
std::map<std::string, RsTlvSecurityKey>& keys = grpKeySet.keys;
|
|
|
|
std::map<std::string, RsTlvSecurityKey>::iterator mit = keys.begin();
|
|
|
|
|
|
|
|
std::string keyId;
|
|
|
|
for(; mit != keys.end() ; mit++)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2013-02-07 18:04:16 -05:00
|
|
|
RsTlvSecurityKey& key = mit->second;
|
|
|
|
|
|
|
|
if((key.keyFlags & RSTLV_KEY_DISTRIB_PUBLIC) &&
|
|
|
|
(key.keyFlags & RSTLV_KEY_TYPE_PUBLIC_ONLY))
|
|
|
|
{
|
|
|
|
keyId = key.keyId;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!keyId.empty())
|
|
|
|
{
|
|
|
|
RsTlvSecurityKey& key = keys[keyId];
|
2013-03-06 18:33:23 -05:00
|
|
|
publishValidate &= GxsSecurity::validateNxsMsg(*msg, sign, key);
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
publishValidate = false;
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
else
|
|
|
|
{
|
|
|
|
publishValidate = true;
|
|
|
|
}
|
2012-11-10 18:42:38 -05:00
|
|
|
|
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
if(needIdentitySign)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
if(mGixs)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
bool haveKey = mGixs->haveKey(metaData.mAuthorId);
|
|
|
|
|
|
|
|
if(haveKey)
|
|
|
|
{
|
2012-11-10 18:42:38 -05:00
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
RsTlvSecurityKey authorKey;
|
2013-03-06 18:33:23 -05:00
|
|
|
bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) == 1;
|
2012-11-10 18:42:38 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if (auth_key_fetched)
|
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
|
|
|
|
idValidate &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
std::cerr << "RsGenExchange::validateMsg()";
|
2013-03-06 18:33:23 -05:00
|
|
|
std::cerr << " ERROR Cannot Retrieve AUTHOR KEY for Message Validation";
|
2013-02-27 16:20:00 -05:00
|
|
|
std::cerr << std::endl;
|
2013-03-06 18:33:23 -05:00
|
|
|
idValidate = false;
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}else
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2013-02-16 05:51:00 -05:00
|
|
|
std::list<std::string> peers;
|
|
|
|
mGixs->requestKey(metaData.mAuthorId, peers);
|
2013-03-06 18:33:23 -05:00
|
|
|
return VALIDATE_FAIL_TRY_LATER;
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
|
|
|
else
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
#ifdef GEN_EXHANGE_DEBUG
|
|
|
|
std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl;
|
|
|
|
#endif
|
2013-03-06 18:33:23 -05:00
|
|
|
idValidate = false;
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
else
|
|
|
|
{
|
|
|
|
idValidate = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(publishValidate && idValidate)
|
|
|
|
return VALIDATE_SUCCESS;
|
|
|
|
else
|
|
|
|
return VALIDATE_FAIL;
|
2012-11-10 18:42:38 -05:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
int RsGenExchange::validateGrp(RsNxsGrp* grp, RsTlvSecurityKeySet& grpKeySet)
|
|
|
|
{
|
|
|
|
|
|
|
|
bool needIdentitySign = false, idValidate = false;
|
|
|
|
RsGxsGrpMetaData& metaData = *(grp->metaData);
|
|
|
|
|
|
|
|
int id_ret;
|
|
|
|
|
|
|
|
uint8_t author_flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN;
|
|
|
|
|
|
|
|
PrivacyBitPos pos = GRP_OPTION_BITS;
|
|
|
|
|
|
|
|
// Check required permissions, and allow them to sign it - if they want too - as well!
|
|
|
|
if (!(metaData.mAuthorId.empty()) || checkAuthenFlag(pos, author_flag))
|
|
|
|
{
|
|
|
|
needIdentitySign = true;
|
|
|
|
std::cerr << "Needs Identity sign! (Service Flags)";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(needIdentitySign)
|
|
|
|
{
|
|
|
|
if(mGixs)
|
|
|
|
{
|
|
|
|
bool haveKey = mGixs->haveKey(metaData.mAuthorId);
|
|
|
|
|
|
|
|
if(haveKey)
|
|
|
|
{
|
|
|
|
|
|
|
|
RsTlvSecurityKey authorKey;
|
|
|
|
bool auth_key_fetched = mGixs->getKey(metaData.mAuthorId, authorKey) == 1;
|
|
|
|
|
|
|
|
if (auth_key_fetched)
|
|
|
|
{
|
|
|
|
|
|
|
|
RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY];
|
|
|
|
idValidate = GxsSecurity::validateNxsGrp(*grp, sign, authorKey);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "RsGenExchange::validateGrp()";
|
|
|
|
std::cerr << " ERROR Cannot Retrieve AUTHOR KEY for Group Sign Validation";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
idValidate = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
std::list<std::string> peers;
|
|
|
|
mGixs->requestKey(metaData.mAuthorId, peers);
|
|
|
|
return VALIDATE_FAIL_TRY_LATER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef GEN_EXHANGE_DEBUG
|
|
|
|
std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl;
|
|
|
|
#endif
|
|
|
|
idValidate = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
idValidate = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(idValidate)
|
|
|
|
return VALIDATE_SUCCESS;
|
|
|
|
else
|
|
|
|
return VALIDATE_FAIL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
bool RsGenExchange::checkAuthenFlag(const PrivacyBitPos& pos, const uint8_t& flag) const
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2013-02-27 17:51:58 -05:00
|
|
|
std::cerr << "RsGenExchange::checkMsgAuthenFlag(pos: " << pos << " flag: ";
|
|
|
|
std::cerr << (int) flag << " mAuthenPolicy: " << mAuthenPolicy << ")";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
switch(pos)
|
|
|
|
{
|
|
|
|
case PUBLIC_GRP_BITS:
|
|
|
|
return mAuthenPolicy & flag;
|
|
|
|
break;
|
|
|
|
case RESTRICTED_GRP_BITS:
|
|
|
|
return flag & (mAuthenPolicy >> RESTR_GRP_OFFSET);
|
|
|
|
break;
|
|
|
|
case PRIVATE_GRP_BITS:
|
|
|
|
return flag & (mAuthenPolicy >> PRIV_GRP_OFFSET);
|
|
|
|
break;
|
|
|
|
case GRP_OPTION_BITS:
|
|
|
|
return flag & (mAuthenPolicy >> GRP_OPTIONS_OFFSET);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
std::cerr << "pos option not recognised";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2012-07-05 17:26:14 -04:00
|
|
|
|
2013-02-28 16:58:38 -05:00
|
|
|
void RsGenExchange::receiveChanges(std::vector<RsGxsNotify*>& changes)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
|
|
|
std::vector<RsGxsNotify*>::iterator vit = changes.begin();
|
|
|
|
|
|
|
|
for(; vit != changes.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsNotify* n = *vit;
|
|
|
|
RsGxsGroupChange* gc;
|
|
|
|
RsGxsMsgChange* mc;
|
|
|
|
if((mc = dynamic_cast<RsGxsMsgChange*>(n)) != NULL)
|
|
|
|
{
|
|
|
|
mMsgChange.push_back(mc);
|
|
|
|
}
|
|
|
|
else if((gc = dynamic_cast<RsGxsGroupChange*>(n)) != NULL)
|
|
|
|
{
|
|
|
|
mGroupChange.push_back(gc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delete n;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGenExchange::msgsChanged(std::map<RsGxsGroupId,
|
|
|
|
std::vector<RsGxsMessageId> >& msgs)
|
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
if(mGenMtx.trylock())
|
2013-02-28 16:58:38 -05:00
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
while(!mMsgChange.empty())
|
|
|
|
{
|
|
|
|
RsGxsMsgChange* mc = mMsgChange.back();
|
|
|
|
msgs = mc->msgChangeMap;
|
|
|
|
mMsgChange.pop_back();
|
|
|
|
delete mc;
|
|
|
|
}
|
2013-03-19 16:13:13 -04:00
|
|
|
mGenMtx.unlock();
|
2013-02-28 16:58:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGenExchange::groupsChanged(std::list<RsGxsGroupId>& grpIds)
|
|
|
|
{
|
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
if(mGenMtx.trylock())
|
2013-02-28 16:58:38 -05:00
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
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;
|
|
|
|
}
|
2013-03-19 16:13:13 -04:00
|
|
|
mGenMtx.unlock();
|
2013-02-28 16:58:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGenExchange::subscribeToGroup(uint32_t& token, const RsGxsGroupId& grpId, bool subscribe)
|
|
|
|
{
|
|
|
|
if(subscribe)
|
2013-03-16 12:44:33 -04:00
|
|
|
setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED,
|
|
|
|
(GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED | GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED));
|
2013-02-28 16:58:38 -05:00
|
|
|
else
|
2013-03-16 12:44:33 -04:00
|
|
|
setGroupSubscribeFlags(token, grpId, GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED,
|
|
|
|
(GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED | GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED));
|
2013-02-28 16:58:38 -05:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2013-03-23 10:07:52 -04:00
|
|
|
|
|
|
|
bool RsGenExchange::getGroupStatistic(const uint32_t& token, GxsGroupStatistic& stats)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGenExchange::getServiceStatistic(const uint32_t& token, GxsServiceStatistic& stats)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-02-28 16:58:38 -05:00
|
|
|
bool RsGenExchange::updated(bool willCallGrpChanged, bool willCallMsgChanged)
|
|
|
|
{
|
|
|
|
bool changed = false;
|
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
if(mGenMtx.trylock())
|
|
|
|
{
|
2013-02-28 16:58:38 -05:00
|
|
|
changed = (!mGroupChange.empty() || !mMsgChange.empty());
|
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
if(!willCallGrpChanged)
|
|
|
|
{
|
|
|
|
while(!mGroupChange.empty())
|
|
|
|
{
|
|
|
|
RsGxsGroupChange* gc = mGroupChange.back();
|
|
|
|
mGroupChange.pop_back();
|
|
|
|
delete gc;
|
|
|
|
}
|
|
|
|
}
|
2013-02-28 16:58:38 -05:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
if(!willCallMsgChanged)
|
|
|
|
{
|
|
|
|
while(!mMsgChange.empty())
|
|
|
|
{
|
|
|
|
RsGxsMsgChange* mc = mMsgChange.back();
|
|
|
|
mMsgChange.pop_back();
|
|
|
|
delete mc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mGenMtx.unlock();
|
2013-02-28 16:58:38 -05:00
|
|
|
}
|
2013-03-11 12:04:25 -04:00
|
|
|
|
2013-02-28 16:58:38 -05:00
|
|
|
return changed;
|
|
|
|
}
|
|
|
|
|
2012-07-22 17:38:15 -04:00
|
|
|
bool RsGenExchange::getGroupList(const uint32_t &token, std::list<RsGxsGroupId> &groupIds)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
2012-07-22 17:38:15 -04:00
|
|
|
return mDataAccess->getGroupList(token, groupIds);
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGenExchange::getMsgList(const uint32_t &token,
|
2012-07-22 17:38:15 -04:00
|
|
|
GxsMsgIdResult &msgIds)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
2012-07-22 17:38:15 -04:00
|
|
|
return mDataAccess->getMsgList(token, msgIds);
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
2012-11-13 17:36:06 -05:00
|
|
|
bool RsGenExchange::getMsgRelatedList(const uint32_t &token, MsgRelatedIdResult &msgIds)
|
|
|
|
{
|
|
|
|
return mDataAccess->getMsgRelatedList(token, msgIds);
|
|
|
|
}
|
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
bool RsGenExchange::getGroupMeta(const uint32_t &token, std::list<RsGroupMetaData> &groupInfo)
|
|
|
|
{
|
2012-07-22 17:38:15 -04:00
|
|
|
std::list<RsGxsGrpMetaData*> metaL;
|
|
|
|
bool ok = mDataAccess->getGroupSummary(token, metaL);
|
|
|
|
|
2012-07-26 17:48:54 -04:00
|
|
|
std::list<RsGxsGrpMetaData*>::iterator lit = metaL.begin();
|
2012-07-28 16:01:30 -04:00
|
|
|
RsGroupMetaData m;
|
2012-07-26 17:48:54 -04:00
|
|
|
for(; lit != metaL.end(); lit++)
|
|
|
|
{
|
2012-07-28 16:01:30 -04:00
|
|
|
RsGxsGrpMetaData& gMeta = *(*lit);
|
|
|
|
m = gMeta;
|
2012-07-26 17:48:54 -04:00
|
|
|
groupInfo.push_back(m);
|
2012-07-28 16:01:30 -04:00
|
|
|
delete (*lit);
|
2012-07-26 17:48:54 -04:00
|
|
|
}
|
|
|
|
|
2012-07-22 17:38:15 -04:00
|
|
|
return ok;
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
2012-07-22 17:38:15 -04:00
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
bool RsGenExchange::getMsgMeta(const uint32_t &token,
|
2012-07-22 17:38:15 -04:00
|
|
|
GxsMsgMetaMap &msgInfo)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
2012-07-22 17:38:15 -04:00
|
|
|
std::list<RsGxsMsgMetaData*> metaL;
|
|
|
|
GxsMsgMetaResult result;
|
|
|
|
bool ok = mDataAccess->getMsgSummary(token, result);
|
|
|
|
|
|
|
|
GxsMsgMetaResult::iterator mit = result.begin();
|
|
|
|
|
|
|
|
for(; mit != result.end(); mit++)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsMsgMetaData*>& metaV = mit->second;
|
|
|
|
|
2012-08-06 17:00:38 -04:00
|
|
|
msgInfo[mit->first] = std::vector<RsMsgMetaData>();
|
|
|
|
std::vector<RsMsgMetaData>& msgInfoV = msgInfo[mit->first];
|
2012-07-05 17:26:14 -04:00
|
|
|
|
2012-08-06 17:00:38 -04:00
|
|
|
std::vector<RsGxsMsgMetaData*>::iterator vit = metaV.begin();
|
|
|
|
RsMsgMetaData meta;
|
2012-07-22 17:38:15 -04:00
|
|
|
for(; vit != metaV.end(); vit++)
|
|
|
|
{
|
2012-08-06 17:00:38 -04:00
|
|
|
RsGxsMsgMetaData& m = *(*vit);
|
|
|
|
meta = m;
|
|
|
|
msgInfoV.push_back(meta);
|
2012-07-22 17:38:15 -04:00
|
|
|
delete *vit;
|
|
|
|
}
|
2012-08-06 17:00:38 -04:00
|
|
|
metaV.clear();
|
2012-07-22 17:38:15 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
return ok;
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
2012-11-13 17:36:06 -05:00
|
|
|
bool RsGenExchange::getMsgRelatedMeta(const uint32_t &token, GxsMsgRelatedMetaMap &msgMeta)
|
|
|
|
{
|
|
|
|
MsgRelatedMetaResult result;
|
|
|
|
bool ok = mDataAccess->getMsgRelatedSummary(token, result);
|
|
|
|
|
|
|
|
MsgRelatedMetaResult::iterator mit = result.begin();
|
|
|
|
|
|
|
|
for(; mit != result.end(); mit++)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsMsgMetaData*>& metaV = mit->second;
|
|
|
|
|
|
|
|
msgMeta[mit->first] = std::vector<RsMsgMetaData>();
|
|
|
|
std::vector<RsMsgMetaData>& msgInfoV = msgMeta[mit->first];
|
|
|
|
|
|
|
|
std::vector<RsGxsMsgMetaData*>::iterator vit = metaV.begin();
|
|
|
|
RsMsgMetaData meta;
|
|
|
|
for(; vit != metaV.end(); vit++)
|
|
|
|
{
|
|
|
|
RsGxsMsgMetaData& m = *(*vit);
|
|
|
|
meta = m;
|
|
|
|
msgInfoV.push_back(meta);
|
|
|
|
delete *vit;
|
|
|
|
}
|
|
|
|
metaV.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-12 16:46:21 -04:00
|
|
|
bool RsGenExchange::getGroupData(const uint32_t &token, std::vector<RsGxsGrpItem *>& grpItem)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
2012-07-22 17:38:15 -04:00
|
|
|
std::list<RsNxsGrp*> nxsGrps;
|
|
|
|
bool ok = mDataAccess->getGroupData(token, nxsGrps);
|
|
|
|
|
|
|
|
std::list<RsNxsGrp*>::iterator lit = nxsGrps.begin();
|
|
|
|
|
2012-11-08 19:56:07 -05:00
|
|
|
std::cerr << "RsGenExchange::getGroupData() RsNxsGrp::len: " << nxsGrps.size();
|
|
|
|
std::cerr << std::endl;
|
|
|
|
|
2013-07-20 21:50:13 -04:00
|
|
|
if(ok)
|
2012-07-22 17:38:15 -04:00
|
|
|
{
|
|
|
|
for(; lit != nxsGrps.end(); lit++)
|
|
|
|
{
|
2012-07-26 17:48:54 -04:00
|
|
|
RsTlvBinaryData& data = (*lit)->grp;
|
2013-03-23 10:07:52 -04:00
|
|
|
RsItem* item = NULL;
|
|
|
|
|
|
|
|
if(data.bin_len != 0)
|
|
|
|
item = mSerialiser->deserialise(data.bin_data, &data.bin_len);
|
2012-08-06 17:00:38 -04:00
|
|
|
|
2013-03-23 10:07:52 -04:00
|
|
|
if(item)
|
|
|
|
{
|
2012-08-06 17:00:38 -04:00
|
|
|
RsGxsGrpItem* gItem = dynamic_cast<RsGxsGrpItem*>(item);
|
2013-03-04 17:43:55 -05:00
|
|
|
if (gItem)
|
|
|
|
{
|
|
|
|
gItem->meta = *((*lit)->metaData);
|
2013-07-20 21:50:13 -04:00
|
|
|
grpItem.push_back(gItem);
|
2013-03-04 17:43:55 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "RsGenExchange::getGroupData() deserialisation/dynamic_cast ERROR";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
delete item;
|
|
|
|
}
|
2012-08-06 17:00:38 -04:00
|
|
|
}
|
2012-11-08 19:56:07 -05:00
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "RsGenExchange::getGroupData() ERROR deserialising item";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2013-07-20 21:50:13 -04:00
|
|
|
delete *lit;
|
2012-07-22 17:38:15 -04:00
|
|
|
}
|
|
|
|
}
|
2013-07-20 21:50:13 -04:00
|
|
|
return ok;
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
2013-07-20 21:50:13 -04:00
|
|
|
bool RsGenExchange::getMsgData(const uint32_t &token, GxsMsgDataMap &msgItems)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
2013-07-20 21:50:13 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
NxsMsgDataResult msgResult;
|
|
|
|
bool ok = mDataAccess->getMsgData(token, msgResult);
|
|
|
|
NxsMsgDataResult::iterator mit = msgResult.begin();
|
2012-07-22 17:38:15 -04:00
|
|
|
|
2013-07-20 21:50:13 -04:00
|
|
|
if(ok)
|
|
|
|
{
|
|
|
|
for(; mit != msgResult.end(); mit++)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsMsgItem*> gxsMsgItems;
|
|
|
|
const RsGxsGroupId& grpId = mit->first;
|
|
|
|
std::vector<RsNxsMsg*>& nxsMsgsV = mit->second;
|
|
|
|
std::vector<RsNxsMsg*>::iterator vit = nxsMsgsV.begin();
|
|
|
|
for(; vit != nxsMsgsV.end(); vit++)
|
|
|
|
{
|
|
|
|
RsNxsMsg*& msg = *vit;
|
|
|
|
RsItem* item = NULL;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-07-20 21:50:13 -04:00
|
|
|
if(msg->msg.bin_len != 0)
|
|
|
|
item = mSerialiser->deserialise(msg->msg.bin_data, &msg->msg.bin_len);
|
2013-03-23 10:07:52 -04:00
|
|
|
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
RsGxsMsgItem* mItem = dynamic_cast<RsGxsMsgItem*>(item);
|
|
|
|
if (mItem)
|
|
|
|
{
|
2013-07-20 21:50:13 -04:00
|
|
|
mItem->meta = *((*vit)->metaData); // get meta info from nxs msg
|
|
|
|
gxsMsgItems.push_back(mItem);
|
2013-03-23 10:07:52 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::getMsgData() deserialisation/dynamic_cast ERROR";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::getMsgData() deserialisation ERROR";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
2013-07-20 21:50:13 -04:00
|
|
|
delete msg;
|
2013-03-04 17:43:55 -05:00
|
|
|
}
|
2013-07-20 21:50:13 -04:00
|
|
|
msgItems[grpId] = gxsMsgItems;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
2012-11-13 17:36:06 -05:00
|
|
|
bool RsGenExchange::getMsgRelatedData(const uint32_t &token, GxsMsgRelatedDataMap &msgItems)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
NxsMsgRelatedDataResult msgResult;
|
|
|
|
bool ok = mDataAccess->getMsgRelatedData(token, msgResult);
|
2013-03-23 10:07:52 -04:00
|
|
|
|
2012-11-13 17:36:06 -05:00
|
|
|
|
|
|
|
if(ok)
|
|
|
|
{
|
2013-03-23 10:07:52 -04:00
|
|
|
NxsMsgRelatedDataResult::iterator mit = msgResult.begin();
|
2012-11-13 17:36:06 -05:00
|
|
|
for(; mit != msgResult.end(); mit++)
|
|
|
|
{
|
|
|
|
std::vector<RsGxsMsgItem*> gxsMsgItems;
|
|
|
|
const RsGxsGrpMsgIdPair& msgId = mit->first;
|
|
|
|
std::vector<RsNxsMsg*>& nxsMsgsV = mit->second;
|
|
|
|
std::vector<RsNxsMsg*>::iterator vit
|
|
|
|
= nxsMsgsV.begin();
|
|
|
|
for(; vit != nxsMsgsV.end(); vit++)
|
|
|
|
{
|
|
|
|
RsNxsMsg*& msg = *vit;
|
2013-03-23 10:07:52 -04:00
|
|
|
RsItem* item = NULL;
|
2012-11-13 17:36:06 -05:00
|
|
|
|
2013-03-23 10:07:52 -04:00
|
|
|
if(msg->msg.bin_len != 0)
|
|
|
|
item = mSerialiser->deserialise(msg->msg.bin_data,
|
2012-11-13 17:36:06 -05:00
|
|
|
&msg->msg.bin_len);
|
2013-03-23 10:07:52 -04:00
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
RsGxsMsgItem* mItem = dynamic_cast<RsGxsMsgItem*>(item);
|
|
|
|
|
|
|
|
if (mItem)
|
|
|
|
{
|
|
|
|
mItem->meta = *((*vit)->metaData); // get meta info from nxs msg
|
|
|
|
gxsMsgItems.push_back(mItem);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "RsGenExchange::getMsgRelatedData() deserialisation/dynamic_cast ERROR";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::cerr << "RsGenExchange::getMsgRelatedData() deserialisation ERROR";
|
|
|
|
std::cerr << std::endl;
|
|
|
|
}
|
2012-11-13 17:36:06 -05:00
|
|
|
|
|
|
|
delete msg;
|
|
|
|
}
|
|
|
|
msgItems[msgId] = gxsMsgItems;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
|
2012-10-05 14:12:52 -04:00
|
|
|
RsTokenService* RsGenExchange::getTokenService()
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
|
|
|
return mDataAccess;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
bool RsGenExchange::setAuthenPolicyFlag(const uint8_t &msgFlag, uint32_t& authenFlag, const PrivacyBitPos &pos)
|
|
|
|
{
|
|
|
|
uint32_t temp = 0;
|
|
|
|
temp = msgFlag;
|
|
|
|
|
|
|
|
switch(pos)
|
|
|
|
{
|
|
|
|
case PUBLIC_GRP_BITS:
|
2013-03-10 11:08:04 -04:00
|
|
|
authenFlag &= ~PUB_GRP_MASK;
|
2012-11-10 18:42:38 -05:00
|
|
|
authenFlag |= temp;
|
|
|
|
break;
|
|
|
|
case RESTRICTED_GRP_BITS:
|
2013-03-10 11:08:04 -04:00
|
|
|
authenFlag &= ~RESTR_GRP_MASK;
|
2012-11-10 18:42:38 -05:00
|
|
|
authenFlag |= (temp << RESTR_GRP_OFFSET);
|
|
|
|
break;
|
|
|
|
case PRIVATE_GRP_BITS:
|
2013-03-10 11:08:04 -04:00
|
|
|
authenFlag &= ~PRIV_GRP_MASK;
|
2012-11-10 18:42:38 -05:00
|
|
|
authenFlag |= (temp << PRIV_GRP_OFFSET);
|
|
|
|
break;
|
|
|
|
case GRP_OPTION_BITS:
|
2013-03-10 11:08:04 -04:00
|
|
|
authenFlag &= ~GRP_OPTIONS_MASK;
|
2012-11-10 18:42:38 -05:00
|
|
|
authenFlag |= (temp << GRP_OPTIONS_OFFSET);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
std::cerr << "pos option not recognised";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
void RsGenExchange::notifyNewGroups(std::vector<RsNxsGrp *> &groups)
|
|
|
|
{
|
2013-02-07 18:04:16 -05:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
std::vector<RsNxsGrp*>::iterator vit = groups.begin();
|
|
|
|
|
|
|
|
// store these for tick() to pick them up
|
|
|
|
for(; vit != groups.end(); vit++)
|
2013-03-10 11:08:04 -04:00
|
|
|
{
|
|
|
|
RsNxsGrp* grp = *vit;
|
|
|
|
NxsGrpPendValidVect::iterator received = std::find(mReceivedGrps.begin(),
|
|
|
|
mReceivedGrps.end(), grp->grpId);
|
|
|
|
|
|
|
|
// drop group if you already have them
|
|
|
|
// TODO: move this to nxs layer to save bandwidth
|
|
|
|
if(received == mReceivedGrps.end())
|
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsPendingItem<RsNxsGrp*, RsGxsGroupId> gpsi(grp, grp->grpId);
|
2013-03-10 11:08:04 -04:00
|
|
|
mReceivedGrps.push_back(gpsi);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delete grp;
|
|
|
|
}
|
|
|
|
}
|
2012-07-05 17:26:14 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2012-08-06 17:00:38 -04:00
|
|
|
void RsGenExchange::notifyNewMessages(std::vector<RsNxsMsg *>& messages)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
2013-02-07 18:04:16 -05:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
std::vector<RsNxsMsg*>::iterator vit = messages.begin();
|
|
|
|
|
|
|
|
// store these for tick() to pick them up
|
|
|
|
for(; vit != messages.end(); vit++)
|
2013-03-06 18:33:23 -05:00
|
|
|
{
|
|
|
|
RsNxsMsg* msg = *vit;
|
|
|
|
|
|
|
|
NxsMsgPendingVect::iterator it =
|
|
|
|
std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(), getMsgIdPair(*msg));
|
|
|
|
|
|
|
|
// if we have msg already just delete it
|
|
|
|
if(it == mMsgPendingValidate.end())
|
|
|
|
mReceivedMsgs.push_back(msg);
|
|
|
|
else
|
|
|
|
delete msg;
|
|
|
|
}
|
2012-07-05 17:26:14 -04:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
|
|
|
|
2012-08-18 06:01:35 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsGrpPendingSign ggps(grpItem, token);
|
|
|
|
mGrpsToPublish.push_back(ggps);
|
2012-11-15 18:50:54 -05:00
|
|
|
|
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::publishGroup() token: " << token;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
}
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-09-15 17:18:20 -04:00
|
|
|
|
2013-10-05 07:36:31 -04:00
|
|
|
void RsGenExchange::updateGroup(uint32_t& token, RsGxsGroupUpdateMeta& updateMeta, RsGxsGrpItem* grpItem)
|
2013-09-15 17:18:20 -04:00
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
2013-10-05 07:36:31 -04:00
|
|
|
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, updateMeta, token));
|
2013-09-15 17:18:20 -04:00
|
|
|
|
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::updateGroup() token: " << token;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
|
|
|
mMsgsToPublish.insert(std::make_pair(token, msgItem));
|
2012-11-15 18:50:54 -05:00
|
|
|
|
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::publishMsg() token: " << token;
|
|
|
|
std::cerr << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2012-07-05 17:26:14 -04:00
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
void RsGenExchange::setGroupSubscribeFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& flag, const uint32_t& mask)
|
2012-07-05 17:26:14 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
/* TODO APPLY MASK TO FLAGS */
|
2012-08-21 17:32:07 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
GrpLocMetaData g;
|
|
|
|
g.grpId = grpId;
|
|
|
|
g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, (int32_t)flag);
|
2012-11-17 09:35:21 -05:00
|
|
|
g.val.put(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location
|
2012-08-21 17:32:07 -04:00
|
|
|
mGrpLocMetaMap.insert(std::make_pair(token, g));
|
|
|
|
}
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
void RsGenExchange::setGroupStatusFlags(uint32_t& token, const RsGxsGroupId& grpId, const uint32_t& status, const uint32_t& mask)
|
2012-08-21 17:32:07 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
/* TODO APPLY MASK TO FLAGS */
|
2012-08-21 17:32:07 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
2012-08-18 06:01:35 -04:00
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
GrpLocMetaData g;
|
|
|
|
g.grpId = grpId;
|
|
|
|
g.val.put(RsGeneralDataService::GRP_META_STATUS, (int32_t)status);
|
2012-11-17 09:35:21 -05:00
|
|
|
g.val.put(RsGeneralDataService::GRP_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location
|
2012-08-21 17:32:07 -04:00
|
|
|
mGrpLocMetaMap.insert(std::make_pair(token, g));
|
2012-07-26 17:48:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-21 17:32:07 -04:00
|
|
|
void RsGenExchange::setGroupServiceString(uint32_t& token, const RsGxsGroupId& grpId, const std::string& servString)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
|
|
|
|
|
|
|
GrpLocMetaData g;
|
|
|
|
g.grpId = grpId;
|
|
|
|
g.val.put(RsGeneralDataService::GRP_META_SERV_STRING, servString);
|
|
|
|
mGrpLocMetaMap.insert(std::make_pair(token, g));
|
|
|
|
}
|
|
|
|
|
2012-10-21 11:48:18 -04:00
|
|
|
void RsGenExchange::setMsgStatusFlags(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const uint32_t& status, const uint32_t& mask)
|
2012-08-21 17:32:07 -04:00
|
|
|
{
|
2012-10-21 11:48:18 -04:00
|
|
|
/* TODO APPLY MASK TO FLAGS */
|
2012-08-21 17:32:07 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
|
|
|
|
|
|
|
MsgLocMetaData m;
|
|
|
|
m.val.put(RsGeneralDataService::MSG_META_STATUS, (int32_t)status);
|
2012-11-17 09:35:21 -05:00
|
|
|
m.val.put(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, (int32_t)mask); // HACK, need to perform mask operation in a non-blocking location
|
2012-08-21 17:32:07 -04:00
|
|
|
m.msgId = msgId;
|
|
|
|
mMsgLocMetaMap.insert(std::make_pair(token, m));
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGenExchange::setMsgServiceString(uint32_t& token, const RsGxsGrpMsgIdPair& msgId, const std::string& servString )
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
token = mDataAccess->generatePublicToken();
|
|
|
|
|
|
|
|
MsgLocMetaData m;
|
|
|
|
m.val.put(RsGeneralDataService::MSG_META_SERV_STRING, servString);
|
|
|
|
m.msgId = msgId;
|
|
|
|
mMsgLocMetaMap.insert(std::make_pair(token, m));
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGenExchange::processMsgMetaChanges()
|
|
|
|
{
|
|
|
|
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
|
|
|
std::map<uint32_t, MsgLocMetaData>::iterator mit = mMsgLocMetaMap.begin(),
|
|
|
|
mit_end = mMsgLocMetaMap.end();
|
|
|
|
|
|
|
|
for(; mit != mit_end; mit++)
|
|
|
|
{
|
|
|
|
MsgLocMetaData& m = mit->second;
|
2012-11-17 09:35:21 -05:00
|
|
|
|
|
|
|
int32_t value, mask;
|
|
|
|
bool ok = true;
|
|
|
|
|
|
|
|
// for meta flag changes get flag to apply mask
|
|
|
|
if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS, value))
|
|
|
|
{
|
|
|
|
ok = false;
|
|
|
|
if(m.val.getAsInt32(RsGeneralDataService::MSG_META_STATUS+GXS_MASK, mask))
|
|
|
|
{
|
|
|
|
GxsMsgReq req;
|
|
|
|
std::vector<RsGxsMessageId> msgIdV;
|
|
|
|
msgIdV.push_back(m.msgId.second);
|
|
|
|
req.insert(std::make_pair(m.msgId.first, msgIdV));
|
|
|
|
GxsMsgMetaResult result;
|
|
|
|
mDataStore->retrieveGxsMsgMetaData(req, result);
|
|
|
|
GxsMsgMetaResult::iterator mit = result.find(m.msgId.first);
|
|
|
|
|
|
|
|
if(mit != result.end())
|
|
|
|
{
|
|
|
|
std::vector<RsGxsMsgMetaData*>& msgMetaV = mit->second;
|
|
|
|
|
|
|
|
if(!msgMetaV.empty())
|
|
|
|
{
|
|
|
|
RsGxsMsgMetaData* meta = *(msgMetaV.begin());
|
|
|
|
value = (meta->mMsgStatus & ~mask) | (mask & value);
|
|
|
|
m.val.put(RsGeneralDataService::MSG_META_STATUS, value);
|
|
|
|
delete meta;
|
|
|
|
ok = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m.val.removeKeyValue(RsGeneralDataService::MSG_META_STATUS+GXS_MASK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ok &= mDataStore->updateMessageMetaData(m) == 1;
|
2012-08-21 17:32:07 -04:00
|
|
|
uint32_t token = mit->first;
|
|
|
|
|
|
|
|
if(ok)
|
|
|
|
{
|
2012-10-05 14:12:52 -04:00
|
|
|
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
|
2012-08-21 17:32:07 -04:00
|
|
|
}else
|
|
|
|
{
|
2012-10-05 14:12:52 -04:00
|
|
|
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
|
2012-08-21 17:32:07 -04:00
|
|
|
}
|
|
|
|
mMsgNotify.insert(std::make_pair(token, m.msgId));
|
|
|
|
}
|
|
|
|
|
|
|
|
mMsgLocMetaMap.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void RsGenExchange::processGrpMetaChanges()
|
|
|
|
{
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
|
|
|
std::map<uint32_t, GrpLocMetaData>::iterator mit = mGrpLocMetaMap.begin(),
|
|
|
|
mit_end = mGrpLocMetaMap.end();
|
|
|
|
|
|
|
|
for(; mit != mit_end; mit++)
|
|
|
|
{
|
|
|
|
GrpLocMetaData& g = mit->second;
|
|
|
|
uint32_t token = mit->first;
|
2012-11-17 09:35:21 -05:00
|
|
|
|
|
|
|
// process mask
|
|
|
|
bool ok = processGrpMask(g.grpId, g.val);
|
|
|
|
|
|
|
|
ok &= mDataStore->updateGroupMetaData(g) == 1;
|
2012-08-21 17:32:07 -04:00
|
|
|
|
|
|
|
if(ok)
|
|
|
|
{
|
2012-10-05 14:12:52 -04:00
|
|
|
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
|
2012-08-21 17:32:07 -04:00
|
|
|
}else
|
|
|
|
{
|
2012-10-05 14:12:52 -04:00
|
|
|
mDataAccess->updatePublicRequestStatus(token, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
|
2012-08-21 17:32:07 -04:00
|
|
|
}
|
|
|
|
mGrpNotify.insert(std::make_pair(token, g.grpId));
|
|
|
|
}
|
|
|
|
|
|
|
|
mGrpLocMetaMap.clear();
|
|
|
|
}
|
|
|
|
|
2012-11-17 09:35:21 -05:00
|
|
|
bool RsGenExchange::processGrpMask(const RsGxsGroupId& grpId, ContentValue &grpCv)
|
|
|
|
{
|
|
|
|
// first find out which mask is involved
|
|
|
|
int32_t value, mask, currValue;
|
|
|
|
std::string key;
|
|
|
|
RsGxsGrpMetaData* grpMeta = NULL;
|
|
|
|
bool ok = false;
|
|
|
|
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData* > grpMetaMap;
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData* >::iterator mit;
|
|
|
|
grpMetaMap.insert(std::make_pair(grpId, (RsGxsGrpMetaData*)(NULL)));
|
|
|
|
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
|
|
|
|
|
|
|
|
if((mit = grpMetaMap.find(grpId)) != grpMetaMap.end())
|
|
|
|
{
|
|
|
|
grpMeta = mit->second;
|
|
|
|
ok = true;
|
|
|
|
}
|
|
|
|
|
2013-06-20 15:50:25 -04:00
|
|
|
if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_STATUS, value) && grpMeta)
|
2012-11-17 09:35:21 -05:00
|
|
|
{
|
|
|
|
key = RsGeneralDataService::GRP_META_STATUS;
|
|
|
|
currValue = grpMeta->mGroupStatus;
|
|
|
|
}
|
2013-06-20 15:50:25 -04:00
|
|
|
else if(grpCv.getAsInt32(RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG, value) && grpMeta)
|
2012-11-17 09:35:21 -05:00
|
|
|
{
|
|
|
|
key = RsGeneralDataService::GRP_META_SUBSCRIBE_FLAG;
|
|
|
|
currValue = grpMeta->mSubscribeFlags;
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
if(grpMeta)
|
|
|
|
delete grpMeta;
|
2013-06-20 15:50:25 -04:00
|
|
|
return false;
|
2012-11-17 09:35:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
ok &= grpCv.getAsInt32(key+GXS_MASK, mask);
|
|
|
|
|
2013-03-16 12:44:33 -04:00
|
|
|
// remove mask entry so it doesn't affect actual entry
|
2012-11-17 09:35:21 -05:00
|
|
|
grpCv.removeKeyValue(key+GXS_MASK);
|
|
|
|
|
|
|
|
// apply mask to current value
|
|
|
|
value = (currValue & ~mask) | (value & mask);
|
|
|
|
|
|
|
|
grpCv.put(key, value);
|
|
|
|
|
|
|
|
if(grpMeta)
|
|
|
|
delete grpMeta;
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
2012-07-26 17:48:54 -04:00
|
|
|
void RsGenExchange::publishMsgs()
|
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
|
2012-07-26 17:48:54 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// stick back msgs pending signature
|
2013-03-11 12:04:25 -04:00
|
|
|
typedef std::map<uint32_t, GxsPendingItem<RsGxsMsgItem*, uint32_t> > PendSignMap;
|
2013-03-06 18:33:23 -05:00
|
|
|
|
|
|
|
PendSignMap::iterator sign_it = mMsgPendingSign.begin();
|
|
|
|
|
|
|
|
for(; sign_it != mMsgPendingSign.end(); sign_it++)
|
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsPendingItem<RsGxsMsgItem*, uint32_t>& item = sign_it->second;
|
2013-03-06 18:33:23 -05:00
|
|
|
mMsgsToPublish.insert(std::make_pair(sign_it->first, item.mItem));
|
|
|
|
}
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::map<RsGxsGroupId, std::vector<RsGxsMessageId> > msgChangeMap;
|
2012-08-18 06:01:35 -04:00
|
|
|
std::map<uint32_t, RsGxsMsgItem*>::iterator mit = mMsgsToPublish.begin();
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
for(; mit != mMsgsToPublish.end(); mit++)
|
2012-07-26 17:48:54 -04:00
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
std::cerr << "RsGenExchange::publishMsgs() Publishing a Message";
|
|
|
|
std::cerr << std::endl;
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
RsNxsMsg* msg = new RsNxsMsg(mServType);
|
|
|
|
RsGxsMsgItem* msgItem = mit->second;
|
|
|
|
const uint32_t& token = mit->first;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
msg->grpId = msgItem->meta.mGroupId;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
uint32_t size = mSerialiser->size(msgItem);
|
|
|
|
char* mData = new char[size];
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
bool serialOk = false;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// for fatal sign creation
|
|
|
|
bool createOk = false;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// if sign requests to try later
|
|
|
|
bool tryLater = false;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
serialOk = mSerialiser->serialise(msgItem, mData, &size);
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if(serialOk)
|
|
|
|
{
|
|
|
|
msg->msg.setBinData(mData, size);
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// now create meta
|
|
|
|
msg->metaData = new RsGxsMsgMetaData();
|
|
|
|
*(msg->metaData) = msgItem->meta;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// assign time stamp
|
|
|
|
msg->metaData->mPublishTs = time(NULL);
|
2012-11-15 18:50:54 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// now intialise msg (sign it)
|
|
|
|
uint8_t createReturn = createMessage(msg);
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if(createReturn == CREATE_FAIL)
|
|
|
|
{
|
|
|
|
createOk = false;
|
|
|
|
}
|
|
|
|
else if(createReturn == CREATE_FAIL_TRY_LATER)
|
|
|
|
{
|
|
|
|
PendSignMap::iterator pit = mMsgPendingSign.find(token);
|
|
|
|
tryLater = true;
|
2013-02-07 18:04:16 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// add to queue of messages waiting for a successful
|
|
|
|
// sign attempt
|
|
|
|
if(pit == mMsgPendingSign.end())
|
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsPendingItem<RsGxsMsgItem*, uint32_t> gsi(msgItem, token);
|
2013-03-06 18:33:23 -05:00
|
|
|
mMsgPendingSign.insert(std::make_pair(token, gsi));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// remove from attempts queue if over sign
|
|
|
|
// attempts limit
|
|
|
|
if(pit->second.mAttempts == SIGN_MAX_ATTEMPTS)
|
|
|
|
{
|
|
|
|
mMsgPendingSign.erase(token);
|
|
|
|
tryLater = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pit->second.mAttempts++;
|
|
|
|
}
|
|
|
|
}
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
createOk = false;
|
|
|
|
}
|
|
|
|
else if(createReturn == CREATE_SUCCESS)
|
|
|
|
{
|
|
|
|
createOk = true;
|
2012-10-23 17:52:51 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// erase from queue if it exists
|
|
|
|
mMsgPendingSign.erase(token);
|
|
|
|
}
|
|
|
|
else // unknown return, just fail
|
|
|
|
createOk = false;
|
2012-08-19 18:15:37 -04:00
|
|
|
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-02-27 16:20:00 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
RsGxsMessageId msgId;
|
|
|
|
RsGxsGroupId grpId = msgItem->meta.mGroupId;
|
|
|
|
|
|
|
|
bool validSize = false;
|
2013-02-27 16:20:00 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// check message not over single msg storage limit
|
|
|
|
if(createOk)
|
|
|
|
{
|
|
|
|
validSize = mDataStore->validSize(msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(createOk && validSize)
|
|
|
|
{
|
|
|
|
// empty orig msg id means this is the original
|
|
|
|
// msg
|
|
|
|
if(msg->metaData->mOrigMsgId.empty())
|
|
|
|
{
|
|
|
|
msg->metaData->mOrigMsgId = msg->metaData->mMsgId;
|
|
|
|
}
|
|
|
|
|
|
|
|
// now serialise meta data
|
|
|
|
size = msg->metaData->serial_size();
|
|
|
|
|
|
|
|
char* metaDataBuff = new char[size];
|
|
|
|
bool s = msg->metaData->serialise(metaDataBuff, &size);
|
|
|
|
s &= msg->meta.setBinData(metaDataBuff, size);
|
|
|
|
|
|
|
|
msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD;
|
|
|
|
msgId = msg->msgId;
|
|
|
|
grpId = msg->grpId;
|
2013-06-04 17:00:43 -04:00
|
|
|
computeHash(msg->msg, msg->metaData->mHash);
|
2013-03-06 18:33:23 -05:00
|
|
|
mDataAccess->addMsgData(msg);
|
2013-06-04 17:00:43 -04:00
|
|
|
msgChangeMap[grpId].push_back(msgId);
|
2013-03-06 18:33:23 -05:00
|
|
|
|
|
|
|
delete[] metaDataBuff;
|
|
|
|
|
|
|
|
// add to published to allow acknowledgement
|
|
|
|
mMsgNotify.insert(std::make_pair(mit->first, std::make_pair(grpId, msgId)));
|
|
|
|
mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE);
|
2013-06-04 17:00:43 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// delete msg if create msg not ok
|
|
|
|
delete msg;
|
|
|
|
|
|
|
|
if(!tryLater)
|
|
|
|
mDataAccess->updatePublicRequestStatus(mit->first,
|
|
|
|
RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
|
2012-07-26 17:48:54 -04:00
|
|
|
|
|
|
|
#ifdef GEN_EXCH_DEBUG
|
2013-03-06 18:33:23 -05:00
|
|
|
std::cerr << "RsGenExchange::publishMsgs() failed to publish msg " << std::endl;
|
2012-07-26 17:48:54 -04:00
|
|
|
#endif
|
2013-03-06 18:33:23 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-11-15 18:50:54 -05:00
|
|
|
#ifdef GEN_EXCH_DEBUG
|
2013-03-06 18:33:23 -05:00
|
|
|
std::cerr << "RsGenExchange::publishMsgs() failed to serialise msg " << std::endl;
|
2012-11-15 18:50:54 -05:00
|
|
|
#endif
|
2013-03-06 18:33:23 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
delete[] mData;
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if(!tryLater)
|
|
|
|
delete msgItem;
|
2012-07-26 17:48:54 -04:00
|
|
|
}
|
2012-08-06 17:00:38 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// clear msg item map as we're done publishing them and all
|
|
|
|
// entries are invalid
|
2012-08-06 17:00:38 -04:00
|
|
|
mMsgsToPublish.clear();
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
if(!msgChangeMap.empty())
|
|
|
|
{
|
|
|
|
RsGxsMsgChange* ch = new RsGxsMsgChange(RsGxsNotify::TYPE_PUBLISH);
|
|
|
|
ch->msgChangeMap = msgChangeMap;
|
|
|
|
mNotifications.push_back(ch);
|
|
|
|
}
|
|
|
|
|
2012-07-26 17:48:54 -04:00
|
|
|
}
|
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpItem* /* grpItem */,
|
|
|
|
RsTlvSecurityKeySet& /* keySet */)
|
2012-11-03 21:38:48 -04:00
|
|
|
{
|
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::service_CreateGroup(): Does nothing"
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
2013-03-08 14:55:59 -05:00
|
|
|
return SERVICE_CREATE_SUCCESS;
|
2012-11-03 21:38:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
#define PENDING_SIGN_TIMEOUT 10 // 5 seconds
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2013-09-15 17:18:20 -04:00
|
|
|
|
|
|
|
void RsGenExchange::processGroupUpdatePublish()
|
|
|
|
{
|
|
|
|
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
|
|
|
// get keys for group update publish
|
|
|
|
|
|
|
|
// first build meta request map for groups to be updated
|
|
|
|
std::map<std::string, RsGxsGrpMetaData*> grpMeta;
|
|
|
|
std::vector<GroupUpdatePublish>::iterator vit = mGroupUpdatePublish.begin();
|
|
|
|
|
|
|
|
for(; vit != mGroupUpdatePublish.end(); vit++)
|
|
|
|
{
|
|
|
|
GroupUpdatePublish& gup = *vit;
|
|
|
|
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
|
|
|
grpMeta.insert(std::make_pair(groupId, (RsGxsGrpMetaData*)(NULL)));
|
|
|
|
}
|
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
if(grpMeta.empty())
|
|
|
|
return;
|
|
|
|
|
2013-09-15 17:18:20 -04:00
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMeta);
|
|
|
|
|
|
|
|
// now
|
|
|
|
vit = mGroupUpdatePublish.begin();
|
|
|
|
for(; vit != mGroupUpdatePublish.end(); vit++)
|
|
|
|
{
|
|
|
|
GroupUpdatePublish& gup = *vit;
|
|
|
|
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
|
|
|
|
RsGxsGrpMetaData* meta = grpMeta[groupId];
|
|
|
|
|
2013-10-05 07:36:31 -04:00
|
|
|
gup.grpItem->meta = *meta;
|
|
|
|
assignMetaUpdates(gup.grpItem->meta, gup.mUpdateMeta);
|
|
|
|
GxsGrpPendingSign ggps(gup.grpItem, ggps.mToken);
|
2013-09-15 17:18:20 -04:00
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
bool publishAndAdminPrivatePresent = checkKeys(meta->keys);
|
2013-09-15 17:18:20 -04:00
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
if(publishAndAdminPrivatePresent)
|
2013-09-15 17:18:20 -04:00
|
|
|
{
|
2013-10-06 17:07:31 -04:00
|
|
|
ggps.mPrivateKeys = meta->keys;
|
|
|
|
generatePublicFromPrivateKeys(ggps.mPrivateKeys, ggps.mPublicKeys);
|
|
|
|
ggps.mHaveKeys = true;
|
|
|
|
ggps.mStartTS = time(NULL);
|
|
|
|
ggps.mLastAttemptTS = 0;
|
|
|
|
ggps.mIsUpdate = true;
|
|
|
|
mGrpsToPublish.push_back(ggps);
|
2013-09-15 17:18:20 -04:00
|
|
|
}else
|
|
|
|
{
|
2013-10-06 17:07:31 -04:00
|
|
|
delete gup.grpItem;
|
|
|
|
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
|
2013-09-15 17:18:20 -04:00
|
|
|
}
|
2013-10-06 17:07:31 -04:00
|
|
|
delete meta;
|
2013-09-15 17:18:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
mGroupUpdatePublish.clear();
|
|
|
|
}
|
|
|
|
|
2013-10-05 07:36:31 -04:00
|
|
|
void RsGenExchange::assignMetaUpdates(RsGroupMetaData& meta, const RsGxsGroupUpdateMeta metaUpdate) const
|
|
|
|
{
|
2013-10-06 17:07:31 -04:00
|
|
|
const RsGxsGroupUpdateMeta::GxsMetaUpdate* updates = metaUpdate.getUpdates();
|
2013-10-05 07:36:31 -04:00
|
|
|
RsGxsGroupUpdateMeta::GxsMetaUpdate::const_iterator mit = updates->begin();
|
|
|
|
for(; mit != updates->end(); mit++)
|
|
|
|
{
|
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
if(mit->first == RsGxsGroupUpdateMeta::NAME)
|
|
|
|
meta.mGroupName = mit->second;
|
2013-10-05 07:36:31 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-06 17:07:31 -04:00
|
|
|
bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet)
|
2013-09-15 17:18:20 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
typedef std::map<std::string, RsTlvSecurityKey> keyMap;
|
|
|
|
const keyMap& allKeys = keySet.keys;
|
|
|
|
keyMap::const_iterator cit = allKeys.begin();
|
2013-10-06 17:07:31 -04:00
|
|
|
bool adminFound = false, publishFound = false;
|
2013-09-15 17:18:20 -04:00
|
|
|
for(; cit != allKeys.end(); cit++)
|
|
|
|
{
|
2013-10-06 17:07:31 -04:00
|
|
|
const RsTlvSecurityKey& key = cit->second;
|
|
|
|
if(key.keyFlags & RSTLV_KEY_TYPE_FULL)
|
|
|
|
{
|
|
|
|
if(key.keyFlags & RSTLV_KEY_DISTRIB_ADMIN)
|
|
|
|
adminFound = true;
|
|
|
|
|
|
|
|
if(key.keyFlags & RSTLV_KEY_DISTRIB_PRIVATE)
|
|
|
|
publishFound = true;
|
|
|
|
|
|
|
|
}
|
2013-09-15 17:18:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// user must have both private and public parts of publish and admin keys
|
2013-10-06 17:07:31 -04:00
|
|
|
return adminFound && publishFound;
|
2013-09-15 17:18:20 -04:00
|
|
|
}
|
|
|
|
|
2012-07-26 17:48:54 -04:00
|
|
|
void RsGenExchange::publishGrps()
|
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
RsStackMutex stack(mGenMtx);
|
2013-03-11 12:04:25 -04:00
|
|
|
NxsGrpSignPendVect::iterator vit = mGrpsToPublish.begin();
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
typedef std::pair<bool, RsGxsGroupId> GrpNote;
|
|
|
|
std::map<uint32_t, GrpNote> toNotify;
|
2013-03-08 14:55:59 -05:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
while( vit != mGrpsToPublish.end() )
|
2013-03-08 14:55:59 -05:00
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsGrpPendingSign& ggps = *vit;
|
2013-03-08 14:55:59 -05:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
/* do intial checks to see if this entry has expired */
|
|
|
|
time_t now = time(NULL) ;
|
|
|
|
uint32_t token = ggps.mToken;
|
2012-12-08 16:50:13 -05:00
|
|
|
|
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
if(now > (ggps.mStartTS + PENDING_SIGN_TIMEOUT) )
|
|
|
|
{
|
|
|
|
// timed out
|
|
|
|
toNotify.insert(std::make_pair(
|
|
|
|
token, GrpNote(false, "")));
|
|
|
|
delete ggps.mItem;
|
|
|
|
vit = mGrpsToPublish.erase(vit);
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsGxsGroupId grpId;
|
2012-11-11 18:45:22 -05:00
|
|
|
RsNxsGrp* grp = new RsNxsGrp(mServType);
|
2013-03-11 12:04:25 -04:00
|
|
|
RsGxsGrpItem* grpItem = ggps.mItem;
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
RsTlvSecurityKeySet privatekeySet, publicKeySet;
|
2012-08-26 10:02:47 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
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
|
2012-11-11 18:45:22 -05:00
|
|
|
RsTlvSecurityKey privAdminKey;
|
2013-02-07 18:04:16 -05:00
|
|
|
std::map<std::string, RsTlvSecurityKey>::iterator mit_keys = privatekeySet.keys.begin();
|
2012-11-08 19:56:07 -05:00
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
bool privKeyFound = false;
|
2013-02-07 18:04:16 -05:00
|
|
|
for(; mit_keys != privatekeySet.keys.end(); mit_keys++)
|
2012-11-11 18:45:22 -05:00
|
|
|
{
|
|
|
|
RsTlvSecurityKey& key = mit_keys->second;
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2012-11-19 17:00:05 -05:00
|
|
|
if(key.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
|
2012-11-03 21:38:48 -04:00
|
|
|
{
|
2012-11-11 18:45:22 -05:00
|
|
|
privAdminKey = key;
|
|
|
|
privKeyFound = true;
|
|
|
|
}
|
|
|
|
}
|
2012-11-08 19:56:07 -05:00
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
uint8_t create = CREATE_FAIL;
|
2012-11-08 19:56:07 -05:00
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
if(privKeyFound)
|
|
|
|
{
|
2013-03-08 14:55:59 -05:00
|
|
|
// get group id from private admin key id
|
|
|
|
grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId;
|
2013-02-07 18:04:16 -05:00
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
ServiceCreate_Return ret = service_CreateGroup(grpItem, privatekeySet);
|
2012-11-08 19:56:07 -05:00
|
|
|
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
bool serialOk = false, servCreateOk;
|
|
|
|
|
|
|
|
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;
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
}else
|
|
|
|
{
|
|
|
|
servCreateOk = false;
|
|
|
|
}
|
2013-03-10 11:08:04 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
if(serialOk && servCreateOk)
|
2013-03-08 14:55:59 -05:00
|
|
|
{
|
|
|
|
grp->metaData = new RsGxsGrpMetaData();
|
|
|
|
grpItem->meta.mPublishTs = time(NULL);
|
|
|
|
*(grp->metaData) = grpItem->meta;
|
2013-03-16 12:44:33 -04:00
|
|
|
|
|
|
|
// TODO: change when publish key optimisation added (public groups don't have publish key
|
|
|
|
grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN | GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED
|
|
|
|
| GXS_SERV::GROUP_SUBSCRIBE_PUBLISH;
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
create = createGroup(grp, privatekeySet, publicKeySet);
|
2012-11-11 18:45:22 -05:00
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
if(create == CREATE_SUCCESS)
|
|
|
|
{
|
2013-03-10 11:08:04 -04:00
|
|
|
|
|
|
|
uint32_t mdSize = grp->metaData->serial_size();
|
|
|
|
char* metaData = new char[mdSize];
|
|
|
|
serialOk = grp->metaData->serialise(metaData, mdSize);
|
|
|
|
grp->meta.setBinData(metaData, mdSize);
|
|
|
|
delete[] metaData;
|
|
|
|
|
|
|
|
// place back private keys for publisher
|
|
|
|
grp->metaData->keys = privatekeySet;
|
|
|
|
|
|
|
|
if(mDataStore->validSize(grp) && serialOk)
|
2013-03-08 14:55:59 -05:00
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
grpId = grp->grpId;
|
2013-06-04 17:00:43 -04:00
|
|
|
computeHash(grp->grp, grp->metaData->mHash);
|
2013-09-15 17:18:20 -04:00
|
|
|
|
|
|
|
if(ggps.mIsUpdate)
|
|
|
|
mDataAccess->updateGroupData(grp);
|
|
|
|
else
|
|
|
|
mDataAccess->addGroupData(grp);
|
2013-03-08 14:55:59 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
create = CREATE_FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-11 12:04:25 -04:00
|
|
|
else if(ret == SERVICE_CREATE_FAIL_TRY_LATER)
|
|
|
|
{
|
|
|
|
create = CREATE_FAIL_TRY_LATER;
|
|
|
|
}
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
2013-03-08 14:55:59 -05:00
|
|
|
else
|
2012-11-11 18:45:22 -05:00
|
|
|
{
|
2013-03-08 14:55:59 -05:00
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::publishGrps() Could not find private publish keys " << std::endl;
|
|
|
|
#endif
|
|
|
|
create = CREATE_FAIL;
|
|
|
|
}
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
if(create == CREATE_FAIL)
|
|
|
|
{
|
2012-07-26 17:48:54 -04:00
|
|
|
#ifdef GEN_EXCH_DEBUG
|
2013-03-08 14:55:59 -05:00
|
|
|
std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl;
|
2012-07-26 17:48:54 -04:00
|
|
|
#endif
|
2012-11-11 18:45:22 -05:00
|
|
|
delete grp;
|
2013-03-08 14:55:59 -05:00
|
|
|
delete grpItem;
|
2013-03-11 12:04:25 -04:00
|
|
|
vit = mGrpsToPublish.erase(vit);
|
|
|
|
toNotify.insert(std::make_pair(
|
|
|
|
token, GrpNote(false, grpId)));
|
2012-11-03 21:38:48 -04:00
|
|
|
|
2013-03-08 14:55:59 -05:00
|
|
|
}
|
|
|
|
else if(create == CREATE_FAIL_TRY_LATER)
|
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::publishGrps() failed grp, trying again " << std::endl;
|
|
|
|
#endif
|
|
|
|
ggps.mLastAttemptTS = time(NULL);
|
|
|
|
vit++;
|
2013-03-08 14:55:59 -05:00
|
|
|
}
|
|
|
|
else if(create == CREATE_SUCCESS)
|
|
|
|
{
|
|
|
|
delete grpItem;
|
2013-03-11 12:04:25 -04:00
|
|
|
vit = mGrpsToPublish.erase(vit);
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
#ifdef GEN_EXCH_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies"
|
|
|
|
<< std::endl;
|
|
|
|
#endif
|
2013-03-08 14:55:59 -05:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
// add to published to allow acknowledgement
|
|
|
|
toNotify.insert(std::make_pair(token,
|
|
|
|
GrpNote(true,grpId)));
|
2013-03-08 14:55:59 -05:00
|
|
|
}
|
2012-11-11 18:45:22 -05:00
|
|
|
}
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2013-03-11 12:04:25 -04:00
|
|
|
std::map<uint32_t, GrpNote>::iterator mit = toNotify.begin();
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
std::list<RsGxsGroupId> grpChanged;
|
2013-03-11 12:04:25 -04:00
|
|
|
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);
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
if(note.first)
|
|
|
|
grpChanged.push_back(note.second);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!grpChanged.empty())
|
|
|
|
{
|
|
|
|
RsGxsGroupChange* gc = new RsGxsGroupChange(RsGxsNotify::TYPE_PUBLISH);
|
|
|
|
gc->mGrpIdList = grpChanged;
|
|
|
|
mNotifications.push_back(gc);
|
2013-03-11 12:04:25 -04:00
|
|
|
}
|
|
|
|
|
2012-08-06 17:00:38 -04:00
|
|
|
}
|
2012-08-19 18:15:37 -04:00
|
|
|
|
2012-10-15 14:52:47 -04:00
|
|
|
|
|
|
|
|
|
|
|
uint32_t RsGenExchange::generatePublicToken()
|
|
|
|
{
|
|
|
|
return mDataAccess->generatePublicToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGenExchange::updatePublicRequestStatus(const uint32_t &token, const uint32_t &status)
|
|
|
|
{
|
|
|
|
return mDataAccess->updatePublicRequestStatus(token, status);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGenExchange::disposeOfPublicToken(const uint32_t &token)
|
|
|
|
{
|
|
|
|
return mDataAccess->disposeOfPublicToken(token);
|
|
|
|
}
|
|
|
|
|
|
|
|
RsGeneralDataService* RsGenExchange::getDataStore()
|
|
|
|
{
|
|
|
|
return mDataStore;
|
|
|
|
}
|
|
|
|
|
2012-10-23 17:52:51 -04:00
|
|
|
bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet &keySet)
|
|
|
|
{
|
|
|
|
if(grpId.empty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMeta;
|
|
|
|
grpMeta[grpId] = NULL;
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMeta);
|
|
|
|
|
|
|
|
if(grpMeta.empty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
RsGxsGrpMetaData* meta = grpMeta[grpId];
|
|
|
|
|
|
|
|
if(meta == NULL)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
keySet = meta->keys;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-08-06 17:00:38 -04:00
|
|
|
void RsGenExchange::processRecvdData()
|
|
|
|
{
|
2012-09-25 17:04:04 -04:00
|
|
|
processRecvdGroups();
|
2012-09-30 10:21:17 -04:00
|
|
|
|
|
|
|
processRecvdMessages();
|
2013-09-11 16:42:56 -04:00
|
|
|
|
|
|
|
performUpdateValidation();
|
2012-05-21 18:07:43 -04:00
|
|
|
}
|
2012-07-26 17:48:54 -04:00
|
|
|
|
|
|
|
|
2013-06-04 17:00:43 -04:00
|
|
|
void RsGenExchange::computeHash(const RsTlvBinaryData& data, std::string& hash)
|
|
|
|
{
|
|
|
|
pqihash pHash;
|
|
|
|
pHash.addData(data.bin_data, data.bin_len);
|
|
|
|
pHash.Complete(hash);
|
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
|
2012-08-06 17:00:38 -04:00
|
|
|
void RsGenExchange::processRecvdMessages()
|
|
|
|
{
|
2012-09-30 10:21:17 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
NxsMsgPendingVect::iterator pend_it = mMsgPendingValidate.begin();
|
|
|
|
|
|
|
|
for(; pend_it != mMsgPendingValidate.end();)
|
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair>& gpsi = *pend_it;
|
2013-03-06 18:33:23 -05:00
|
|
|
|
|
|
|
if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS)
|
|
|
|
{
|
|
|
|
delete gpsi.mItem;
|
|
|
|
pend_it = mMsgPendingValidate.erase(pend_it);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mReceivedMsgs.push_back(gpsi.mItem);
|
|
|
|
pend_it++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-09-30 10:21:17 -04:00
|
|
|
std::vector<RsNxsMsg*>::iterator vit = mReceivedMsgs.begin();
|
|
|
|
GxsMsgReq msgIds;
|
|
|
|
std::map<RsNxsMsg*, RsGxsMsgMetaData*> msgs;
|
|
|
|
|
2012-11-10 18:42:38 -05:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*> grpMetas;
|
|
|
|
|
|
|
|
// coalesce group meta retrieval for performance
|
2012-09-30 10:21:17 -04:00
|
|
|
for(; vit != mReceivedMsgs.end(); vit++)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
|
|
|
RsNxsMsg* msg = *vit;
|
|
|
|
grpMetas.insert(std::make_pair(msg->grpId, (RsGxsGrpMetaData*)NULL));
|
|
|
|
}
|
|
|
|
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetas);
|
|
|
|
|
|
|
|
for(vit = mReceivedMsgs.begin(); vit != mReceivedMsgs.end(); vit++)
|
2012-09-30 10:21:17 -04:00
|
|
|
{
|
|
|
|
RsNxsMsg* msg = *vit;
|
|
|
|
RsGxsMsgMetaData* meta = new RsGxsMsgMetaData();
|
2013-03-23 10:07:52 -04:00
|
|
|
|
|
|
|
bool ok = false;
|
|
|
|
|
|
|
|
if(msg->meta.bin_len != 0)
|
|
|
|
ok = meta->deserialise(msg->meta.bin_data, &(msg->meta.bin_len));
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
msg->metaData = meta;
|
2012-09-30 10:21:17 -04:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
uint8_t validateReturn = VALIDATE_FAIL;
|
2012-12-02 14:40:17 -05:00
|
|
|
|
2012-09-30 10:21:17 -04:00
|
|
|
if(ok)
|
|
|
|
{
|
2012-11-10 18:42:38 -05:00
|
|
|
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = grpMetas.find(msg->grpId);
|
|
|
|
|
|
|
|
// validate msg
|
2013-03-06 18:33:23 -05:00
|
|
|
if(mit != grpMetas.end())
|
|
|
|
{
|
2012-11-10 18:42:38 -05:00
|
|
|
RsGxsGrpMetaData* grpMeta = mit->second;
|
2013-03-06 18:33:23 -05:00
|
|
|
validateReturn = validateMsg(msg, grpMeta->mGroupFlags, grpMeta->keys);
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if(validateReturn == VALIDATE_SUCCESS)
|
2012-11-10 18:42:38 -05:00
|
|
|
{
|
2012-11-17 09:35:21 -05:00
|
|
|
meta->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD;
|
2012-11-10 18:42:38 -05:00
|
|
|
msgs.insert(std::make_pair(msg, meta));
|
|
|
|
msgIds[msg->grpId].push_back(msg->msgId);
|
2013-03-06 18:33:23 -05:00
|
|
|
|
|
|
|
NxsMsgPendingVect::iterator validated_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(),
|
|
|
|
getMsgIdPair(*msg));
|
|
|
|
|
|
|
|
if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry);
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
computeHash(msg->msg, meta->mHash);
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
2012-09-30 10:21:17 -04:00
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
else
|
2012-09-30 10:21:17 -04:00
|
|
|
{
|
2013-03-06 18:33:23 -05:00
|
|
|
validateReturn = VALIDATE_FAIL;
|
|
|
|
}
|
2013-02-27 16:20:00 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
if(validateReturn == VALIDATE_FAIL)
|
|
|
|
{
|
2013-02-27 16:20:00 -05:00
|
|
|
|
2012-09-30 10:21:17 -04:00
|
|
|
#ifdef GXS_GENX_DEBUG
|
2013-03-23 10:07:52 -04:00
|
|
|
std::cerr << "failed to deserialise incoming meta, msgId: "
|
|
|
|
<< "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl;
|
2012-09-30 10:21:17 -04:00
|
|
|
#endif
|
2013-03-06 18:33:23 -05:00
|
|
|
|
|
|
|
NxsMsgPendingVect::iterator failed_entry = std::find(mMsgPendingValidate.begin(), mMsgPendingValidate.end(),
|
|
|
|
getMsgIdPair(*msg));
|
|
|
|
|
|
|
|
if(failed_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(failed_entry);
|
2013-03-10 11:08:04 -04:00
|
|
|
delete msg;
|
2013-03-06 18:33:23 -05:00
|
|
|
|
|
|
|
|
2012-09-30 10:21:17 -04:00
|
|
|
}
|
2013-03-06 18:33:23 -05:00
|
|
|
else if(validateReturn == VALIDATE_FAIL_TRY_LATER)
|
|
|
|
{
|
2012-09-30 10:21:17 -04:00
|
|
|
|
2013-03-23 10:07:52 -04:00
|
|
|
#ifdef GXS_GENX_DEBUG
|
|
|
|
std::cerr << "failed to validate msg, trying again: "
|
|
|
|
<< "msg->grpId: " << msg->grpId << ", msgId: " << msg->msgId << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
RsGxsGrpMsgIdPair id;
|
|
|
|
id.first = msg->grpId;
|
|
|
|
id.second = msg->msgId;
|
2012-11-10 18:42:38 -05:00
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// first check you haven't made too many attempts
|
|
|
|
|
|
|
|
NxsMsgPendingVect::iterator vit = std::find(
|
|
|
|
mMsgPendingValidate.begin(), mMsgPendingValidate.end(), id);
|
|
|
|
|
|
|
|
if(vit == mMsgPendingValidate.end())
|
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsPendingItem<RsNxsMsg*, RsGxsGrpMsgIdPair> item(msg, id);
|
2013-03-06 18:33:23 -05:00
|
|
|
mMsgPendingValidate.push_back(item);
|
|
|
|
}else
|
|
|
|
{
|
|
|
|
vit->mAttempts++;
|
|
|
|
}
|
|
|
|
}
|
2012-11-10 18:42:38 -05:00
|
|
|
}
|
|
|
|
|
2013-03-06 18:33:23 -05:00
|
|
|
// clean up resources from group meta retrieval
|
|
|
|
freeAndClearContainerResource<std::map<RsGxsGroupId, RsGxsGrpMetaData*>,
|
|
|
|
RsGxsGrpMetaData*>(grpMetas);
|
|
|
|
|
2012-09-30 10:21:17 -04:00
|
|
|
if(!msgIds.empty())
|
|
|
|
{
|
|
|
|
mDataStore->storeMessage(msgs);
|
2013-06-04 17:00:43 -04:00
|
|
|
RsGxsMsgChange* c = new RsGxsMsgChange(RsGxsNotify::TYPE_RECEIVE);
|
2012-09-30 10:21:17 -04:00
|
|
|
c->msgChangeMap = msgIds;
|
|
|
|
mNotifications.push_back(c);
|
|
|
|
}
|
|
|
|
|
|
|
|
mReceivedMsgs.clear();
|
2012-08-06 17:00:38 -04:00
|
|
|
}
|
2012-07-26 17:48:54 -04:00
|
|
|
|
2012-08-06 17:00:38 -04:00
|
|
|
void RsGenExchange::processRecvdGroups()
|
|
|
|
{
|
2012-09-25 17:04:04 -04:00
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin();
|
2013-09-15 17:18:20 -04:00
|
|
|
std::vector<std::string> existingGrpIds;
|
|
|
|
std::list<std::string> grpIds;
|
2013-09-11 16:42:56 -04:00
|
|
|
|
2012-09-25 17:04:04 -04:00
|
|
|
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
|
|
|
|
|
2013-09-11 16:42:56 -04:00
|
|
|
mDataStore->retrieveGroupIds(existingGrpIds);
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
while( vit != mReceivedGrps.end())
|
2012-09-25 17:04:04 -04:00
|
|
|
{
|
2013-03-11 12:04:25 -04:00
|
|
|
GxsPendingItem<RsNxsGrp*, RsGxsGroupId>& gpsi = *vit;
|
2013-03-10 11:08:04 -04:00
|
|
|
RsNxsGrp* grp = gpsi.mItem;
|
2012-09-25 17:04:04 -04:00
|
|
|
RsGxsGrpMetaData* meta = new RsGxsGrpMetaData();
|
2013-03-23 10:07:52 -04:00
|
|
|
bool deserialOk = false;
|
|
|
|
|
|
|
|
if(grp->meta.bin_len != 0)
|
|
|
|
deserialOk = meta->deserialise(grp->meta.bin_data, grp->meta.bin_len);
|
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
bool erase = true;
|
2012-09-25 17:04:04 -04:00
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
if(deserialOk)
|
2012-09-30 10:21:17 -04:00
|
|
|
{
|
2013-03-10 11:08:04 -04:00
|
|
|
grp->metaData = meta;
|
|
|
|
uint8_t ret = validateGrp(grp, meta->keys);
|
|
|
|
|
|
|
|
|
|
|
|
if(ret == VALIDATE_SUCCESS)
|
|
|
|
{
|
|
|
|
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD;
|
2013-03-16 12:44:33 -04:00
|
|
|
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
|
2013-06-04 17:00:43 -04:00
|
|
|
|
|
|
|
computeHash(grp->grp, meta->mHash);
|
2013-03-10 11:08:04 -04:00
|
|
|
|
2013-09-11 16:42:56 -04:00
|
|
|
// now check if group already existss
|
|
|
|
if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end())
|
|
|
|
{
|
2013-10-13 17:49:17 -04:00
|
|
|
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
|
|
|
|
meta->mOriginator = grp->PeerId();
|
|
|
|
|
2013-09-11 16:42:56 -04:00
|
|
|
grps.insert(std::make_pair(grp, meta));
|
|
|
|
grpIds.push_back(grp->grpId);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
GroupUpdate update;
|
|
|
|
update.newGrp = grp;
|
|
|
|
mGroupUpdates.push_back(update);
|
|
|
|
}
|
2013-03-10 11:08:04 -04:00
|
|
|
erase = true;
|
|
|
|
}
|
|
|
|
else if(ret == VALIDATE_FAIL)
|
|
|
|
{
|
|
|
|
#ifdef GXS_GENX_DEBUG
|
|
|
|
std::cerr << "failed to deserialise incoming meta, grpId: "
|
|
|
|
<< grp->grpId << std::endl;
|
|
|
|
#endif
|
|
|
|
delete grp;
|
|
|
|
erase = true;
|
|
|
|
}
|
|
|
|
else if(ret == VALIDATE_FAIL_TRY_LATER)
|
|
|
|
{
|
2013-03-23 10:07:52 -04:00
|
|
|
|
|
|
|
#ifdef GXS_GENX_DEBUG
|
|
|
|
std::cerr << "failed to validate incoming grp, trying again. grpId: "
|
|
|
|
<< grp->grpId << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2013-03-10 11:08:04 -04:00
|
|
|
if(gpsi.mAttempts == VALIDATE_MAX_ATTEMPTS)
|
|
|
|
{
|
|
|
|
delete grp;
|
|
|
|
erase = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
erase = false;
|
|
|
|
}
|
|
|
|
}
|
2012-09-30 10:21:17 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-03-10 11:08:04 -04:00
|
|
|
delete grp;
|
2013-03-17 11:46:05 -04:00
|
|
|
delete meta;
|
2013-03-10 11:08:04 -04:00
|
|
|
erase = true;
|
2012-09-30 10:21:17 -04:00
|
|
|
}
|
2013-03-10 11:08:04 -04:00
|
|
|
|
|
|
|
if(erase)
|
|
|
|
vit = mReceivedGrps.erase(vit);
|
|
|
|
else
|
|
|
|
vit++;
|
2012-09-25 17:04:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!grpIds.empty())
|
|
|
|
{
|
2013-06-04 17:00:43 -04:00
|
|
|
RsGxsGroupChange* c = new RsGxsGroupChange(RsGxsNotify::TYPE_RECEIVE);
|
2013-02-28 16:58:38 -05:00
|
|
|
c->mGrpIdList = grpIds;
|
2012-09-25 17:04:04 -04:00
|
|
|
mNotifications.push_back(c);
|
|
|
|
mDataStore->storeGroup(grps);
|
|
|
|
}
|
2012-08-06 17:00:38 -04:00
|
|
|
}
|
2013-09-11 16:42:56 -04:00
|
|
|
|
|
|
|
void RsGenExchange::performUpdateValidation()
|
|
|
|
{
|
2013-10-13 17:49:17 -04:00
|
|
|
|
|
|
|
RsStackMutex stack(mGenMtx);
|
|
|
|
|
2013-09-11 16:42:56 -04:00
|
|
|
#ifdef GXS_GENX_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
|
|
|
#endif
|
|
|
|
|
2013-09-18 14:13:38 -04:00
|
|
|
if(mGroupUpdates.empty())
|
|
|
|
return;
|
|
|
|
|
2013-09-11 16:42:56 -04:00
|
|
|
std::map<std::string, RsGxsGrpMetaData*> grpMetas;
|
|
|
|
|
|
|
|
std::vector<GroupUpdate>::iterator vit = mGroupUpdates.begin();
|
|
|
|
for(; vit != mGroupUpdates.end(); vit++)
|
|
|
|
grpMetas.insert(std::make_pair(vit->newGrp->grpId, (RsGxsGrpMetaData*)NULL));
|
|
|
|
|
2013-09-18 14:13:38 -04:00
|
|
|
if(!grpMetas.empty())
|
|
|
|
mDataStore->retrieveGxsGrpMetaData(grpMetas);
|
|
|
|
else
|
|
|
|
return;
|
2013-09-11 16:42:56 -04:00
|
|
|
|
|
|
|
vit = mGroupUpdates.begin();
|
|
|
|
for(; vit != mGroupUpdates.end(); vit++)
|
|
|
|
{
|
|
|
|
GroupUpdate& gu = *vit;
|
|
|
|
std::map<std::string, RsGxsGrpMetaData*>::iterator mit =
|
|
|
|
grpMetas.find(gu.newGrp->grpId);
|
|
|
|
gu.oldGrpMeta = mit->second;
|
|
|
|
gu.validUpdate = updateValid(*(gu.oldGrpMeta), *(gu.newGrp));
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef GXS_GENX_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
vit = mGroupUpdates.begin();
|
|
|
|
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
|
|
|
|
for(; vit != mGroupUpdates.end(); vit++)
|
|
|
|
{
|
|
|
|
GroupUpdate& gu = *vit;
|
2013-10-13 17:49:17 -04:00
|
|
|
|
|
|
|
if(gu.validUpdate)
|
|
|
|
{
|
|
|
|
if(gu.newGrp->metaData->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
|
|
|
|
gu.newGrp->metaData->mOriginator = gu.newGrp->PeerId();
|
|
|
|
|
|
|
|
grps.insert(std::make_pair(gu.newGrp, gu.newGrp->metaData));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
delete gu.newGrp;
|
|
|
|
}
|
|
|
|
|
2013-09-11 16:42:56 -04:00
|
|
|
delete gu.oldGrpMeta;
|
|
|
|
}
|
|
|
|
|
|
|
|
mDataStore->updateGroup(grps);
|
|
|
|
mGroupUpdates.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RsGenExchange::updateValid(RsGxsGrpMetaData& oldGrpMeta, RsNxsGrp& newGrp) const
|
|
|
|
{
|
|
|
|
std::map<SignType, RsTlvKeySignature>& signSet = newGrp.metaData->signSet.keySignSet;
|
|
|
|
std::map<SignType, RsTlvKeySignature>::iterator mit = signSet.find(GXS_SERV::FLAG_AUTHEN_ADMIN);
|
|
|
|
|
|
|
|
if(mit == signSet.end())
|
|
|
|
{
|
|
|
|
#ifdef GXS_GENX_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::updateValid() new admin sign not found! " << std::endl;
|
|
|
|
std::cerr << "RsGenExchange::updateValid() grpId: " << oldGrp.grpId << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
RsTlvKeySignature& adminSign = mit->second;
|
|
|
|
|
|
|
|
std::map<std::string, RsTlvSecurityKey>& keys = oldGrpMeta.keys.keys;
|
|
|
|
std::map<std::string, RsTlvSecurityKey>::iterator keyMit = keys.find(oldGrpMeta.mGroupId);
|
|
|
|
|
|
|
|
if(keyMit == keys.end())
|
|
|
|
{
|
|
|
|
#ifdef GXS_GENX_DEBUG
|
|
|
|
std::cerr << "RsGenExchange::updateValid() admin key not found! " << std::endl;
|
|
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// also check this is the latest published group
|
|
|
|
bool latest = newGrp.metaData->mPublishTs > oldGrpMeta.mPublishTs;
|
|
|
|
|
|
|
|
return GxsSecurity::validateNxsGrp(newGrp, adminSign, keyMit->second) && latest;
|
|
|
|
}
|