Пример #1
0
/**
 * test_last_status_new - Is the last message new
 * @param fp File to check
 * @retval true if the last message is new
 */
static bool test_last_status_new(FILE *fp)
{
  struct Email *e = NULL;
  struct Envelope *tmp_envelope = NULL;
  bool rc = false;

  if (fseek_last_message(fp) == -1)
    return false;

  e = mutt_email_new();
  tmp_envelope = mutt_rfc822_read_header(fp, e, false, false);
  if (!(e->read || e->old))
    rc = true;

  mutt_env_free(&tmp_envelope);
  mutt_email_free(&e);

  return rc;
}
Пример #2
0
/**
 * mutt_protect - Encrypt and/or sign a message
 * @param msg     Header of the message
 * @param keylist List of keys to encrypt to (space-separated)
 * @retval  0 Success
 * @retval -1 Error
 */
int mutt_protect(struct Email *msg, char *keylist)
{
  struct Body *pbody = NULL, *tmp_pbody = NULL;
  struct Body *tmp_smime_pbody = NULL;
  struct Body *tmp_pgp_pbody = NULL;
  int flags = (WithCrypto & APPLICATION_PGP) ? msg->security : 0;

  if (!WithCrypto)
    return -1;

  if (!(msg->security & (SEC_ENCRYPT | SEC_SIGN)))
    return 0;

  if ((msg->security & SEC_SIGN) && !crypt_valid_passphrase(msg->security))
    return -1;

  if (((WithCrypto & APPLICATION_PGP) != 0) && ((msg->security & PGP_INLINE) == PGP_INLINE))
  {
    if ((msg->content->type != TYPE_TEXT) ||
        (mutt_str_strcasecmp(msg->content->subtype, "plain") != 0))
    {
      if (query_quadoption(C_PgpMimeAuto,
                           _("Inline PGP can't be used with attachments.  "
                             "Revert to PGP/MIME?")) != MUTT_YES)
      {
        mutt_error(
            _("Mail not sent: inline PGP can't be used with attachments"));
        return -1;
      }
    }
    else if (mutt_str_strcasecmp("flowed", mutt_param_get(&msg->content->parameter, "format")) == 0)
    {
      if ((query_quadoption(C_PgpMimeAuto,
                            _("Inline PGP can't be used with format=flowed.  "
                              "Revert to PGP/MIME?"))) != MUTT_YES)
      {
        mutt_error(
            _("Mail not sent: inline PGP can't be used with format=flowed"));
        return -1;
      }
    }
    else
    {
      /* they really want to send it inline... go for it */
      if (!isendwin())
      {
        mutt_endwin();
        puts(_("Invoking PGP..."));
      }
      pbody = crypt_pgp_traditional_encryptsign(msg->content, flags, keylist);
      if (pbody)
      {
        msg->content = pbody;
        return 0;
      }

      /* otherwise inline won't work...ask for revert */
      if (query_quadoption(
              C_PgpMimeAuto,
              _("Message can't be sent inline.  Revert to using PGP/MIME?")) != MUTT_YES)
      {
        mutt_error(_("Mail not sent"));
        return -1;
      }
    }

    /* go ahead with PGP/MIME */
  }

  if (!isendwin())
    mutt_endwin();

  if (WithCrypto & APPLICATION_SMIME)
    tmp_smime_pbody = msg->content;
  if (WithCrypto & APPLICATION_PGP)
    tmp_pgp_pbody = msg->content;

  if (C_CryptUsePka && (msg->security & SEC_SIGN))
  {
    /* Set sender (necessary for e.g. PKA).  */
    const char *mailbox = NULL;
    struct Address *from = msg->env->from;

    if (!from)
      from = mutt_default_from();

    mailbox = from->mailbox;
    if (!mailbox && C_EnvelopeFromAddress)
      mailbox = C_EnvelopeFromAddress->mailbox;

    if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME))
      crypt_smime_set_sender(mailbox);
    else if (((WithCrypto & APPLICATION_PGP) != 0) && (msg->security & APPLICATION_PGP))
      crypt_pgp_set_sender(mailbox);

    if (!msg->env->from)
      mutt_addr_free(&from);
  }

  if (C_CryptProtectedHeadersWrite)
  {
    struct Envelope *protected_headers = mutt_env_new();
    mutt_str_replace(&protected_headers->subject, msg->env->subject);
    /* Note: if other headers get added, such as to, cc, then a call to
     * mutt_env_to_intl() will need to be added here too. */
    mutt_prepare_envelope(protected_headers, 0);

    mutt_env_free(&msg->content->mime_headers);
    msg->content->mime_headers = protected_headers;
  }

  if (msg->security & SEC_SIGN)
  {
    if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME))
    {
      tmp_pbody = crypt_smime_sign_message(msg->content);
      if (!tmp_pbody)
        goto bail;
      pbody = tmp_pbody;
      tmp_smime_pbody = tmp_pbody;
    }

    if (((WithCrypto & APPLICATION_PGP) != 0) && (msg->security & APPLICATION_PGP) &&
        (!(flags & SEC_ENCRYPT) || C_PgpRetainableSigs))
    {
      tmp_pbody = crypt_pgp_sign_message(msg->content);
      if (!tmp_pbody)
        goto bail;

      flags &= ~SEC_SIGN;
      pbody = tmp_pbody;
      tmp_pgp_pbody = tmp_pbody;
    }

    if ((WithCrypto != 0) && (msg->security & APPLICATION_SMIME) &&
        (msg->security & APPLICATION_PGP))
    {
      /* here comes the draft ;-) */
    }
  }

  if (msg->security & SEC_ENCRYPT)
  {
    if (((WithCrypto & APPLICATION_SMIME) != 0) && (msg->security & APPLICATION_SMIME))
    {
      tmp_pbody = crypt_smime_build_smime_entity(tmp_smime_pbody, keylist);
      if (!tmp_pbody)
      {
        /* signed ? free it! */
        goto bail;
      }
      /* free tmp_body if messages was signed AND encrypted ... */
      if ((tmp_smime_pbody != msg->content) && (tmp_smime_pbody != tmp_pbody))
      {
        /* detach and don't delete msg->content,
         * which tmp_smime_pbody->parts after signing. */
        tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
        msg->content->next = NULL;
        mutt_body_free(&tmp_smime_pbody);
      }
      pbody = tmp_pbody;
    }

    if (((WithCrypto & APPLICATION_PGP) != 0) && (msg->security & APPLICATION_PGP))
    {
      pbody = crypt_pgp_encrypt_message(tmp_pgp_pbody, keylist, (flags & SEC_SIGN));
      if (!pbody)
      {
        /* did we perform a retainable signature? */
        if (flags != msg->security)
        {
          /* remove the outer multipart layer */
          tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
          /* get rid of the signature */
          mutt_body_free(&tmp_pgp_pbody->next);
        }

        goto bail;
      }

      /* destroy temporary signature envelope when doing retainable
       * signatures.

       */
      if (flags != msg->security)
      {
        tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
        mutt_body_free(&tmp_pgp_pbody->next);
      }
    }
  }

  if (pbody)
  {
    msg->content = pbody;
    return 0;
  }

bail:
  mutt_env_free(&msg->content->mime_headers);
  return -1;
}