From 6617946fbdc0a6a44a9007a8a6ad24d34cb5aebe Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 15 Nov 2020 20:49:48 +0100 Subject: [PATCH 1/3] fixed bug causing missing of statistics update in channels, and missing of update when publish key is received --- .../src/gui/gxschannels/GxsChannelDialog.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 09dec15c7..1a63186b6 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -64,21 +64,21 @@ void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr ev if(e) switch(e->mChannelEventCode) { - case RsChannelEventCode::NEW_MESSAGE: // [[fallthrough]]; + case RsChannelEventCode::STATISTICS_CHANGED: // [[fallthrough]]; + updateDisplay(true); // no breaks, on purpose! + + case RsChannelEventCode::NEW_MESSAGE: // [[fallthrough]]; case RsChannelEventCode::UPDATED_MESSAGE: // [[fallthrough]]; case RsChannelEventCode::READ_STATUS_CHANGED: // [[fallthrough]]; - updateGroupStatisticsReal(e->mChannelGroupId); // update the list immediately + updateGroupStatisticsReal(e->mChannelGroupId);// update the list immediately break; - case RsChannelEventCode::NEW_CHANNEL: // [[fallthrough]]; - case RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED: + case RsChannelEventCode::RECEIVED_PUBLISH_KEY: // [[fallthrough]]; + case RsChannelEventCode::NEW_CHANNEL: // [[fallthrough]]; + case RsChannelEventCode::SUBSCRIBE_STATUS_CHANGED:// reloads group summary (calling GxsGroupFrameDialog parent method) updateDisplay(true); break; - case RsChannelEventCode::STATISTICS_CHANGED: - updateGroupStatistics(e->mChannelGroupId); - break; - default: break; } From 7db84002330a14891d944e155d71e99127e698f9 Mon Sep 17 00:00:00 2001 From: csoler Date: Sun, 15 Nov 2020 21:22:25 +0100 Subject: [PATCH 2/3] disable limit of forward time checking for validating signatures --- libretroshare/src/gxs/gxssecurity.cc | 37 +++++++++++++++++++++------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/libretroshare/src/gxs/gxssecurity.cc b/libretroshare/src/gxs/gxssecurity.cc index d5b377328..8fd603558 100644 --- a/libretroshare/src/gxs/gxssecurity.cc +++ b/libretroshare/src/gxs/gxssecurity.cc @@ -417,11 +417,22 @@ bool GxsSecurity::validateNxsMsg(const RsNxsMsg& msg, const RsTlvKeySignature& s // /********************* check signature *******************/ /* check signature timeperiod */ - if ((msgMeta.mPublishTs < key.startTS) || (key.endTS != 0 && msgMeta.mPublishTs > key.endTS)) + if(msgMeta.mPublishTs < key.startTS) + { + RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId + << " The signed message has an inconsistent msg publish time of " << msgMeta.mPublishTs + << " whereas the signing key was created later at TS " << key.startTS + << ". Validation rejected for security. If you see this, something irregular is going on." << std::endl; + return false; + } + + if(key.endTS != 0 && msgMeta.mPublishTs > key.endTS) { RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for key " << msgMeta.mAuthorId - << " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs << std::endl; - return false; + << " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << msgMeta.mPublishTs + << " The validation still passes, but that key should be renewed." << std::endl; + + // no return here. We still proceed checking the signature. } /* decode key */ @@ -1053,14 +1064,22 @@ bool GxsSecurity::validateNxsGrp(const RsNxsGrp& grp, const RsTlvKeySignature& s /********************* check signature *******************/ /* check signature timeperiod */ - if ((grpMeta.mPublishTs < key.startTS) || (key.endTS != 0 && grpMeta.mPublishTs > key.endTS)) + if (grpMeta.mPublishTs < key.startTS) { -#ifdef GXS_SECURITY_DEBUG - std::cerr << " GxsSecurity::validateNxsMsg() TS out of range"; - std::cerr << std::endl; -#endif - return false; + RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsGrp() TS out of range for admin/publish key of group " << grpMeta.mGroupId + << " The signed group has an inconsistent creation/modification time of " << grpMeta.mPublishTs + << " whereas the key was created later at TS " << key.startTS + << ". Validation rejected for security. If you see this, something irregular is going on." << std::endl; + return false; } + if (key.endTS != 0 && grpMeta.mPublishTs > key.endTS) + { + RsWarn() << __PRETTY_FUNCTION__ << " GxsSecurity::validateNxsMsg() TS out of range for admin/publish key for group " << grpMeta.mGroupId + << " usage is limited to TS=[" << key.startTS << "," << key.endTS << "] and msg publish time is " << grpMeta.mPublishTs + << " The validation still passes, but that key should be renewed." << std::endl; + + // no return. Still proceed checking signature. + } /* decode key */ const unsigned char *keyptr = (const unsigned char *) key.keyData.bin_data; From 883dfd9c99ad5aefc9a101054085d12f3b9e05b2 Mon Sep 17 00:00:00 2001 From: csoler Date: Tue, 17 Nov 2020 23:54:43 +0100 Subject: [PATCH 3/3] fixed quadratic cost in IdDialog::loadCircles(). --- retroshare-gui/src/gui/Identity/IdDialog.cpp | 34 ++++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index 944fe399b..747e4706f 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -597,6 +597,10 @@ void IdDialog::loadCircles(const std::list& groupInfo) mStateHelper->setActive(CIRCLESDIALOG_GROUPMETA, true); + // Disable sorting while updating which avoids calling sortChildren() in child(i), causing heavy loads when adding + // many items to a tree. + ui->treeWidget_membership->setSortingEnabled(false); + std::vector expanded_top_level_items; std::set expanded_circle_items; saveExpandedCircleItems(expanded_top_level_items,expanded_circle_items); @@ -730,6 +734,15 @@ void IdDialog::loadCircles(const std::list& groupInfo) for(auto index:to_delete) delete item->takeChild(index); // delete items starting from the largest index, because otherwise the count changes while deleting... + // Now make a list of items to add, but only add them at once at the end of the loop, to avoid a quadratic cost. + QList new_sub_items; + + // ...and make a map of which index each item has, to make the search logarithmic + std::map subitem_indices; + + for(uint32_t k=0; k < (uint32_t)item->childCount(); ++k) + subitem_indices[item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString()] = k; + for(std::map::const_iterator it(details.mSubscriptionFlags.begin());it!=details.mSubscriptionFlags.end();++it) { #ifdef ID_DEBUG @@ -745,15 +758,11 @@ void IdDialog::loadCircles(const std::list& groupInfo) int subitem_index = -1; // see if the item already exists - for(uint32_t k=0; k < (uint32_t)item->childCount(); ++k) - if(item->child(k)->data(CIRCLEGROUP_CIRCLE_COL_GROUPID,Qt::UserRole).toString().toStdString() == it->first.toStdString()) - { - subitem_index = k; -#ifdef ID_DEBUG - std::cerr << " found existing sub item." << std::endl; -#endif - break ; - } + + auto itt = subitem_indices.find(QString::fromStdString(it->first.toStdString())); + + if(itt != subitem_indices.end()) + subitem_index = itt->second; if(!(invited || subscrb)) { @@ -819,7 +828,7 @@ void IdDialog::loadCircles(const std::list& groupInfo) //subitem->setIcon(RSID_COL_NICKNAME, QIcon(pixmap)); - item->addChild(subitem) ; + new_sub_items.push_back(subitem); } else subitem = item->child(subitem_index); @@ -851,6 +860,9 @@ void IdDialog::loadCircles(const std::list& groupInfo) } } + // add all items + item->addChildren(new_sub_items); + // The bullet colors below are for the *Membership*. This is independent from admin rights, which cannot be shown as a color. // Admin/non admin is shows using Bold font. @@ -861,6 +873,8 @@ void IdDialog::loadCircles(const std::list& groupInfo) else item->setIcon(CIRCLEGROUP_CIRCLE_COL_GROUPNAME,FilesDefs::getIconFromQtResourcePath(IMAGE_UNKNOWN)) ; } + ui->treeWidget_membership->setSortingEnabled(true); + restoreExpandedCircleItems(expanded_top_level_items,expanded_circle_items); }