src/message_api.c
author vb
Sun, 22 Feb 2015 13:49:19 +0100
changeset 64 d393c205d201
parent 63 f5b2641f4ae7
child 67 65cc950ce03d
permissions -rw-r--r--
even nicer ;-)
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@63
    14
    char * longmsg;
vb@62
    15
    assert(src);
vb@63
    16
    assert(src->shortmsg && strcmp(src->shortmsg, "pEp") != 0);
vb@62
    17
vb@63
    18
    if (src->longmsg)
vb@63
    19
        longmsg = src->longmsg;
vb@63
    20
    else
vb@63
    21
        longmsg = "";
vb@63
    22
vb@63
    23
    ptext = calloc(1, strlen(src->shortmsg) + strlen(longmsg) + 12);
vb@62
    24
    if (ptext == NULL)
vb@62
    25
        return NULL;
vb@62
    26
vb@62
    27
    strcpy(ptext, "subject: ");
vb@62
    28
    strcat(ptext, src->shortmsg);
vb@62
    29
    strcat(ptext, "\n\n");
vb@63
    30
    strcat(ptext, longmsg);
vb@62
    31
vb@62
    32
    return ptext;
vb@62
    33
}
vb@44
    34
vb@48
    35
DYNAMIC_API PEP_STATUS encrypt_message(
vb@37
    36
        PEP_SESSION session,
vb@37
    37
        const message *src,
vb@37
    38
        stringlist_t * extra,
vb@38
    39
        message **dst,
vb@38
    40
        PEP_enc_format format
vb@37
    41
    )
vb@37
    42
{
vb@37
    43
    PEP_STATUS status = PEP_STATUS_OK;
vb@63
    44
    message * msg = NULL;
vb@63
    45
    stringlist_t * keys = NULL;
vb@37
    46
vb@37
    47
    assert(session);
vb@37
    48
    assert(src);
vb@37
    49
    assert(dst);
vb@37
    50
    *dst = NULL;
vb@38
    51
    assert(format != PEP_enc_none);
vb@37
    52
vb@40
    53
    pEp_identity *from = identity_dup(src->from);
vb@40
    54
    if (from == NULL)
vb@63
    55
        goto enomem;
vb@63
    56
    from->me = true;
vb@40
    57
vb@40
    58
    identity_list *to = identity_list_dup(src->to);
vb@40
    59
    if (to == NULL) {
vb@40
    60
        free_identity(from);
vb@63
    61
        goto enomem;
vb@40
    62
    }
vb@40
    63
vb@63
    64
    msg = new_message(src->dir, from, to, NULL);
vb@56
    65
    if (msg == NULL) {
vb@56
    66
        free_identity(from);
vb@56
    67
        free_identity_list(to);
vb@63
    68
        goto enomem;
vb@56
    69
    }
vb@48
    70
    msg->enc_format = PEP_enc_pieces;
vb@37
    71
vb@63
    72
    status = myself(session, from);
vb@63
    73
    if (status != PEP_STATUS_OK)
vb@63
    74
        goto pep_error;
vb@37
    75
vb@63
    76
    keys = new_stringlist(from->fpr);
vb@63
    77
    if (keys == NULL)
vb@63
    78
        goto enomem;
vb@37
    79
vb@39
    80
    stringlist_t *_k = keys;
vb@39
    81
vb@39
    82
    if (extra) {
vb@39
    83
        _k = stringlist_append(_k, extra);
vb@63
    84
        if (_k == NULL)
vb@63
    85
            goto enomem;
vb@37
    86
    }
vb@39
    87
vb@39
    88
    bool dest_keys_found = false;
vb@37
    89
    identity_list * _il;
vb@40
    90
    for (_il = to; _il && _il->ident; _il = _il->next) {
vb@63
    91
        PEP_STATUS status = update_identity(session, _il->ident);
vb@63
    92
        if (status != PEP_STATUS_OK)
vb@63
    93
            goto pep_error;
vb@63
    94
vb@37
    95
        if (_il->ident->fpr) {
vb@39
    96
            dest_keys_found = true;
vb@39
    97
            _k = stringlist_add(_k, _il->ident->fpr);
vb@63
    98
            if (_k == NULL)
vb@63
    99
                goto enomem;
vb@37
   100
        }
vb@37
   101
        else
vb@37
   102
            status = PEP_KEY_NOT_FOUND;
vb@37
   103
    }
vb@37
   104
vb@39
   105
    if (dest_keys_found) {
vb@38
   106
        char *ptext;
vb@37
   107
        char *ctext = NULL;
vb@37
   108
        size_t csize = 0;
vb@37
   109
vb@38
   110
        switch (format) {
vb@44
   111
        case PEP_enc_MIME_multipart: {
vb@63
   112
            char *resulttext = NULL;
vb@62
   113
            bool free_ptext = false;
vb@64
   114
vb@48
   115
            msg->enc_format = PEP_enc_MIME_multipart;
vb@37
   116
vb@63
   117
            if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
vb@62
   118
                ptext = combine_short_and_long(src);
vb@63
   119
                if (ptext == NULL)
vb@63
   120
                    goto enomem;
vb@62
   121
                free_ptext = true;
vb@62
   122
            }
vb@62
   123
            else if (src->longmsg) {
vb@62
   124
                ptext = src->longmsg;
vb@62
   125
            }
vb@62
   126
vb@62
   127
            status = mime_encode_text(ptext, src->longmsg_formatted,
vb@62
   128
                    src->attachments, &resulttext);
vb@62
   129
            assert(status == PEP_STATUS_OK);
vb@62
   130
            if (free_ptext)
vb@62
   131
                free(ptext);
vb@62
   132
            assert(resulttext);
vb@63
   133
            if (resulttext == NULL)
vb@63
   134
                goto pep_error;
vb@62
   135
            
vb@62
   136
            status = encrypt_and_sign(session, keys, resulttext, strlen(resulttext),
vb@62
   137
                    &ctext, &csize);
vb@62
   138
            free(resulttext);
vb@62
   139
            if (ctext) {
vb@62
   140
                msg->longmsg = strdup(ctext);
vb@64
   141
                if (msg->longmsg == NULL)
vb@63
   142
                    goto enomem;
vb@63
   143
            }
vb@63
   144
            else {
vb@63
   145
                goto pep_error;
vb@62
   146
            }
vb@62
   147
        }
vb@63
   148
        break;
vb@62
   149
vb@62
   150
        case PEP_enc_pieces:
vb@64
   151
            msg->enc_format = PEP_enc_pieces;
vb@64
   152
vb@63
   153
            if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
vb@62
   154
                ptext = combine_short_and_long(src);
vb@63
   155
                if (ptext == NULL)
vb@63
   156
                    goto enomem;
vb@63
   157
vb@39
   158
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   159
                        &ctext, &csize);
vb@40
   160
                free(ptext);
vb@38
   161
                if (ctext) {
vb@40
   162
                    msg->longmsg = strdup(ctext);
vb@64
   163
                    if (msg->longmsg == NULL)
vb@63
   164
                        goto enomem;
vb@38
   165
                }
vb@38
   166
                else {
vb@63
   167
                    goto pep_error;
vb@38
   168
                }
vb@38
   169
            }
vb@38
   170
            else if (src->longmsg) {
vb@38
   171
                ptext = src->longmsg;
vb@39
   172
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   173
                        &ctext, &csize);
vb@38
   174
                if (ctext) {
vb@40
   175
                    msg->longmsg = strdup(ctext);
vb@64
   176
                    if (msg->longmsg == NULL)
vb@63
   177
                        goto enomem;
vb@38
   178
                }
vb@38
   179
                else {
vb@63
   180
                    goto pep_error;
vb@38
   181
                }
vb@38
   182
            }
vb@63
   183
vb@63
   184
            if (msg->longmsg_formatted) {
vb@38
   185
                ptext = src->longmsg_formatted;
vb@39
   186
                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
vb@39
   187
                        &ctext, &csize);
vb@38
   188
                if (ctext) {
vb@40
   189
                    msg->longmsg_formatted = strdup(ctext);
vb@63
   190
                    if (msg->longmsg_formatted == NULL)
vb@63
   191
                        goto enomem;
vb@63
   192
                }
vb@63
   193
                else {
vb@63
   194
                    goto pep_error;
vb@63
   195
                }
vb@63
   196
            }
vb@63
   197
vb@63
   198
            if (src->attachments) {
vb@63
   199
                bloblist_t *_s;
vb@63
   200
                bloblist_t *_d = new_bloblist(NULL, 0, NULL, NULL);
vb@63
   201
                if (_d == NULL)
vb@63
   202
                    goto enomem;
vb@63
   203
vb@63
   204
                msg->attachments = _d;
vb@63
   205
                for (_s = src->attachments; _s && _s->data; _s = _s->next) {
vb@63
   206
                    int psize = _s->size;
vb@63
   207
                    ptext = _s->data;
vb@63
   208
                    status = encrypt_and_sign(session, keys, ptext, psize,
vb@63
   209
                            &ctext, &csize);
vb@63
   210
                    if (ctext) {
vb@63
   211
                        char * _c = strdup(ctext);
vb@63
   212
                        if (_c == NULL)
vb@63
   213
                            goto enomem;
vb@63
   214
vb@63
   215
                        _d = bloblist_add(_d, _c, csize, _s->mime_type,
vb@63
   216
                                _s->file_name);
vb@63
   217
                        if (_d == NULL)
vb@63
   218
                            goto enomem;
vb@63
   219
                    }
vb@63
   220
                    else {
vb@63
   221
                        goto pep_error;
vb@40
   222
                    }
vb@38
   223
                }
vb@38
   224
            }
vb@38
   225
            break;
vb@38
   226
vb@38
   227
        default:
vb@38
   228
            assert(0);
vb@63
   229
            status = PEP_ILLEGAL_VALUE;
vb@63
   230
            goto pep_error;
vb@37
   231
        }
vb@37
   232
    }
vb@37
   233
vb@37
   234
    free_stringlist(keys);
vb@63
   235
vb@64
   236
    if (msg->shortmsg == NULL)
vb@64
   237
        msg->shortmsg = strdup("pEp");
vb@64
   238
vb@63
   239
    *dst = msg;
vb@63
   240
    return PEP_STATUS_OK;
vb@63
   241
vb@63
   242
enomem:
vb@63
   243
    status = PEP_OUT_OF_MEMORY;
vb@63
   244
vb@63
   245
pep_error:
vb@63
   246
    free_stringlist(keys);
vb@63
   247
    free_message(msg);
vb@63
   248
vb@37
   249
    return status;
vb@37
   250
}
vb@37
   251
vb@48
   252
DYNAMIC_API PEP_STATUS decrypt_message(
vb@37
   253
        PEP_SESSION session,
vb@37
   254
        const message *src,
vb@37
   255
        message **dst
vb@37
   256
    )
vb@37
   257
{
vb@37
   258
    PEP_STATUS status = PEP_STATUS_OK;
vb@37
   259
vb@39
   260
    NOT_IMPLEMENTED
vb@39
   261
vb@37
   262
    return status;
vb@37
   263
}
vb@37
   264