mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
fixed exchange of PGP keys in binary format and update of PGP signature flags on short invites when the key is received
This commit is contained in:
parent
b0c7f8f0ca
commit
a20ec1a885
@ -36,7 +36,8 @@ RsItem *RsDiscSerialiser::create_item(
|
|||||||
switch(static_cast<RsGossipDiscoveryItemType>(item_subtype))
|
switch(static_cast<RsGossipDiscoveryItemType>(item_subtype))
|
||||||
{
|
{
|
||||||
case RsGossipDiscoveryItemType::PGP_LIST: return new RsDiscPgpListItem();
|
case RsGossipDiscoveryItemType::PGP_LIST: return new RsDiscPgpListItem();
|
||||||
case RsGossipDiscoveryItemType::PGP_CERT: return new RsDiscPgpCertItem();
|
// case RsGossipDiscoveryItemType::PGP_CERT: return new RsDiscPgpCertItem();
|
||||||
|
case RsGossipDiscoveryItemType::PGP_CERT_BINARY: return new RsDiscPgpKeyItem();
|
||||||
case RsGossipDiscoveryItemType::CONTACT: return new RsDiscContactItem();
|
case RsGossipDiscoveryItemType::CONTACT: return new RsDiscContactItem();
|
||||||
case RsGossipDiscoveryItemType::IDENTITY_LIST:
|
case RsGossipDiscoveryItemType::IDENTITY_LIST:
|
||||||
return new RsDiscIdentityListItem();
|
return new RsDiscIdentityListItem();
|
||||||
@ -78,6 +79,18 @@ void RsDiscPgpCertItem::serial_process(RsGenericSerializer::SerializeJob j,RsGen
|
|||||||
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PGPCERT,pgpCert,"pgpCert") ;
|
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_PGPCERT,pgpCert,"pgpCert") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RsDiscPgpKeyItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)
|
||||||
|
{
|
||||||
|
RsTypeSerializer::serial_process(j,ctx,pgpKeyId,"pgpKeyId") ;
|
||||||
|
RsTypeSerializer::serial_process(j,ctx,pgpKeyData,"pgpKeyData") ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RsDiscPgpKeyItem::clear()
|
||||||
|
{
|
||||||
|
pgpKeyId.clear();
|
||||||
|
pgpKeyData.TlvClear();
|
||||||
|
}
|
||||||
|
|
||||||
void RsDiscContactItem::clear()
|
void RsDiscContactItem::clear()
|
||||||
{
|
{
|
||||||
pgpId.clear();
|
pgpId.clear();
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "serialiser/rsserial.h"
|
#include "serialiser/rsserial.h"
|
||||||
#include "serialiser/rstlvidset.h"
|
#include "serialiser/rstlvidset.h"
|
||||||
#include "serialiser/rstlvaddrs.h"
|
#include "serialiser/rstlvaddrs.h"
|
||||||
|
#include "serialiser/rstlvbinary.h"
|
||||||
#include "rsitems/rsserviceids.h"
|
#include "rsitems/rsserviceids.h"
|
||||||
#include "rsitems/rsitem.h"
|
#include "rsitems/rsitem.h"
|
||||||
#include "rsitems/itempriorities.h"
|
#include "rsitems/itempriorities.h"
|
||||||
@ -34,11 +35,12 @@
|
|||||||
enum class RsGossipDiscoveryItemType : uint8_t
|
enum class RsGossipDiscoveryItemType : uint8_t
|
||||||
{
|
{
|
||||||
PGP_LIST = 0x1,
|
PGP_LIST = 0x1,
|
||||||
PGP_CERT = 0x2,
|
PGP_CERT = 0x2, // deprecated
|
||||||
CONTACT = 0x5,
|
CONTACT = 0x5,
|
||||||
IDENTITY_LIST = 0x6,
|
IDENTITY_LIST = 0x6,
|
||||||
INVITE = 0x7,
|
INVITE = 0x7,
|
||||||
INVITE_REQUEST = 0x8
|
INVITE_REQUEST = 0x8,
|
||||||
|
PGP_CERT_BINARY = 0x9,
|
||||||
};
|
};
|
||||||
|
|
||||||
class RsDiscItem: public RsItem
|
class RsDiscItem: public RsItem
|
||||||
@ -96,6 +98,20 @@ public:
|
|||||||
std::string pgpCert;
|
std::string pgpCert;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RsDiscPgpKeyItem: public RsDiscItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
RsDiscPgpKeyItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT_BINARY)
|
||||||
|
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT); }
|
||||||
|
|
||||||
|
void clear() override;
|
||||||
|
void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override;
|
||||||
|
|
||||||
|
RsPgpId pgpKeyId; // duplicate information for practical reasons
|
||||||
|
RsTlvBinaryData pgpKeyData;
|
||||||
|
};
|
||||||
|
|
||||||
class RsDiscContactItem: public RsDiscItem
|
class RsDiscContactItem: public RsDiscItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
/****
|
/****
|
||||||
* #define P3DISC_DEBUG 1
|
* #define P3DISC_DEBUG 1
|
||||||
****/
|
****/
|
||||||
|
#define P3DISC_DEBUG 1
|
||||||
|
|
||||||
/*extern*/ std::shared_ptr<RsGossipDiscovery> rsGossipDiscovery(nullptr);
|
/*extern*/ std::shared_ptr<RsGossipDiscovery> rsGossipDiscovery(nullptr);
|
||||||
|
|
||||||
@ -261,11 +262,12 @@ int p3discovery2::handleIncoming()
|
|||||||
while(nullptr != (item = recvItem()))
|
while(nullptr != (item = recvItem()))
|
||||||
{
|
{
|
||||||
RsDiscPgpListItem* pgplist = nullptr;
|
RsDiscPgpListItem* pgplist = nullptr;
|
||||||
RsDiscPgpCertItem* pgpcert = nullptr;
|
RsDiscPgpCertItem* pgpcert = nullptr; // deprecated
|
||||||
|
RsDiscPgpKeyItem* pgpkey = nullptr;
|
||||||
RsDiscContactItem* contact = nullptr;
|
RsDiscContactItem* contact = nullptr;
|
||||||
RsDiscIdentityListItem* gxsidlst = nullptr;
|
RsDiscIdentityListItem* gxsidlst = nullptr;
|
||||||
RsGossipDiscoveryInviteItem* invite = nullptr;
|
// RsGossipDiscoveryInviteItem* invite = nullptr;
|
||||||
RsGossipDiscoveryInviteRequestItem* inviteReq = nullptr;
|
// RsGossipDiscoveryInviteRequestItem* inviteReq = nullptr;
|
||||||
|
|
||||||
++nhandled;
|
++nhandled;
|
||||||
|
|
||||||
@ -276,16 +278,18 @@ int p3discovery2::handleIncoming()
|
|||||||
{
|
{
|
||||||
if (item->PeerId() == contact->sslId)
|
if (item->PeerId() == contact->sslId)
|
||||||
recvOwnContactInfo(item->PeerId(), contact);
|
recvOwnContactInfo(item->PeerId(), contact);
|
||||||
else processContactInfo(item->PeerId(), contact);
|
else
|
||||||
|
processContactInfo(item->PeerId(), contact);
|
||||||
}
|
}
|
||||||
else if( (gxsidlst = dynamic_cast<RsDiscIdentityListItem *>(item))
|
else if( (gxsidlst = dynamic_cast<RsDiscIdentityListItem *>(item)) != nullptr )
|
||||||
!= nullptr )
|
|
||||||
{
|
{
|
||||||
recvIdentityList(item->PeerId(),gxsidlst->ownIdentityList);
|
recvIdentityList(item->PeerId(),gxsidlst->ownIdentityList);
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
else if((pgpcert = dynamic_cast<RsDiscPgpCertItem *>(item)) != nullptr)
|
// else if((pgpcert = dynamic_cast<RsDiscPgpCertItem *>(item)) != nullptr)
|
||||||
recvPGPCertificate(item->PeerId(), pgpcert);
|
// recvPGPCertificate(item->PeerId(), pgpcert);
|
||||||
|
else if((pgpkey = dynamic_cast<RsDiscPgpKeyItem *>(item)) != nullptr)
|
||||||
|
recvPGPCertificate(item->PeerId(), pgpkey);
|
||||||
else if((pgplist = dynamic_cast<RsDiscPgpListItem *>(item)) != nullptr)
|
else if((pgplist = dynamic_cast<RsDiscPgpListItem *>(item)) != nullptr)
|
||||||
{
|
{
|
||||||
if (pgplist->mode == RsGossipDiscoveryPgpListMode::FRIENDS)
|
if (pgplist->mode == RsGossipDiscoveryPgpListMode::FRIENDS)
|
||||||
@ -294,16 +298,15 @@ int p3discovery2::handleIncoming()
|
|||||||
recvPGPCertificateRequest(pgplist->PeerId(), pgplist);
|
recvPGPCertificateRequest(pgplist->PeerId(), pgplist);
|
||||||
else delete item;
|
else delete item;
|
||||||
}
|
}
|
||||||
else if( (invite = dynamic_cast<RsGossipDiscoveryInviteItem*>(item))
|
// else if( (invite = dynamic_cast<RsGossipDiscoveryInviteItem*>(item)) != nullptr )
|
||||||
!= nullptr )
|
// recvInvite(std::unique_ptr<RsGossipDiscoveryInviteItem>(invite));
|
||||||
recvInvite(std::unique_ptr<RsGossipDiscoveryInviteItem>(invite));
|
// else if( (inviteReq =
|
||||||
else if( (inviteReq =
|
// dynamic_cast<RsGossipDiscoveryInviteRequestItem*>(item))
|
||||||
dynamic_cast<RsGossipDiscoveryInviteRequestItem*>(item))
|
// != nullptr )
|
||||||
!= nullptr )
|
// {
|
||||||
{
|
// sendInvite(inviteReq->mInviteId, item->PeerId());
|
||||||
sendInvite(inviteReq->mInviteId, item->PeerId());
|
// delete item;
|
||||||
delete item;
|
// }
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
RsWarn() << __PRETTY_FUNCTION__ << " Received unknown item type! "
|
RsWarn() << __PRETTY_FUNCTION__ << " Received unknown item type! "
|
||||||
@ -365,6 +368,7 @@ void p3discovery2::sendOwnContactInfo(const SSLID &sslid)
|
|||||||
|
|
||||||
void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactItem *item)
|
void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactItem *item)
|
||||||
{
|
{
|
||||||
|
std::unique_ptr<const RsDiscContactItem> pitem(item); // ensures that item will be destroyed whichever door we leave through
|
||||||
|
|
||||||
#ifdef P3DISC_DEBUG
|
#ifdef P3DISC_DEBUG
|
||||||
std::cerr << "p3discovery2::recvOwnContactInfo()";
|
std::cerr << "p3discovery2::recvOwnContactInfo()";
|
||||||
@ -377,6 +381,21 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
|
|||||||
std::cerr << " -> location : " << item->location << std::endl;
|
std::cerr << " -> location : " << item->location << std::endl;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
// Check that the "own" ID sent corresponds to the one we think it should be.
|
||||||
|
// Some of these checks may look superfluous but it's better to risk to check twice than not check at all.
|
||||||
|
|
||||||
|
// was obtained using a short invite. , and that the friend is marked as "ignore PGP validation" because it
|
||||||
|
RsPeerDetails det ;
|
||||||
|
if(!rsPeers->getPeerDetails(fromId,det))
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) Cannot obtain details from " << fromId << " who is supposed to be a friend! Dropping the info." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(det.gpg_id != item->pgpId)
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) peer " << fromId << " sent own details with PGP key ID " << item->pgpId << " which does not match the known key id " << det.gpg_id << ". Dropping the info." << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Peer Own Info replaces the existing info, because the
|
// Peer Own Info replaces the existing info, because the
|
||||||
// peer is the primary source of his own IPs.
|
// peer is the primary source of his own IPs.
|
||||||
@ -389,6 +408,17 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
|
|||||||
|
|
||||||
updatePeerAddresses(item);
|
updatePeerAddresses(item);
|
||||||
|
|
||||||
|
// if the peer is not validated, we stop the exchange here
|
||||||
|
|
||||||
|
if(det.skip_signature_validation)
|
||||||
|
{
|
||||||
|
#ifdef P3DISC_DEBUG
|
||||||
|
std::cerr << "p3discovery2::recvOwnContactInfo() missing PGP key " << item->pgpId << " from short invite friend " << fromId << ". Requesting it." << std::endl;
|
||||||
|
#endif
|
||||||
|
requestPGPCertificate(det.gpg_id, fromId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// This information will be sent out to online peers, at the receipt of their PGPList.
|
// This information will be sent out to online peers, at the receipt of their PGPList.
|
||||||
// It is important that PGPList is received after the OwnContactItem.
|
// It is important that PGPList is received after the OwnContactItem.
|
||||||
// This should happen, but is not enforced by the protocol.
|
// This should happen, but is not enforced by the protocol.
|
||||||
@ -422,17 +452,6 @@ void p3discovery2::recvOwnContactInfo(const SSLID &fromId, const RsDiscContactIt
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef P3DISC_DEBUG
|
|
||||||
std::cerr << "p3discovery2::recvOwnContactInfo()";
|
|
||||||
std::cerr << " ERROR missing PGP Entry: " << pgpId;
|
|
||||||
std::cerr << std::endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleanup.
|
|
||||||
delete item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3discovery2::recvIdentityList(const RsPeerId& pid,const std::list<RsGxsId>& ids)
|
void p3discovery2::recvIdentityList(const RsPeerId& pid,const std::list<RsGxsId>& ids)
|
||||||
@ -690,7 +709,7 @@ void p3discovery2::processPGPList(const SSLID &fromId, const RsDiscPgpListItem *
|
|||||||
if (!AuthGPG::getAuthGPG()->isGPGId(*fit))
|
if (!AuthGPG::getAuthGPG()->isGPGId(*fit))
|
||||||
{
|
{
|
||||||
#ifdef P3DISC_DEBUG
|
#ifdef P3DISC_DEBUG
|
||||||
std::cerr << "p3discovery2::processPGPList() requesting PgpId: " << *fit;
|
std::cerr << "p3discovery2::processPGPList() requesting certificate for PgpId: " << *fit;
|
||||||
std::cerr << " from SslId: " << fromId;
|
std::cerr << " from SslId: " << fromId;
|
||||||
std::cerr << std::endl;
|
std::cerr << std::endl;
|
||||||
#endif
|
#endif
|
||||||
@ -1023,30 +1042,97 @@ void p3discovery2::recvPGPCertificateRequest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void p3discovery2::sendPGPCertificate(const PGPID &aboutId, const SSLID &toId)
|
void p3discovery2::sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId)
|
||||||
{
|
{
|
||||||
RsDiscPgpCertItem* item = new RsDiscPgpCertItem();
|
//RsDiscPgpCertItem* item = new RsDiscPgpCertItem();
|
||||||
item->pgpId = aboutId;
|
//item->pgpId = aboutId;
|
||||||
item->PeerId(toId);
|
|
||||||
|
|
||||||
Dbg4() << __PRETTY_FUNCTION__ << " queuing for Cert generation: "
|
//Dbg4() << __PRETTY_FUNCTION__ << " queuing for Cert generation: " << std::endl << *item << std::endl;
|
||||||
<< std::endl << *item << std::endl;
|
|
||||||
|
|
||||||
{
|
RsDiscPgpKeyItem *pgp_key_item = new RsDiscPgpKeyItem;
|
||||||
RS_STACK_MUTEX(mDiscMtx);
|
|
||||||
mPendingDiscPgpCertOutList.push_back(item);
|
pgp_key_item->PeerId(toId);
|
||||||
}
|
pgp_key_item->pgpKeyId = aboutId;
|
||||||
|
unsigned char *bin_data;
|
||||||
|
size_t bin_len;
|
||||||
|
|
||||||
|
if(!AuthGPG::getAuthGPG()->exportPublicKey(aboutId,bin_data,bin_len,false,true))
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) cannot export public key " << aboutId << " requested by peer " << toId << std::endl;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
pgp_key_item->pgpKeyData.bin_data = bin_data;
|
||||||
|
pgp_key_item->pgpKeyData.bin_len = bin_len;
|
||||||
|
|
||||||
|
sendItem(pgp_key_item);
|
||||||
|
|
||||||
|
// (cyril) we shouldn't need to use a queue for that! There's no cost in getting a PGP cert from AuthGPG.
|
||||||
|
// {
|
||||||
|
// RS_STACK_MUTEX(mDiscMtx);
|
||||||
|
// mPendingDiscPgpCertOutList.push_back(item);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void p3discovery2::recvPGPCertificate(
|
void p3discovery2::recvPGPCertificate(const RsPeerId& fromId, RsDiscPgpKeyItem* item )
|
||||||
const SSLID& /*fromId*/, RsDiscPgpCertItem* item )
|
|
||||||
{
|
{
|
||||||
|
// 1 - check that the cert structure is valid.
|
||||||
|
|
||||||
|
RsPgpId cert_pgp_id;
|
||||||
|
std::string cert_name;
|
||||||
|
std::list<RsPgpId> cert_signers;
|
||||||
|
|
||||||
|
if(!AuthGPG::getAuthGPG()->getGPGDetailsFromBinaryBlock( (unsigned char*)item->pgpKeyData.bin_data,item->pgpKeyData.bin_len, cert_pgp_id, cert_name, cert_signers ))
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) cannot parse own PGP key sent by " << fromId << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cert_pgp_id != item->pgpKeyId)
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) received a PGP key from " << fromId << " which ID (" << cert_pgp_id << ") is different from the one anounced in the packet (" << item->pgpKeyId << ")!" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2 - check if the peer who is sending us a cert is already validated
|
||||||
|
|
||||||
|
RsPeerDetails det;
|
||||||
|
if(!rsPeers->getPeerDetails(fromId,det))
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) cannot get peer details from friend " << fromId << ": this is very wrong!"<< std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We treat own pgp keys right away when they are sent by a friend for which we dont have it. This way we can keep the skip_pgg_signature_validation consistent
|
||||||
|
|
||||||
|
if(det.skip_signature_validation)
|
||||||
|
{
|
||||||
#ifdef P3DISC_DEBUG
|
#ifdef P3DISC_DEBUG
|
||||||
std::cerr << __PRETTY_FUNCTION__ << " queuing for Cert loading" << std::endl;
|
std::cerr << __PRETTY_FUNCTION__ << " Received own full certificate from short-invite friend " << fromId << std::endl;
|
||||||
#endif
|
#endif
|
||||||
/* push this back to be processed by pgp when possible */
|
// do some extra checks. Dont remove them. They cost nothing as compared to what they could avoid.
|
||||||
RS_STACK_MUTEX(mDiscMtx);
|
|
||||||
mPendingDiscPgpCertInList.push_back(item);
|
if(item->pgpKeyId != det.gpg_id)
|
||||||
|
{
|
||||||
|
std::cerr << "(EE) received a PGP key with ID " << item->pgpKeyId << " from non validated peer " << fromId << ", which should only be allowed to send his own key " << det.gpg_id << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RsPgpId tmp_pgp_id;
|
||||||
|
std::string error_string;
|
||||||
|
|
||||||
|
#ifdef P3DISC_DEBUG
|
||||||
|
std::cerr << __PRETTY_FUNCTION__ << "Received PGP key " << cert_pgp_id << " from from friend " << fromId << ". Adding to keyring." << std::endl;
|
||||||
|
#endif
|
||||||
|
// now that will add the key *and* set the skip_signature_validation flag at once
|
||||||
|
rsPeers->loadPgpKeyFromBinaryData((unsigned char*)item->pgpKeyData.bin_data,item->pgpKeyData.bin_len, tmp_pgp_id,error_string); // no error should occur at this point because we called loadDetailsFromStringCert() already
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
// Make sure we allow connections after the key is added. This is not the case otherwise. We only do that if the peer is non validated peer, since
|
||||||
|
// otherwise the connection should already be accepted. This only happens when the short invite peer sends its own PGP key.
|
||||||
|
|
||||||
|
if(det.skip_signature_validation)
|
||||||
|
AuthGPG::getAuthGPG()->AllowConnection(det.gpg_id,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************* from pqiServiceMonitor *******************/
|
/************* from pqiServiceMonitor *******************/
|
||||||
@ -1139,7 +1225,7 @@ bool p3discovery2::getDiscFriends(const RsPeerId& id, std::list<RsPeerId> &proxy
|
|||||||
bool p3discovery2::getWaitingDiscCount(size_t &sendCount, size_t &recvCount)
|
bool p3discovery2::getWaitingDiscCount(size_t &sendCount, size_t &recvCount)
|
||||||
{
|
{
|
||||||
RS_STACK_MUTEX(mDiscMtx);
|
RS_STACK_MUTEX(mDiscMtx);
|
||||||
sendCount = mPendingDiscPgpCertOutList.size();
|
//sendCount = mPendingDiscPgpCertOutList.size();
|
||||||
recvCount = mPendingDiscPgpCertInList.size();
|
recvCount = mPendingDiscPgpCertInList.size();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -1256,20 +1342,18 @@ void p3discovery2::rsEventsHandler(const RsEvent& event)
|
|||||||
|
|
||||||
switch(event.mType)
|
switch(event.mType)
|
||||||
{
|
{
|
||||||
case RsEventType::PEER_STATE_CHANGED:
|
// case RsEventType::PEER_STATE_CHANGED:
|
||||||
{
|
// {
|
||||||
const RsPeerId& sslId =
|
// const RsPeerId& sslId = static_cast<const RsPeerStateChangedEvent&>(event).mSslId;
|
||||||
static_cast<const RsPeerStateChangedEvent&>(event).mSslId;
|
//
|
||||||
if( rsPeers && rsPeers->isSslOnlyFriend(sslId) &&
|
// if( rsPeers && rsPeers->isSslOnlyFriend(sslId) && mServiceCtrl->isPeerConnected( getServiceInfo().mServiceType, sslId ) )
|
||||||
mServiceCtrl->isPeerConnected(
|
// {
|
||||||
getServiceInfo().mServiceType, sslId ) )
|
// if(!requestPGPCertificate(sslId, sslId))
|
||||||
{
|
// RsErr() << __PRETTY_FUNCTION__ << " requestInvite to peer "
|
||||||
if(!requestInvite(sslId, sslId))
|
// << sslId << " failed" << std::endl;
|
||||||
RsErr() << __PRETTY_FUNCTION__ << " requestInvite to peer "
|
// }
|
||||||
<< sslId << " failed" << std::endl;
|
// break;
|
||||||
}
|
// }
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1292,17 +1376,17 @@ AuthGPGOperation *p3discovery2::getGPGOperation()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
// {
|
||||||
RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
|
// RsStackMutex stack(mDiscMtx); /********** STACK LOCKED MTX ******/
|
||||||
|
//
|
||||||
/* process disc reply in list */
|
// /* process disc reply in list */
|
||||||
if (!mPendingDiscPgpCertOutList.empty()) {
|
// if (!mPendingDiscPgpCertOutList.empty()) {
|
||||||
RsDiscPgpCertItem *item = mPendingDiscPgpCertOutList.front();
|
// RsDiscPgpCertItem *item = mPendingDiscPgpCertOutList.front();
|
||||||
mPendingDiscPgpCertOutList.pop_front();
|
// mPendingDiscPgpCertOutList.pop_front();
|
||||||
|
//
|
||||||
return new AuthGPGOperationLoadOrSave(false, item->pgpId, "", item);
|
// return new AuthGPGOperationLoadOrSave(false, item->pgpId, "", item);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,8 +130,9 @@ private:
|
|||||||
void recvPGPCertificateRequest(
|
void recvPGPCertificateRequest(
|
||||||
const RsPeerId& fromId, const RsDiscPgpListItem* item );
|
const RsPeerId& fromId, const RsDiscPgpListItem* item );
|
||||||
|
|
||||||
void sendPGPCertificate(const PGPID &aboutId, const SSLID &toId);
|
void sendPGPCertificate(const RsPgpId &aboutId, const RsPeerId &toId);
|
||||||
void recvPGPCertificate(const SSLID &fromId, RsDiscPgpCertItem *item);
|
void recvPGPCertificate(const SSLID &fromId, RsDiscPgpCertItem *item); // deprecated
|
||||||
|
void recvPGPCertificate(const SSLID &fromId, RsDiscPgpKeyItem *item);
|
||||||
void recvIdentityList(const RsPeerId& pid,const std::list<RsGxsId>& ids);
|
void recvIdentityList(const RsPeerId& pid,const std::list<RsGxsId>& ids);
|
||||||
|
|
||||||
bool setPeerVersion(const SSLID &peerId, const std::string &version);
|
bool setPeerVersion(const SSLID &peerId, const std::string &version);
|
||||||
@ -160,7 +161,7 @@ private:
|
|||||||
std::map<SSLID, DiscPeerInfo> mLocationMap;
|
std::map<SSLID, DiscPeerInfo> mLocationMap;
|
||||||
|
|
||||||
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertInList;
|
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertInList;
|
||||||
std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertOutList;
|
//std::list<RsDiscPgpCertItem *> mPendingDiscPgpCertOutList;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RS_SET_CONTEXT_DEBUG_LEVEL(1)
|
RS_SET_CONTEXT_DEBUG_LEVEL(1)
|
||||||
|
@ -1037,7 +1037,17 @@ void PGPHandler::addNewKeyToOPSKeyring(ops_keyring_t *kr,const ops_keydata_t& ke
|
|||||||
kr->nkeys++ ;
|
kr->nkeys++ ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PGPHandler::LoadCertificateFromBinaryData(const unsigned char *data,uint32_t data_len,RsPgpId& id,std::string& error_string)
|
||||||
|
{
|
||||||
|
return LoadCertificate(data,data_len,ops_false,id,error_string);
|
||||||
|
}
|
||||||
|
|
||||||
bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string)
|
bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId& id,std::string& error_string)
|
||||||
|
{
|
||||||
|
return LoadCertificate((unsigned char*)(pgp_cert.c_str()),pgp_cert.length(),ops_true,id,error_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PGPHandler::LoadCertificate(const unsigned char *data,uint32_t data_len,bool armoured,RsPgpId& id,std::string& error_string)
|
||||||
{
|
{
|
||||||
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
|
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
|
||||||
#ifdef DEBUG_PGPHANDLER
|
#ifdef DEBUG_PGPHANDLER
|
||||||
@ -1046,9 +1056,9 @@ bool PGPHandler::LoadCertificateFromString(const std::string& pgp_cert,RsPgpId&
|
|||||||
|
|
||||||
ops_keyring_t *tmp_keyring = allocateOPSKeyring();
|
ops_keyring_t *tmp_keyring = allocateOPSKeyring();
|
||||||
ops_memory_t *mem = ops_memory_new() ;
|
ops_memory_t *mem = ops_memory_new() ;
|
||||||
ops_memory_add(mem,(unsigned char *)pgp_cert.c_str(),pgp_cert.length()) ;
|
ops_memory_add(mem,data,data_len) ;
|
||||||
|
|
||||||
if(!ops_keyring_read_from_mem(tmp_keyring,ops_true,mem))
|
if(!ops_keyring_read_from_mem(tmp_keyring,armoured,mem))
|
||||||
{
|
{
|
||||||
ops_keyring_free(tmp_keyring) ;
|
ops_keyring_free(tmp_keyring) ;
|
||||||
free(tmp_keyring) ;
|
free(tmp_keyring) ;
|
||||||
|
@ -104,6 +104,7 @@ class PGPHandler
|
|||||||
bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) ;
|
bool GeneratePGPCertificate(const std::string& name, const std::string& email, const std::string& passwd, RsPgpId& pgpId, const int keynumbits, std::string& errString) ;
|
||||||
|
|
||||||
bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string);
|
bool LoadCertificateFromString(const std::string& pem, RsPgpId& gpg_id, std::string& error_string);
|
||||||
|
bool LoadCertificateFromBinaryData(const unsigned char *bin_data,uint32_t bin_data_len, RsPgpId& gpg_id, std::string& error_string);
|
||||||
|
|
||||||
std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ;
|
std::string SaveCertificateToString(const RsPgpId& id,bool include_signatures) const ;
|
||||||
bool exportPublicKey(const RsPgpId& id,unsigned char *& mem,size_t& mem_size,bool armoured,bool include_signatures) const ;
|
bool exportPublicKey(const RsPgpId& id,unsigned char *& mem,size_t& mem_size,bool armoured,bool include_signatures) const ;
|
||||||
@ -172,6 +173,7 @@ class PGPHandler
|
|||||||
bool syncDatabase() ;
|
bool syncDatabase() ;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool LoadCertificate(const unsigned char *bin_data,uint32_t bin_data_len, bool armoured, RsPgpId& gpg_id, std::string& error_string);
|
||||||
void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ;
|
void initCertificateInfo(PGPCertificateInfo& cert,const ops_keydata_t *keydata,uint32_t i) ;
|
||||||
|
|
||||||
// Returns true if the signatures have been updated
|
// Returns true if the signatures have been updated
|
||||||
|
@ -534,6 +534,19 @@ bool AuthGPG::getGPGSignedList(std::list<RsPgpId> &ids)
|
|||||||
|
|
||||||
return PGPHandler::SaveCertificateToString(id,include_signatures) ;
|
return PGPHandler::SaveCertificateToString(id,include_signatures) ;
|
||||||
}
|
}
|
||||||
|
/* import to GnuPG and other Certificates */
|
||||||
|
bool AuthGPG::LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(gpgMtxEngine); /******* LOCKED ******/
|
||||||
|
|
||||||
|
if(PGPHandler::LoadCertificateFromBinaryData(data,data_len,gpg_id,error_string))
|
||||||
|
{
|
||||||
|
updateOwnSignatureFlag(gpg_id,mOwnGpgId) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
/* import to GnuPG and other Certificates */
|
/* import to GnuPG and other Certificates */
|
||||||
bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string)
|
bool AuthGPG::LoadCertificateFromString(const std::string &str, RsPgpId& gpg_id,std::string& error_string)
|
||||||
|
@ -172,6 +172,7 @@ public:
|
|||||||
*
|
*
|
||||||
****/
|
****/
|
||||||
virtual bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string);
|
virtual bool LoadCertificateFromString(const std::string &pem, RsPgpId& gpg_id,std::string& error_string);
|
||||||
|
virtual bool LoadPGPKeyFromBinaryData(const unsigned char *data,uint32_t data_len, RsPgpId& gpg_id,std::string& error_string);
|
||||||
virtual std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ;
|
virtual std::string SaveCertificateToString(const RsPgpId &id,bool include_signatures) ;
|
||||||
|
|
||||||
// Cached certificates.
|
// Cached certificates.
|
||||||
|
@ -886,8 +886,7 @@ bool p3PeerMgrIMPL::haveOnceConnected()
|
|||||||
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
||||||
|
|
||||||
/* check for existing */
|
/* check for existing */
|
||||||
std::map<RsPeerId, peerState>::iterator it;
|
for(auto it = mFriendList.begin(); it != mFriendList.end(); ++it)
|
||||||
for(it = mFriendList.begin(); it != mFriendList.end(); ++it)
|
|
||||||
{
|
{
|
||||||
if (it->second.lastcontact > 0)
|
if (it->second.lastcontact > 0)
|
||||||
{
|
{
|
||||||
@ -910,6 +909,28 @@ bool p3PeerMgrIMPL::haveOnceConnected()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool p3PeerMgrIMPL::notifyPgpKeyReceived(const RsPgpId& pgp_id)
|
||||||
|
{
|
||||||
|
RsStackMutex stack(mPeerMtx); /****** STACK LOCK MUTEX *******/
|
||||||
|
|
||||||
|
bool changed = false;
|
||||||
|
|
||||||
|
for(auto it(mFriendList.begin());it!=mFriendList.end();++it)
|
||||||
|
{
|
||||||
|
if(it->second.gpg_id == pgp_id)
|
||||||
|
{
|
||||||
|
std::cerr << "(WW) notification that full key " << pgp_id << " is available. Reseting short invite flag for peer " << it->first << std::endl;
|
||||||
|
it->second.skip_pgp_signature_validation = false;
|
||||||
|
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(changed)
|
||||||
|
IndicateConfigChanged();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
/*******************************************************************/
|
/*******************************************************************/
|
||||||
@ -946,16 +967,9 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
|
|||||||
std::map<RsPeerId, peerState>::iterator it;
|
std::map<RsPeerId, peerState>::iterator it;
|
||||||
if (mFriendList.end() != (it=mFriendList.find(id)))
|
if (mFriendList.end() != (it=mFriendList.find(id)))
|
||||||
{
|
{
|
||||||
#ifdef PEER_DEBUG
|
// The friend may already be here, including with a short invite (meaning the PGP key is unknown).
|
||||||
std::cerr << "p3PeerMgrIMPL::addFriend() Already Exists" << std::endl;
|
|
||||||
#endif
|
if(it->second.gpg_id != input_gpg_id)// already exists as a friend with a different PGP id!!
|
||||||
if(it->second.gpg_id.isNull()) // already exists as a SSL-only friend
|
|
||||||
{
|
|
||||||
it->second.gpg_id = input_gpg_id;
|
|
||||||
it->second.skip_pgp_signature_validation = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if(it->second.gpg_id != input_gpg_id)// already exists as a friend with a different PGP id!!
|
|
||||||
{
|
{
|
||||||
RsErr() << "Trying to add SSL id (" << id << ") that is already a friend with existing PGP key (" << it->second.gpg_id << ") but using a different PGP key (" << input_gpg_id << "). This is a bug!" << std::endl;
|
RsErr() << "Trying to add SSL id (" << id << ") that is already a friend with existing PGP key (" << it->second.gpg_id << ") but using a different PGP key (" << input_gpg_id << "). This is a bug!" << std::endl;
|
||||||
return false;
|
return false;
|
||||||
@ -975,6 +989,7 @@ bool p3PeerMgrIMPL::addFriend(const RsPeerId& input_id, const RsPgpId& input_gpg
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// after that, we know that we have the key, because AuthGPG wouldn't answer yes for a key it doesn't know.
|
||||||
|
|
||||||
/* check if it is in others */
|
/* check if it is in others */
|
||||||
if (mOthersList.end() != (it = mOthersList.find(id)))
|
if (mOthersList.end() != (it = mOthersList.find(id)))
|
||||||
|
@ -80,7 +80,6 @@ class peerState
|
|||||||
// have short invites. However, because this represent a significant security risk, we perform multiple consistency checks
|
// have short invites. However, because this represent a significant security risk, we perform multiple consistency checks
|
||||||
// whenever we use this flag, in particular:
|
// whenever we use this flag, in particular:
|
||||||
// flat is true <==> friend SSL cert is in the friend list, but PGP id is not in the friend list
|
// flat is true <==> friend SSL cert is in the friend list, but PGP id is not in the friend list
|
||||||
// PGP id is undefined and therefore set to null
|
|
||||||
|
|
||||||
bool skip_pgp_signature_validation;
|
bool skip_pgp_signature_validation;
|
||||||
|
|
||||||
@ -140,6 +139,9 @@ public:
|
|||||||
const RsPgpId& pgpId,
|
const RsPgpId& pgpId,
|
||||||
const RsPeerDetails& details = RsPeerDetails() ) = 0;
|
const RsPeerDetails& details = RsPeerDetails() ) = 0;
|
||||||
|
|
||||||
|
// Calling this removed the skip_pgp_signature_validation flag on all peers which PGP key is the one supplied.
|
||||||
|
virtual bool notifyPgpKeyReceived(const RsPgpId& pgp_key_id) = 0;
|
||||||
|
|
||||||
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0;
|
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId) = 0;
|
||||||
virtual bool isFriend(const RsPeerId& ssl_id) = 0;
|
virtual bool isFriend(const RsPeerId& ssl_id) = 0;
|
||||||
virtual bool isSslOnlyFriend(const RsPeerId &ssl_id)=0;
|
virtual bool isSslOnlyFriend(const RsPeerId &ssl_id)=0;
|
||||||
@ -259,6 +261,8 @@ public:
|
|||||||
|
|
||||||
bool addSslOnlyFriend(const RsPeerId& sslId, const RsPgpId &pgp_id, const RsPeerDetails& details = RsPeerDetails() ) override;
|
bool addSslOnlyFriend(const RsPeerId& sslId, const RsPgpId &pgp_id, const RsPeerDetails& details = RsPeerDetails() ) override;
|
||||||
|
|
||||||
|
virtual bool notifyPgpKeyReceived(const RsPgpId& pgp_key_id) override;
|
||||||
|
|
||||||
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId);
|
virtual bool removeFriend(const RsPeerId &ssl_id, bool removePgpId);
|
||||||
virtual bool removeFriend(const RsPgpId &pgp_id);
|
virtual bool removeFriend(const RsPgpId &pgp_id);
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ const uint32_t RS_HIDDEN_TYPE_I2P = 0x0004;
|
|||||||
/* mask to match all valid hidden types */
|
/* mask to match all valid hidden types */
|
||||||
const uint32_t RS_HIDDEN_TYPE_MASK = RS_HIDDEN_TYPE_I2P | RS_HIDDEN_TYPE_TOR;
|
const uint32_t RS_HIDDEN_TYPE_MASK = RS_HIDDEN_TYPE_I2P | RS_HIDDEN_TYPE_TOR;
|
||||||
|
|
||||||
/* Visibility */
|
/* Visibility parameter for discovery */
|
||||||
const uint32_t RS_VS_DISC_OFF = 0x0000;
|
const uint32_t RS_VS_DISC_OFF = 0x0000;
|
||||||
const uint32_t RS_VS_DISC_MINIMAL = 0x0001;
|
const uint32_t RS_VS_DISC_MINIMAL = 0x0001;
|
||||||
const uint32_t RS_VS_DISC_FULL = 0x0002;
|
const uint32_t RS_VS_DISC_FULL = 0x0002;
|
||||||
@ -734,6 +734,11 @@ public:
|
|||||||
const std::string& cert, RsPeerDetails& certDetails,
|
const std::string& cert, RsPeerDetails& certDetails,
|
||||||
uint32_t& errorCode ) = 0;
|
uint32_t& errorCode ) = 0;
|
||||||
|
|
||||||
|
virtual bool loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,
|
||||||
|
uint32_t bin_key_len,
|
||||||
|
RsPgpId& gpg_id,
|
||||||
|
std::string& error_string )=0;
|
||||||
|
|
||||||
// Certificate utils
|
// Certificate utils
|
||||||
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert,bool& is_short_format,uint32_t& error_code) = 0;
|
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert,bool& is_short_format,uint32_t& error_code) = 0;
|
||||||
virtual bool saveCertificateToFile(const RsPeerId& id, const std::string &fname) = 0;
|
virtual bool saveCertificateToFile(const RsPeerId& id, const std::string &fname) = 0;
|
||||||
|
@ -1526,12 +1526,25 @@ bool p3Peers::loadCertificateFromString(
|
|||||||
}
|
}
|
||||||
|
|
||||||
RsPgpId gpgid;
|
RsPgpId gpgid;
|
||||||
bool res = AuthGPG::getAuthGPG()->LoadCertificateFromString(
|
bool res = AuthGPG::getAuthGPG()->LoadCertificateFromString( crt->armouredPGPKey(), gpgid, error_string );
|
||||||
crt->armouredPGPKey(), gpgid, error_string );
|
|
||||||
|
|
||||||
gpg_id = gpgid;
|
gpg_id = gpgid;
|
||||||
ssl_id = crt->sslid();
|
ssl_id = crt->sslid();
|
||||||
|
|
||||||
|
// now get all friends who declare this key ID to be the one needed to check connections, and clear their "skip_pgp_signature_validation" flag
|
||||||
|
|
||||||
|
if(res)
|
||||||
|
mPeerMgr->notifyPgpKeyReceived(gpgid);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
bool p3Peers::loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string )
|
||||||
|
{
|
||||||
|
bool res = AuthGPG::getAuthGPG()->LoadPGPKeyFromBinaryData( bin_key_data,bin_key_len, gpg_id, error_string );
|
||||||
|
|
||||||
|
if(res)
|
||||||
|
mPeerMgr->notifyPgpKeyReceived(gpg_id);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,6 +157,7 @@ public:
|
|||||||
virtual bool hasExportMinimal();
|
virtual bool hasExportMinimal();
|
||||||
|
|
||||||
virtual bool loadCertificateFromString(const std::string& cert, RsPeerId& ssl_id,RsPgpId& pgp_id, std::string& error_string);
|
virtual bool loadCertificateFromString(const std::string& cert, RsPeerId& ssl_id,RsPgpId& pgp_id, std::string& error_string);
|
||||||
|
virtual bool loadPgpKeyFromBinaryData( const unsigned char *bin_key_data,uint32_t bin_key_len, RsPgpId& gpg_id, std::string& error_string );
|
||||||
virtual bool loadDetailsFromStringCert(const std::string &cert, RsPeerDetails &pd, uint32_t& error_code);
|
virtual bool loadDetailsFromStringCert(const std::string &cert, RsPeerDetails &pd, uint32_t& error_code);
|
||||||
|
|
||||||
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert, bool &is_short_format, uint32_t& error_code) override;
|
virtual bool cleanCertificate(const std::string &certstr, std::string &cleanCert, bool &is_short_format, uint32_t& error_code) override;
|
||||||
|
Loading…
Reference in New Issue
Block a user