X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=smime.c;h=cba710063687f1f2642699ab6882d2757420799f;hp=fda19e957975e0a076c9675147b40fcd31bb7f6c;hb=4eaac5c4a87b84ea9ec0668b4e088ac27e2d1106;hpb=6833ce8bdca2d64e14485118f2a4417b7e1cb1b1 diff --git a/smime.c b/smime.c index fda19e9..cba7100 100644 --- a/smime.c +++ b/smime.c @@ -1,29 +1,32 @@ /* + * Copyright notice from original mutt: * Copyright (C) 2001,2002 Oliver Ehli * Copyright (C) 2002 Mike Schiraldi + * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * This file is part of mutt-ng, see http://www.muttng.org/. + * It's licensed under the GNU General Public License, + * please see the file GPL in the top level source directory. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + #include "mutt.h" +#include "enter.h" +#include "handler.h" #include "mutt_curses.h" #include "mutt_menu.h" #include "smime.h" #include "mime.h" #include "copy.h" +#include "lib/mem.h" +#include "lib/intl.h" +#include "lib/str.h" +#include "lib/debug.h" + #include #include #include @@ -48,14 +51,13 @@ #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 */ + 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 */ }; @@ -64,13 +66,13 @@ typedef struct { 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 */ + 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? */ +time_t SmimeExptime = 0; /* when does the cached passphrase expire? */ static char SmimeKeyToUse[_POSIX_PATH_MAX] = { 0 }; @@ -94,9 +96,26 @@ void smime_void_passphrase (void) 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_field_unbuffered (_("Enter S/MIME passphrase:"), SmimePass, + sizeof (SmimePass), M_PASS) == 0) { + SmimeExptime = time (NULL) + SmimeTimeout; + return (1); + } + else + SmimeExptime = 0; + + return 0; +} /* @@ -106,126 +125,121 @@ void smime_void_passphrase (void) /* 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) + 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': + + 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); + 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; + optional = 0; break; } - - case 'c': - { /* certificate (list) */ + + case 'c': + { /* certificate (list) */ if (!optional) { - snprintf (fmt, sizeof (fmt), "%%%ss", prefix); - snprintf (dest, destlen, fmt, NONULL(cctx->certificates)); + snprintf (fmt, sizeof (fmt), "%%%ss", prefix); + snprintf (dest, destlen, fmt, NONULL (cctx->certificates)); } else if (!cctx->certificates) - optional = 0; + optional = 0; break; } - - case 'i': - { /* intermediate certificates */ + + case 'i': + { /* intermediate certificates */ if (!optional) { - snprintf (fmt, sizeof (fmt), "%%%ss", prefix); - snprintf (dest, destlen, fmt, NONULL(cctx->intermediates)); + snprintf (fmt, sizeof (fmt), "%%%ss", prefix); + snprintf (dest, destlen, fmt, NONULL (cctx->intermediates)); } else if (!cctx->intermediates) - optional = 0; + optional = 0; break; } - - case 's': - { /* detached signature */ - if (!optional) - { - snprintf (fmt, sizeof (fmt), "%%%ss", prefix); - snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname)); + + 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; + optional = 0; break; } - - case 'k': - { /* private key */ - if (!optional) - { - snprintf (fmt, sizeof (fmt), "%%%ss", prefix); - snprintf (dest, destlen, fmt, NONULL (cctx->key)); + + 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; + optional = 0; break; } - - case 'a': - { /* algorithm for encryption */ + + case 'a': + { /* algorithm for encryption */ if (!optional) { - snprintf (fmt, sizeof (fmt), "%%%ss", prefix); - snprintf (dest, destlen, fmt, NONULL (cctx->cryptalg)); + snprintf (fmt, sizeof (fmt), "%%%ss", prefix); + snprintf (dest, destlen, fmt, NONULL (cctx->cryptalg)); } else if (!cctx->key) - optional = 0; + optional = 0; break; } - - case 'f': - { /* file to process */ - if (!optional) - { - snprintf (fmt, sizeof (fmt), "%%%ss", prefix); - snprintf (dest, destlen, fmt, NONULL (cctx->fname)); + + 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; + optional = 0; break; } - - default: - *dest = '\0'; - break; + + default: + *dest = '\0'; + break; } if (optional) mutt_FormatString (dest, destlen, ifstring, _mutt_fmt_smime_command, - data, 0); + data, 0); else if (flags & M_FORMAT_OPTIONAL) mutt_FormatString (dest, destlen, elsestring, _mutt_fmt_smime_command, - data, 0); + data, 0); return (src); } @@ -233,45 +247,40 @@ static const char *_mutt_fmt_smime_command (char *dest, static void mutt_smime_command (char *d, size_t dlen, - struct smime_command_context *cctx, const char *fmt) + 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)); + mutt_FormatString (d, dlen, NONULL (fmt), _mutt_fmt_smime_command, + (unsigned long) cctx, 0); + debug_print (2, ("%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) +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; - + 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); + smimeinfd, smimeoutfd, smimeerrfd); } @@ -292,131 +301,134 @@ static pid_t smime_invoke (FILE **smimein, FILE **smimeout, FILE **smimeerr, static void smime_entry (char *s, size_t l, MUTTMENU * menu, int num) { - smime_id *Table = (smime_id*) menu->data; + 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 "); + const 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); + 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); + 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 *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... */ + 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; + int numFields, hash_suffix, done, cur; /* The current entry */ + MUTTMENU *menu; unsigned int hash; - char helpstr[HUGE_STRING*3]; + 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); + 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++; + while (!feof (index)) { + if (fgets (buf, sizeof (buf), index)) + cert_num++; } - fclose(index); + fclose (index); - FOREVER - { + FOREVER { *qry = 0; - if (mutt_get_field(prompt, - qry, sizeof(qry), 0)) + if (mutt_get_field (prompt, qry, sizeof (qry), 0)) return NULL; - snprintf(title, sizeof(title), _("S/MIME certificates matching \"%s\"."), - qry); + snprintf (title, sizeof (title), + _("S/MIME certificates matching \"%s\"."), qry); - - index = fopen(index_file, "r"); - if (index == NULL) - { - mutt_perror (index_file); + + 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]); - + Table = mem_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; - + if (numFields < 2) + continue; + /* Check if query matches this certificate */ - if (!mutt_stristr(fields[0], qry) && - !mutt_stristr(fields[2], qry)) + if (!str_isstr (fields[0], qry) && !str_isstr (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)); + 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); - + fclose (index); + /* Make Helpstring */ helpstr[0] = 0; mutt_make_help (buf, sizeof (buf), _("Exit "), MENU_SMIME, OP_EXIT); - strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ + 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__ */ - + 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 = mutt_new_menu (); menu->max = cur; menu->make_entry = smime_entry; menu->menu = MENU_SMIME; @@ -424,214 +436,193 @@ char* smime_ask_for_key (char *prompt, char *mailbox, short public) menu->data = Table; menu->title = title; /* sorting keys might be done later - TODO */ - - mutt_clear_error(); - + + 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; + 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(14); /* Hash + '.' + Suffix + \n + \0 */ - sprintf(fname, "%.8x.%i\n", Table[cur].hash, Table[cur].suffix); + fname = mem_malloc (13); /* Hash + '.' + Suffix + \0 */ + sprintf (fname, "%.8x.%i", Table[cur].hash, Table[cur].suffix); } - else fname = NULL; - + else + fname = NULL; + mutt_menuDestroy (&menu); - FREE (&Table); + mem_free (&Table); set_option (OPTNEEDREDRAW); - - if (fname) return fname; + + if (fname) + return fname; } } -char *smime_get_field_from_db (char *mailbox, char *query, short public, short may_ask) +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=NULL, key_trust_level = 0; + char key_trust_level = 0; FILE *fp; - if(!mailbox && !query) return(NULL); + if (!mailbox && !query) + return (NULL); + + addr_len = mailbox ? str_len (mailbox) : 0; + query_len = query ? str_len (query) : 0; - 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 - \n is also copied here, serving as delimitation. - 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))); + (public ? NONULL (SmimeCertificates) : NONULL (SmimeKeys))); - if (!stat (cert_path, &info)) - { - if ((fp = safe_fopen (cert_path, "r")) == NULL) - { + if (!stat (cert_path, &info)) { + if ((fp = safe_fopen (cert_path, "r")) == NULL) { mutt_perror (cert_path); return (NULL); } while (fgets (buf, sizeof (buf) - 1, fp) != NULL) - if (mailbox && !(mutt_strncasecmp (mailbox, buf, addr_len))) - { - numFields = sscanf (buf, - MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " - MUTT_FORMAT(STRING) " " MUTT_FORMAT(STRING) " " - MUTT_FORMAT(STRING) "\n", - fields[0], fields[1], - fields[2], fields[3], - fields[4]); - if (numFields < 2) - continue; - if (mailbox && public && - (!fields[4] || - *fields[4] == 'i' || *fields[4] == 'e' || *fields[4] == 'r')) - continue; - - if (found) - { - if (public && *fields[4] == 'u' ) - snprintf (prompt, sizeof (prompt), - _("ID %s is unverified. Do you want to use it for %s ?"), - fields[1], mailbox); - else if (public && *fields[4] == 'v' ) - snprintf (prompt, sizeof (prompt), - _("Use (untrusted!) ID %s for %s ?"), - fields[1], mailbox); - else - snprintf (prompt, sizeof (prompt), _("Use ID %s for %s ?"), - fields[1], mailbox); - if (may_ask == 0) - choice = M_YES; - if (may_ask && (choice = mutt_yesorno (prompt, M_NO)) == -1) - { - found = 0; - ask = 0; - FREE (&key); - key = NULL; - break; - } - else if (choice == M_NO) - { - ask = 1; - continue; - } - else if (choice == M_YES) - { - snprintf (key,mutt_strlen(key)+1, fields[1]); - ask = 0; - break; - } - } - else - { - key = safe_calloc(1, mutt_strlen(fields[1])+2); - if (public) key_trust_level = *fields[4]; - snprintf(key, mutt_strlen(fields[1])+1, "%s", fields[1]); - - } - found = 1; + if (mailbox && !(str_ncasecmp (mailbox, buf, addr_len))) { + numFields = sscanf (buf, + MUTT_FORMAT (STRING) " " MUTT_FORMAT (STRING) " " + MUTT_FORMAT (STRING) " " MUTT_FORMAT (STRING) " " + MUTT_FORMAT (STRING) "\n", + fields[0], fields[1], + fields[2], fields[3], fields[4]); + if (numFields < 2) + continue; + if (mailbox && public && + (!fields[4] || + *fields[4] == 'i' || *fields[4] == 'e' || *fields[4] == 'r')) + continue; + + if (found) { + if (public && *fields[4] == 'u') + snprintf (prompt, sizeof (prompt), + _ + ("ID %s is unverified. Do you want to use it for %s ?"), + fields[1], mailbox); + else if (public && *fields[4] == 'v') + snprintf (prompt, sizeof (prompt), + _("Use (untrusted!) ID %s for %s ?"), + fields[1], mailbox); + else + snprintf (prompt, sizeof (prompt), _("Use ID %s for %s ?"), + fields[1], mailbox); + if (may_ask == 0) + choice = M_YES; + if (may_ask && (choice = mutt_yesorno (prompt, M_NO)) == -1) { + found = 0; + ask = 0; + *key = '\0'; + break; + } + else if (choice == M_NO) { + ask = 1; + continue; + } + else if (choice == M_YES) { + strfcpy (key, fields[1], sizeof (key)); + ask = 0; + break; + } + } + else { + if (public) + key_trust_level = *fields[4]; + strfcpy (key, fields[1], sizeof (key)); + } + found = 1; } - else if(query) - { - numFields = sscanf (buf, "%s %s %s %s %s\n", fields[0], fields[1], - fields[2], fields[3], fields[4]); - - /* query = label: return certificate. */ - if (numFields >= 3 && - !(mutt_strncasecmp (query, fields[2], query_len))) - { - ask = 0; - key = safe_calloc(1, mutt_strlen(fields[1])+2); - snprintf(key, mutt_strlen(fields[1])+1, "%s", fields[1]); - } - /* query = certificate: return intermediate certificate. */ - else if (numFields >= 4 && - !(mutt_strncasecmp (query, fields[1], query_len))) - { - ask = 0; - key = safe_calloc(1, mutt_strlen(fields[3])+2); - snprintf(key, mutt_strlen(fields[3])+1, "%s", fields[3]); - } + else if (query) { + numFields = sscanf (buf, + MUTT_FORMAT (STRING) " " MUTT_FORMAT (STRING) " " + MUTT_FORMAT (STRING) " " MUTT_FORMAT (STRING) " " + MUTT_FORMAT (STRING) "\n", + fields[0], fields[1], + fields[2], fields[3], fields[4]); + + /* query = label: return certificate. */ + if (numFields >= 3 && + !(str_ncasecmp (query, fields[2], query_len))) { + ask = 0; + strfcpy (key, fields[1], sizeof (key)); + } + /* query = certificate: return intermediate certificate. */ + else if (numFields >= 4 && + !(str_ncasecmp (query, fields[1], query_len))) { + ask = 0; + strfcpy (key, fields[3], sizeof (key)); + } } - fclose (fp); + safe_fclose (&fp); - if (ask) - { - if (public && *fields[4] == 'u' ) - snprintf (prompt, sizeof (prompt), - _("ID %s is unverified. Do you want to use it for %s ?"), - fields[1], mailbox); - else if (public && *fields[4] == 'v' ) - snprintf (prompt, sizeof (prompt), - _("Use (untrusted!) ID %s for %s ?"), - fields[1], mailbox); + if (ask) { + if (public && *fields[4] == 'u') + snprintf (prompt, sizeof (prompt), + _("ID %s is unverified. Do you want to use it for %s ?"), + fields[1], mailbox); + else if (public && *fields[4] == 'v') + snprintf (prompt, sizeof (prompt), + _("Use (untrusted!) ID %s for %s ?"), fields[1], mailbox); else - snprintf (prompt, sizeof(prompt), _("Use ID %s for %s ?"), key, - mailbox); + snprintf (prompt, sizeof (prompt), _("Use ID %s for %s ?"), key, + mailbox); choice = mutt_yesorno (prompt, M_NO); if (choice == -1 || choice == M_NO) - { - FREE (&key); - key = NULL; - } + *key = '\0'; } - else if (key_trust_level && may_ask) - { - if (key_trust_level == 'u' ) - { - snprintf (prompt, sizeof (prompt), - _("ID %s is unverified. Do you want to use it for %s ?"), - key, mailbox); - choice = mutt_yesorno (prompt, M_NO); - if (choice != M_YES) - { - FREE (&key); - key = NULL; - } - + else if (key_trust_level && may_ask) { + if (key_trust_level == 'u') { + snprintf (prompt, sizeof (prompt), + _("ID %s is unverified. Do you want to use it for %s ?"), + key, mailbox); + choice = mutt_yesorno (prompt, M_NO); + if (choice != M_YES) + *key = '\0'; } - else if (key_trust_level == 'v' ) - { - mutt_error (_("Warning: You have not yet decided to trust ID %s. (any key to continue)"), key); - mutt_sleep (5); + else if (key_trust_level == 'v') { + mutt_error (_ + ("Warning: You have not yet decided to trust ID %s. (any key to continue)"), + key); + mutt_sleep (5); } } } - if (key) - { - key[mutt_strlen(key)+1] = '\0'; - key[mutt_strlen(key)] = '\n'; - } - - return key; + /* Note: str_dup ("") returns NULL. */ + return str_dup (key); } @@ -649,85 +640,75 @@ void _smime_getkeys (char *mailbox) k = smime_get_field_from_db (mailbox, NULL, 0, 1); - if (!k) - { - snprintf(buf, sizeof(buf), _("Enter keyID for %s: "), - mailbox); - k = smime_ask_for_key(buf, mailbox, 0); + if (!k) { + snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), mailbox); + k = smime_ask_for_key (buf, mailbox, 0); } - if (k) - { - k[mutt_strlen (k)-1] = '\0'; - + if (k) { /* the key used last time. */ - if (*SmimeKeyToUse && - !mutt_strcasecmp (k, SmimeKeyToUse + mutt_strlen (SmimeKeys)+1)) - { - FREE (&k); + if (*SmimeKeyToUse && + !str_casecmp (k, SmimeKeyToUse + str_len (SmimeKeys) + 1)) { + mem_free (&k); return; } - else smime_void_passphrase (); + else + smime_void_passphrase (); + + snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", + NONULL (SmimeKeys), k); - snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", - NONULL(SmimeKeys), k); - snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", - NONULL(SmimeCertificates), k); + NONULL (SmimeCertificates), k); - if (mutt_strcasecmp (k, SmimeDefaultKey)) + if (str_casecmp (k, SmimeDefaultKey)) smime_void_passphrase (); - FREE (&k); + mem_free (&k); return; } - if (*SmimeKeyToUse) - { - if (!mutt_strcasecmp (SmimeDefaultKey, - SmimeKeyToUse + mutt_strlen (SmimeKeys)+1)) + if (*SmimeKeyToUse) { + if (!str_casecmp (SmimeDefaultKey, + SmimeKeyToUse + str_len (SmimeKeys) + 1)) return; smime_void_passphrase (); } - snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", - NONULL (SmimeKeys), NONULL (SmimeDefaultKey)); - + snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", + NONULL (SmimeKeys), NONULL (SmimeDefaultKey)); + snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", - NONULL (SmimeCertificates), NONULL (SmimeDefaultKey)); + NONULL (SmimeCertificates), NONULL (SmimeDefaultKey)); } -void smime_getkeys (ENVELOPE *env) +void smime_getkeys (ENVELOPE * env) { ADDRESS *t; int found = 0; - if (option (OPTSDEFAULTDECRYPTKEY) && SmimeDefaultKey && *SmimeDefaultKey) - { - snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", - NONULL (SmimeKeys), SmimeDefaultKey); - + if (option (OPTSDEFAULTDECRYPTKEY) && SmimeDefaultKey && *SmimeDefaultKey) { + snprintf (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", + NONULL (SmimeKeys), SmimeDefaultKey); + snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", - NONULL(SmimeCertificates), SmimeDefaultKey); + NONULL (SmimeCertificates), SmimeDefaultKey); return; } for (t = env->to; !found && t; t = t->next) - if (mutt_addr_is_user (t)) - { + if (mutt_addr_is_user (t)) { found = 1; _smime_getkeys (t->mailbox); } for (t = env->cc; !found && t; t = t->next) - if (mutt_addr_is_user (t)) - { + if (mutt_addr_is_user (t)) { found = 1; _smime_getkeys (t->mailbox); } - if (!found && (t = mutt_default_from())) - { + if (!found && (t = mutt_default_from ())) { _smime_getkeys (t->mailbox); rfc822_free_address (&t); } @@ -737,7 +718,7 @@ void smime_getkeys (ENVELOPE *env) * It returns NULL if any of the keys can not be found. */ -char *smime_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) +char *smime_findKeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc) { char *keyID, *keylist = NULL; size_t keylist_size = 0; @@ -748,17 +729,22 @@ char *smime_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) int i; const char *fqdn = mutt_fqdn (1); - - for (i = 0; i < 3; i++) - { - switch (i) - { - case 0: p = to; break; - case 1: p = cc; break; - case 2: p = bcc; break; - default: abort (); + + for (i = 0; i < 3; i++) { + switch (i) { + case 0: + p = to; + break; + case 1: + p = cc; + break; + case 2: + p = bcc; + break; + default: + abort (); } - + *last = rfc822_cpy_adr (p); while (*last) last = &((*last)->next); @@ -768,33 +754,28 @@ char *smime_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) rfc822_qualify (tmp, fqdn); tmp = mutt_remove_duplicates (tmp); - - for (p = tmp; p ; p = p->next) - { + + for (p = tmp; p; p = p->next) { char buf[LONG_STRING]; q = p; - if ((keyID = smime_get_field_from_db (q->mailbox, NULL, 1, 1)) == NULL) - { - snprintf(buf, sizeof(buf), - _("Enter keyID for %s: "), - q->mailbox); - keyID = smime_ask_for_key(buf, q->mailbox, 1); + if ((keyID = smime_get_field_from_db (q->mailbox, NULL, 1, 1)) == NULL) { + snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox); + keyID = smime_ask_for_key (buf, q->mailbox, 1); } - if(!keyID) - { + if (!keyID) { mutt_message (_("No (valid) certificate found for %s."), q->mailbox); - FREE (&keylist); + mem_free (&keylist); rfc822_free_address (&tmp); rfc822_free_address (&addr); return NULL; } - - keylist_size += mutt_strlen (keyID) + 1; - safe_realloc (&keylist, keylist_size); - sprintf (keylist + keylist_used, "%s", keyID); /* __SPRINTF_CHECKED__ */ - keylist_used = mutt_strlen (keylist); + + keylist_size += str_len (keyID) + 2; + mem_realloc (&keylist, keylist_size); + sprintf (keylist + keylist_used, "%s\n", keyID); /* __SPRINTF_CHECKED__ */ + keylist_used = str_len (keylist); rfc822_free_address (&addr); @@ -809,7 +790,7 @@ char *smime_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) static int smime_handle_cert_email (char *certificate, char *mailbox, - int copy, char ***buffer, int *num) + int copy, char ***buffer, int *num) { FILE *fpout = NULL, *fperr = NULL; char tmpfname[_POSIX_PATH_MAX]; @@ -818,27 +799,24 @@ static int smime_handle_cert_email (char *certificate, char *mailbox, pid_t thepid; mutt_mktemp (tmpfname); - if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) - { + if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return 1; } mutt_unlink (tmpfname); mutt_mktemp (tmpfname); - if ((fpout = safe_fopen (tmpfname, "w+")) == NULL) - { + if ((fpout = safe_fopen (tmpfname, "w+")) == NULL) { fclose (fperr); mutt_perror (tmpfname); return 1; } mutt_unlink (tmpfname); - if ((thepid = smime_invoke (NULL, NULL, NULL, - -1, fileno (fpout), fileno (fperr), - certificate, NULL, NULL, NULL, NULL, NULL, - SmimeGetCertEmailCommand))== -1) - { + if ((thepid = smime_invoke (NULL, NULL, NULL, + -1, fileno (fpout), fileno (fperr), + certificate, NULL, NULL, NULL, NULL, NULL, + SmimeGetCertEmailCommand)) == -1) { mutt_message (_("Error: unable to create OpenSSL subprocess!")); fclose (fperr); fclose (fpout); @@ -853,43 +831,42 @@ static int smime_handle_cert_email (char *certificate, char *mailbox, fflush (fperr); - while ((fgets (email, sizeof (email), fpout))) - { - *(email + mutt_strlen (email)-1) = '\0'; - if(mutt_strncasecmp (email, mailbox, mutt_strlen (mailbox)) == 0) - ret=1; + while ((fgets (email, sizeof (email), fpout))) { + *(email + str_len (email) - 1) = '\0'; + if (str_ncasecmp (email, mailbox, str_len (mailbox)) == 0) + ret = 1; ret = ret < 0 ? 0 : ret; count++; } - if (ret == -1) - { - mutt_endwin(NULL); + if (ret == -1) { + mutt_endwin (NULL); mutt_copy_stream (fperr, stdout); - mutt_any_key_to_continue (_("Error: unable to create OpenSSL subprocess!")); + mutt_any_key_to_continue (_ + ("Error: unable to create OpenSSL subprocess!")); ret = 1; } else if (!ret) ret = 1; - else ret = 0; + else + ret = 0; - if(copy && buffer && num) - { + if (copy && buffer && num) { (*num) = count; - *buffer = safe_calloc(sizeof(char*), count); + *buffer = mem_calloc (sizeof (char *), count); count = 0; rewind (fpout); - while ((fgets (email, sizeof (email), fpout))) - { - *(email + mutt_strlen (email) - 1) = '\0'; - (*buffer)[count] = safe_calloc(1, mutt_strlen (email) + 1); - strncpy((*buffer)[count], email, mutt_strlen (email)); + while ((fgets (email, sizeof (email), fpout))) { + *(email + str_len (email) - 1) = '\0'; + (*buffer)[count] = mem_calloc (1, str_len (email) + 1); + strncpy ((*buffer)[count], email, str_len (email)); count++; } } - else if(copy) ret = 2; + else if (copy) + ret = 2; fclose (fpout); fclose (fperr); @@ -909,16 +886,14 @@ static char *smime_extract_certificate (char *infile) mutt_mktemp (tmpfname); - if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) - { + if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return NULL; } mutt_unlink (tmpfname); mutt_mktemp (pk7out); - if ((fpout = safe_fopen (pk7out, "w+")) == NULL) - { + if ((fpout = safe_fopen (pk7out, "w+")) == NULL) { fclose (fperr); mutt_perror (pk7out); return NULL; @@ -926,13 +901,13 @@ static char *smime_extract_certificate (char *infile) /* Step 1: Convert the signature to a PKCS#7 structure, as we can't extract the full set of certificates directly. - */ - if ((thepid = smime_invoke (NULL, NULL, NULL, - -1, fileno (fpout), fileno (fperr), - infile, NULL, NULL, NULL, NULL, NULL, - SmimePk7outCommand))== -1) - { - mutt_any_key_to_continue (_("Error: unable to create OpenSSL subprocess!")); + */ + if ((thepid = smime_invoke (NULL, NULL, NULL, + -1, fileno (fpout), fileno (fperr), + infile, NULL, NULL, NULL, NULL, NULL, + SmimePk7outCommand)) == -1) { + mutt_any_key_to_continue (_ + ("Error: unable to create OpenSSL subprocess!")); fclose (fperr); fclose (fpout); mutt_unlink (pk7out); @@ -947,36 +922,34 @@ static char *smime_extract_certificate (char *infile) rewind (fperr); fflush (fperr); empty = (fgetc (fpout) == EOF); - if (empty) - { + if (empty) { mutt_perror (pk7out); mutt_copy_stream (fperr, stdout); fclose (fpout); fclose (fperr); mutt_unlink (pk7out); return NULL; - + } fclose (fpout); mutt_mktemp (certfile); - if ((fpout = safe_fopen (certfile, "w+")) == NULL) - { + if ((fpout = safe_fopen (certfile, "w+")) == NULL) { fclose (fperr); mutt_unlink (pk7out); mutt_perror (certfile); return NULL; } - + /* Step 2: Extract the certificates from a PKCS#7 structure. */ - if ((thepid = smime_invoke (NULL, NULL, NULL, - -1, fileno (fpout), fileno (fperr), - pk7out, NULL, NULL, NULL, NULL, NULL, - SmimeGetCertCommand))== -1) - { - mutt_any_key_to_continue (_("Error: unable to create OpenSSL subprocess!")); + if ((thepid = smime_invoke (NULL, NULL, NULL, + -1, fileno (fpout), fileno (fperr), + pk7out, NULL, NULL, NULL, NULL, NULL, + SmimeGetCertCommand)) == -1) { + mutt_any_key_to_continue (_ + ("Error: unable to create OpenSSL subprocess!")); fclose (fperr); fclose (fpout); mutt_unlink (pk7out); @@ -992,9 +965,8 @@ static char *smime_extract_certificate (char *infile) rewind (fpout); rewind (fperr); fflush (fperr); - empty = (fgetc (fpout) == EOF); - if (empty) - { + empty = (fgetc (fpout) == EOF); + if (empty) { mutt_copy_stream (fperr, stdout); fclose (fpout); fclose (fperr); @@ -1005,7 +977,7 @@ static char *smime_extract_certificate (char *infile) fclose (fpout); fclose (fperr); - return safe_strdup (certfile); + return str_dup (certfile); } static char *smime_extract_signer_certificate (char *infile) @@ -1018,8 +990,7 @@ static char *smime_extract_signer_certificate (char *infile) mutt_mktemp (tmpfname); - if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) - { + if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return NULL; } @@ -1027,21 +998,20 @@ static char *smime_extract_signer_certificate (char *infile) mutt_mktemp (certfile); - if ((fpout = safe_fopen (certfile, "w+")) == NULL) - { + 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!")); + 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); @@ -1055,9 +1025,8 @@ static char *smime_extract_signer_certificate (char *infile) rewind (fpout); rewind (fperr); fflush (fperr); - empty = (fgetc (fpout) == EOF); - if (empty) - { + empty = (fgetc (fpout) == EOF); + if (empty) { mutt_endwin (NULL); mutt_copy_stream (fperr, stdout); mutt_any_key_to_continue (NULL); @@ -1070,7 +1039,7 @@ static char *smime_extract_signer_certificate (char *infile) fclose (fpout); fclose (fperr); - return safe_strdup (certfile); + return str_dup (certfile); } @@ -1081,20 +1050,18 @@ static char *smime_extract_signer_certificate (char *infile) 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; + FILE *smimein = NULL, *fpout = NULL, *fperr = NULL; + pid_t thepid = -1; mutt_mktemp (tmpfname); - if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) - { + if ((fperr = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); return; } mutt_unlink (tmpfname); mutt_mktemp (tmpfname); - if ((fpout = safe_fopen (tmpfname, "w+")) == NULL) - { + if ((fpout = safe_fopen (tmpfname, "w+")) == NULL) { fclose (fperr); mutt_perror (tmpfname); return; @@ -1107,26 +1074,24 @@ void smime_invoke_import (char *infile, char *mailbox) mutt_get_field ("Label for certificate:", buf, sizeof (buf), 0); mutt_endwin (NULL); - if ((certfile = smime_extract_certificate(infile))) - { + 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) - { + + 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); + fclose (smimein); mutt_wait_filter (thepid); - + mutt_unlink (certfile); - FREE (&certfile); + mem_free (&certfile); } fflush (fpout); @@ -1144,62 +1109,56 @@ void smime_invoke_import (char *infile, char *mailbox) -int smime_verify_sender(HEADER *h) +int smime_verify_sender (HEADER * h) { char *mbox = NULL, *certfile, tempfname[_POSIX_PATH_MAX]; FILE *fpout; - int retval=1; + int retval = 1; mutt_mktemp (tempfname); - if (!(fpout = safe_fopen (tempfname, "w"))) - { + if (!(fpout = safe_fopen (tempfname, "w"))) { mutt_perror (tempfname); return 1; } - if(h->security & ENCRYPT) + if (h->security & ENCRYPT) mutt_copy_message (fpout, Context, h, - M_CM_DECODE_CRYPT & M_CM_DECODE_SMIME, - CH_MIME|CH_WEED|CH_NONEWLINE); + 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); + fflush (fpout); fclose (fpout); - if (h->env->from) - { - h->env->from = mutt_expand_aliases (h->env->from); - mbox = h->env->from->mailbox; + 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; + 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); + 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); + retval = 0; + mutt_unlink (certfile); + mem_free (&certfile); } - else - mutt_any_key_to_continue(_("no certfile")); + else + mutt_any_key_to_continue (_("no certfile")); } - else - mutt_any_key_to_continue(_("no mbox")); + else + mutt_any_key_to_continue (_("no mbox")); - mutt_unlink(tempfname); + mutt_unlink (tempfname); return retval; } @@ -1219,32 +1178,33 @@ int smime_verify_sender(HEADER *h) static -pid_t smime_invoke_encrypt (FILE **smimein, FILE **smimeout, FILE **smimeerr, - int smimeinfd, int smimeoutfd, int smimeerrfd, - const char *fname, const char *uids) +pid_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); + smimeinfd, smimeoutfd, smimeerrfd, + fname, NULL, SmimeCryptAlg, NULL, uids, NULL, + SmimeEncryptCommand); } static -pid_t smime_invoke_sign (FILE **smimein, FILE **smimeout, FILE **smimeerr, - int smimeinfd, int smimeoutfd, int smimeerrfd, - const char *fname) +pid_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); + smimeerrfd, fname, NULL, NULL, SmimeKeyToUse, + SmimeCertToUse, SmimeIntermediateToUse, + SmimeSignCommand); } -BODY *smime_build_smime_entity (BODY *a, char *certlist) +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]; @@ -1254,27 +1214,24 @@ BODY *smime_build_smime_entity (BODY *a, char *certlist) BODY *t; int err = 0, empty; pid_t thepid; - + mutt_mktemp (tempfile); - if ((fpout = safe_fopen (tempfile, "w+")) == NULL) - { + if ((fpout = safe_fopen (tempfile, "w+")) == NULL) { mutt_perror (tempfile); return (NULL); } mutt_mktemp (smimeerrfile); - if ((smimeerr = safe_fopen (smimeerrfile, "w+")) == NULL) - { + 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) - { + if ((fptmp = safe_fopen (smimeinfile, "w+")) == NULL) { mutt_perror (smimeinfile); mutt_unlink (tempfile); fclose (fpout); @@ -1283,14 +1240,15 @@ BODY *smime_build_smime_entity (BODY *a, char *certlist) } *certfile = '\0'; - while (1) - { - int off = mutt_strlen (certfile); + while (1) { + int off = str_len (certfile); + while (*++cert_end && *cert_end != '\n'); - if (!*cert_end) break; + if (!*cert_end) + break; *cert_end = '\0'; - snprintf (certfile+off, sizeof (certfile)-off, " %s/%s", - NONULL(SmimeCertificates), cert_start); + snprintf (certfile + off, sizeof (certfile) - off, " %s/%s", + NONULL (SmimeCertificates), cert_start); *cert_end = '\n'; cert_start = cert_end; cert_start++; @@ -1304,9 +1262,8 @@ BODY *smime_build_smime_entity (BODY *a, char *certlist) if ((thepid = smime_invoke_encrypt (&smimein, NULL, NULL, -1, - fileno (fpout), fileno (smimeerr), - smimeinfile, certfile)) == -1) - { + fileno (fpout), fileno (smimeerr), + smimeinfile, certfile)) == -1) { fclose (smimeerr); mutt_unlink (smimeinfile); mutt_unlink (certfile); @@ -1314,20 +1271,19 @@ BODY *smime_build_smime_entity (BODY *a, char *certlist) } 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) - { + while (fgets (buf, sizeof (buf) - 1, smimeerr) != NULL) { err = 1; fputs (buf, stdout); } @@ -1337,35 +1293,36 @@ BODY *smime_build_smime_entity (BODY *a, char *certlist) if (err) mutt_any_key_to_continue (NULL); - if (empty) - { + if (empty) { /* fatal error while trying to encrypt message */ - if (!err) mutt_any_key_to_continue _("No output from OpenSSL.."); + 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"); + t->subtype = str_dup ("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->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; - + t->d_filename = str_dup ("smime.p7m"); + t->filename = str_dup (tempfile); + t->unlink = 1; /*delete after sending the message */ + t->parts = 0; + t->next = 0; + return (t); } -BODY *smime_sign_message (BODY *a ) +BODY *smime_sign_message (BODY * a) { BODY *t; char buffer[LONG_STRING]; @@ -1374,56 +1331,52 @@ BODY *smime_sign_message (BODY *a ) int err = 0; int empty = 0; pid_t thepid; - char *intermediates = smime_get_field_from_db(NULL, SmimeDefaultKey, 1, 1); + 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 */ + if (!intermediates) { + mutt_message (_("Warning: Intermediate certificate not found.")); + intermediates = SmimeDefaultKey; /* so openssl won't complain in any case */ } - else - intermediates[mutt_strlen (intermediates)-1] = '\0'; - convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */ + convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */ mutt_mktemp (filetosign); - if ((sfp = safe_fopen (filetosign, "w+")) == NULL) - { + if ((sfp = safe_fopen (filetosign, "w+")) == NULL) { mutt_perror (filetosign); return NULL; } mutt_mktemp (signedfile); - if ((smimeout = safe_fopen (signedfile, "w+")) == NULL) - { + 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 (SmimeKeyToUse, sizeof (SmimeKeyToUse), "%s/%s", + NONULL (SmimeKeys), SmimeDefaultKey); snprintf (SmimeCertToUse, sizeof (SmimeCertToUse), "%s/%s", - NONULL(SmimeCertificates), SmimeDefaultKey); - + NONULL (SmimeCertificates), SmimeDefaultKey); + snprintf (SmimeIntermediateToUse, sizeof (SmimeIntermediateToUse), "%s/%s", - NONULL(SmimeCertificates), intermediates); - + NONULL (SmimeCertificates), intermediates); + if ((thepid = smime_invoke_sign (&smimein, NULL, &smimeerr, - -1, fileno (smimeout), -1, filetosign)) == -1) - { - mutt_perror _("Can't open OpenSSL subprocess!"); + -1, fileno (smimeout), -1, + filetosign)) == -1) { + mutt_perror (_("Can't open OpenSSL subprocess!")); + fclose (smimeout); mutt_unlink (signedfile); mutt_unlink (filetosign); @@ -1432,7 +1385,7 @@ BODY *smime_sign_message (BODY *a ) fputs (SmimePass, smimein); fputc ('\n', smimein); fclose (smimein); - + mutt_wait_filter (thepid); @@ -1440,8 +1393,7 @@ BODY *smime_sign_message (BODY *a ) err = 0; fflush (smimeerr); rewind (smimeerr); - while (fgets (buffer, sizeof (buffer) - 1, smimeerr) != NULL) - { + while (fgets (buffer, sizeof (buffer) - 1, smimeerr) != NULL) { err = 1; fputs (buffer, stdout); } @@ -1454,21 +1406,21 @@ BODY *smime_sign_message (BODY *a ) fclose (smimeout); mutt_unlink (filetosign); - + if (err) mutt_any_key_to_continue (NULL); - if (empty) - { + if (empty) { mutt_any_key_to_continue _("No output from OpenSSL..."); + mutt_unlink (signedfile); - return (NULL); /* fatal error while signing */ + return (NULL); /* fatal error while signing */ } t = mutt_new_body (); t->type = TYPEMULTIPART; - t->subtype = safe_strdup ("signed"); + t->subtype = str_dup ("signed"); t->encoding = ENC7BIT; t->use_disp = 0; t->disposition = DISPINLINE; @@ -1477,7 +1429,7 @@ BODY *smime_sign_message (BODY *a ) /* 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->parameter); t->parts = a; a = t; @@ -1485,13 +1437,13 @@ BODY *smime_sign_message (BODY *a ) 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->subtype = str_dup ("x-pkcs7-signature"); + t->filename = str_dup (signedfile); + t->d_filename = str_dup ("smime.p7s"); t->use_disp = 1; t->disposition = DISPATTACH; t->encoding = ENCBASE64; - t->unlink = 1; /* ok to remove this file after sending. */ + t->unlink = 1; /* ok to remove this file after sending. */ return (a); @@ -1512,32 +1464,34 @@ BODY *smime_sign_message (BODY *a ) static -pid_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) +pid_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)); + smimeerrfd, fname, sig_fname, NULL, NULL, NULL, NULL, + (opaque ? SmimeVerifyOpaqueCommand : + SmimeVerifyCommand)); } static -pid_t smime_invoke_decrypt (FILE **smimein, FILE **smimeout, FILE **smimeerr, - int smimeinfd, int smimeoutfd, int smimeerrfd, - const char *fname) +pid_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); + smimeerrfd, fname, NULL, NULL, SmimeKeyToUse, + SmimeCertToUse, NULL, SmimeDecryptCommand); } -int smime_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) +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; + FILE *fp = NULL, *smimeout = NULL, *smimeerr = NULL; pid_t thepid; int badsig = -1; @@ -1548,11 +1502,10 @@ int smime_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) snprintf (signedfile, sizeof (signedfile), "%s.sig", tempfile); - + /* decode to a tempfile, saving the original destination */ fp = s->fpout; - if ((s->fpout = safe_fopen (signedfile, "w")) == NULL) - { + if ((s->fpout = safe_fopen (signedfile, "w")) == NULL) { mutt_perror (signedfile); return -1; } @@ -1570,7 +1523,7 @@ int smime_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) mutt_decode_attachment (sigbdy, s); - sigbdy->length = ftell (s->fpout); + sigbdy->length = ftello (s->fpout); sigbdy->offset = 0; fclose (s->fpout); @@ -1581,63 +1534,60 @@ int smime_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) /* restore the prefix */ s->prefix = savePrefix; - + sigbdy->type = origType; - + mutt_mktemp (smimeerrfile); - if (!(smimeerr = safe_fopen (smimeerrfile, "w+"))) - { + if (!(smimeerr = safe_fopen (smimeerrfile, "w+"))) { mutt_perror (smimeerrfile); mutt_unlink (signedfile); return -1; } - + crypt_current_time (s, "OpenSSL"); - - if ((thepid = smime_invoke_verify (NULL, &smimeout, NULL, - -1, -1, fileno (smimeerr), - tempfile, signedfile, 0)) != -1) - { + + if ((thepid = smime_invoke_verify (NULL, &smimeout, NULL, + -1, -1, fileno (smimeerr), + tempfile, signedfile, 0)) != -1) { fflush (smimeout); fclose (smimeout); - + if (mutt_wait_filter (thepid)) badsig = -1; - else - { + else { char *line = NULL; int lineno = 0; size_t linelen; - + fflush (smimeerr); rewind (smimeerr); - + line = mutt_read_line (line, &linelen, smimeerr, &lineno); - if (linelen && !mutt_strcasecmp (line, "verification successful")) - badsig = 0; + if (linelen && !str_casecmp (line, "verification successful")) + badsig = 0; - FREE (&line); + mem_free (&line); } } - + fflush (smimeerr); rewind (smimeerr); mutt_copy_stream (smimeerr, s->fpout); fclose (smimeerr); - + state_attach_puts (_("[-- End of OpenSSL output --]\n\n"), s); - + mutt_unlink (signedfile); mutt_unlink (smimeerrfile); sigbdy->length = tmplength; sigbdy->offset = tmpoffset; - + /* restore the original source stream */ fclose (s->fpin); s->fpin = fp; - + return badsig; } @@ -1651,81 +1601,85 @@ int smime_verify_one (BODY *sigbdy, STATE *s, const char *tempfile) or an encrypted message. */ -static BODY *smime_handle_entity (BODY *m, STATE *s, FILE *outFile) +static BODY *smime_handle_entity (BODY * m, STATE * s, FILE * outFile) { - int len=0; + int len = 0; int c; long last_pos; char buf[HUGE_STRING]; char outfile[_POSIX_PATH_MAX], errfile[_POSIX_PATH_MAX]; char tmpfname[_POSIX_PATH_MAX]; char tmptmpfname[_POSIX_PATH_MAX]; - FILE *smimeout = NULL, *smimein=NULL, *smimeerr=NULL; - FILE *tmpfp=NULL, *tmpfp_buffer=NULL, *fpout=NULL; + FILE *smimeout = NULL, *smimein = NULL, *smimeerr = NULL; + FILE *tmpfp = NULL, *tmpfp_buffer = NULL, *fpout = NULL; struct stat info; - BODY *p=NULL; - pid_t thepid=-1; + BODY *p = NULL; + pid_t thepid = -1; unsigned int type = mutt_is_application_smime (m); - if (!(type & APPLICATION_SMIME)) return NULL; + if (!(type & APPLICATION_SMIME)) + return NULL; mutt_mktemp (outfile); - if ((smimeout = safe_fopen (outfile, "w+")) == NULL) - { + if ((smimeout = safe_fopen (outfile, "w+")) == NULL) { mutt_perror (outfile); return NULL; } - + mutt_mktemp (errfile); - if ((smimeerr = safe_fopen (errfile, "w+")) == NULL) - { + if ((smimeerr = safe_fopen (errfile, "w+")) == NULL) { mutt_perror (errfile); - fclose (smimeout); smimeout = NULL; + fclose (smimeout); + smimeout = NULL; return NULL; } mutt_unlink (errfile); - + mutt_mktemp (tmpfname); - if ((tmpfp = safe_fopen (tmpfname, "w+")) == NULL) - { + if ((tmpfp = safe_fopen (tmpfname, "w+")) == NULL) { mutt_perror (tmpfname); - fclose (smimeout); smimeout = NULL; - fclose (smimeerr); smimeerr = NULL; + fclose (smimeout); + smimeout = NULL; + fclose (smimeerr); + smimeerr = NULL; return NULL; } - fseek (s->fpin, m->offset, 0); + fseeko (s->fpin, m->offset, 0); last_pos = m->offset; - mutt_copy_bytes (s->fpin, tmpfp, m->length); + mutt_copy_bytes (s->fpin, tmpfp, m->length); fflush (tmpfp); fclose (tmpfp); if ((type & ENCRYPT) && (thepid = smime_invoke_decrypt (&smimein, NULL, NULL, -1, - fileno (smimeout), fileno (smimeerr), tmpfname)) == -1) - { - fclose (smimeout); smimeout = NULL; + fileno (smimeout), fileno (smimeerr), + tmpfname)) == -1) { + fclose (smimeout); + smimeout = NULL; mutt_unlink (tmpfname); - state_attach_puts (_("[-- Error: unable to create OpenSSL subprocess! --]\n"), s); + if (s->flags & M_DISPLAY) + state_attach_puts (_("[-- Error: unable to create OpenSSL subprocess! --]\n"), s); return NULL; } else if ((type & SIGNOPAQUE) && - (thepid = smime_invoke_verify (&smimein, NULL, NULL, -1, - fileno (smimeout), fileno (smimeerr), NULL, - tmpfname, SIGNOPAQUE)) == -1) - { - fclose (smimeout); smimeout = NULL; + (thepid = smime_invoke_verify (&smimein, NULL, NULL, -1, + fileno (smimeout), + fileno (smimeerr), NULL, tmpfname, + SIGNOPAQUE)) == -1) { + fclose (smimeout); + smimeout = NULL; mutt_unlink (tmpfname); - state_attach_puts (_("[-- Error: unable to create OpenSSL subprocess! --]\n"), s); + if (s->flags & M_DISPLAY) + state_attach_puts (_("[-- Error: unable to create OpenSSL subprocess! --]\n"), s); return NULL; } - - if (type & ENCRYPT) - { + + if (type & ENCRYPT) { if (!smime_valid_passphrase ()) smime_void_passphrase (); fputs (SmimePass, smimein); @@ -1733,114 +1687,104 @@ static BODY *smime_handle_entity (BODY *m, STATE *s, FILE *outFile) } fclose (smimein); - + mutt_wait_filter (thepid); mutt_unlink (tmpfname); - - if (s->flags & M_DISPLAY) - { + + if (s->flags & M_DISPLAY) { rewind (smimeerr); - - if ((c = fgetc (smimeerr)) != EOF) - { + + if ((c = fgetc (smimeerr)) != EOF) { ungetc (c, smimeerr); - + crypt_current_time (s, "OpenSSL"); mutt_copy_stream (smimeerr, s->fpout); state_attach_puts (_("[-- End of OpenSSL output --]\n\n"), s); } - + if (type & ENCRYPT) state_attach_puts (_("[-- The following data is S/MIME" " encrypted --]\n"), s); else - state_attach_puts (_("[-- The following data is S/MIME signed --]\n"), s); + state_attach_puts (_("[-- The following data is S/MIME signed --]\n"), + s); } - if (smimeout) - { + if (smimeout) { fflush (smimeout); rewind (smimeout); - - if (outFile) fpout = outFile; - else - { + + if (outFile) + fpout = outFile; + else { mutt_mktemp (tmptmpfname); - if ((fpout = safe_fopen (tmptmpfname, "w+")) == NULL) - { - mutt_perror(tmptmpfname); - fclose (smimeout); smimeout = NULL; - return NULL; + if ((fpout = safe_fopen (tmptmpfname, "w+")) == NULL) { + mutt_perror (tmptmpfname); + fclose (smimeout); + smimeout = NULL; + return NULL; } } - while (fgets (buf, sizeof (buf) - 1, smimeout) != NULL) - { - len = mutt_strlen (buf); - if (len > 1 && buf[len - 2] == '\r') - { - buf[len-2] = '\n'; - buf[len-1] = '\0'; + while (fgets (buf, sizeof (buf) - 1, smimeout) != NULL) { + len = str_len (buf); + if (len > 1 && buf[len - 2] == '\r') { + buf[len - 2] = '\n'; + buf[len - 1] = '\0'; } fputs (buf, fpout); } fflush (fpout); - rewind (fpout); + rewind (fpout); - if ((p = mutt_read_mime_header (fpout, 0)) != NULL) - { + if ((p = mutt_read_mime_header (fpout, 0)) != NULL) { fstat (fileno (fpout), &info); p->length = info.st_size - p->offset; - + mutt_parse_part (fpout, p); - if (s->fpout) - { - rewind (fpout); - tmpfp_buffer = s->fpin; - s->fpin = fpout; - mutt_body_handler (p, s); - s->fpin = tmpfp_buffer; + if (s->fpout) { + rewind (fpout); + tmpfp_buffer = s->fpin; + s->fpin = fpout; + mutt_body_handler (p, s); + s->fpin = tmpfp_buffer; } - + } fclose (smimeout); smimeout = NULL; mutt_unlink (outfile); - if (!outFile) - { + if (!outFile) { fclose (fpout); mutt_unlink (tmptmpfname); } fpout = NULL; } - if (s->flags & M_DISPLAY) - { + if (s->flags & M_DISPLAY) { if (type & ENCRYPT) state_attach_puts (_("\n[-- End of S/MIME encrypted data. --]\n"), s); else state_attach_puts (_("\n[-- End of S/MIME signed data. --]\n"), s); } - if (type & SIGNOPAQUE) - { + if (type & SIGNOPAQUE) { char *line = NULL; int lineno = 0; size_t linelen; - + rewind (smimeerr); - + line = mutt_read_line (line, &linelen, smimeerr, &lineno); - if (linelen && !mutt_strcasecmp (line, "verification successful")) + if (linelen && !str_casecmp (line, "verification successful")) m->goodsig = 1; - FREE (&line); + mem_free (&line); } - else - { + else { m->goodsig = p->goodsig; - m->badsig = p->badsig; + m->badsig = p->badsig; } fclose (smimeerr); @@ -1851,7 +1795,7 @@ static BODY *smime_handle_entity (BODY *m, STATE *s, FILE *outFile) -int smime_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) +int smime_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) { @@ -1860,21 +1804,21 @@ int smime_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) long tmpoffset = b->offset; size_t tmplength = b->length; int origType = b->type; - FILE *tmpfp=NULL; + FILE *tmpfp = NULL; + int rv = 0; if (!mutt_is_application_smime (b)) return -1; if (b->parts) return -1; - + memset (&s, 0, sizeof (s)); s.fpin = fpin; - fseek (s.fpin, b->offset, 0); + fseeko (s.fpin, b->offset, 0); mutt_mktemp (tempfile); - if ((tmpfp = safe_fopen (tempfile, "w+")) == NULL) - { + if ((tmpfp = safe_fopen (tempfile, "w+")) == NULL) { mutt_perror (tempfile); return (-1); } @@ -1883,38 +1827,170 @@ int smime_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur) s.fpout = tmpfp; mutt_decode_attachment (b, &s); fflush (tmpfp); - b->length = ftell (s.fpout); + b->length = ftello (s.fpout); b->offset = 0; rewind (tmpfp); s.fpin = tmpfp; s.fpout = 0; mutt_mktemp (tempfile); - if ((*fpout = safe_fopen (tempfile, "w+")) == NULL) - { + if ((*fpout = safe_fopen (tempfile, "w+")) == NULL) { mutt_perror (tempfile); - return (-1); + rv = -1; + goto bail; } mutt_unlink (tempfile); - *cur = smime_handle_entity (b, &s, *fpout); + if (!(*cur = smime_handle_entity (b, &s, *fpout))) { + rv = -1; + goto bail; + } + (*cur)->goodsig = b->goodsig; - (*cur)->badsig = b->badsig; + (*cur)->badsig = b->badsig; + +bail: b->type = origType; b->length = tmplength; b->offset = tmpoffset; - fclose (tmpfp); - - rewind (*fpout); - return (0); + safe_fclose (&tmpfp); + if (*fpout) + rewind (*fpout); + return (rv); } -void smime_application_smime_handler (BODY *m, STATE *s) +int smime_application_smime_handler (BODY * m, STATE * s) +{ + return smime_handle_entity (m, s, NULL) ? 0 : -1; +} + +int smime_send_menu (HEADER * msg, int *redraw) { - - smime_handle_entity (m, s, NULL); + char *p; + if (!(WithCrypto & APPLICATION_SMIME)) + return msg->security; + + switch (mutt_multi_choice + (_ + ("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, or (c)lear? "), + _("eswabfc"))) { + case 1: /* (e)ncrypt */ + msg->security |= ENCRYPT; + msg->security &= ~SIGN; + break; + + case 3: /* encrypt (w)ith */ + { + int choice = 0; + msg->security |= ENCRYPT; + + do { + /* I use "dra" because "123" is recognized anyway */ + switch (mutt_multi_choice (_("Choose algorithm family:" + " 1: DES, 2: RC2, 3: AES," + " or (c)lear? "), _("drac"))) { + case 1: + switch (choice = mutt_multi_choice (_("1: DES, 2: Triple-DES "), + _("dt"))) { + case 1: + str_replace (&SmimeCryptAlg, "des"); + break; + case 2: + str_replace (&SmimeCryptAlg, "des3"); + break; + } + break; + + case 2: + switch (choice = mutt_multi_choice (_("1: RC2-40, 2: RC2-64, 3: RC2-128 "), + _("468"))) { + case 1: + str_replace (&SmimeCryptAlg, "rc2-40"); + break; + case 2: + str_replace (&SmimeCryptAlg, "rc2-64"); + break; + case 3: + str_replace (&SmimeCryptAlg, "rc2-128"); + break; + } + break; + + case 3: + switch (choice = mutt_multi_choice (_("1: AES128, 2: AES192, 3: AES256 "), + _("895"))) { + case 1: + str_replace (&SmimeCryptAlg, "aes128"); + break; + case 2: + str_replace (&SmimeCryptAlg, "aes192"); + break; + case 3: + str_replace (&SmimeCryptAlg, "aes256"); + break; + } + break; + + case 4: /* (c)lear */ + mem_free (&SmimeCryptAlg); + /* fallback */ + case -1: /* Ctrl-G or Enter */ + choice = 0; + break; + } + } while (choice == -1); + } + break; + + case 2: /* (s)ign */ + + if (!SmimeDefaultKey) + mutt_message (_("Can't sign: No key specified. Use Sign As.")); + + else { + msg->security |= SIGN; + msg->security &= ~ENCRYPT; + } + break; + + case 4: /* sign (a)s */ + + if ((p = smime_ask_for_key (_("Sign as: "), NULL, 0))) { + str_replace (&SmimeDefaultKey, p); + + msg->security |= SIGN; + + /* probably need a different passphrase */ + crypt_smime_void_passphrase (); + } +#if 0 + else + msg->security &= ~SIGN; +#endif + + *redraw = REDRAW_FULL; + break; + + case 5: /* (b)oth */ + msg->security |= (ENCRYPT | SIGN); + break; + + case 6: /* (f)orget it */ + case 7: /* (c)lear */ + msg->security = 0; + break; + } + + if (msg->security && msg->security != APPLICATION_SMIME) + msg->security |= APPLICATION_SMIME; + else + msg->security = 0; + + return (msg->security); } + + #endif /* CRYPT_BACKEND_CLASSIC_SMIME */