src/message_api.c
changeset 260 75481f577114
parent 259 71d6c073fda4
child 261 c007f4b3818a
     1.1 --- a/src/message_api.c	Fri May 08 16:53:39 2015 +0200
     1.2 +++ b/src/message_api.c	Sat May 09 17:55:02 2015 +0200
     1.3 @@ -342,6 +342,187 @@
     1.4      return NULL;
     1.5  }
     1.6  
     1.7 +static PEP_STATUS encrypt_PGP_MIME(
     1.8 +        PEP_SESSION session,
     1.9 +        const message *src,
    1.10 +        stringlist_t *keys,
    1.11 +        message *dst
    1.12 +    )
    1.13 +{
    1.14 +    PEP_STATUS status = PEP_STATUS_OK;
    1.15 +    bool free_ptext = false;
    1.16 +    char *ptext;
    1.17 +    char *ctext = NULL;
    1.18 +    char *mimetext = NULL;
    1.19 +    size_t csize;
    1.20 +    assert(dst->longmsg == NULL);
    1.21 +    dst->enc_format = PEP_enc_PGP_MIME;
    1.22 +
    1.23 +    if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
    1.24 +        ptext = combine_short_and_long(src->shortmsg, src->longmsg);
    1.25 +        if (ptext == NULL)
    1.26 +            goto enomem;
    1.27 +        free_ptext = true;
    1.28 +    }
    1.29 +    else if (src->longmsg) {
    1.30 +        ptext = src->longmsg;
    1.31 +    }
    1.32 +    else {
    1.33 +        ptext = "pEp";
    1.34 +    }
    1.35 +
    1.36 +    message *_src = calloc(1, sizeof(message));
    1.37 +    assert(_src);
    1.38 +    if (_src == NULL)
    1.39 +        goto enomem;
    1.40 +    _src->longmsg = ptext;
    1.41 +    _src->longmsg_formatted = src->longmsg_formatted;
    1.42 +    _src->attachments = src->attachments;
    1.43 +    _src->enc_format = PEP_enc_none;
    1.44 +    status = mime_encode_message(_src, true, &mimetext);
    1.45 +    assert(status == PEP_STATUS_OK);
    1.46 +    if (free_ptext)
    1.47 +        free(ptext);
    1.48 +    free(_src);
    1.49 +    assert(mimetext);
    1.50 +    if (mimetext == NULL)
    1.51 +        goto pep_error;
    1.52 +
    1.53 +    status = encrypt_and_sign(session, keys, mimetext, strlen(mimetext),
    1.54 +            &ctext, &csize);
    1.55 +    free(mimetext);
    1.56 +    if (ctext == NULL)
    1.57 +        goto pep_error;
    1.58 +
    1.59 +    dst->longmsg = strdup("this message was encrypted with p≡p "
    1.60 +            "http://pEp-project.org");
    1.61 +    if (dst->longmsg == NULL)
    1.62 +        goto enomem;
    1.63 +
    1.64 +    char *v = strdup("Version: 1");
    1.65 +    if (v == NULL)
    1.66 +        goto enomem;
    1.67 +
    1.68 +    bloblist_t *_a = new_bloblist(v, 11, "application/pgp-encrypted", NULL);
    1.69 +    if (_a == NULL)
    1.70 +        goto enomem;
    1.71 +    dst->attachments = _a;
    1.72 +    _a = bloblist_add(_a, ctext, strlen(ctext) + 1, "application/octet-stream",
    1.73 +            "msg.asc");
    1.74 +    if (_a == NULL)
    1.75 +        goto enomem;
    1.76 +
    1.77 +theend:
    1.78 +    return PEP_STATUS_OK;
    1.79 +
    1.80 +enomem:
    1.81 +    status = PEP_OUT_OF_MEMORY;
    1.82 +
    1.83 +pep_error:
    1.84 +    if (free_ptext)
    1.85 +        free(ptext);
    1.86 +    free(ctext);
    1.87 +    return status;
    1.88 +}
    1.89 +
    1.90 +static PEP_STATUS encrypt_PGP_in_pieces(
    1.91 +        PEP_SESSION session,
    1.92 +        const message *src,
    1.93 +        stringlist_t *keys,
    1.94 +        message *dst
    1.95 +    )
    1.96 +{
    1.97 +    PEP_STATUS status = PEP_STATUS_OK;
    1.98 +    char *ctext = NULL;
    1.99 +    size_t csize;
   1.100 +
   1.101 +    assert(dst->longmsg == NULL);
   1.102 +    assert(dst->attachments == NULL);
   1.103 +
   1.104 +    dst->enc_format = PEP_enc_pieces;
   1.105 +
   1.106 +    if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
   1.107 +        char *ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   1.108 +        if (ptext == NULL)
   1.109 +            goto enomem;
   1.110 +
   1.111 +        status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.112 +                &csize);
   1.113 +        free(ptext);
   1.114 +        if (ctext) {
   1.115 +            dst->longmsg = strdup(ctext);
   1.116 +            if (dst->longmsg == NULL)
   1.117 +                goto enomem;
   1.118 +        }
   1.119 +        else {
   1.120 +            goto pep_error;
   1.121 +        }
   1.122 +    }
   1.123 +    else if (src->longmsg) {
   1.124 +        char *ptext = src->longmsg;
   1.125 +        status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.126 +                &csize);
   1.127 +        if (ctext) {
   1.128 +            dst->longmsg = strdup(ctext);
   1.129 +            if (dst->longmsg == NULL)
   1.130 +                goto enomem;
   1.131 +        }
   1.132 +        else {
   1.133 +            goto pep_error;
   1.134 +        }
   1.135 +    }
   1.136 +
   1.137 +    if (src->longmsg_formatted) {
   1.138 +        char *ptext = src->longmsg_formatted;
   1.139 +        status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.140 +                &csize);
   1.141 +        if (ctext) {
   1.142 +            dst->longmsg_formatted = strdup(ctext);
   1.143 +            if (dst->longmsg_formatted == NULL)
   1.144 +                goto enomem;
   1.145 +        }
   1.146 +        else {
   1.147 +            goto pep_error;
   1.148 +        }
   1.149 +    }
   1.150 +
   1.151 +    if (src->attachments) {
   1.152 +        bloblist_t *_s;
   1.153 +        bloblist_t *_d = new_bloblist(NULL, 0, NULL, NULL);
   1.154 +        if (_d == NULL)
   1.155 +            goto enomem;
   1.156 +
   1.157 +        dst->attachments = _d;
   1.158 +        for (_s = src->attachments; _s && _s->data; _s = _s->next) {
   1.159 +            int psize = _s->size;
   1.160 +            char *ptext = _s->data;
   1.161 +            status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
   1.162 +                    &csize);
   1.163 +            if (ctext) {
   1.164 +                char * _c = strdup(ctext);
   1.165 +                if (_c == NULL)
   1.166 +                    goto enomem;
   1.167 +
   1.168 +                _d = bloblist_add(_d, _c, csize, _s->mime_type, _s->filename);
   1.169 +                if (_d == NULL)
   1.170 +                    goto enomem;
   1.171 +            }
   1.172 +            else {
   1.173 +                goto pep_error;
   1.174 +            }
   1.175 +        }
   1.176 +    }
   1.177 +
   1.178 +theend:
   1.179 +    return PEP_STATUS_OK;
   1.180 +
   1.181 +enomem:
   1.182 +    status = PEP_OUT_OF_MEMORY;
   1.183 +
   1.184 +pep_error:
   1.185 +    return status;
   1.186 +}
   1.187 +
   1.188  DYNAMIC_API PEP_STATUS encrypt_message(
   1.189          PEP_SESSION session,
   1.190          message *src,
   1.191 @@ -358,13 +539,14 @@
   1.192      assert(session);
   1.193      assert(src);
   1.194      assert(dst);
   1.195 -    assert(enc_format >= PEP_enc_pieces);
   1.196 +    assert(enc_format != PEP_enc_none);
   1.197  
   1.198 -    if (!(session && src && dst && (enc_format >= PEP_enc_pieces)))
   1.199 +    if (!(session && src && dst && enc_format != PEP_enc_none))
   1.200          return PEP_ILLEGAL_VALUE;
   1.201  
   1.202 -    import_attached_keys(session, src);
   1.203      determine_encryption_format(src);
   1.204 +    if (src->enc_format != PEP_enc_none)
   1.205 +        return PEP_ILLEGAL_VALUE;
   1.206  
   1.207      *dst = NULL;
   1.208  
   1.209 @@ -411,147 +593,17 @@
   1.210          size_t csize = 0;
   1.211  
   1.212          switch (enc_format) {
   1.213 -        case PEP_enc_PGP_MIME: {
   1.214 -            bool free_ptext = false;
   1.215 -
   1.216 -            msg->enc_format = PEP_enc_PGP_MIME;
   1.217 -
   1.218 -            if (src->mime == PEP_MIME) {
   1.219 -                message *_src = NULL;
   1.220 -                assert(src->longmsg);
   1.221 -                status = mime_decode_message(src->longmsg, &_src);
   1.222 -                if (status != PEP_STATUS_OK)
   1.223 -                    goto pep_error;
   1.224 -                if (free_src)
   1.225 -                    free_message(src);
   1.226 -                src = _src;
   1.227 -                free_src = true;
   1.228 -            }
   1.229 -
   1.230 -            if (src->mime == PEP_MIME_none) {
   1.231 -                if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
   1.232 -                    ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   1.233 -                    if (ptext == NULL)
   1.234 -                        goto enomem;
   1.235 -                    free_ptext = true;
   1.236 -                }
   1.237 -                else if (src->longmsg) {
   1.238 -                    ptext = src->longmsg;
   1.239 -                }
   1.240 -                else {
   1.241 -                    ptext = "pEp";
   1.242 -                }
   1.243 -
   1.244 -                message *_src = calloc(1, sizeof(message));
   1.245 -                assert(_src);
   1.246 -                if (_src == NULL)
   1.247 -                    goto enomem;
   1.248 -                _src->longmsg = ptext;
   1.249 -                _src->longmsg_formatted = src->longmsg_formatted;
   1.250 -                _src->attachments = src->attachments;
   1.251 -                _src->enc_format = PEP_enc_PGP_MIME;
   1.252 -                status = mime_encode_message(_src, true, &ptext);
   1.253 -                assert(status == PEP_STATUS_OK);
   1.254 -                if (free_ptext)
   1.255 -                    free(_src->longmsg);
   1.256 -                free(_src);
   1.257 -                assert(ptext);
   1.258 -                if (ptext == NULL)
   1.259 -                    goto pep_error;
   1.260 -                free_ptext = true;
   1.261 -            }
   1.262 -            else /* if (src->mime == PEP_MIME_fields_omitted) */ {
   1.263 -                ptext = src->longmsg;
   1.264 -            }
   1.265 -
   1.266 -            status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
   1.267 -                    &ctext, &csize);
   1.268 -            if (free_ptext)
   1.269 -                free(ptext);
   1.270 -            if (ctext == NULL)
   1.271 +        case PEP_enc_PGP_MIME:
   1.272 +            status = encrypt_PGP_MIME(session, src, keys, msg);
   1.273 +            if (status != PEP_STATUS_OK)
   1.274                  goto pep_error;
   1.275 -
   1.276 -            msg->longmsg = strdup(ctext);
   1.277 -            if (msg->longmsg == NULL)
   1.278 -                goto enomem;
   1.279 -        }
   1.280 -        break;
   1.281 +            break;
   1.282  
   1.283          case PEP_enc_pieces:
   1.284 -            msg->enc_format = PEP_enc_pieces;
   1.285 -
   1.286 -            if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
   1.287 -                ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   1.288 -                if (ptext == NULL)
   1.289 -                    goto enomem;
   1.290 -
   1.291 -                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
   1.292 -                        &ctext, &csize);
   1.293 -                free(ptext);
   1.294 -                if (ctext) {
   1.295 -                    msg->longmsg = strdup(ctext);
   1.296 -                    if (msg->longmsg == NULL)
   1.297 -                        goto enomem;
   1.298 -                }
   1.299 -                else {
   1.300 -                    goto pep_error;
   1.301 -                }
   1.302 -            }
   1.303 -            else if (src->longmsg) {
   1.304 -                ptext = src->longmsg;
   1.305 -                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
   1.306 -                        &ctext, &csize);
   1.307 -                if (ctext) {
   1.308 -                    msg->longmsg = strdup(ctext);
   1.309 -                    if (msg->longmsg == NULL)
   1.310 -                        goto enomem;
   1.311 -                }
   1.312 -                else {
   1.313 -                    goto pep_error;
   1.314 -                }
   1.315 -            }
   1.316 -
   1.317 -            if (msg->longmsg_formatted) {
   1.318 -                ptext = src->longmsg_formatted;
   1.319 -                status = encrypt_and_sign(session, keys, ptext, strlen(ptext),
   1.320 -                        &ctext, &csize);
   1.321 -                if (ctext) {
   1.322 -                    msg->longmsg_formatted = strdup(ctext);
   1.323 -                    if (msg->longmsg_formatted == NULL)
   1.324 -                        goto enomem;
   1.325 -                }
   1.326 -                else {
   1.327 -                    goto pep_error;
   1.328 -                }
   1.329 -            }
   1.330 -
   1.331 -            if (src->attachments) {
   1.332 -                bloblist_t *_s;
   1.333 -                bloblist_t *_d = new_bloblist(NULL, 0, NULL, NULL);
   1.334 -                if (_d == NULL)
   1.335 -                    goto enomem;
   1.336 -
   1.337 -                msg->attachments = _d;
   1.338 -                for (_s = src->attachments; _s && _s->data; _s = _s->next) {
   1.339 -                    int psize = _s->size;
   1.340 -                    ptext = _s->data;
   1.341 -                    status = encrypt_and_sign(session, keys, ptext, psize,
   1.342 -                            &ctext, &csize);
   1.343 -                    if (ctext) {
   1.344 -                        char * _c = strdup(ctext);
   1.345 -                        if (_c == NULL)
   1.346 -                            goto enomem;
   1.347 -
   1.348 -                        _d = bloblist_add(_d, _c, csize, _s->mime_type,
   1.349 -                                _s->filename);
   1.350 -                        if (_d == NULL)
   1.351 -                            goto enomem;
   1.352 -                    }
   1.353 -                    else {
   1.354 -                        goto pep_error;
   1.355 -                    }
   1.356 -                }
   1.357 -            }
   1.358 +            status = encrypt_PGP_in_pieces(session, src, keys, msg);
   1.359 +            if (status != PEP_STATUS_OK)
   1.360 +                goto pep_error;
   1.361 +            attach_own_key(session, msg);
   1.362              break;
   1.363  
   1.364          case PEP_enc_PEP:
   1.365 @@ -564,6 +616,9 @@
   1.366              goto pep_error;
   1.367          }
   1.368      }
   1.369 +    else {
   1.370 +        attach_own_key(session, msg);
   1.371 +    }
   1.372  
   1.373      free_stringlist(keys);
   1.374      if (free_src)
   1.375 @@ -572,8 +627,6 @@
   1.376      if (msg->shortmsg == NULL)
   1.377          msg->shortmsg = strdup("pEp");
   1.378  
   1.379 -    attach_own_key(session, msg);
   1.380 -
   1.381      *dst = msg;
   1.382      return PEP_STATUS_OK;
   1.383  
   1.384 @@ -716,23 +769,20 @@
   1.385      for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.386          PEP_comm_type ct;
   1.387          PEP_STATUS status;
   1.388 -        PEP_color _color;
   1.389  
   1.390 -        _color = key_color(session, _kl->value);
   1.391 -        if (_color == PEP_rating_under_attack)
   1.392 +        color = key_color(session, _kl->value);
   1.393 +        if (color == PEP_rating_under_attack)
   1.394              return PEP_rating_under_attack;
   1.395  
   1.396 -        color = MIN(color, _color);
   1.397 -
   1.398 -        status = least_trust(session, _kl->value, &ct);
   1.399 -        if (status != PEP_STATUS_OK)
   1.400 -            return PEP_rating_undefined;
   1.401 -
   1.402 -        _color = _rating(ct);
   1.403 -        if (_color == PEP_rating_under_attack)
   1.404 -            return PEP_rating_under_attack;
   1.405 -
   1.406 -        color = MIN(color, _color);
   1.407 +        if (color >= PEP_rating_reliable) {
   1.408 +            status = least_trust(session, _kl->value, &ct);
   1.409 +            if (status != PEP_STATUS_OK)
   1.410 +                return PEP_rating_undefined;
   1.411 +            if (ct == PEP_ct_unknown)
   1.412 +                color = PEP_rating_unreliable;
   1.413 +            else
   1.414 +                color = _rating(ct);
   1.415 +        }
   1.416      }
   1.417  
   1.418      return color;
   1.419 @@ -741,7 +791,6 @@
   1.420  DYNAMIC_API PEP_STATUS decrypt_message(
   1.421          PEP_SESSION session,
   1.422          message *src,
   1.423 -        PEP_MIME_format mime,
   1.424          message **dst,
   1.425          stringlist_t **keylist,
   1.426          PEP_color *color
   1.427 @@ -772,27 +821,6 @@
   1.428      *keylist = NULL;
   1.429      *color = PEP_rating_undefined;
   1.430   
   1.431 -    if (src->mime == PEP_MIME_fields_omitted || src->mime == PEP_MIME) {
   1.432 -        message *_src = NULL;
   1.433 -        status = mime_decode_message(src->longmsg, &_src);
   1.434 -        if (status != PEP_STATUS_OK)
   1.435 -            goto pep_error;
   1.436 -
   1.437 -        if ( src->mime == PEP_MIME_fields_omitted) {
   1.438 -            status = copy_fields(_src, src);
   1.439 -            if (status != PEP_STATUS_OK) {
   1.440 -                free_message(_src);
   1.441 -                goto pep_error;
   1.442 -            }
   1.443 -        }
   1.444 -
   1.445 -        src = _src;
   1.446 -        free_src = true;
   1.447 -    }
   1.448 -
   1.449 -    // src message is not MIME encoded (any more)
   1.450 -    assert(src->mime == PEP_MIME_none);
   1.451 -
   1.452      if (crypto) {
   1.453          ctext = src->longmsg;
   1.454          csize = strlen(src->longmsg);
   1.455 @@ -804,6 +832,7 @@
   1.456      }
   1.457      else {
   1.458          status = PEP_UNENCRYPTED;
   1.459 +        goto theend;
   1.460      }
   1.461  
   1.462      *color = decrypt_color(status);
   1.463 @@ -817,16 +846,13 @@
   1.464          if (kl_color == PEP_rating_under_attack)
   1.465              *color = PEP_rating_under_attack;
   1.466  
   1.467 -        else if (*color == PEP_rating_reliable &&
   1.468 -                kl_color >= PEP_rating_trusted)
   1.469 -            *color = kl_color;
   1.470 -
   1.471 -        else if (*color == PEP_rating_reliable &&
   1.472 +        else if (*color >= PEP_rating_reliable &&
   1.473                  kl_color < PEP_rating_reliable)
   1.474              *color = PEP_rating_unreliable;
   1.475  
   1.476 -        else
   1.477 -            *color = MIN(*color, kl_color);
   1.478 +        else if (*color >= PEP_rating_reliable &&
   1.479 +                kl_color >= PEP_rating_trusted)
   1.480 +            *color = kl_color;
   1.481      }
   1.482  
   1.483      if (ptext) {
   1.484 @@ -934,38 +960,10 @@
   1.485                  NOT_IMPLEMENTED
   1.486          }
   1.487  
   1.488 -        switch (mime) {
   1.489 -            case PEP_MIME_none:
   1.490 -                break;
   1.491 -
   1.492 -            case PEP_MIME:
   1.493 -            case PEP_MIME_fields_omitted:
   1.494 -                {
   1.495 -                    char *text = NULL;
   1.496 -                    status = mime_encode_message(msg,
   1.497 -                            mime == PEP_MIME_fields_omitted, &text);
   1.498 -                    if (status != PEP_STATUS_OK)
   1.499 -                        goto pep_error;
   1.500 -
   1.501 -                    message *_msg = clone_to_empty_message(msg);
   1.502 -                    if (_msg == NULL) {
   1.503 -                        free(text);
   1.504 -                        goto enomem;
   1.505 -                    }
   1.506 -                    _msg->longmsg = text;
   1.507 -                    _msg->shortmsg = strdup(msg->shortmsg);
   1.508 -                    if (msg->shortmsg == NULL)
   1.509 -                        goto enomem;
   1.510 -
   1.511 -                    free_message(msg);
   1.512 -                    msg = _msg;
   1.513 -                }
   1.514 -                break;
   1.515 -        }
   1.516 -
   1.517          import_attached_keys(session, msg);
   1.518      }
   1.519  
   1.520 +theend:
   1.521      if (free_src)
   1.522          free_message(src);
   1.523