diff --git a/libretroshare/src/gxs/rsdataservice.h b/libretroshare/src/gxs/rsdataservice.h index 4daa24111..7a8a8fb25 100644 --- a/libretroshare/src/gxs/rsdataservice.h +++ b/libretroshare/src/gxs/rsdataservice.h @@ -6,7 +6,7 @@ * * General Data service, interface for RetroShare. * - * Copyright 2011-2011 by Evi-Parker Christopher + * Copyright 2011-2012 by Evi-Parker Christopher * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public diff --git a/libretroshare/src/gxs/rsgenexchange.cc b/libretroshare/src/gxs/rsgenexchange.cc index 4e04d7788..7096fd9dd 100644 --- a/libretroshare/src/gxs/rsgenexchange.cc +++ b/libretroshare/src/gxs/rsgenexchange.cc @@ -154,7 +154,7 @@ bool RsGenExchange::acknowledgeTokenGrp(const uint32_t& token, return true; } -void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) +void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys) { /* create Keys */ @@ -162,85 +162,96 @@ void RsGenExchange::generateGroupKeys(RsTlvSecurityKeySet& keySet) RSA *rsa_admin = RSA_generate_key(2048, 65537, NULL, NULL); RSA *rsa_admin_pub = RSAPublicKey_dup(rsa_admin); - // publish keys - RSA *rsa_publish = RSA_generate_key(2048, 65537, NULL, NULL); - RSA *rsa_publish_pub = RSAPublicKey_dup(rsa_admin); - - /* set keys */ + /* set admin keys */ RsTlvSecurityKey adminKey, privAdminKey; - /* set publish keys */ - RsTlvSecurityKey pubKey, privPubKey; - GxsSecurity::setRSAPublicKey(adminKey, rsa_admin_pub); GxsSecurity::setRSAPrivateKey(privAdminKey, rsa_admin); - GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub); - GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish); - adminKey.startTS = time(NULL); adminKey.endTS = 0; /* no end */ privAdminKey.startTS = adminKey.startTS; privAdminKey.endTS = 0; /* no end */ - pubKey.startTS = adminKey.startTS; - pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */ - - privPubKey.startTS = adminKey.startTS; - privPubKey.endTS = 0; /* no end */ - // for now all public adminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY; privAdminKey.keyFlags = RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL; - // for now all public - pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; - privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL; - keySet.keys[adminKey.keyId] = adminKey; - keySet.keys[pubKey.keyId] = pubKey; - keySet.keys[privAdminKey.keyId] = privAdminKey; - keySet.keys[privPubKey.keyId] = privPubKey; // clean up RSA_free(rsa_admin); RSA_free(rsa_admin_pub); - RSA_free(rsa_publish); - RSA_free(rsa_publish_pub); + if(genPublishKeys) + { + // publish keys + RSA *rsa_publish = RSA_generate_key(2048, 65537, NULL, NULL); + RSA *rsa_publish_pub = RSAPublicKey_dup(rsa_publish); + + /* set publish keys */ + RsTlvSecurityKey pubKey, privPubKey; + + GxsSecurity::setRSAPublicKey(pubKey, rsa_publish_pub); + GxsSecurity::setRSAPrivateKey(privPubKey, rsa_publish); + + pubKey.startTS = adminKey.startTS; + pubKey.endTS = pubKey.startTS + 60 * 60 * 24 * 365 * 5; /* approx 5 years */ + + privPubKey.startTS = adminKey.startTS; + privPubKey.endTS = 0; /* no end */ + + // for now all public + pubKey.keyFlags = RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY; + privPubKey.keyFlags = RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL; + + keySet.keys[pubKey.keyId] = pubKey; + keySet.keys[privPubKey.keyId] = privPubKey; + + RSA_free(rsa_publish); + RSA_free(rsa_publish_pub); + } + } bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) { - std::cerr << "RsGenExchange::createGroup()"; - std::cerr << std::endl; - + std::cerr << "RsGenExchange::createGroup()"; + std::cerr << std::endl; RsGxsGrpMetaData* meta = grp->metaData; - /* add keys to grp */ - meta->keys = keySet; + /* add public admin and publish keys to grp */ // find private admin key RsTlvSecurityKey privAdminKey; std::map::iterator mit = keySet.keys.begin(); + bool privKeyFound = false; for(; mit != keySet.keys.end(); mit++) { - RsTlvSecurityKey& pk = mit->second; + RsTlvSecurityKey& key = mit->second; - if(pk.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + // add public admin key + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_PUBLIC_ONLY)) + meta->keys.keys.insert(std::make_pair(key.keyId, key)); + + // add public publish key + if(key.keyFlags & (RSTLV_KEY_DISTRIB_PUBLIC | RSTLV_KEY_TYPE_PUBLIC_ONLY)) + meta->keys.keys.insert(std::make_pair(key.keyId, key)); + + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) { - privAdminKey = pk; - break; + privAdminKey = key; + privKeyFound = true; } } - if(mit == keySet.keys.end()) + if(!privKeyFound) { - std::cerr << "RsGenExchange::createGroup() Missing ADMIN Key"; + std::cerr << "RsGenExchange::createGroup() Missing private ADMIN Key"; std::cerr << std::endl; return false; @@ -248,8 +259,7 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) // group is self signing // for the creation of group signature - // only public admin and publish keys are present - // key set + // only public admin and publish keys are present in meta uint32_t metaDataLen = meta->serial_size(); uint32_t allGrpDataLen = metaDataLen + grp->grp.bin_len; char* metaData = new char[metaDataLen]; @@ -267,7 +277,14 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) // add admin sign to grpMeta meta->signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_ADMIN] = adminSign; - grp->grpId = meta->mGroupId = privAdminKey.keyId; + // set meta to be transported as meta without private + // key components + grp->meta.setBinData(metaData, metaDataLen); + + // but meta that is stored locally + // has all keys + // nxs net transports only bin data + meta->keys = keySet; // clean up delete[] allGrpData; @@ -282,6 +299,167 @@ bool RsGenExchange::createGroup(RsNxsGrp *grp, RsTlvSecurityKeySet& keySet) return ok; } +bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData, + const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta) +{ + bool isParent = false; + bool needPublishSign, needIdentitySign; + bool ok = true; + uint32_t grpFlag = grpMeta.mGroupFlags; + + // publish signature is determined by whether group is public or not + // for private group signature is not needed as it needs decrypting with + // the private publish key anyways + + // restricted is a special case which heeds whether publish sign needs to be checked or not + // one may or may not want + + if(msgMeta.mParentId.empty()) + { + isParent = true; + } + else + { + isParent = false; + } + + + if(isParent) + { + needIdentitySign = false; + needPublishSign = false; + + if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + needIdentitySign = true; + + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) + { + needPublishSign = true; + + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + needIdentitySign = true; + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_ROOT_AUTHOR_SIGN)) + needIdentitySign = true; + } + + }else + { + if(grpFlag & GXS_SERV::FLAG_PRIVACY_PUBLIC) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PUBLIC_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + needIdentitySign = true; + + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_RESTRICTED) + { + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_PUBLISH_SIGN)) + needPublishSign = true; + + if(checkMsgAuthenFlag(RESTRICTED_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + needIdentitySign = true; + } + else if(grpFlag & GXS_SERV::FLAG_PRIVACY_PRIVATE) + { + needPublishSign = false; + + if(checkMsgAuthenFlag(PRIVATE_GRP_BITS, GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN)) + needIdentitySign = true; + } + } + + if(needPublishSign) + { + + // public and shared is publish key + RsTlvSecurityKeySet& keys = grpMeta.keys; + RsTlvSecurityKey* pubKey; + + std::map::iterator mit = + keys.keys.begin(), mit_end = keys.keys.end(); + bool pub_key_found = false; + for(; mit != mit_end; mit++) + { + + pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); + if(pub_key_found) + break; + } + + // private publish key + pubKey = &(mit->second); + + RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + + ok &= GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, pubKey, pubSign); + + //place signature in msg meta + signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = pubSign; + } + + + if(needIdentitySign) + { + if(mGixs) + { + bool haveKey = mGixs->havePrivateKey(msgMeta.mAuthorId); + + if(haveKey) + { + mGixs->requestPrivateKey(msgMeta.mAuthorId); + + RsTlvSecurityKey authorKey; + + double timeDelta = 0.002; // fast polling + time_t now = time(NULL); + + // poll immediately but, don't spend more than a second polling + while( (mGixs->getPrivateKey(msgMeta.mAuthorId, authorKey) == -1) && + ((now + 1) >> time(NULL)) + ) + { + #ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); + #else + Sleep((int) (timeDelta * 1000)); + #endif + } + + + RsTlvKeySignature sign; + ok &= GxsSecurity::getSignature((char*)msgData.bin_data, msgData.bin_len, + &authorKey, sign); + signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_IDENTITY] = sign; + + }else + { + ok = false; + } + } + else + { +#ifdef GEN_EXHANGE_DEBUG + std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; +#endif + } + } + + return ok; + + +} + bool RsGenExchange::createMessage(RsNxsMsg* msg) { const RsGxsGroupId& id = msg->grpId; @@ -290,78 +468,48 @@ bool RsGenExchange::createMessage(RsNxsMsg* msg) metaMap.insert(std::make_pair(id, (RsGxsGrpMetaData*)(NULL))); mDataStore->retrieveGxsGrpMetaData(metaMap); - bool ok = true; - RSA* rsa_pub = NULL; + bool ok = true; + RsGxsMsgMetaData &meta = *(msg->metaData); if(!metaMap[id]) { - return false; + return false; } else { - // get publish key - RsGxsGrpMetaData* grpMeta = metaMap[id]; + // get publish key + RsGxsGrpMetaData* grpMeta = metaMap[id]; - // public and shared is publish key - RsTlvSecurityKeySet& keys = grpMeta->keys; - RsTlvSecurityKey* pubKey; + uint32_t metaDataLen = meta.serial_size(); + uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; + char* metaData = new char[metaDataLen]; + char* allMsgData = new char[allMsgDataLen]; // msgData + metaData - std::map::iterator mit = - keys.keys.begin(), mit_end = keys.keys.end(); - bool pub_key_found = false; - for(; mit != mit_end; mit++) - { + meta.serialise(metaData, &metaDataLen); - pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL); - if(pub_key_found) - break; - } + // copy msg data and meta in allmsgData buffer + memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); + memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); - if(pub_key_found) - { - RsGxsMsgMetaData &meta = *(msg->metaData); + RsTlvBinaryData msgData(0); - uint32_t metaDataLen = meta.serial_size(); - uint32_t allMsgDataLen = metaDataLen + msg->msg.bin_len; - char* metaData = new char[metaDataLen]; - char* allMsgData = new char[allMsgDataLen]; // msgData + metaData + msgData.setBinData(allMsgData, allMsgDataLen); - meta.serialise(metaData, &metaDataLen); + // create signatures + ok &= createMsgSignatures(meta.signSet, msgData, meta, *grpMeta); - // copy msg data and meta in allmsgData buffer - memcpy(allMsgData, msg->msg.bin_data, msg->msg.bin_len); - memcpy(allMsgData+(msg->msg.bin_len), metaData, metaDataLen); + // get hash of msg data to create msg id + pqihash hash; + hash.addData(allMsgData, allMsgDataLen); + hash.Complete(msg->msgId); - // private publish key - pubKey = &(mit->second); + // assign msg id to msg meta + msg->metaData->mMsgId = msg->msgId; - RsTlvKeySignatureSet& signSet = meta.signSet; - RsTlvKeySignature pubSign = signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + delete[] metaData; + delete[] allMsgData; - GxsSecurity::getSignature(allMsgData, allMsgDataLen, pubKey, pubSign); - - // get hash of msg data to create msg id - pqihash hash; - hash.addData(allMsgData, allMsgDataLen); - hash.Complete(msg->msgId); - - // assign msg id to msg meta - msg->metaData->mMsgId = msg->msgId; - - //place signature in msg meta - signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH] = pubSign; - - // clean up - - delete[] metaData; - delete[] allMsgData; - } - else - { - ok = false; - } - - delete grpMeta; + delete grpMeta; } return ok; @@ -382,11 +530,11 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec if(msg->metaData->mParentId.empty()) { - isParent = false; + isParent = true; } else { - isParent = true; + isParent = false; } @@ -464,37 +612,49 @@ bool RsGenExchange::validateMsg(RsNxsMsg *msg, const uint32_t& grpFlag, RsTlvSec } + if(checkIdentitySign) { - bool haveKey = mGixs->haveKey(metaData.mAuthorId); - - if(haveKey) + if(mGixs) { - std::list peers; - mGixs->requestKey(metaData.mAuthorId, peers); + bool haveKey = mGixs->haveKey(metaData.mAuthorId); - RsTlvSecurityKey authorKey; - - double timeDelta = 0.002; // fast polling - time_t now = time(NULL); - // poll immediately but, don't spend more than a second polling - while( (mGixs->getKey(metaData.mAuthorId, authorKey) == -1) && - ((now + 1) >> time(NULL)) - ) + if(haveKey) { -#ifndef WINDOWS_SYS - usleep((int) (timeDelta * 1000000)); -#else - Sleep((int) (timeDelta * 1000)); -#endif - } + std::list peers; + mGixs->requestKey(metaData.mAuthorId, peers); - RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; - valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); - }else + RsTlvSecurityKey authorKey; + + double timeDelta = 0.002; // fast polling + time_t now = time(NULL); + // poll immediately but, don't spend more than a second polling + while( (mGixs->getKey(metaData.mAuthorId, authorKey) == -1) && + ((now + 1) >> time(NULL)) + ) + { + #ifndef WINDOWS_SYS + usleep((int) (timeDelta * 1000000)); + #else + Sleep((int) (timeDelta * 1000)); + #endif + } + + RsTlvKeySignature sign = metaData.signSet.keySignSet[GXS_SERV::FLAG_AUTHEN_PUBLISH]; + valid &= GxsSecurity::validateNxsMsg(*msg, sign, authorKey); + }else + { + valid = false; + } + } + else { +#ifdef GEN_EXHANGE_DEBUG + std::cerr << "Gixs not enabled while request identity signature validation!" << std::endl; +#endif valid = false; } + } return valid; @@ -956,91 +1116,114 @@ void RsGenExchange::service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeyS void RsGenExchange::publishGrps() { - RsStackMutex stack(mGenMtx); + RsStackMutex stack(mGenMtx); - std::map::iterator mit = mGrpsToPublish.begin(); - std::vector toRemove; - int i = 0; - for(; mit != mGrpsToPublish.end(); mit++) - { - toRemove.push_back(mit->first); - i++; - if(i > GEN_EXCH_GRP_CHUNK) break; + std::map::iterator mit = mGrpsToPublish.begin(); + std::vector toRemove; + int i = 0; + for(; mit != mGrpsToPublish.end(); mit++) + { + toRemove.push_back(mit->first); + i++; + if(i > GEN_EXCH_GRP_CHUNK) break; - RsNxsGrp* grp = new RsNxsGrp(mServType); - RsGxsGrpItem* grpItem = mit->second; + RsNxsGrp* grp = new RsNxsGrp(mServType); + RsGxsGrpItem* grpItem = mit->second; - RsTlvSecurityKeySet keySet; - generateGroupKeys(keySet); + RsTlvSecurityKeySet keySet; + generateGroupKeys(keySet, + !(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC)); - service_CreateGroup(grpItem, keySet); + // find private admin key + RsTlvSecurityKey privAdminKey; + std::map::iterator mit_keys = keySet.keys.begin(); - uint32_t size = mSerialiser->size(grpItem); - char gData[size]; - bool ok = mSerialiser->serialise(grpItem, gData, &size); - if (!ok) - { - std::cerr << "RsGenExchange::publishGrps() !ok ERROR After First Serialise" << std::endl; - } + bool privKeyFound = false; + for(; mit_keys != keySet.keys.end(); mit_keys++) + { + RsTlvSecurityKey& key = mit_keys->second; - grp->grp.setBinData(gData, size); - - if(ok) + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) { - grp->metaData = new RsGxsGrpMetaData(); - grpItem->meta.mPublishTs = time(NULL); - *(grp->metaData) = grpItem->meta; - grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; - ok &= createGroup(grp, keySet); - if (!ok) - { - std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl; - } + privAdminKey = key; + privKeyFound = true; + } + } - size = grp->metaData->serial_size(); - char mData[size]; - grp->metaData->mGroupId = grp->grpId; - ok &= grp->metaData->serialise(mData, size); - if (!ok) - { - std::cerr << "RsGenExchange::publishGrps() !ok ERROR After Meta Serialise" << std::endl; - } + bool ok = true; - grp->meta.setBinData(mData, size); - RsGxsGroupId grpId = grp->grpId; - mDataAccess->addGroupData(grp); + if(privKeyFound) + { + // get group id from private admin key id + grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId; + } + else + { + ok = false; + } - std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl; - // add to published to allow acknowledgement - mGrpNotify.insert(std::make_pair(mit->first, grpId)); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); + service_CreateGroup(grpItem, keySet); + + uint32_t size = mSerialiser->size(grpItem); + char gData[size]; + ok = mSerialiser->serialise(grpItem, gData, &size); + + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After First Serialise" << std::endl; + } + + grp->grp.setBinData(gData, size); + + if(ok) + { + grp->metaData = new RsGxsGrpMetaData(); + grpItem->meta.mPublishTs = time(NULL); + *(grp->metaData) = grpItem->meta; + grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; + + ok &= createGroup(grp, keySet); + + if (!ok) + { + std::cerr << "RsGenExchange::publishGrps() !ok ERROR After createGroup" << std::endl; } - if(!ok) - { + RsGxsGroupId grpId = grp->grpId; + mDataAccess->addGroupData(grp); + + std::cerr << "RsGenExchange::publishGrps() ok -> pushing to notifies" << std::endl; + + // add to published to allow acknowledgement + mGrpNotify.insert(std::make_pair(mit->first, grpId)); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE); + } + + if(!ok) + { #ifdef GEN_EXCH_DEBUG #endif - std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; - delete grp; + std::cerr << "RsGenExchange::publishGrps() failed to publish grp " << std::endl; + delete grp; - // add to published to allow acknowledgement, grpid is empty as grp creation failed - mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); - mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); - continue; - } + // add to published to allow acknowledgement, grpid is empty as grp creation failed + mGrpNotify.insert(std::make_pair(mit->first, RsGxsGroupId(""))); + mDataAccess->updatePublicRequestStatus(mit->first, RsTokenService::GXS_REQUEST_V2_STATUS_FAILED); + continue; + } - delete grpItem; + delete grpItem; - } + } - // clear grp list as we're done publishing them and entries - // are invalid + // clear grp list as we're done publishing them and entries + // are invalid - for(int i = 0; i < toRemove.size(); i++) - mGrpsToPublish.erase(toRemove[i]); + for(int i = 0; i < toRemove.size(); i++) + mGrpsToPublish.erase(toRemove[i]); } @@ -1090,33 +1273,54 @@ bool RsGenExchange::getGroupKeys(const RsGxsGroupId &grpId, RsTlvSecurityKeySet void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem) { - RsStackMutex stack(mGenMtx); - RsNxsGrp* grp = new RsNxsGrp(mServType); uint32_t size = mSerialiser->size(grpItem); char gData[size]; bool ok = mSerialiser->serialise(grpItem, gData, &size); grp->grp.setBinData(gData, size); - RsTlvSecurityKeySet keySet; - generateGroupKeys(keySet); + RsTlvSecurityKeySet keySet; + generateGroupKeys(keySet, + !(grpItem->meta.mGroupFlags & GXS_SERV::FLAG_PRIVACY_PUBLIC)); - service_CreateGroup(grpItem, keySet); + // find private admin key + RsTlvSecurityKey privAdminKey; + std::map::iterator mit_keys = keySet.keys.begin(); + + bool privKeyFound = false; + for(; mit_keys != keySet.keys.end(); mit_keys++) + { + RsTlvSecurityKey& key = mit_keys->second; + + if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL)) + { + privAdminKey = key; + privKeyFound = true; + } + } + + + if(privKeyFound) + { + // get group id from private admin key id + grpItem->meta.mGroupId = grp->grpId = privAdminKey.keyId; + } + else + { + ok = false; + } + + service_CreateGroup(grpItem, keySet); if(ok) { grp->metaData = new RsGxsGrpMetaData(); grpItem->meta.mPublishTs = time(NULL); *(grp->metaData) = grpItem->meta; - grp->metaData->mSubscribeFlags = ~GXS_SERV::GROUP_SUBSCRIBE_MASK; + grp->metaData->mSubscribeFlags = GXS_SERV::GROUP_SUBSCRIBE_ADMIN; createGroup(grp, keySet); - size = grp->metaData->serial_size(); - char mData[size]; - grp->metaData->mGroupId = grp->grpId; - ok = grp->metaData->serialise(mData, size); - grp->meta.setBinData(mData, size); mDataAccess->addGroupData(grp); } diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index 232deab1b..73169dc58 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -384,7 +384,8 @@ private: /*! * This completes the creation of an instance on RsNxsGrp - * by assigning it a groupId and signature via SHA1 and EVP_sign respectively + * by assigning it a groupId and signature via SHA1 and EVP_sign respectively \n + * Meta is serialised and stored in group at this point also * @param grp Nxs group to create */ bool createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& keySet); @@ -398,6 +399,16 @@ private: */ bool createMessage(RsNxsMsg* msg); + /*! + * convenience function to create sign + * @param signSet signatures are stored here + * @param msgData message data to be signed + * @param grpMeta the meta data for group the message belongs to + * @return false if signature creation for any required signature fails, true otherwise + */ + bool createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBinaryData& msgData, + const RsGxsMsgMetaData& msgMeta, RsGxsGrpMetaData& grpMeta); + /*! * check meta change is legal * @return false if meta change is not legal @@ -407,8 +418,9 @@ private: /*! * Generate a set of keys that can define a GXS group * @param keySet this is set generated keys + * @param genPublicKeys should public keys also be generated */ - void generateGroupKeys(RsTlvSecurityKeySet& keySet); + void generateGroupKeys(RsTlvSecurityKeySet& keySet, bool genPublishKeys); /*! * Attempts to validate msg @@ -419,8 +431,16 @@ private: */ bool validateMsg(RsNxsMsg* msg, const uint32_t& grpFlag, RsTlvSecurityKeySet& grpKeySet); + /*! + * Checks flag against a given privacy bit block + * @param pos Determines 8 bit wide privacy block to check + * @param flag the flag to and(&) against + * @param the result of the (bit-block & flag) + */ bool checkMsgAuthenFlag(const PrivacyBitPos& pos, const uint8_t& flag) const; + void groupShareKeys(std::list peers); + private: RsMutex mGenMtx; diff --git a/libretroshare/src/gxs/rsgxsnetservice.cc b/libretroshare/src/gxs/rsgxsnetservice.cc index f1a60973c..b572c3336 100644 --- a/libretroshare/src/gxs/rsgxsnetservice.cc +++ b/libretroshare/src/gxs/rsgxsnetservice.cc @@ -363,8 +363,8 @@ void RsGxsNetService::run(){ bool RsGxsNetService::locked_checkTransacTimedOut(NxsTransaction* tr) { - // return tr->mTimeOut < ((uint32_t) time(NULL)); - return false; + return tr->mTimeOut < ((uint32_t) time(NULL)); + // return false; } void RsGxsNetService::processTransactions(){ @@ -1022,7 +1022,7 @@ void RsGxsNetService::locked_genSendMsgsTransaction(NxsTransaction* tr) uint32_t transN = locked_getTransactionId(); - // store grp items to send in transaction + // store msg items to send in transaction GxsMsgResult::iterator mit = msgs.begin(); std::string peerId = tr->mTransaction->PeerId(); uint32_t msgSize = 0; diff --git a/libretroshare/src/pqi/pqihash.h b/libretroshare/src/pqi/pqihash.h index 7bf3cd506..7e08868ff 100644 --- a/libretroshare/src/pqi/pqihash.h +++ b/libretroshare/src/pqi/pqihash.h @@ -23,6 +23,9 @@ * */ +#ifndef PQI_HASH_ +#define PQI_HASH_ + #include #include #include @@ -86,4 +89,4 @@ void Complete(std::string &hash) SHA_CTX *sha_ctx; }; - +#endif diff --git a/libretroshare/src/retroshare/rsposted.h b/libretroshare/src/retroshare/rsposted.h index a1324e468..c5becb9ff 100644 --- a/libretroshare/src/retroshare/rsposted.h +++ b/libretroshare/src/retroshare/rsposted.h @@ -42,6 +42,7 @@ class RsPostedGroup { public: RsGroupMetaData mMeta; + std::string mDescription; RsPostedGroup() { return; } }; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 240a5b1f2..ee455565f 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -2329,6 +2329,11 @@ int RsServer::StartupRetroShare() RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, RsGenExchange::RESTRICTED_GRP_BITS); +// Re-enable later, photo not using gixs yet +// flag = GXS_SERV::MSG_AUTHEN_CHILD_AUTHOR_SIGN; +// RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, +// RsGenExchange::RESTRICTED_GRP_BITS); + flag = GXS_SERV::GRP_OPTION_AUTHEN_AUTHOR_SIGN; RsGenExchange::setAuthenPolicyFlag(flag, photoAuthenPolicy, RsGenExchange::GRP_OPTION_BITS); diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 381c78e93..1a7f72fcd 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -70,7 +70,7 @@ public: RsNxsItem(uint16_t servtype, uint8_t subtype) : RsItem(RS_PKT_VERSION_SERVICE, servtype, subtype), transactionNumber(0) { - setPriorityLevel(QOS_PRIORITY_RS_GXS_NET); + setPriorityLevel(QOS_PRIORITY_RS_VOIP_PING); return; } diff --git a/libretroshare/src/services/p3photoserviceV2.cc b/libretroshare/src/services/p3photoserviceV2.cc index 82d871d8f..febb7e44b 100644 --- a/libretroshare/src/services/p3photoserviceV2.cc +++ b/libretroshare/src/services/p3photoserviceV2.cc @@ -90,8 +90,10 @@ p3PhotoServiceV2::p3PhotoServiceV2(RsGeneralDataService* gds, RsNetworkExchangeS RsGxsPhotoAlbumItem* item1 = new RsGxsPhotoAlbumItem(), *item2 = new RsGxsPhotoAlbumItem(); item1->meta.mGroupName = "Dummy Album 1"; + item1->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; item1->album.mCaption = "Dummy 1"; item2->meta.mGroupName = "Dummy Album 2"; + item2->meta.mGroupFlags = GXS_SERV::FLAG_PRIVACY_RESTRICTED; item2->album.mCaption = "Dummy 2"; createDummyGroup(item1); diff --git a/libretroshare/src/tests/gxs/nxstestscenario.cc b/libretroshare/src/tests/gxs/nxstestscenario.cc index e6973cf0c..73a720c36 100644 --- a/libretroshare/src/tests/gxs/nxstestscenario.cc +++ b/libretroshare/src/tests/gxs/nxstestscenario.cc @@ -7,6 +7,7 @@ #include "nxstestscenario.h" #include "gxs/rsdataservice.h" +#include "gxs/rsgxsflags.h" #include "data_support.h" #include @@ -147,6 +148,8 @@ void NxsMessageTestObserver::notifyNewGroups(std::vector &groups) { RsNxsGrp* grp = *vit; RsGxsGrpMetaData* meta = new RsGxsGrpMetaData(); + meta->deserialise(grp->meta.bin_data, grp->meta.bin_len); + meta->mSubscribeFlags |= GXS_SERV::GROUP_SUBSCRIBE_SUBSCRIBED; meta->mGroupId = grp->grpId; grps.insert(std::make_pair(grp, meta)); } diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp index c39825bdf..4d9234ee8 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.cpp @@ -2,6 +2,7 @@ #include "AlbumDialog.h" #include "ui_AlbumDialog.h" +#include "gxs/rsgxsflags.h" AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPhotoV2* rs_Photo, QWidget *parent) : QDialog(parent), @@ -13,6 +14,12 @@ AlbumDialog::AlbumDialog(const RsPhotoAlbum& album, TokenQueue* photoQueue, RsPh connect(ui->pushButton_DeletePhoto, SIGNAL(clicked()), this, SLOT(deletePhoto())); mPhotoDrop = ui->scrollAreaWidgetContents; + + if(!(mAlbum.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN)) + { + ui->scrollAreaPhotos->setEnabled(false); + ui->pushButton_DeletePhoto->setEnabled(false); + } mPhotoDrop->setPhotoItemHolder(this); setUp(); @@ -32,6 +39,7 @@ void AlbumDialog::setUp() } void AlbumDialog::updateAlbumPhotos(){ + QSet photos; mPhotoDrop->getPhotos(photos); diff --git a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui index b5568d690..5d42b38cf 100644 --- a/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui +++ b/retroshare-gui/src/gui/PhotoShare/AlbumDialog.ui @@ -285,7 +285,7 @@ p, li { white-space: pre-wrap; } 0 0 627 - 107 + 116 @@ -344,7 +344,7 @@ p, li { white-space: pre-wrap; } - Publish Photos + Publish Photos / Close diff --git a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp index 9c89cd4bf..e471859f5 100644 --- a/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp +++ b/retroshare-gui/src/gui/PhotoShare/PhotoDialog.cpp @@ -2,7 +2,7 @@ #include #include "PhotoDialog.h" #include "ui_PhotoDialog.h" - +#include "retroshare/rsidentity.h" #include "AddCommentDialog.h" PhotoDialog::PhotoDialog(RsPhotoV2 *rs_photo, const RsPhotoPhoto &photo, QWidget *parent) : @@ -37,8 +37,6 @@ void PhotoDialog::setUp() ui->label_Photo->setPixmap(qtn); ui->lineEdit_Title->setText(QString::fromStdString(mPhotoDetails.mMeta.mMsgName)); - //ui->scrollAreaWidgetContents->setLayout(new QVBoxLayout()); - requestComments(); } diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp index 358ab9ef6..71381fb84 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.cpp @@ -56,21 +56,13 @@ bool PostedGroupDialog::service_CreateGroup(uint32_t &token, const RsGroupMetaDa { // Specific Function. RsPostedGroup grp; + grp.mDescription = getDescription().toStdString(); grp.mMeta = meta; rsPosted->submitGroup(token, grp); return true; } -QPixmap PostedGroupDialog::service_getLogo() -{ - return QPixmap(); // null pixmap -} - -QString PostedGroupDialog::service_getDescription() -{ - return QString(); -} diff --git a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h index 09dac9043..187f1416d 100644 --- a/retroshare-gui/src/gui/Posted/PostedGroupDialog.h +++ b/retroshare-gui/src/gui/Posted/PostedGroupDialog.h @@ -46,19 +46,6 @@ protected: bool service_CreateGroup(uint32_t &token, const RsGroupMetaData &meta); - /*! - * This should return a group logo \n - * Will be called when GxsGroupDialog is initialised in show mode - * - */ - virtual QPixmap service_getLogo(); - - /*! - * This should return a group description string - * @return group description string - */ - virtual QString service_getDescription(); - private: RsPostedGroup mGrp; diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp index ca987bbe1..29f428486 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.cpp @@ -399,7 +399,15 @@ void GxsGroupDialog::addGroupLogo() ui.groupLogo->setIcon(picture); } +QPixmap GxsGroupDialog::getLogo() +{ + return picture; +} +QString GxsGroupDialog::getDescription() +{ + return ui.groupDesc->document()->toPlainText(); +} /*********************************************************************************** Share Lists. diff --git a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h index b318b7863..a417621e5 100644 --- a/retroshare-gui/src/gui/gxs/GxsGroupDialog.h +++ b/retroshare-gui/src/gui/gxs/GxsGroupDialog.h @@ -149,24 +149,24 @@ protected: /*! * Main purpose is to help tansfer meta data to service - * and also + * * @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; /*! - * This should return a group logo \n - * Will be called when GxsGroupDialog is initialised in show mode + * This returns a group logo from the ui \n + * Should be calleld by deriving service * @return The logo for the service */ - virtual QPixmap service_getLogo() = 0; + QPixmap getLogo(); /*! - * This should return a group description string + * This returns a group description string from the ui * @return group description string */ - virtual QString service_getDescription() = 0; + virtual QString getDescription(); private slots: