Merge pull request #2251 from csoler/v0.6-BugFixing_7

Additional fixes for 0.6.6
This commit is contained in:
csoler 2021-01-30 19:55:01 +01:00 committed by GitHub
commit 70a536b13e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 202 additions and 141 deletions

View File

@ -1066,8 +1066,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
}
bool p3PeerMgrIMPL::addSslOnlyFriend(
const RsPeerId& sslId, const RsPgpId& pgp_id, const RsPeerDetails& dt )
bool p3PeerMgrIMPL::addSslOnlyFriend( const RsPeerId& sslId, const RsPgpId& pgp_id, const RsPeerDetails& dt )
{
constexpr auto fname = __PRETTY_FUNCTION__;
const auto failure = [&](const std::string& err)
@ -2435,7 +2434,6 @@ void p3PeerMgrIMPL::saveDone()
bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
{
// DEFAULTS.
bool useExtAddrFinder = true;
std::string proxyIpAddressTor = kConfigDefaultProxyServerIpAddr;
@ -2684,13 +2682,31 @@ bool p3PeerMgrIMPL::loadList(std::list<RsItem *>& load)
groupList[info.id] = info;
}
// Also filter out profiles in groups that are not friends. Normally this shouldn't be needed, but it's a precaution
for(auto group_pair:groupList)
{
for(auto profileIdIt(group_pair.second.peerIds.begin());profileIdIt!=group_pair.second.peerIds.end();)
if(AuthGPG::getAuthGPG()->isGPGAccepted(*profileIdIt) || *profileIdIt == AuthGPG::getAuthGPG()->getGPGOwnId())
++profileIdIt;
else
{
std::cerr << "(WW) filtering out profile " << profileIdIt->toStdString() << " from group " << group_pair.first.toStdString() << " because it is not a friend anymore" << std::endl;
auto tmp = profileIdIt;
++tmp;
group_pair.second.peerIds.erase(profileIdIt);
profileIdIt=tmp;
IndicateConfigChanged();
}
}
}
// If we are hidden - don't want ExtAddrFinder - ever!
if (isHidden())
{
useExtAddrFinder = false;
}
mNetMgr->setIPServersEnabled(useExtAddrFinder);

View File

@ -47,6 +47,7 @@
* #define DEBUG_IDS 1
* #define DEBUG_RECOGN 1
* #define DEBUG_OPINION 1
* #define DEBUG_SERVICE_STRING 1
* #define GXSID_GEN_DUMMY_DATA 1
****/
@ -102,6 +103,7 @@ RsIdentity* rsIdentity = nullptr;
#define GXSIDREQ_RECOGN 0x0020
#define GXSIDREQ_OPINION 0x0030
#define GXSIDREQ_SERIALIZE_TO_MEMORY 0x0040
#define GXSIDREQ_LOAD_PGPIDDATA 0x0080
#define GXSIDREQ_CACHETEST 0x1000
@ -166,6 +168,7 @@ p3IdService::p3IdService( RsGeneralDataService *gds
, mMaxKeepKeysBanned(MAX_KEEP_KEYS_BANNED_DEFAULT)
{
mLastKeyCleaningTime = time(NULL) - int(MAX_DELAY_BEFORE_CLEANING * 0.9) ;
mLastPGPHashProcessTime = 0;
// Kick off Cache Testing, + Others.
RsTickEvent::schedule_now(GXSID_EVENT_CACHEOWNIDS);//First Thing to do
@ -587,6 +590,13 @@ void p3IdService::service_tick()
cleanUnusedKeys() ;
mLastKeyCleaningTime = now ;
}
if(mLastPGPHashProcessTime + PGPHASH_PROC_PERIOD < now && !mGroupsToProcess.empty())
{
pgphash_process();
mLastPGPHashProcessTime=now;
}
return;
}
@ -2377,7 +2387,7 @@ bool SSGxsIdGroup::load(const std::string &input)
// split into parts.
if (3 != sscanf(input.c_str(), "v2 {P:%[^}]}{T:%[^}]}{R:%[^}]}", pgpstr, recognstr, scorestr))
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() Failed to extract 4 Parts";
std::cerr << std::endl;
#endif // DEBUG_IDS
@ -2387,14 +2397,14 @@ bool SSGxsIdGroup::load(const std::string &input)
bool ok = true;
if (pgp.load(pgpstr))
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() pgpstr: " << pgpstr;
std::cerr << std::endl;
#endif // DEBUG_IDS
}
else
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() Invalid pgpstr: " << pgpstr;
std::cerr << std::endl;
#endif // DEBUG_IDS
@ -2419,14 +2429,14 @@ bool SSGxsIdGroup::load(const std::string &input)
if (score.load(scorestr))
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() scorestr: " << scorestr;
std::cerr << std::endl;
#endif // DEBUG_IDS
}
else
{
#ifdef DEBUG_IDS
#ifdef DEBUG_SERVICE_STRING
std::cerr << "SSGxsIdGroup::load() Invalid scorestr: " << scorestr;
std::cerr << std::endl;
#endif // DEBUG_IDS
@ -3450,7 +3460,7 @@ void p3IdService::CacheArbitrationDone(uint32_t mode)
/************************************************************************************/
/************************************************************************************/
/* Task to determine GPGHash matches
/* Task to determine PGPHash matches
*
* Info to be stored in GroupServiceString + Cache.
*
@ -3693,15 +3703,17 @@ bool p3IdService::pgphash_start()
// ACTUALLY only need summary - but have written code for data.
// Also need to use opts.groupFlags to filter stuff properly to REALID's only.
// TODO
// TODO
uint32_t ansType = RS_TOKREQ_ANSTYPE_SUMMARY;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_META;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
GxsTokenQueue::queueRequest(token, GXSIDREQ_PGPHASH);
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts);
GxsTokenQueue::queueRequest(token, GXSIDREQ_PGPHASH);
return true;
}
@ -3723,44 +3735,52 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
// We Will do this later!
std::vector<RsGxsIdGroup> groups;
bool groupsToProcess = false;
bool ok = getGroupData(token, groups);
std::list<RsGroupMetaData> group_metas;
std::list<RsGxsGroupId> groups_to_process;
bool ok = getGroupMeta(token, group_metas);
if(ok)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() Have " << groups.size() << " Groups";
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() Have " << group_metas.size() << " Groups" << std::endl;
#endif // DEBUG_IDS
std::vector<RsGxsIdGroup>::iterator vit;
for(vit = groups.begin(); vit != groups.end(); ++vit)
for(auto vit = group_metas.begin(); vit != group_metas.end(); ++vit)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mMeta.mGroupId;
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() Group Id: " << vit->mGroupId << " ";
#endif // DEBUG_IDS
/* Filter based on IdType */
if (!(vit->mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility))
/* Filter based on IdType */
if (!(vit->mGroupFlags & RSGXSID_GROUPFLAG_REALID_kept_for_compatibility))
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() discarding AnonID";
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() discarding AnonID" << std::endl;
#endif // DEBUG_IDS
continue;
}
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
if(mGroupsToProcess.find(vit->mGroupId) != mGroupsToProcess.end())
{
#ifdef DEBUG_IDS
std::cerr << " => already in checking list!" << std::endl;
#endif
continue;
}
}
/* now we need to decode the Service String - see what is saved there */
SSGxsIdGroup ssdata;
if (ssdata.load(vit->mMeta.mServiceString))
SSGxsIdGroup ssdata;
if (ssdata.load(vit->mServiceString))
{
if (ssdata.pgp.validatedSignature)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() discarding Already Known";
std::cerr << std::endl;
std::cerr << "p3IdService::pgphash_request() discarding Already Known" << std::endl;
#endif // DEBUG_IDS
continue;
}
@ -3773,11 +3793,11 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
#define SECS_PER_DAY (3600 * 24)
rstime_t age = time(NULL) - ssdata.pgp.lastCheckTs;
rstime_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY;
rstime_t wait_period = ssdata.pgp.checkAttempts * SECS_PER_DAY;
if (wait_period > 30 * SECS_PER_DAY)
{
wait_period = 30 * SECS_PER_DAY;
}
wait_period = 30 * SECS_PER_DAY;
#ifdef DEBUG_IDS
std::cerr << "p3IdService: group " << *vit << " age=" << age << ", attempts=" << ssdata.pgp.checkAttempts << ", wait period = " << wait_period ;
#endif
@ -3789,20 +3809,17 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
#endif // DEBUG_IDS
continue;
}
#ifdef DEBUG_IDS
std::cerr << " => recheck!" << std::endl;
#endif
}
/* if we get here -> then its to be processed */
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_request() ToProcess Group: " << vit->mMeta.mGroupId;
std::cerr << std::endl;
#endif // DEBUG_IDS
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
mGroupsToProcess.push_back(*vit);
groupsToProcess = true;
groups_to_process.push_back(vit->mGroupId);
}
}
else
@ -3811,28 +3828,56 @@ bool p3IdService::pgphash_handlerequest(uint32_t token)
std::cerr << std::endl;
}
if (groupsToProcess)
{
// update PgpIdList -> if there are groups to process.
getPgpIdList();
}
// If they are groups to process, load the data for these groups
// Schedule Processing.
RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH_PROC, PGPHASH_PROC_PERIOD);
return true;
if(!groups_to_process.empty())
{
uint32_t ansType = RS_TOKREQ_ANSTYPE_DATA;
RsTokReqOptions opts;
opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA;
uint32_t token = 0;
RsGenExchange::getTokenService()->requestGroupInfo(token, ansType, opts,groups_to_process);
GxsTokenQueue::queueRequest(token, GXSIDREQ_LOAD_PGPIDDATA);
}
return true;
}
bool p3IdService::pgphash_load_group_data(uint32_t token)
{
// Update PgpIdList -> if there are groups to process.
getPgpIdList();
std::vector<RsGxsIdGroup> groups;
// Add the loaded groups into the list of groups to process
getGroupData(token, groups);
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
for(auto grp:groups)
{
mGroupsToProcess[grp.mMeta.mGroupId] = grp;
#ifdef DEBUG_IDS
std::cerr << "pgphash_load_group_data(): loaded group data for group " << grp.mMeta.mGroupId << ". mGroupsToProcess contains " << mGroupsToProcess.size() << " elements." << std::endl;
#endif
}
return true;
}
bool p3IdService::pgphash_process()
{
/* each time this is called - process one Id from mGroupsToProcess */
/* each time this is called - process one Id from mGroupsToProcess */
RsGxsIdGroup pg;
bool isDone = false;
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
if (!mGroupsToProcess.empty())
{
pg = mGroupsToProcess.front();
mGroupsToProcess.pop_front();
pg = mGroupsToProcess.begin()->second;
mGroupsToProcess.erase(mGroupsToProcess.begin());
#ifdef DEBUG_IDS
std::cerr << "p3IdService::pgphash_process() Popped Group: " << pg.mMeta.mGroupId;
@ -3840,9 +3885,7 @@ bool p3IdService::pgphash_process()
#endif // DEBUG_IDS
}
else
{
isDone = true;
}
}
if (isDone)
@ -3911,13 +3954,17 @@ bool p3IdService::pgphash_process()
cache_update_if_cached(RsGxsId(pg.mMeta.mGroupId), serviceString);
}
// Schedule Next Processing.
RsTickEvent::schedule_in(GXSID_EVENT_PGPHASH_PROC, PGPHASH_PROC_PERIOD);
return false; // as there are more items on the queue to process.
return true;
}
// This method allows to have a null issuer ID in the signature, in which case the signature is anonymous.
// The correct PGP key to check is looked for by bruteforcing
//
// grp.mPgpIdHash == SHA1( GroupId | PgpFingerPrint )
//
// For now, this is probably never used because signed IDs use a clear signature. The advntage of hiding the
// ID has not been clearly demonstrated anyway, which allows to directly look for the ID in the list of
// known keys instead of computing tons of hashes.
bool p3IdService::checkId(const RsGxsIdGroup &grp, RsPgpId &pgpId,bool& error)
{
@ -3937,99 +3984,97 @@ bool p3IdService::checkId(const RsGxsIdGroup &grp, RsPgpId &pgpId,bool& error)
#endif // DEBUG_IDS
/* iterate through and check hash */
Sha1CheckSum ans = grp.mPgpIdHash;
Sha1CheckSum hash;
#ifdef DEBUG_IDS
std::string esign ;
Radix64::encode((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),esign) ;
std::cerr << "Checking group signature " << esign << std::endl;
#endif
RsPgpId issuer_id ;
RsPgpFingerprint pgp_fingerprint;
pgpId.clear() ;
if(mPgpUtils->parseSignature((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),issuer_id))
if(mPgpUtils->parseSignature((unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),issuer_id) && !issuer_id.isNull())
{
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
pgpId = issuer_id ;
auto mit = mPgpFingerprintMap.find(issuer_id);
if(mit == mPgpFingerprintMap.end())
{
#ifdef DEBUG_IDS
std::cerr << "Issuer found: " << issuer_id << std::endl;
std::cerr << "Issuer Id: " << issuer_id << " is not known. Key will be marked as non verified." << std::endl;
#endif
pgpId = issuer_id ;
error = false;
return false;
}
calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash);
#ifdef DEBUG_IDS
std::cerr << "Issuer from PGP signature: " << issuer_id << " is known. Computed corresponding hash: " << hash << std::endl;
#endif
if(grp.mPgpIdHash != hash)
{
std::cerr << "(EE) Unexpected situation: GxsId signature hash (" << hash << ") doesn't correspond to what's listed in the mPgpIdHash field (" << grp.mPgpIdHash << ")." << std::endl;
error = true;
return false;
}
pgp_fingerprint = mit->second;
}
else
{
std::cerr << "Signature parsing failed!!" << std::endl;
pgpId.clear() ;
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
#ifdef DEBUG_IDS
std::cerr << "Bruteforcing PGP hash from GxsId mPgpHash: " << grp.mPgpIdHash << std::endl;
#endif
for(auto mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); ++mit)
{
calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash);
std::cerr << " profile key " << mit->first << " (" << mit->second << ") : ";
if (grp.mPgpIdHash == hash)
{
#ifdef DEBUG_IDS
std::cerr << "MATCH!" << std::endl;
#endif
pgpId = mit->first;
pgp_fingerprint = mit->second;
break;
}
#ifdef DEBUG_IDS
else
std::cerr << "fails" << std::endl;
#endif
}
}
// Look for the PGP id given by the signature
#ifdef DEBUG_IDS
std::cerr << "\tExpected Answer: " << ans.toStdString();
std::cerr << std::endl;
#endif // DEBUG_IDS
RsStackMutex stack(mIdMtx); /********** STACK LOCKED MTX ******/
std::map<RsPgpId, PGPFingerprintType>::iterator mit;
for(mit = mPgpFingerprintMap.begin(); mit != mPgpFingerprintMap.end(); ++mit)
{
Sha1CheckSum hash;
calcPGPHash(RsGxsId(grp.mMeta.mGroupId), mit->second, hash);
if (ans == hash)
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::checkId() HASH MATCH!";
std::cerr << std::endl;
std::cerr << "p3IdService::checkId() Hash : " << hash.toStdString();
std::cerr << std::endl;
std::cerr << "Now checking the signature: ";
#endif
/* miracle match! */
/* check signature too */
if (mPgpUtils->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES,
(unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(),
mit->second))
{
if (mPgpUtils->VerifySignBin((void *) hash.toByteArray(), hash.SIZE_IN_BYTES, (unsigned char *) grp.mPgpIdSign.c_str(), grp.mPgpIdSign.length(), pgp_fingerprint))
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::checkId() Signature Okay too!";
std::cerr << std::endl;
std::cerr << " Signature validates!" << std::endl;
#endif
pgpId = mit->first;
return true;
}
/* error */
std::cerr << "p3IdService::checkId() ERROR Signature Failed";
std::cerr << std::endl;
std::cerr << "p3IdService::checkId() Matched PGPID: " << mit->first.toStdString();
std::cerr << " Fingerprint: " << mit->second.toStdString();
std::cerr << std::endl;
std::cerr << "p3IdService::checkId() Signature: ";
std::string strout;
/* push binary into string -> really bad! */
for(unsigned int i = 0; i < grp.mPgpIdSign.length(); i++)
{
rs_sprintf_append(strout, "%02x", (uint32_t) ((uint8_t) grp.mPgpIdSign[i]));
}
std::cerr << strout;
std::cerr << std::endl;
error = true ;
return false ;
}
}
error = false;
return true;
}
else
{
#ifdef DEBUG_IDS
std::cerr << "p3IdService::checkId() Checked " << mPgpFingerprintMap.size() << " Hashes without Match";
std::cerr << std::endl;
#endif // DEBUG_IDS
return false;
std::cerr << " Signature fails!" << std::endl;
#endif
error = true;
return false;
}
}
/* worker functions */
void p3IdService::getPgpIdList()
{
@ -4742,6 +4787,9 @@ void p3IdService::handleResponse(uint32_t token, uint32_t req_type
case GXSIDREQ_OPINION:
if (status == RsTokenService::COMPLETE) opinion_handlerequest(token);
break;
case GXSIDREQ_LOAD_PGPIDDATA:
if (status == RsTokenService::COMPLETE) pgphash_load_group_data(token);
break;
case GXSIDREQ_SERIALIZE_TO_MEMORY:
if (status == RsTokenService::COMPLETE) handle_get_serialized_grp(token);
break;
@ -4780,10 +4828,6 @@ void p3IdService::handle_event(uint32_t event_type, const std::string &/*elabel*
pgphash_start();
break;
case GXSID_EVENT_PGPHASH_PROC:
pgphash_process();
break;
case GXSID_EVENT_RECOGN:
recogn_start();
break;

View File

@ -488,7 +488,8 @@ private:
*
*/
bool pgphash_start();
bool pgphash_handlerequest(uint32_t token);
bool pgphash_load_group_data(uint32_t token);
bool pgphash_handlerequest(uint32_t token);
bool pgphash_process();
bool checkId(const RsGxsIdGroup &grp, RsPgpId &pgp_id, bool &error);
@ -497,7 +498,7 @@ private:
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
std::map<RsPgpId, RsPgpFingerprint> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess;
std::map<RsGxsGroupId,RsGxsIdGroup> mGroupsToProcess;
/************************************************************************
* recogn processing.
@ -625,7 +626,7 @@ private:
*/
PgpAuxUtils *mPgpUtils;
rstime_t mLastPGPHashProcessTime ;
rstime_t mLastKeyCleaningTime ;
rstime_t mLastConfigUpdate ;