|
|
@ -2,6 +2,7 @@ |
|
|
|
// see LICENSE.txt
|
|
|
|
|
|
|
|
// System
|
|
|
|
#include <iostream> ///////////////////////////////////////////////// |
|
|
|
#include <cstdlib> |
|
|
|
#include <cstring> |
|
|
|
#include <stdexcept> |
|
|
@ -13,6 +14,7 @@ |
|
|
|
#include <pEp/mime.h> |
|
|
|
#include <pEp/keymanagement.h> |
|
|
|
#include <pEp/message_api.h> |
|
|
|
#include <pEp/mixnet.h> |
|
|
|
|
|
|
|
// local
|
|
|
|
#include "message.hh" |
|
|
@ -27,6 +29,8 @@ namespace pEp { |
|
|
|
if (!_bl) { |
|
|
|
throw std::bad_alloc(); |
|
|
|
} |
|
|
|
std::cerr << "Built a blob at " << this << " from a C bloblist (chained? " << chained << ")\n"; |
|
|
|
std::cerr << " its _bl is at " << _bl << "\n"; |
|
|
|
} |
|
|
|
|
|
|
|
Message::Blob::Blob(object data, string mime_type, string filename) : |
|
|
@ -50,23 +54,52 @@ namespace pEp { |
|
|
|
} |
|
|
|
|
|
|
|
memcpy(mem, src.buf, src.len); |
|
|
|
std::cerr << " copied old cd " << src.buf << " ...\n"; |
|
|
|
std::cerr << " ... to " << mem << " ...\n"; |
|
|
|
free(_bl->value); |
|
|
|
std::cerr << " keeping _bl " << _bl << "\n"; |
|
|
|
std::cerr << " freed value " << (void*) _bl->value << "\n"; |
|
|
|
_bl->size = src.len; |
|
|
|
_bl->value = mem; |
|
|
|
std::cerr << " replaced with " << (void*) _bl->value << "\n"; |
|
|
|
|
|
|
|
PyBuffer_Release(&src); |
|
|
|
|
|
|
|
this->mime_type(mime_type); |
|
|
|
this->filename(filename); |
|
|
|
std::cerr << "Built a blob at " << this << " from a C++ data object\n"; |
|
|
|
std::cerr << " its _bl is at " << _bl << "\n"; |
|
|
|
} |
|
|
|
|
|
|
|
Message::Blob::Blob(const Message::Blob &second) : _bl(second._bl), part_of_chain(true) {} |
|
|
|
Message::Blob::Blob(const Message::Blob &second) : _bl(second._bl), part_of_chain(second.part_of_chain) { |
|
|
|
std::cerr << "Built a blob at " << this << " as a copy of " << & second << " which " << (second.part_of_chain ? "WAS" : "was NOT") << " part of a chain\n"; |
|
|
|
if (! part_of_chain) { |
|
|
|
assert(second._bl->next == NULL); |
|
|
|
// Replace _bc with a copy.
|
|
|
|
char *data_c = NULL; |
|
|
|
data_c = (char*) malloc(_bl->size); |
|
|
|
if (data_c == NULL) |
|
|
|
throw std::bad_alloc(); |
|
|
|
memcpy(data_c, _bl->value, _bl->size); |
|
|
|
::bloblist_t *_new_bl = ::new_bloblist(data_c, _bl->size, _bl->mime_type, NULL); |
|
|
|
if (_new_bl == NULL) { |
|
|
|
free(data_c); |
|
|
|
throw std::bad_alloc(); |
|
|
|
} |
|
|
|
_bl = _new_bl; |
|
|
|
} |
|
|
|
std::cerr << " its _bl is at " << _bl << "\n"; |
|
|
|
} |
|
|
|
|
|
|
|
Message::Blob::~Blob() |
|
|
|
{ |
|
|
|
std::cerr << "Destroy blob at " << this << "\n"; |
|
|
|
std::cerr << " its _bl was at" << _bl << (part_of_chain ? " (NOT destroying it)" : "(DESTROYING it)") << "\n"; |
|
|
|
if (!part_of_chain) { |
|
|
|
free(_bl->value); |
|
|
|
std::cerr << " freed c_data " << (void*) _bl->value << "\n"; |
|
|
|
free(_bl); |
|
|
|
std::cerr << " freed _bl " << (void*) _bl << "\n"; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -77,6 +110,9 @@ namespace pEp { |
|
|
|
if (!_bl) { |
|
|
|
build << "b'', '', ''"; |
|
|
|
} else { |
|
|
|
build << "@ " << this << " _bl " << (void*) _bl << " c_data " << (void*) _bl->value << " " ; |
|
|
|
//build << "\"" << (char *)_bl->value << "\""; // only for debugging, of course: dangerous unless '\0'-terminated
|
|
|
|
build << " "; |
|
|
|
build << "bytes(" << _bl->size << "), "; |
|
|
|
string mime_type; |
|
|
|
if (_bl->mime_type) |
|
|
@ -395,6 +431,56 @@ namespace pEp { |
|
|
|
return _color(outgoing_rating()); |
|
|
|
} |
|
|
|
|
|
|
|
Message Message::onionize(boost::python::list relays) |
|
|
|
{ |
|
|
|
return onionize(relays, boost::python::list(), (int) PEP_enc_PEP_message_v2, (int) PEP_encrypt_flag_default); |
|
|
|
} |
|
|
|
Message Message::onionize(boost::python::list relays, boost::python::list extra) |
|
|
|
{ |
|
|
|
return onionize(relays, extra, (int) PEP_enc_PEP_message_v2, (int) PEP_encrypt_flag_default); |
|
|
|
} |
|
|
|
Message Message::onionize(boost::python::list relays, boost::python::list extra, int enc_format) |
|
|
|
{ |
|
|
|
return onionize(relays, extra, enc_format, (int) PEP_encrypt_flag_default); |
|
|
|
} |
|
|
|
Message Message::onionize(boost::python::list relays, boost::python::list extra, int enc_format, int flags) |
|
|
|
{ |
|
|
|
::identity_list *identities_c = NULL; |
|
|
|
PEP_STATUS status = PEP_STATUS_OK; |
|
|
|
|
|
|
|
// In case of any error, be it memory allocation or type conversion,
|
|
|
|
// free our temporary data before re-throwing to the caller.
|
|
|
|
::pEp_identity *identity_c = NULL; |
|
|
|
stringlist_t *extra_c = NULL; |
|
|
|
try { |
|
|
|
// Turn Python lists into C lists.
|
|
|
|
extra_c = to_stringlist(extra); |
|
|
|
for (int i = len(relays) - 1; i >= 0; i--) { |
|
|
|
Identity &identity = boost::python::extract<Identity &>(relays [i]); |
|
|
|
::identity_list *new_identities_c = identity_list_cons_copy(identity, identities_c); |
|
|
|
if (new_identities_c == NULL) |
|
|
|
throw std::bad_alloc(); |
|
|
|
identities_c = new_identities_c; |
|
|
|
} |
|
|
|
|
|
|
|
// Call the C function to do the actual work.
|
|
|
|
::message *in_message_c = * this; |
|
|
|
::message *out_message_c = NULL; |
|
|
|
status = ::onionize(Adapter::session(), in_message_c, extra_c, &out_message_c, (::PEP_enc_format) enc_format, (::PEP_encrypt_flags_t) flags, identities_c); |
|
|
|
_throw_status(status); |
|
|
|
|
|
|
|
// Success.
|
|
|
|
free_stringlist(extra_c); |
|
|
|
free_identity_list(identities_c); |
|
|
|
return out_message_c; |
|
|
|
} catch (const std::exception &e) { |
|
|
|
free_identity(identity_c); |
|
|
|
free_stringlist(extra_c); |
|
|
|
free_identity_list(identities_c); |
|
|
|
throw e; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Message Message::copy() |
|
|
|
{ |
|
|
|
message *dup = message_dup(*this); |
|
|
@ -409,6 +495,50 @@ namespace pEp { |
|
|
|
return copy(); |
|
|
|
} |
|
|
|
|
|
|
|
Message::Blob Message::serialize() |
|
|
|
{ |
|
|
|
std::cerr << "Message::serialize this is " << this << "\n"; |
|
|
|
size_t length_in_bytes_c; |
|
|
|
char *data_c = NULL; |
|
|
|
::bloblist_t *blob_c; |
|
|
|
|
|
|
|
/* Serialise the message into a memory buffer. */ |
|
|
|
PEP_STATUS status = onion_serialize_message(Adapter::session(), *this, &data_c, &length_in_bytes_c); |
|
|
|
_throw_status(status); |
|
|
|
|
|
|
|
/* Turn the memory buffer into a blob. */ |
|
|
|
blob_c = new_bloblist(data_c, length_in_bytes_c, PEP_ONION_MESSAGE_MIME_TYPE, NULL); |
|
|
|
if (blob_c == NULL) { |
|
|
|
::free(data_c); |
|
|
|
throw std::bad_alloc(); |
|
|
|
} |
|
|
|
return Message::Blob(blob_c, false); |
|
|
|
/*
|
|
|
|
char *data_c = strdup("foo!"); |
|
|
|
size_t length_in_bytes_c = strlen(data_c); |
|
|
|
::bloblist_t *blob_c = NULL; |
|
|
|
blob_c = ::new_bloblist(data_c, length_in_bytes_c, PEP_ONION_MESSAGE_MIME_TYPE, NULL); |
|
|
|
if (blob_c == NULL) { |
|
|
|
::free(data_c); |
|
|
|
throw std::bad_alloc(); |
|
|
|
} |
|
|
|
std::cerr << "Message::serialize data_c is " << (void*) data_c << "\n"; |
|
|
|
std::cerr << "Message::serialize blob_c is " << blob_c << "\n"; |
|
|
|
return Message::Blob(blob_c, false); |
|
|
|
*/ |
|
|
|
} |
|
|
|
|
|
|
|
Message deserialize(const Message::Blob &blob) |
|
|
|
{ |
|
|
|
const char *data_c = blob.c_data(); |
|
|
|
size_t length_in_bytes_c = blob.size(); |
|
|
|
message *msg = NULL; |
|
|
|
PEP_STATUS status = onion_deserialize_message(Adapter::session(), data_c, length_in_bytes_c, &msg); |
|
|
|
_throw_status(status); |
|
|
|
|
|
|
|
return Message(msg); |
|
|
|
} |
|
|
|
|
|
|
|
Message outgoing_message(Identity me) |
|
|
|
{ |
|
|
|
if (me.address().empty() || me.user_id().empty()) { |
|
|
|