📄 smime.c
字号:
mutt_mktemp (certfile); if ((fpout = safe_fopen (certfile, "w+")) == NULL) { fclose (fperr); mutt_perror (certfile); return NULL; } /* Extract signer's certificate */ if ((thepid = smime_invoke (NULL, NULL, NULL, -1, -1, fileno (fperr), infile, NULL, NULL, NULL, certfile, NULL, SmimeGetSignerCertCommand))== -1) { mutt_any_key_to_continue (_("Error: unable to create OpenSSL subprocess!")); fclose (fperr); fclose (fpout); mutt_unlink (pk7out); mutt_unlink (certfile); return NULL; } mutt_wait_filter (thepid); fflush (fpout); rewind (fpout); rewind (fperr); fflush (fperr); empty = (fgetc (fpout) == EOF); if (empty) { mutt_endwin (NULL); mutt_copy_stream (fperr, stdout); mutt_any_key_to_continue (NULL); fclose (fpout); fclose (fperr); mutt_unlink (certfile); return NULL; } fclose (fpout); fclose (fperr); return safe_strdup (certfile);}/* Add a certificate and update index file (externally). */void smime_invoke_import (char *infile, char *mailbox){ char tmpfname[_POSIX_PATH_MAX], *certfile = NULL, buf[STRING]; FILE *smimein=NULL, *fpout = NULL, *fperr = NULL; pid_t thepid=-1; mutt_mktemp (tmpfname); if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return; } mutt_unlink (tmpfname); mutt_mktemp (tmpfname); if ((fpout = safe_fopen (tmpfname, "w+")) == NULL) { fclose (fperr); mutt_perror (tmpfname); return; } mutt_unlink (tmpfname); buf[0] = '\0'; if (option (OPTASKCERTLABEL)) mutt_get_field ("Label for certificate:", buf, sizeof (buf), 0); mutt_endwin (NULL); if ((certfile = smime_extract_certificate(infile))) { mutt_endwin (NULL); if ((thepid = smime_invoke (&smimein, NULL, NULL, -1, fileno(fpout), fileno(fperr), certfile, NULL, NULL, NULL, NULL, NULL, SmimeImportCertCommand))== -1) { mutt_message (_("Error: unable to create OpenSSL subprocess!")); return; } fputs (buf, smimein); fputc ('\n', smimein); fclose(smimein); mutt_wait_filter (thepid); mutt_unlink (certfile); FREE (&certfile); } fflush (fpout); rewind (fpout); fflush (fperr); rewind (fperr); mutt_copy_stream (fpout, stdout); mutt_copy_stream (fperr, stdout); fclose (fpout); fclose (fperr);}int smime_verify_sender(HEADER *h){ char *mbox = NULL, *certfile, tempfname[_POSIX_PATH_MAX]; FILE *fpout; int retval=1; mutt_mktemp (tempfname); if (!(fpout = safe_fopen (tempfname, "w"))) { mutt_perror (tempfname); return 1; } if(h->security & ENCRYPT) mutt_copy_message (fpout, Context, h, M_CM_DECODE_CRYPT & M_CM_DECODE_SMIME, CH_MIME|CH_WEED|CH_NONEWLINE); else mutt_copy_message (fpout, Context, h, 0, 0); fflush(fpout); fclose (fpout); if (h->env->from) { h->env->from = mutt_expand_aliases (h->env->from); mbox = h->env->from->mailbox; } else if (h->env->sender) { h->env->sender = mutt_expand_aliases (h->env->sender); mbox = h->env->sender->mailbox; } if (mbox) { if ((certfile = smime_extract_signer_certificate(tempfname))) { mutt_unlink(tempfname); if (smime_handle_cert_email (certfile, mbox, 0, NULL, NULL)) { if(isendwin()) mutt_any_key_to_continue(NULL); } else retval = 0; mutt_unlink(certfile); FREE (&certfile); } else mutt_any_key_to_continue(_("no certfile")); } else mutt_any_key_to_continue(_("no mbox")); mutt_unlink(tempfname); return retval;}/* * Creating S/MIME - bodies. */staticpid_t smime_invoke_encrypt (FILE **smimein, FILE **smimeout, FILE **smimeerr, int smimeinfd, int smimeoutfd, int smimeerrfd, const char *fname, const char *uids){ return smime_invoke (smimein, smimeout, smimeerr, smimeinfd, smimeoutfd, smimeerrfd, fname, NULL, SmimeCryptAlg, NULL, uids, NULL, SmimeEncryptCommand);}staticpid_t smime_invoke_sign (FILE **smimein, FILE **smimeout, FILE **smimeerr, int smimeinfd, int smimeoutfd, int smimeerrfd, const char *fname){ return smime_invoke (smimein, smimeout, smimeerr, smimeinfd, smimeoutfd, smimeerrfd, fname, NULL, NULL, SmimeKeyToUse, SmimeCertToUse, SmimeIntermediateToUse, SmimeSignCommand);}BODY *smime_build_smime_entity (BODY *a, char *certlist){ char buf[LONG_STRING], certfile[LONG_STRING]; char tempfile[_POSIX_PATH_MAX], smimeerrfile[_POSIX_PATH_MAX]; char smimeinfile[_POSIX_PATH_MAX]; char *cert_start = certlist, *cert_end = certlist; FILE *smimein = NULL, *smimeerr = NULL, *fpout = NULL, *fptmp = NULL; BODY *t; int err = 0, empty; pid_t thepid; mutt_mktemp (tempfile); if ((fpout = safe_fopen (tempfile, "w+")) == NULL) { mutt_perror (tempfile); return (NULL); } mutt_mktemp (smimeerrfile); if ((smimeerr = safe_fopen (smimeerrfile, "w+")) == NULL) { mutt_perror (smimeerrfile); fclose (fpout); mutt_unlink (tempfile); return NULL; } mutt_unlink (smimeerrfile); mutt_mktemp (smimeinfile); if ((fptmp = safe_fopen (smimeinfile, "w+")) == NULL) { mutt_perror (smimeinfile); mutt_unlink (tempfile); fclose (fpout); fclose (smimeerr); return NULL; } *certfile = '\0'; while (1) { int off = mutt_strlen (certfile); while (*++cert_end && *cert_end != '\n'); if (!*cert_end) break; *cert_end = '\0'; snprintf (certfile+off, sizeof (certfile)-off, " %s/%s", NONULL(SmimeCertificates), cert_start); *cert_end = '\n'; cert_start = cert_end; cert_start++; } /* write a MIME entity */ mutt_write_mime_header (a, fptmp); fputc ('\n', fptmp); mutt_write_mime_body (a, fptmp); fclose (fptmp); if ((thepid = smime_invoke_encrypt (&smimein, NULL, NULL, -1, fileno (fpout), fileno (smimeerr), smimeinfile, certfile)) == -1) { fclose (smimeerr); mutt_unlink (smimeinfile); mutt_unlink (certfile); return (NULL); } fclose (smimein); mutt_wait_filter (thepid); mutt_unlink (smimeinfile); mutt_unlink (certfile); fflush (fpout); rewind (fpout); empty = (fgetc (fpout) == EOF); fclose (fpout); fflush (smimeerr); rewind (smimeerr); while (fgets (buf, sizeof (buf) - 1, smimeerr) != NULL) { err = 1; fputs (buf, stdout); } fclose (smimeerr); /* pause if there is any error output from SMIME */ if (err) mutt_any_key_to_continue (NULL); if (empty) { /* fatal error while trying to encrypt message */ if (!err) mutt_any_key_to_continue _("No output from OpenSSL.."); mutt_unlink (tempfile); return (NULL); } t = mutt_new_body (); t->type = TYPEAPPLICATION; t->subtype = safe_strdup ("x-pkcs7-mime"); mutt_set_parameter ("name", "smime.p7m", &t->parameter); mutt_set_parameter ("smime-type", "enveloped-data", &t->parameter); t->encoding = ENCBASE64; /* The output of OpenSSL SHOULD be binary */ t->use_disp = 1; t->disposition = DISPATTACH; t->d_filename = safe_strdup ("smime.p7m"); t->filename = safe_strdup (tempfile); t->unlink = 1; /*delete after sending the message */ t->parts=0; t->next=0; return (t);}BODY *smime_sign_message (BODY *a ){ BODY *t; char buffer[LONG_STRING]; char signedfile[_POSIX_PATH_MAX], filetosign[_POSIX_PATH_MAX]; FILE *smimein = NULL, *smimeout = NULL, *smimeerr = NULL, *sfp = NULL; int err = 0; int empty = 0; pid_t thepid; char *intermediates = smime_get_field_from_db(NULL, SmimeDefaultKey, 1, 1); if (!intermediates) { mutt_message(_("Warning: Intermediate certificate not found.")); intermediates = SmimeDefaultKey; /* so openssl won't complain in any case */ } convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */ mutt_mktemp (filetosign); if ((sfp = safe_fopen (filetosign, "w+")) == NULL) { mutt_perror (filetosign); return NULL; } mutt_mktemp (signedfile); if ((smimeout = safe_fopen (signedfile, "w+")) == NULL) { mutt_perror (signedfile); fclose (sfp); mutt_unlink (filetosign); return NULL; } mutt_write_mime_header (a, sfp); fputc ('\n', sfp); mutt_write_mime_body (a, sfp); fclose (sfp); snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", NONULL(SmimeKeys), SmimeDefaultKey); snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", NONULL(SmimeCertificates), SmimeDefaultKey); snprintf (SmimeIntermediateToUse, sizeof (SmimeIntermediateToUse), "%s/%s", NONULL(SmimeCertificates), intermediates); if ((thepid = smime_invoke_sign (&smimein, NULL, &smimeerr, -1, fileno (smimeout), -1, filetosign)) == -1) { mutt_perror _("Can't open OpenSSL subprocess!"); fclose (smimeout); mutt_unlink (signedfile); mutt_unlink (filetosign); return NULL; } fputs (SmimePass, smimein); fputc ('\n', smimein); fclose (smimein); mutt_wait_filter (thepid); /* check for errors from OpenSSL */ err = 0; fflush (smimeerr); rewind (smimeerr); while (fgets (buffer, sizeof (buffer) - 1, smimeerr) != NULL) { err = 1; fputs (buffer, stdout); } fclose (smimeerr); fflush (smimeout); rewind (smimeout); empty = (fgetc (smimeout) == EOF); fclose (smimeout); mutt_unlink (filetosign); if (err) mutt_any_key_to_continue (NULL); if (empty) { mutt_any_key_to_continue _("No output from OpenSSL..."); mutt_unlink (signedfile); 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; t->disposition = DISPINLINE; mutt_generate_boundary (&t->parameter); /* check if this can be extracted from private key somehow.... */ mutt_set_parameter ("micalg", "sha1", &t->parameter); mutt_set_parameter ("protocol", "application/x-pkcs7-signature", &t->parameter); t->parts = a; a = t; t->parts->next = mutt_new_body (); t = t->parts->next; t->type = TYPEAPPLICATION; t->subtype = safe_strdup ("x-pkcs7-signature"); t->filename = safe_strdup (signedfile); t->d_filename = safe_strdup ("smime.p7s"); t->use_disp = 1; t->disposition = DISPATTACH; t->encoding = ENCBASE64; t->unlink = 1; /* ok to remove this file after sending. */ return (a);}/* * Handling S/MIME - bodies. */staticpid_t smime_invoke_verify (FILE **smimein, FILE **smimeout, FILE **smimeerr, int smimeinfd, int smimeoutfd, int smimeerrfd, const char *fname, const char *sig_fname, int opaque){ return smime_invoke (smimein, smimeout, smimeerr, smimeinfd, smimeoutfd, smimeerrfd, fname, sig_fname, NULL, NULL, NULL, NULL, (opaque ? SmimeVerifyOpaqueCommand : SmimeVerifyCommand));}staticpid_t smime_invoke_decrypt (FILE **smimein, FILE **smimeout, FILE **smimeerr, int smimeinfd, int smimeoutfd, int smimeerrfd, const char *fname){ return smime_invoke (smimein, smimeout, smimeerr, smimeinfd, smimeoutfd, smimeerrfd, fname, NULL, NULL, SmimeKeyToUse, SmimeCertToUse, NULL, SmimeDecryptCommand);}int smime_verify_one (BODY *sigbdy, STATE *s, const char *tempfile){ char signedfile[_POSIX_PATH_MAX], smimeerrfile[_POSIX_PATH_MAX]; FILE *fp=NULL, *smimeout=NULL, *smimeerr=NULL; pid_t thepid; int badsig = -1; long tmpoffset = 0; size_t tmplength = 0; int origType = sigbdy->type; char *savePrefix = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -