⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smime.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (C) 2001,2002 Oliver Ehli <elmy@acm.org> * Copyright (C) 2002 Mike Schiraldi <raldi@research.netsol.com> * Copyright (C) 2004 g10 Code GmbH * *     This program is free software; you can redistribute it and/or modify *     it under the terms of the GNU General Public License as published by *     the Free Software Foundation; either version 2 of the License, or *     (at your option) any later version. *  *     This program is distributed in the hope that it will be useful, *     but WITHOUT ANY WARRANTY; without even the implied warranty of *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *     GNU General Public License for more details. *  *     You should have received a copy of the GNU General Public License *     along with this program; if not, write to the Free Software *     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. */#if HAVE_CONFIG_H# include "config.h"#endif#include "mutt.h"#include "mutt_curses.h"#include "mutt_menu.h"#include "smime.h"#include "mime.h"#include "copy.h"#include <sys/wait.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <sys/stat.h>#include <errno.h>#include <ctype.h>#ifdef HAVE_LOCALE_H#include <locale.h>#endif#ifdef HAVE_SYS_TIME_H# include <sys/time.h>#endif#ifdef HAVE_SYS_RESOURCE_H# include <sys/resource.h>#endif#ifdef CRYPT_BACKEND_CLASSIC_SMIME#include "mutt_crypt.h"struct smime_command_context {  const char *key;		    /* %k */  const char *cryptalg;		    /* %a */  const char *fname;		    /* %f */  const char *sig_fname;	    /* %s */  const char *certificates;	    /* %c */  const char *intermediates;        /* %i */};typedef struct {  unsigned int hash;  char suffix;  char email[256];  char nick[256];  char trust; /* i=Invalid r=revoked e=expired u=unverified v=verified t=trusted */  short public; /* 1=public 0=private */} smime_id;char SmimePass[STRING];time_t SmimeExptime = 0; /* when does the cached passphrase expire? */static char SmimeKeyToUse[_POSIX_PATH_MAX] = { 0 };static char SmimeCertToUse[_POSIX_PATH_MAX];static char SmimeIntermediateToUse[_POSIX_PATH_MAX];/* *     Queries and passphrase handling. *//* these are copies from pgp.c */void smime_void_passphrase (void){  memset (SmimePass, 0, sizeof (SmimePass));  SmimeExptime = 0;}int smime_valid_passphrase (void){  time_t now = time (NULL);  if (now < SmimeExptime)    /* Use cached copy.  */    return 1;  smime_void_passphrase();    if (mutt_get_password (_("Enter S/MIME passphrase:"), SmimePass, sizeof (SmimePass)) == 0)    {      SmimeExptime = time (NULL) + SmimeTimeout;      return (1);    }  else    SmimeExptime = 0;  return 0;}/* *     The OpenSSL interface *//* This is almost identical to ppgp's invoking interface. */static const char *_mutt_fmt_smime_command (char *dest,					    size_t destlen,					    char op,					    const char *src,					    const char *prefix,					    const char *ifstring,					    const char *elsestring,					    unsigned long data,					    format_flag flags){  char fmt[16];  struct smime_command_context *cctx = (struct smime_command_context *) data;  int optional = (flags & M_FORMAT_OPTIONAL);    switch (op)  {    case 'C':    {      if (!optional)      {	char path[_POSIX_PATH_MAX];	char buf1[LONG_STRING], buf2[LONG_STRING];	struct stat sb;	strfcpy (path, NONULL (SmimeCALocation), sizeof (path));	mutt_expand_path (path, sizeof (path));	mutt_quote_filename (buf1, sizeof (buf1), path);	if (stat (path, &sb) != 0 || !S_ISDIR (sb.st_mode))	  snprintf (buf2, sizeof (buf2), "-CAfile %s", buf1);	else	  snprintf (buf2, sizeof (buf2), "-CApath %s", buf1);		snprintf (fmt, sizeof (fmt), "%%%ss", prefix);	snprintf (dest, destlen, fmt, buf2);      }      else if (!SmimeCALocation)	optional = 0;      break;    }        case 'c':    {           /* certificate (list) */      if (!optional) {	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);	snprintf (dest, destlen, fmt, NONULL(cctx->certificates));      }      else if (!cctx->certificates)	optional = 0;      break;    }        case 'i':    {           /* intermediate certificates  */      if (!optional) {	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);	snprintf (dest, destlen, fmt, NONULL(cctx->intermediates));      }      else if (!cctx->intermediates)	optional = 0;      break;    }        case 's':    {           /* detached signature */      if (!optional)      {	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);	snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));      }      else if (!cctx->sig_fname)	optional = 0;      break;    }        case 'k':    {           /* private key */      if (!optional)      {	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);	snprintf (dest, destlen, fmt, NONULL (cctx->key));      }      else if (!cctx->key)	optional = 0;      break;    }        case 'a':    {           /* algorithm for encryption */      if (!optional) {	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);	snprintf (dest, destlen, fmt, NONULL (cctx->cryptalg));      }      else if (!cctx->key)	optional = 0;      break;    }        case 'f':    {           /* file to process */      if (!optional)      {	snprintf (fmt, sizeof (fmt), "%%%ss", prefix);	snprintf (dest, destlen, fmt, NONULL (cctx->fname));      }      else if (!cctx->fname)	optional = 0;      break;    }        default:      *dest = '\0';      break;  }  if (optional)    mutt_FormatString (dest, destlen, ifstring, _mutt_fmt_smime_command,		       data, 0);  else if (flags & M_FORMAT_OPTIONAL)    mutt_FormatString (dest, destlen, elsestring, _mutt_fmt_smime_command,		       data, 0);  return (src);}static void mutt_smime_command (char *d, size_t dlen,				struct smime_command_context *cctx, const char *fmt){  mutt_FormatString (d, dlen, NONULL(fmt), _mutt_fmt_smime_command,		    (unsigned long) cctx, 0);  dprint (2,(debugfile, "mutt_smime_command: %s\n", d));}static pid_t smime_invoke (FILE **smimein, FILE **smimeout, FILE **smimeerr,			   int smimeinfd, int smimeoutfd, int smimeerrfd,			   const char *fname,			   const char *sig_fname,			   const char *cryptalg,			   const char *key,			   const char *certificates,			   const char *intermediates,			   const char *format){  struct smime_command_context cctx;  char cmd[HUGE_STRING];    memset (&cctx, 0, sizeof (cctx));  if (!format || !*format)    return (pid_t) -1;    cctx.fname	       = fname;  cctx.sig_fname       = sig_fname;  cctx.key	       = key;  cctx.cryptalg	       = cryptalg;  cctx.certificates    = certificates;  cctx.intermediates   = intermediates;    mutt_smime_command (cmd, sizeof (cmd), &cctx, format);  return mutt_create_filter_fd (cmd, smimein, smimeout, smimeerr,				smimeinfd, smimeoutfd, smimeerrfd);}/* *    Key and certificate handling. *//*    Search the certificate index for given mailbox.   return certificate file name.*/static void smime_entry (char *s, size_t l, MUTTMENU * menu, int num){  smime_id *Table = (smime_id*) menu->data;  smime_id this = Table[num];  char* truststate;  switch(this.trust) {    case 't':      truststate = N_("Trusted   ");      break;    case 'v':      truststate = N_("Verified  ");      break;    case 'u':      truststate = N_("Unverified");      break;    case 'e':      truststate = N_("Expired   ");      break;    case 'r':      truststate = N_("Revoked   ");      break;    case 'i':      truststate = N_("Invalid   ");      break;    default:      truststate = N_("Unknown   ");  }  if (this.public)    snprintf(s, l, " 0x%.8X.%i %s %-35.35s %s", this.hash, this.suffix, truststate, this.email, this.nick);  else    snprintf(s, l, " 0x%.8X.%i %-35.35s %s", this.hash, this.suffix, this.email, this.nick);}char* smime_ask_for_key (char *prompt, char *mailbox, short public){  char *fname;  smime_id *Table;  long cert_num; /* Will contain the number of certificates.      * To be able to get it, the .index file will be read twice... */  char index_file[_POSIX_PATH_MAX];  FILE *index;  char buf[LONG_STRING];  char fields[5][STRING];  int numFields, hash_suffix, done, cur; /* The current entry */  MUTTMENU* menu;  unsigned int hash;  char helpstr[HUGE_STRING*3];  char qry[256];  char title[256];  if (!prompt) prompt = _("Enter keyID: ");  snprintf(index_file, sizeof (index_file), "%s/.index",    public ? NONULL(SmimeCertificates) : NONULL(SmimeKeys));    index = fopen(index_file, "r");  if (index == NULL)   {    mutt_perror (index_file);          return NULL;  }  /* Count Lines */  cert_num = 0;  while (!feof(index)) {    if (fgets(buf, sizeof(buf), index)) cert_num++;  }  fclose(index);  FOREVER  {    *qry = 0;    if (mutt_get_field(prompt,      qry, sizeof(qry), 0))      return NULL;    snprintf(title, sizeof(title), _("S/MIME certificates matching \"%s\"."),      qry);        index = fopen(index_file, "r");    if (index == NULL)     {      mutt_perror (index_file);            return NULL;    }    /* Read Entries */    cur = 0;    Table = safe_calloc(cert_num, sizeof (smime_id));    while (!feof(index)) {        numFields = fscanf (index, MUTT_FORMAT(STRING) " %x.%i " MUTT_FORMAT(STRING), fields[0], &hash,          &hash_suffix, fields[2]);        if (public)          fscanf (index, MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) "\n", fields[3], fields[4]);        /* 0=email 1=name 2=nick 3=intermediate 4=trust */      if (numFields < 2) continue;        /* Check if query matches this certificate */      if (!mutt_stristr(fields[0], qry) &&          !mutt_stristr(fields[2], qry))        continue;        Table[cur].hash = hash;      Table[cur].suffix = hash_suffix;      strncpy(Table[cur].email, fields[0], sizeof(Table[cur].email));      strncpy(Table[cur].nick, fields[2], sizeof(Table[cur].nick));      Table[cur].trust = *fields[4];      Table[cur].public = public;        cur++;    }    fclose(index);      /* Make Helpstring */    helpstr[0] = 0;    mutt_make_help (buf, sizeof (buf), _("Exit  "), MENU_SMIME, OP_EXIT);    strcat (helpstr, buf);	/* __STRCAT_CHECKED__ */    mutt_make_help (buf, sizeof (buf), _("Select  "), MENU_SMIME,        OP_GENERIC_SELECT_ENTRY);    strcat (helpstr, buf);	/* __STRCAT_CHECKED__ */    mutt_make_help (buf, sizeof(buf), _("Help"), MENU_SMIME, OP_HELP);    strcat (helpstr, buf);	/* __STRCAT_CHECKED__ */      /* Create the menu */    menu = mutt_new_menu();    menu->max = cur;    menu->make_entry = smime_entry;    menu->menu = MENU_SMIME;    menu->help = helpstr;    menu->data = Table;    menu->title = title;    /* sorting keys might be done later - TODO */      mutt_clear_error();      done = 0;    hash = 0;    while (!done) {      switch (mutt_menuLoop (menu)) {        case OP_GENERIC_SELECT_ENTRY:          cur = menu->current;  	hash = 1;          done = 1;          break;        case OP_EXIT:          hash = 0;          done = 1;          break;      }    }    if (hash) {      fname = safe_malloc(13); /* Hash + '.' + Suffix + \0 */      sprintf(fname, "%.8x.%i", Table[cur].hash, Table[cur].suffix);    }    else fname = NULL;      mutt_menuDestroy (&menu);    FREE (&Table);    set_option (OPTNEEDREDRAW);      if (fname) return fname;  }}char *smime_get_field_from_db (char *mailbox, char *query, short public, short may_ask){  int addr_len, query_len, found = 0, ask = 0, choice = 0;  char cert_path[_POSIX_PATH_MAX];  char buf[LONG_STRING], prompt[STRING];  char fields[5][STRING];  char key[STRING];    int numFields;  struct stat info;  char key_trust_level = 0;  FILE *fp;  if(!mailbox && !query) return(NULL);  addr_len = mailbox ? mutt_strlen (mailbox) : 0;  query_len = query ? mutt_strlen (query) : 0;    *key = '\0';  /* index-file format:     mailbox certfile label issuer_certfile trust_flags\n     certfile is a hash value generated by openssl.     Note that this was done according to the OpenSSL     specs on their CA-directory.  */  snprintf (cert_path, sizeof (cert_path), "%s/.index",	    (public ? NONULL(SmimeCertificates) : NONULL(SmimeKeys)));  if (!stat (cert_path, &info))  {    if ((fp = safe_fopen (cert_path, "r")) == NULL)    {      mutt_perror (cert_path);      return (NULL);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -