merging rs_gxs-finale to v0.6 branch

git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.6-initdev@6953 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
chrisparker126 2013-12-21 18:20:47 +00:00
commit 39909b705f
67 changed files with 5686 additions and 488 deletions

View File

@ -38,7 +38,7 @@ GxsSecurity::~GxsSecurity()
{
}
RSA *GxsSecurity::extractPublicKey(RsTlvSecurityKey& key)
RSA *GxsSecurity::extractPublicKey(const RsTlvSecurityKey& key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;
@ -489,7 +489,7 @@ void GxsSecurity::setRSAPrivateKey(RsTlvSecurityKey & key, RSA *rsa_priv)
key.keyId = keyId;
}
RSA *GxsSecurity::extractPrivateKey(RsTlvSecurityKey & key)
RSA *GxsSecurity::extractPrivateKey(const RsTlvSecurityKey & key)
{
const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data;
long keylen = key.keyData.bin_len;

View File

@ -51,14 +51,14 @@ public:
* @param key RsTlvSecurityKey to extract public RSA key from
* @return pointer to the public RSA key if successful, null otherwise
*/
static RSA *extractPublicKey(RsTlvSecurityKey &key);
static RSA *extractPublicKey(const RsTlvSecurityKey &key);
/*!
* extracts the public key from an RsTlvSecurityKey
* @param key RsTlvSecurityKey to extract private RSA key from
* @return pointer to the private RSA key if successful, null otherwise
*/
static RSA *extractPrivateKey(RsTlvSecurityKey &key);
static RSA *extractPrivateKey(const RsTlvSecurityKey &key);
/*!
* stores the rsa public key in a RsTlvSecurityKey

View File

@ -34,6 +34,8 @@
#define MSG_TABLE_NAME std::string("MESSAGES")
#define GRP_TABLE_NAME std::string("GROUPS")
#define GRP_LAST_POST_UPDATE_TRIGGER std::string("LAST_POST_UPDATE")
// generic
#define KEY_NXS_FILE std::string("nxsFile")
@ -48,6 +50,7 @@
#define KEY_NXS_META std::string("meta")
#define KEY_NXS_SERV_STRING std::string("serv_str")
#define KEY_NXS_HASH std::string("hash")
#define KEY_RECV_TS std::string("recv_time_stamp")
// grp table columns
@ -111,6 +114,7 @@
#define COL_GRP_INTERN_CIRCLE 18
#define COL_GRP_ORIGINATOR 19
#define COL_GRP_AUTHEN_FLAGS 20
#define COL_GRP_RECV_TS 21
// msg col numbers
@ -122,6 +126,7 @@
#define COL_THREAD_ID 11
#define COL_MSG_NAME 12
#define COL_MSG_SERV_STRING 13
#define COL_MSG_RECV_TS 14
// generic meta shared col numbers
#define COL_GRP_ID 0
@ -154,7 +159,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
msgMetaColumns.push_back(KEY_SIGN_SET); msgMetaColumns.push_back(KEY_NXS_IDENTITY); msgMetaColumns.push_back(KEY_NXS_HASH);
msgMetaColumns.push_back(KEY_MSG_ID); msgMetaColumns.push_back(KEY_ORIG_MSG_ID); msgMetaColumns.push_back(KEY_MSG_STATUS);
msgMetaColumns.push_back(KEY_CHILD_TS); msgMetaColumns.push_back(KEY_MSG_PARENT_ID); msgMetaColumns.push_back(KEY_MSG_THREAD_ID);
msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING);
msgMetaColumns.push_back(KEY_MSG_NAME); msgMetaColumns.push_back(KEY_NXS_SERV_STRING); msgMetaColumns.push_back(KEY_RECV_TS);
// for retrieving actual data
msgColumns.push_back(KEY_GRP_ID); msgColumns.push_back(KEY_NXS_FILE); msgColumns.push_back(KEY_NXS_FILE_OFFSET);
@ -168,7 +173,7 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
grpMetaColumns.push_back(KEY_GRP_LAST_POST); grpMetaColumns.push_back(KEY_ORIG_GRP_ID); grpMetaColumns.push_back(KEY_NXS_SERV_STRING);
grpMetaColumns.push_back(KEY_GRP_SIGN_FLAGS); grpMetaColumns.push_back(KEY_GRP_CIRCLE_ID); grpMetaColumns.push_back(KEY_GRP_CIRCLE_TYPE);
grpMetaColumns.push_back(KEY_GRP_INTERNAL_CIRCLE); grpMetaColumns.push_back(KEY_GRP_ORIGINATOR);
grpMetaColumns.push_back(KEY_GRP_AUTHEN_FLAGS);
grpMetaColumns.push_back(KEY_GRP_AUTHEN_FLAGS); grpMetaColumns.push_back(KEY_RECV_TS);
// for retrieving actual grp data
grpColumns.push_back(KEY_GRP_ID); grpColumns.push_back(KEY_NXS_FILE); grpColumns.push_back(KEY_NXS_FILE_OFFSET);
@ -177,6 +182,8 @@ RsDataService::RsDataService(const std::string &serviceDir, const std::string &d
// for retrieving msg offsets
mMsgOffSetColumns.push_back(KEY_MSG_ID); mMsgOffSetColumns.push_back(KEY_NXS_FILE_OFFSET);
mMsgOffSetColumns.push_back(KEY_NXS_FILE_LEN);
grpIdColumn.push_back(KEY_GRP_ID);
}
RsDataService::~RsDataService(){
@ -210,6 +217,7 @@ void RsDataService::initialise(){
KEY_MSG_NAME + " TEXT," +
KEY_NXS_SERV_STRING + " TEXT," +
KEY_NXS_HASH + " TEXT," +
KEY_RECV_TS + " INT," +
KEY_NXS_FILE_LEN + " INT);");
// create table for grp data
@ -238,8 +246,15 @@ void RsDataService::initialise(){
KEY_GRP_INTERNAL_CIRCLE + " TEXT," +
KEY_GRP_ORIGINATOR + " TEXT," +
KEY_NXS_HASH + " TEXT," +
KEY_RECV_TS + " INT," +
KEY_SIGN_SET + " BLOB);");
mDb->execSQL("CREATE TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER +
" INSERT ON " + MSG_TABLE_NAME +
std::string(" BEGIN ") +
" UPDATE " + GRP_TABLE_NAME + " SET " + KEY_GRP_LAST_POST + "= new."
+ KEY_RECV_TS + " WHERE " + KEY_GRP_ID + "=new." + KEY_GRP_ID + ";"
+ std::string("END;"));
}
RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
@ -291,6 +306,7 @@ RsGxsGrpMetaData* RsDataService::locked_getGrpMeta(RetroCursor &c)
c.getString(COL_GRP_INTERN_CIRCLE, grpMeta->mInternalCircle);
c.getString(COL_GRP_ORIGINATOR, grpMeta->mOriginator);
grpMeta->mAuthenFlags = c.getInt32(COL_GRP_AUTHEN_FLAGS);
grpMeta->mRecvTS = c.getInt32(COL_GRP_RECV_TS);
if(ok)
@ -377,6 +393,7 @@ RsGxsMsgMetaData* RsDataService::locked_getMsgMeta(RetroCursor &c)
c.getString(COL_MSG_NAME, msgMeta->mMsgName);
c.getString(COL_MSG_SERV_STRING, msgMeta->mServiceString);
c.getString(COL_HASH, msgMeta->mHash);
msgMeta->recvTS = c.getInt32(COL_MSG_RECV_TS);
offset = 0;
data = (char*)c.getData(COL_SIGN_SET, data_len);
@ -489,6 +506,7 @@ int RsDataService::storeMessage(std::map<RsNxsMsg *, RsGxsMsgMetaData *> &msg)
cv.put(KEY_GRP_ID, msgMetaPtr->mGroupId);
cv.put(KEY_NXS_SERV_STRING, msgMetaPtr->mServiceString);
cv.put(KEY_NXS_HASH, msgMetaPtr->mHash);
cv.put(KEY_RECV_TS, (int32_t)msgMetaPtr->recvTS);
char signSetData[msgMetaPtr->signSet.TlvSize()];
@ -596,6 +614,7 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator);
cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags);
cv.put(KEY_NXS_HASH, grpMetaPtr->mHash);
cv.put(KEY_RECV_TS, (int32_t)grpMetaPtr->mRecvTS);
if(! (grpMetaPtr->mAuthorId.empty()) ){
cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId);
@ -641,6 +660,98 @@ int RsDataService::storeGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
return ret;
}
int RsDataService::updateGroup(std::map<RsNxsGrp *, RsGxsGrpMetaData *> &grp)
{
RsStackMutex stack(mDbMutex);
std::map<RsNxsGrp*, RsGxsGrpMetaData* >::iterator sit = grp.begin();
// begin transaction
mDb->execSQL("BEGIN;");
for(; sit != grp.end(); sit++)
{
RsNxsGrp* grpPtr = sit->first;
RsGxsGrpMetaData* grpMetaPtr = sit->second;
// if data is larger than max item size do not add
if(!validSize(grpPtr)) continue;
std::string grpFile = mServiceDir + "/" + grpPtr->grpId;
std::ofstream ostrm(grpFile.c_str(), std::ios::binary | std::ios::trunc);
uint32_t offset = 0; // get file offset
/*!
* STORE file offset, file length, file name,
* grpId, flags, publish time stamp, identity,
* id signature, admin signatue, key set, last posting ts
* and meta data
**/
ContentValue cv;
cv.put(KEY_NXS_FILE_OFFSET, (int32_t)offset);
cv.put(KEY_NXS_FILE_LEN, (int32_t)grpPtr->grp.TlvSize());
cv.put(KEY_NXS_FILE, grpFile);
cv.put(KEY_GRP_ID, grpPtr->grpId);
cv.put(KEY_GRP_NAME, grpMetaPtr->mGroupName);
cv.put(KEY_ORIG_GRP_ID, grpMetaPtr->mOrigGrpId);
cv.put(KEY_NXS_SERV_STRING, grpMetaPtr->mServiceString);
cv.put(KEY_NXS_FLAGS, (int32_t)grpMetaPtr->mGroupFlags);
cv.put(KEY_TIME_STAMP, (int32_t)grpMetaPtr->mPublishTs);
cv.put(KEY_GRP_SIGN_FLAGS, (int32_t)grpMetaPtr->mSignFlags);
cv.put(KEY_GRP_CIRCLE_ID, grpMetaPtr->mCircleId);
cv.put(KEY_GRP_CIRCLE_TYPE, (int32_t)grpMetaPtr->mCircleType);
cv.put(KEY_GRP_INTERNAL_CIRCLE, grpMetaPtr->mInternalCircle);
cv.put(KEY_GRP_ORIGINATOR, grpMetaPtr->mOriginator);
cv.put(KEY_GRP_AUTHEN_FLAGS, (int32_t)grpMetaPtr->mAuthenFlags);
cv.put(KEY_NXS_HASH, grpMetaPtr->mHash);
if(! (grpMetaPtr->mAuthorId.empty()) ){
cv.put(KEY_NXS_IDENTITY, grpMetaPtr->mAuthorId);
}
offset = 0;
char keySetData[grpMetaPtr->keys.TlvSize()];
grpMetaPtr->keys.SetTlv(keySetData, grpMetaPtr->keys.TlvSize(), &offset);
cv.put(KEY_KEY_SET, grpMetaPtr->keys.TlvSize(), keySetData);
offset = 0;
char metaData[grpPtr->meta.TlvSize()];
grpPtr->meta.SetTlv(metaData, grpPtr->meta.TlvSize(), &offset);
cv.put(KEY_NXS_META, grpPtr->meta.TlvSize(), metaData);
// local meta data
cv.put(KEY_GRP_SUBCR_FLAG, (int32_t)grpMetaPtr->mSubscribeFlags);
cv.put(KEY_GRP_POP, (int32_t)grpMetaPtr->mPop);
cv.put(KEY_MSG_COUNT, (int32_t)grpMetaPtr->mMsgCount);
cv.put(KEY_GRP_STATUS, (int32_t)grpMetaPtr->mGroupStatus);
cv.put(KEY_GRP_LAST_POST, (int32_t)grpMetaPtr->mLastPost);
offset = 0;
char grpData[grpPtr->grp.TlvSize()];
grpPtr->grp.SetTlv(grpData, grpPtr->grp.TlvSize(), &offset);
ostrm.write(grpData, grpPtr->grp.TlvSize());
ostrm.close();
mDb->sqlUpdate(GRP_TABLE_NAME, "grpId='" + grpPtr->grpId + "'", cv);
}
// finish transaction
bool ret = mDb->execSQL("COMMIT;");
for(sit = grp.begin(); sit != grp.end(); sit++)
{
//TODO: API encourages aliasing, remove this abomination
if(sit->second != sit->first->metaData)
delete sit->second;
delete sit->first;
}
return ret;
}
bool RsDataService::validSize(RsNxsGrp* grp) const
{
if((grp->grp.TlvSize() + grp->meta.TlvSize()) <= GXS_MAX_ITEM_SIZE) return true;
@ -964,34 +1075,33 @@ int RsDataService::retrieveGxsGrpMetaData(std::map<RsGxsGroupId, RsGxsGrpMetaDat
}else
{
std::map<RsGxsGroupId, RsGxsGrpMetaData *>::iterator mit = grp.begin();
for(; mit != grp.end(); mit++)
{
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "grpId='" + grpId + "'", "");
for(; mit != grp.end(); mit++)
{
const RsGxsGroupId& grpId = mit->first;
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpMetaColumns, "grpId='" + grpId + "'", "");
if(c)
{
bool valid = c->moveToFirst();
if(c)
{
bool valid = c->moveToFirst();
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c);
while(valid)
{
RsGxsGrpMetaData* g = locked_getGrpMeta(*c);
if(g)
{
grp[g->mGroupId] = g;
}
valid = c->moveToNext();
}
delete c;
}
if(g)
{
grp[g->mGroupId] = g;
}
valid = c->moveToNext();
}
delete c;
}
}
}
}
}
return 1;
@ -1010,21 +1120,22 @@ int RsDataService::resetDataStore()
std::map<std::string, RsNxsGrp*>::iterator mit
= grps.begin();
// remove all grp msgs files from service dir
for(; mit != grps.end(); mit++){
std::string file = mServiceDir + "/" + mit->first;
std::string msgFile = file + "-msgs";
remove(file.c_str()); // remove group file
remove(msgFile.c_str()); // and remove messages file
delete mit->second;
}
{
RsStackMutex stack(mDbMutex);
mDb->closeDb();
}
remove(mDbName.c_str()); // remove db file
// remove all grp msgs files from service dir
for(; mit != grps.end(); mit++){
std::string file = mServiceDir + "/" + mit->first;
std::string msgFile = file + "-msgs";
remove(file.c_str()); // remove group file
remove(msgFile.c_str()); // and remove messages file
delete mit->second;
}
mDb->execSQL("DROP TABLE " + MSG_TABLE_NAME);
mDb->execSQL("DROP TABLE " + GRP_TABLE_NAME);
mDb->execSQL("DROP TRIGGER " + GRP_LAST_POST_UPDATE_TRIGGER);
}
// recreate database
initialise();
@ -1177,6 +1288,31 @@ int RsDataService::removeGroups(const std::vector<std::string> &grpIds)
return 1;
}
int RsDataService::retrieveGroupIds(std::vector<std::string> &grpIds)
{
RsStackMutex stack(mDbMutex);
RetroCursor* c = mDb->sqlQuery(GRP_TABLE_NAME, grpIdColumn, "", "");
if(c)
{
bool valid = c->moveToFirst();
while(valid)
{
std::string grpId;
c->getString(0, grpId);
grpIds.push_back(grpId);
valid = c->moveToNext();
}
delete c;
}else
{
return 0;
}
return 1;
}
bool RsDataService::locked_updateMessageEntries(const MsgUpdates& updates)
{

View File

@ -106,6 +106,13 @@ public:
*/
int removeGroups(const std::vector<RsGxsGroupId>& grpIds);
/*!
* Retrieves all group ids in store
* @param grpIds all grpids in store is inserted into this vector
* @return error code
*/
int retrieveGroupIds(std::vector<std::string> &grpIds);
/*!
* @return the cache size set for this RsGeneralDataService in bytes
*/
@ -130,6 +137,13 @@ public:
*/
int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grp);
/*!
* Updates group entries in Db
* @param grp map of group and decoded meta data
* @return error code
*/
int updateGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp);
/*!
* @param metaData The meta data item to update
* @return error code
@ -238,6 +252,7 @@ private:
std::list<std::string> grpColumns;
std::list<std::string> grpMetaColumns;
std::list<std::string> grpIdColumn;
std::string mServiceDir, mDbName;
uint16_t mServType;

View File

@ -169,6 +169,13 @@ public:
*/
virtual int removeGroups(const std::vector<RsGxsGroupId>& grpIds) = 0;
/*!
* Retrieves all group ids in store
* @param grpIds all grpids in store is inserted into this vector
* @return error code
*/
virtual int retrieveGroupIds(std::vector<RsGxsGroupId>& grpIds) = 0;
/*!
* @return the cache size set for this RsGeneralDataService in bytes
*/
@ -194,6 +201,13 @@ public:
virtual int storeGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp) = 0;
/*!
* Updates group entries in Db
* @param grp map of group and decoded meta data
* @return error code
*/
virtual int updateGroup(std::map<RsNxsGrp*, RsGxsGrpMetaData*>& grsp) = 0;
/*!
* @param metaData
*/

View File

@ -113,6 +113,8 @@ void RsGenExchange::tick()
publishMsgs();
processGroupUpdatePublish();
processRecvdData();
if(!mNotifications.empty())
@ -273,6 +275,56 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& privatekeySet,
}
}
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;
pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */
publickeySet.keys.insert(std::make_pair(pubKey.keyId, pubKey));
}
if(rsaPrivKey)
RSA_free(rsaPrivKey);
if(rsaPubKey)
RSA_free(rsaPubKey);
}
}
}
uint8_t RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& privateKeySet, RsTlvSecurityKeySet& publicKeySet)
{
std::cerr << "RsGenExchange::createGroup()";
@ -763,6 +815,7 @@ int RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSecu
}else
{
std::list<std::string> peers;
peers.push_back(msg->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers);
return VALIDATE_FAIL_TRY_LATER;
}
@ -836,6 +889,7 @@ int RsGenExchange::validateGrp(RsNxsGrp* grp, RsTlvSecurityKeySet& grpKeySet)
}else
{
std::list<std::string> peers;
peers.push_back(grp->PeerId());
mGixs->requestKey(metaData.mAuthorId, peers);
return VALIDATE_FAIL_TRY_LATER;
}
@ -1364,6 +1418,20 @@ void RsGenExchange::publishGroup(uint32_t& token, RsGxsGrpItem *grpItem)
}
void RsGenExchange::updateGroup(uint32_t& token, RsGxsGroupUpdateMeta& updateMeta, RsGxsGrpItem* grpItem)
{
RsStackMutex stack(mGenMtx);
token = mDataAccess->generatePublicToken();
mGroupUpdatePublish.push_back(GroupUpdatePublish(grpItem, updateMeta, token));
#ifdef GEN_EXCH_DEBUG
std::cerr << "RsGenExchange::updateGroup() token: " << token;
std::cerr << std::endl;
#endif
}
void RsGenExchange::publishMsg(uint32_t& token, RsGxsMsgItem *msgItem)
{
RsStackMutex stack(mGenMtx);
@ -1716,6 +1784,7 @@ void RsGenExchange::publishMsgs()
msg->metaData->mMsgStatus = GXS_SERV::GXS_MSG_STATUS_UNPROCESSED | GXS_SERV::GXS_MSG_STATUS_UNREAD;
msgId = msg->msgId;
grpId = msg->grpId;
msg->metaData->recvTS = time(NULL);
computeHash(msg->msg, msg->metaData->mHash);
mDataAccess->addMsgData(msg);
msgChangeMap[grpId].push_back(msgId);
@ -1780,6 +1849,115 @@ RsGenExchange::ServiceCreate_Return RsGenExchange::service_CreateGroup(RsGxsGrpI
#define PENDING_SIGN_TIMEOUT 10 // 5 seconds
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)));
}
if(grpMeta.empty())
return;
mDataStore->retrieveGxsGrpMetaData(grpMeta);
// now
vit = mGroupUpdatePublish.begin();
for(; vit != mGroupUpdatePublish.end(); vit++)
{
GroupUpdatePublish& gup = *vit;
const RsGxsGroupId& groupId = gup.grpItem->meta.mGroupId;
std::map<std::string, RsGxsGrpMetaData*>::iterator mit = grpMeta.find(groupId);
RsGxsGrpMetaData* meta = NULL;
if(mit == grpMeta.end())
{
std::cerr << "Error! could not find meta of old group to update!" << std::endl;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
delete gup.grpItem;
continue;
}else
{
meta = mit->second;
}
gup.grpItem->meta = *meta;
assignMetaUpdates(gup.grpItem->meta, gup.mUpdateMeta);
GxsGrpPendingSign ggps(gup.grpItem, ggps.mToken);
bool publishAndAdminPrivatePresent = checkKeys(meta->keys);
if(publishAndAdminPrivatePresent)
{
ggps.mPrivateKeys = meta->keys;
generatePublicFromPrivateKeys(ggps.mPrivateKeys, ggps.mPublicKeys);
ggps.mHaveKeys = true;
ggps.mStartTS = time(NULL);
ggps.mLastAttemptTS = 0;
ggps.mIsUpdate = true;
ggps.mToken = gup.mToken;
mGrpsToPublish.push_back(ggps);
}else
{
delete gup.grpItem;
mDataAccess->updatePublicRequestStatus(gup.mToken, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED);
}
delete meta;
}
mGroupUpdatePublish.clear();
}
void RsGenExchange::assignMetaUpdates(RsGroupMetaData& meta, const RsGxsGroupUpdateMeta metaUpdate) const
{
const RsGxsGroupUpdateMeta::GxsMetaUpdate* updates = metaUpdate.getUpdates();
RsGxsGroupUpdateMeta::GxsMetaUpdate::const_iterator mit = updates->begin();
for(; mit != updates->end(); mit++)
{
if(mit->first == RsGxsGroupUpdateMeta::NAME)
meta.mGroupName = mit->second;
}
}
bool RsGenExchange::checkKeys(const RsTlvSecurityKeySet& keySet)
{
typedef std::map<std::string, RsTlvSecurityKey> keyMap;
const keyMap& allKeys = keySet.keys;
keyMap::const_iterator cit = allKeys.begin();
bool adminFound = false, publishFound = false;
for(; cit != allKeys.end(); cit++)
{
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;
}
}
// user must have both private and public parts of publish and admin keys
return adminFound && publishFound;
}
void RsGenExchange::publishGrps()
{
RsStackMutex stack(mGenMtx);
@ -1850,10 +2028,6 @@ void RsGenExchange::publishGrps()
// get group id from private admin key id
grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId;
// what!? this will remove the private keys!
privatekeySet.keys.insert(publicKeySet.keys.begin(),
publicKeySet.keys.end());
ServiceCreate_Return ret = service_CreateGroup(grpItem, privatekeySet);
@ -1901,7 +2075,12 @@ void RsGenExchange::publishGrps()
{
grpId = grp->grpId;
computeHash(grp->grp, grp->metaData->mHash);
mDataAccess->addGroupData(grp);
grp->metaData->mRecvTS = time(NULL);
if(ggps.mIsUpdate)
mDataAccess->updateGroupData(grp);
else
mDataAccess->addGroupData(grp);
}
else
{
@ -2033,6 +2212,8 @@ void RsGenExchange::processRecvdData()
processRecvdGroups();
processRecvdMessages();
performUpdateValidation();
}
@ -2117,6 +2298,7 @@ void RsGenExchange::processRecvdMessages()
if(validated_entry != mMsgPendingValidate.end()) mMsgPendingValidate.erase(validated_entry);
computeHash(msg->msg, meta->mHash);
meta->recvTS = time(NULL);
}
}
else
@ -2188,9 +2370,12 @@ void RsGenExchange::processRecvdGroups()
RsStackMutex stack(mGenMtx);
NxsGrpPendValidVect::iterator vit = mReceivedGrps.begin();
std::vector<std::string> existingGrpIds;
std::list<std::string> grpIds;
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grps;
std::list<RsGxsGroupId> grpIds;
mDataStore->retrieveGroupIds(existingGrpIds);
while( vit != mReceivedGrps.end())
{
@ -2215,13 +2400,24 @@ void RsGenExchange::processRecvdGroups()
meta->mGroupStatus = GXS_SERV::GXS_GRP_STATUS_UNPROCESSED | GXS_SERV::GXS_GRP_STATUS_UNREAD;
meta->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_NOT_SUBSCRIBED;
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
computeHash(grp->grp, meta->mHash);
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
// now check if group already existss
if(std::find(existingGrpIds.begin(), existingGrpIds.end(), grp->grpId) == existingGrpIds.end())
{
meta->mRecvTS = time(NULL);
if(meta->mCircleType == GXS_CIRCLE_TYPE_YOUREYESONLY)
meta->mOriginator = grp->PeerId();
grps.insert(std::make_pair(grp, meta));
grpIds.push_back(grp->grpId);
}
else
{
GroupUpdate update;
update.newGrp = grp;
mGroupUpdates.push_back(update);
}
erase = true;
}
else if(ret == VALIDATE_FAIL)
@ -2273,3 +2469,99 @@ void RsGenExchange::processRecvdGroups()
mDataStore->storeGroup(grps);
}
}
void RsGenExchange::performUpdateValidation()
{
RsStackMutex stack(mGenMtx);
#ifdef GXS_GENX_DEBUG
std::cerr << "RsGenExchange::performUpdateValidation() " << std::endl;
#endif
if(mGroupUpdates.empty())
return;
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));
if(!grpMetas.empty())
mDataStore->retrieveGxsGrpMetaData(grpMetas);
else
return;
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;
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;
}
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;
}

View File

@ -71,13 +71,14 @@ class GxsGrpPendingSign
public:
GxsGrpPendingSign(RsGxsGrpItem* item, uint32_t token): mLastAttemptTS(0), mStartTS(time(NULL)), mToken(token),
mItem(item), mHaveKeys(false)
mItem(item), mHaveKeys(false), mIsUpdate(false)
{}
time_t mLastAttemptTS, mStartTS;
uint32_t mToken;
RsGxsGrpItem* mItem;
bool mHaveKeys; // mKeys->first == true if key present
bool mIsUpdate;
RsTlvSecurityKeySet mPrivateKeys;
RsTlvSecurityKeySet mPublicKeys;
};
@ -516,7 +517,6 @@ protected:
/*!
* Enables publication of a group item \n
* If the item exists already this is simply versioned \n
* This will induce a related change message \n
* Ownership of item passes to this rsgenexchange \n
* @param token
@ -524,6 +524,16 @@ protected:
*/
void publishGroup(uint32_t& token, RsGxsGrpItem* grpItem);
/*!
* Updates an existing group item \n
* This will induce a related change message \n
* Ownership of item passes to this rsgenexchange \n
* @param token
* @param grpItem
*/
void updateGroup(uint32_t& token, RsGxsGroupUpdateMeta& updateMeta, RsGxsGrpItem* grpItem);
public:
/*!
* Enables publication of a message item \n
@ -629,6 +639,8 @@ private:
void publishGrps();
void processGroupUpdatePublish();
void publishMsgs();
/*!
@ -700,11 +712,20 @@ private:
/*!
* Generate a set of keys that can define a GXS group
* @param privatekeySet contains private generated keys
* @param privatekeySet contains public generated keys (counterpart of private)
* @param publickeySet contains public generated keys (counterpart of private)
* @param genPublicKeys should publish key pair also be generated
*/
void generateGroupKeys(RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet, bool genPublishKeys);
/*!
* Generate public set of keys from their private counterparts
* No keys will be generated if one fails
* @param privatekeySet contains private generated keys
* @param publickeySet contains public generated keys (counterpart of private)
* @return false if key gen failed for a key set
*/
void generatePublicFromPrivateKeys(const RsTlvSecurityKeySet& privatekeySet, RsTlvSecurityKeySet& publickeySet);
/*!
* Attempts to validate msg signatures
* @param msg message to be validated
@ -736,6 +757,32 @@ private:
static void computeHash(const RsTlvBinaryData& data, std::string& hash);
/*!
* Checks validation of recently received groups to be
* updated
*/
void performUpdateValidation();
/*!
* Checks if the update is valid (i.e. the new admin signature is by the old admin key)
* @param oldGrp the old group to be updated (must have meta data member initialised)
* @param newGrp the new group that updates the old group (must have meta data member initialised)
* @return
*/
bool updateValid(RsGxsGrpMetaData& oldGrp, RsNxsGrp& newGrp) const;
/*!
* convenience function for checking private publish and admin keys are present
* @param keySet The keys set to split into a private and public set
* @return false, if private admin and publish keys cannot be found, true otherwise
*/
bool checkKeys(const RsTlvSecurityKeySet& keySet);
/*!
* Convenience function for assigning the meta update items to the actual group meta
*/
void assignMetaUpdates(RsGroupMetaData& meta, const RsGxsGroupUpdateMeta metaUpdate) const;
private:
RsMutex mGenMtx;
@ -798,6 +845,13 @@ private:
const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_ATTEMPTS;
const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER;
const uint8_t VALIDATE_FAIL, VALIDATE_SUCCESS, VALIDATE_FAIL_TRY_LATER, VALIDATE_MAX_ATTEMPTS;
private:
std::vector<GroupUpdate> mGroupUpdates, mPeersGroupUpdate;
std::vector<GroupUpdatePublish> mGroupUpdatePublish;
};
#endif // RSGENEXCHANGE_H

View File

@ -176,7 +176,7 @@ class RsGixsReputation
public:
// get Reputation.
virtual bool haveReputation(const RsGxsId &id) = 0;
virtual bool loadReputation(const RsGxsId &id) = 0;
virtual bool loadReputation(const RsGxsId &id, const std::list<std::string>& peers) = 0;
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep) = 0;
};

View File

@ -74,6 +74,7 @@ void RsGxsGrpMetaData::clear(){
mOriginator.clear();
mCircleType = 0;
mAuthenFlags = 0;
mRecvTS = 0;
}
@ -196,6 +197,7 @@ void RsGxsMsgMetaData::clear()
mMsgFlags = 0;
mMsgStatus = 0;
mChildTs = 0;
recvTS = 0;
}
bool RsGxsMsgMetaData::serialise(void *data, uint32_t *size)

View File

@ -70,17 +70,16 @@ public:
uint32_t mPop; // HOW DO WE DO THIS NOW.
uint32_t mMsgCount; // ???
time_t mLastPost; // ???
uint32_t mLastPost; // ???
uint32_t mGroupStatus;
uint32_t mRecvTS;
std::string mOriginator;
std::string mInternalCircle;
std::string mHash;
};
class RsGxsMsgMetaData
{
public:
@ -114,6 +113,7 @@ public:
uint32_t mMsgStatus;
time_t mChildTs;
uint32_t recvTS;
std::string mHash;
bool validated;

View File

@ -1487,7 +1487,14 @@ bool RsGxsDataAccess::addGroupData(RsNxsGrp* grp) {
return mDataStore->storeGroup(grpM);
}
bool RsGxsDataAccess::updateGroupData(RsNxsGrp* grp) {
RsStackMutex stack(mDataMutex);
std::map<RsNxsGrp*, RsGxsGrpMetaData*> grpM;
grpM.insert(std::make_pair(grp, grp->metaData));
return mDataStore->updateGroup(grpM);
}
bool RsGxsDataAccess::addMsgData(RsNxsMsg* msg) {

View File

@ -126,14 +126,21 @@ public:
public:
/*!
* This adds a groups to the gxs data base, this is a blocking call
* Responsibility for grp still lies with callee \n
* This adds a groups to the gxs data base, this is a blocking call \n
* If function returns successfully DataAccess can be queried for grp
* @param grp the group to add, responsibility grp passed lies with callee
* @return false if group cound not be added
*/
bool addGroupData(RsNxsGrp* grp);
/*!
* This updates a groups in the gxs data base, this is a blocking call \n
* If function returns successfully DataAccess can be queried for grp
* @param grp the group to add, responsibility grp passed lies with callee
* @return false if group cound not be added
*/
bool updateGroupData(RsNxsGrp* grp);
/*!
* This adds a group to the gxs data base, this is a blocking call \n
* Responsibility for msg still lies with callee \n

View File

@ -36,16 +36,16 @@
#define GIXS_CUT_OFF 0
#define SYNC_PERIOD 12 // in microseconds every 10 seconds (1 second for testing)
#define TRANSAC_TIMEOUT 5 // 5 seconds
#define TRANSAC_TIMEOUT 10 // 10 seconds
const uint32_t RsGxsNetService::FRAGMENT_SIZE = 150000;
RsGxsNetService::RsGxsNetService(uint16_t servType, RsGeneralDataService *gds,
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs, RsGixsReputation* reputations, RsGcxs* circles)
RsNxsNetMgr *netMgr, RsNxsObserver *nxsObs, RsGixsReputation* reputations, RsGcxs* circles, bool grpAutoSync)
: p3Config(servType), p3ThreadedService(servType),
mTransactionTimeOut(TRANSAC_TIMEOUT), mServType(servType), mDataStore(gds), mTransactionN(0),
mObserver(nxsObs), mNxsMutex("RsGxsNetService"), mNetMgr(netMgr), mSYNC_PERIOD(SYNC_PERIOD),
mSyncTs(0), mReputations(reputations), mCircles(circles)
mSyncTs(0), mReputations(reputations), mCircles(circles), mGrpAutoSync(grpAutoSync), mGrpServerUpdateItem(NULL)
{
addSerialType(new RsNxsSerialiser(mServType));
@ -85,13 +85,27 @@ void RsGxsNetService::syncWithPeers()
std::set<std::string>::iterator sit = peers.begin();
// for now just grps
for(; sit != peers.end(); sit++)
if(mGrpAutoSync)
{
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
grp->clear();
grp->PeerId(*sit);
sendItem(grp);
// for now just grps
for(; sit != peers.end(); sit++)
{
const std::string peerId = *sit;
ClientGrpMap::const_iterator cit = mClientGrpUpdateMap.find(peerId);
uint32_t updateTS = 0;
if(cit != mClientGrpUpdateMap.end())
{
const RsGxsGrpUpdateItem *gui = cit->second;
updateTS = gui->grpUpdateTS;
}
RsNxsSyncGrp *grp = new RsNxsSyncGrp(mServType);
grp->clear();
grp->PeerId(*sit);
grp->updateTS = updateTS;
sendItem(grp);
}
}
#ifdef GXS_ENABLE_SYNC_MSGS
@ -108,7 +122,9 @@ void RsGxsNetService::syncWithPeers()
RsGxsGrpMetaData* meta = mit->second;
if(meta->mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED )
{
grpIds.push_back(mit->first);
}
delete meta;
}
@ -122,13 +138,36 @@ void RsGxsNetService::syncWithPeers()
std::vector<RsGxsGroupId>::iterator vit = grpIds.begin();
// now see if you have an updateTS so optimise whether you need
// to get a new list of peer data
RsGxsMsgUpdateItem* mui = NULL;
ClientMsgMap::const_iterator cit = mClientMsgUpdateMap.find(*sit);
if(cit != mClientMsgUpdateMap.end())
{
mui = cit->second;
}
for(; vit != grpIds.end(); vit++)
{
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType);
msg->clear();
msg->PeerId(*sit);
msg->grpId = *vit;
sendItem(msg);
uint32_t updateTS = 0;
if(mui)
{
std::map<std::string, uint32_t>::const_iterator cit2 = mui->msgUpdateTS.find(*vit);
if(cit2 != mui->msgUpdateTS.end())
{
updateTS = cit2->second;
}
}
RsNxsSyncMsg* msg = new RsNxsSyncMsg(mServType);
msg->clear();
msg->PeerId(*sit);
msg->grpId = *vit;
msg->updateTS = updateTS;
sendItem(msg);
}
}
#endif
@ -524,20 +563,105 @@ void RsGxsNetService::collateMsgFragments(MsgFragments fragments, std::map<RsGxs
fragments.clear();
}
bool RsGxsNetService::loadList(std::list<RsItem*>& load)
class StoreHere
{
return false;
public:
StoreHere(RsGxsNetService::ClientGrpMap& cgm, RsGxsNetService::ClientMsgMap& cmm,
RsGxsNetService::ServerMsgMap& smm,
RsGxsServerGrpUpdateItem*& sgm) : mClientGrpMap(cgm), mClientMsgMap(cmm),
mServerMsgMap(smm), mServerGrpUpdateItem(sgm)
{}
void operator() (RsItem* item)
{
RsGxsMsgUpdateItem* mui;
RsGxsGrpUpdateItem* gui;
RsGxsServerGrpUpdateItem* gsui;
RsGxsServerMsgUpdateItem* msui;
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
mClientMsgMap.insert(std::make_pair(mui->peerId, mui));
else if((gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL)
mClientGrpMap.insert(std::make_pair(gui->peerId, gui));
else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
mServerMsgMap.insert(std::make_pair(msui->grpId, msui));
else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
{
if(mServerGrpUpdateItem == NULL)
{
mServerGrpUpdateItem = gsui;
}
else
{
#ifdef NXS_NET_DEBUG
std::cerr << "Error! More than one server group update item exists!" << std::endl;
#endif
delete gsui;
}
}
else
{
std::cerr << "Type not expected!" << std::endl;
}
}
private:
RsGxsNetService::ClientGrpMap& mClientGrpMap;
RsGxsNetService::ClientMsgMap& mClientMsgMap;
RsGxsNetService::ServerMsgMap& mServerMsgMap;
RsGxsServerGrpUpdateItem*& mServerGrpUpdateItem;
};
bool RsGxsNetService::loadList(std::list<RsItem *> &load)
{
std::for_each(load.begin(), load.end(), StoreHere(mClientGrpUpdateMap, mClientMsgUpdateMap,
mServerMsgUpdateMap, mGrpServerUpdateItem));
return true;
}
#include <algorithm>
template <typename UpdateMap>
struct get_second : public std::unary_function<typename UpdateMap::value_type, RsItem*>
{
RsItem* operator()(const typename UpdateMap::value_type& value) const
{
return value.second;
}
};
bool RsGxsNetService::saveList(bool& cleanup, std::list<RsItem*>& save)
{
return false;
RsStackMutex stack(mNxsMutex);
// hardcore templates
std::transform(mClientGrpUpdateMap.begin(), mClientGrpUpdateMap.end(),
std::back_inserter(save), get_second<ClientGrpMap>());
std::transform(mClientMsgUpdateMap.begin(), mClientMsgUpdateMap.end(),
std::back_inserter(save), get_second<ClientMsgMap>());
std::transform(mServerMsgUpdateMap.begin(), mServerMsgUpdateMap.end(),
std::back_inserter(save), get_second<ServerMsgMap>());
save.push_back(mGrpServerUpdateItem);
cleanup = false;
return true;
}
RsSerialiser *RsGxsNetService::setupSerialiser()
{
return NULL;
RsSerialiser *rss = new RsSerialiser;
rss->addSerialType(new RsGxsUpdateSerialiser(mServType));
return rss;
}
void RsGxsNetService::recvNxsItemQueue(){
@ -749,6 +873,7 @@ void RsGxsNetService::run(){
double timeDelta = 0.2;
int updateCounter = 0;
while(isRunning()){
@ -758,6 +883,14 @@ void RsGxsNetService::run(){
Sleep((int) (timeDelta * 1000));
#endif
if(updateCounter == 3)
{
updateServerSyncTS();
updateCounter = 0;
}
else
updateCounter++;
// process active transactions
processTransactions();
@ -767,13 +900,71 @@ void RsGxsNetService::run(){
// vetting of id and circle info
runVetting();
processExplicitGroupRequests();
}
}
void RsGxsNetService::updateServerSyncTS()
{
RsStackMutex stack(mNxsMutex);
std::map<RsGxsGroupId, RsGxsGrpMetaData*> gxsMap;
// retrieve all grps and update TS
mDataStore->retrieveGxsGrpMetaData(gxsMap);
std::map<RsGxsGroupId, RsGxsGrpMetaData*>::iterator mit = gxsMap.begin();
// as a grp list server also note this is the latest item you have
if(mGrpServerUpdateItem == NULL)
{
mGrpServerUpdateItem = new RsGxsServerGrpUpdateItem(mServType);
}
bool change = false;
for(; mit != gxsMap.end(); mit++)
{
const RsGxsGroupId& grpId = mit->first;
RsGxsGrpMetaData* grpMeta = mit->second;
ServerMsgMap::iterator mapIT = mServerMsgUpdateMap.find(grpId);
RsGxsServerMsgUpdateItem* msui = NULL;
if(mapIT == mServerMsgUpdateMap.end())
{
msui = new RsGxsServerMsgUpdateItem(mServType);
msui->grpId = grpMeta->mGroupId;
mServerMsgUpdateMap.insert(std::make_pair(msui->grpId, msui));
}else
{
msui = mapIT->second;
}
if(grpMeta->mLastPost > msui->msgUpdateTS )
{
change = true;
msui->msgUpdateTS = grpMeta->mLastPost;
}
// this might be very inefficient with time
if(grpMeta->mRecvTS > mGrpServerUpdateItem->grpUpdateTS)
{
mGrpServerUpdateItem->grpUpdateTS = grpMeta->mRecvTS;
change = true;
}
}
// actual change in config settings, then save configuration
if(change)
IndicateConfigChanged();
freeAndClearContainerResource<std::map<RsGxsGroupId, RsGxsGrpMetaData*>,
RsGxsGrpMetaData*>(gxsMap);
}
bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr)
{
//return tr->mTimeOut < ((uint32_t) time(NULL));
return false;
return tr->mTimeOut < ((uint32_t) time(NULL));
}
void RsGxsNetService::processTransactions(){
@ -1036,25 +1227,52 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
// notify listener of grps
mObserver->notifyNewGroups(grps);
// now note this as the latest you've received from this peer
std::string peerFrom = tr->mTransaction->PeerId();
uint32_t updateTS = tr->mTransaction->updateTS;
ClientGrpMap::iterator it = mClientGrpUpdateMap.find(peerFrom);
RsGxsGrpUpdateItem* item = NULL;
if(it != mClientGrpUpdateMap.end())
{
item = it->second;
}else
{
item = new RsGxsGrpUpdateItem(mServType);
mClientGrpUpdateMap.insert(
std::make_pair(peerFrom, item));
}
item->grpUpdateTS = updateTS;
item->peerId = peerFrom;
IndicateConfigChanged();
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
{
std::vector<RsNxsMsg*> msgs;
std::string grpId;
while(tr->mItems.size() > 0)
{
RsNxsMsg* msg = dynamic_cast<RsNxsMsg*>(tr->mItems.front());
if(msg)
{
tr->mItems.pop_front();
msgs.push_back(msg);
if(grpId.empty())
grpId = msg->grpId;
tr->mItems.pop_front();
msgs.push_back(msg);
}
else
{
#ifdef NXS_NET_DEBUG
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg"
<< std::endl;
std::cerr << "RsGxsNetService::processCompletedTransactions(): item did not caste to msg"
<< std::endl;
#endif
}
}
@ -1078,6 +1296,10 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
// notify listener of msgs
mObserver->notifyNewMessages(msgs);
// now note that this is the latest you've received from this peer
// for the grp id
locked_doMsgUpdateWork(tr->mTransaction, grpId);
}
}else if(tr->mFlag == NxsTransaction::FLAG_STATE_FAILED){
// don't do anything transaction will simply be cleaned
@ -1085,6 +1307,33 @@ void RsGxsNetService::locked_processCompletedIncomingTrans(NxsTransaction* tr)
return;
}
void RsGxsNetService::locked_doMsgUpdateWork(const RsNxsTransac *nxsTrans, const std::string &grpId)
{
// firts check if peer exists
const std::string& peerFrom = nxsTrans->PeerId();
ClientMsgMap::iterator it = mClientMsgUpdateMap.find(peerFrom);
RsGxsMsgUpdateItem* mui = NULL;
// now update the peer's entry for this grp id
if(it != mClientMsgUpdateMap.end())
{
mui = it->second;
}
else
{
mui = new RsGxsMsgUpdateItem(mServType);
mClientMsgUpdateMap.insert(std::make_pair(peerFrom, mui));
}
mui->msgUpdateTS[grpId] = nxsTrans->updateTS;
mui->peerId = peerFrom;
IndicateConfigChanged();
}
void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
{
uint16_t flag = tr->mTransaction->transactFlag;
@ -1125,6 +1374,7 @@ void RsGxsNetService::locked_processCompletedOutgoingTrans(NxsTransaction* tr)
std::cerr << "complete Sending Grp Data, transN: " <<
tr->mTransaction->transactionNumber << std::endl;
#endif
}else if(flag & RsNxsTransac::FLAG_TYPE_MSGS)
{
#ifdef NXS_NET_DEBUG
@ -1166,7 +1416,7 @@ void RsGxsNetService::locked_pushMsgTransactionFromList(
newTrans->mTimeOut = time(NULL) + mTransactionTimeOut;
// create transaction copy with your id to indicate
// its an outgoing transaction
newTrans->mTransaction = new RsNxsTransac(*transac);
newTrans->mTransaction = new RsNxsTransac(*transac);
newTrans->mTransaction->PeerId(mOwnId);
sendItem(transac);
{
@ -1248,7 +1498,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
msgIdSet.insert((*vit)->mMsgId);
delete(*vit);
}
msgMetaV.clear();
msgMetaV.clear();
// get unique id for this transaction
uint32_t transN = locked_getTransactionId();
@ -1261,6 +1511,9 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
MsgAuthorV toVet;
std::list<std::string> peers;
peers.push_back(tr->mTransaction->PeerId());
for(; llit != msgItemL.end(); llit++)
{
RsNxsSyncMsgItem*& syncItem = *llit;
@ -1294,7 +1547,7 @@ void RsGxsNetService::locked_genReqMsgTransaction(NxsTransaction* tr)
else
{
// preload for speed
mReputations->loadReputation(syncItem->authorId);
mReputations->loadReputation(syncItem->authorId, peers);
MsgAuthEntry entry;
entry.mAuthorId = syncItem->authorId;
entry.mGrpId = syncItem->grpId;
@ -1375,6 +1628,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
}
std::map<std::string, RsGxsGrpMetaData*> grpMetaMap;
std::map<std::string, RsGxsGrpMetaData*>::const_iterator metaIter;
mDataStore->retrieveGxsGrpMetaData(grpMetaMap);
// now do compare and add loop
@ -1384,13 +1638,20 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
uint32_t transN = locked_getTransactionId();
GrpAuthorV toVet;
std::list<std::string> peers;
peers.push_back(tr->mTransaction->PeerId());
for(; llit != grpItemL.end(); llit++)
{
RsNxsSyncGrpItem*& grpSyncItem = *llit;
const std::string& grpId = grpSyncItem->grpId;
metaIter = grpMetaMap.find(grpId);
bool haveItem = metaIter != grpMetaMap.end();
bool latestVersion = false;
if(grpMetaMap.find(grpId) == grpMetaMap.end()){
latestVersion = grpSyncItem->publishTs > metaIter->second->mPublishTs;
if(!haveItem || (haveItem && latestVersion) ){
// determine if you need to check reputation
bool checkRep = !grpSyncItem->authorId.empty();
@ -1412,7 +1673,7 @@ void RsGxsNetService::locked_genReqGrpTransaction(NxsTransaction* tr)
else
{
// preload reputation for later
mReputations->loadReputation(grpSyncItem->authorId);
mReputations->loadReputation(grpSyncItem->authorId, peers);
GrpAuthEntry entry;
entry.mAuthorId = grpSyncItem->authorId;
entry.mGrpId = grpSyncItem->grpId;
@ -1505,11 +1766,15 @@ void RsGxsNetService::locked_genSendGrpsTransaction(NxsTransaction* tr)
return;
}
uint32_t updateTS = 0;
if(mGrpServerUpdateItem)
updateTS = mGrpServerUpdateItem->grpUpdateTS;
RsNxsTransac* ntr = new RsNxsTransac(mServType);
ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
RsNxsTransac::FLAG_TYPE_GRPS;
ntr->updateTS = updateTS;
ntr->nItems = grps.size();
ntr->PeerId(tr->mTransaction->PeerId());
@ -1625,12 +1890,17 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
return;
}
std::string grpId = "";
for(;lit != tr->mItems.end(); lit++)
{
RsNxsSyncMsgItem* item = dynamic_cast<RsNxsSyncMsgItem*>(*lit);
if (item)
{
msgIds[item->grpId].push_back(item->msgId);
if(grpId.empty())
grpId = item->grpId;
}
else
{
@ -1687,10 +1957,18 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr)
return;
}
uint32_t updateTS = 0;
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(grpId);
if(cit != mServerMsgUpdateMap.end())
updateTS = cit->second->msgUpdateTS;
RsNxsTransac* ntr = new RsNxsTransac(mServType);
ntr->transactionNumber = transN;
ntr->transactFlag = RsNxsTransac::FLAG_BEGIN_P1 |
RsNxsTransac::FLAG_TYPE_MSGS;
ntr->updateTS = updateTS;
ntr->nItems = msgSize;
ntr->PeerId(peerId);
@ -1766,13 +2044,32 @@ void RsGxsNetService::locked_pushGrpRespFromList(std::list<RsNxsItem*>& respList
locked_addTransaction(tr);
}
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncGrp *item)
{
// don't sync if you have no new updates for this peer
if(mGrpServerUpdateItem)
{
if(item->updateTS >= mGrpServerUpdateItem->grpUpdateTS && item->updateTS != 0)
{
return false;
}
}
return true;
}
void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
{
RsStackMutex stack(mNxsMutex);
if(!locked_CanReceiveUpdate(item))
return;
std::string peer = item->PeerId();
std::map<std::string, RsGxsGrpMetaData*> grp;
mDataStore->retrieveGxsGrpMetaData(grp);
@ -1826,6 +2123,8 @@ void RsGxsNetService::handleRecvSyncGroup(RsNxsSyncGrp* item)
return;
}
bool RsGxsNetService::canSendGrpId(const std::string& sslId, RsGxsGrpMetaData& grpMeta, std::vector<GrpIdCircleVet>& toVet)
{
// first do the simple checks
@ -1881,10 +2180,31 @@ bool RsGxsNetService::canSendGrpId(const std::string& sslId, RsGxsGrpMetaData& g
return true;
}
bool RsGxsNetService::locked_CanReceiveUpdate(const RsNxsSyncMsg *item)
{
ServerMsgMap::const_iterator cit = mServerMsgUpdateMap.find(item->grpId);
if(cit != mServerMsgUpdateMap.end())
{
const RsGxsServerMsgUpdateItem *msui = cit->second;
if(item->updateTS >= msui->msgUpdateTS && item->updateTS != 0)
{
#ifdef NXS_NET_DEBUG
std::cerr << "RsGxsNetService::locked_CanReceiveUpdate(): Msgs up to date" << std::endl;
#endif
return false;
}
}
return true;
}
void RsGxsNetService::handleRecvSyncMessage(RsNxsSyncMsg* item)
{
RsStackMutex stack(mNxsMutex);
if(!locked_CanReceiveUpdate(item))
return;
const std::string& peer = item->PeerId();
GxsMsgMetaResult metaResult;
@ -2066,3 +2386,40 @@ void RsGxsNetService::setSyncAge(uint32_t age)
}
int RsGxsNetService::requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId)
{
RsStackMutex stack(mNxsMutex);
mExplicitRequest[peerId].assign(grpId.begin(), grpId.end());
return 1;
}
void RsGxsNetService::processExplicitGroupRequests()
{
RsStackMutex stack(mNxsMutex);
std::map<std::string, std::list<RsGxsGroupId> >::const_iterator cit = mExplicitRequest.begin();
for(; cit != mExplicitRequest.end(); cit++)
{
const std::string& peerId = cit->first;
const std::list<RsGxsGroupId>& groupIdList = cit->second;
std::list<RsNxsItem*> grpSyncItems;
std::list<RsGxsGroupId>::const_iterator git = groupIdList.begin();
uint32_t transN = locked_getTransactionId();
for(; git != groupIdList.end(); git++)
{
RsNxsSyncGrpItem* item = new RsNxsSyncGrpItem(mServType);
item->grpId = *git;
item->PeerId(peerId);
item->flag = RsNxsSyncGrpItem::FLAG_REQUEST;
item->transactionNumber = transN;
grpSyncItems.push_back(item);
}
if(!grpSyncItems.empty())
locked_pushGrpTransactionFromList(grpSyncItems, peerId, transN);
}
mExplicitRequest.clear();
}

View File

@ -34,6 +34,7 @@
#include "rsnxsobserver.h"
#include "pqi/p3linkmgr.h"
#include "serialiser/rsnxsitems.h"
#include "serialiser/rsgxsupdateitems.h"
#include "rsgxsnetutils.h"
#include "pqi/p3cfgmgr.h"
#include "rsgixs.h"
@ -73,7 +74,7 @@ public:
* arrive
*/
RsGxsNetService(uint16_t servType, RsGeneralDataService* gds, RsNxsNetMgr* netMgr,
RsNxsObserver* nxsObs = NULL, RsGixsReputation* repuations = NULL, RsGcxs* circles = NULL);
RsNxsObserver* nxsObs = NULL, RsGixsReputation* repuations = NULL, RsGcxs* circles = NULL, bool grpAutoSync = true);
virtual ~RsGxsNetService();
@ -115,7 +116,7 @@ public:
* @param msgId the messages to retrieve
* @return request token to be redeemed
*/
int requestMsg(const std::string& msgId, uint8_t hops){ return 0;}
int requestMsg(const RsGxsGrpMsgIdPair& msgId){ return 0;}
/*!
* Request for this group is sent through to peers on your network
@ -123,7 +124,7 @@ public:
* @param enabled set to false to disable pause, and true otherwise
* @return request token to be redeemed
*/
int requestGrp(const std::list<std::string>& grpId, uint8_t hops){ return 0;}
int requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId);
/* p3Config methods */
@ -322,6 +323,15 @@ private:
bool locked_canReceive(const RsGxsGrpMetaData * const grpMeta, const std::string& peerId);
void processExplicitGroupRequests();
void locked_doMsgUpdateWork(const RsNxsTransac* nxsTrans, const std::string& grpId);
void updateServerSyncTS();
bool locked_CanReceiveUpdate(const RsNxsSyncGrp* item);
bool locked_CanReceiveUpdate(const RsNxsSyncMsg* item);
private:
typedef std::vector<RsNxsGrp*> GrpFragments;
@ -418,10 +428,30 @@ private:
RsGcxs* mCircles;
RsGixsReputation* mReputations;
bool mGrpAutoSync;
// need to be verfied
std::vector<AuthorPending*> mPendingResp;
std::vector<GrpCircleVetting*> mPendingCircleVets;
std::map<std::string, std::list<RsGxsGroupId> > mExplicitRequest;
// nxs sync optimisation
// can pull dynamically the latest timestamp for each message
public:
typedef std::map<std::string, RsGxsMsgUpdateItem*> ClientMsgMap;
typedef std::map<std::string, RsGxsServerMsgUpdateItem*> ServerMsgMap;
typedef std::map<std::string, RsGxsGrpUpdateItem*> ClientGrpMap;
private:
ClientMsgMap mClientMsgUpdateMap;
ServerMsgMap mServerMsgUpdateMap;
ClientGrpMap mClientGrpUpdateMap;
RsGxsServerGrpUpdateItem* mGrpServerUpdateItem;
};
#endif // RSGXSNETSERVICE_H

View File

@ -47,14 +47,16 @@ bool AuthorPending::expired() const
}
bool AuthorPending::getAuthorRep(GixsReputation& rep,
const std::string& authorId)
const std::string& authorId, const std::string& peerId)
{
if(mRep->haveReputation(authorId))
{
return mRep->getReputation(authorId, rep);
}
mRep->loadReputation(authorId);
std::list<std::string> peers;
peers.push_back(peerId);
mRep->loadReputation(authorId, peers);
return false;
}
@ -94,7 +96,7 @@ bool MsgRespPending::accepted()
if(!entry.mPassedVetting)
{
GixsReputation rep;
if(getAuthorRep(rep, entry.mAuthorId))
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{
if(rep.score > mCutOff)
{
@ -129,7 +131,7 @@ bool GrpRespPending::accepted()
{
GixsReputation rep;
if(getAuthorRep(rep, entry.mAuthorId))
if(getAuthorRep(rep, entry.mAuthorId, mPeerId))
{
if(rep.score > mCutOff)
{

View File

@ -141,7 +141,7 @@ protected:
* @param authorId reputation to get
* @return true if successfully retrieve repution
*/
bool getAuthorRep(GixsReputation& rep, const std::string& authorId);
bool getAuthorRep(GixsReputation& rep, const std::string& authorId, const std::string& peerId);
private:

View File

@ -129,4 +129,24 @@ private:
};
class GroupUpdate
{
public:
GroupUpdate() : oldGrpMeta(NULL), newGrp(NULL), validUpdate(false)
{}
RsGxsGrpMetaData* oldGrpMeta;
RsNxsGrp* newGrp;
bool validUpdate;
};
class GroupUpdatePublish
{
public:
GroupUpdatePublish(RsGxsGrpItem* item, RsGxsGroupUpdateMeta updateMeta, uint32_t token)
: grpItem(item), mToken(token), mUpdateMeta(updateMeta) {}
RsGxsGrpItem* grpItem;
RsGxsGroupUpdateMeta mUpdateMeta;
uint32_t mToken;
};
#endif /* GXSUTIL_H_ */

View File

@ -68,21 +68,6 @@ public:
*/
virtual void setSyncAge(uint32_t age) = 0;
/*!
* Explicitly requests all the groups contained by a peer
* Circumvents polling of peers for message
* @param peerId id of peer
*/
virtual void requestGroupsOfPeer(const std::string& peerId) = 0;
/*!
* get messages of a peer for a given group id, this circumvents the normal
* polling of peers for messages of given group id
* @param peerId Id of peer
* @param grpId id of group to request messages for
*/
virtual void requestMessagesOfPeer(const std::string& peerId, const std::string& grpId) = 0;
/*!
* Initiates a search through the network
* This returns messages which contains the search terms set in RsGxsSearch
@ -116,7 +101,7 @@ public:
* @param msgId the messages to retrieve
* @return request token to be redeemed
*/
virtual int requestMsg(const std::string& msgId, uint8_t hops) = 0;
virtual int requestMsg(const RsGxsGrpMsgIdPair& msgId) = 0;
/*!
* Request for this group is sent through to peers on your network
@ -124,7 +109,7 @@ public:
* @param enabled set to false to disable pause, and true otherwise
* @return request token to be redeemed
*/
virtual int requestGrp(const std::list<std::string>& grpId, uint8_t hops) = 0;
virtual int requestGrp(const std::list<RsGxsGroupId>& grpId, const std::string& peerId) = 0;
};

View File

@ -390,6 +390,9 @@ HEADERS += serialiser/rsbaseserial.h \
serialiser/rsdiscovery2items.h \
serialiser/rsheartbeatitems.h \
serialiser/rsrttitems.h \
serialiser/rsgxsrecognitems.h \
serialiser/rstunnelitems.h \
serialiser/rsgxsupdateitems.h
HEADERS += services/p3chatservice.h \
services/p3msgservice.h \
@ -425,6 +428,7 @@ HEADERS += util/folderiterator.h \
util/pugiconfig.h \
util/rsmemcache.h \
util/rstickevent.h \
util/rsrecogn.h \
SOURCES += dbase/cachestrapper.cc \
dbase/fimonitor.cc \
@ -522,6 +526,9 @@ SOURCES += serialiser/rsbaseserial.cc \
serialiser/rsdiscovery2items.cc \
serialiser/rsheartbeatitems.cc \
serialiser/rsrttitems.cc \
serialiser/rsgxsrecognitems.cc \
serialiser/rstunnelitems.cc \
serialiser/rsgxsupdateitems.cc
SOURCES += services/p3chatservice.cc \
services/p3msgservice.cc \
@ -559,6 +566,7 @@ SOURCES += util/folderiterator.cc \
util/rsaes.cc \
util/rsrandom.cc \
util/rstickevent.cc \
util/rsrecogn.cc \
upnp_miniupnpc {

View File

@ -84,6 +84,14 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0;
/*!
* To update forum group with new information
* @param token the token used to check completion status of update
* @param group group to be updated, groupId element must be set or will be rejected
* @return false groupId not set, true if set and accepted (still check token for completion)
*/
virtual bool updateGroup(uint32_t &token, RsGxsGroupUpdateMeta&, RsGxsForumGroup &group) = 0;
};

View File

@ -46,8 +46,9 @@ public:
mGroupStatus = 0;
mCircleType = 0;
mAuthenFlags = 0;
//mPublishTs = 0;
mPublishTs = 0;
}
void operator =(const RsGxsGrpMetaData& rGxsMeta);
@ -128,7 +129,6 @@ public:
class GxsGroupStatistic
{
public:
/// number of message
RsGxsGroupId mGrpId;
uint32_t mNumMsgs;
@ -147,4 +147,56 @@ public:
uint32_t mSizeStore;
};
class UpdateItem
{
public:
virtual ~UpdateItem() { }
};
class StringUpdateItem : public UpdateItem
{
public:
StringUpdateItem(const std::string update) : mUpdate(update) {}
const std::string& getUpdate() const { return mUpdate; }
private:
std::string mUpdate;
};
class RsGxsGroupUpdateMeta
{
public:
// expand as support is added for other utypes
enum UpdateType { DESCRIPTION, NAME };
RsGxsGroupUpdateMeta(const std::string& groupId) : mGroupId(groupId) {}
typedef std::map<UpdateType, std::string> GxsMetaUpdate;
/*!
* Only one item of a utype can exist
* @param utype the type of meta update
* @param item update item containing the change value
*/
void setMetaUpdate(UpdateType utype, const std::string& update)
{
mUpdates[utype] = update;
}
/*!
* @param utype update type to remove
* @return false if update did not exist, true if update successfully removed
*/
bool removeUpdateType(UpdateType utype){ return mUpdates.erase(utype) == 1; }
const GxsMetaUpdate* getUpdates() const { return &mUpdates; }
const std::string& getGroupId() const { return mGroupId; }
private:
GxsMetaUpdate mUpdates;
std::string mGroupId;
};
#endif /* RSGXSIFACETYPES_H_ */

View File

@ -55,6 +55,8 @@ extern RsIdentity *rsIdentity;
#define RSID_RELATION_OTHER 0x0008
#define RSID_RELATION_UNKNOWN 0x0010
#define RSRECOGN_MAX_TAGINFO 5
std::string rsIdTypeToString(uint32_t idtype);
class RsGxsIdGroup
@ -82,6 +84,9 @@ class RsGxsIdGroup
std::string mPgpIdHash;
std::string mPgpIdSign; // Need a signature as proof - otherwise anyone could add others Hashes.
// Recognition Strings. MAX# defined above.
std::list<std::string> mRecognTags;
// Not Serialised - for GUI's benefit.
bool mPgpKnown;
std::string mPgpId;
@ -163,6 +168,36 @@ class RsIdOpinion
typedef std::string RsGxsId; // TMP. =>
class RsRecognTag
{
public:
RsRecognTag(uint16_t tc, uint16_t tt, bool v)
:tag_class(tc), tag_type(tt), valid(v) { return; }
uint16_t tag_class;
uint16_t tag_type;
bool valid;
};
class RsRecognTagDetails
{
public:
RsRecognTagDetails()
:valid_from(0), valid_to(0), tag_class(0), tag_type(0),
is_valid(false), is_pending(false) { return; }
time_t valid_from;
time_t valid_to;
uint16_t tag_class;
uint16_t tag_type;
std::string signer;
bool is_valid;
bool is_pending;
};
class RsIdentityDetails
{
public:
@ -181,6 +216,9 @@ class RsIdentityDetails
bool mPgpKnown;
std::string mPgpId;
// Recogn details.
std::list<RsRecognTag> mRecognTags;
// reputation details.
double mOpinion;
double mReputation;
@ -230,6 +268,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds) = 0;
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion) = 0;
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params) = 0;
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group) = 0;
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
const std::string &tag, RsRecognTagDetails &details) = 0;
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag) = 0;
// Specific RsIdentity Functions....
/* Specific Service Data */
/* We expose these initially for testing / GUI purposes.

View File

@ -2282,7 +2282,7 @@ int RsServer::StartupRetroShare()
std::string currGxsDir = RsInitConfig::configDir + "/GXS_phase2";
#ifdef GXS_DEV_TESTNET // Different Directory for testing.
currGxsDir += "_TESTNET5";
currGxsDir += "_TESTNET6";
#endif
bool cleanUpGxsDir = false;
@ -2323,8 +2323,10 @@ int RsServer::StartupRetroShare()
// create GXS photo service
RsGxsNetService* gxsid_ns = new RsGxsNetService(
RS_SERVICE_GXSV2_TYPE_GXSID, gxsid_ds, nxsMgr,
mGxsIdService, mGxsIdService, mGxsCircles);
mGxsIdService, mGxsIdService, mGxsCircles,
false); // don't synchronise group automatic (need explicit group request)
mGxsIdService->setNes(gxsid_ns);
/**** GxsCircle service ****/
@ -2543,6 +2545,19 @@ int RsServer::StartupRetroShare()
mConfigMgr->addConfiguration("bitdht.cfg", mBitDht);
#endif
#ifdef RS_ENABLE_GXS
mConfigMgr->addConfiguration("identity.cfg", gxsid_ns);
mConfigMgr->addConfiguration("gxsforums.cfg", gxsforums_ns);
mConfigMgr->addConfiguration("gxschannels.cfg", gxschannels_ns);
mConfigMgr->addConfiguration("gxscircles.cfg", gxscircles_ns);
mConfigMgr->addConfiguration("posted.cfg", posted_ns);
mConfigMgr->addConfiguration("wire.cfg", wire_ns);
mConfigMgr->addConfiguration("wiki.cfg", wiki_ns);
mConfigMgr->addConfiguration("photo.cfg", photo_ns);
#endif
mPluginsManager->addConfigurations(mConfigMgr) ;
ftserver->addConfiguration(mConfigMgr);
@ -2683,7 +2698,6 @@ int RsServer::StartupRetroShare()
createThread(*gxsforums_ns);
createThread(*gxschannels_ns);
#endif // RS_ENABLE_GXS
ftserver->StartupThreads();

View File

@ -122,20 +122,30 @@ void RsGxsIdGroupItem::clear()
group.mPgpIdHash.clear();
group.mPgpIdSign.clear();
group.mRecognTags.clear();
group.mPgpKnown = false;
group.mPgpId.clear();
}
std::ostream& RsGxsIdGroupItem::print(std::ostream& out, uint16_t indent)
{
printRsItemBase(out, "RsGxsIdGroupItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "MetaData: " << meta << std::endl;
printIndent(out, int_Indent);
out << "PgpIdHash: " << group.mPgpIdHash << std::endl;
printIndent(out, int_Indent);
out << "PgpIdSign: " << group.mPgpIdSign << std::endl;
printIndent(out, int_Indent);
out << "RecognTags:" << std::endl;
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, group.mRecognTags);
set.print(out, int_Indent + 2);
printRsItemEnd(out ,"RsGxsIdGroupItem", indent);
return out;
@ -151,6 +161,9 @@ uint32_t RsGxsIdSerialiser::sizeGxsIdGroupItem(RsGxsIdGroupItem *item)
s += GetTlvStringSize(group.mPgpIdHash);
s += GetTlvStringSize(group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
s += set.TlvSize();
return s;
}
@ -181,6 +194,9 @@ bool RsGxsIdSerialiser::serialiseGxsIdGroupItem(RsGxsIdGroupItem *item, void *da
/* GxsIdGroupItem */
ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdHash);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
ok &= set.SetTlv(data, tlvsize, &offset);
if(offset != tlvsize)
{
@ -238,6 +254,10 @@ RsGxsIdGroupItem* RsGxsIdSerialiser::deserialiseGxsIdGroupItem(void *data, uint3
ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdHash);
ok &= GetTlvString(data, rssize, &offset, 1, item->group.mPgpIdSign);
RsTlvStringSetRef set(TLV_TYPE_RECOGNSET, item->group.mRecognTags);
ok &= set.GetTlv(data, rssize, &offset);
if (offset != rssize)
{

View File

@ -52,7 +52,8 @@
std::ostream &operator<<(std::ostream &out, const RsGroupMetaData &meta)
{
out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName << " ]";
out << "[ GroupId: " << meta.mGroupId << " Name: " << meta.mGroupName;
out << " PublishTs: " << meta.mPublishTs << " ]";
return out;
}

View File

@ -0,0 +1,600 @@
/*
* libretroshare/src/serialiser: rsgxsrecogitems.cc
*
* RetroShare Serialiser.
*
* Copyright 2013-2013 by 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.1 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".
*
*/
#include "serialiser/rsbaseserial.h"
#include "serialiser/rsgxsrecognitems.h"
/***
#define RSSERIAL_DEBUG 1
***/
#include <iostream>
/*************************************************************************/
RsGxsRecognReqItem::~RsGxsRecognReqItem()
{
return;
}
void RsGxsRecognReqItem::clear()
{
issued_at = 0;
period = 0;
tag_class = 0;
tag_type = 0;
identity.clear();
nickname.clear();
comment.clear();
sign.TlvClear();
}
std::ostream &RsGxsRecognReqItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognReqItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "issued_at: " << issued_at << std::endl;
printIndent(out, int_Indent);
out << "period: " << period << std::endl;
printIndent(out, int_Indent);
out << "tag_class: " << tag_class << std::endl;
printIndent(out, int_Indent);
out << "tag_type: " << tag_type << std::endl;
printIndent(out, int_Indent);
out << "identity: " << identity << std::endl;
printIndent(out, int_Indent);
out << "nickname: " << nickname << std::endl;
printIndent(out, int_Indent);
out << "comment: " << comment << std::endl;
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognReqItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeReq(RsGxsRecognReqItem *item)
{
uint32_t s = 8; /* header */
s += 4; // issued_at;
s += 4; // period;
s += 2; // tag_class;
s += 2; // tag_type;
s += GetTlvStringSize(item->identity);
s += GetTlvStringSize(item->nickname);
s += GetTlvStringSize(item->comment);
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseReq(RsGxsRecognReqItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeReq(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->issued_at);
ok &= setRawUInt32(data, tlvsize, &offset, item->period);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_class);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_type);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->comment);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseReq() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognReqItem *RsGxsRecognSerialiser::deserialiseReq(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_REQ != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognReqItem *item = new RsGxsRecognReqItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= getRawUInt32(data, tlvsize, &offset, &(item->issued_at));
ok &= getRawUInt32(data, tlvsize, &offset, &(item->period));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_class));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_type));
ok &= GetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->comment);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsGxsRecognTagItem::~RsGxsRecognTagItem()
{
return;
}
void RsGxsRecognTagItem::clear()
{
valid_from = 0;
valid_to = 0;
tag_class = 0;
tag_type = 0;
identity.clear();
nickname.clear();
sign.TlvClear();
}
std::ostream &RsGxsRecognTagItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognTagItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "valid_from: " << valid_from << std::endl;
printIndent(out, int_Indent);
out << "valid_to: " << valid_to << std::endl;
printIndent(out, int_Indent);
out << "tag_class: " << tag_class << std::endl;
printIndent(out, int_Indent);
out << "tag_type: " << tag_type << std::endl;
printIndent(out, int_Indent);
out << "identity: " << identity << std::endl;
printIndent(out, int_Indent);
out << "nickname: " << nickname << std::endl;
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognTagItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeTag(RsGxsRecognTagItem *item)
{
uint32_t s = 8; /* header */
s += 4; // valid_from;
s += 4; // valid_to;
s += 2; // tag_class;
s += 2; // tag_type;
s += GetTlvStringSize(item->identity);
s += GetTlvStringSize(item->nickname);
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseTag(RsGxsRecognTagItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeTag(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= setRawUInt32(data, tlvsize, &offset, item->valid_from);
ok &= setRawUInt32(data, tlvsize, &offset, item->valid_to);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_class);
ok &= setRawUInt16(data, tlvsize, &offset, item->tag_type);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= SetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseTag() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognTagItem *RsGxsRecognSerialiser::deserialiseTag(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_TAG != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognTagItem *item = new RsGxsRecognTagItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= getRawUInt32(data, tlvsize, &offset, &(item->valid_from));
ok &= getRawUInt32(data, tlvsize, &offset, &(item->valid_to));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_class));
ok &= getRawUInt16(data, tlvsize, &offset, &(item->tag_type));
ok &= GetTlvString(data, tlvsize, &offset, 1, item->identity);
ok &= GetTlvString(data, tlvsize, &offset, 1, item->nickname);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
RsGxsRecognSignerItem::~RsGxsRecognSignerItem()
{
return;
}
void RsGxsRecognSignerItem::clear()
{
signing_classes.TlvClear();
key.TlvClear();
sign.TlvClear();
}
std::ostream &RsGxsRecognSignerItem::print(std::ostream &out, uint16_t indent)
{
printRsItemBase(out, "RsGxsRecognSignerItem", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "signing_classes: " << std::endl;
signing_classes.print(out, int_Indent + 2);
printIndent(out, int_Indent);
out << "key: " << std::endl;
key.print(out, int_Indent + 2);
printIndent(out, int_Indent);
out << "signature: " << std::endl;
sign.print(out, int_Indent + 2);
printRsItemEnd(out, "RsGxsRecognSignerItem", indent);
return out;
}
uint32_t RsGxsRecognSerialiser::sizeSigner(RsGxsRecognSignerItem *item)
{
uint32_t s = 8; /* header */
s += item->signing_classes.TlvSize();
s += item->key.TlvSize();
s += item->sign.TlvSize();
return s;
}
/* serialise the data to the buffer */
bool RsGxsRecognSerialiser::serialiseSigner(RsGxsRecognSignerItem *item, void *data, uint32_t *pktsize)
{
uint32_t tlvsize = sizeSigner(item);
uint32_t offset = 0;
if (*pktsize < tlvsize)
return false; /* not enough space */
*pktsize = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Header: " << ok << std::endl;
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Size: " << tlvsize << std::endl;
#endif
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->signing_classes.SetTlv(data, tlvsize, &offset);
ok &= item->key.SetTlv(data, tlvsize, &offset);
ok &= item->sign.SetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
ok = false;
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsRecognSerialiser::serialiseSigner() Size Error! " << std::endl;
#endif
}
return ok;
}
RsGxsRecognSignerItem *RsGxsRecognSerialiser::deserialiseSigner(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t tlvsize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_RECOGN_SIGNER != getRsItemSubType(rstype)))
{
return NULL; /* wrong type */
}
if (*pktsize < tlvsize) /* check size */
return NULL; /* not enough data */
/* set the packet length */
*pktsize = tlvsize;
bool ok = true;
/* ready to load */
RsGxsRecognSignerItem *item = new RsGxsRecognSignerItem();
item->clear();
/* skip the header */
offset += 8;
/* add mandatory parts first */
ok &= item->signing_classes.GetTlv(data, tlvsize, &offset);
ok &= item->key.GetTlv(data, tlvsize, &offset);
ok &= item->sign.GetTlv(data, tlvsize, &offset);
if (offset != tlvsize)
{
/* error */
delete item;
return NULL;
}
if (!ok)
{
delete item;
return NULL;
}
return item;
}
/*************************************************************************/
uint32_t RsGxsRecognSerialiser::size(RsItem *i)
{
RsGxsRecognReqItem *rqi;
RsGxsRecognTagItem *rti;
RsGxsRecognSignerItem *rsi;
if (NULL != (rqi = dynamic_cast<RsGxsRecognReqItem *>(i)))
{
return sizeReq(rqi);
}
if (NULL != (rti = dynamic_cast<RsGxsRecognTagItem *>(i)))
{
return sizeTag(rti);
}
if (NULL != (rsi = dynamic_cast<RsGxsRecognSignerItem *>(i)))
{
return sizeSigner(rsi);
}
return 0;
}
bool RsGxsRecognSerialiser::serialise(RsItem *i, void *data, uint32_t *pktsize)
{
RsGxsRecognReqItem *rri;
RsGxsRecognTagItem *rti;
RsGxsRecognSignerItem *rsi;
if (NULL != (rri = dynamic_cast<RsGxsRecognReqItem *>(i)))
{
return serialiseReq(rri, data, pktsize);
}
if (NULL != (rti = dynamic_cast<RsGxsRecognTagItem *>(i)))
{
return serialiseTag(rti, data, pktsize);
}
if (NULL != (rsi = dynamic_cast<RsGxsRecognSignerItem *>(i)))
{
return serialiseSigner(rsi, data, pktsize);
}
return false;
}
RsItem *RsGxsRecognSerialiser::deserialise(void *data, uint32_t *pktsize)
{
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(RS_SERVICE_TYPE_GXS_RECOGN != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_RECOGN_REQ:
return deserialiseReq(data, pktsize);
break;
case RS_PKT_SUBTYPE_RECOGN_TAG:
return deserialiseTag(data, pktsize);
break;
case RS_PKT_SUBTYPE_RECOGN_SIGNER:
return deserialiseSigner(data, pktsize);
break;
default:
return NULL;
break;
}
}
/*************************************************************************/

View File

@ -0,0 +1,152 @@
#ifndef RS_GXS_RECOG_ITEMS_H
#define RS_GXS_RECOG_ITEMS_H
/*
* libretroshare/src/serialiser: rsgxsrecogitems.h
*
* RetroShare Serialiser.
*
* Copyright 2013-2013 by 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.1 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".
*
*/
#include <map>
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvkeys.h"
/**************************************************************************/
#define RS_PKT_SUBTYPE_RECOGN_REQ 0x01
#define RS_PKT_SUBTYPE_RECOGN_TAG 0x02
#define RS_PKT_SUBTYPE_RECOGN_SIGNER 0x03
class RsGxsRecognReqItem: public RsItem
{
public:
RsGxsRecognReqItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_REQ)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognReqItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t issued_at;
uint32_t period;
uint16_t tag_class;
uint16_t tag_type;
std::string identity;
std::string nickname;
std::string comment;
RsTlvKeySignature sign;
};
class RsGxsRecognTagItem: public RsItem
{
public:
RsGxsRecognTagItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_TAG)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognTagItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
uint32_t valid_from;
uint32_t valid_to;
uint16_t tag_class;
uint16_t tag_type;
std::string identity;
std::string nickname;
RsTlvKeySignature sign;
};
class RsGxsRecognSignerItem: public RsItem
{
public:
RsGxsRecognSignerItem()
:RsItem(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN,
RS_PKT_SUBTYPE_RECOGN_SIGNER)
{
setPriorityLevel(QOS_PRIORITY_DEFAULT);
return;
}
virtual ~RsGxsRecognSignerItem();
virtual void clear();
std::ostream &print(std::ostream &out, uint16_t indent = 0);
RsTlvServiceIdSet signing_classes;
RsTlvSecurityKey key; // has from->to, and flags.
RsTlvKeySignature sign;
};
class RsGxsRecognSerialiser: public RsSerialType
{
public:
RsGxsRecognSerialiser()
:RsSerialType(RS_PKT_VERSION_SERVICE, RS_SERVICE_TYPE_GXS_RECOGN)
{ return; }
virtual ~RsGxsRecognSerialiser()
{ return; }
virtual uint32_t size(RsItem *);
virtual bool serialise (RsItem *item, void *data, uint32_t *size);
virtual RsItem * deserialise(void *data, uint32_t *size);
private:
virtual uint32_t sizeReq(RsGxsRecognReqItem *);
virtual bool serialiseReq(RsGxsRecognReqItem *item, void *data, uint32_t *size);
virtual RsGxsRecognReqItem *deserialiseReq(void *data, uint32_t *size);
virtual uint32_t sizeTag(RsGxsRecognTagItem *);
virtual bool serialiseTag(RsGxsRecognTagItem *item, void *data, uint32_t *size);
virtual RsGxsRecognTagItem *deserialiseTag(void *data, uint32_t *size);
virtual uint32_t sizeSigner(RsGxsRecognSignerItem *);
virtual bool serialiseSigner(RsGxsRecognSignerItem *item, void *data, uint32_t *size);
virtual RsGxsRecognSignerItem *deserialiseSigner(void *data, uint32_t *size);
};
/**************************************************************************/
#endif /* RS_GXS_RECOGN_ITEMS_H */

View File

@ -0,0 +1,704 @@
/*
* libretroshare/src/serialiser: rsgxsupdateitems.h
*
* RetroShare Serialiser.
*
* Copyright 2012 Christopher Evi-Parker
*
* 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".
*
*/
#include "rsgxsupdateitems.h"
#include "rsbaseserial.h"
void RsGxsGrpUpdateItem::clear()
{
grpUpdateTS = 0;
peerId.clear();
}
std::ostream& RsGxsGrpUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
void RsGxsMsgUpdateItem::clear()
{
msgUpdateTS.clear();
peerId.clear();
}
std::ostream& RsGxsMsgUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
void RsGxsServerMsgUpdateItem::clear()
{
msgUpdateTS = 0;
grpId.clear();
}
std::ostream& RsGxsServerMsgUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
void RsGxsServerGrpUpdateItem::clear()
{
grpUpdateTS = 0;
}
std::ostream& RsGxsServerGrpUpdateItem::print(std::ostream& out, uint16_t indent)
{
}
uint32_t RsGxsUpdateSerialiser::size(RsItem* item)
{
RsGxsMsgUpdateItem* mui = NULL;
RsGxsGrpUpdateItem* gui = NULL;
RsGxsServerGrpUpdateItem* gsui = NULL;
RsGxsServerMsgUpdateItem* msui = NULL;
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
{
return sizeGxsMsgUpdate(mui);
}else if(( gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL){
return sizeGxsGrpUpdate(gui);
}else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
{
return sizeGxsServerGrpUpdate(gsui);
}else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
{
return sizeGxsServerMsgUpdate(msui);
}else
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::size(): Could not find appropriate size function"
<< std::endl;
#endif
return 0;
}
}
bool RsGxsUpdateSerialiser::serialise(RsItem* item, void* data,
uint32_t* size)
{
RsGxsMsgUpdateItem* mui;
RsGxsGrpUpdateItem* gui;
RsGxsServerGrpUpdateItem* gsui;
RsGxsServerMsgUpdateItem* msui;
if((mui = dynamic_cast<RsGxsMsgUpdateItem*>(item)) != NULL)
return serialiseGxsMsgUpdate(mui, data, size);
else if((gui = dynamic_cast<RsGxsGrpUpdateItem*>(item)) != NULL)
return serialiseGxsGrpUpdate(gui, data, size);
else if((msui = dynamic_cast<RsGxsServerMsgUpdateItem*>(item)) != NULL)
return serialiseGxsServerMsgUpdate(msui, data, size);
else if((gsui = dynamic_cast<RsGxsServerGrpUpdateItem*>(item)) != NULL)
return serialiseGxsServerGrpUpdate(gsui, data, size);
else
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialise() item does not caste to known type"
<< std::endl;
#endif
return false;
}
}
RsItem* RsGxsUpdateSerialiser::deserialise(void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialise()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)))
{
return NULL; /* wrong type */
}
switch(getRsItemSubType(rstype))
{
case RS_PKT_SUBTYPE_GXS_MSG_UPDATE:
return deserialGxsMsgUpdate(data, size);
case RS_PKT_SUBTYPE_GXS_GRP_UPDATE:
return deserialGxsGrpUpddate(data, size);
case RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE:
return deserialGxsServerGrpUpddate(data, size);
case RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE:
return deserialGxsServerMsgUpdate(data, size);
default:
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialise() : data has no type"
<< std::endl;
#endif
return NULL;
}
}
}
uint32_t RsGxsUpdateSerialiser::sizeGxsGrpUpdate(RsGxsGrpUpdateItem* item)
{
uint32_t s = 8; // header size
s += GetTlvStringSize(item->peerId);
s += 4;
return s;
}
uint32_t RsGxsUpdateSerialiser::sizeGxsServerGrpUpdate(RsGxsServerGrpUpdateItem* item)
{
uint32_t s = 8; // header size
s += 4; // time stamp
return s;
}
bool RsGxsUpdateSerialiser::serialiseGxsGrpUpdate(RsGxsGrpUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsGrpUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsGxsGrpUpdateItem */
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
ok &= setRawUInt32(data, *size, &offset, item->grpUpdateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsGrpUpdate() NOK" << std::endl;
}
#endif
return ok;
}
bool RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate(RsGxsServerGrpUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsServerGrpUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsGxsServerGrpUpdateItem */
ok &= setRawUInt32(data, *size, &offset, item->grpUpdateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerGrpUpdate() NOK" << std::endl;
}
#endif
return ok;
}
RsGxsGrpUpdateItem* RsGxsUpdateSerialiser::deserialGxsGrpUpddate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_GRP_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsGrpUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsGrpUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsGrpUpdateItem* item = new RsGxsGrpUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
ok &= getRawUInt32(data, *size, &offset, &(item->grpUpdateTS));
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxxGrpUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsGrpUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
RsGxsServerGrpUpdateItem* RsGxsUpdateSerialiser::deserialGxsServerGrpUpddate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsServerGrpUpdateItem* item = new RsGxsServerGrpUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= getRawUInt32(data, *size, &offset, &(item->grpUpdateTS));
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerGrpUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
uint32_t RsGxsUpdateSerialiser::sizeGxsMsgUpdate(RsGxsMsgUpdateItem* item)
{
uint32_t s = 8; // header size
s += GetTlvStringSize(item->peerId);
const std::map<std::string, uint32_t>& msgUpdateTS = item->msgUpdateTS;
std::map<std::string, uint32_t>::const_iterator cit = msgUpdateTS.begin();
for(; cit != msgUpdateTS.end(); cit++)
{
s += GetTlvStringSize(cit->first);
s += 4;
}
s += 4; // number of map items
return s;
}
uint32_t RsGxsUpdateSerialiser::sizeGxsServerMsgUpdate(RsGxsServerMsgUpdateItem* item)
{
uint32_t s = 8; // header size
s += GetTlvStringSize(item->grpId);
s += 4; // grp TS
return s;
}
bool RsGxsUpdateSerialiser::serialiseGxsMsgUpdate(RsGxsMsgUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsMsgUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsGxsMsgUpdateItem */
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
const std::map<std::string, uint32_t>& msgUpdateTS = item->msgUpdateTS;
std::map<std::string, uint32_t>::const_iterator cit = msgUpdateTS.begin();
uint32_t numItems = msgUpdateTS.size();
ok &= setRawUInt32(data, *size, &offset, numItems);
for(; cit != msgUpdateTS.end(); cit++)
{
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, cit->first);
ok &= setRawUInt32(data, *size, &offset, cit->second);
}
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsMsgUpdate() NOK" << std::endl;
}
#endif
return ok;
}
bool RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate(RsGxsServerMsgUpdateItem* item,
void* data, uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate()" << std::endl;
#endif
uint32_t tlvsize = sizeGxsServerMsgUpdate(item);
uint32_t offset = 0;
if(*size < tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate() size do not match" << std::endl;
#endif
return false;
}
*size = tlvsize;
bool ok = true;
ok &= setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize);
/* skip the header */
offset += 8;
/* RsNxsSyncm */
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= setRawUInt32(data, *size, &offset, item->msgUpdateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate() FAIL Size Error! " << std::endl;
#endif
ok = false;
}
#ifdef RSSERIAL_DEBUG
if (!ok)
{
std::cerr << "RsGxsUpdateSerialiser::serialiseGxsServerMsgUpdate() NOK" << std::endl;
}
#endif
return ok;
}
RsGxsMsgUpdateItem* RsGxsUpdateSerialiser::deserialGxsMsgUpdate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_MSG_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsMsgUpdateItem* item = new RsGxsMsgUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_PEERID, item->peerId);
uint32_t numUpdateItems;
ok &= getRawUInt32(data, *size, &offset, &(numUpdateItems));
std::map<std::string, uint32_t>& msgUpdateItem = item->msgUpdateTS;
std::string grpId;
uint32_t updateTS;
for(uint32_t i = 0; i < numUpdateItems; i++)
{
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, grpId);
if(!ok)
break;
ok &= getRawUInt32(data, *size, &offset, &(updateTS));
if(!ok)
break;
msgUpdateItem.insert(std::make_pair(grpId, updateTS));
}
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsMsgUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}
RsGxsServerMsgUpdateItem* RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate(void* data,
uint32_t* size)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate()" << std::endl;
#endif
/* get the type and size */
uint32_t rstype = getRsItemId(data);
uint32_t rssize = getRsItemSize(data);
uint32_t offset = 0;
if ((RS_PKT_VERSION_SERVICE != getRsItemVersion(rstype)) ||
(SERVICE_TYPE != getRsItemService(rstype)) ||
(RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE != getRsItemSubType(rstype)))
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() FAIL wrong type" << std::endl;
#endif
return NULL; /* wrong type */
}
if (*size < rssize) /* check size */
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() FAIL wrong size" << std::endl;
#endif
return NULL; /* not enough data */
}
/* set the packet length */
*size = rssize;
bool ok = true;
RsGxsServerMsgUpdateItem* item = new RsGxsServerMsgUpdateItem(getRsItemService(rstype));
/* skip the header */
offset += 8;
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= getRawUInt32(data, *size, &offset, &(item->msgUpdateTS));
if (offset != rssize)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() FAIL size mismatch" << std::endl;
#endif
/* error */
delete item;
return NULL;
}
if (!ok)
{
#ifdef RSSERIAL_DEBUG
std::cerr << "RsGxsUpdateSerialiser::deserialGxsServerMsgUpdate() NOK" << std::endl;
#endif
delete item;
return NULL;
}
return item;
}

View File

@ -0,0 +1,149 @@
#ifndef RSGXSUPDATEITEMS_H_
#define RSGXSUPDATEITEMS_H_
/*
* libretroshare/src/serialiser: rsgxsupdateitems.h
*
* RetroShare Serialiser.
*
* Copyright 2012 Christopher Evi-Parker
*
* 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".
*
*/
#include <map>
#include "serialiser/rsserviceids.h"
#include "serialiser/rsserial.h"
#include "serialiser/rstlvbase.h"
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvkeys.h"
#include "gxs/rsgxsdata.h"
const uint8_t RS_PKT_SUBTYPE_GXS_GRP_UPDATE = 0x0001;
const uint8_t RS_PKT_SUBTYPE_GXS_MSG_UPDATE = 0x0002;
const uint8_t RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE = 0x0004;
const uint8_t RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE = 0x0008;
class RsGxsGrpUpdateItem : public RsItem {
public:
RsGxsGrpUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE, servType,
RS_PKT_SUBTYPE_GXS_GRP_UPDATE)
{clear();}
virtual ~RsGxsGrpUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::string peerId;
uint32_t grpUpdateTS;
};
class RsGxsServerGrpUpdateItem : public RsItem {
public:
RsGxsServerGrpUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE, servType,
RS_PKT_SUBTYPE_GXS_SERVER_GRP_UPDATE)
{ clear();}
virtual ~RsGxsServerGrpUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint32_t grpUpdateTS;
};
class RsGxsMsgUpdateItem : public RsItem
{
public:
RsGxsMsgUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE, servType, RS_PKT_SUBTYPE_GXS_MSG_UPDATE)
{ clear();}
virtual ~RsGxsMsgUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::string peerId;
std::map<std::string, uint32_t> msgUpdateTS;
};
class RsGxsServerMsgUpdateItem : public RsItem
{
public:
RsGxsServerMsgUpdateItem(uint16_t servType) : RsItem(RS_PKT_VERSION_SERVICE,
servType, RS_PKT_SUBTYPE_GXS_SERVER_MSG_UPDATE)
{ clear();}
virtual ~RsGxsServerMsgUpdateItem() {}
virtual void clear();
virtual std::ostream &print(std::ostream &out, uint16_t indent);
std::string grpId;
uint32_t msgUpdateTS; // the last time this group received a new msg
};
class RsGxsUpdateSerialiser : public RsSerialType
{
public:
RsGxsUpdateSerialiser(uint16_t servtype) :
RsSerialType(RS_PKT_VERSION_SERVICE, servtype), SERVICE_TYPE(servtype) { return; }
virtual ~RsGxsUpdateSerialiser() { return; }
virtual uint32_t size(RsItem *item);
virtual bool serialise(RsItem *item, void *data, uint32_t *size);
virtual RsItem* deserialise(void *data, uint32_t *size);
private:
/* for RS_PKT_SUBTYPE_GRP_UPDATE_ITEM */
virtual uint32_t sizeGxsGrpUpdate(RsGxsGrpUpdateItem* item);
virtual bool serialiseGxsGrpUpdate(RsGxsGrpUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsGrpUpdateItem* deserialGxsGrpUpddate(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_GRP_SERVER_UPDATE_ITEM */
virtual uint32_t sizeGxsServerGrpUpdate(RsGxsServerGrpUpdateItem* item);
virtual bool serialiseGxsServerGrpUpdate(RsGxsServerGrpUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsServerGrpUpdateItem* deserialGxsServerGrpUpddate(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_GXS_MSG_UPDATE_ITEM */
virtual uint32_t sizeGxsMsgUpdate(RsGxsMsgUpdateItem* item);
virtual bool serialiseGxsMsgUpdate(RsGxsMsgUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsMsgUpdateItem* deserialGxsMsgUpdate(void *data, uint32_t *size);
/* for RS_PKT_SUBTYPE_GXS_SERVER_UPDATE_ITEM */
virtual uint32_t sizeGxsServerMsgUpdate(RsGxsServerMsgUpdateItem* item);
virtual bool serialiseGxsServerMsgUpdate(RsGxsServerMsgUpdateItem *item, void *data, uint32_t *size);
virtual RsGxsServerMsgUpdateItem* deserialGxsServerMsgUpdate(void *data, uint32_t *size);
private:
const uint16_t SERVICE_TYPE;
};
#endif /* RSGXSUPDATEITEMS_H_ */

View File

@ -354,8 +354,9 @@ bool RsNxsSerialiser::serialiseNxsSyncGrp(RsNxsSyncGrp *item, void *data, uint32
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt8(data, *size, &offset, item->flag);
ok &= setRawUInt32(data, *size, &offset, item->syncAge);
ok &= setRawUInt32(data, *size, &offset, item->createdSince);
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= setRawUInt32(data, *size, &offset, item->updateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
@ -403,7 +404,7 @@ bool RsNxsSerialiser::serialiseNxsTrans(RsNxsTransac *item, void *data, uint32_t
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt16(data, *size, &offset, item->transactFlag);
ok &= setRawUInt32(data, *size, &offset, item->nItems);
ok &= setRawUInt32(data, *size, &offset, item->timestamp);
ok &= setRawUInt32(data, *size, &offset, item->updateTS);
@ -501,9 +502,10 @@ bool RsNxsSerialiser::serialiseNxsSyncMsg(RsNxsSyncMsg *item, void *data, uint32
ok &= setRawUInt32(data, *size, &offset, item->transactionNumber);
ok &= setRawUInt8(data, *size, &offset, item->flag);
ok &= setRawUInt32(data, *size, &offset, item->syncAge);
ok &= setRawUInt32(data, *size, &offset, item->createdSince);
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= SetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= setRawUInt32(data, *size, &offset, item->updateTS);
if(offset != tlvsize){
#ifdef RSSERIAL_DEBUG
@ -710,8 +712,9 @@ RsNxsSyncGrp* RsNxsSerialiser::deserialNxsSyncGrp(void *data, uint32_t *size){
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt8(data, *size, &offset, &(item->flag));
ok &= getRawUInt32(data, *size, &offset, &(item->syncAge));
ok &= getRawUInt32(data, *size, &offset, &(item->createdSince));
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= getRawUInt32(data, *size, &offset, &(item->updateTS));
if (offset != rssize)
{
@ -846,7 +849,7 @@ RsNxsTransac* RsNxsSerialiser::deserialNxsTrans(void *data, uint32_t *size){
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt16(data, *size, &offset, &(item->transactFlag));
ok &= getRawUInt32(data, *size, &offset, &(item->nItems));
ok &= getRawUInt32(data, *size, &offset, &(item->timestamp));
ok &= getRawUInt32(data, *size, &offset, &(item->updateTS));
if (offset != rssize)
{
@ -984,9 +987,10 @@ RsNxsSyncMsg* RsNxsSerialiser::deserialNxsSyncMsg(void *data, uint32_t *size)
ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber));
ok &= getRawUInt8(data, *size, &offset, &(item->flag));
ok &= getRawUInt32(data, *size, &offset, &(item->syncAge));
ok &= getRawUInt32(data, *size, &offset, &(item->createdSince));
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_HASH_SHA1, item->syncHash);
ok &= GetTlvString(data, *size, &offset, TLV_TYPE_STR_GROUPID, item->grpId);
ok &= getRawUInt32(data, *size, &offset, &(item->updateTS));
if (offset != rssize)
{
@ -1057,6 +1061,7 @@ uint32_t RsNxsSerialiser::sizeNxsSyncGrp(RsNxsSyncGrp *item)
s += 1; // flag
s += 4; // sync age
s += GetTlvStringSize(item->syncHash);
s += 4; // updateTS
return s;
}
@ -1086,6 +1091,7 @@ uint32_t RsNxsSerialiser::sizeNxsSyncMsg(RsNxsSyncMsg *item)
s += 4; // age
s += GetTlvStringSize(item->grpId);
s += GetTlvStringSize(item->syncHash);
s += 4; // updateTS
return s;
}
@ -1111,7 +1117,7 @@ uint32_t RsNxsSerialiser::sizeNxsTrans(RsNxsTransac *item){
s += 4; // transaction number
s += 2; // flag
s += 4; // nMsgs
s += 4; // timeout
s += 4; // updateTS
return s;
}
@ -1141,16 +1147,18 @@ void RsNxsGrp::clear()
void RsNxsSyncGrp::clear()
{
flag = 0;
syncAge = 0;
createdSince = 0;
syncHash.clear();
updateTS = 0;
}
void RsNxsSyncMsg::clear()
{
grpId.clear();
flag = 0;
syncAge = 0;
createdSince = 0;
syncHash.clear();
updateTS = 0;
}
void RsNxsSyncGrpItem::clear()
@ -1172,6 +1180,7 @@ void RsNxsSyncMsgItem::clear()
void RsNxsTransac::clear(){
transactFlag = 0;
nItems = 0;
updateTS = 0;
timestamp = 0;
transactionNumber = 0;
}
@ -1185,10 +1194,11 @@ std::ostream& RsNxsSyncGrp::print(std::ostream &out, uint16_t indent)
printIndent(out , int_Indent);
out << "Hash: " << syncHash << std::endl;
printIndent(out , int_Indent);
out << "Sync Age: " << syncAge << std::endl;
out << "Sync Age: " << createdSince << std::endl;
printIndent(out , int_Indent);
out << "flag" << flag << std::endl;
printIndent(out , int_Indent);
out << "updateTS" << updateTS << std::endl;
printRsItemEnd(out ,"RsNxsSyncGrp", indent);
@ -1217,11 +1227,13 @@ std::ostream& RsNxsSyncMsg::print(std::ostream &out, uint16_t indent)
printIndent(out , int_Indent);
out << "GrpId: " << grpId << std::endl;
printIndent(out , int_Indent);
out << "syncAge: " << syncAge << std::endl;
out << "createdSince: " << createdSince << std::endl;
printIndent(out , int_Indent);
out << "syncHash: " << syncHash << std::endl;
printIndent(out , int_Indent);
out << "flag: " << flag << std::endl;
printIndent(out , int_Indent);
out << "updateTS: " << updateTS << std::endl;
printRsItemEnd(out, "RsNxsSyncMsg", indent);
return out;
@ -1316,6 +1328,8 @@ std::ostream& RsNxsTransac::print(std::ostream &out, uint16_t indent){
printIndent(out , int_Indent);
out << "timeout: " << timestamp << std::endl;
printIndent(out , int_Indent);
out << "updateTS: " << updateTS << std::endl;
printIndent(out , int_Indent);
out << "transactionNumber: " << transactionNumber << std::endl;
printIndent(out , int_Indent);

View File

@ -100,7 +100,8 @@ public:
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint8_t flag; // advises whether to use sync hash
uint32_t syncAge; // how far back to sync data
uint32_t createdSince; // how far back to sync data
uint32_t updateTS; // time of last group update
std::string syncHash; // use to determine if changes that have occured since last hash
@ -146,6 +147,9 @@ public:
uint16_t transactFlag;
uint32_t nItems;
uint32_t updateTS;
// not serialised
uint32_t timestamp;
};
@ -235,7 +239,8 @@ public:
std::string grpId;
uint8_t flag;
uint32_t syncAge;
uint32_t createdSince;
uint32_t updateTS; // time of last update
std::string syncHash;
};

View File

@ -154,6 +154,8 @@ const uint16_t RS_SERVICE_GXSV3_TYPE_POSTED = 0xf326;
const uint16_t RS_SERVICE_GXSV3_TYPE_CHANNELS = 0xf327;
const uint16_t RS_SERVICE_GXSV3_TYPE_GXSCIRCLE = 0xf328;
const uint16_t RS_SERVICE_TYPE_GXS_RECOGN = 0xf331;
/***************** IDS ALLOCATED FOR PLUGINS ******************/
const uint16_t RS_SERVICE_TYPE_PLUGIN_ARADO_TEST_ID1 = 0xf401;

View File

@ -429,6 +429,165 @@ std::ostream &RsTlvStringSet::printHex(std::ostream &out, uint16_t indent)
}
/************************************* String Set Ref ************************************/
/* This is exactly the same as StringSet, but it uses an alternative list.
*/
RsTlvStringSetRef::RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids)
:mType(type), ids(refids)
{
}
void RsTlvStringSetRef::TlvClear()
{
ids.clear();
}
uint32_t RsTlvStringSetRef::TlvSize()
{
uint32_t s = TLV_HEADER_SIZE; /* header */
/* determine the total size of ids strings in list */
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
if (it->length() > 0)
s += GetTlvStringSize(*it);
}
return s;
}
bool RsTlvStringSetRef::SetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
/* must check sizes */
uint32_t tlvsize = TlvSize();
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend)
return false; /* not enough space */
bool ok = true;
/* start at data[offset] */
ok &= SetTlvBase(data, tlvend, offset, mType , tlvsize);
/* determine the total size of ids strings in list */
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
if (it->length() > 0)
ok &= SetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, *it);
}
return ok;
}
bool RsTlvStringSetRef::GetTlv(void *data, uint32_t size, uint32_t *offset) /* serialise */
{
if (size < *offset + TLV_HEADER_SIZE)
return false;
uint16_t tlvtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
uint32_t tlvsize = GetTlvSize( &(((uint8_t *) data)[*offset]) );
uint32_t tlvend = *offset + tlvsize;
if (size < tlvend) /* check size */
return false; /* not enough space */
if (tlvtype != mType) /* check type */
return false;
bool ok = true;
/* ready to load */
TlvClear();
/* skip the header */
(*offset) += TLV_HEADER_SIZE;
/* while there is TLV */
while((*offset) + 2 < tlvend)
{
/* get the next type */
uint16_t tlvsubtype = GetTlvType( &(((uint8_t *) data)[*offset]) );
if (tlvsubtype == TLV_TYPE_STR_GENID)
{
std::string newIds;
ok &= GetTlvString(data, tlvend, offset, TLV_TYPE_STR_GENID, newIds);
if(ok)
{
ids.push_back(newIds);
}
}
else
{
/* Step past unknown TLV TYPE */
ok &= SkipUnknownTlv(data, tlvend, offset);
}
if (!ok)
{
break;
}
}
/***************************************************************************
* NB: extra components could be added (for future expansion of the type).
* or be present (if this code is reading an extended version).
*
* We must chew up the extra characters to conform with TLV specifications
***************************************************************************/
if (*offset != tlvend)
{
#ifdef TLV_DEBUG
std::cerr << "RsTlvPeerIdSetRef::GetTlv() Warning extra bytes at end of item";
std::cerr << std::endl;
#endif
*offset = tlvend;
}
return ok;
}
/// print to screen RsTlvStringSet contents
std::ostream &RsTlvStringSetRef::print(std::ostream &out, uint16_t indent)
{
printBase(out, "RsTlvStringSetRef", indent);
uint16_t int_Indent = indent + 2;
printIndent(out, int_Indent);
out << "type:" << mType;
out << std::endl;
std::list<std::string>::iterator it;
for(it = ids.begin(); it != ids.end() ; ++it)
{
printIndent(out, int_Indent);
out << "id:" << *it;
out << std::endl;
}
printEnd(out, "RsTlvStringSetRef", indent);
return out;
}
/************************************* Service Id Set ************************************/
void RsTlvServiceIdSet::TlvClear()

View File

@ -145,6 +145,22 @@ virtual std::ostream &print(std::ostream &out, uint16_t indent);
};
class RsTlvStringSetRef: public RsTlvItem
{
public:
RsTlvStringSetRef(uint16_t type, std::list<std::string> &refids);
virtual ~RsTlvStringSetRef() { return; }
virtual uint32_t TlvSize();
virtual void TlvClear();
virtual bool SetTlv(void *data, uint32_t size, uint32_t *offset); /* serialise */
virtual bool GetTlv(void *data, uint32_t size, uint32_t *offset); /* deserialise */
virtual std::ostream &print(std::ostream &out, uint16_t indent);
uint16_t mType;
std::list<std::string> &ids; /* Mandatory */
};
/**** MORE TLV *****
*
* File Items/Data.

View File

@ -215,6 +215,21 @@ bool p3GxsForums::createGroup(uint32_t &token, RsGxsForumGroup &group)
return true;
}
bool p3GxsForums::updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group)
{
std::cerr << "p3GxsForums::updateGroup()" << std::endl;
if(meta.getGroupId().empty())
return false;
RsGxsForumGroupItem* grpItem = new RsGxsForumGroupItem();
grpItem->mGroup = group;
grpItem->meta = group.mMeta;
grpItem->meta.mGroupId = meta.getGroupId();
RsGenExchange::updateGroup(token, meta, grpItem);
return true;
}
bool p3GxsForums::createMsg(uint32_t &token, RsGxsForumMsg &msg)
{

View File

@ -74,6 +74,13 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
/*!
* To update forum group with new information
* @param token the token used to check completion status of update
* @param group group to be updated, groupId element must be set or will be rejected
* @return false groupId not set, true if set and accepted (still check token for completion)
*/
virtual bool updateGroup(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsGxsForumGroup &group);
private:

File diff suppressed because it is too large Load Diff

View File

@ -38,9 +38,12 @@
#include "util/rsmemcache.h"
#include "util/rstickevent.h"
#include "util/rsrecogn.h"
#include "pqi/authgpg.h"
#include "serialiser/rsgxsrecognitems.h"
/*
* Identity Service
*
@ -73,6 +76,27 @@ virtual std::string save() const;
std::string pgpId;
};
class SSGxsIdRecognTags: public SSBit
{
public:
SSGxsIdRecognTags()
:tagFlags(0), publishTs(0), lastCheckTs(0) { return; }
virtual bool load(const std::string &input);
virtual std::string save() const;
void setTags(bool processed, bool pending, uint32_t flags);
bool tagsProcessed() const; // have we processed?
bool tagsPending() const; // should we reprocess?
bool tagValid(int i) const;
time_t publishTs;
time_t lastCheckTs;
uint32_t tagFlags;
};
class SSGxsIdScore: public SSBit
{
public:
@ -113,11 +137,14 @@ virtual std::string save() const;
// pgphash status
SSGxsIdPgp pgp;
// recogTags.
SSGxsIdRecognTags recogntags;
// reputation score.
SSGxsIdScore score;
SSGxsIdCumulator opinion;
SSGxsIdCumulator reputation;
};
#define ID_LOCAL_STATUS_FULL_CALC_FLAG 0x00010000
@ -133,10 +160,14 @@ class RsGxsIdCache
{
public:
RsGxsIdCache();
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey);
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey,
const std::list<RsRecognTag> &tagList);
void updateServiceString(std::string serviceString);
time_t mPublishTs;
std::list<RsRecognTag> mRecognTags; // Only partially validated.
RsIdentityDetails details;
RsTlvSecurityKey pubkey;
};
@ -165,6 +196,12 @@ static uint32_t idAuthenPolicy();
virtual void service_tick(); // needed for background processing.
/*!
* Design hack, id service must be constructed first as it
* is need for construction of subsequent net services
*/
void setNes(RsNetworkExchangeService* nes);
/* General Interface is provided by RsIdentity / RsGxsIfaceImpl. */
/* Data Specific Interface */
@ -175,6 +212,7 @@ virtual bool getMsgData(const uint32_t &token, std::vector<RsGxsIdOpinion> &opin
// These are local - and not exposed via RsIdentity.
virtual bool createGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool updateGroup(uint32_t& token, RsGxsIdGroup &group);
virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion);
/**************** RsIdentity External Interface.
@ -197,6 +235,13 @@ virtual bool getOwnIds(std::list<RsGxsId> &ownIds);
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion);
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params);
virtual bool updateIdentity(uint32_t& token, RsGxsIdGroup &group);
virtual bool parseRecognTag(const RsGxsId &id, const std::string &nickname,
const std::string &tag, RsRecognTagDetails &details);
virtual bool getRecognTagRequest(const RsGxsId &id, const std::string &comment,
uint16_t tag_class, uint16_t tag_type, std::string &tag);
/**************** RsGixs Implementation
* Notes:
@ -219,7 +264,7 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
// get Reputation.
virtual bool haveReputation(const RsGxsId &id);
virtual bool loadReputation(const RsGxsId &id);
virtual bool loadReputation(const RsGxsId &id, const std::list<std::string>& peers);
virtual bool getReputation(const RsGxsId &id, GixsReputation &rep);
@ -245,16 +290,20 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
*/
int cache_tick();
bool cache_request_load(const RsGxsId &id);
bool cache_request_load(const RsGxsId &id, const std::list<std::string>& peers = std::list<std::string>());
bool cache_start_load();
bool cache_load_for_token(uint32_t token);
bool cache_store(const RsGxsIdGroupItem *item);
bool cache_update_if_cached(const RsGxsId &id, std::string serviceString);
bool isPendingNetworkRequest(const RsGxsId& gxsId) const;
void requestIdsFromNet();
// Mutex protected.
std::list<RsGxsId> mCacheLoad_ToCache;
//std::list<RsGxsId> mCacheLoad_ToCache;
std::map<RsGxsId, std::list<std::string> > mCacheLoad_ToCache, mPendingCache;
// Switching to RsMemCache for Key Caching.
RsMemCache<RsGxsId, RsGxsIdCache> mPublicKeyCache;
@ -303,6 +352,39 @@ virtual void handle_event(uint32_t event_type, const std::string &elabel);
std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess;
/************************************************************************
* recogn processing.
*
*/
bool recogn_schedule();
bool recogn_start();
bool recogn_handlerequest(uint32_t token);
bool recogn_process();
// helper functions.
bool recogn_extract_taginfo(const RsGxsIdGroupItem *item, std::list<RsGxsRecognTagItem *> &tagItems);
bool cache_process_recogntaginfo(const RsGxsIdGroupItem *item, std::list<RsRecognTag> &tagList);
bool recogn_checktag(const RsGxsId &id, const std::string &nickname, RsGxsRecognTagItem *item, bool doSignCheck, bool &isPending);
void loadRecognKeys();
/************************************************************************
* for getting identities that are not present
*
*/
void checkPeerForIdentities();
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
bool checkRecognSignature_locked(std::string encoded, RSA &key, std::string signature);
bool getRecognKey_locked(std::string signer, RSA &key);
std::list<RsGxsGroupId> mRecognGroupIds;
std::list<RsGxsIdGroupItem *> mRecognGroupsToProcess;
std::map<std::string, RsGxsRecognSignerItem *> mRecognSignKeys;
std::map<std::string, uint32_t> mRecognOldSignKeys;
/************************************************************************
* Below is the background task for processing opinions => reputations
*
@ -348,6 +430,12 @@ std::string genRandomId(int len = 20);
std::vector<RsGxsGroupChange*> mGroupChange;
std::vector<RsGxsMsgChange*> mMsgChange;
private:
std::map<uint32_t, std::set<RsGxsGroupId> > mIdsPendingCache;
std::map<uint32_t, std::list<RsGxsGroupId> > mGroupNotPresent;
std::map<RsGxsId, std::list<std::string> > mIdsNotPresent;
RsNetworkExchangeService* mNes;
};
#endif // P3_IDENTITY_SERVICE_HEADER

View File

@ -40,7 +40,6 @@
/****
* #define POSTED_DEBUG 1
****/
#define POSTED_DEBUG 1
RsPosted *rsPosted = NULL;

View File

@ -56,7 +56,9 @@ linux-* {
LIBS += ../../../lib/libretroshare.a
LIBS += ../../../../../libbitdht/src/lib/libbitdht.a
LIBS += ../../../../../openpgpsdk/src/lib/libops.a
LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lsqlite3 -lbz2
LIBS += -lssl -lgpgme -lupnp -lixml -lgnome-keyring -lbz2
# We need a explicit path here, to force using the home version of sqlite3 that really encrypts the database.
LIBS += /home/crispy/Development/retroshare/sqlcipher/sqlcipher/.libs/libsqlite3.a
LIBS *= -rdynamic -frtti
DEFINES *= HAVE_XSS # for idle time, libx screensaver extensions
DEFINES *= UBUNTU

View File

@ -108,7 +108,7 @@ bool GenExchangeTest::pollForMsgAcknowledgement(uint32_t token,
now = time(NULL);
}
return false;
}
}
GenExchangeTestService* GenExchangeTest::getTestService()
{
@ -155,12 +155,13 @@ void GenExchangeTest::setUp()
// would be useful for genexchange services
// to have a protected reset button
mTestService->start();
}
}
void GenExchangeTest::breakDown()
{
mTestService->join();
clearAllData();
mDataService->resetDataStore();
mTestService->join();
clearAllData();
}
bool msgDataSort(const RsDummyMsg* m1, const RsDummyMsg* m2)
@ -189,7 +190,7 @@ bool GenExchangeTest::compareMsgDataMaps()
}
return ok;
}
}
bool GenExchangeTest::compareMsgIdMaps()
@ -205,7 +206,7 @@ bool GenExchangeTest::compareMsgIdMaps()
ok &= Comparison<std::vector<RsGxsMessageId>, RsGxsMessageId>::comparison(v1, v2);
}
return ok;
}
}
bool GenExchangeTest::compareMsgMetaMaps()
@ -220,19 +221,19 @@ bool GenExchangeTest::compareMsgMetaMaps()
ok &= Comparison<std::vector<RsMsgMetaData>, RsMsgMetaData>::comparison(v1, v2);
}
return ok;
}
}
bool GenExchangeTest::compareMsgRelateIdsMap()
{
return false;
}
}
bool GenExchangeTest::compareMsgRelatedDataMap()
{
return false;
}
}
bool grpDataSort(const RsDummyGrp* g1, const RsDummyGrp* g2)
{
@ -247,7 +248,7 @@ bool GenExchangeTest::compareGrpData()
bool ok = Comparison<std::vector<RsDummyGrp*>, RsDummyGrp*>::comparison
(mGrpDataIn, mGrpDataOut);
return ok;
}
}
bool operator<(const RsGroupMetaData& l, const RsGroupMetaData& r)
{
@ -263,7 +264,7 @@ bool GenExchangeTest::compareGrpMeta()
bool ok = Comparison<std::list<RsGroupMetaData>, RsGroupMetaData>::comparison
(mGrpMetaDataIn, mGrpMetaDataOut);
return ok;
}
}
bool GenExchangeTest::compareGrpIds()
@ -289,7 +290,7 @@ void GenExchangeTest::createGrps(uint32_t nGrps,
pollForGrpAcknowledgement(token, grpId);
groupId.push_back(grpId);
}
}
}
void GenExchangeTest::init(RsMsgMetaData& msgMetaData) const
{
@ -334,7 +335,7 @@ void GenExchangeTest::init(RsDummyGrp& grpItem) const
{
randString(SHORT_STR, grpItem.grpData);
init(grpItem.meta);
}
}
void GenExchangeTest::init(RsDummyMsg& msgItem) const
@ -346,72 +347,72 @@ void GenExchangeTest::init(RsDummyMsg& msgItem) const
void GenExchangeTest::storeToMsgDataOutMaps(const DummyMsgMap& msgDataOut)
{
mMsgDataOut.insert(msgDataOut.begin(), msgDataOut.end());
}
}
void GenExchangeTest::storeToMsgIdsOutMaps(const GxsMsgIdResult& msgIdsOut)
{
mMsgIdsOut.insert(msgIdsOut.begin(), msgIdsOut.end());
}
}
void GenExchangeTest::storeToMsgMetaOutMaps(const GxsMsgMetaMap& msgMetaOut)
{
mMsgMetaDataOut.insert(msgMetaOut.begin(), msgMetaOut.end());
}
}
void GenExchangeTest::storeToMsgDataInMaps(const DummyMsgMap& msgDataIn)
{
mMsgDataIn.insert(msgDataIn.begin(), msgDataIn.end());
}
}
void GenExchangeTest::storeToMsgIdsInMaps(const GxsMsgIdResult& msgIdsIn)
{
mMsgIdsIn.insert(msgIdsIn.begin(), msgIdsIn.end());
}
}
void GenExchangeTest::storeToMsgMetaInMaps(const GxsMsgMetaMap& msgMetaIn)
{
mMsgMetaDataIn.insert(msgMetaIn.begin(), msgMetaIn.end());
}
}
void GenExchangeTest::storeToGrpIdsOutList(
const std::list<RsGxsGroupId>& grpIdOut)
{
mGrpIdsOut.insert(mGrpIdsOut.end(), grpIdOut.begin(), grpIdOut.end());
}
}
void GenExchangeTest::storeToGrpMetaOutList(
const std::list<RsGroupMetaData>& grpMetaOut)
{
mGrpMetaDataOut.insert(mGrpMetaDataOut.end(), grpMetaOut.begin(), grpMetaOut.end());
}
}
void GenExchangeTest::storeToGrpDataOutList(
const std::vector<RsDummyGrp*>& grpDataOut)
{
mGrpDataOut.insert(mGrpDataOut.end(), grpDataOut.begin(), grpDataOut.end());
}
}
void GenExchangeTest::storeToGrpIdsInList(
const std::list<RsGxsGroupId>& grpIdIn)
{
mGrpIdsIn.insert(mGrpIdsIn.end(), grpIdIn.begin(), grpIdIn.end());
}
}
void GenExchangeTest::storeToGrpMetaInList(
const std::list<RsGroupMetaData>& grpMetaIn)
{
mGrpMetaDataIn.insert(mGrpMetaDataIn.end(), grpMetaIn.begin(), grpMetaIn.end());
}
}
void GenExchangeTest::storeToGrpDataInList(
@ -437,14 +438,14 @@ void GenExchangeTest::clearAllData()
void GenExchangeTest::clearMsgDataInMap()
{
mMsgDataIn.clear();
}
}
void GenExchangeTest::clearMsgDataOutMap()
{
clearMsgDataMap(mMsgDataOut);
}
}
void GenExchangeTest::clearMsgDataMap(DummyMsgMap& msgDataMap) const
{
@ -459,31 +460,31 @@ void GenExchangeTest::clearMsgDataMap(DummyMsgMap& msgDataMap) const
void GenExchangeTest::clearMsgMetaInMap()
{
mMsgMetaDataIn.clear();
}
}
void GenExchangeTest::clearMsgMetaOutMap()
{
mMsgMetaDataOut.clear();
}
}
void GenExchangeTest::clearMsgIdInMap()
{
mMsgIdsIn.clear();
}
}
void GenExchangeTest::clearMsgIdOutMap()
{
mMsgIdsOut.clear();
}
}
void GenExchangeTest::clearMsgRelatedIdInMap()
{
mMsgRelatedIdsIn.clear();
}
}
void GenExchangeTest::clearGrpDataInList()
@ -494,38 +495,38 @@ void GenExchangeTest::clearGrpDataInList()
void GenExchangeTest::clearGrpDataList(std::vector<RsDummyGrp*>& grpData) const
{
deleteResVector<RsDummyGrp>(grpData);
}
}
void GenExchangeTest::clearGrpDataOutList()
{
clearGrpDataList(mGrpDataOut);
}
}
void GenExchangeTest::clearGrpMetaInList()
{
mGrpMetaDataIn.clear();
}
}
void GenExchangeTest::clearGrpMetaOutList()
{
mGrpMetaDataOut.clear();
}
}
void GenExchangeTest::clearGrpIdInList()
{
mGrpIdsIn.clear();
}
}
void GenExchangeTest::clearGrpIdOutList()
{
mGrpIdsOut.clear();
}
}
bool operator ==(const RsMsgMetaData& lMeta, const RsMsgMetaData& rMeta)
{
@ -584,5 +585,5 @@ bool operator ==(const RsDummyMsg& lMsg, const RsDummyMsg& rMsg)
bool operator ==(const RsGxsGrpItem& lGrp, const RsGxsGrpItem& rGrp)
{
return false;
}
}

View File

@ -258,7 +258,7 @@ private:
std::list<RsGroupMetaData> mGrpMetaDataOut, mGrpMetaDataIn;
std::list<RsGxsGroupId> mGrpIdsOut, mGrpIdsIn;
DummyMsgMap mMsgDataOut, mMsgDataIn;
std::map<RsGxsGroupId, std::vector<RsDummyMsg*> > mMsgDataOut, mMsgDataIn;
GxsMsgMetaMap mMsgMetaDataOut, mMsgMetaDataIn;
GxsMsgIdResult mMsgIdsOut, mMsgIdsIn;

View File

@ -17,6 +17,11 @@ void GenExchangeTestService::publishDummyGrp(uint32_t &token, RsDummyGrp *grp)
publishGroup(token, grp);
}
void GenExchangeTestService::updateDummyGrp(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta, RsDummyGrp *group)
{
updateGroup(token, updateMeta, group);
}
void GenExchangeTestService::publishDummyMsg(uint32_t &token, RsDummyMsg *msg)
{
publishMsg(token, msg);

View File

@ -15,6 +15,7 @@ public:
void notifyChanges(std::vector<RsGxsNotify*>& changes);
void publishDummyGrp(uint32_t& token, RsDummyGrp* grp);
void updateDummyGrp(uint32_t &token, RsGxsGroupUpdateMeta& meta, RsDummyGrp *group);
void publishDummyMsg(uint32_t& token, RsDummyMsg* msg);
/*!

View File

@ -7,6 +7,7 @@
#include "gxspublishgrouptest.h"
#include "util/utest.h"
#include "support.h"
#define POLLING_TIME_OUT 5
@ -169,6 +170,65 @@ bool GxsPublishGroupTest::testGrpIdRetrieval()
return ok;
}
bool GxsPublishGroupTest::testUpdateGroup()
{
setUp();
GenExchangeTestService* testService = getTestService();
RsTokenService* tokenService = getTokenService();
// create some random grps to allow msg testing
RsDummyGrp* dgrp1 = new RsDummyGrp();
RsDummyGrp* dgrp2 = new RsDummyGrp();
RsDummyGrp* dgrp2_copy = new RsDummyGrp();
init(*dgrp1);
init(*dgrp2);
RsTokReqOptions opts;
opts.mReqType = 45000;
uint32_t token;
RsGxsGroupId grpId;
std::vector<RsDummyGrp*> groupsPublished;
std::list<RsGxsGroupId> grpIds;
std::string name = dgrp1->meta.mGroupName;
*dgrp2 = *dgrp1;
testService->publishDummyGrp(token, dgrp1);
bool ok = pollForGrpAcknowledgement(token, grpId);
grpIds.push_back(grpId);
RsGxsGroupUpdateMeta updateMeta(grpId);
updateMeta.setMetaUpdate(RsGxsGroupUpdateMeta::NAME, name);
randString(SHORT_STR, dgrp2->grpData);
dgrp2->meta.mGroupId = grpId;
*dgrp2_copy = *dgrp2;
dgrp2->grpData ="ojfosfjsofjsof";
testService->updateDummyGrp(token, updateMeta, dgrp2);
ok &= pollForGrpAcknowledgement(token, grpId);
groupsPublished.push_back(dgrp2_copy);
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
tokenService->requestGroupInfo(token, 0, opts, grpIds);
pollForToken(token, opts, true);
ok &= compareGrpData();
breakDown();
return ok;
}
bool GxsPublishGroupTest::testGrpMetaRetrieval()
{
@ -229,10 +289,11 @@ bool GxsPublishGroupTest::testGrpMetaRetrieval()
}
void GxsPublishGroupTest::runTests()
{
CHECK(testGrpSubmissionRetrieval());
CHECK(testGrpIdRetrieval());
CHECK(testGrpMetaRetrieval());
CHECK(testSpecificGrpRetrieval());
// CHECK(testGrpSubmissionRetrieval());
// CHECK(testGrpIdRetrieval());
// CHECK(testGrpMetaRetrieval());
// CHECK(testSpecificGrpRetrieval());
CHECK(testUpdateGroup());
}

View File

@ -26,6 +26,7 @@ private:
bool testSpecificGrpRetrieval();
bool testGrpIdRetrieval();
bool testGrpMetaRetrieval();
bool testUpdateGroup();
private:

View File

@ -49,10 +49,10 @@ bool GxsPublishMsgTest::testMsgSubmissionRetrieval()
msgOut->meta.mMsgId = msgId.second;
DummyMsgMap msgMap;
std::vector<RsDummyMsg*> msgV;
msgV.push_back(msgOut);
msgMap[msgOut->meta.mGroupId] = msgV;
storeToMsgDataOutMaps(msgMap);
std::vector<RsDummyMsg*> msgV;
msgV.push_back(msgOut);
msgMap[msgOut->meta.mGroupId] = msgV;
storeToMsgDataOutMaps(msgMap);
RsTokReqOptions opts;

View File

@ -30,16 +30,16 @@ INITTEST();
int main()
{
RsGeneralDataService* dataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL);
RsGeneralDataService* dataStore = new RsDataService("./", "testServiceDb", RS_SERVICE_TYPE_DUMMY, NULL, "");
// we want to use default authentication which is NO authentication :)
GenExchangeTestService testService(dataStore, NULL, NULL);
//GxsPublishGroupTest testGrpPublishing(&testService, dataStore);
//testGrpPublishing.runTests();
GxsPublishGroupTest testGrpPublishing(&testService, dataStore);
testGrpPublishing.runTests();
GxsPublishMsgTest testMsgPublishing(&testService, dataStore);
testMsgPublishing.runTests();
//GxsPublishMsgTest testMsgPublishing(&testService, dataStore);
//testMsgPublishing.runTests();
FINALREPORT("RsGenExchangeTest");

View File

@ -0,0 +1,110 @@
/*
* rsgxsupdateitem_test.cc
*
* Created on: 9 Dec 2013
* Author: crispy
*/
#include "support.h"
#include "rsgxsupdateitem_test.h"
INITTEST();
RsSerialType* init_item(RsGxsGrpUpdateItem& i)
{
i.clear();
i.grpUpdateTS = rand()%2424;
randString(SHORT_STR, i.peerId);
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsGxsMsgUpdateItem& i)
{
i.clear();
randString(SHORT_STR, i.peerId);
int numUpdates = rand()%123;
std::string peer;
for(int j=0; j < numUpdates; j++)
{
randString(SHORT_STR, peer);
i.msgUpdateTS.insert(std::make_pair(peer, rand()%45));
}
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsGxsServerGrpUpdateItem& i)
{
i.clear();
i.grpUpdateTS = rand()%2424;
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
RsSerialType* init_item(RsGxsServerMsgUpdateItem& i)
{
i.clear();
randString(SHORT_STR, i.grpId);
i.msgUpdateTS = rand()%4252;
return new RsGxsUpdateSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
}
bool operator ==(const RsGxsGrpUpdateItem& l, const RsGxsGrpUpdateItem& r)
{
bool ok = l.grpUpdateTS == r.grpUpdateTS;
ok &= l.peerId == r.peerId;
return ok;
}
bool operator ==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r)
{
bool ok = l.peerId == r.peerId;
const std::map<std::string, uint32_t>& lUp = l.msgUpdateTS, rUp = r.msgUpdateTS;
ok &= lUp.size() == rUp.size();
std::map<std::string, uint32_t>::const_iterator lit = lUp.begin(), rit;
for(; lit != lUp.end(); lit++)
{
std::string key = lit->first;
if((rit = rUp.find(key)) != rUp.end())
ok &= lit->second == rit->second;
else
return false;
}
return ok;
}
bool operator ==(const RsGxsServerGrpUpdateItem& l,
const RsGxsServerGrpUpdateItem& r)
{
return l.grpUpdateTS == r.grpUpdateTS;
}
bool operator ==(const RsGxsServerMsgUpdateItem& l,
const RsGxsServerMsgUpdateItem& r)
{
bool ok = l.grpId == r.grpId;
ok &= l.msgUpdateTS == r.msgUpdateTS;
return ok;
}
int main()
{
std::cerr << "RsGxsUpdateItem Tests" << std::endl;
test_RsItem<RsGxsGrpUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsGrpUpdateItem");
test_RsItem<RsGxsMsgUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsMsgUpdateItem");
test_RsItem<RsGxsServerGrpUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsServerGrpUpdateItem");
test_RsItem<RsGxsServerMsgUpdateItem>(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM); REPORT("Serialise/Deserialise RsGxsServerMsgUpdateItem");
FINALREPORT("RsGxsUpdateItem Tests");
return TESTRESULT();
}

View File

@ -0,0 +1,25 @@
/*
* rsgxsupdateitem_test.h
*
* Created on: 9 Dec 2013
* Author: crispy
*/
#ifndef RSGXSUPDATEITEM_TEST_H_
#define RSGXSUPDATEITEM_TEST_H_
#include "serialiser/rsgxsupdateitems.h"
#include "support.h"
RsSerialType* init_item(RsGxsGrpUpdateItem& i);
RsSerialType* init_item(RsGxsMsgUpdateItem& i);
RsSerialType* init_item(RsGxsServerGrpUpdateItem& i);
RsSerialType* init_item(RsGxsServerMsgUpdateItem& i);
bool operator==(const RsGxsGrpUpdateItem& l, const RsGxsGrpUpdateItem& r);
bool operator==(const RsGxsMsgUpdateItem& l, const RsGxsMsgUpdateItem& r);
bool operator==(const RsGxsServerGrpUpdateItem& l, const RsGxsServerGrpUpdateItem& r);
bool operator==(const RsGxsServerMsgUpdateItem& l, const RsGxsServerMsgUpdateItem& r);
#endif /* RSGXSUPDATEITEM_TEST_H_ */

View File

@ -39,7 +39,7 @@ RsSerialType* init_item(RsNxsSyncGrp& rsg)
{
rsg.clear();
rsg.flag = RsNxsSyncGrp::FLAG_USE_SYNC_HASH;
rsg.syncAge = rand()%2423;
rsg.createdSince = rand()%2423;
randString(3124,rsg.syncHash);
return new RsNxsSerialiser(RS_SERVICE_TYPE_PLUGIN_SIMPLE_FORUM);
@ -50,7 +50,7 @@ RsSerialType* init_item(RsNxsSyncMsg& rsgm)
rsgm.clear();
rsgm.flag = RsNxsSyncMsg::FLAG_USE_SYNC_HASH;
rsgm.syncAge = rand()%24232;
rsgm.createdSince = rand()%24232;
rsgm.transactionNumber = rand()%23;
randString(SHORT_STR, rsgm.grpId);
randString(SHORT_STR, rsgm.syncHash);
@ -120,7 +120,7 @@ bool operator==(const RsNxsSyncGrp& l, const RsNxsSyncGrp& r)
if(l.syncHash != r.syncHash) return false;
if(l.flag != r.flag) return false;
if(l.syncAge != r.syncAge) return false;
if(l.createdSince != r.createdSince) return false;
if(l.transactionNumber != r.transactionNumber) return false;
return true;
@ -130,7 +130,7 @@ bool operator==(const RsNxsSyncMsg& l, const RsNxsSyncMsg& r)
{
if(l.flag != r.flag) return false;
if(l.syncAge != r.syncAge) return false;
if(l.createdSince != r.createdSince) return false;
if(l.syncHash != r.syncHash) return false;
if(l.grpId != r.grpId) return false;
if(l.transactionNumber != r.transactionNumber) return false;

View File

@ -65,6 +65,7 @@ template<class Key, class Value> class RsMemCache
bool fetch(const Key &key, Value &data);
Value &ref(const Key &key); // like map[] installs empty one if non-existent.
bool store(const Key &key, const Value &data);
bool erase(const Key &key); // clean up cache.
bool resize(); // should be called periodically to cleanup old entries.
@ -169,6 +170,48 @@ template<class Key, class Value> bool RsMemCache<Key, Value>::fetch(const Key &k
}
template<class Key, class Value> bool RsMemCache<Key, Value>::erase(const Key &key)
{
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase()";
std::cerr << std::endl;
printStats(std::cerr);
#endif // DEBUG_RSMEMCACHE
typename std::map<Key, cache_data>::iterator it;
it = mDataMap.find(key);
if (it == mDataMap.end())
{
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase(" << key << ") false";
std::cerr << std::endl;
#endif // DEBUG_RSMEMCACHE
mStats_accessmiss++;
return false;
}
#ifdef DEBUG_RSMEMCACHE
std::cerr << "RsMemCache::erase(" << key << ") OK";
std::cerr << std::endl;
#endif // DEBUG_RSMEMCACHE
/* get timestamps */
time_t old_ts = it->second.ts;
time_t new_ts = 0;
// remove from lru.
mDataMap.erase(it);
update_lrumap(key, old_ts, new_ts);
mDataCount--;
mStats_access++;
return true;
}
template<class Key, class Value> Value &RsMemCache<Key, Value>::ref(const Key &key)
{
#ifdef DEBUG_RSMEMCACHE
@ -320,6 +363,12 @@ template<class Key, class Value> bool RsMemCache<Key, Value>::resize()
// ERROR.
std::cerr << "RsMemCache::resize() CONSISTENCY ERROR";
std::cerr << std::endl;
std::cerr << "\tmDataMap.size() = " << mDataMap.size();
std::cerr << std::endl;
std::cerr << "\tmLruMap.size() = " << mLruMap.size();
std::cerr << std::endl;
std::cerr << "\tmDataCount = " << mDataCount;
std::cerr << std::endl;
}
if (mDataCount > mMaxSize)

View File

@ -0,0 +1,640 @@
/*
* libretroshare/src/util: rsrecogn.cc
*
* RetroShare Utilities
*
* Copyright 2013 by 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.1 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".
*
*/
#include <openssl/ssl.h>
#include <openssl/evp.h>
#include "pqi/pqi_base.h"
#include "util/rsrecogn.h"
#include "util/radix64.h"
#include "util/rsstring.h"
#include "gxs/gxssecurity.h"
/***
* #define DEBUG_RECOGN 1
***/
#define DEBUG_RECOGN 1
static std::string RecognKey = "MIICCgKCAgEA4/i2fy+zR27/H8fzphM8mR/Nz+yXjMJTtqKlCvEMQlyk7lKzDbKifNjGSiAXjSv3b9TRgMtje7hfEhs3//Oeu4KsCf6sz17aj2StBF579IdJTSUPDwq6jCsZ6NDEYpG8xz3FVV+Ac8q5Vpr/+jdg23ta09zq4aV8VIdIsroVOmZQqjwPcmQK57iWHd538i/XBtc2rnzbYq5bprnmtAKdx55gXVXDfALa0s6yR0HYvCaWguMEJhMIKWfi/9PEgLgwF9OmRwywc2TU/EdvYJo8fYHLfGk0PnYBuL1oSnn3cwAAef02W2JyCzQ84g30tLSUk+hC1LLi+iYj3x7IRR4q7Rlf/FYv/Q5fvjRtPT9eqM6fKyJ9ZO4NjlrSPFGydNbgABzP6WMhBzFjUkEKS27bGmr8Qxdj3Zp0TvR2IkyM6oM+6YknuM4RndUEgC1ZxtoIhugMjm6HdMQmoaHNK3kXewgQB90HHqzKA/J1gok3NcqL8Yls5g0LHepVHsU4cuaIqQr5yr665ZTLU2oqn1HIdkgydBYYUt6G3eWJKXYRbDhWPthGo/HK+W+iw6cTGWxzlCZS40EU9efxz4mDuhow67jOe704lBP3kiYXu05Y5uspaYnuvrvIwaRWBYapyR9UmKktnY8xJYrZvrcZgCovAbiodTzWeYg37xjFfGgYNI8CAwEAAQ==";
#define NUM_RECOGN_SIGN_KEYS 3
static std::string RecognSigningKeys[NUM_RECOGN_SIGN_KEYS] =
{
"AvMxAwAAA5YQMAAAABAANAAAAAoAAAABEEAAAAFMAKQAAAAmYjI2ZTUyNGFlZjczYmY3Y2MyMzUwNTc0ZTMyMjcxZWEAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQCyblJK73O/fMI1BXTjInHqIWma62Z2r3K7/giT6Xm3k+lyNokvpR+I45XdEvPRmFVZmTU7XT2n3YiPDLe7y2r9fnYiLvBCdu+FBaVv5UQG8nvFGMLKbhdyRpOSBgDc+Y+8plMPn8jqgfNhLROMowmvDJQkJQjlm80d/9wj+VZ+tLiPPo8uOlghqNhdXDGK7HnfeLrJyD8kLEW7+4huaxR8IsLgjzuK8rovGLYCBcnx4TXvtbEeafJBBBt8S/GPeUaB1rxWpVV6fi+oBU6cvjbEqPzSalIrwNPyqlj+1SbL1jGEGEr1XIMzDa96SVsJ0F93lS3H9c8HdvByAifgzbPZAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBp1w449QGjchVotgHvGWRh18zpsDUHRv8PlRX1vXy8FMstTrnRjaDofFitmpJm8K6F1t/9jviCdB+BCvRzAS4SxER49YCBp04xZfX7c03xdq/e27jYRds2w6YHTiEgNi5v1cyWhrwDcCdefXRnHTH1UOw3jOoWnlnmM6jEsL39XI5fvsog9z8GxcG54APKA7JgiqhgMcrKRwNk74XJAzcjB6FS8xaV2gzpZZLNZ1TU+tJoLSiRqTU8UiAGbAR85lYLT5Ozdd2C+bTQ9f6vltz8bpzicJzxGCIsYtSL44InQsO/Oar9IgZu8QE4pTuunGJhVqEZru7ZN+oV+wXt51n+24SS0sNgNKVUFS74RfvsFi67CrXSWTOI8bVS0Lvv3EMWMdSF9dHGbdCFnp2/wqbW/4Qz7XYF4lcu9gLe4UtIrZ6TkAvBtnSfvTTdXj7kD6oHDjrUCjHPxdhz3BLRbj1wENZsoS3QDl22Ts7dbO8wHjutsS3/zx4DLlADoFlU8p7HJaCdrsq20P4WCeQJb6JbbLpGRAccKAidAPHMxQ4fr3b+GtjxpLJtXaytr4CPSXsCt4TloE9g5yCE6n/2UxQACp8Guh9l2MXmrD7qEGexhYqFB/OG84u3vL+gskmsKXTEqi2SiSmhvzta2p2hGCLCKRQeYbn+4TsIQfgWtYNQvC",
"AvMxAwAAA5YQMAAAABAANAAAAAoAAAACEEAAAAFMAKQAAAAmYjY0OTJkODMzNTI5ZjMxMGM1MmRjMDc3ZjBmZDgyMjcAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQC2SS2DNSnzEMUtwHfw/YInm/XLXEUMktyZTmyMWACBbEfmU6aztT3vxz6UHoCBYtKkzKrfDZLvXe0a5TRLMmK+yfl5IzIVUPdqTg6FF3Bx/GXdj4v/ZP6lAuqY5YeI4wPcKldrrIJ9DTUdhZhgdtgDtxGvrXZ8eFjcl9zM+QEykYKMwfnTCixzVOPCCo3q1lJO13NmlhVQDO+f9vvTZsYDCcZHMqlKZWcCEyY1ZpQiCqlsL8wN6tKxMuSQO8EGdH/tNzsGHwCoZq6EEL7SX/pmc2ABjpDQTLixgXwJtCpw8Fwj1xiavsFFbqSLu3SjUCcrMz9f8U5p2ROyv//lWxsXAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBksDPQ93PdZBGCEnKXcQsdB4yBA9NpImVR81JZdPmWlTwZGAXGJwt4EkBcz+xdey84JDujVtHJUzIL9Ws/Jq5MuXHr0tP5ebah1GCQF2/Ov7sctUk3UPBxeroon7gZQhuzaIJVhl0rzwWriFUbTu7H7g9eaTHMvyfUg+S0Z2p+e0+PdL5rfGOJJZ6+NJCXxxbQ//cF4s0PAzkjAuwDmC+OiUiU5V6fY4XtRMCEI7w+UCj+wQn2Wu1Wc7xVM9uow13rGaLPYkWZ/9v+wNhg0KCsVfKGhkAGGzGyKI9LAppFVTu52pBlRu9Ung7VkhF0JC2aadYKKFl99wCbsGqUYN/gtfgHYCV24LNVah2dAy8CI9UmHdWk1kIwWazbPTYKLfpYCTFxqEqXqo3ijLf0YPsfhIvCQpc5VHAvLJlDm0RFKwzK6N9Zu9s9IvJHzIpaAAHCQJPtYxPwWMdt83njGo9wu1+aVkl5Sb5X8N16AybbnQ7fCBqJruGBM0LHtWVbHEiEygD7OStzyhT5rXKZSQYMA9I2CvK1t7qfDXDM40k8SVQ5CrS9R8x1wqQbe+DqNJ9tMfbUmN0xrO/w2pTl/4edKW30TShW/fr3vCWpVq8gcm3CVFSZUaC4T9wqH96K6KgIPbmg1Hk158pxXYXopEv6ZxR7UTPxKB0O22aIHB6UQ5",
"AvMxAwAAA5YQMAAAABAANAAAAAoAAAABEEAAAAFMAKQAAAAmOTdhNTJkMThjMDBjYWE3YmZlYmQ4NTg0MDJkMzBhY2QAAAAAUl8ogFRAXAABEAAAARQwggEKAoIBAQCXpS0YwAyqe/69hYQC0wrNz7eUHAmJfR5EV7NVFQeOxtTlFwbdvRMK8ZpfqEoRhIPXAYCc9Dv3F7WcmcFer8d50EWhlK7rCQScaRdwL1UmF1dUY8bR8QxhJOUgwmrlzeKOHi2DJ3/9AXm7NJR8XMJgHEQQwi3z/aQsWrwCUA0mk68C8a3vjLtcMj5XBuNXRtGZ9zFjiI9Xt19y0iIKdYpfzOnJTKVETcjH7XPBBbJETWkrEyToHXPjcfhESAbJDOoyfQQbxHMQNE7no7owN08LoWX2kOSGtl2m6JbE2OEdJig83a6U3PDYfYM5LCfsAJEIroYhB3qZJDE98zGC8jihAgMBAAEQUAAAAjIApAAAACZlM2Y4YjY3ZjJmYjM0NzZlZmYxZmM3ZjNhNjEzM2M5OQEgAAACBiwl7oRPJzLlwDd8AzVolFQH1ZS+MWLA4B1eHCjCXSMn+zS0Su6CrpC6/vLwECaKSfNZ8y7T2fNDPJHMLmc1F6jJkdNZq3TZGNRgJx24OF3G5MU6mAH7DBsz7muFto+URTJl9CdJviIyQAn5E+R4Gp531RJdKlbqJl/gWuQMVem+eo3elpVEn8Ckg0yvFaFdhGFTOPyrXOZ6fI0pdCX0SH2q/vAIxGDRzaSYmsR0Y+oYZs0AeRnZD9iEh1v17xnVEdSoLZmZbjlLXXgqhbdXGik6ZoXQg3bTfl5D1j8Tk/d/CXqf0SUKBnIafaNgUeQSMY95M3k3vjPQN7vHdXmg19GnqQmBnGq45qdKI7+0Erfhl4po1z6yVvx9JfIMIDOsKwO3U/As5zbO2BYso0pUP4+gndissfDfqlPRni3orA0tlV6NuLmXi1wkHCu8HQ8WOqEUlWDJNLNpHW5OmgjMFqlIPt7hX5jlc9eXd4oMyaqXm1Tg8Cgbh5DYaT9A7He47+QhqYlPygqK9Fm0ZnH3Yz51cm3p2tRB1JU7qH9h5UqLLKJMBuIx7e9L5ieTfzKmTw6tqpIpHpiR/8bSQlKkw2LxikFy3OXL5obY1t9sWk35BNZQqcqflI6mkPrvGQKwN+co8GjUon5/Y1HSM6ursaJtkD8dz+oXVyWAokkuD7QZ",
};
EVP_PKEY *RsRecogn::loadMasterKey()
{
/* load master signing key */
size_t keylen;
char *keyptr;
Radix64::decode(RecognKey, keyptr, keylen);
const unsigned char *keyptr2 = (const unsigned char *) keyptr;
long keylen2 = keylen;
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr2), keylen2);
delete []keyptr;
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadMasterKeys() failed rsakey load";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return NULL;
}
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
return signKey;
}
bool RsRecogn::loadSigningKeys(std::map<std::string, RsGxsRecognSignerItem *> &signMap)
{
EVP_PKEY *signKey = loadMasterKey();
RsGxsRecognSerialiser recognSerialiser;
if (!signKey)
{
std::cerr << "RsRecogn::loadSigningKeys() missing Master Key";
return false;
}
time_t now = time(NULL);
for(int i = 0; i < NUM_RECOGN_SIGN_KEYS; i++)
{
char *signerbuf;
size_t len;
Radix64::decode(RecognSigningKeys[i], signerbuf, len);
uint32_t pktsize = len;
RsItem *pktitem = recognSerialiser.deserialise(signerbuf, &pktsize);
RsGxsRecognSignerItem *item = dynamic_cast<RsGxsRecognSignerItem *>(pktitem);
delete []signerbuf;
if (!item)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() failed to deserialise SignerItem";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
continue;
}
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() SignerItem: ";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
/* check dates */
if ((item->key.startTS > (unsigned) now) || (item->key.endTS < (unsigned) now))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() failed timestamp";
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() key.startTS: " << item->key.startTS;
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() now: " << now;
std::cerr << std::endl;
std::cerr << "RsRecogn::loadSigningKeys() key.endTS: " << item->key.endTS;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
delete item;
continue;
}
/* check signature */
RsTlvKeySignature signature = item->sign;
item->sign.TlvShallowClear();
unsigned int siglen = signature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data;
/* store in */
uint32_t datalen = recognSerialiser.size(item);
uint8_t *data = (uint8_t *) malloc(datalen);
uint32_t pktlen = datalen;
int signOk = 0;
if (recognSerialiser.serialise(item, data, &pktlen))
{
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, pktlen);
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
EVP_MD_CTX_destroy(mdctx);
item->sign = signature;
signature.TlvShallowClear();
if (signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() signature ok";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
std::string signerId = item->key.keyId;
signMap[signerId] = item;
}
}
if (!signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::loadSigningKeys() signature failed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
delete item;
}
free(data);
}
/* clean up */
EVP_PKEY_free(signKey);
return true;
}
bool RsRecogn::validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item)
{
if (item->sign.keyId != signer->key.keyId)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() keyId mismatch";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
const unsigned char *keyptr = (const unsigned char *) signer->key.keyData.bin_data;
long keylen = signer->key.keyData.bin_len;
/* extract admin key */
RSA *rsakey = d2i_RSAPublicKey(NULL, &(keyptr), keylen);
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() failed extract signkey";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
/* check signature */
RsTlvKeySignature signature = item->sign;
item->sign.TlvShallowClear();
unsigned int siglen = signature.signData.bin_len;
unsigned char *sigbuf = (unsigned char *) signature.signData.bin_data;
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_PKEY *signKey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(signKey, rsakey);
/* store in */
RsGxsRecognSerialiser serialiser;
uint32_t datalen = serialiser.size(item);
uint8_t *data = (uint8_t *) malloc(datalen);
int signOk = 0;
uint32_t pktlen = datalen;
if (serialiser.serialise(item, data, &pktlen))
{
EVP_VerifyInit(mdctx, EVP_sha1());
EVP_VerifyUpdate(mdctx, data, pktlen);
signOk = EVP_VerifyFinal(mdctx, sigbuf, siglen, signKey);
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() sign_result: " << signOk;
std::cerr << std::endl;
#endif // DEBUG_RECOGN
}
else
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::validateTagSignature() failed to serialise";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
}
// Clean up.
item->sign = signature;
signature.TlvShallowClear();
EVP_MD_CTX_destroy(mdctx);
EVP_PKEY_free(signKey);
free(data);
return (signOk == 1);
}
bool rsa_sanity_check(RSA *rsa)
{
std::cerr << "rsa_sanity_check()";
std::cerr << std::endl;
if (!rsa)
{
std::cerr << "rsa_sanity_check() RSA == NULL";
std::cerr << std::endl;
return false;
}
RSA *pubkey = RSAPublicKey_dup(rsa);
std::string signId = RsRecogn::getRsaKeyId(rsa);
std::string signId2 = RsRecogn::getRsaKeyId(pubkey);
bool ok = true;
if (signId != signId2)
{
std::cerr << "rsa_sanity_check() ERROR SignId Failure";
std::cerr << std::endl;
ok = false;
}
if (1 != RSA_check_key(rsa))
{
std::cerr << "rsa_sanity_check() ERROR RSA key is not private";
std::cerr << std::endl;
ok = false;
}
#if 0
if (1 == RSA_check_key(pubkey))
{
std::cerr << "rsa_sanity_check() ERROR RSA dup key is private";
std::cerr << std::endl;
ok = false;
}
#endif
RSA_free(pubkey);
if (!ok)
{
exit(1);
}
return true;
}
bool RsRecogn::signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item)
{
RsGxsRecognSerialiser serialiser;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signTag() Failed serialise TagItem:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item)
{
std::cerr << "RsRecogn::signSigner()";
std::cerr << std::endl;
RsGxsRecognSerialiser serialiser;
std::cerr << "RsRecogn::signSigner() Checking Key";
std::cerr << std::endl;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
std::cerr << "RsRecogn::signSigner() Key Okay";
std::cerr << std::endl;
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signSigner() Failed serialise SignerItem:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item)
{
std::cerr << "RsRecogn::signTagRequest()";
std::cerr << std::endl;
RsGxsRecognSerialiser serialiser;
RSA *rsa = EVP_PKEY_get1_RSA(signKey);
std::string signId = getRsaKeyId(rsa);
rsa_sanity_check(rsa);
RSA_free(rsa);
item->sign.TlvClear();
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::signTagRequest() Failed serialise Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete []buf;
return false;
}
/* calc and check signature */
EVP_MD_CTX *mdctx = EVP_MD_CTX_create();
EVP_SignInit(mdctx, EVP_sha1());
EVP_SignUpdate(mdctx, buf, len);
unsigned int siglen = EVP_PKEY_size(signKey);
unsigned char sigbuf[siglen];
EVP_SignFinal(mdctx, sigbuf, &siglen, signKey);
/* save signature */
item->sign.signData.setBinData(sigbuf, siglen);
item->sign.keyId = signId;
/* clean up */
EVP_MD_CTX_destroy(mdctx);
delete []buf;
return true;
}
bool RsRecogn::itemToRadix64(RsItem *item, std::string &radstr)
{
RsGxsRecognSerialiser serialiser;
/* write out the item for signing */
uint32_t len = serialiser.size(item);
char *buf = new char[len];
if (!serialiser.serialise(item, buf, &len))
{
return false;
}
radstr.clear();
Radix64::encode(buf, len, radstr);
return true;
}
std::string RsRecogn::getRsaKeyId(RSA *pubkey)
{
int len = BN_num_bytes(pubkey -> n);
unsigned char tmp[len];
BN_bn2bin(pubkey -> n, tmp);
// copy first CERTSIGNLEN bytes...
if (len > CERTSIGNLEN)
{
len = CERTSIGNLEN;
}
std::string id;
for(uint32_t i = 0; i < CERTSIGNLEN; i++)
{
rs_sprintf_append(id, "%02x", (uint16_t) (((uint8_t *) (tmp))[i]));
}
return id;
}
RsGxsRecognTagItem *RsRecogn::extractTag(const std::string &encoded)
{
// Decode from Radix64 encoded Packet.
size_t buflen;
char *buffer;
uint32_t pktsize;
Radix64::decode(encoded, buffer, buflen);
pktsize = buflen;
RsGxsRecognSerialiser serialiser;
RsItem *item = serialiser.deserialise(buffer, &pktsize);
delete []buffer;
if (!item)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::extractTag() ERROR Deserialise failed";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return NULL;
}
RsGxsRecognTagItem *tagitem = dynamic_cast<RsGxsRecognTagItem *>(item);
if (!tagitem)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::extractTag() ERROR Not TagItem, is: ";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete item;
}
return tagitem;
}
bool RsRecogn::createTagRequest(const RsTlvSecurityKey &key, const std::string &id, const std::string &nickname, uint16_t tag_class, uint16_t tag_type, const std::string &comment, std::string &tag)
{
RsGxsRecognReqItem *item = new RsGxsRecognReqItem();
EVP_PKEY *signKey = EVP_PKEY_new();
RSA *rsakey = GxsSecurity::extractPrivateKey(key);
if (!rsakey)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to extract key";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
if (!EVP_PKEY_assign_RSA(signKey, rsakey))
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to assign key";
std::cerr << std::endl;
#endif // DEBUG_RECOGN
return false;
}
item->issued_at = time(NULL);
item->period = 365 * 24 * 3600;
item->tag_class = tag_class;
item->tag_type = tag_type;
item->nickname = nickname;
item->identity = id;
item->comment = comment;
bool signOk = RsRecogn::signTagRequest(signKey,item);
EVP_PKEY_free(signKey);
if (!signOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed to sign Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
delete item;
return false;
}
/* write out the item for signing */
RsGxsRecognSerialiser serialiser;
uint32_t len = serialiser.size(item);
char *buf = new char[len];
bool serOk = serialiser.serialise(item, buf, &len);
delete item;
if (serOk)
{
Radix64::encode(buf, len, tag);
}
delete []buf;
if (!serOk)
{
#ifdef DEBUG_RECOGN
std::cerr << "RsRecogn::createTagRequest() Failed serialise Tag Request:";
std::cerr << std::endl;
item->print(std::cerr);
#endif // DEBUG_RECOGN
return false;
}
return serOk;
}

View File

@ -0,0 +1,61 @@
/*
* libretroshare/src/util: rsrecogn.h
*
* RetroShare Utilities
*
* Copyright 2013 by 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.1 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".
*
*/
#ifndef RSUTIL_RECOGN_H
#define RSUTIL_RECOGN_H
#include <inttypes.h>
#include <string>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include "serialiser/rsgxsrecognitems.h"
namespace RsRecogn {
EVP_PKEY * loadMasterKey();
bool loadSigningKeys(std::map<std::string, RsGxsRecognSignerItem *> &signMap);
bool validateTagSignature(RsGxsRecognSignerItem *signer, RsGxsRecognTagItem *item);
bool signTag(EVP_PKEY *signKey, RsGxsRecognTagItem *item);
bool signSigner(EVP_PKEY *signKey, RsGxsRecognSignerItem *item);
bool signTagRequest(EVP_PKEY *signKey, RsGxsRecognReqItem *item);
bool itemToRadix64(RsItem *item, std::string &radstr);
std::string getRsaKeyId(RSA *pubkey);
RsGxsRecognTagItem *extractTag(const std::string &encoded);
bool createTagRequest(const RsTlvSecurityKey &key,
const std::string &id, const std::string &nickname,
uint16_t tag_class, uint16_t tag_type,
const std::string &comment, std::string &tag);
}
#endif

View File

@ -80,6 +80,7 @@ void RsTickEvent::tick_events()
mEvents.erase(it);
count_adjust_locked(event_type, -1);
note_event_locked(event_type);
}
}

View File

@ -473,8 +473,7 @@ void IdDialog::insertIdDetails(uint32_t token)
mStateHelper->setWidgetEnabled(ui.pushButton_Reputation, false);
// No Delete Ids yet!
mStateHelper->setWidgetEnabled(ui.pushButton_Delete, /*true*/ false);
// No Editing Ids yet!
mStateHelper->setWidgetEnabled(ui.pushButton_EditId, /*true*/ false);
mStateHelper->setWidgetEnabled(ui.pushButton_EditId, true);
}
else
{

View File

@ -61,10 +61,19 @@ IdEditDialog::IdEditDialog(QWidget *parent)
/* Connect signals */
connect(ui.radioButton_GpgId, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool)));
connect(ui.radioButton_Pseudo, SIGNAL(toggled(bool)), this, SLOT(idTypeToggled(bool)));
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(updateId()));
connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(submit()));
connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
connect(ui.plainTextEdit_Tag, SIGNAL(textChanged()), this, SLOT(checkNewTag()));
connect(ui.pushButton_Tag, SIGNAL(clicked(bool)), this, SLOT(addRecognTag()));
connect(ui.toolButton_Tag1, SIGNAL(clicked(bool)), this, SLOT(rmTag1()));
connect(ui.toolButton_Tag2, SIGNAL(clicked(bool)), this, SLOT(rmTag2()));
connect(ui.toolButton_Tag3, SIGNAL(clicked(bool)), this, SLOT(rmTag3()));
connect(ui.toolButton_Tag4, SIGNAL(clicked(bool)), this, SLOT(rmTag4()));
connect(ui.toolButton_Tag5, SIGNAL(clicked(bool)), this, SLOT(rmTag5()));
mIdQueue = new TokenQueue(rsIdentity->getTokenService(), this);
ui.pushButton_Tag->setEnabled(false);
}
void IdEditDialog::setupNewId(bool pseudo)
@ -89,6 +98,10 @@ void IdEditDialog::setupNewId(bool pseudo)
// force - incase it wasn't triggered.
idTypeToggled(true);
ui.frame_Tags->setHidden(true);
ui.radioButton_GpgId->setEnabled(true);
ui.radioButton_Pseudo->setEnabled(true);
}
void IdEditDialog::idTypeToggled(bool checked)
@ -144,7 +157,6 @@ void IdEditDialog::loadExistingId(uint32_t token)
mStateHelper->setLoading(IDEDITDIALOG_LOADID, false);
/* get details from libretroshare */
RsGxsIdGroup data;
std::vector<RsGxsIdGroup> datavector;
if (!rsIdentity->getGroupData(token, datavector))
{
@ -166,9 +178,9 @@ void IdEditDialog::loadExistingId(uint32_t token)
return;
}
data = datavector[0];
mEditGroup = datavector[0];
bool realid = (data.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
bool realid = (mEditGroup.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
if (realid)
{
@ -178,25 +190,28 @@ void IdEditDialog::loadExistingId(uint32_t token)
{
ui.radioButton_Pseudo->setChecked(true);
}
// these are not editable for existing Id.
ui.radioButton_GpgId->setEnabled(false);
ui.radioButton_Pseudo->setEnabled(false);
// DOES THIS TRIGGER ALREADY???
// force - incase it wasn't triggered.
idTypeToggled(true);
ui.lineEdit_Nickname->setText(QString::fromUtf8(data.mMeta.mGroupName.c_str()));
ui.lineEdit_KeyId->setText(QString::fromStdString(data.mMeta.mGroupId));
ui.lineEdit_Nickname->setText(QString::fromUtf8(mEditGroup.mMeta.mGroupName.c_str()));
ui.lineEdit_KeyId->setText(QString::fromStdString(mEditGroup.mMeta.mGroupId));
if (realid)
{
ui.lineEdit_GpgHash->setText(QString::fromStdString(data.mPgpIdHash));
ui.lineEdit_GpgHash->setText(QString::fromStdString(mEditGroup.mPgpIdHash));
if (data.mPgpKnown)
if (mEditGroup.mPgpKnown)
{
RsPeerDetails details;
rsPeers->getGPGDetails(data.mPgpId, details);
rsPeers->getGPGDetails(mEditGroup.mPgpId, details);
ui.lineEdit_GpgName->setText(QString::fromUtf8(details.name.c_str()));
ui.lineEdit_GpgId->setText(QString::fromStdString(data.mPgpId));
ui.lineEdit_GpgId->setText(QString::fromStdString(mEditGroup.mPgpId));
}
else
{
@ -210,53 +225,216 @@ void IdEditDialog::loadExistingId(uint32_t token)
ui.lineEdit_GpgId->setText(tr("N/A"));
ui.lineEdit_GpgName->setText(tr("N/A"));
}
// RecognTags.
ui.frame_Tags->setHidden(false);
loadRecognTags();
}
void IdEditDialog::updateId()
#define MAX_RECOGN_TAGS 5
void IdEditDialog::checkNewTag()
{
RsGxsIdGroup rid;
// Must set, Nickname, KeyId(if existing), mIdType, GpgId.
std::string tag = ui.plainTextEdit_Tag->toPlainText().toStdString();
std::string id = ui.lineEdit_KeyId->text().toStdString();
std::string name = ui.lineEdit_Nickname->text().toUtf8().data();
rid.mMeta.mGroupName = ui.lineEdit_Nickname->text().toUtf8().constData();
QString desc;
bool ok = tagDetails(id, name, tag, desc);
ui.label_TagCheck->setText(desc);
if (rid.mMeta.mGroupName.size() < 2)
// hack to allow add invalid tags (for testing).
if (!tag.empty())
{
std::cerr << "IdEditDialog::updateId() Nickname too short";
ok = true;
}
if (mEditGroup.mRecognTags.size() >= MAX_RECOGN_TAGS)
{
ok = false;
}
ui.pushButton_Tag->setEnabled(ok);
}
void IdEditDialog::addRecognTag()
{
std::string tag = ui.plainTextEdit_Tag->toPlainText().toStdString();
if (mEditGroup.mRecognTags.size() >= MAX_RECOGN_TAGS)
{
std::cerr << "IdEditDialog::addRecognTag() Too many Tags, delete one first";
std::cerr << std::endl;
}
mEditGroup.mRecognTags.push_back(tag);
loadRecognTags();
}
void IdEditDialog::rmTag1()
{
rmTag(0);
}
void IdEditDialog::rmTag2()
{
rmTag(1);
}
void IdEditDialog::rmTag3()
{
rmTag(2);
}
void IdEditDialog::rmTag4()
{
rmTag(3);
}
void IdEditDialog::rmTag5()
{
rmTag(4);
}
void IdEditDialog::rmTag(int idx)
{
std::list<std::string>::iterator it;
int i = 0;
for(it = mEditGroup.mRecognTags.begin(); it != mEditGroup.mRecognTags.end() && (idx < i); it++, i++) ;
if (it != mEditGroup.mRecognTags.end())
{
mEditGroup.mRecognTags.erase(it);
}
loadRecognTags();
}
bool IdEditDialog::tagDetails(const std::string &id, const std::string &name, const std::string &tag, QString &desc)
{
if (tag.empty())
{
desc += "Empty Tag";
return false;
}
/* extract details for each tag */
RsRecognTagDetails tagDetails;
bool ok = false;
if (rsIdentity->parseRecognTag(id, name, tag, tagDetails))
{
desc += QString::number(tagDetails.tag_class);
desc += ":";
desc += QString::number(tagDetails.tag_type);
if (tagDetails.is_valid)
{
ok = true;
desc += " Valid";
}
else
{
desc += " Invalid";
}
if (tagDetails.is_pending)
{
ok = true;
desc += " Pending";
}
}
else
{
desc += "Unparseable";
}
return ok;
}
void IdEditDialog::loadRecognTags()
{
std::cerr << "IdEditDialog::loadRecognTags()";
std::cerr << std::endl;
// delete existing items.
ui.label_Tag1->setHidden(true);
ui.label_Tag2->setHidden(true);
ui.label_Tag3->setHidden(true);
ui.label_Tag4->setHidden(true);
ui.label_Tag5->setHidden(true);
ui.toolButton_Tag1->setHidden(true);
ui.toolButton_Tag2->setHidden(true);
ui.toolButton_Tag3->setHidden(true);
ui.toolButton_Tag4->setHidden(true);
ui.toolButton_Tag5->setHidden(true);
ui.plainTextEdit_Tag->setPlainText("");
int i = 0;
std::list<std::string>::const_iterator it;
for(it = mEditGroup.mRecognTags.begin(); it != mEditGroup.mRecognTags.end(); it++, i++)
{
QString recognTag;
tagDetails(mEditGroup.mMeta.mGroupId, mEditGroup.mMeta.mGroupName, *it, recognTag);
switch(i)
{
default:
case 0:
ui.label_Tag1->setText(recognTag);
ui.label_Tag1->setHidden(false);
ui.toolButton_Tag1->setHidden(false);
break;
case 1:
ui.label_Tag2->setText(recognTag);
ui.label_Tag2->setHidden(false);
ui.toolButton_Tag2->setHidden(false);
break;
case 2:
ui.label_Tag3->setText(recognTag);
ui.label_Tag3->setHidden(false);
ui.toolButton_Tag3->setHidden(false);
break;
case 3:
ui.label_Tag4->setText(recognTag);
ui.label_Tag4->setHidden(false);
ui.toolButton_Tag4->setHidden(false);
break;
case 4:
ui.label_Tag5->setText(recognTag);
ui.label_Tag5->setHidden(false);
ui.toolButton_Tag5->setHidden(false);
break;
}
}
}
void IdEditDialog::submit()
{
if (mIsNew)
{
createId();
}
else
{
updateId();
}
}
void IdEditDialog::createId()
{
std::string groupname = ui.lineEdit_Nickname->text().toUtf8().constData();
if (groupname.size() < 2)
{
std::cerr << "IdEditDialog::createId() Nickname too short";
std::cerr << std::endl;
return;
}
//rid.mIdType = RSID_RELATION_YOURSELF;
if (mIsNew)
{
rid.mMeta.mGroupId = "";
}
else
{
rid.mMeta.mGroupId = ui.lineEdit_KeyId->text().toStdString();
}
if (ui.radioButton_GpgId->isChecked())
{
//rid.mIdType |= RSID_TYPE_REALID;
//rid.mGpgId = ui.lineEdit_GpgId->text().toStdString();
rid.mPgpIdHash = ui.lineEdit_GpgHash->text().toStdString();
//rid.mGpgName = ui.lineEdit_GpgName->text().toUtf8().constData();
}
else
{
//rid.mIdType |= RSID_TYPE_PSEUDONYM;
//rid.mGpgId = "";
rid.mPgpIdHash = "";
//rid.mGpgName = "";
//rid.mGpgEmail = "";
}
// Can only create Identities for the moment!
RsIdentityParameters params;
params.nickname = rid.mMeta.mGroupName;
params.nickname = groupname;
params.isPgpLinked = (ui.radioButton_GpgId->isChecked());
uint32_t dummyToken = 0;
@ -265,6 +443,30 @@ void IdEditDialog::updateId()
close();
}
void IdEditDialog::updateId()
{
/* submit updated details */
std::string groupname = ui.lineEdit_Nickname->text().toUtf8().constData();
if (groupname.size() < 2)
{
std::cerr << "IdEditDialog::updateId() Nickname too short";
std::cerr << std::endl;
return;
}
mEditGroup.mMeta.mGroupName = groupname;
uint32_t dummyToken = 0;
rsIdentity->updateIdentity(dummyToken, mEditGroup);
close();
}
void IdEditDialog::loadRequest(const TokenQueue */*queue*/, const TokenRequest &req)
{
std::cerr << "IdDialog::loadRequest() UserType: " << req.mUserType;

View File

@ -29,6 +29,7 @@
#include <inttypes.h>
#include "util/TokenQueue.h"
#include <retroshare/rsidentity.h>
class UIStateHelper;
@ -46,16 +47,33 @@ public:
private slots:
void idTypeToggled(bool checked);
void updateId();
void submit();
void addRecognTag();
void checkNewTag();
void rmTag1();
void rmTag2();
void rmTag3();
void rmTag4();
void rmTag5();
private:
void createId();
void updateId();
void updateIdType(bool pseudo);
void loadExistingId(uint32_t token);
void loadRecognTags();
// extract details.
bool tagDetails(const std::string &id, const std::string &name, const std::string &tag, QString &desc);
void rmTag(int idx);
protected:
Ui::IdEditDialog ui;
bool mIsNew;
UIStateHelper *mStateHelper;
RsGxsIdGroup mEditGroup;
TokenQueue *mIdQueue;
};

View File

@ -6,147 +6,233 @@
<rect>
<x>0</x>
<y>0</y>
<width>557</width>
<height>179</height>
<width>510</width>
<height>595</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Nickname</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Key ID</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>PGP Hash</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_GpgHash">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>PGP Id</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>PGP Name</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="verticalSpacer_2">
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QRadioButton" name="radioButton_GpgId">
<property name="text">
<string>PGP Associated ID</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_Pseudo">
<property name="text">
<string>Pseudonym</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Nickname</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Nickname"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Key ID</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_KeyId">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>PGP Hash</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_GpgHash">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>PGP Id</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLineEdit" name="lineEdit_GpgId">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>PGP Name</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QLineEdit" name="lineEdit_GpgName">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_Tags">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label_Tag1">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QToolButton" name="toolButton_Tag1">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_Tag2">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="toolButton_Tag2">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_Tag3">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QToolButton" name="toolButton_Tag3">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_Tag4">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QToolButton" name="toolButton_Tag4">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_Tag5">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QToolButton" name="toolButton_Tag5">
<property name="text">
<string>RM</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QPlainTextEdit" name="plainTextEdit_Tag"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_TagCheck">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="pushButton_Tag">
<property name="text">
<string>Add</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<width>328</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="1">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QRadioButton" name="radioButton_GpgId">
<property name="text">
<string>PGP Associated ID</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_Pseudo">
<property name="text">
<string>Pseudonym</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>lineEdit_Nickname</tabstop>
<tabstop>lineEdit_KeyId</tabstop>
<tabstop>lineEdit_GpgHash</tabstop>
<tabstop>lineEdit_GpgId</tabstop>
<tabstop>lineEdit_GpgName</tabstop>
<tabstop>radioButton_GpgId</tabstop>
<tabstop>radioButton_Pseudo</tabstop>
<tabstop>buttonBox</tabstop>

View File

@ -148,13 +148,13 @@ void GxsGroupDialog::initMode()
{
ui.buttonBox->setStandardButtons(QDialogButtonBox::Close);
}
break;
//TODO
// case MODE_EDIT:
// {
// ui.createButton->setText(tr("Submit Changes"));
// }
// break;
break;
case MODE_EDIT:
{
ui.buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
ui.buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Submit Group Changes"));
}
break;
}
}
@ -320,14 +320,42 @@ void GxsGroupDialog::submitGroup()
break;
case MODE_EDIT:
{
/* TEMP: just close if down */
cancelDialog();
{
editGroup();
}
break;
}
}
void GxsGroupDialog::editGroup()
{
std::cerr << "GxsGroupDialog::editGroup()" << std::endl;
QString name = misc::removeNewLine(ui.groupName->text());
uint32_t flags = GXS_SERV::FLAG_PRIVACY_PUBLIC;
if(name.isEmpty())
{
/* error message */
QMessageBox::warning(this, "RetroShare", tr("Please add a Name"), QMessageBox::Ok, QMessageBox::Ok);
return; //Don't add a empty name!!
}
uint32_t token;
RsGxsGroupUpdateMeta updateMeta(mGrpMeta.mGroupId);
updateMeta.setMetaUpdate(RsGxsGroupUpdateMeta::NAME, std::string(name.toUtf8()));
if (service_EditGroup(token, updateMeta))
{
// get the Queue to handle response.
if(mTokenQueue != NULL)
mTokenQueue->queueRequest(token, TOKENREQ_GROUPINFO, RS_TOKREQ_ANSTYPE_ACK, GXSGROUP_NEWGROUPID);
}
close();
}
void GxsGroupDialog::createGroup()
{
std::cerr << "GxsGroupDialog::createGroup()";

View File

@ -163,13 +163,21 @@ protected:
void setUiText(UiType uiType, const QString &text);
/*!
* Main purpose is to help tansfer meta data to service
*
* It is up to the service to do the actual group creation
* Service can also modify initial meta going into group
* @param token This should be set to the token retrieved
* @param meta The deriving GXS service should set their grp meta to this value
*/
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta) = 0;
/*!
* It is up to the service to do the actual group editing
* TODO: make pure virtual
* @param token This should be set to the token retrieved
* @param meta The deriving GXS service should set their grp meta to this value
*/
virtual bool service_EditGroup(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta) {}
/*!
* This returns a group logo from the ui \n
* Should be calleld by deriving service
@ -202,6 +210,7 @@ private:
void setupVisibility();
void clearForm();
void createGroup();
void editGroup();
void sendShareList(std::string forumId);
void loadNewGroupId(const uint32_t &token);
@ -215,6 +224,8 @@ private:
uint32_t mReadonlyFlags;
uint32_t mDefaultsFlags;
protected:
/** Qt Designer generated object */
Ui::GxsGroupDialog ui;
};

View File

@ -67,6 +67,17 @@ bool GxsIdChooser::MakeIdDesc(const RsGxsId &id, QString &desc)
if (found)
{
desc = QString::fromUtf8(details.mNickname.c_str());
std::list<RsRecognTag>::iterator it;
for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); it++)
{
desc += " (";
desc += QString::number(it->tag_class);
desc += ":";
desc += QString::number(it->tag_type);
desc += ")";
}
if (details.mPgpLinked)
{
desc += " (PGP) [";

View File

@ -71,6 +71,16 @@ static bool MakeIdDesc(const RsGxsId &id, QString &str)
str = QString::fromUtf8(details.mNickname.c_str());
std::list<RsRecognTag>::iterator it;
for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); it++)
{
str += " (";
str += QString::number(it->tag_class);
str += ":";
str += QString::number(it->tag_type);
str += ")";
}
bool addCode = true;
if (details.mPgpLinked)
{

View File

@ -45,6 +45,17 @@ static bool MakeIdDesc(const RsGxsId &id, QString &str)
str = QString::fromUtf8(details.mNickname.c_str());
std::list<RsRecognTag>::iterator it;
for(it = details.mRecognTags.begin(); it != details.mRecognTags.end(); it++)
{
str += " (";
str += QString::number(it->tag_class);
str += ":";
str += QString::number(it->tag_type);
str += ")";
}
bool addCode = true;
if (details.mPgpLinked)
{

View File

@ -52,6 +52,13 @@ const uint32_t ForumCreateDefaultsFlags = ( GXS_GROUP_DEFAULTS_DISTRIB_PUBLIC
GXS_GROUP_DEFAULTS_COMMENTS_NO |
0);
const uint32_t ForumEditEnabledFlags = ( GXS_GROUP_FLAGS_ICON |
GXS_GROUP_FLAGS_DESCRIPTION |
0);
const uint32_t ForumEditDefaultsFlags = 0;
GxsForumGroupDialog::GxsForumGroupDialog(TokenQueue *tokenQueue, QWidget *parent)
:GxsGroupDialog(tokenQueue, ForumCreateEnabledFlags, ForumCreateDefaultsFlags, parent)
{
@ -88,8 +95,17 @@ bool GxsForumGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMeta
// Specific Function.
RsGxsForumGroup grp;
grp.mMeta = meta;
//grp.mDescription = std::string(desc.toUtf8());
grp.mDescription = std::string(ui.groupDesc->toPlainText().toUtf8());
rsGxsForums->createGroup(token, grp);
return true;
}
bool GxsForumGroupDialog::service_EditGroup(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta)
{
RsGxsForumGroup grp;
grp.mDescription = std::string(ui.groupDesc->toPlainText().toUtf8());
rsGxsForums->updateGroup(token, updateMeta, grp);
return true;
}

View File

@ -37,6 +37,7 @@ protected:
virtual void initUi();
virtual QPixmap serviceImage();
virtual bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta);
virtual bool service_EditGroup(uint32_t &token, RsGxsGroupUpdateMeta &updateMeta);
};
#endif

View File

@ -193,8 +193,10 @@ macx {
gxs {
LIBS += ../../supportlibs/pegmarkdown/lib/libpegmarkdown.a
LIBS += ../../../lib/libsqlcipher.a
#LIBS += -lsqlite3
}