X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=smime.c;h=24c237cb3c255ffbe4293b4cb75883828fe6b044;hp=fda19e957975e0a076c9675147b40fcd31bb7f6c;hb=9bd4cf1b49105dcc131bf722abcbb24fed67d4dc;hpb=6833ce8bdca2d64e14485118f2a4417b7e1cb1b1 diff --git a/smime.c b/smime.c index fda19e9..24c237c 100644 --- a/smime.c +++ b/smime.c @@ -1,6 +1,7 @@ /* * 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 @@ -17,6 +18,10 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + #include "mutt.h" #include "mutt_curses.h" #include "mutt_menu.h" @@ -48,7 +53,6 @@ #include "mutt_crypt.h" - struct smime_command_context { const char *key; /* %k */ const char *cryptalg; /* %a */ @@ -94,9 +98,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_password (_("Enter SMIME passphrase:"), SmimePass, sizeof (SmimePass)) == 0) + { + SmimeExptime = time (NULL) + SmimeTimeout; + return (1); + } + else + SmimeExptime = 0; + return 0; +} /* @@ -464,21 +485,22 @@ char *smime_get_field_from_db (char *mailbox, char *query, short public, short m 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); 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. @@ -531,8 +553,7 @@ char *smime_get_field_from_db (char *mailbox, char *query, short public, short m { found = 0; ask = 0; - FREE (&key); - key = NULL; + *key = '\0'; break; } else if (choice == M_NO) @@ -542,44 +563,46 @@ char *smime_get_field_from_db (char *mailbox, char *query, short public, short m } else if (choice == M_YES) { - snprintf (key,mutt_strlen(key)+1, fields[1]); + strfcpy (key, fields[1], sizeof (key)); 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]); - + 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]); + 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 && !(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]); + strfcpy (key, fields[1], sizeof (key)); } /* 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]); + strfcpy (key, fields[3], sizeof (key)); } } - fclose (fp); + safe_fclose (&fp); if (ask) { @@ -596,10 +619,7 @@ char *smime_get_field_from_db (char *mailbox, char *query, short public, short m 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) { @@ -610,11 +630,7 @@ char *smime_get_field_from_db (char *mailbox, char *query, short public, short m key, mailbox); choice = mutt_yesorno (prompt, M_NO); if (choice != M_YES) - { - FREE (&key); - key = NULL; - } - + *key = '\0'; } else if (key_trust_level == 'v' ) { @@ -625,13 +641,8 @@ char *smime_get_field_from_db (char *mailbox, char *query, short public, short m } - if (key) - { - key[mutt_strlen(key)+1] = '\0'; - key[mutt_strlen(key)] = '\n'; - } - - return key; + /* Note: safe_strdup ("") returns NULL. */ + return safe_strdup (key); } @@ -658,8 +669,6 @@ void _smime_getkeys (char *mailbox) if (k) { - k[mutt_strlen (k)-1] = '\0'; - /* the key used last time. */ if (*SmimeKeyToUse && !mutt_strcasecmp (k, SmimeKeyToUse + mutt_strlen (SmimeKeys)+1)) @@ -791,9 +800,9 @@ char *smime_findKeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc) return NULL; } - keylist_size += mutt_strlen (keyID) + 1; + keylist_size += mutt_strlen (keyID) + 2; safe_realloc (&keylist, keylist_size); - sprintf (keylist + keylist_used, "%s", keyID); /* __SPRINTF_CHECKED__ */ + sprintf (keylist + keylist_used, "%s\n", keyID); /* __SPRINTF_CHECKED__ */ keylist_used = mutt_strlen (keylist); rfc822_free_address (&addr); @@ -1381,8 +1390,6 @@ BODY *smime_sign_message (BODY *a ) 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. */ @@ -1917,4 +1924,95 @@ void smime_application_smime_handler (BODY *m, STATE *s) smime_handle_entity (m, s, NULL); } + +int smime_send_menu (HEADER *msg, int *redraw) +{ + 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 */ + msg->security |= ENCRYPT; + switch (mutt_multi_choice (_("1: DES, 2: Triple-DES, 3: RC2-40," + " 4: RC2-64, 5: RC2-128, or (f)orget it? "), + _("12345f"))) { + case 1: + mutt_str_replace (&SmimeCryptAlg, "des"); + break; + case 2: + mutt_str_replace (&SmimeCryptAlg, "des3"); + break; + case 3: + mutt_str_replace (&SmimeCryptAlg, "rc2-40"); + break; + case 4: + mutt_str_replace (&SmimeCryptAlg, "rc2-64"); + break; + case 5: + mutt_str_replace (&SmimeCryptAlg, "rc2-128"); + break; + case 6: /* forget it */ + break; + } + 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))) + { + p[mutt_strlen (p)-1] = '\0'; + mutt_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 */