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