📄 pgp.c
字号:
return 0; /* fix the content type */ mutt_set_parameter ("format", "fixed", &b->parameter); if (enc) mutt_set_parameter ("x-action", "pgp-encrypted", &b->parameter); else if (sgn) mutt_set_parameter ("x-action", "pgp-signed", &b->parameter); else if (key) mutt_set_parameter ("x-action", "pgp-keys", &b->parameter); return 1;}int pgp_check_traditional (FILE *fp, BODY *b, int tagged_only){ int rv = 0; int r; for (; b; b = b->next) { if (is_multipart (b)) rv = pgp_check_traditional (fp, b->parts, tagged_only) || rv; else if (b->type == TYPETEXT) { if ((r = mutt_is_application_pgp (b))) rv = rv || r; else rv = pgp_check_traditional_one_body (fp, b, tagged_only) || rv; } } return rv;} int pgp_verify_one (BODY *sigbdy, STATE *s, const char *tempfile){ char sigfile[_POSIX_PATH_MAX], pgperrfile[_POSIX_PATH_MAX]; FILE *fp, *pgpout, *pgperr; pid_t thepid; int badsig = -1; int rv; snprintf (sigfile, sizeof (sigfile), "%s.asc", tempfile); if(!(fp = safe_fopen (sigfile, "w"))) { mutt_perror(sigfile); return -1; } fseeko (s->fpin, sigbdy->offset, 0); mutt_copy_bytes (s->fpin, fp, sigbdy->length); fclose (fp); mutt_mktemp(pgperrfile); if(!(pgperr = safe_fopen(pgperrfile, "w+"))) { mutt_perror(pgperrfile); unlink(sigfile); return -1; } crypt_current_time (s, "PGP"); if((thepid = pgp_invoke_verify (NULL, &pgpout, NULL, -1, -1, fileno(pgperr), tempfile, sigfile)) != -1) { if (pgp_copy_checksig (pgpout, s->fpout) >= 0) badsig = 0; safe_fclose (&pgpout); fflush (pgperr); rewind (pgperr); if (pgp_copy_checksig (pgperr, s->fpout) >= 0) badsig = 0; if ((rv = mutt_wait_filter (thepid))) badsig = -1; dprint (1, (debugfile, "pgp_verify_one: mutt_wait_filter returned %d.\n", rv)); } safe_fclose (&pgperr); state_attach_puts (_("[-- End of PGP output --]\n\n"), s); mutt_unlink (sigfile); mutt_unlink (pgperrfile); dprint (1, (debugfile, "pgp_verify_one: returning %d.\n", badsig)); return badsig;}/* Extract pgp public keys from messages or attachments */void pgp_extract_keys_from_messages (HEADER *h){ int i; char tempfname[_POSIX_PATH_MAX]; FILE *fpout; if (h) { mutt_parse_mime_message (Context, h); if(h->security & PGPENCRYPT && !pgp_valid_passphrase ()) return; } mutt_mktemp (tempfname); if (!(fpout = safe_fopen (tempfname, "w"))) { mutt_perror (tempfname); return; } set_option (OPTDONTHANDLEPGPKEYS); if (!h) { for (i = 0; i < Context->vcount; i++) { if (Context->hdrs[Context->v2r[i]]->tagged) { mutt_parse_mime_message (Context, Context->hdrs[Context->v2r[i]]); if (Context->hdrs[Context->v2r[i]]->security & PGPENCRYPT && !pgp_valid_passphrase()) { fclose (fpout); goto bailout; } mutt_copy_message (fpout, Context, Context->hdrs[Context->v2r[i]], M_CM_DECODE|M_CM_CHARCONV, 0); } } } else { mutt_parse_mime_message (Context, h); if (h->security & PGPENCRYPT && !pgp_valid_passphrase()) { fclose (fpout); goto bailout; } mutt_copy_message (fpout, Context, h, M_CM_DECODE|M_CM_CHARCONV, 0); } fclose (fpout); mutt_endwin (NULL); pgp_invoke_import (tempfname); mutt_any_key_to_continue (NULL); bailout: mutt_unlink (tempfname); unset_option (OPTDONTHANDLEPGPKEYS); }static void pgp_extract_keys_from_attachment (FILE *fp, BODY *top){ STATE s; FILE *tempfp; char tempfname[_POSIX_PATH_MAX]; mutt_mktemp (tempfname); if (!(tempfp = safe_fopen (tempfname, "w"))) { mutt_perror (tempfname); return; } memset (&s, 0, sizeof (STATE)); s.fpin = fp; s.fpout = tempfp; mutt_body_handler (top, &s); fclose (tempfp); pgp_invoke_import (tempfname); mutt_any_key_to_continue (NULL); mutt_unlink (tempfname);}void pgp_extract_keys_from_attachment_list (FILE *fp, int tag, BODY *top){ if(!fp) { mutt_error _("Internal error. Inform <roessler@does-not-exist.org>."); return; } mutt_endwin (NULL); set_option(OPTDONTHANDLEPGPKEYS); for(; top; top = top->next) { if(!tag || top->tagged) pgp_extract_keys_from_attachment (fp, top); if(!tag) break; } unset_option(OPTDONTHANDLEPGPKEYS);}BODY *pgp_decrypt_part (BODY *a, STATE *s, FILE *fpout, BODY *p){ char buf[LONG_STRING]; FILE *pgpin, *pgpout, *pgperr, *pgptmp; struct stat info; BODY *tattach; int len; char pgperrfile[_POSIX_PATH_MAX]; char pgptmpfile[_POSIX_PATH_MAX]; pid_t thepid; int rv; mutt_mktemp (pgperrfile); if ((pgperr = safe_fopen (pgperrfile, "w+")) == NULL) { mutt_perror (pgperrfile); return NULL; } unlink (pgperrfile); mutt_mktemp (pgptmpfile); if((pgptmp = safe_fopen (pgptmpfile, "w")) == NULL) { mutt_perror (pgptmpfile); fclose(pgperr); return NULL; } /* Position the stream at the beginning of the body, and send the data to * the temporary file. */ fseeko (s->fpin, a->offset, 0); mutt_copy_bytes (s->fpin, pgptmp, a->length); fclose (pgptmp); if ((thepid = pgp_invoke_decrypt (&pgpin, &pgpout, NULL, -1, -1, fileno (pgperr), pgptmpfile)) == -1) { fclose (pgperr); unlink (pgptmpfile); if (s->flags & M_DISPLAY) state_attach_puts (_("[-- Error: could not create a PGP subprocess! --]\n\n"), s); return (NULL); } /* send the PGP passphrase to the subprocess. Never do this if the agent is active, because this might lead to a passphrase send as the message. */ if (!pgp_use_gpg_agent()) fputs (PgpPass, pgpin); fputc ('\n', pgpin); fclose(pgpin); /* Read the output from PGP, and make sure to change CRLF to LF, otherwise * read_mime_header has a hard time parsing the message. */ while (fgets (buf, sizeof (buf) - 1, pgpout) != NULL) { len = mutt_strlen (buf); if (len > 1 && buf[len - 2] == '\r') strcpy (buf + len - 2, "\n"); /* __STRCPY_CHECKED__ */ fputs (buf, fpout); } fclose (pgpout); rv = mutt_wait_filter (thepid); mutt_unlink(pgptmpfile); if (s->flags & M_DISPLAY) { fflush (pgperr); rewind (pgperr); if (pgp_copy_checksig (pgperr, s->fpout) == 0 && !rv && p) p->goodsig = 1; else p->goodsig = 0; state_attach_puts (_("[-- End of PGP output --]\n\n"), s); } fclose (pgperr); fflush (fpout); rewind (fpout); if (fgetc (fpout) == EOF) { mutt_error _("Decryption failed"); pgp_void_passphrase (); return NULL; } rewind (fpout); if ((tattach = mutt_read_mime_header (fpout, 0)) != NULL) { /* * Need to set the length of this body part. */ fstat (fileno (fpout), &info); tattach->length = info.st_size - tattach->offset; /* See if we need to recurse on this MIME part. */ mutt_parse_part (fpout, tattach); } return (tattach);}int pgp_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur){ char tempfile[_POSIX_PATH_MAX]; STATE s; BODY *p = b; if(!mutt_is_multipart_encrypted(b)) return -1; if(!b->parts || !b->parts->next) return -1; b = b->parts->next; 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, p); rewind (*fpout); if (!*cur) return -1; return (0);}int pgp_encrypted_handler (BODY *a, STATE *s){ char tempfile[_POSIX_PATH_MAX]; FILE *fpout, *fpin; BODY *tattach; BODY *p = a; int rc = 0; a = a->parts; if (!a || a->type != TYPEAPPLICATION || !a->subtype || ascii_strcasecmp ("pgp-encrypted", a->subtype) != 0 || !a->next || a->next->type != TYPEAPPLICATION || !a->next->subtype || ascii_strcasecmp ("octet-stream", a->next->subtype) != 0) { if (s->flags & M_DISPLAY) state_attach_puts (_("[-- Error: malformed PGP/MIME message! --]\n\n"), s); return -1; } /* * Move forward to the application/pgp-encrypted body. */ a = a->next; mutt_mktemp (tempfile); if ((fpout = safe_fopen (tempfile, "w+")) == NULL) { if (s->flags & M_DISPLAY) state_attach_puts (_("[-- Error: could not create temporary file! --]\n"), s); return -1; } if (s->flags & M_DISPLAY) crypt_current_time (s, "PGP"); if ((tattach = pgp_decrypt_part (a, s, fpout, p)) != NULL) { if (s->flags & M_DISPLAY) state_attach_puts (_("[-- The following data is PGP/MIME encrypted --]\n\n"), s); fpin = s->fpin; s->fpin = fpout; rc = mutt_body_handler (tattach, s); s->fpin = fpin; /* * if a multipart/signed is the _only_ sub-part of a * multipart/encrypted, cache signature verification * status. * */ if (mutt_is_multipart_signed (tattach) && !tattach->next) p->goodsig |= tattach->goodsig; if (s->flags & M_DISPLAY) { state_puts ("\n", s); state_attach_puts (_("[-- End of PGP/MIME encrypted data --]\n"), s); } mutt_free_body (&tattach); /* clear 'Invoking...' message, since there's no error */ mutt_message _("PGP message successfully decrypted."); } else { mutt_error _("Could not decrypt PGP message"); /* void the passphrase, even if it's not necessarily the problem */ pgp_void_passphrase (); rc = -1; } fclose (fpout); mutt_unlink(tempfile); return rc;}/* ---------------------------------------------------------------------------- * Routines for sending PGP/MIME messages. */BODY *pgp_sign_message (BODY *a){ BODY *t; char buffer[LONG_STRING]; char sigfile[_POSIX_PATH_MAX], signedfile[_POSIX_PATH_MAX]; FILE *pgpin, *pgpout, *pgperr, *fp, *sfp; int err = 0; int empty = 1; pid_t thepid; convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */ mutt_mktemp (sigfile); if ((fp = safe_fopen (sigfile, "w")) == NULL) { return (NULL); } mutt_mktemp (signedfile); if ((sfp = safe_fopen(signedfile, "w")) == NULL) { mutt_perror(signedfile); fclose(fp); unlink(sigfile); return NULL; } mutt_write_mime_header (a, sfp); fputc ('\n', sfp); mutt_write_mime_body (a, sfp); fclose(sfp); if ((thepid = pgp_invoke_sign (&pgpin, &pgpout, &pgperr, -1, -1, -1, signedfile)) == -1) { mutt_perror _("Can't open PGP subprocess!"); fclose(fp); unlink(sigfile); unlink(signedfile); return NULL; } if (!pgp_use_gpg_agent()) fputs(PgpPass, pgpin); fputc('\n', pgpin); fclose(pgpin); /* * Read back the PGP signature. Also, change MESSAGE=>SIGNATURE as * recommended for future releases of PGP. */ while (fgets (buffer, sizeof (buffer) - 1, pgpout) != NULL) { if (mutt_strcmp ("-----BEGIN PGP MESSAGE-----\n", buffer) == 0) fputs ("-----BEGIN PGP SIGNATURE-----\n", fp); else if (mutt_strcmp("-----END PGP MESSAGE-----\n", buffer) == 0) fputs ("-----END PGP SIGNATURE-----\n", fp); else fputs (buffer, fp); empty = 0; /* got some output, so we're ok */ } /* check for errors from PGP */ err = 0; while (fgets (buffer, sizeof (buffer) - 1, pgperr) != NULL) { err = 1; fputs (buffer, stdout); } if(mutt_wait_filter (thepid) && option(OPTPGPCHECKEXIT)) empty=1; fclose (pgperr); fclose (pgpout); unlink (signedfile); if (fclose (fp) != 0) { mutt_perror ("fclose"); unlink (sigfile); return (NULL); } if (err) mutt_any_key_to_continue (NULL); if (empty) { unlink (sigfile); /* most likely error is a bad passphrase, so automatically forget it */ pgp_void_passphrase (); return (NULL); /* fatal error while signing */ } t = mutt_new_body (); t->type = TYPEMULTIPART; t->subtype = safe_strdup ("signed"); t->encoding = ENC7BIT; t->use_disp = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -