src/message_api.c
author vb
Sat, 21 Feb 2015 16:55:43 +0100
changeset 62 ad5e484720e1
parent 56 eb39f8399076
child 63 f5b2641f4ae7
permissions -rw-r--r--
signal() and init()
vb@37
     1
#include "message_api.h"
vb@37
     2
#include "keymanagement.h"
vb@62
     3
#include "mime.h"
vb@37
     4
vb@37
     5
#include <assert.h>
vb@37
     6
#include <string.h>
vb@39
     7
#include <stdlib.h>
vb@39
     8
vb@39
     9
#define NOT_IMPLEMENTED assert(0);
vb@37
    10
vb@62
    11
static char * combine_short_and_long(const message * src)
vb@62
    12
{
vb@62
    13
    char * ptext;
vb@62
    14
    assert(src);
vb@62
    15
    assert(src->shortmsg && src->longmsg && strcmp(src->shortmsg, "pEp") != 0);
vb@62
    16
vb@62
    17
    ptext = calloc(1, strlen(src->shortmsg) + strlen(src->longmsg)
vb@62
    18
            + 12);
vb@62
    19
    if (ptext == NULL)
vb@62
    20
        return NULL;
vb@62
    21
vb@62
    22
    strcpy(ptext, "subject: ");
vb@62
    23
    strcat(ptext, src->shortmsg);
vb@62
    24
    strcat(ptext, "\n\n");
vb@62
    25
    strcat(ptext, src->longmsg);
vb@62
    26
vb@62
    27
    return ptext;
vb@62
    28
}
vb@44
    29
vb@48
    30
DYNAMIC_API PEP_STATUS encrypt_message(
vb@37
    31
        PEP_SESSION session,
vb@37
    32
        const message *src,
vb@37
    33
        stringlist_t * extra,
vb@38
    34
        message **dst,
vb@38
    35
        PEP_enc_format format
vb@37
    36
    )
vb@37
    37
{
vb@37
    38
    PEP_STATUS status = PEP_STATUS_OK;
vb@37
    39
vb@37
    40
    assert(session);
vb@37
    41
    assert(src);
vb@37
    42
    assert(dst);
vb@37
    43
    *dst = NULL;
vb@38
    44
    assert(format != PEP_enc_none);
vb@37
    45
vb@40
    46
    pEp_identity *from = identity_dup(src->from);
vb@40
    47
    if (from == NULL)
vb@40
    48
        return PEP_OUT_OF_MEMORY;
vb@40
    49
vb@40
    50
    identity_list *to = identity_list_dup(src->to);
vb@40
    51
    if (to == NULL) {
vb@40
    52
        free_identity(from);
vb@40
    53
        return PEP_OUT_OF_MEMORY;
vb@40
    54
    }
vb@40
    55
vb@40
    56
    message *msg = new_message(src->dir, from, to, NULL);
vb@56
    57
    if (msg == NULL) {
vb@56
    58
        free_identity(from);
vb@56
    59
        free_identity_list(to);
vb@37
    60
        return PEP_OUT_OF_MEMORY;
vb@56
    61
    }
vb@48
    62
    msg->enc_format = PEP_enc_pieces;
vb@37
    63
vb@40
    64
    from->me = true;
vb@37
    65
vb@40
    66
    status = myself(session, from);
vb@37
    67
    if (status != PEP_STATUS_OK) {
vb@37
    68
        free_message(msg);
vb@37
    69
        return status;
vb@37
    70
    }
vb@37
    71
vb@40
    72
    stringlist_t * keys = new_stringlist(from->fpr);
vb@37
    73
    if (keys == NULL) {
vb@37
    74
        free_message(msg);
vb@37
    75
        return PEP_OUT_OF_MEMORY;
vb@37
    76
    }
vb@37
    77
vb@39
    78
    stringlist_t *_k = keys;
vb@39
    79
vb@39
    80
    if (extra) {
vb@39
    81
        _k = stringlist_append(_k, extra);
vb@39
    82
        if (_k == NULL) {
vb@39
    83
            free_stringlist(keys);
vb@37
    84
            free_message(msg);
vb@37
    85
            return PEP_OUT_OF_MEMORY;
vb@37
    86
        }
vb@37
    87
    }
vb@39
    88
vb@39
    89
    bool dest_keys_found = false;
vb@37
    90
    identity_list * _il;
vb@40
    91
    for (_il = to; _il && _il->ident; _il = _il->next) {
vb@39
    92
        PEP_STATUS _status = update_identity(session, _il->ident);
vb@39
    93
        if (_status != PEP_STATUS_OK) {
vb@37
    94
            free_message(msg);
vb@37
    95
            free_stringlist(keys);
vb@39
    96
            return _status;
vb@37
    97
        }
vb@37
    98
        if (_il->ident->fpr) {
vb@39
    99
            dest_keys_found = true;
vb@39
   100
            _k = stringlist_add(_k, _il->ident->fpr);
vb@39
   101
            if (_k == NULL) {
vb@37
   102
                free_message(msg);
vb@37
   103
                free_stringlist(keys);
vb@37
   104
                return PEP_OUT_OF_MEMORY;
vb@37
   105
            }
vb@37
   106
        }
vb@37
   107
        else
vb@37
   108
            status = PEP_KEY_NOT_FOUND;
vb@37
   109
    }
vb@37
   110
vb@39
   111
    if (dest_keys_found) {
vb@38
   112
        char *ptext;
vb@37
   113
        char *ctext = NULL;
vb@37
   114
        size_t csize = 0;
vb@48
   115
        msg->enc_format = PEP_enc_pieces;
vb@37
   116
vb@38
   117
        switch (format) {
vb@44
   118
        case PEP_enc_MIME_multipart: {
vb@62
   119
            char *resulttext;
vb@62
   120
            bool free_ptext = false;
vb@48
   121
            msg->enc_format = PEP_enc_MIME_multipart;
vb@37
   122
vb@48
   123
            if (src->shortmsg && src->longmsg && strcmp(src->shortmsg, "pEp") != 0) {
vb@62
   124
                ptext = combine_short_and_long(src);
vb@38
   125
                if (ptext == NULL) {
vb@38
   126
                    free_message(msg);
vb@38
   127
                    free_stringlist(keys);
vb@38
   128
                    return PEP_OUT_OF_MEMORY;
vb@38
   129
                }
vb@62
   130
                free_ptext = true;
vb@62
   131
            }
vb@62
   132
            else if (src->longmsg) {
vb@62
   133
                ptext = src->longmsg;
vb@62
   134
            }
vb@62
   135
            else {
vb@62
   136
                ptext = NULL;
vb@62
   137
            }
vb@62
   138
vb@62
   139
            // TO EXTEND: we only support HTML yet
vb@62
   140
            assert(src->format == PEP_format_plain
vb@62
   141
                    || src->format == PEP_format_html);
vb@62
   142
vb@62
   143
            status = mime_encode_text(ptext, src->longmsg_formatted,
vb@62
   144
                    src->attachments, &resulttext);
vb@62
   145
            assert(status == PEP_STATUS_OK);
vb@62
   146
            if (free_ptext)
vb@62
   147
                free(ptext);
vb@62
   148
            assert(resulttext);
vb@62
   149
            if (resulttext == NULL) {
vb@62
   150
                free_message(msg);
vb@62
   151
                free_stringlist(keys);
vb@62
   152
                return status;
vb@62
   153
            }
vb@62
   154
            
vb@62
   155
            status = encrypt_and_sign(session, keys, resulttext, strlen(resulttext),
vb@62
   156
                    &ctext, &csize);
vb@62
   157
            free(resulttext);
vb@62
   158
            free_stringlist(keys);
vb@62
   159
            if (ctext) {
vb@62
   160
                msg->longmsg = strdup(ctext);
vb@62
   161
                msg->shortmsg = strdup("pEp");
vb@62
   162
                if (!(msg->longmsg && msg->shortmsg)) {
vb@62
   163
                    free_message(msg);
vb@62
   164
                    return PEP_OUT_OF_MEMORY;
vb@62
   165
                }
vb@62
   166
            }
vb@62
   167
        }
vb@62
   168
vb@62
   169
        case PEP_enc_pieces:
vb@62
   170
            if (src->shortmsg && src->longmsg && strcmp(src->shortmsg, "pEp") != 0) {
vb@62
   171
                ptext = combine_short_and_long(src);
vb@62
   172
                if (ptext == NULL) {
vb@62
   173
                    free_message(msg);
vb@62
   174
                    free_stringlist(keys);
vb@62
   175
                    return PEP_OUT_OF_MEMORY;
vb@62
   176
                }
vb@39
   177
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   178
                        &ctext, &csize);
vb@40
   179
                free(ptext);
vb@38
   180
                if (ctext) {
vb@40
   181
                    msg->longmsg = strdup(ctext);
vb@38
   182
                    msg->shortmsg = strdup("pEp");
vb@40
   183
                    if (!(msg->longmsg && msg->shortmsg)) {
vb@62
   184
                        free_stringlist(keys);
vb@40
   185
                        free_message(msg);
vb@40
   186
                        return PEP_OUT_OF_MEMORY;
vb@40
   187
                    }
vb@38
   188
                }
vb@38
   189
                else {
vb@38
   190
                    free_message(msg);
vb@62
   191
                    free_stringlist(keys);
vb@38
   192
                    msg = NULL;
vb@38
   193
                }
vb@38
   194
            }
vb@48
   195
            else if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
vb@43
   196
                ptext = calloc(1, strlen(src->shortmsg) + 12);
vb@43
   197
                if (ptext == NULL) {
vb@43
   198
                    free_message(msg);
vb@43
   199
                    free_stringlist(keys);
vb@43
   200
                    return PEP_OUT_OF_MEMORY;
vb@43
   201
                }
vb@43
   202
                strcpy(ptext, "subject: ");
vb@43
   203
                strcat(ptext, src->shortmsg);
vb@43
   204
                strcat(ptext, "\n\n");
vb@39
   205
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   206
                        &ctext, &csize);
vb@43
   207
                free(ptext);
vb@38
   208
                if (ctext) {
vb@40
   209
                    msg->longmsg = strdup(ctext);
vb@40
   210
                    msg->shortmsg = strdup("pEp");
vb@40
   211
                    if (!(msg->longmsg && msg->shortmsg)) {
vb@40
   212
                        free_message(msg);
vb@62
   213
                        free_stringlist(keys);
vb@40
   214
                        return PEP_OUT_OF_MEMORY;
vb@40
   215
                    }
vb@38
   216
                }
vb@38
   217
                else {
vb@38
   218
                    free_message(msg);
vb@38
   219
                    msg = NULL;
vb@38
   220
                }
vb@38
   221
            }
vb@38
   222
            else if (src->longmsg) {
vb@38
   223
                ptext = src->longmsg;
vb@39
   224
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   225
                        &ctext, &csize);
vb@38
   226
                if (ctext) {
vb@40
   227
                    msg->longmsg = strdup(ctext);
vb@38
   228
                    msg->shortmsg = strdup("pEp");
vb@40
   229
                    if (!(msg->longmsg && msg->shortmsg)) {
vb@40
   230
                        free_message(msg);
vb@40
   231
                        return PEP_OUT_OF_MEMORY;
vb@40
   232
                    }
vb@38
   233
                }
vb@38
   234
                else {
vb@38
   235
                    free_message(msg);
vb@38
   236
                    msg = NULL;
vb@38
   237
                }
vb@38
   238
            }
vb@38
   239
            if (msg && msg->longmsg_formatted) {
vb@38
   240
                ptext = src->longmsg_formatted;
vb@39
   241
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   242
                        &ctext, &csize);
vb@38
   243
                if (ctext) {
vb@40
   244
                    msg->longmsg_formatted = strdup(ctext);
vb@40
   245
                    if (msg->longmsg_formatted == NULL) {
vb@40
   246
                        free_message(msg);
vb@40
   247
                        return PEP_OUT_OF_MEMORY;
vb@40
   248
                    }
vb@38
   249
                }
vb@38
   250
                else {
vb@38
   251
                    free_message(msg);
vb@38
   252
                    msg = NULL;
vb@38
   253
                }
vb@38
   254
            }
vb@38
   255
            if (msg) {
vb@42
   256
                if (src->attachments) {
vb@42
   257
                    bloblist_t *_s;
vb@42
   258
                    bloblist_t *_d = new_bloblist(NULL, 0, NULL, NULL);
vb@42
   259
                    if (_d == NULL) {
vb@42
   260
                        free_message(msg);
vb@42
   261
                        free_stringlist(keys);
vb@42
   262
                        return PEP_OUT_OF_MEMORY;
vb@42
   263
                    }
vb@42
   264
                    msg->attachments = _d;
vb@42
   265
                    for (_s = src->attachments; _s && _s->data; _s = _s->next) {
vb@42
   266
                        int psize = _s->size;
vb@42
   267
                        ptext = _s->data;
vb@42
   268
                        status = encrypt_and_sign(session, keys, ptext, psize,
vb@42
   269
                                &ctext, &csize);
vb@42
   270
                        if (ctext) {
vb@42
   271
                            char * _c = strdup(ctext);
vb@42
   272
                            if (_c == NULL) {
vb@42
   273
                                free_message(msg);
vb@42
   274
                                free_stringlist(keys);
vb@42
   275
                                return PEP_OUT_OF_MEMORY;
vb@42
   276
                            }
vb@42
   277
                            _d = bloblist_add(_d, _c, csize, _s->mime_type,
vb@42
   278
                                    _s->file_name);
vb@42
   279
                            if (_d == NULL) {
vb@42
   280
                                free_message(msg);
vb@42
   281
                                free_stringlist(keys);
vb@42
   282
                                return PEP_OUT_OF_MEMORY;
vb@42
   283
                            }
vb@42
   284
                        }
vb@42
   285
                        else {
vb@40
   286
                            free_message(msg);
vb@42
   287
                            msg = NULL;
vb@42
   288
                            break;
vb@40
   289
                        }
vb@38
   290
                    }
vb@38
   291
                }
vb@38
   292
                *dst = msg;
vb@38
   293
            }
vb@38
   294
            break;
vb@38
   295
vb@38
   296
        default:
vb@38
   297
            assert(0);
vb@37
   298
        }
vb@37
   299
    }
vb@37
   300
    else
vb@37
   301
        free_message(msg);
vb@37
   302
vb@37
   303
    free_stringlist(keys);
vb@37
   304
    return status;
vb@37
   305
}
vb@37
   306
vb@48
   307
DYNAMIC_API PEP_STATUS decrypt_message(
vb@37
   308
        PEP_SESSION session,
vb@37
   309
        const message *src,
vb@37
   310
        message **dst
vb@37
   311
    )
vb@37
   312
{
vb@37
   313
    PEP_STATUS status = PEP_STATUS_OK;
vb@37
   314
vb@39
   315
    NOT_IMPLEMENTED
vb@39
   316
vb@37
   317
    return status;
vb@37
   318
}
vb@37
   319