src/aux_mime_msg.c
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Thu, 04 Jun 2020 11:18:45 +0200
changeset 4729 3df9a2a67597
parent 4592 f0e7ec9616c5
child 4785 08d521da5611
child 4792 7056435ab9e7
child 4878 419c6d10c000
permissions -rw-r--r--
forgot test files
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #ifdef ENIGMAIL_MAY_USE_THIS
     5 
     6 #include "pEp_internal.h"
     7 #include "message_api.h"
     8 #include "mime.h"
     9 
    10 #include <assert.h>
    11 #include <string.h>
    12 #include <stdlib.h>
    13 
    14 #include "aux_mime_msg.h"
    15 
    16 
    17 static PEP_STATUS update_identity_recip_list(PEP_SESSION session,
    18                                              identity_list* list) {
    19 
    20     PEP_STATUS status = PEP_STATUS_OK;
    21 
    22     if (!session)
    23         return PEP_UNKNOWN_ERROR;
    24     
    25     identity_list* id_list_ptr = NULL;
    26         
    27     for (id_list_ptr = list; id_list_ptr; id_list_ptr = id_list_ptr->next) {
    28         pEp_identity* curr_identity = id_list_ptr->ident;
    29         if (curr_identity) {
    30             if (!is_me(session, curr_identity)) {
    31                 char* name_bak = curr_identity->username;
    32                 curr_identity->username = NULL;
    33                 status = update_identity(session, curr_identity);
    34                 if (name_bak && 
    35                     (EMPTYSTR(curr_identity->username) || strcmp(name_bak, curr_identity->username) != 0)) {
    36                     free(curr_identity->username);
    37                     curr_identity->username = name_bak;
    38                 }                        
    39             }
    40             else
    41                 status = _myself(session, curr_identity, false, false, true);
    42         if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
    43             return status;
    44         }
    45     }
    46     
    47     return PEP_STATUS_OK;                                  
    48 }
    49 
    50 DYNAMIC_API PEP_STATUS MIME_decrypt_message(
    51     PEP_SESSION session,
    52     const char *mimetext,
    53     size_t size,
    54     char** mime_plaintext,
    55     stringlist_t **keylist,
    56     PEP_rating *rating,
    57     PEP_decrypt_flags_t *flags,
    58     char** modified_src
    59 )
    60 {
    61     assert(mimetext);
    62     assert(mime_plaintext);
    63     assert(keylist);
    64     assert(rating);
    65     assert(flags);
    66     assert(modified_src);
    67 
    68     if (!(mimetext && mime_plaintext && keylist && rating && flags && modified_src))
    69         return PEP_ILLEGAL_VALUE;
    70         
    71     PEP_STATUS status = PEP_STATUS_OK;
    72     message* tmp_msg = NULL;
    73     message* dec_msg = NULL;
    74     *mime_plaintext = NULL;
    75 
    76     status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
    77     if (status != PEP_STATUS_OK)
    78         goto pEp_error;
    79 
    80     tmp_msg->dir = PEP_dir_incoming;
    81     // MIME decode message delivers only addresses. We need more.
    82     if (tmp_msg->from) {
    83         if (!is_me(session, tmp_msg->from))
    84             status = update_identity(session, (tmp_msg->from));
    85         else
    86             status = _myself(session, tmp_msg->from, false, false, true);
    87 
    88         if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY)
    89             goto pEp_error;
    90     }
    91 
    92     status = update_identity_recip_list(session, tmp_msg->to);
    93     if (status != PEP_STATUS_OK)
    94         goto pEp_error;
    95 
    96     status = update_identity_recip_list(session, tmp_msg->cc);
    97     if (status != PEP_STATUS_OK)
    98         goto pEp_error;
    99 
   100     status = update_identity_recip_list(session, tmp_msg->bcc);
   101     if (status != PEP_STATUS_OK)
   102         goto pEp_error;
   103 
   104     PEP_STATUS decrypt_status = decrypt_message(session,
   105                                                 tmp_msg,
   106                                                 &dec_msg,
   107                                                 keylist,
   108                                                 rating,
   109                                                 flags);
   110 
   111 
   112     if (!dec_msg && (decrypt_status == PEP_UNENCRYPTED || decrypt_status == PEP_VERIFIED)) {
   113         dec_msg = message_dup(tmp_msg);
   114     }
   115     
   116     if (decrypt_status > PEP_CANNOT_DECRYPT_UNKNOWN || !dec_msg)
   117     {
   118         status = decrypt_status;
   119         goto pEp_error;
   120     }
   121 
   122     if (*flags & PEP_decrypt_flag_src_modified) {
   123         mime_encode_message(tmp_msg, false, modified_src, false);
   124         if (!modified_src) {
   125             *flags &= (~PEP_decrypt_flag_src_modified);
   126             decrypt_status = PEP_CANNOT_REENCRYPT; // Because we couldn't return it, I guess.
   127         }
   128     }
   129 
   130     // FIXME: test with att
   131     status = mime_encode_message(dec_msg, false, mime_plaintext, false);
   132 
   133     if (status == PEP_STATUS_OK)
   134     {
   135         free(tmp_msg);
   136         free(dec_msg);
   137         return decrypt_status;
   138     }
   139     
   140 pEp_error:
   141     free_message(tmp_msg);
   142     free_message(dec_msg);
   143 
   144     return status;
   145 }
   146 
   147 
   148 DYNAMIC_API PEP_STATUS MIME_encrypt_message(
   149     PEP_SESSION session,
   150     const char *mimetext,
   151     size_t size,
   152     stringlist_t* extra,
   153     char** mime_ciphertext,
   154     PEP_enc_format enc_format,
   155     PEP_encrypt_flags_t flags
   156 )
   157 {
   158     PEP_STATUS status = PEP_STATUS_OK;
   159     PEP_STATUS tmp_status = PEP_STATUS_OK;
   160     message* tmp_msg = NULL;
   161     message* enc_msg = NULL;
   162     message* ret_msg = NULL;                             
   163 
   164     status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   165     if (status != PEP_STATUS_OK)
   166         goto pEp_error;
   167 
   168     // MIME decode message delivers only addresses. We need more.
   169     if (tmp_msg->from) {
   170         char* own_id = NULL;
   171         status = get_default_own_userid(session, &own_id);
   172         free(tmp_msg->from->user_id);
   173         
   174         if (status != PEP_STATUS_OK || !own_id) {
   175             tmp_msg->from->user_id = strdup(PEP_OWN_USERID);
   176         }
   177         else {
   178             tmp_msg->from->user_id = own_id; // ownership transfer
   179         }
   180             
   181         status = myself(session, tmp_msg->from);
   182         if (status != PEP_STATUS_OK)
   183             goto pEp_error;
   184     }
   185     
   186     // Own identities can be retrieved here where they would otherwise
   187     // fail because we lack all other information. This is ok and even
   188     // desired. FIXME: IS it?
   189     status = update_identity_recip_list(session, tmp_msg->to);
   190     if (status != PEP_STATUS_OK)
   191         goto pEp_error;
   192     
   193     status = update_identity_recip_list(session, tmp_msg->cc);
   194     if (status != PEP_STATUS_OK)
   195         goto pEp_error;
   196     
   197     status = update_identity_recip_list(session, tmp_msg->bcc);
   198     if (status != PEP_STATUS_OK)
   199         goto pEp_error;
   200     
   201     // This isn't incoming, though... so we need to reverse the direction
   202     tmp_msg->dir = PEP_dir_outgoing;
   203     status = encrypt_message(session,
   204                              tmp_msg,
   205                              extra,
   206                              &enc_msg,
   207                              enc_format,
   208                              flags);
   209                              
   210     if (status == PEP_STATUS_OK || status == PEP_UNENCRYPTED)
   211         ret_msg = (status == PEP_STATUS_OK ? enc_msg : tmp_msg);
   212     else                                
   213         goto pEp_error;
   214 
   215     if (status == PEP_STATUS_OK && !enc_msg) {
   216         status = PEP_UNKNOWN_ERROR;
   217         goto pEp_error;
   218     }
   219     
   220     tmp_status = mime_encode_message(ret_msg, 
   221                                      false, 
   222                                      mime_ciphertext, 
   223                                      false);
   224     
   225     if (tmp_status != PEP_STATUS_OK)
   226         status = tmp_status;
   227 
   228 pEp_error:
   229     free_message(tmp_msg);
   230     free_message(enc_msg);
   231 
   232     return status;
   233 
   234 }
   235 
   236 DYNAMIC_API PEP_STATUS MIME_encrypt_message_for_self(
   237     PEP_SESSION session,
   238     pEp_identity* target_id,
   239     const char *mimetext,
   240     size_t size,
   241     stringlist_t* extra,
   242     char** mime_ciphertext,
   243     PEP_enc_format enc_format,
   244     PEP_encrypt_flags_t flags
   245 )
   246 {
   247     PEP_STATUS status = PEP_STATUS_OK;
   248     message* tmp_msg = NULL;
   249     message* enc_msg = NULL;
   250 
   251     status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   252     if (status != PEP_STATUS_OK)
   253         goto pEp_error;
   254 
   255     // This isn't incoming, though... so we need to reverse the direction
   256     tmp_msg->dir = PEP_dir_outgoing;
   257     status = encrypt_message_for_self(session,
   258                                       target_id,
   259                                       tmp_msg,
   260                                       extra,
   261                                       &enc_msg,
   262                                       enc_format,
   263                                       flags);
   264     if (status != PEP_STATUS_OK)
   265         goto pEp_error;
   266  
   267     if (!enc_msg) {
   268         status = PEP_UNKNOWN_ERROR;
   269         goto pEp_error;
   270     }
   271 
   272     status = mime_encode_message(enc_msg, false, mime_ciphertext, false);
   273 
   274 pEp_error:
   275     free_message(tmp_msg);
   276     free_message(enc_msg);
   277 
   278     return status;
   279 }
   280 #else
   281 const int the_answer_my_friend = 42;
   282 #endif