diff --git a/libretroshare/src/gxs/rsgenexchange.h b/libretroshare/src/gxs/rsgenexchange.h index f14619c45..b918789c7 100644 --- a/libretroshare/src/gxs/rsgenexchange.h +++ b/libretroshare/src/gxs/rsgenexchange.h @@ -718,18 +718,19 @@ private: */ uint8_t createGroup(RsNxsGrp* grp, RsTlvSecurityKeySet& keySet); +protected: /*! * This completes the creation of an instance on RsNxsMsg * by assigning it a groupId and signature via SHA1 and EVP_sign respectively * What signatures are calculated are based on the authentication policy * of the service * @param msg the Nxs message to create - * CREATE_FAIL, CREATE_SUCCESS, CREATE_ID_SIGN_NOT_AVAIL * @return CREATE_SUCCESS for success, CREATE_FAIL for fail, * CREATE_FAIL_TRY_LATER for Id sign key not avail (but requested) */ int createMessage(RsNxsMsg* msg); +private: /*! * convenience function to create sign * @param signSet signatures are stored here @@ -876,8 +877,7 @@ private: time_t mLastCheck; RsGxsIntegrityCheck* mIntegrityCheck; -private: - +protected: // TODO: cleanup this should be an enum! const uint8_t CREATE_FAIL, CREATE_SUCCESS, CREATE_FAIL_TRY_LATER, SIGN_MAX_WAITING_TIME; const uint8_t SIGN_FAIL, SIGN_SUCCESS, SIGN_FAIL_TRY_LATER; diff --git a/libretroshare/src/serialiser/rsgxsmailitems.cc b/libretroshare/src/serialiser/rsgxsmailitems.cc index 40d71b220..38cd90140 100644 --- a/libretroshare/src/serialiser/rsgxsmailitems.cc +++ b/libretroshare/src/serialiser/rsgxsmailitems.cc @@ -28,6 +28,7 @@ bool RsGxsMailBaseItem::serialize(uint8_t* data, uint32_t size, ok = ok && (offset += 8); // Take header in account ok = ok && setRawUInt8(data, size, &offset, cryptoType); ok = ok && recipientsHint.serialise(data, size, offset); + ok = ok && setRawUInt64(data, size, &offset, receiptId); return ok; } @@ -42,6 +43,7 @@ bool RsGxsMailBaseItem::deserialize(const uint8_t* data, uint32_t& size, ok = ok && getRawUInt8(dataPtr, rssize, &roffset, &crType); cryptoType = static_cast(crType); ok = ok && recipientsHint.deserialise(dataPtr, rssize, roffset); + ok = ok && getRawUInt64(dataPtr, rssize, &roffset, &receiptId); if(ok) { size = rssize; offset = roffset; } else size = 0; return ok; @@ -68,19 +70,19 @@ bool RsGxsMailSerializer::serialise(RsItem* item, void* data, uint32_t* size) { uint32_t offset = 0; RsGxsMailItem* i = dynamic_cast(item); - ok = ok && i->serialize(dataPtr, itemSize, offset); + ok = i->serialize(dataPtr, itemSize, offset); break; } - case GXS_MAIL_SUBTYPE_ACK: + case GXS_MAIL_SUBTYPE_RECEIPT: { - RsGxsMailAckItem* i = dynamic_cast(item); - ok = ok && setRsItemHeader(data, itemSize, item->PacketId(), itemSize); - uint32_t offset = 8; - ok = ok && i->recipient.serialise(data, itemSize, offset); + RsGxsMailPresignedReceipt* i = + dynamic_cast(item); + uint32_t offset = 0; + ok = i->serialize(dataPtr, itemSize, offset); break; } case GXS_MAIL_SUBTYPE_GROUP: - ok = ok && setRsItemHeader(data, itemSize, item->PacketId(), itemSize); + ok = setRsItemHeader(data, itemSize, item->PacketId(), itemSize); break; default: ok = false; break; } @@ -94,3 +96,4 @@ bool RsGxsMailSerializer::serialise(RsItem* item, void* data, uint32_t* size) std::cout << "RsGxsMailSerializer::serialise(...) failed!" << std::endl; return false; } + diff --git a/libretroshare/src/serialiser/rsgxsmailitems.h b/libretroshare/src/serialiser/rsgxsmailitems.h index 278b18c48..f215d10a2 100644 --- a/libretroshare/src/serialiser/rsgxsmailitems.h +++ b/libretroshare/src/serialiser/rsgxsmailitems.h @@ -30,16 +30,60 @@ enum GxsMailItemsSubtypes { GXS_MAIL_SUBTYPE_MAIL = 1, - GXS_MAIL_SUBTYPE_ACK = 2, + GXS_MAIL_SUBTYPE_RECEIPT = 2, GXS_MAIL_SUBTYPE_GROUP = 3 }; +struct RsNxsMailPresignedReceipt : RsNxsMsg +{ + RsNxsMailPresignedReceipt() : RsNxsMsg(RS_SERVICE_TYPE_GXS_MAIL) {} +}; + +struct RsGxsMailPresignedReceipt : RsGxsMsgItem +{ + RsGxsMailPresignedReceipt() : + RsGxsMsgItem( RS_SERVICE_TYPE_GXS_MAIL, + static_cast(GXS_MAIL_SUBTYPE_RECEIPT) ), + receiptId(0) {} + + uint64_t receiptId; + + static uint32_t inline size() + { + return 8 + // Header + 8; // receiptId + } + bool serialize(uint8_t* data, uint32_t size, uint32_t& offset) const + { + bool ok = setRsItemHeader(data, size, PacketId(), size); + ok = ok && (offset += 8); // Take header in account + ok = ok && setRawUInt64(data, size, &offset, receiptId); + return ok; + } + bool deserialize(const uint8_t* data, uint32_t& size, uint32_t& offset) + { + void* dataPtr = reinterpret_cast(const_cast(data)); + uint32_t rssize = getRsItemSize(dataPtr); + uint32_t roffset = offset + 8; // Take header in account + bool ok = rssize <= size; + ok = ok && getRawUInt64(dataPtr, rssize, &roffset, &receiptId); + if(ok) { size = rssize; offset = roffset; } + else size = 0; + return ok; + } + + void clear() { receiptId = 0; } + std::ostream &print(std::ostream &out, uint16_t /*indent = 0*/) + { return out << receiptId; } +}; + + struct RsGxsMailBaseItem : RsGxsMsgItem { RsGxsMailBaseItem(GxsMailItemsSubtypes subtype) : RsGxsMsgItem( RS_SERVICE_TYPE_GXS_MAIL, static_cast(subtype) ), - cryptoType(UNDEFINED_ENCRYPTION) {} + cryptoType(UNDEFINED_ENCRYPTION), receiptId(0) {} /// Values must fit into uint8_t enum EncryptionMode @@ -107,10 +151,13 @@ struct RsGxsMailBaseItem : RsGxsMsgItem const static RsGxsId allRecipientsHint; + uint64_t receiptId; + void inline clear() { cryptoType = UNDEFINED_ENCRYPTION; recipientsHint.clear(); + receiptId = 0; meta = RsMsgMetaData(); } @@ -118,7 +165,8 @@ struct RsGxsMailBaseItem : RsGxsMsgItem { return 8 + // Header 1 + // cryptoType - RsGxsId::serial_size(); // recipientsHint + RsGxsId::serial_size() + // recipientsHint + 8; // receiptId } bool serialize(uint8_t* data, uint32_t size, uint32_t& offset) const; bool deserialize(const uint8_t* data, uint32_t& size, uint32_t& offset); @@ -160,16 +208,6 @@ struct RsGxsMailItem : RsGxsMailBaseItem const static uint32_t MAX_SIZE = 10*8*1024*1024; }; -struct RsGxsMailAckItem : RsGxsMailBaseItem -{ - RsGxsMailAckItem() : RsGxsMailBaseItem(GXS_MAIL_SUBTYPE_ACK) {} - RsGxsId recipient; - - void clear() { recipient.clear(); } - std::ostream &print(std::ostream &out, uint16_t /*indent = 0*/) - { return out << recipient.toStdString(); } -}; - struct RsGxsMailGroupItem : RsGxsGrpItem { RsGxsMailGroupItem() : @@ -202,18 +240,8 @@ struct RsGxsMailSerializer : RsSerialType if(i) sz = i->size(); break; } - case GXS_MAIL_SUBTYPE_ACK: - { - RsGxsMailAckItem* i = dynamic_cast(item); - if(i) - { - sz = 8; // Header - sz += 4; // RsGxsMailBaseItem::recipient_hint - sz += 1; // RsGxsMailAckItem::read - sz += i->recipient.serial_size(); - } - break; - } + case GXS_MAIL_SUBTYPE_RECEIPT: + sz = RsGxsMailPresignedReceipt::size(); break; case GXS_MAIL_SUBTYPE_GROUP: sz = 8; break; default: break; } @@ -229,6 +257,7 @@ struct RsGxsMailSerializer : RsSerialType uint32_t rssize = getRsItemSize(data); uint8_t pktv = getRsItemVersion(rstype); uint16_t srvc = getRsItemService(rstype); + const uint8_t* dataPtr = reinterpret_cast(data); if ( (RS_PKT_VERSION_SERVICE != pktv) || // 0x02 (RS_SERVICE_TYPE_GXS_MAIL != srvc) || // 0x0230 = 560 @@ -248,16 +277,15 @@ struct RsGxsMailSerializer : RsSerialType { RsGxsMailItem* i = new RsGxsMailItem(); uint32_t offset = 0; - const uint8_t* dataPtr = reinterpret_cast(data); ok = ok && i->deserialize(dataPtr, *size, offset); ret = i; break; } - case GXS_MAIL_SUBTYPE_ACK: + case GXS_MAIL_SUBTYPE_RECEIPT: { - RsGxsMailAckItem* i = new RsGxsMailAckItem(); + RsGxsMailPresignedReceipt* i = new RsGxsMailPresignedReceipt(); uint32_t offset = 0; - ok &= i->recipient.deserialise(data, *size, offset); + ok &= i->deserialize(dataPtr, *size, offset); ret = i; break; } diff --git a/libretroshare/src/serialiser/rsnxsitems.cc b/libretroshare/src/serialiser/rsnxsitems.cc index d17002ca9..db7892c8a 100644 --- a/libretroshare/src/serialiser/rsnxsitems.cc +++ b/libretroshare/src/serialiser/rsnxsitems.cc @@ -199,6 +199,30 @@ bool RsNxsMsg::serialise(void *data, uint32_t& size) const return ok; } +bool RsNxsMsg::deserialize( const uint8_t* data, uint32_t& size, + uint32_t& offset ) +{ + void* dataPtr = reinterpret_cast(const_cast(data+offset)); + + uint32_t rssize = getRsItemSize(dataPtr); + uint32_t roffset = 8; // Take header in account + + bool ok = rssize+offset <= size; + ok = ok && getRawUInt32(dataPtr, rssize, &roffset, &transactionNumber); + ok = ok && getRawUInt8(dataPtr, rssize, &roffset, &pos); + ok = ok && msgId.deserialise(dataPtr, rssize, roffset); + ok = ok && grpId.deserialise(dataPtr, rssize, roffset); + ok = ok && msg.GetTlv(dataPtr, rssize, &roffset); + ok = ok && meta.GetTlv(dataPtr, rssize, &roffset); + + if(ok) { size = rssize; offset += roffset; } + else std::cerr << "RsNxsMsg::deserialize(, " << size << ", " << offset + << ") failed at: " << roffset << " rssize: " << rssize + << std::endl; + + return ok; +} + bool RsNxsGrp::serialise(void *data, uint32_t& size) const { @@ -519,20 +543,13 @@ RsNxsGrp* RsNxsSerialiser::deserialNxsGrpItem(void *data, uint32_t *size) } -RsNxsMsg* RsNxsSerialiser::deserialNxsMsgItem(void *data, uint32_t *size){ +RsNxsMsg* RsNxsSerialiser::deserialNxsMsgItem(void *data, uint32_t *size) +{ + if (!checkItemHeader(data, size, RS_PKT_SUBTYPE_NXS_MSG_ITEM)) return NULL; - bool ok = checkItemHeader(data,size,RS_PKT_SUBTYPE_NXS_MSG_ITEM); - uint32_t offset = 8; - - RsNxsMsg* item = new RsNxsMsg(SERVICE_TYPE); - /* skip the header */ - - ok &= getRawUInt32(data, *size, &offset, &(item->transactionNumber)); - ok &= getRawUInt8(data, *size, &offset, &(item->pos)); - ok &= item->msgId.deserialise(data, *size, offset); - ok &= item->grpId.deserialise(data, *size, offset); - ok &= item->msg.GetTlv(data, *size, &offset); - ok &= item->meta.GetTlv(data, *size, &offset); + RsNxsMsg* item = new RsNxsMsg(SERVICE_TYPE); + uint32_t offset = 0; + bool ok = item->deserialize(static_cast(data), *size, offset); if (offset != *size) { diff --git a/libretroshare/src/serialiser/rsnxsitems.h b/libretroshare/src/serialiser/rsnxsitems.h index 88f0ca914..ad450bd50 100644 --- a/libretroshare/src/serialiser/rsnxsitems.h +++ b/libretroshare/src/serialiser/rsnxsitems.h @@ -399,50 +399,39 @@ public: * Used to respond to a RsGrpMsgsReq * with message items satisfying request */ -class RsNxsMsg : public RsNxsItem +struct RsNxsMsg : RsNxsItem { -public: + RsNxsMsg(uint16_t servtype) : + RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG_ITEM), meta(servtype), + msg(servtype), metaData(NULL) { clear(); } + virtual ~RsNxsMsg() { delete metaData; } - RsNxsMsg(uint16_t servtype) : RsNxsItem(servtype, RS_PKT_SUBTYPE_NXS_MSG_ITEM), meta(servtype), msg(servtype), - metaData(NULL) { - // std::cout << "\nrefcount++ : " << ++refcount << std::endl; - clear(); return; - } - virtual ~RsNxsMsg() - { - //std::cout << "\nrefcount-- : " << --refcount << std::endl; - if(metaData){ - //std::cout << "\ndeleted\n"; - delete metaData; - } - } + virtual uint32_t serial_size() const; + virtual bool serialise(void *data,uint32_t& size) const; + bool deserialize(const uint8_t* data, uint32_t& size, uint32_t& offset); - virtual bool serialise(void *data,uint32_t& size) const; - virtual uint32_t serial_size() const; - - virtual void clear(); - virtual std::ostream &print(std::ostream &out, uint16_t indent); + virtual void clear(); + virtual std::ostream &print(std::ostream &out, uint16_t indent); - uint8_t pos; /// used for splitting up msg - uint8_t count; /// number of split up messages - RsGxsGroupId grpId; /// group id, forms part of version id - RsGxsMessageId msgId; /// msg id - static int refcount; + uint8_t pos; /// used for splitting up msg + uint8_t count; /// number of split up messages + RsGxsGroupId grpId; /// group id, forms part of version id + RsGxsMessageId msgId; /// msg id + static int refcount; - /*! - * This should contains all the data - * which is not specific to the Gxs service data - */ - RsTlvBinaryData meta; + /*! + * This should contains all the data + * which is not specific to the Gxs service data + */ + RsTlvBinaryData meta; - /*! - * This contains Gxs specific data - * only client of API knows who to decode this - */ - RsTlvBinaryData msg; - - RsGxsMsgMetaData* metaData; + /*! + * This contains Gxs specific data + * only client of API knows how to decode this + */ + RsTlvBinaryData msg; + RsGxsMsgMetaData* metaData; }; /*! diff --git a/libretroshare/src/services/p3gxsmails.cpp b/libretroshare/src/services/p3gxsmails.cpp index 21bfc4460..6db2d2c6c 100644 --- a/libretroshare/src/services/p3gxsmails.cpp +++ b/libretroshare/src/services/p3gxsmails.cpp @@ -24,17 +24,6 @@ bool p3GxsMails::sendMail( GxsMailsClient::GxsMailSubServices service, const RsGxsId& own_gxsid, const RsGxsId& recipient, const uint8_t* data, uint32_t size, RsGxsMailBaseItem::EncryptionMode cm) -{ - std::vector recipients; - recipients.push_back(&recipient); - return sendMail(service, own_gxsid, recipients, data, size, cm); -} - -bool p3GxsMails::sendMail( GxsMailsClient::GxsMailSubServices service, - const RsGxsId& own_gxsid, - const std::vector& recipients, - const uint8_t* data, uint32_t size, - RsGxsMailBaseItem::EncryptionMode cm ) { std::cout << "p3GxsMails::sendEmail(...)" << std::endl; @@ -53,25 +42,9 @@ bool p3GxsMails::sendMail( GxsMailsClient::GxsMailSubServices service, return false; } - std::set rcps; - typedef std::vector::const_iterator itT; - for(itT it = recipients.begin(); it != recipients.end(); it++) + if(recipient.isNull()) { - const RsGxsId* gId = *it; - - if(!gId || gId->isNull()) - { - std::cerr << "p3GxsMails::sendEmail(...) got invalid recipient" - << std::endl; - print_stacktrace(); - return false; - } - - rcps.insert(*gId); - } - if(rcps.empty()) - { - std::cerr << "p3GxsMails::sendEmail(...) got no recipients" + std::cerr << "p3GxsMails::sendEmail(...) got invalid recipient" << std::endl; print_stacktrace(); return false; @@ -83,25 +56,22 @@ bool p3GxsMails::sendMail( GxsMailsClient::GxsMailSubServices service, item->meta.mAuthorId = own_gxsid; item->meta.mGroupId = preferredGroupId; item->cryptoType = cm; + item->saltRecipientHint(recipient); + item->saltRecipientHint(RsGxsId::random()); + item->receiptId = RSRandom::random_u64(); - typedef std::set::const_iterator siT; - for(siT it = rcps.begin(); it != rcps.end(); ++it) - item->saltRecipientHint(*it); - - // If there is jut one recipient salt with a random id to avoid leaking it - if(rcps.size() == 1) item->saltRecipientHint(RsGxsId::random()); - - /* At this point we do a lot of memory copying, it doesn't look pretty but - * ATM haven't thinked of an elegant way to have the GxsMailSubServices - * travelling encrypted withuot copying memory around or responsabilize the - * client service to embed it in data array that is awful */ + RsNxsMailPresignedReceipt nrcpt; + preparePresignedReceipt(*item, nrcpt); uint16_t serv = static_cast(service); - uint32_t clearTextPldSize = size+2; - item->payload.resize(clearTextPldSize); - uint32_t _discard = 0; - setRawUInt16(&item->payload[0], 2, &_discard, serv); - memcpy(&item->payload[2], data, size); + uint32_t rcptsize = nrcpt.serial_size(); + item->payload.resize(2 + rcptsize + size); + uint32_t offset = 0; + setRawUInt16(&item->payload[0], 2, &offset, serv); + nrcpt.serialise(&item->payload[offset], rcptsize); offset += rcptsize; + memcpy(&item->payload[offset], data, size); //offset += size; + + std::cout << "p3GxsMails::sendMail(...) receipt size: " << rcptsize << std::endl; switch (cm) { @@ -117,9 +87,9 @@ bool p3GxsMails::sendMail( GxsMailsClient::GxsMailSubServices service, uint8_t* encryptedData = NULL; uint32_t encryptedSize = 0; uint32_t encryptError = 0; - if( idService.encryptData( &item->payload[0], clearTextPldSize, + if( idService.encryptData( &item->payload[0], item->payload.size(), encryptedData, encryptedSize, - rcps, encryptError, true ) ) + recipient, encryptError, true ) ) { item->payload.resize(encryptedSize); memcpy(&item->payload[0], encryptedData, encryptedSize); @@ -143,8 +113,11 @@ bool p3GxsMails::sendMail( GxsMailsClient::GxsMailSubServices service, } uint32_t token; - std::cout << "p3GxsMails::sendEmail(...) sending mail to:"<< *recipients[0] - << " payload size: : " << item->payload.size() << std::endl; + std::cout << "p3GxsMails::sendEmail(...) sending mail to: "<< recipient + << " with cryptoType: " << item->cryptoType + << " recipientHint: " << item->recipientsHint + << " receiptId: " << item->receiptId + << " payload size: " << item->payload.size() << std::endl; publishMsg(token, item); return true; } @@ -230,8 +203,6 @@ void p3GxsMails::handleResponse(uint32_t token, uint32_t req_type) for( vT::const_iterator mIt = mv.begin(); mIt != mv.end(); ++mIt ) { RsGxsMsgItem* gItem = *mIt; - std::cout << "p3GxsMails::handleResponse(...) MAILS_UPDATE " - << (uint32_t)gItem->PacketSubType() << std::endl; switch(gItem->PacketSubType()) { case GXS_MAIL_SUBTYPE_MAIL: @@ -246,13 +217,48 @@ void p3GxsMails::handleResponse(uint32_t token, uint32_t req_type) break; } + std::cout << "p3GxsMails::handleResponse(...) MAILS_UPDATE " + << "GXS_MAIL_SUBTYPE_MAIL handling: " + << msg->meta.mMsgId + << " with cryptoType: "<< msg->cryptoType + << " recipientHint: " << msg->recipientsHint + << " receiptId: "<< msg->receiptId + << " payload.size(): " << msg->payload.size() + << std::endl; + handleEcryptedMail(msg); break; } + case GXS_MAIL_SUBTYPE_RECEIPT: + { + RsGxsMailPresignedReceipt* msg = + dynamic_cast(gItem); + if(!msg) + { + std::cerr << "p3GxsMails::handleResponse(...) " + << "GXS_MAIL_SUBTYPE_RECEIPT cast error, " + << "something really wrong is happening" + << std::endl; + break; + } + + std::cout << "p3GxsMails::handleResponse(...) MAILS_UPDATE " + << "GXS_MAIL_SUBTYPE_RECEIPT handling: " + << msg->meta.mMsgId + << "with receiptId: "<< msg->receiptId + << std::endl; + + /* TODO: Notify client services if the original mail was + * sent from this node and mark for deletion, otherwise + * just mark original mail for deletion. */ + + break; + } default: std::cerr << "p3GxsMails::handleResponse(...) MAILS_UPDATE " << "Unknown mail subtype : " - << gItem->PacketSubType() << std::endl; + << static_cast(gItem->PacketSubType()) + << std::endl; break; } delete gItem; @@ -262,7 +268,7 @@ void p3GxsMails::handleResponse(uint32_t token, uint32_t req_type) } default: std::cerr << "p3GxsMails::handleResponse(...) Unknown req_type: " - << req_type << std::endl; + << req_type << std::endl; break; } } @@ -285,13 +291,13 @@ void p3GxsMails::service_tick() reinterpret_cast(ciao.data()), ciao.size(), RsGxsMailBaseItem::RSA ); } - else if(idService.isOwnId(gxsidB)) - { - std::string ciao("CiBuono!"); - sendMail( GxsMailsClient::TEST_SERVICE, gxsidB, gxsidA, - reinterpret_cast(ciao.data()), - ciao.size(), RsGxsMailBaseItem::RSA ); - } +// else if(idService.isOwnId(gxsidB)) +// { +// std::string ciao("CiBuono!"); +// sendMail( GxsMailsClient::TEST_SERVICE, gxsidB, gxsidA, +// reinterpret_cast(ciao.data()), +// ciao.size(), RsGxsMailBaseItem::RSA ); +// } } GxsTokenQueue::checkRequests(); @@ -386,6 +392,8 @@ bool p3GxsMails::requestGroupsData(const std::list* groupIds) bool p3GxsMails::handleEcryptedMail(const RsGxsMailItem* mail) { + std::cout << "p3GxsMails::handleEcryptedMail(...)" << std::endl; + std::set decryptIds; std::list ownIds; idService.getOwnIds(ownIds); @@ -393,7 +401,11 @@ bool p3GxsMails::handleEcryptedMail(const RsGxsMailItem* mail) if(mail->maybeRecipient(*it)) decryptIds.insert(*it); // Hint match none of our own ids - if(decryptIds.empty()) return true; + if(decryptIds.empty()) + { + std::cout << "p3GxsMails::handleEcryptedMail(...) hint doesn't match" << std::endl; + return true; + } switch (mail->cryptoType) { @@ -409,17 +421,21 @@ bool p3GxsMails::handleEcryptedMail(const RsGxsMailItem* mail) } case RsGxsMailBaseItem::RSA: { - uint8_t* decrypted_data = NULL; - uint32_t decrypted_data_size = 0; - uint32_t decryption_error; bool ok = true; - if( idService.decryptData( &mail->payload[0], - mail->payload.size(), decrypted_data, - decrypted_data_size, decryptIds, - decryption_error ) ) - ok = dispatchDecryptedMail( mail, decrypted_data, - decrypted_data_size ); - free(decrypted_data); + for( std::set::const_iterator it = decryptIds.begin(); + it != decryptIds.end(); ++it ) + { + uint8_t* decrypted_data = NULL; + uint32_t decrypted_data_size = 0; + uint32_t decryption_error; + if( idService.decryptData( &mail->payload[0], + mail->payload.size(), decrypted_data, + decrypted_data_size, *it, + decryption_error ) ) + ok = ok && dispatchDecryptedMail( mail, decrypted_data, + decrypted_data_size ); + free(decrypted_data); + } return ok; } default: @@ -433,13 +449,37 @@ bool p3GxsMails::dispatchDecryptedMail( const RsGxsMailItem* received_msg, const uint8_t* decrypted_data, uint32_t decrypted_data_size ) { - std::cout << "p3GxsMails::dispatchDecryptedMail(, , " << decrypted_data_size << ")" << std::endl; + std::cout << "p3GxsMails::dispatchDecryptedMail(, , " << decrypted_data_size + << ")" << std::endl; + uint16_t csri = 0; - uint32_t off = 0; - getRawUInt16( decrypted_data, decrypted_data_size, &off, &csri); + uint32_t offset = 0; + if(!getRawUInt16( decrypted_data, decrypted_data_size, &offset, &csri)) + { + std::cerr << "p3GxsMails::dispatchDecryptedMail(...) (EE) fatal error " + << "deserializing service type, something really wrong is " + << "happening!" << std::endl; + return false; + } GxsMailsClient::GxsMailSubServices rsrvc; rsrvc = static_cast(csri); + RsNxsMailPresignedReceipt* receipt = new RsNxsMailPresignedReceipt(); + uint32_t rcptsize = decrypted_data_size; + if(!receipt->deserialize(decrypted_data, rcptsize, offset)) + { + std::cerr << "p3GxsMails::dispatchDecryptedMail(...) (EE) fatal error " + << "deserializing presigned return receipt , something really" + << " wrong is happening!" << std::endl; + delete receipt; + return false; + } + std::cout << "p3GxsMails::dispatchDecryptedMail(...) dispatching receipt " + << "with: msgId: " << receipt->msgId << std::endl; + + std::vector rcct; rcct.push_back(receipt); + RsGenExchange::notifyNewMessages(rcct); + GxsMailsClient* reecipientService = NULL; { RS_STACK_MUTEX(servClientsMutex); @@ -448,8 +488,8 @@ bool p3GxsMails::dispatchDecryptedMail( const RsGxsMailItem* received_msg, if(reecipientService) return reecipientService->receiveGxsMail( received_msg, - &decrypted_data[2], - decrypted_data_size-2 ); + &decrypted_data[offset], + decrypted_data_size-offset ); else { std::cerr << "p3GxsMails::dispatchReceivedMail(...) " @@ -459,3 +499,39 @@ bool p3GxsMails::dispatchDecryptedMail( const RsGxsMailItem* received_msg, } } +bool p3GxsMails::preparePresignedReceipt(const RsGxsMailItem& mail, RsNxsMailPresignedReceipt& receipt) +{ + RsGxsMailPresignedReceipt grcpt; + grcpt.meta = mail.meta; + grcpt.meta.mPublishTs = time(NULL); + grcpt.receiptId = mail.receiptId; + uint32_t groff = 0, grsz = grcpt.size(); + std::vector grsrz; + grsrz.resize(grsz); + grcpt.serialize(&grsrz[0], grsz, groff); + receipt.msg.setBinData(&grsrz[0], grsz); + + receipt.grpId = preferredGroupId; + receipt.metaData = new RsGxsMsgMetaData(); + *receipt.metaData = grcpt.meta; + + if(createMessage(&receipt) != CREATE_SUCCESS) + { + std::cout << "p3GxsMails::preparePresignedReceipt(...) receipt creation" + << " failed!" << std::endl; + return false; + } + + uint32_t metaSize = receipt.metaData->serial_size(); + std::vector srx; srx.resize(metaSize); + receipt.metaData->serialise(&srx[0], &metaSize); + receipt.meta.setBinData(&srx[0], metaSize); + + std::cout << "p3GxsMails::preparePresignedReceipt(...) prepared receipt" + << "with: grcpt.meta.mMsgId: " << grcpt.meta.mMsgId + << " msgId: " << receipt.msgId + << " metaData.mMsgId: " << receipt.metaData->mMsgId + << std::endl; + return true; +} + diff --git a/libretroshare/src/services/p3gxsmails.h b/libretroshare/src/services/p3gxsmails.h index 110e8fe47..0dac2c5a6 100644 --- a/libretroshare/src/services/p3gxsmails.h +++ b/libretroshare/src/services/p3gxsmails.h @@ -67,21 +67,6 @@ struct p3GxsMails : RsGenExchange, GxsTokenQueue RsGxsMailBaseItem::EncryptionMode cm = RsGxsMailBaseItem::RSA ); - /** - * Send an email to recipients, in the process author of the email is - * disclosed to the network (because the sent GXS item is signed), while - * recipients are not @see RsGxsMailBaseItem::recipientsHint for details on - * recipient protection. - * This method is part of the public interface of this service. - * @return true if the mail will be sent, false if not - */ - bool sendMail( GxsMailsClient::GxsMailSubServices service, - const RsGxsId& own_gxsid, - const std::vector& recipients, - const uint8_t* data, uint32_t size, - RsGxsMailBaseItem::EncryptionMode cm = RsGxsMailBaseItem::RSA - ); - /** * Register a client service to p3GxsMails to receive mails via * GxsMailsClient::receiveGxsMail(...) callback @@ -185,6 +170,9 @@ private: bool dispatchDecryptedMail( const RsGxsMailItem* received_msg, const uint8_t* decrypted_data, uint32_t decrypted_data_size ); + + bool preparePresignedReceipt( const RsGxsMailItem& mail, + RsNxsMailPresignedReceipt& receipt ); };