diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 1998-09-07 11:47:26 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 1998-09-07 11:47:26 +0000 |
commit | 12004c0e7a91721f115d52f449adff93d030b2a4 (patch) | |
tree | 88315b3c2ed58cd491bffb4739f7242677a5be94 | |
parent | 5ee262734e576feaa5ceaad562e27c95fc2e4eee (diff) |
Introducing decrypt-save, decrypt-copy, and
$forw{ard,}-decrypt. Based on work by Emil Laurentiu.
-rw-r--r-- | OPS.PGP | 2 | ||||
-rw-r--r-- | commands.c | 99 | ||||
-rw-r--r-- | copy.c | 33 | ||||
-rw-r--r-- | copy.h | 3 | ||||
-rw-r--r-- | curs_main.c | 25 | ||||
-rw-r--r-- | functions.h | 61 | ||||
-rw-r--r-- | handler.c | 6 | ||||
-rw-r--r-- | init.h | 6 | ||||
-rw-r--r-- | mutt.h | 1 | ||||
-rw-r--r-- | pager.c | 24 | ||||
-rw-r--r-- | pgp.c | 33 | ||||
-rw-r--r-- | pgp.h | 3 | ||||
-rw-r--r-- | protos.h | 2 | ||||
-rw-r--r-- | recvattach.c | 27 | ||||
-rw-r--r-- | sendlib.c | 53 |
15 files changed, 222 insertions, 156 deletions
@@ -5,3 +5,5 @@ OP_FORGET_PASSPHRASE "wipe PGP passphrase from memory" OP_MAIL_KEY "mail a PGP public key" OP_VERIFY_KEY "verify a PGP public key" OP_VIEW_ID "view the key's user id" +OP_DECRYPT_SAVE "make decrypted copy and delete" +OP_DECRYPT_COPY "make decrypted copy" @@ -509,12 +509,52 @@ void mutt_display_address (ADDRESS *adr) mutt_message ("%s", buf); } +static void set_copy_flags(HEADER *hdr, int decode, int decrypt, int *cmflags, int *chflags) +{ + *cmflags = 0; + *chflags = decode ? CH_XMIT | CH_MIME : CH_UPDATE_LEN; + +#ifdef _PGPPATH + if(!decode && decrypt && (hdr->pgp & PGPENCRYPT)) + { + if(hdr->content->type == TYPEMULTIPART) + { + *chflags |= CH_NONEWLINE; + *cmflags = M_CM_DECODE_PGP; + } + else if((hdr->content->type == TYPEAPPLICATION) && mutt_is_pgp_subtype(hdr->content->subtype)) + decode = 1; + } +#endif + + if(decode) + { + *chflags |= CH_TXTPLAIN; + *cmflags |= M_CM_DECODE; + } + + +} + +static void _mutt_save_message (HEADER *h, CONTEXT *ctx, int delete, int decode, int decrypt) +{ + int cmflags, chflags; + + set_copy_flags(h, decode, decrypt, &cmflags, &chflags); + if (decode) + mutt_parse_mime_message (Context, h); + + if (mutt_append_message (ctx, Context, h, cmflags, chflags) == 0 && delete) + { + mutt_set_flag (Context, h, M_DELETE, 1); + mutt_set_flag (Context, h, M_TAG, 0); + } +} + /* returns 0 if the copy/save was successful, or -1 on error/abort */ -int mutt_save_message (HEADER *h, int delete, int decode, int *redraw) +int mutt_save_message (HEADER *h, int delete, int decode, int decrypt, int *redraw) { - int i, need_buffy_cleanup; - int cmflags = decode ? M_CM_DECODE : 0; - int chflags = decode ? CH_XMIT | CH_MIME : CH_UPDATE_LEN; + int i, need_buffy_cleanup, need_passphrase = 0; char prompt[SHORT_STRING], buf[_POSIX_PATH_MAX]; CONTEXT ctx; struct stat st; @@ -528,10 +568,14 @@ int mutt_save_message (HEADER *h, int delete, int decode, int *redraw) snprintf (prompt, sizeof (prompt), "%s%s to mailbox", decode ? (delete ? "Decode-save" : "Decode-copy") : - (delete ? "Save" : "Copy"), h ? "" : " tagged"); - + (decrypt ? (delete ? "Decrypt-save" : "Decrypt-copy"): + (delete ? "Save" : "Copy")), h ? "" : " tagged"); + if (h) + { + need_passphrase = h->pgp & PGPENCRYPT; mutt_default_save (buf, sizeof (buf), h); + } else { /* look for the first tagged message */ @@ -548,10 +592,15 @@ int mutt_save_message (HEADER *h, int delete, int decode, int *redraw) if (h) { mutt_default_save (buf, sizeof (buf), h); + need_passphrase |= h->pgp & PGPENCRYPT; h = NULL; } } + if((decrypt || decode) && need_passphrase && + !pgp_valid_passphrase()) + return -1; + mutt_pretty_mailbox (buf); if (mutt_enter_fname (prompt, buf, sizeof (buf), redraw, 0) == -1) return (-1); @@ -589,46 +638,14 @@ int mutt_save_message (HEADER *h, int delete, int decode, int *redraw) if (mx_open_mailbox (buf, M_APPEND, &ctx) != NULL) { if (h) - { - if (decode) - { - mutt_parse_mime_message (Context, h); -#ifdef _PGPPATH - if((h->pgp & PGPENCRYPT) && !pgp_valid_passphrase()) - { - mx_close_mailbox (&ctx); - return (-1); - } -#endif /* _PGPPATH */ - } - if (mutt_append_message (&ctx, Context, h, cmflags, chflags) == 0 && delete) - { - mutt_set_flag (Context, h, M_DELETE, 1); - mutt_set_flag (Context, h, M_TAG, 0); - } - } + _mutt_save_message(h, &ctx, delete, decode, decrypt); else { for (i = 0; i < Context->vcount; i++) { if (Context->hdrs[Context->v2r[i]]->tagged) - { - h = Context->hdrs[Context->v2r[i]]; - if (decode) - { - mutt_parse_mime_message (Context, h); -#ifdef _PGPPATH - if((h->pgp & PGPENCRYPT) && !pgp_valid_passphrase()) - continue; -#endif /* _PGPPATH */ - } - mutt_append_message (&ctx, Context, h, cmflags, chflags); - if (delete) - { - mutt_set_flag (Context, h, M_DELETE, 1); - mutt_set_flag (Context, h, M_TAG, 0); - } - } + _mutt_save_message(Context->hdrs[Context->v2r[i]], + &ctx, delete, decode, decrypt); } } @@ -22,6 +22,12 @@ #include "copy.h" #include "rfc2047.h" #include "parse.h" +#include "mime.h" + +#ifdef _PGPPATH +#include "pgp.h" +#endif + #include <string.h> #include <stdlib.h> #include <ctype.h> @@ -356,6 +362,7 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix) M_CM_DECODE decode message body to text/plain M_CM_DISPLAY displaying output to the user M_CM_UPDATE update structures in memory after syncing + M_CM_DECODE_PGP used for decoding PGP messages chflags flags to mutt_copy_header() */ @@ -399,17 +406,37 @@ _mutt_copy_message (FILE *fpout, FILE *fpin, HEADER *hdr, BODY *body, if (flags & M_CM_DISPLAY) s.flags |= M_DISPLAY; - - #ifdef _PGPPATH if (flags & M_CM_VERIFY) s.flags |= M_VERIFY; #endif + mutt_body_handler (body, &s); + } +#ifdef _PGPPATH + else if ((flags & M_CM_DECODE_PGP) && (hdr->pgp & PGPENCRYPT) && + hdr->content->type == TYPEMULTIPART) + { + BODY *cur; + FILE *fp; + if (pgp_decrypt_mime (fpin, &fp, hdr->content->parts->next, &cur)) + return (-1); + fputs ("Mime-Version: 1.0\n", fpout); + mutt_write_mime_header (cur, fpout); + fputc ('\n', fpout); - mutt_body_handler (body, &s); + fseek (fp, cur->offset, 0); + if (mutt_copy_bytes (fp, fpout, cur->length) == -1) + { + fclose (fp); + mutt_free_body (&cur); + return (-1); + } + mutt_free_body (&cur); + fclose (fp); } +#endif else { fseek (fpin, body->offset, 0); @@ -26,7 +26,8 @@ #ifdef _PGPPATH -#define M_CM_VERIFY (1<<4) /* do signature verification */ +#define M_CM_DECODE_PGP (1<<5) /* used for decoding PGP messages */ +#define M_CM_VERIFY (1<<6) /* do signature verification */ #endif diff --git a/curs_main.c b/curs_main.c index 0f69764b..2fcad670 100644 --- a/curs_main.c +++ b/curs_main.c @@ -1065,13 +1065,28 @@ int mutt_index_menu (int attach_msg /* invoked while attaching a message */) case OP_SAVE: case OP_DECODE_COPY: case OP_DECODE_SAVE: - +#ifdef _PGPPATH + case OP_DECRYPT_COPY: + case OP_DECRYPT_SAVE: +#endif CHECK_MSGCOUNT; - if (mutt_save_message (tag ? NULL : CURHDR, - (op == OP_SAVE || op == OP_DECODE_SAVE), - (op == OP_DECODE_SAVE || op == OP_DECODE_COPY), + if (mutt_save_message (tag ? NULL : CURHDR, +#ifdef _PGPPATH + (op == OP_DECRYPT_SAVE) || +#endif + (op == OP_SAVE) || (op == OP_DECODE_SAVE), + (op == OP_DECODE_SAVE) || (op == OP_DECODE_COPY), +#ifdef _PGPPATH + (op == OP_DECRYPT_SAVE) || (op == OP_DECRYPT_COPY), +#else + 0, +#endif &menu->redraw) == 0 && - (op == OP_SAVE || op == OP_DECODE_SAVE)) + (op == OP_SAVE || op == OP_DECODE_SAVE +#ifdef _PGPPATH + || op == OP_DECRYPT_SAVE +#endif + )) { if (tag) menu->redraw |= REDRAW_INDEX; diff --git a/functions.h b/functions.h index 01e5a431..5a23db62 100644 --- a/functions.h +++ b/functions.h @@ -133,6 +133,8 @@ struct binding_t OpMain[] = { { "extract-keys", OP_EXTRACT_KEYS, "\013" }, { "forget-passphrase", OP_FORGET_PASSPHRASE, "\006" }, { "mail-key", OP_MAIL_KEY, "\033k" }, + { "decrypt-copy", OP_DECRYPT_COPY, NULL }, + { "decrypt-save", OP_DECRYPT_SAVE, NULL }, #endif @@ -211,72 +213,17 @@ struct binding_t OpPager[] = { - - - - - - - #ifdef _PGPPATH { "extract-keys", OP_EXTRACT_KEYS, "\013" }, { "forget-passphrase",OP_FORGET_PASSPHRASE, "\006" }, { "mail-key", OP_MAIL_KEY, "\033k" }, + { "decrypt-copy", OP_DECRYPT_COPY, NULL }, + { "decrypt-save", OP_DECRYPT_SAVE, NULL }, #endif - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { NULL, 0, NULL } }; @@ -934,8 +934,7 @@ int mutt_can_decode (BODY *a) #ifdef _PGPPATH else if (a->type == TYPEAPPLICATION) { - if (strcasecmp (a->subtype, "pgp") == 0 || - strcasecmp (a->subtype, "x-pgp-message") == 0 || + if (mutt_is_pgp_subtype(a->subtype) || strcasecmp (a->subtype, "pgp-signed") == 0 || strcasecmp (a->subtype, "pgp-keys") == 0) return (1); @@ -1242,8 +1241,7 @@ void mutt_body_handler (BODY *b, STATE *s) #ifdef _PGPPATH else if (b->type == TYPEAPPLICATION) { - if (strcasecmp ("pgp", b->subtype) == 0 || - strcasecmp ("x-pgp-message", b->subtype) == 0 || + if (mutt_is_pgp_subtype(b->subtype) || strcasecmp ("pgp-signed", b->subtype) == 0 || strcasecmp ("pgp-keys", b->subtype) == 0) @@ -198,11 +198,11 @@ struct option_t MuttVars[] = { { "pgp_receive_version", DT_STR, R_NONE, UL &PgpReceiveVersion, UL "default" }, { "pgp_send_version", DT_STR, R_NONE, UL &PgpSendVersion, UL "default" }, { "pgp_key_version", DT_STR, R_NONE, UL &PgpKeyVersion, UL "default" }, - + + { "forward_decrypt", DT_BOOL, R_NONE, OPTFORWDECRYPT, 1 }, + { "forw_decrypt", DT_SYN, R_NONE, UL "forward_decrypt", 0 }, #endif /* _PGPPATH */ - - { "pipe_split", DT_BOOL, R_NONE, OPTPIPESPLIT, 0 }, { "pipe_decode", DT_BOOL, R_NONE, OPTPIPEDECODE, 0 }, { "pipe_sep", DT_STR, R_NONE, UL &PipeSep, UL "\n" }, @@ -308,6 +308,7 @@ enum OPTPGPREPLYSIGN, OPTPGPENCRYPTSELF, OPTPGPSTRICTENC, + OPTFORWDECRYPT, #endif /* pseudo options */ @@ -2053,6 +2053,9 @@ mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra, redraw = REDRAW_FULL; break; +#ifdef _PGPPATH + case OP_DECRYPT_SAVE: +#endif case OP_SAVE: if (IsAttach (extra)) { @@ -2063,11 +2066,26 @@ mutt_pager (const char *banner, const char *fname, int do_color, pager_t *extra, case OP_COPY_MESSAGE: case OP_DECODE_SAVE: case OP_DECODE_COPY: +#ifdef _PGPPATH + case OP_DECRYPT_COPY: +#endif CHECK_MODE(IsHeader (extra)); if (mutt_save_message (extra->hdr, - (ch == OP_SAVE || ch == OP_DECODE_SAVE), - (ch == OP_DECODE_SAVE || ch == OP_DECODE_COPY), - &redraw) == 0 && (ch == OP_SAVE || ch == OP_DECODE_SAVE)) +#ifdef _PGPPATH + (ch == OP_DECRYPT_SAVE) || +#endif + (ch == OP_SAVE) || (ch == OP_DECODE_SAVE), + (ch == OP_DECODE_SAVE) || (ch == OP_DECODE_COPY), +#ifdef _PGPPATH + (ch == OP_DECRYPT_SAVE) || (ch == OP_DECRYPT_COPY), +#else + 0, +#endif + &redraw) == 0 && (ch == OP_SAVE || ch == OP_DECODE_SAVE +#ifdef _PGPPATH + || ch == OP_DECRYPT_SAVE +#endif + )) { if (option (OPTRESOLVE)) { @@ -479,6 +479,18 @@ void application_pgp_handler (BODY *m, STATE *s) } +int mutt_is_pgp_subtype(const char *st) +{ + if(st) + { + if(!strcasecmp(st, "pgp")) return 1; + if(!strcasecmp(st, "x-pgp-message")) return 1; + } + + return 0; +} + + int pgp_query (BODY *m) { char *p; @@ -892,6 +904,27 @@ BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout) return (tattach); } +int pgp_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) +{ + char tempfile[_POSIX_PATH_MAX]; + STATE s; + + memset (&s, 0, sizeof (s)); + s.fpin = fpin; + mutt_mktemp (tempfile); + if ((*fpout = safe_fopen (tempfile, "w+")) == NULL) + { + mutt_perror (tempfile); + return (-1); + } + unlink (tempfile); + + *cur = pgp_decrypt_part (b, &s, *fpout); + + rewind (*fpout); + return (0); +} + void pgp_encrypted_handler (BODY *a, STATE *s) { char tempfile[_POSIX_PATH_MAX]; @@ -166,6 +166,9 @@ struct pgp_vinfo *pgp_get_vinfo(enum pgp_ops); int mutt_check_pgp (HEADER *h); int mutt_parse_pgp_hdr (char *, int); +int mutt_is_pgp_subtype(const char *); + +int pgp_decrypt_mime (FILE *, FILE **, BODY *, BODY **); int pgp_get_keys (HEADER *, char **); int pgp_protect (HEADER *, char *); int pgp_query (BODY *); @@ -252,7 +252,7 @@ int mutt_pipe_message (HEADER *); int mutt_print_attachment (FILE *, BODY *); int mutt_query_complete (char *, size_t); int mutt_save_attachment (FILE *, BODY *, char *, int, HEADER *); -int mutt_save_message (HEADER *, int, int, int *); +int mutt_save_message (HEADER *, int, int, int, int *); int mutt_search_command (int, int); int mutt_send_menu (HEADER *, char *, size_t, HEADER *); int mutt_strcmp (const char *, const char *); diff --git a/recvattach.c b/recvattach.c index 585fb56a..00a766d7 100644 --- a/recvattach.c +++ b/recvattach.c @@ -780,7 +780,6 @@ void mutt_view_attachments (HEADER *hdr) #ifdef _PGPPATH - char tempfile[_POSIX_PATH_MAX]; int pgp = 0; #endif @@ -806,7 +805,6 @@ void mutt_view_attachments (HEADER *hdr) #ifdef _PGPPATH - if((hdr->pgp & PGPENCRYPT) && !pgp_valid_passphrase()) { mx_close_message(&msg); @@ -815,37 +813,15 @@ void mutt_view_attachments (HEADER *hdr) if ((hdr->pgp & PGPENCRYPT) && hdr->content->type == TYPEMULTIPART) { - STATE s; - - memset (&s, 0, sizeof (s)); - s.fpin = msg->fp; - mutt_mktemp (tempfile); - if ((fp = safe_fopen (tempfile, "w+")) == NULL) + if (pgp_decrypt_mime (msg->fp, &fp, hdr->content->parts->next, &cur)) { - mutt_perror (tempfile); mx_close_message (&msg); return; } - cur = pgp_decrypt_part (hdr->content->parts->next, &s, fp); - rewind (fp); - pgp = 1; } else #endif /* _PGPPATH */ - - - - - - - - - - - - - { fp = msg->fp; cur = hdr->content; @@ -1046,7 +1022,6 @@ void mutt_view_attachments (HEADER *hdr) { fclose (fp); mutt_free_body (&cur); - unlink (tempfile); } #endif /* _PGPPATH */ @@ -918,6 +918,14 @@ BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg) char buffer[LONG_STRING]; BODY *body; FILE *fp; + int cmflags, chflags; + int pgp = hdr->pgp; + +#ifdef _PGPPATH + if ((option(OPTMIMEFORWDECODE) || option(OPTFORWDECRYPT)) && + (hdr->pgp & PGPENCRYPT) && !pgp_valid_passphrase()) + return (NULL); +#endif /* _PGPPATH */ mutt_mktemp (buffer); if ((fp = safe_fopen (buffer, "w+")) == NULL) @@ -930,19 +938,40 @@ BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg) body->unlink = 1; body->use_disp = 0; -#if 0 - /* this MUST come after setting ->filename because we reuse buffer[] */ - strfcpy (buffer, "Forwarded message from ", sizeof (buffer)); - rfc822_write_address (buffer + 23, sizeof (buffer) - 23, hdr->env->from); - body->description = safe_strdup (buffer); -#endif - mutt_parse_mime_message (ctx, hdr); + chflags = CH_XMIT; + cmflags = 0; + + if (!attach_msg && option (OPTMIMEFORWDECODE)) + { + chflags |= CH_MIME | CH_TXTPLAIN; + cmflags = M_CM_DECODE; + pgp &= ~PGPENCRYPT; + } + else +#ifdef _PGPPATH + if(option(OPTFORWDECRYPT) + && (hdr->pgp & PGPENCRYPT)) + { + if(hdr->content->type == TYPEMULTIPART) + { + chflags |= CH_MIME | CH_NONEWLINE; + cmflags = M_CM_DECODE_PGP; + pgp &= ~PGPENCRYPT; + } + else if((hdr->content->type == TYPEAPPLICATION) && + mutt_is_pgp_subtype(hdr->content->subtype)) + { + chflags |= CH_MIME | CH_TXTPLAIN; + cmflags = M_CM_DECODE; + pgp &= ~PGPENCRYPT; + } + } +#endif + /* If we are attaching a message, ignore OPTMIMEFORWDECODE */ - mutt_copy_message (fp, ctx, hdr, - (!attach_msg && option (OPTMIMEFORWDECODE)) ? M_CM_DECODE : 0, - CH_XMIT | ((!attach_msg && option (OPTMIMEFORWDECODE)) ? (CH_MIME | CH_TXTPLAIN ) : 0)); + mutt_copy_message (fp, ctx, hdr, cmflags, chflags); fflush(fp); rewind(fp); @@ -951,8 +980,8 @@ BODY *mutt_make_message_attach (CONTEXT *ctx, HEADER *hdr, int attach_msg) body->hdr->offset = 0; body->hdr->env = mutt_read_rfc822_header(fp, body->hdr); #ifdef _PGPPATH - body->hdr->pgp = hdr->pgp; -#endif + body->hdr->pgp = pgp; +#endif /* _PGPPATH */ mutt_update_encoding (body); body->parts = body->hdr->content; |