Return of the evil MIME functions - now in a separate file, and only compiled in with ENIGMAIL_MAY_USE_THIS flag.

ENGINE-550
parent 9ddc6468b4
commit 4811db84f9

@ -103,7 +103,7 @@ install_headers:
timestamp.h identity_list.h bloblist.h stringpair.h message.h mime.h \
cryptotech.h sync_api.h blacklist.h pEp_string.h openpgp_compat.h \
labeled_int_list.h key_reset.h base64.h sync_codec.h status_to_string.h\
../asn.1/*.h $(PREFIX)/include/pEp/
aux_mime_msg.h ../asn.1/*.h $(PREFIX)/include/pEp/
install: $(TARGET) install_headers
mkdir -p "$(PREFIX)/lib/"

@ -0,0 +1,272 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#ifdef ENIGMAIL_MAY_USE_THIS
#include "pEp_internal.h"
#include "message_api.h"
#include "mime.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "aux_mime_msg.h"
static PEP_STATUS update_identity_recip_list(PEP_SESSION session,
identity_list* list) {
PEP_STATUS status = PEP_STATUS_OK;
if (!session)
return PEP_UNKNOWN_ERROR;
identity_list* id_list_ptr = NULL;
for (id_list_ptr = list; id_list_ptr; id_list_ptr = id_list_ptr->next) {
pEp_identity* curr_identity = id_list_ptr->ident;
if (curr_identity) {
if (!is_me(session, curr_identity)) {
char* name_bak = curr_identity->username;
curr_identity->username = NULL;
status = update_identity(session, curr_identity);
if (name_bak &&
(EMPTYSTR(curr_identity->username) || strcmp(name_bak, curr_identity->username) != 0)) {
free(curr_identity->username);
curr_identity->username = name_bak;
}
}
else
status = _myself(session, curr_identity, false, false, true);
if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
return status;
}
}
return PEP_STATUS_OK;
}
DYNAMIC_API PEP_STATUS MIME_decrypt_message(
PEP_SESSION session,
const char *mimetext,
size_t size,
char** mime_plaintext,
stringlist_t **keylist,
PEP_rating *rating,
PEP_decrypt_flags_t *flags,
char** modified_src
)
{
assert(mimetext);
assert(mime_plaintext);
assert(keylist);
assert(rating);
assert(flags);
assert(modified_src);
if (!(mimetext && mime_plaintext && keylist && rating && flags && modified_src))
return PEP_ILLEGAL_VALUE;
PEP_STATUS status = PEP_STATUS_OK;
message* tmp_msg = NULL;
message* dec_msg = NULL;
*mime_plaintext = NULL;
status = mime_decode_message(mimetext, size, &tmp_msg);
if (status != PEP_STATUS_OK)
goto pEp_error;
tmp_msg->dir = PEP_dir_incoming;
// MIME decode message delivers only addresses. We need more.
if (tmp_msg->from) {
if (!is_me(session, tmp_msg->from))
status = update_identity(session, (tmp_msg->from));
else
status = _myself(session, tmp_msg->from, false, false, true);
if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
goto pEp_error;
}
status = update_identity_recip_list(session, tmp_msg->to);
if (status != PEP_STATUS_OK)
goto pEp_error;
status = update_identity_recip_list(session, tmp_msg->cc);
if (status != PEP_STATUS_OK)
goto pEp_error;
status = update_identity_recip_list(session, tmp_msg->bcc);
if (status != PEP_STATUS_OK)
goto pEp_error;
PEP_STATUS decrypt_status = decrypt_message(session,
tmp_msg,
&dec_msg,
keylist,
rating,
flags);
if (!dec_msg && (decrypt_status == PEP_UNENCRYPTED || decrypt_status == PEP_VERIFIED)) {
dec_msg = message_dup(tmp_msg);
}
if (decrypt_status > PEP_CANNOT_DECRYPT_UNKNOWN || !dec_msg)
{
status = decrypt_status;
goto pEp_error;
}
if (*flags & PEP_decrypt_flag_src_modified) {
_mime_encode_message_internal(tmp_msg, false, modified_src, true);
if (!modified_src) {
*flags &= (~PEP_decrypt_flag_src_modified);
decrypt_status = PEP_CANNOT_REENCRYPT; // Because we couldn't return it, I guess.
}
}
// FIXME: test with att
status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true);
if (status == PEP_STATUS_OK)
{
free(tmp_msg);
free(dec_msg);
return decrypt_status;
}
pEp_error:
free_message(tmp_msg);
free_message(dec_msg);
return status;
}
DYNAMIC_API PEP_STATUS MIME_encrypt_message(
PEP_SESSION session,
const char *mimetext,
size_t size,
stringlist_t* extra,
char** mime_ciphertext,
PEP_enc_format enc_format,
PEP_encrypt_flags_t flags
)
{
PEP_STATUS status = PEP_STATUS_OK;
message* tmp_msg = NULL;
message* enc_msg = NULL;
status = mime_decode_message(mimetext, size, &tmp_msg);
if (status != PEP_STATUS_OK)
goto pEp_error;
// MIME decode message delivers only addresses. We need more.
if (tmp_msg->from) {
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
free(tmp_msg->from->user_id);
if (status != PEP_STATUS_OK || !own_id) {
tmp_msg->from->user_id = strdup(PEP_OWN_USERID);
}
else {
tmp_msg->from->user_id = own_id; // ownership transfer
}
status = myself(session, tmp_msg->from);
if (status != PEP_STATUS_OK)
goto pEp_error;
}
// Own identities can be retrieved here where they would otherwise
// fail because we lack all other information. This is ok and even
// desired. FIXME: IS it?
status = update_identity_recip_list(session, tmp_msg->to);
if (status != PEP_STATUS_OK)
goto pEp_error;
status = update_identity_recip_list(session, tmp_msg->cc);
if (status != PEP_STATUS_OK)
goto pEp_error;
status = update_identity_recip_list(session, tmp_msg->bcc);
if (status != PEP_STATUS_OK)
goto pEp_error;
// This isn't incoming, though... so we need to reverse the direction
tmp_msg->dir = PEP_dir_outgoing;
status = encrypt_message(session,
tmp_msg,
extra,
&enc_msg,
enc_format,
flags);
if (status != PEP_STATUS_OK)
goto pEp_error;
if (!enc_msg) {
status = PEP_UNKNOWN_ERROR;
goto pEp_error;
}
status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false);
pEp_error:
free_message(tmp_msg);
free_message(enc_msg);
return status;
}
DYNAMIC_API PEP_STATUS MIME_encrypt_message_for_self(
PEP_SESSION session,
pEp_identity* target_id,
const char *mimetext,
size_t size,
stringlist_t* extra,
char** mime_ciphertext,
PEP_enc_format enc_format,
PEP_encrypt_flags_t flags
)
{
PEP_STATUS status = PEP_STATUS_OK;
message* tmp_msg = NULL;
message* enc_msg = NULL;
status = mime_decode_message(mimetext, size, &tmp_msg);
if (status != PEP_STATUS_OK)
goto pEp_error;
// This isn't incoming, though... so we need to reverse the direction
tmp_msg->dir = PEP_dir_outgoing;
status = encrypt_message_for_self(session,
target_id,
tmp_msg,
extra,
&enc_msg,
enc_format,
flags);
if (status != PEP_STATUS_OK)
goto pEp_error;
if (!enc_msg) {
status = PEP_UNKNOWN_ERROR;
goto pEp_error;
}
status = mime_encode_message(enc_msg, false, mime_ciphertext);
pEp_error:
free_message(tmp_msg);
free_message(enc_msg);
return status;
}
#endif

@ -0,0 +1,150 @@
// This file is under GNU General Public License 3.0
// see LICENSE.txt
#pragma once
#ifdef ENIGMAIL_MAY_USE_THIS
#include "pEpEngine.h"
#include "keymanagement.h"
#include "message.h"
#include "cryptotech.h"
#ifdef __cplusplus
extern "C" {
#endif
// MIME_encrypt_message() - encrypt a MIME message, with MIME output
//
// parameters:
// session (in) session handle
// mimetext (in) MIME encoded text to encrypt
// size (in) size of input mime text
// extra (in) extra keys for encryption
// mime_ciphertext (out) encrypted, encoded message
// enc_format (in) encrypted format
// flags (in) flags to set special encryption features
//
// return value:
// PEP_STATUS_OK if everything worked
// PEP_BUFFER_TOO_SMALL if encoded message size is too big to handle
// PEP_CANNOT_CREATE_TEMP_FILE
// if there are issues with temp files; in
// this case errno will contain the underlying
// error
// PEP_OUT_OF_MEMORY if not enough memory could be allocated
//
// caveat:
// the encrypted, encoded mime text will go to the ownership of the caller; mimetext
// will remain in the ownership of the caller
DYNAMIC_API PEP_STATUS MIME_encrypt_message(
PEP_SESSION session,
const char *mimetext,
size_t size,
stringlist_t* extra,
char** mime_ciphertext,
PEP_enc_format enc_format,
PEP_encrypt_flags_t flags
);
// MIME_encrypt_message_for_self() - encrypt MIME message for user's identity only,
// ignoring recipients and other identities from
// the message, with MIME output
// parameters:
// session (in) session handle
// target_id (in) self identity this message should be encrypted for
// mimetext (in) MIME encoded text to encrypt
// size (in) size of input mime text
// extra (in) extra keys for encryption
// mime_ciphertext (out) encrypted, encoded message
// enc_format (in) encrypted format
// flags (in) flags to set special encryption features
//
// return value:
// PEP_STATUS_OK if everything worked
// PEP_BUFFER_TOO_SMALL if encoded message size is too big to handle
// PEP_CANNOT_CREATE_TEMP_FILE
// if there are issues with temp files; in
// this case errno will contain the underlying
// error
// PEP_OUT_OF_MEMORY if not enough memory could be allocated
//
// caveat:
// the encrypted, encoded mime text will go to the ownership of the caller; mimetext
// will remain in the ownership of the caller
DYNAMIC_API PEP_STATUS MIME_encrypt_message_for_self(
PEP_SESSION session,
pEp_identity* target_id,
const char *mimetext,
size_t size,
stringlist_t* extra,
char** mime_ciphertext,
PEP_enc_format enc_format,
PEP_encrypt_flags_t flags
);
// MIME_decrypt_message() - decrypt a MIME message, with MIME output
//
// parameters:
// session (in) session handle
// mimetext (in) MIME encoded text to decrypt
// size (in) size of mime text to decode (in order to decrypt)
// mime_plaintext (out) decrypted, encoded message
// keylist (inout) in: stringlist with additional keyids for reencryption if needed
// (will be freed and replaced with output keylist)
// out: stringlist with keyids
// rating (out) rating for the message
// flags (inout) flags to signal special decryption features (see below)
// modified_src (out) modified source string, if decrypt had reason to change it
//
// return value:
// decrypt status if everything worked with MIME encode/decode,
// the status of the decryption is returned
// (PEP_STATUS_OK or decryption error status)
// PEP_BUFFER_TOO_SMALL if encoded message size is too big to handle
// PEP_CANNOT_CREATE_TEMP_FILE
// if there are issues with temp files; in
// this case errno will contain the underlying
// error
// PEP_OUT_OF_MEMORY if not enough memory could be allocated
//
// flag values:
// in:
// PEP_decrypt_flag_untrusted_server
// used to signal that decrypt function should engage in behaviour
// specified for when the server storing the source is untrusted.
// out:
// PEP_decrypt_flag_own_private_key
// private key was imported for one of our addresses (NOT trusted
// or set to be used - handshake/trust is required for that)
// PEP_decrypt_flag_src_modified
// indicates that the modified_src field should contain a modified
// version of the source, at the moment always as a result of the
// input flags.
// PEP_decrypt_flag_consume
// used by sync
// PEP_decrypt_flag_ignore
// used by sync
//
// caveat:
// the decrypted, encoded mime text will go to the ownership of the caller; mimetext
// will remain in the ownership of the caller
DYNAMIC_API PEP_STATUS MIME_decrypt_message(
PEP_SESSION session,
const char *mimetext,
size_t size,
char** mime_plaintext,
stringlist_t **keylist,
PEP_rating *rating,
PEP_decrypt_flags_t *flags,
char** modified_src
);
#ifdef __cplusplus
}
#endif
#endif

@ -8,6 +8,7 @@
#include "pEpEngine.h"
#include "message_api.h"
#include "aux_mime_msg.h"
void test_init();
@ -58,6 +59,8 @@ int util_delete_filepath(const char *filepath,
int ftw_info,
struct FTW * ftw_struct);
#ifndef ENIGMAIL_MAY_USE_THIS
// MIME_decrypt_message() - decrypt a MIME message, with MIME output
//
// parameters:
@ -185,7 +188,7 @@ PEP_STATUS MIME_encrypt_message_for_self(
PEP_encrypt_flags_t flags
);
#endif

@ -432,6 +432,8 @@ int util_delete_filepath(const char *filepath,
return retval;
}
#ifndef ENIGMAIL_MAY_USE_THIS
static PEP_STATUS update_identity_recip_list(PEP_SESSION session,
identity_list* list) {
@ -687,3 +689,5 @@ pEp_error:
return status;
}
#endif

Loading…
Cancel
Save