src/message_api.c
changeset 311 9156ad78df17
parent 304 c4976f5c95c2
child 319 dc8892e88eff
     1.1 --- a/src/message_api.c	Wed Jun 03 08:58:17 2015 +0200
     1.2 +++ b/src/message_api.c	Fri Jun 05 14:22:08 2015 +0200
     1.3 @@ -53,61 +53,6 @@
     1.4      return strcmp(bl->filename + (fn_len - fe_len), fe) == 0;
     1.5  }
     1.6  
     1.7 -void import_attached_keys(PEP_SESSION session, const message *msg)
     1.8 -{
     1.9 -    assert(session);
    1.10 -    assert(msg);
    1.11 -
    1.12 -    bloblist_t *bl;
    1.13 -    for (bl = msg->attachments; bl && bl->value; bl = bl->next) {
    1.14 -        assert(bl && bl->value && bl->size);
    1.15 -
    1.16 -        if (bl->mime_type == NULL ||
    1.17 -                    is_mime_type(bl, "application/octet-stream")) {
    1.18 -            if (is_fileending(bl, ".pgp") || is_fileending(bl, ".gpg") ||
    1.19 -                    is_fileending(bl, ".key") ||
    1.20 -                    string_equality(bl->filename, "key.asc"))
    1.21 -                import_key(session, bl->value, bl->size);
    1.22 -        }
    1.23 -        else if (is_mime_type(bl, "application/pgp-keys")) {
    1.24 -            import_key(session, bl->value, bl->size);
    1.25 -        }
    1.26 -        else if (is_mime_type(bl, "text/plain")) {
    1.27 -            if (is_fileending(bl, ".pgp") || is_fileending(bl, ".gpg") ||
    1.28 -                    is_fileending(bl, ".key") || is_fileending(bl, ".asc"))
    1.29 -                import_key(session, bl->value, bl->size);
    1.30 -        }
    1.31 -    }
    1.32 -}
    1.33 -
    1.34 -void attach_own_key(PEP_SESSION session, message *msg)
    1.35 -{
    1.36 -    char *keydata;
    1.37 -    size_t size;
    1.38 -    bloblist_t *bl;
    1.39 -
    1.40 -    assert(session);
    1.41 -    assert(msg);
    1.42 -
    1.43 -    if (msg->dir == PEP_dir_incoming)
    1.44 -        return;
    1.45 -
    1.46 -    assert(msg->from && msg->from->fpr);
    1.47 -    if (msg->from == NULL || msg->from->fpr == NULL)
    1.48 -        return;
    1.49 -
    1.50 -    PEP_STATUS status = export_key(session, msg->from->fpr, &keydata, &size);
    1.51 -    assert(status == PEP_STATUS_OK);
    1.52 -    if (status != PEP_STATUS_OK)
    1.53 -        return;
    1.54 -    assert(size);
    1.55 -
    1.56 -    bl = bloblist_add(msg->attachments, keydata, size, "application/pgp-keys",
    1.57 -            "pEp_key.asc");
    1.58 -    if (msg->attachments == NULL && bl)
    1.59 -        msg->attachments = bl;
    1.60 -}
    1.61 -
    1.62  static void add_opt_field(message *msg, const char *name, const char *value)
    1.63  {
    1.64      assert(msg);
    1.65 @@ -126,27 +71,6 @@
    1.66      }
    1.67  }
    1.68  
    1.69 -PEP_cryptotech determine_encryption_format(message *msg)
    1.70 -{
    1.71 -    assert(msg);
    1.72 -
    1.73 -    if (is_PGP_message_text(msg->longmsg)) {
    1.74 -        msg->enc_format = PEP_enc_pieces;
    1.75 -        return PEP_crypt_OpenPGP;
    1.76 -    }
    1.77 -    else if (msg->attachments && msg->attachments->next &&
    1.78 -            is_mime_type(msg->attachments, "application/pgp-encrypted") &&
    1.79 -            is_PGP_message_text(msg->attachments->next->value)
    1.80 -        ) {
    1.81 -        msg->enc_format = PEP_enc_PGP_MIME;
    1.82 -        return PEP_crypt_OpenPGP;
    1.83 -    }
    1.84 -    else {
    1.85 -        msg->enc_format = PEP_enc_none;
    1.86 -        return PEP_crypt_none;
    1.87 -    }
    1.88 -}
    1.89 -
    1.90  static char * combine_short_and_long(const char *shortmsg, const char *longmsg)
    1.91  {
    1.92      char * ptext;
    1.93 @@ -184,7 +108,7 @@
    1.94  
    1.95      if (strncasecmp(src, "subject: ", 9) == 0) {
    1.96          char *line_end = strchr(src, '\n');
    1.97 -        
    1.98 +
    1.99          if (line_end == NULL) {
   1.100              _shortmsg = strdup(src + 9);
   1.101              if (_shortmsg == NULL)
   1.102 @@ -220,7 +144,7 @@
   1.103          if (_longmsg == NULL)
   1.104              goto enomem;
   1.105      }
   1.106 -    
   1.107 +
   1.108      *shortmsg = _shortmsg;
   1.109      *longmsg = _longmsg;
   1.110  
   1.111 @@ -364,10 +288,10 @@
   1.112  }
   1.113  
   1.114  static PEP_STATUS encrypt_PGP_MIME(
   1.115 -        PEP_SESSION session,
   1.116 -        const message *src,
   1.117 -        stringlist_t *keys,
   1.118 -        message *dst
   1.119 +    PEP_SESSION session,
   1.120 +    const message *src,
   1.121 +    stringlist_t *keys,
   1.122 +    message *dst
   1.123      )
   1.124  {
   1.125      PEP_STATUS status = PEP_STATUS_OK;
   1.126 @@ -411,13 +335,13 @@
   1.127          goto pep_error;
   1.128  
   1.129      status = encrypt_and_sign(session, keys, mimetext, strlen(mimetext),
   1.130 -            &ctext, &csize);
   1.131 +        &ctext, &csize);
   1.132      free(mimetext);
   1.133      if (ctext == NULL)
   1.134          goto pep_error;
   1.135  
   1.136      dst->longmsg = strdup("this message was encrypted with p≡p "
   1.137 -            "http://pEp-project.org");
   1.138 +        "http://pEp-project.org");
   1.139      if (dst->longmsg == NULL)
   1.140          goto enomem;
   1.141  
   1.142 @@ -437,7 +361,7 @@
   1.143      memcpy(_ctext, ctext, csize);
   1.144  
   1.145      _a = bloblist_add(_a, _ctext, csize, "application/octet-stream",
   1.146 -            "msg.asc");
   1.147 +        "msg.asc");
   1.148      if (_a == NULL)
   1.149          goto enomem;
   1.150  
   1.151 @@ -454,10 +378,10 @@
   1.152  }
   1.153  
   1.154  static PEP_STATUS encrypt_PGP_in_pieces(
   1.155 -        PEP_SESSION session,
   1.156 -        const message *src,
   1.157 -        stringlist_t *keys,
   1.158 -        message *dst
   1.159 +    PEP_SESSION session,
   1.160 +    const message *src,
   1.161 +    stringlist_t *keys,
   1.162 +    message *dst
   1.163      )
   1.164  {
   1.165      PEP_STATUS status = PEP_STATUS_OK;
   1.166 @@ -475,7 +399,7 @@
   1.167              goto enomem;
   1.168  
   1.169          status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.170 -                &csize);
   1.171 +            &csize);
   1.172          free(ptext);
   1.173          if (ctext) {
   1.174              dst->longmsg = strndup(ctext, csize);
   1.175 @@ -490,7 +414,7 @@
   1.176      else if (src->longmsg) {
   1.177          char *ptext = src->longmsg;
   1.178          status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.179 -                &csize);
   1.180 +            &csize);
   1.181          if (ctext) {
   1.182              dst->longmsg = strndup(ctext, csize);
   1.183              assert(dst->longmsg);
   1.184 @@ -510,7 +434,7 @@
   1.185      if (src->longmsg_formatted) {
   1.186          char *ptext = src->longmsg_formatted;
   1.187          status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.188 -                &csize);
   1.189 +            &csize);
   1.190          if (ctext) {
   1.191              char *_ctext = malloc(csize);
   1.192              assert(_ctext);
   1.193 @@ -519,7 +443,7 @@
   1.194              memcpy(_ctext, ctext, csize);
   1.195  
   1.196              bloblist_t *_a = bloblist_add(dst->attachments, _ctext, csize,
   1.197 -                    "application/octet-stream", "PGPexch.htm.pgp");
   1.198 +                "application/octet-stream", "PGPexch.htm.pgp");
   1.199              if (_a == NULL)
   1.200                  goto enomem;
   1.201              if (dst->attachments == NULL)
   1.202 @@ -544,7 +468,7 @@
   1.203              int psize = _s->size;
   1.204              char *ptext = _s->value;
   1.205              status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
   1.206 -                    &csize);
   1.207 +                &csize);
   1.208              if (ctext) {
   1.209                  char *filename = NULL;
   1.210  
   1.211 @@ -574,7 +498,7 @@
   1.212                  memcpy(_ctext, ctext, csize);
   1.213  
   1.214                  _d = bloblist_add(_d, _ctext, csize, "application/octet-stream",
   1.215 -                        filename);
   1.216 +                    filename);
   1.217                  if (_d == NULL)
   1.218                      goto enomem;
   1.219              }
   1.220 @@ -593,6 +517,329 @@
   1.221      return status;
   1.222  }
   1.223  
   1.224 +static char * keylist_to_string(const stringlist_t *keylist)
   1.225 +{
   1.226 +    if (keylist) {
   1.227 +        size_t size = stringlist_length(keylist);
   1.228 +
   1.229 +        const stringlist_t *_kl;
   1.230 +        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.231 +            size += strlen(_kl->value);
   1.232 +        }
   1.233 +
   1.234 +        char *result = calloc(1, size);
   1.235 +        if (result == NULL)
   1.236 +            return NULL;
   1.237 +
   1.238 +        char *_r = result;
   1.239 +        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.240 +            _r = stpcpy(_r, _kl->value);
   1.241 +            if (_kl->next && _kl->next->value)
   1.242 +                _r = stpcpy(_r, ",");
   1.243 +        }
   1.244 +
   1.245 +        return result;
   1.246 +    }
   1.247 +    else {
   1.248 +        return NULL;
   1.249 +    }
   1.250 +}
   1.251 +
   1.252 +static const char * color_to_string(PEP_color color)
   1.253 +{
   1.254 +    switch (color) {
   1.255 +    case PEP_rating_cannot_decrypt:
   1.256 +        return "cannot_decrypt";
   1.257 +    case PEP_rating_have_no_key:
   1.258 +        return "have_no_key";
   1.259 +    case PEP_rating_unencrypted:
   1.260 +        return "unencrypted";
   1.261 +    case PEP_rating_unreliable:
   1.262 +        return "unreliable";
   1.263 +    case PEP_rating_reliable:
   1.264 +        return "reliable";
   1.265 +    case PEP_rating_trusted:
   1.266 +        return "trusted";
   1.267 +    case PEP_rating_trusted_and_anonymized:
   1.268 +        return "trusted_and_anonymized";
   1.269 +    case PEP_rating_fully_anonymous:
   1.270 +        return "fully_anonymous";
   1.271 +    case PEP_rating_under_attack:
   1.272 +        return "unter_attack";
   1.273 +    case PEP_rating_b0rken:
   1.274 +        return "b0rken";
   1.275 +    default:
   1.276 +        return "undefined";
   1.277 +    }
   1.278 +}
   1.279 +
   1.280 +static void decorate_message(
   1.281 +    message *msg,
   1.282 +    PEP_color color,
   1.283 +    stringlist_t *keylist
   1.284 +    )
   1.285 +{
   1.286 +    assert(msg);
   1.287 +
   1.288 +    add_opt_field(msg, "X-pEp-Version", "1.0");
   1.289 +    
   1.290 +    if (color != PEP_rating_undefined)
   1.291 +        add_opt_field(msg, "X-EncStatus", color_to_string(color));
   1.292 +
   1.293 +    if (keylist) {
   1.294 +        char *_keylist = keylist_to_string(keylist);
   1.295 +        add_opt_field(msg, "X-KeyList", _keylist);
   1.296 +        free(_keylist);
   1.297 +    }
   1.298 +}
   1.299 +
   1.300 +static PEP_color _rating(PEP_comm_type ct)
   1.301 +{
   1.302 +    if (ct == PEP_ct_unknown)
   1.303 +        return PEP_rating_undefined;
   1.304 +
   1.305 +    else if (ct == PEP_ct_compromized)
   1.306 +        return PEP_rating_under_attack;
   1.307 +
   1.308 +    else if (ct >= PEP_ct_confirmed_enc_anon)
   1.309 +        return PEP_rating_trusted_and_anonymized;
   1.310 +
   1.311 +    else if (ct >= PEP_ct_strong_encryption)
   1.312 +        return PEP_rating_trusted;
   1.313 +
   1.314 +    else if (ct >= PEP_ct_strong_but_unconfirmed && ct < PEP_ct_confirmed)
   1.315 +        return PEP_rating_reliable;
   1.316 +
   1.317 +    else if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel)
   1.318 +        return PEP_rating_unencrypted;
   1.319 +
   1.320 +    else
   1.321 +        return PEP_rating_unreliable;
   1.322 +}
   1.323 +
   1.324 +static bool is_encrypted_attachment(const bloblist_t *blob)
   1.325 +{
   1.326 +    char *ext;
   1.327 +
   1.328 +    assert(blob);
   1.329 +
   1.330 +    if (blob->filename == NULL)
   1.331 +        return false;
   1.332 +
   1.333 +    ext = strrchr(blob->filename, '.');
   1.334 +    if (ext == NULL)
   1.335 +        return false;
   1.336 +
   1.337 +    if (strcmp(blob->mime_type, "application/octet-stream")) {
   1.338 +        if (strcmp(ext, ".pgp") == 0 || strcmp(ext, ".gpg") == 0 ||
   1.339 +            strcmp(ext, ".asc") == 0)
   1.340 +            return true;
   1.341 +    }
   1.342 +    else if (strcmp(blob->mime_type, "text/plain")) {
   1.343 +        if (strcmp(ext, ".asc") == 0)
   1.344 +            return true;
   1.345 +    }
   1.346 +
   1.347 +    return false;
   1.348 +}
   1.349 +
   1.350 +static bool is_encrypted_html_attachment(const bloblist_t *blob)
   1.351 +{
   1.352 +    assert(blob);
   1.353 +    assert(blob->filename);
   1.354 +
   1.355 +    if (strncmp(blob->filename, "PGPexch.htm.", 12) == 0) {
   1.356 +        if (strcmp(blob->filename + 11, ".pgp") == 0 ||
   1.357 +            strcmp(blob->filename + 11, ".asc") == 0)
   1.358 +            return true;
   1.359 +    }
   1.360 +
   1.361 +    return false;
   1.362 +}
   1.363 +
   1.364 +static char * without_double_ending(const char *filename)
   1.365 +{
   1.366 +    char *ext;
   1.367 +
   1.368 +    assert(filename);
   1.369 +
   1.370 +    ext = strrchr(filename, '.');
   1.371 +    if (ext == NULL)
   1.372 +        return NULL;
   1.373 +
   1.374 +    return strndup(filename, ext - filename);
   1.375 +}
   1.376 +
   1.377 +static PEP_color decrypt_color(PEP_STATUS status)
   1.378 +{
   1.379 +    switch (status) {
   1.380 +    case PEP_UNENCRYPTED:
   1.381 +    case PEP_VERIFIED:
   1.382 +    case PEP_VERIFY_NO_KEY:
   1.383 +    case PEP_VERIFIED_AND_TRUSTED:
   1.384 +        return PEP_rating_unencrypted;
   1.385 +
   1.386 +    case PEP_DECRYPTED:
   1.387 +        return PEP_rating_unreliable;
   1.388 +
   1.389 +    case PEP_DECRYPTED_AND_VERIFIED:
   1.390 +        return PEP_rating_reliable;
   1.391 +
   1.392 +    case PEP_DECRYPT_NO_KEY:
   1.393 +        return PEP_rating_have_no_key;
   1.394 +
   1.395 +    case PEP_DECRYPT_WRONG_FORMAT:
   1.396 +    case PEP_CANNOT_DECRYPT_UNKNOWN:
   1.397 +        return PEP_rating_cannot_decrypt;
   1.398 +
   1.399 +    default:
   1.400 +        return PEP_rating_undefined;
   1.401 +    }
   1.402 +}
   1.403 +
   1.404 +static PEP_color key_color(PEP_SESSION session, const char *fpr)
   1.405 +{
   1.406 +    PEP_comm_type comm_type = PEP_ct_unknown;
   1.407 +
   1.408 +    assert(session);
   1.409 +    assert(fpr);
   1.410 +
   1.411 +    PEP_STATUS status = get_key_rating(session, fpr, &comm_type);
   1.412 +    if (status != PEP_STATUS_OK)
   1.413 +        return PEP_rating_undefined;
   1.414 +
   1.415 +    return _rating(comm_type);
   1.416 +}
   1.417 +
   1.418 +static PEP_color keylist_color(PEP_SESSION session, stringlist_t *keylist)
   1.419 +{
   1.420 +    PEP_color color = PEP_rating_reliable;
   1.421 +
   1.422 +    assert(keylist && keylist->value);
   1.423 +    if (keylist == NULL || keylist->value == NULL)
   1.424 +        return PEP_rating_unencrypted;
   1.425 +
   1.426 +    stringlist_t *_kl;
   1.427 +    for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.428 +        PEP_comm_type ct;
   1.429 +        PEP_STATUS status;
   1.430 +
   1.431 +        color = key_color(session, _kl->value);
   1.432 +        if (color == PEP_rating_under_attack)
   1.433 +            return PEP_rating_under_attack;
   1.434 +
   1.435 +        if (color >= PEP_rating_reliable) {
   1.436 +            status = least_trust(session, _kl->value, &ct);
   1.437 +            if (status != PEP_STATUS_OK)
   1.438 +                return PEP_rating_undefined;
   1.439 +            if (ct == PEP_ct_unknown)
   1.440 +                color = PEP_rating_unreliable;
   1.441 +            else
   1.442 +                color = _rating(ct);
   1.443 +        }
   1.444 +    }
   1.445 +
   1.446 +    return color;
   1.447 +}
   1.448 +
   1.449 +static PEP_comm_type _get_comm_type(
   1.450 +    PEP_SESSION session,
   1.451 +    PEP_comm_type max_comm_type,
   1.452 +    pEp_identity *ident
   1.453 +    )
   1.454 +{
   1.455 +    PEP_STATUS status = update_identity(session, ident);
   1.456 +
   1.457 +    if (max_comm_type == PEP_ct_compromized)
   1.458 +        return PEP_ct_compromized;
   1.459 +
   1.460 +    if (status == PEP_STATUS_OK) {
   1.461 +        if (ident->comm_type == PEP_ct_compromized)
   1.462 +            return PEP_ct_compromized;
   1.463 +        else
   1.464 +            return MIN(max_comm_type, ident->comm_type);
   1.465 +    }
   1.466 +    else {
   1.467 +        return PEP_ct_unknown;
   1.468 +    }
   1.469 +}
   1.470 +
   1.471 +void import_attached_keys(PEP_SESSION session, const message *msg)
   1.472 +{
   1.473 +    assert(session);
   1.474 +    assert(msg);
   1.475 +
   1.476 +    bloblist_t *bl;
   1.477 +    for (bl = msg->attachments; bl && bl->value; bl = bl->next) {
   1.478 +        assert(bl && bl->value && bl->size);
   1.479 +
   1.480 +        if (bl->mime_type == NULL ||
   1.481 +                    is_mime_type(bl, "application/octet-stream")) {
   1.482 +            if (is_fileending(bl, ".pgp") || is_fileending(bl, ".gpg") ||
   1.483 +                    is_fileending(bl, ".key") ||
   1.484 +                    string_equality(bl->filename, "key.asc"))
   1.485 +                import_key(session, bl->value, bl->size);
   1.486 +        }
   1.487 +        else if (is_mime_type(bl, "application/pgp-keys")) {
   1.488 +            import_key(session, bl->value, bl->size);
   1.489 +        }
   1.490 +        else if (is_mime_type(bl, "text/plain")) {
   1.491 +            if (is_fileending(bl, ".pgp") || is_fileending(bl, ".gpg") ||
   1.492 +                    is_fileending(bl, ".key") || is_fileending(bl, ".asc"))
   1.493 +                import_key(session, bl->value, bl->size);
   1.494 +        }
   1.495 +    }
   1.496 +}
   1.497 +
   1.498 +void attach_own_key(PEP_SESSION session, message *msg)
   1.499 +{
   1.500 +    char *keydata;
   1.501 +    size_t size;
   1.502 +    bloblist_t *bl;
   1.503 +
   1.504 +    assert(session);
   1.505 +    assert(msg);
   1.506 +
   1.507 +    if (msg->dir == PEP_dir_incoming)
   1.508 +        return;
   1.509 +
   1.510 +    assert(msg->from && msg->from->fpr);
   1.511 +    if (msg->from == NULL || msg->from->fpr == NULL)
   1.512 +        return;
   1.513 +
   1.514 +    PEP_STATUS status = export_key(session, msg->from->fpr, &keydata, &size);
   1.515 +    assert(status == PEP_STATUS_OK);
   1.516 +    if (status != PEP_STATUS_OK)
   1.517 +        return;
   1.518 +    assert(size);
   1.519 +
   1.520 +    bl = bloblist_add(msg->attachments, keydata, size, "application/pgp-keys",
   1.521 +            "pEp_key.asc");
   1.522 +    if (msg->attachments == NULL && bl)
   1.523 +        msg->attachments = bl;
   1.524 +}
   1.525 +
   1.526 +PEP_cryptotech determine_encryption_format(message *msg)
   1.527 +{
   1.528 +    assert(msg);
   1.529 +
   1.530 +    if (is_PGP_message_text(msg->longmsg)) {
   1.531 +        msg->enc_format = PEP_enc_pieces;
   1.532 +        return PEP_crypt_OpenPGP;
   1.533 +    }
   1.534 +    else if (msg->attachments && msg->attachments->next &&
   1.535 +            is_mime_type(msg->attachments, "application/pgp-encrypted") &&
   1.536 +            is_PGP_message_text(msg->attachments->next->value)
   1.537 +        ) {
   1.538 +        msg->enc_format = PEP_enc_PGP_MIME;
   1.539 +        return PEP_crypt_OpenPGP;
   1.540 +    }
   1.541 +    else {
   1.542 +        msg->enc_format = PEP_enc_none;
   1.543 +        return PEP_crypt_none;
   1.544 +    }
   1.545 +}
   1.546 +
   1.547  DYNAMIC_API PEP_STATUS encrypt_message(
   1.548          PEP_SESSION session,
   1.549          message *src,
   1.550 @@ -715,6 +962,9 @@
   1.551      if (msg && msg->shortmsg == NULL)
   1.552          msg->shortmsg = strdup("pEp");
   1.553  
   1.554 +    if (msg)
   1.555 +        decorate_message(msg, PEP_rating_undefined, NULL);
   1.556 +
   1.557      *dst = msg;
   1.558      return status;
   1.559  
   1.560 @@ -728,226 +978,6 @@
   1.561      return status;
   1.562  }
   1.563  
   1.564 -static bool is_encrypted_attachment(const bloblist_t *blob)
   1.565 -{
   1.566 -    char *ext;
   1.567 - 
   1.568 -    assert(blob);
   1.569 -
   1.570 -    if (blob->filename == NULL)
   1.571 -        return false;
   1.572 -
   1.573 -    ext = strrchr(blob->filename, '.');
   1.574 -    if (ext == NULL)
   1.575 -        return false;
   1.576 -
   1.577 -    if (strcmp(blob->mime_type, "application/octet-stream")) {
   1.578 -        if (strcmp(ext, ".pgp") == 0 || strcmp(ext, ".gpg") == 0 ||
   1.579 -                strcmp(ext, ".asc") == 0)
   1.580 -            return true;
   1.581 -    }
   1.582 -    else if (strcmp(blob->mime_type, "text/plain")) {
   1.583 -        if (strcmp(ext, ".asc") == 0)
   1.584 -            return true;
   1.585 -    }
   1.586 -
   1.587 -    return false;
   1.588 -}
   1.589 -
   1.590 -static bool is_encrypted_html_attachment(const bloblist_t *blob)
   1.591 -{
   1.592 -    assert(blob);
   1.593 -    assert(blob->filename);
   1.594 -
   1.595 -    if (strncmp(blob->filename, "PGPexch.htm.", 12) == 0) {
   1.596 -        if (strcmp(blob->filename + 11, ".pgp") == 0 ||
   1.597 -                strcmp(blob->filename + 11, ".asc") == 0)
   1.598 -            return true;
   1.599 -    }
   1.600 -
   1.601 -    return false;
   1.602 -}
   1.603 -
   1.604 -static char * without_double_ending(const char *filename)
   1.605 -{
   1.606 -    char *ext;
   1.607 -
   1.608 -    assert(filename);
   1.609 -
   1.610 -    ext = strrchr(filename, '.');
   1.611 -    if (ext == NULL)
   1.612 -        return NULL;
   1.613 -
   1.614 -    return strndup(filename, ext - filename);
   1.615 -}
   1.616 -
   1.617 -static PEP_color decrypt_color(PEP_STATUS status)
   1.618 -{
   1.619 -    switch (status) {
   1.620 -        case PEP_UNENCRYPTED:
   1.621 -        case PEP_VERIFIED:
   1.622 -        case PEP_VERIFY_NO_KEY:
   1.623 -        case PEP_VERIFIED_AND_TRUSTED:
   1.624 -            return PEP_rating_unencrypted;
   1.625 -
   1.626 -        case PEP_DECRYPTED:
   1.627 -            return PEP_rating_unreliable;
   1.628 -
   1.629 -        case PEP_DECRYPTED_AND_VERIFIED:
   1.630 -            return PEP_rating_reliable;
   1.631 -
   1.632 -        case PEP_DECRYPT_NO_KEY:
   1.633 -            return PEP_rating_have_no_key;
   1.634 -
   1.635 -        case PEP_DECRYPT_WRONG_FORMAT:
   1.636 -        case PEP_CANNOT_DECRYPT_UNKNOWN:
   1.637 -            return PEP_rating_cannot_decrypt;
   1.638 -
   1.639 -        default:
   1.640 -            return PEP_rating_undefined;
   1.641 -    }
   1.642 -}
   1.643 -
   1.644 -static PEP_color _rating(PEP_comm_type ct)
   1.645 -{
   1.646 -    if (ct == PEP_ct_unknown)
   1.647 -        return PEP_rating_undefined;
   1.648 -
   1.649 -    else if (ct == PEP_ct_compromized)
   1.650 -        return PEP_rating_under_attack;
   1.651 -
   1.652 -    else if (ct >= PEP_ct_confirmed_enc_anon)
   1.653 -        return PEP_rating_trusted_and_anonymized;
   1.654 -
   1.655 -    else if (ct >= PEP_ct_strong_encryption)
   1.656 -        return PEP_rating_trusted;
   1.657 -
   1.658 -    else if (ct >= PEP_ct_strong_but_unconfirmed && ct < PEP_ct_confirmed)
   1.659 -        return PEP_rating_reliable;
   1.660 -    
   1.661 -    else if (ct == PEP_ct_no_encryption || ct == PEP_ct_no_encrypted_channel)
   1.662 -        return PEP_rating_unencrypted;
   1.663 -
   1.664 -    else
   1.665 -        return PEP_rating_unreliable;
   1.666 -}
   1.667 -
   1.668 -static PEP_color key_color(PEP_SESSION session, const char *fpr) {
   1.669 -    PEP_comm_type comm_type = PEP_ct_unknown;
   1.670 -
   1.671 -    assert(session);
   1.672 -    assert(fpr);
   1.673 -
   1.674 -    PEP_STATUS status = get_key_rating(session, fpr, &comm_type);
   1.675 -    if (status != PEP_STATUS_OK)
   1.676 -        return PEP_rating_undefined;
   1.677 -
   1.678 -    return _rating(comm_type);
   1.679 -}
   1.680 -
   1.681 -static PEP_color keylist_color(PEP_SESSION session, stringlist_t *keylist)
   1.682 -{
   1.683 -    PEP_color color = PEP_rating_reliable;
   1.684 -
   1.685 -    assert(keylist && keylist->value);
   1.686 -    if (keylist == NULL || keylist->value == NULL)
   1.687 -        return PEP_rating_unencrypted;
   1.688 -
   1.689 -    stringlist_t *_kl;
   1.690 -    for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.691 -        PEP_comm_type ct;
   1.692 -        PEP_STATUS status;
   1.693 -
   1.694 -        color = key_color(session, _kl->value);
   1.695 -        if (color == PEP_rating_under_attack)
   1.696 -            return PEP_rating_under_attack;
   1.697 -
   1.698 -        if (color >= PEP_rating_reliable) {
   1.699 -            status = least_trust(session, _kl->value, &ct);
   1.700 -            if (status != PEP_STATUS_OK)
   1.701 -                return PEP_rating_undefined;
   1.702 -            if (ct == PEP_ct_unknown)
   1.703 -                color = PEP_rating_unreliable;
   1.704 -            else
   1.705 -                color = _rating(ct);
   1.706 -        }
   1.707 -    }
   1.708 -
   1.709 -    return color;
   1.710 -}
   1.711 -
   1.712 -static char * keylist_to_string(const stringlist_t *keylist)
   1.713 -{
   1.714 -    if (keylist) {
   1.715 -        size_t size = stringlist_length(keylist);
   1.716 -
   1.717 -        const stringlist_t *_kl;
   1.718 -        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.719 -            size += strlen(_kl->value);
   1.720 -        }
   1.721 -
   1.722 -        char *result = calloc(1, size);
   1.723 -        if (result == NULL)
   1.724 -            return NULL;
   1.725 -
   1.726 -        char *_r = result;
   1.727 -        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.728 -            _r = stpcpy(_r, _kl->value);
   1.729 -            if (_kl->next && _kl->next->value)
   1.730 -                _r = stpcpy(_r, ",");
   1.731 -        }
   1.732 -
   1.733 -        return result;
   1.734 -    }
   1.735 -    else {
   1.736 -        return NULL;
   1.737 -    }
   1.738 -}
   1.739 -
   1.740 -static const char * color_to_string(PEP_color color)
   1.741 -{
   1.742 -    switch (color) {
   1.743 -        case PEP_rating_cannot_decrypt:
   1.744 -            return "cannot_decrypt";
   1.745 -        case PEP_rating_have_no_key:
   1.746 -            return "have_no_key";
   1.747 -        case PEP_rating_unencrypted:
   1.748 -            return "unencrypted";
   1.749 -        case PEP_rating_unreliable:
   1.750 -            return "unreliable";
   1.751 -        case PEP_rating_reliable:
   1.752 -            return "reliable";
   1.753 -        case PEP_rating_trusted:
   1.754 -            return "trusted";
   1.755 -        case PEP_rating_trusted_and_anonymized:
   1.756 -            return "trusted_and_anonymized";
   1.757 -        case PEP_rating_fully_anonymous:
   1.758 -            return "fully_anonymous";
   1.759 -        case PEP_rating_under_attack:
   1.760 -            return "unter_attack";
   1.761 -        case PEP_rating_b0rken:
   1.762 -            return "b0rken";
   1.763 -        default:
   1.764 -            return "undefined";
   1.765 -    }
   1.766 -}
   1.767 -
   1.768 -static void decorate_message(
   1.769 -        message *msg,
   1.770 -        stringlist_t *keylist,
   1.771 -        PEP_color color
   1.772 -    )
   1.773 -{
   1.774 -    assert(msg);
   1.775 -
   1.776 -    add_opt_field(msg, "X-pEp-Version", "1.0");
   1.777 -    add_opt_field(msg, "X-EncStatus", color_to_string(color));
   1.778 -
   1.779 -    char *_keylist = keylist_to_string(keylist);
   1.780 -    add_opt_field(msg, "X-KeyList", _keylist);
   1.781 -    free(_keylist);
   1.782 -}
   1.783 -
   1.784  DYNAMIC_API PEP_STATUS decrypt_message(
   1.785          PEP_SESSION session,
   1.786          message *src,
   1.787 @@ -1145,7 +1175,7 @@
   1.788      }
   1.789  
   1.790      if (msg)
   1.791 -        decorate_message(msg, _keylist, *color);
   1.792 +        decorate_message(msg, *color, _keylist);
   1.793  
   1.794      *dst = msg;
   1.795      *keylist = _keylist;
   1.796 @@ -1162,28 +1192,6 @@
   1.797      return status;
   1.798  }
   1.799  
   1.800 -static PEP_comm_type _get_comm_type(
   1.801 -        PEP_SESSION session,
   1.802 -        PEP_comm_type max_comm_type,
   1.803 -        pEp_identity *ident
   1.804 -    )
   1.805 -{
   1.806 -    PEP_STATUS status = update_identity(session, ident);
   1.807 -
   1.808 -    if (max_comm_type == PEP_ct_compromized)
   1.809 -        return PEP_ct_compromized;
   1.810 -
   1.811 -    if (status == PEP_STATUS_OK) {
   1.812 -        if (ident->comm_type == PEP_ct_compromized)
   1.813 -            return PEP_ct_compromized;
   1.814 -        else
   1.815 -            return MIN(max_comm_type, ident->comm_type);
   1.816 -    }
   1.817 -    else {
   1.818 -        return PEP_ct_unknown;
   1.819 -    }
   1.820 -}
   1.821 -
   1.822  DYNAMIC_API PEP_STATUS outgoing_message_color(
   1.823          PEP_SESSION session,
   1.824          message *msg,