Fix memory management and deprecated removal from serialization

Fix missing RsDiscPgpKeyItem initialization
Fix inconsistent new[]/delete[] usage in RsDiscPgpKeyItem and
  PGPHandler::exportPublicKey which now consistently uses malloc/free
Remove deprecated RsGenericSerializer::FORMAT_*
Move from deprecated RsServiceSerializer::SERIALIZATION_FLAG_* to
  RsSerializationFlags
Solve a bunch of compiler warnings
Stricter checks in SerializeContext costructor
This commit is contained in:
Gioacchino Mazzurco 2020-03-18 23:04:16 +01:00
parent 39bde58c29
commit 5610cc8600
No known key found for this signature in database
GPG Key ID: A1FBCA3872E87051
24 changed files with 230 additions and 244 deletions

View File

@ -221,7 +221,8 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const
mGixs->requestKey(obj->signature.keyId,peer_list,RsIdentityUsage(RS_SERVICE_TYPE_CHAT,RsIdentityUsage::CHAT_LOBBY_MSG_VALIDATION,RsGxsGroupId(),RsGxsMessageId(),obj->lobby_id));
uint32_t size = RsChatSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_SIGNATURE).size(dynamic_cast<RsItem*>(obj)) ;
uint32_t size = RsChatSerialiser(RsSerializationFlags::SIGNATURE)
.size(dynamic_cast<RsItem*>(obj));
RsTemporaryMemory memory(size) ;
#ifdef DEBUG_CHAT_LOBBIES
@ -229,7 +230,8 @@ bool DistributedChatService::checkSignature(RsChatLobbyBouncingObject *obj,const
std::cerr << " signature id: " << obj->signature.keyId << std::endl;
#endif
if(!RsChatSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_SIGNATURE).serialise(dynamic_cast<RsItem*>(obj),memory,&size))
if( !RsChatSerialiser(RsSerializationFlags::SIGNATURE)
.serialise(dynamic_cast<RsItem*>(obj),memory,&size) )
{
std::cerr << " (EE) Cannot serialise message item. " << std::endl;
return false ;
@ -1003,10 +1005,12 @@ bool DistributedChatService::locked_initLobbyBouncableObject(const ChatLobbyId&
// now sign the object, if the lobby expects it
uint32_t size = RsChatSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_SIGNATURE).size(dynamic_cast<RsItem*>(&item)) ;
uint32_t size = RsChatSerialiser(RsSerializationFlags::SIGNATURE)
.size(dynamic_cast<RsItem*>(&item));
RsTemporaryMemory memory(size) ;
if(!RsChatSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_SIGNATURE).serialise(dynamic_cast<RsItem*>(&item),memory,&size))
if( !RsChatSerialiser(RsSerializationFlags::SIGNATURE)
.serialise(dynamic_cast<RsItem*>(&item),memory,&size) )
{
std::cerr << "(EE) Cannot sign message item. " << std::endl;
return false ;

View File

@ -85,8 +85,8 @@ void RsChatLobbyBouncingObject::serial_process(RsGenericSerializer::SerializeJob
RsTypeSerializer::serial_process(j,ctx,msg_id ,"msg_id") ;
RsTypeSerializer::serial_process(j,ctx,TLV_TYPE_STR_NAME,nick,"nick") ;
if(!(ctx.mFlags & RsServiceSerializer::SERIALIZATION_FLAG_SIGNATURE))
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,signature,"signature") ;
if(!(ctx.mFlags & RsSerializationFlags::SIGNATURE))
RS_SERIAL_PROCESS(signature);
}
void RsChatLobbyMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSerializer::SerializeContext& ctx)

View File

@ -369,9 +369,8 @@ struct PrivateOugoingMapItem : RsChatItem
struct RsChatSerialiser : RsServiceSerializer
{
RsChatSerialiser(SerializationFlags flags = SERIALIZATION_FLAG_NONE) :
RsServiceSerializer( RS_SERVICE_TYPE_CHAT,
RsGenericSerializer::FORMAT_BINARY, flags ) {}
RsChatSerialiser(RsSerializationFlags flags = RsSerializationFlags::NONE):
RsServiceSerializer(RS_SERVICE_TYPE_CHAT, flags) {}
virtual RsItem *create_item(uint16_t service_id,uint8_t item_sub_id) const;
};

View File

@ -61,7 +61,7 @@ RsFileTree::fromBase64(const std::string& base64)
RsGenericSerializer::SerializeContext ctx(
mem.data(), static_cast<uint32_t>(mem.size()),
SerializationFlags::fromEFT(RsSerializationFlags::INTEGER_VLQ) );
RsSerializationFlags::INTEGER_VLQ );
std::unique_ptr<RsFileTree> ft(new RsFileTree);
ft->serial_process(
RsGenericSerializer::SerializeJob::DESERIALIZE, ctx);
@ -73,7 +73,7 @@ RsFileTree::fromBase64(const std::string& base64)
std::string RsFileTree::toBase64() const
{
RsGenericSerializer::SerializeContext ctx;
ctx.mFlags = SerializationFlags::fromEFT(RsSerializationFlags::INTEGER_VLQ);
ctx.mFlags = RsSerializationFlags::INTEGER_VLQ;
RsFileTree* ncThis = const_cast<RsFileTree*>(this);
ncThis->serial_process(
RsGenericSerializer::SerializeJob::SIZE_ESTIMATE, ctx );

View File

@ -74,8 +74,8 @@ void RsDiscPgpKeyItem::clear()
{
pgpKeyId.clear();
free(bin_data);
bin_data = nullptr;
bin_len=0;
bin_data = nullptr;
bin_len = 0;
}
void RsDiscContactItem::clear()

View File

@ -84,17 +84,23 @@ class RsDiscPgpKeyItem: public RsDiscItem
{
public:
RsDiscPgpKeyItem() : RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT_BINARY)
RsDiscPgpKeyItem() :
RsDiscItem(RsGossipDiscoveryItemType::PGP_CERT_BINARY),
bin_data(nullptr), bin_len(0)
{ setPriorityLevel(QOS_PRIORITY_RS_DISC_PGP_CERT); }
virtual ~RsDiscPgpKeyItem() { delete[](bin_data);bin_data=nullptr;bin_len=0;}
~RsDiscPgpKeyItem() override { free(bin_data); }
void clear() override;
void serial_process( RsGenericSerializer::SerializeJob j, RsGenericSerializer::SerializeContext& ctx) override;
RsPgpId pgpKeyId; // duplicate information for practical reasons
unsigned char *bin_data; // binry key data allocated with new unsigned char[]
uint32_t bin_len;
void serial_process(
RsGenericSerializer::SerializeJob j,
RsGenericSerializer::SerializeContext& ctx ) override;
/// duplicate information for practical reasons
RsPgpId pgpKeyId;
unsigned char* bin_data;
uint32_t bin_len;
};
class RsDiscContactItem: public RsDiscItem

View File

@ -99,12 +99,10 @@ void RsGRouterGenericDataItem::serial_process(RsGenericSerializer::SerializeJob
RsTypeSerializer::serial_process (j,ctx,destination_key,"destination_key") ;
RsTypeSerializer::serial_process<uint32_t>(j,ctx,service_id,"service_id") ;
RsTypeSerializer::TlvMemBlock_proxy prox(data_bytes,data_size) ;
RsTypeSerializer::RawMemoryWrapper prox(data_bytes, data_size);
RsTypeSerializer::serial_process(j, ctx, prox, "data");
RsTypeSerializer::serial_process(j,ctx,prox,"data") ;
if(ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE)
return ;
if(!!(ctx.mFlags & RsSerializationFlags::SIGNATURE)) return;
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,signature,"signature") ;
RsTypeSerializer::serial_process<uint32_t>(j,ctx,duplication_factor,"duplication_factor") ;
@ -133,8 +131,7 @@ void RsGRouterSignedReceiptItem::serial_process(RsGenericSerializer::SerializeJo
RsTypeSerializer::serial_process<uint32_t> (j,ctx,service_id,"service_id") ;
RsTypeSerializer::serial_process (j,ctx,data_hash,"data_hash") ;
if(ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE)
return ;
if(!!(ctx.mFlags & RsSerializationFlags::SIGNATURE)) return;
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,signature,"signature") ;
}

View File

@ -286,7 +286,9 @@ class RsGRouterRoutingInfoItem: public RsGRouterItem, public GRouterRoutingInfo,
class RsGRouterSerialiser: public RsServiceSerializer
{
public:
explicit RsGRouterSerialiser(SerializationFlags flags = SERIALIZATION_FLAG_NONE) : RsServiceSerializer(RS_SERVICE_TYPE_GROUTER,RsGenericSerializer::FORMAT_BINARY,flags) {}
explicit RsGRouterSerialiser(
RsSerializationFlags flags = RsSerializationFlags::NONE ):
RsServiceSerializer(RS_SERVICE_TYPE_GROUTER, flags) {}
virtual RsItem *create_item(uint16_t service,uint8_t subtype) const ;
};

View File

@ -1658,7 +1658,9 @@ void p3GRouter::handleIncomingReceiptItem(const RsGRouterSignedReceiptItem *rece
Sha1CheckSum p3GRouter::computeDataItemHash(const RsGRouterGenericDataItem *data_item)
{
RsGRouterSerialiser signature_serializer(RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE | RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER);
RsGRouterSerialiser signature_serializer(
RsSerializationFlags::SIGNATURE |
RsSerializationFlags::SKIP_HEADER );
uint32_t signed_data_size = signature_serializer.size(const_cast<RsGRouterGenericDataItem*>(data_item));
uint32_t total_size = signed_data_size + data_item->signature.TlvSize() ;
@ -2034,7 +2036,9 @@ bool p3GRouter::signDataItem(RsGRouterAbstractMsgItem *item,const RsGxsId& signi
std::cerr << " Key ID = " << signing_id << std::endl;
std::cerr << " Getting key material..." << std::endl;
//#endif
RsGRouterSerialiser signature_serializer(RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE | RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER) ;
RsGRouterSerialiser signature_serializer(
RsSerializationFlags::SIGNATURE |
RsSerializationFlags::SKIP_HEADER );
uint32_t data_size = signature_serializer.size(item) ;
RsTemporaryMemory data(data_size) ;
@ -2092,8 +2096,8 @@ bool p3GRouter::verifySignedDataItem(const RsGRouterAbstractMsgItem *item,const
}
RsGRouterSerialiser signature_serializer(
RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE |
RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER );
RsSerializationFlags::SIGNATURE |
RsSerializationFlags::SKIP_HEADER );
uint32_t data_size = signature_serializer.size(const_cast<RsGRouterAbstractMsgItem*>(item)); // the const cast shouldn't be necessary if size() took a const.
RsTemporaryMemory data(data_size);

View File

@ -78,10 +78,10 @@ JsonApiServer::corsOptionsHeaders =
#define INITIALIZE_API_CALL_JSON_CONTEXT \
RsGenericSerializer::SerializeContext cReq( \
nullptr, 0, \
RsGenericSerializer::SERIALIZATION_FLAG_YIELDING ); \
RsSerializationFlags::YIELDING ); \
RsJson& jReq(cReq.mJson); \
if(session->get_request()->get_method() == "GET") \
{ \
{ \
const std::string jrqp(session->get_request()->get_query_parameter("jsonData")); \
jReq.Parse(jrqp.c_str(), jrqp.size()); \
} \

View File

@ -630,50 +630,61 @@ std::string PGPHandler::SaveCertificateToString(const RsPgpId& id,bool include_s
return makeRadixEncodedPGPKey(key,include_signatures) ;
}
bool PGPHandler::exportPublicKey(const RsPgpId& id,unsigned char *& mem_block,size_t& mem_size,bool armoured,bool include_signatures) const
bool PGPHandler::exportPublicKey(
const RsPgpId& id,
rs_view_ptr<unsigned char>& mem_block, size_t& mem_size,
bool armoured, bool include_signatures ) const
{
RsStackMutex mtx(pgphandlerMtx) ; // lock access to PGP memory structures.
const ops_keydata_t *key = locked_getPublicKey(id,false) ;
mem_block = NULL ;
mem_block = nullptr; mem_size = 0; // clear just in case
if(armoured)
{
std::cerr << __PRETTY_FUNCTION__ << ": should not be used with armoured=true, because there's a bug in the armoured export of OPS" << std::endl;
return false ;
RsErr() << __PRETTY_FUNCTION__ << " should not be used with "
<< "armoured=true, because there's a bug in the armoured export"
<< " of OPS" << std::endl;
print_stacktrace();
return false;
}
if(key == NULL)
RS_STACK_MUTEX(pgphandlerMtx);
const ops_keydata_t* key = locked_getPublicKey(id,false);
if(!key)
{
std::cerr << "Cannot output key " << id.toStdString() << ": not found in keyring." << std::endl;
return false ;
RsErr() << __PRETTY_FUNCTION__ << " key id: " << id
<< " not found in keyring." << std::endl;
return false;
}
ops_create_info_t* cinfo;
ops_memory_t *buf = NULL ;
ops_setup_memory_write(&cinfo, &buf, 0);
ops_create_info_t* cinfo;
ops_memory_t *buf = nullptr;
ops_setup_memory_write(&cinfo, &buf, 0);
if(ops_write_transferable_public_key_from_packet_data(key,armoured,cinfo) != ops_true)
if(ops_write_transferable_public_key_from_packet_data(
key, armoured, cinfo ) != ops_true)
{
std::cerr << "ERROR: This key cannot be processed by RetroShare because\nDSA certificates are not yet handled." << std::endl;
return false ;
RsErr() << __PRETTY_FUNCTION__ << " This key id " << id
<< " cannot be processed by RetroShare because DSA certificates"
<< " support is not implemented yet." << std::endl;
return false;
}
ops_writer_close(cinfo) ;
ops_writer_close(cinfo);
mem_block = new unsigned char[ops_memory_get_length(buf)] ;
mem_size = ops_memory_get_length(buf) ;
memcpy(mem_block,ops_memory_get_data(buf),mem_size) ;
mem_size = ops_memory_get_length(buf);
mem_block = reinterpret_cast<unsigned char*>(malloc(mem_size));
memcpy(mem_block,ops_memory_get_data(buf),mem_size);
ops_teardown_memory_write(cinfo,buf);
ops_teardown_memory_write(cinfo,buf);
if(!include_signatures)
{
size_t new_size ;
PGPKeyManagement::findLengthOfMinimalKey(mem_block,mem_size,new_size) ;
mem_size = new_size ;
size_t new_size;
PGPKeyManagement::findLengthOfMinimalKey(mem_block, mem_size, new_size);
mem_size = new_size;
}
return true ;
return true;
}
bool PGPHandler::exportGPGKeyPair(const std::string& filename,const RsPgpId& exported_key_id) const

View File

@ -107,7 +107,9 @@ public:
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 ;
bool exportPublicKey(const RsPgpId& id,unsigned char *& mem,size_t& mem_size,bool armoured,bool include_signatures) const ;
bool exportPublicKey( const RsPgpId& id,
rs_view_ptr<unsigned char>& mem,size_t& mem_size,
bool armoured, bool include_signatures) const;
bool parseSignature(unsigned char *sign, unsigned int signlen,RsPgpId& issuer_id) ;
bool SignDataBin(const RsPgpId& id, const void *data, const uint32_t len, unsigned char *sign, unsigned int *signlen, bool make_raw_signature=false, std::string reason = "") ;

View File

@ -241,7 +241,3 @@ typedef t_RsFlags32<FLAGS_TAG_SERVICE_PERM > ServicePermissionFlags ;
//
typedef t_RsFlags32<FLAGS_TAG_SERVICE_CHAT > ChatLobbyFlags ;
/// @deprecated Flags for serializer
RS_DEPRECATED_FOR(RsSerializationFlags)
typedef t_RsFlags32<FLAGS_TAG_SERIALIZER > SerializationFlags ;

View File

@ -803,7 +803,7 @@ public:
ServicePermissionFlags flags = RS_NODE_PERM_DEFAULT ) = 0;
/* Auth Stuff */
RS_DEPRECATED /// This function doesn't provide meaningful error reporting
virtual std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures) = 0;
virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum) = 0;

View File

@ -45,11 +45,12 @@ struct RsItem : RsMemoryManagement::SmallObject, RsSerializable
/// TODO: Do this make sense with the new serialization system?
virtual void clear() = 0;
/// @deprecated use << ostream operator instead
RS_DEPRECATED_FOR("<< ostream operator")
virtual std::ostream &print(std::ostream &out, uint16_t /* indent */ = 0)
{
RsGenericSerializer::SerializeContext ctx(
NULL, 0, RsGenericSerializer::FORMAT_BINARY,
RsGenericSerializer::SERIALIZATION_FLAG_NONE );
nullptr, 0, RsSerializationFlags::NONE );
serial_process(RsGenericSerializer::PRINT,ctx);
return out;
}

View File

@ -147,8 +147,8 @@ void RsMsgItem::serial_process(RsGenericSerializer::SerializeJob j,RsGenericSeri
RsTypeSerializer::serial_process<RsTlvItem>(j,ctx,attachment,"attachment");
if(ctx.mFlags & RsServiceSerializer::SERIALIZATION_FLAG_CONFIG)
RsTypeSerializer::serial_process<uint32_t>(j,ctx,msgId,"msgId");
if(!!(ctx.mFlags & RsSerializationFlags::CONFIG))
RS_SERIAL_PROCESS(msgId);
}
void RsMsgTagType::clear()

View File

@ -19,8 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#ifndef RS_MSG_ITEMS_H
#define RS_MSG_ITEMS_H
#pragma once
#include <map>
@ -33,10 +32,6 @@
#include "serialiser/rstlvfileitem.h"
#include "grouter/grouteritems.h"
#if 0
#include "serialiser/rstlvtypes.h"
#include "serialiser/rstlvfileitem.h"
#endif
/**************************************************************************/
@ -218,17 +213,12 @@ class RsMsgParentId : public RsMessageItem
class RsMsgSerialiser: public RsServiceSerializer
{
public:
RsMsgSerialiser(SerializationFlags flags = RsServiceSerializer::SERIALIZATION_FLAG_NONE)
:RsServiceSerializer(RS_SERVICE_TYPE_MSG,RsGenericSerializer::FORMAT_BINARY,flags){}
public:
RsMsgSerialiser(
RsSerializationFlags flags = RsSerializationFlags::NONE ):
RsServiceSerializer(RS_SERVICE_TYPE_MSG, flags){}
virtual ~RsMsgSerialiser() {}
RsItem* create_item(uint16_t service,uint8_t type) const override;
virtual RsItem *create_item(uint16_t service,uint8_t type) const ;
~RsMsgSerialiser() override = default;
};
/**************************************************************************/
#endif /* RS_MSG_ITEMS_H */

View File

@ -3,8 +3,9 @@
* *
* libretroshare: retroshare core library *
* *
* Copyright 2004-2008 by Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2015-2018 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2004-2008 Robert Fernie <retroshare@lunamutt.com> *
* Copyright (C) 2015-2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -20,7 +21,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
#include "util/radix64.h"
#include "pgp/pgpkeyutil.h"
#include "rsserver/p3peers.h"
@ -35,7 +36,8 @@
#include "retroshare/rsinit.h"
#include "retroshare/rsfiles.h"
#include "util/rsurl.h"
#include "util/radix64.h"
#include "util/rsbase64.h"
#include "pgp/rscertificate.h"
#include <iostream>
@ -1095,51 +1097,59 @@ bool p3Peers::setProxyServer(const uint32_t type, const std::string &addr_str, c
std::string p3Peers::getPGPKey(const RsPgpId& pgp_id,bool include_signatures)
{
unsigned char *mem_block = NULL;
rs_owner_ptr<unsigned char> mem_block = nullptr;
size_t mem_block_size = 0;
if( !AuthGPG::getAuthGPG()->exportPublicKey(
RsPgpId(pgp_id), mem_block, mem_block_size,
false, include_signatures ) )
{
std::cerr << "Cannot output certificate for id \"" << pgp_id
<< "\". Sorry." << std::endl;
return "" ;
RsErr() << __PRETTY_FUNCTION__
<< " Failure retriving certificate for id " << pgp_id
<< std::endl;
return "";
}
RsPeerDetails Detail;
if(!getGPGDetails(pgp_id,Detail)) return "";
RsPeerDetails details;
if(!getGPGDetails(pgp_id, details)) return "";
RsCertificate cert( Detail,mem_block,mem_block_size );
delete[] mem_block ;
auto certPtr =
RsCertificate::fromMemoryBlock(details, mem_block, mem_block_size);
return cert.armouredPGPKey();
free(mem_block);
if(certPtr) return certPtr->armouredPGPKey();
return "";
}
bool p3Peers::GetPGPBase64StringAndCheckSum( const RsPgpId& gpg_id,
std::string& gpg_base64_string,
std::string& gpg_base64_checksum)
bool p3Peers::GetPGPBase64StringAndCheckSum(
const RsPgpId& gpg_id,
std::string& gpg_base64_string, std::string& gpg_base64_checksum )
{
gpg_base64_string = "" ;
gpg_base64_checksum = "" ;
unsigned char *mem_block ;
size_t mem_block_size ;
rs_owner_ptr<unsigned char> mem_block = nullptr;
size_t mem_block_size = 0;
if(!AuthGPG::getAuthGPG()->exportPublicKey(
gpg_id,mem_block,mem_block_size,false,false ))
return false;
if(!AuthGPG::getAuthGPG()->exportPublicKey(gpg_id,mem_block,mem_block_size,false,false))
return false ;
RsBase64::encode(mem_block, mem_block_size, gpg_base64_string, true, false);
Radix64::encode(mem_block,mem_block_size,gpg_base64_string) ;
uint32_t crc = PGPKeyManagement::compute24bitsCRC(mem_block,mem_block_size);
uint32_t crc = PGPKeyManagement::compute24bitsCRC((unsigned char *)mem_block,mem_block_size) ;
free(mem_block);
unsigned char tmp[3] = { uint8_t((crc >> 16) & 0xff), uint8_t((crc >> 8) & 0xff), uint8_t(crc & 0xff) } ;
Radix64::encode(tmp,3,gpg_base64_checksum) ;
unsigned char tmp[3] = {
uint8_t((crc >> 16) & 0xff),
uint8_t((crc >> 8) & 0xff),
uint8_t(crc & 0xff) } ;
RsBase64::encode(tmp, 3, gpg_base64_checksum, true, false);
delete[] mem_block ;
return true ;
return true;
}
enum class RsShortInviteFieldType : uint8_t

View File

@ -141,7 +141,8 @@ public:
virtual std::string GetRetroshareInvite(
const RsPeerId& ssl_id = RsPeerId(),
bool include_signatures = false, bool includeExtraLocators = true );
virtual std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures);
RS_DEPRECATED /// @see RsPeers
std::string getPGPKey(const RsPgpId& pgp_id,bool include_signatures) override;
virtual bool GetPGPBase64StringAndCheckSum(const RsPgpId& gpg_id,std::string& gpg_base64_string,std::string& gpg_base64_checksum);

View File

@ -4,6 +4,8 @@
* libretroshare: retroshare core library *
* *
* Copyright (C) 2016 Cyril Soler <csoler@users.sourceforge.net> *
* Copyright (C) 2020 Gioacchino Mazzurco <gio@eigenlab.org> *
* Copyright (C) 2020 Asociación Civil Altermundi <info@altermundi.net> *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
@ -18,23 +20,17 @@
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
* *
*******************************************************************************/
******************************************************************************/
#include <typeinfo>
#include "rsitems/rsitem.h"
#include "util/rsprint.h"
#include "serialiser/rsserializer.h"
#include "serialiser/rstypeserializer.h"
#include "util/stacktrace.h"
#include "util/rsdebug.h"
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_NONE ( 0x0000 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_CONFIG ( 0x0001 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_SIGNATURE ( 0x0002 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_SKIP_HEADER ( 0x0004 );
const SerializationFlags RsGenericSerializer::SERIALIZATION_FLAG_YIELDING ( 0x0008 );
RsItem *RsServiceSerializer::deserialise(void *data, uint32_t *size)
{
if(!data || !size || !*size)
@ -47,11 +43,13 @@ RsItem *RsServiceSerializer::deserialise(void *data, uint32_t *size)
return nullptr;
}
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
{
std::cerr << "(EE) Cannot deserialise item with flags SERIALIZATION_FLAG_SKIP_HEADER. Check your code!" << std::endl;
return NULL ;
}
if(!!(mFlags & RsSerializationFlags::SKIP_HEADER))
{
RsErr() << __PRETTY_FUNCTION__ << " Cannot deserialise item with flag "
<< "SKIP_HEADER. Check your code!" << std::endl;
print_stacktrace();
return nullptr;
}
uint32_t rstype = getRsItemId(const_cast<void*>((const void*)data)) ;
@ -64,7 +62,9 @@ RsItem *RsServiceSerializer::deserialise(void *data, uint32_t *size)
return NULL ;
}
SerializeContext ctx(const_cast<uint8_t*>(static_cast<uint8_t*>(data)),*size,mFormat,mFlags);
SerializeContext ctx(
const_cast<uint8_t*>(static_cast<uint8_t*>(data)), *size,
mFlags );
ctx.mOffset = 8 ;
item->serial_process(RsGenericSerializer::DESERIALIZE, ctx) ;
@ -85,11 +85,13 @@ RsItem *RsServiceSerializer::deserialise(void *data, uint32_t *size)
}
RsItem *RsConfigSerializer::deserialise(void *data, uint32_t *size)
{
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
{
std::cerr << "(EE) Cannot deserialise item with flags SERIALIZATION_FLAG_SKIP_HEADER. Check your code!" << std::endl;
return NULL ;
}
if(!!(mFlags & RsSerializationFlags::SKIP_HEADER))
{
RsErr() << __PRETTY_FUNCTION__ << " Cannot deserialise item with flag "
<< "SKIP_HEADER. Check your code!" << std::endl;
print_stacktrace();
return nullptr;
}
uint32_t rstype = getRsItemId(const_cast<void*>((const void*)data)) ;
@ -102,7 +104,9 @@ RsItem *RsConfigSerializer::deserialise(void *data, uint32_t *size)
return NULL ;
}
SerializeContext ctx(const_cast<uint8_t*>(static_cast<uint8_t*>(data)),*size,mFormat,mFlags);
SerializeContext ctx(
const_cast<uint8_t*>(static_cast<uint8_t*>(data)), *size,
mFlags );
ctx.mOffset = 8 ;
item->serial_process(DESERIALIZE, ctx) ;
@ -121,50 +125,44 @@ RsItem *RsConfigSerializer::deserialise(void *data, uint32_t *size)
delete item ;
return NULL ;
}
bool RsGenericSerializer::serialise(RsItem *item,void *data,uint32_t *size)
bool RsGenericSerializer::serialise(RsItem* item, void* data, uint32_t* size)
{
SerializeContext ctx(static_cast<uint8_t*>(data),0,mFormat,mFlags);
uint32_t tlvsize = this->size(item);
uint32_t tlvsize = this->size(item) ;
constexpr auto fName = __PRETTY_FUNCTION__;
const auto failure = [=](std::error_condition ec)
{
RsErr() << fName << " " << ec << std::endl;
print_stacktrace();
return false;
};
if(tlvsize > *size)
throw std::runtime_error("Cannot serialise: not enough room.") ;
if(tlvsize > *size) return failure(std::errc::no_buffer_space);
SerializeContext ctx(static_cast<uint8_t*>(data), tlvsize, mFlags);
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
ctx.mOffset = 0;
else
if(!(mFlags & RsSerializationFlags::SKIP_HEADER))
{
if(!setRsItemHeader(data, tlvsize, item->PacketId(), tlvsize))
{
std::cerr << "RsSerializer::serialise_item(): ERROR. Not enough size!" << std::endl;
return false ;
}
return failure(std::errc::no_buffer_space);
ctx.mOffset = 8;
}
ctx.mSize = tlvsize;
item->serial_process(RsGenericSerializer::SERIALIZE,ctx);
item->serial_process(RsGenericSerializer::SERIALIZE,ctx) ;
if(ctx.mSize != ctx.mOffset) return failure(std::errc::message_size);
if(ctx.mSize != ctx.mOffset)
{
std::cerr << "RsSerializer::serialise(): ERROR. offset does not match expected size!" << std::endl;
return false ;
}
*size = ctx.mOffset ;
return true ;
*size = ctx.mOffset;
return true;
}
uint32_t RsGenericSerializer::size(RsItem *item)
{
SerializeContext ctx(NULL,0,mFormat,mFlags);
SerializeContext ctx(nullptr, 0, mFlags);
if(mFlags & SERIALIZATION_FLAG_SKIP_HEADER)
ctx.mOffset = 0;
else
ctx.mOffset = 8 ; // header size
if(!!(mFlags & RsSerializationFlags::SKIP_HEADER)) ctx.mOffset = 0;
else ctx.mOffset = 8; // header size
item->serial_process(SIZE_ESTIMATE, ctx) ;
return ctx.mOffset ;
@ -172,7 +170,7 @@ uint32_t RsGenericSerializer::size(RsItem *item)
void RsGenericSerializer::print(RsItem *item)
{
SerializeContext ctx(NULL,0,mFormat,mFlags);
SerializeContext ctx(nullptr, 0, mFlags);
std::cerr << "***** RsItem class: \"" << typeid(*item).name() << "\" *****" << std::endl;
item->serial_process(PRINT, ctx) ;
@ -255,7 +253,7 @@ RsItem *RsRawSerialiser::deserialise(void *data, uint32_t *pktsize)
RsGenericSerializer::SerializeContext::SerializeContext(
uint8_t* data, uint32_t size, SerializationFlags flags,
uint8_t* data, uint32_t size, RsSerializationFlags flags,
RsJson::AllocatorType* allocator ) :
mData(data), mSize(size), mOffset(0), mOk(true), mFlags(flags),
mJson(rapidjson::kObjectType, allocator)
@ -264,20 +262,23 @@ RsGenericSerializer::SerializeContext::SerializeContext(
{
if(size == 0)
{
std::cerr << __PRETTY_FUNCTION__ << " data passed without "
<< "size! This make no sense report to developers!"
<< std::endl;
RsFatal() << __PRETTY_FUNCTION__ << " data passed without "
<< "size! This make no sense report to developers!"
<< std::endl;
print_stacktrace();
exit(-EINVAL);
}
if(flags & SERIALIZATION_FLAG_YIELDING)
if(!!(flags & RsSerializationFlags::YIELDING))
{
std::cerr << __PRETTY_FUNCTION__ << " Attempt to create a "
RsFatal() << __PRETTY_FUNCTION__
<< " Attempt to create a "
<< "binary serialization context with "
<< "SERIALIZATION_FLAG_YIELDING! "
<< "This make no sense report to developers!"
<< std::endl;
print_stacktrace();
exit(-EINVAL);
}
}
}

View File

@ -238,58 +238,23 @@ struct RsGenericSerializer : RsSerialType
FROM_JSON
} SerializeJob;
/** @deprecated use SerializeJob instead */
RS_DEPRECATED typedef enum
{
FORMAT_BINARY = 0x01,
FORMAT_JSON = 0x02
} SerializationFormat;
struct SerializeContext
{
/** Allow shared allocator usage to avoid costly JSON deepcopy for
* nested RsSerializable */
SerializeContext(
uint8_t* data = nullptr, uint32_t size = 0,
SerializationFlags flags = SERIALIZATION_FLAG_NONE,
RsSerializationFlags flags = RsSerializationFlags::NONE,
RsJson::AllocatorType* allocator = nullptr);
RS_DEPRECATED SerializeContext(
uint8_t *data, uint32_t size, SerializationFormat format,
SerializationFlags flags,
RsJson::AllocatorType* allocator = nullptr) :
mData(data), mSize(size), mOffset(0), mOk(true), mFormat(format),
mFlags{flags}, mJson(rapidjson::kObjectType, allocator) {}
unsigned char *mData;
uint32_t mSize;
uint32_t mOffset;
bool mOk;
RS_DEPRECATED SerializationFormat mFormat;
SerializationFlags mFlags;
RsSerializationFlags mFlags;
RsJson mJson;
};
/** These are convenience flags to be used by the items when processing the
* data. The names of the flags are not very important. What matters is that
* the serial_process() method of each item correctly deals with the data
* when it sees the flags, if the serialiser sets them.
* By default the flags are not set and shouldn't be handled.
* When deriving a new serializer, the user can set his own flags, using
* compatible values
*/
static const SerializationFlags SERIALIZATION_FLAG_NONE; // 0x0000
static const SerializationFlags SERIALIZATION_FLAG_CONFIG; // 0x0001
static const SerializationFlags SERIALIZATION_FLAG_SIGNATURE; // 0x0002
static const SerializationFlags SERIALIZATION_FLAG_SKIP_HEADER; // 0x0004
/** Used for JSON deserialization in JSON API, it causes the deserialization
* to continue even if some field is missing (or incorrect), this way the
* API is more user friendly as some methods need just part of the structs
* they take as parameters. */
static const SerializationFlags SERIALIZATION_FLAG_YIELDING; // 0x0008
/**
* The following functions overload RsSerialType.
* They *should not* need to be further overloaded.
@ -302,18 +267,15 @@ struct RsGenericSerializer : RsSerialType
protected:
RsGenericSerializer(
uint8_t serial_class, uint8_t serial_type,
SerializationFormat format, SerializationFlags flags ) :
RsSerializationFlags flags ):
RsSerialType( RS_PKT_VERSION1, serial_class, serial_type),
mFormat(format), mFlags(flags) {}
RsGenericSerializer(
uint16_t service, SerializationFormat format,
SerializationFlags flags ) :
RsSerialType( RS_PKT_VERSION_SERVICE, service ), mFormat(format),
mFlags(flags) {}
SerializationFormat mFormat;
SerializationFlags mFlags;
RsGenericSerializer(
uint16_t service, RsSerializationFlags flags ):
RsSerialType( RS_PKT_VERSION_SERVICE, service ), mFlags(flags) {}
RsSerializationFlags mFlags;
};
@ -323,9 +285,9 @@ protected:
struct RsServiceSerializer : RsGenericSerializer
{
RsServiceSerializer(
uint16_t service_id, SerializationFormat format = FORMAT_BINARY,
SerializationFlags flags = SERIALIZATION_FLAG_NONE ) :
RsGenericSerializer(service_id, format, flags) {}
uint16_t service_id,
RsSerializationFlags flags = RsSerializationFlags::NONE ) :
RsGenericSerializer(service_id, flags) {}
/*! should be overloaded to create the correct type of item depending on the
* data */
@ -342,11 +304,10 @@ struct RsServiceSerializer : RsGenericSerializer
*/
struct RsConfigSerializer : RsGenericSerializer
{
RsConfigSerializer(uint8_t config_class,
uint8_t config_type,
SerializationFormat format = FORMAT_BINARY,
SerializationFlags flags = SERIALIZATION_FLAG_NONE) :
RsGenericSerializer(config_class,config_type,format,flags) {}
RsConfigSerializer(
uint8_t config_class, uint8_t config_type,
RsSerializationFlags flags = RsSerializationFlags::NONE ) :
RsGenericSerializer(config_class, config_type, flags) {}
/*! should be overloaded to create the correct type of item depending on the
* data */

View File

@ -542,7 +542,7 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
uint32_t serialSize = 0;
RS_SERIAL_PROCESS(serialSize);
if(!ctx.mOk) break;
ctx.mOk = serialSize <= MAX_SERIALIZED_CHUNK_SIZE;
ctx.mOk = serialSize <= MAX_SERIALIZED_CHUNK_SIZE;
if(!ctx.mOk)
{
RsErr() << __PRETTY_FUNCTION__
@ -555,6 +555,8 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
if(!serialSize)
{
Dbg3() << __PRETTY_FUNCTION__ << " Deserialized empty memory chunk"
<< std::endl;
clear();
break;
}
@ -573,7 +575,7 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
if(serialSize != second)
{
first = reinterpret_cast<uint8_t*>(realloc(first, serialSize));
second = static_cast<uint32_t>(serialSize);
second = serialSize;
}
memcpy(first, ctx.mData + ctx.mOffset, second);
@ -593,8 +595,8 @@ void RsTypeSerializer::RawMemoryWrapper::serial_process(
}
case RsGenericSerializer::FROM_JSON:
{
const bool yelding = !!( RsSerializationFlags::YIELDING &
ctx.mFlags.toEFT<RsSerializationFlags>() );
const bool yelding = !!(
RsSerializationFlags::YIELDING & ctx.mFlags );
if(!(ctx.mOk || yelding))
{
clear();

View File

@ -82,8 +82,7 @@ struct RsTypeSerializer
INTT& member, const std::string& member_name )
{
const bool VLQ_ENCODING = !!(
RsSerializationFlags::INTEGER_VLQ &
ctx.mFlags.toEFT<RsSerializationFlags>() );
RsSerializationFlags::INTEGER_VLQ & ctx.mFlags );
switch(j)
{
@ -149,8 +148,7 @@ struct RsTypeSerializer
break;
case RsGenericSerializer::FROM_JSON:
ctx.mOk &= ( ctx.mOk ||
!!( RsSerializationFlags::YIELDING &
ctx.mFlags.toEFT<RsSerializationFlags>() ) )
!!(RsSerializationFlags::YIELDING & ctx.mFlags) )
&& from_JSON(member_name, member, ctx.mJson);
break;
default: fatalUnknownSerialJob(j);
@ -198,7 +196,8 @@ struct RsTypeSerializer
ctx.mOk = ctx.mOk && to_JSON(member_name, member, ctx.mJson);
break;
case RsGenericSerializer::FROM_JSON:
ctx.mOk &= (ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING)
ctx.mOk &= ( ctx.mOk ||
!!(ctx.mFlags & RsSerializationFlags::YIELDING) )
&& from_JSON(member_name, member, ctx.mJson);
break;
default: fatalUnknownSerialJob(j);
@ -236,7 +235,7 @@ struct RsTypeSerializer
break;
case RsGenericSerializer::FROM_JSON:
ctx.mOk &=
(ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING)
(ctx.mOk || !!(ctx.mFlags & RsSerializationFlags::YIELDING))
&& from_JSON(member_name, type_id, member, ctx.mJson);
break;
default: fatalUnknownSerialJob(j);
@ -324,7 +323,7 @@ struct RsTypeSerializer
{
using namespace rapidjson;
bool ok = ctx.mOk || ctx.mFlags & RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;
bool ok = ctx.mOk || !!(ctx.mFlags & RsSerializationFlags::YIELDING);
Document& jDoc(ctx.mJson);
Document::AllocatorType& allocator = jDoc.GetAllocator();
@ -424,8 +423,7 @@ struct RsTypeSerializer
RsJson& jDoc(ctx.mJson);
const char* mName = memberName.c_str();
bool hasMember = jDoc.HasMember(mName);
bool yielding = ctx.mFlags &
RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;
bool yielding = !!(ctx.mFlags & RsSerializationFlags::YIELDING);
if(!hasMember)
{
@ -560,8 +558,7 @@ struct RsTypeSerializer
{
using namespace rapidjson;
bool ok = ctx.mOk || ctx.mFlags &
RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;
bool ok = ctx.mOk || !!(ctx.mFlags & RsSerializationFlags::YIELDING);
Document& jDoc(ctx.mJson);
Document::AllocatorType& allocator = jDoc.GetAllocator();
@ -669,8 +666,8 @@ struct RsTypeSerializer
break;
case RsGenericSerializer::FROM_JSON:
{
bool ok = ctx.mOk || !!( ctx.mFlags.toEFT<RsSerializationFlags>()
& RsSerializationFlags::YIELDING );
bool ok = ctx.mOk || !!(
ctx.mFlags & RsSerializationFlags::YIELDING );
ctx.mOk = ok && from_JSON(memberName, member, ctx.mJson) && ctx.mOk;
break;
}
@ -760,8 +757,7 @@ struct RsTypeSerializer
RsJson& jDoc(ctx.mJson);
const char* mName = memberName.c_str();
bool hasMember = jDoc.HasMember(mName);
bool yielding = ctx.mFlags &
RsGenericSerializer::SERIALIZATION_FLAG_YIELDING;
bool yielding = !!(ctx.mFlags & RsSerializationFlags::YIELDING);
if(!hasMember)
{

View File

@ -80,7 +80,9 @@ p3MsgService::p3MsgService( p3ServiceControl *sc, p3IdService *id_serv,
recentlyReceivedMutex("p3MsgService recently received hash mutex"),
mGxsTransServ(gxsMS)
{
_serialiser = new RsMsgSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_NONE); // this serialiser is used for services. It's not the same than the one returned by setupSerialiser(). We need both!!
/* this serialiser is used for services. It's not the same than the one
* returned by setupSerialiser(). We need both!! */
_serialiser = new RsMsgSerialiser();
addSerialType(_serialiser);
/* MsgIds are not transmitted, but only used locally as a storage index.
@ -509,7 +511,7 @@ RsSerialiser* p3MsgService::setupSerialiser() // this serialiser is used for con
{
RsSerialiser *rss = new RsSerialiser ;
rss->addSerialType(new RsMsgSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_CONFIG));
rss->addSerialType(new RsMsgSerialiser(RsSerializationFlags::CONFIG));
rss->addSerialType(new RsGeneralConfigSerialiser());
return rss;
@ -2386,10 +2388,11 @@ void p3MsgService::sendDistantMsgItem(RsMsgItem *msgitem)
/* The item is serialized and turned into a generic turtle item. Use use the
* explicit serialiser to make sure that the msgId is not included */
uint32_t msg_serialized_rssize = RsMsgSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_NONE).size(msgitem) ;
uint32_t msg_serialized_rssize = RsMsgSerialiser().size(msgitem);
RsTemporaryMemory msg_serialized_data(msg_serialized_rssize) ;
if(!RsMsgSerialiser(RsServiceSerializer::SERIALIZATION_FLAG_NONE).serialise(msgitem,msg_serialized_data,&msg_serialized_rssize))
if( !RsMsgSerialiser().
serialise(msgitem,msg_serialized_data,&msg_serialized_rssize) )
{
std::cerr << "(EE) p3MsgService::sendTurtleData(): Serialization error." << std::endl;
return ;