Compare commits

...

5 Commits

  1. 21
      src/pEp/_pEp/basic_api.cc
  2. 5
      src/pEp/_pEp/basic_api.hh
  3. 134
      src/pEp/_pEp/message.cc
  4. 20
      src/pEp/_pEp/message.hh
  5. 75
      src/pEp/_pEp/pEpmodule.cc

21
src/pEp/_pEp/basic_api.cc

@ -8,6 +8,8 @@
#include <pEp/keymanagement.h>
#include <pEp/message_api.h>
#include <pEp/echo_api.h>
#include <pEp/mixnet.h>
#include <pEp/echo_api.h>
#include <pEp/Adapter.hh>
// local
@ -135,7 +137,6 @@ namespace pEp {
return result;
}
boost::python::tuple import_key_with_fpr_return(string key_data)
{
::identity_list *private_keys = NULL;
@ -222,6 +223,24 @@ namespace pEp {
_throw_status(status);
}
boost::python::list onion_identities(unsigned trusted_no, unsigned total_no)
{
::identity_list *identities = NULL;
PEP_STATUS status = ::onion_identities(Adapter::session(), trusted_no, total_no, &identities);
_throw_status(status);
boost::python::list result;
for (::identity_list *il = identities; il && il->ident; il = il->next) {
::pEp_identity *ident = ::identity_dup(il->ident);
if (!ident) {
free_identity_list(identities);
throw std::bad_alloc();
}
result.append(Identity(ident));
}
free_identity_list(identities);
return result;
}
void send_ping(Identity &own_identity, Identity &other_identity)
{
const std::string own_userid = (*own_identity).user_id;

5
src/pEp/_pEp/basic_api.hh

@ -36,6 +36,11 @@ namespace pEp {
void set_comm_partner_key(Identity &ident, string fpr);
void send_ping(Identity &own_identity, Identity &other_identity);
boost::python::list onion_identities(unsigned trusted_no, unsigned total_no);
void send_ping(Identity &own_identity, Identity &other_identity);
} /* namespace PythonAdapter */
} /* namespace pEp */

134
src/pEp/_pEp/message.cc

@ -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(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(const Message::Blob &second) : _bl(second._bl), part_of_chain(true) {}
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()) {

20
src/pEp/_pEp/message.hh

@ -68,11 +68,20 @@ namespace pEp {
str_attr(_bl->filename, value);
}
size_t size()
size_t size() const
{
return _bl->size;
}
// Return an initial to the internal data, without copying the
// buffer.
// This method is of course unsafe, as the resulting pointer
// must not be dereferenced past the bloblist's destruction.
const char* c_data() const
{
return _bl->value;
}
string decode(string encoding);
string decode()
@ -315,11 +324,20 @@ namespace pEp {
PEP_color outgoing_color();
Message onionize(boost::python::list relays);
Message onionize(boost::python::list relays, boost::python::list extra);
Message onionize(boost::python::list relays, boost::python::list extra, int enc_format);
Message onionize(boost::python::list relays, boost::python::list extra, int enc_format, int flags);
Message deepcopy(dict &memo);
Message copy();
Message::Blob serialize();
};
Message deserialize(const Message::Blob &blob);
Message outgoing_message(Identity me);
Message incoming_message(string mime_text);

75
src/pEp/_pEp/pEpmodule.cc

@ -12,6 +12,7 @@
// Engine
#include <pEp/key_reset.h>
#include <pEp/message_api.h>
#include <pEp/mixnet.h>
#include <pEp/sync_api.h>
#include <pEp/echo_api.h>
#include <pEp/status_to_string.h>
@ -593,6 +594,42 @@ namespace pEp {
" keys a list of keys being used\n"
" rating the rating of the message as integer\n"
" flags flags set while decryption\n")
.def(
"serialize",
&Message::serialize,
"b = msg.serialize()\n"
"\n"
"serialises a p≡p message into a blob (which can be converted into\n"
"a bytes object). The blob can be deserialised back into a message\n"
"through pEp.deserialize\n"
"\n"
" msg a message, encrypted or not\n"
" b the resultint blob\n")
.def(
"onionize",
(Message(Message::*)(boost::python::list)) &
Message::onionize)
.def(
"onionize",
(Message(Message::*)(boost::python::list, boost::python::list)) &
Message::onionize)
.def(
"onionize",
(Message(Message::*)(boost::python::list, boost::python::list, int)) &
Message::onionize)
.def(
"onionize",
(Message(Message::*)(boost::python::list, boost::python::list, int, int)) &
Message::onionize,
"msg2 = msg1.onionize(relays, extra_keys = [], enc_format = 4, flags = 0)\n"
"\n"
"returns a copy of the message onionized with the given relay identities\n"
" relays a list of identities to use as relays\n"
" extra_keys a list of additional FPRs to encrypt the innermost message with"
" enc_format the encryption format, as in encrypt. Only\n"
" recent formats are supported.\n"
" flags flags, as in encrypt. Do not use onionisation flag\n"
" msg2 the resulting onionized message\n")
.add_property(
"outgoing_rating",
&Message::outgoing_rating,
@ -658,7 +695,10 @@ namespace pEp {
&import_key_with_fpr_return,
"imported_keys, affected_own_identities = import_key_with_fpr_return(key_data)\n"
"\n"
"import key(s) from key_data\n");
"import key(s) from key_data\n"
"\n"
"imported_keys a list of FPRs\n"
"affected_own_identities the list of modified own identities\n");
def("export_key",
&export_key,
@ -709,6 +749,39 @@ namespace pEp {
"own_identity the sender identity\n"
"other_identity the recipient identity\n");
def("onion_identities",
&onion_identities,
"onion_identities(trusted_no, total_no)\n"
"\n"
"Return a list of total_no known identities suitable to use as\n"
"onion-routing relays, of which at least trusted_no are trusted.\n"
"The returned identities are all distinct and in random order.\n"
"\n"
"identities = onion_identities(2, 5)\n");
def("deserialize",
&deserialize,
"msg = deserialize(blob)\n"
"\n"
"Return the message obtained by the deserialisation of the given blob.\n"
"The blob must be obtained from Message.serialize.\n"
"\n"
"msg the returned message\n"
"blob a blob returned by Message.serialize\n"
"\n");
def("send_ping",
&send_ping,
"send_ping(own_identity, other_identity)\n"
"\n"
"send a Distribution.Ping message from the given own identity\n"
"to the given identity, usually but not necessarily non-own.\n"
"\n"
"Both identities must have been updated, the own identity\n"
"with pEp.myself() and the second with Identity.update()\n"
"\n"
"own_identity the sender identity\n"
"other_identity the recipient identity\n");
// message API
enum_<PEP_rating>("rating")

Loading…
Cancel
Save