-/* crypt-gpgme.c - GPGME based crypto operations
+/*
+ * Copyright notice from original mutt:
+ * crypt-gpgme.c - GPGME based crypto operations
* Copyright (C) 1996,1997 Michael R. Elkins <me@cs.hmc.edu>
* Copyright (C) 1998,1999,2000 Thomas Roessler <roessler@guug.de>
* Copyright (C) 2001 Thomas Roessler <roessler@guug.de>
* Oliver Ehli <elmy@acm.org>
* Copyright (C) 2002, 2003, 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
* Type definitions.
*/
-struct crypt_cache
-{
+struct crypt_cache {
char *what;
char *dflt;
struct crypt_cache *next;
};
-struct dn_array_s
-{
+struct dn_array_s {
char *key;
char *value;
};
/* We work based on user IDs, getting from a user ID to the key is
check and does not need any memory (gpgme uses reference counting). */
-typedef struct crypt_keyinfo
-{
+typedef struct crypt_keyinfo {
struct crypt_keyinfo *next;
gpgme_key_t kobj;
- int idx; /* and the user ID at this index */
- const char *uid; /* and for convenience point to this user ID */
- unsigned int flags; /* global and per uid flags (for convenience)*/
+ int idx; /* and the user ID at this index */
+ const char *uid; /* and for convenience point to this user ID */
+ unsigned int flags; /* global and per uid flags (for convenience) */
} crypt_key_t;
-typedef struct crypt_entry
-{
+typedef struct crypt_entry {
size_t num;
crypt_key_t *key;
} crypt_entry_t;
*/
/* return true when S pints to a didgit or letter. */
-static int
-digit_or_letter (const unsigned char *s)
+static int digit_or_letter (const unsigned char *s)
{
- return ( (*s >= '0' && *s < '9')
- || (*s >= 'A' && *s <= 'Z')
- || (*s >= 'a' && *s <= 'z'));
+ return ((*s >= '0' && *s < '9')
+ || (*s >= 'A' && *s <= 'Z')
+ || (*s >= 'a' && *s <= 'z'));
}
/* Print the utf-8 encoded string BUF of length LEN bytes to stream
FP. Convert the character set. */
-static void
-print_utf8 (FILE *fp, const char *buf, size_t len)
+static void print_utf8 (FILE * fp, const char *buf, size_t len)
{
char *tstr;
- tstr = safe_malloc (len+1);
+ tstr = safe_malloc (len + 1);
memcpy (tstr, buf, len);
tstr[len] = 0;
mutt_convert_string (&tstr, "utf-8", Charset, M_ICONV_HOOK_FROM);
/* Return the keyID for the key K. Note that this string is valid as
long as K is valid */
-static const char *crypt_keyid (crypt_key_t *k)
+static const char *crypt_keyid (crypt_key_t * k)
{
const char *s = "????????";
- if (k->kobj && k->kobj->subkeys)
- {
- s = k->kobj->subkeys->keyid;
- if ((! option (OPTPGPLONGIDS)) && (strlen (s) == 16))
- /* Return only the short keyID. */
- s += 8;
- }
+ if (k->kobj && k->kobj->subkeys) {
+ s = k->kobj->subkeys->keyid;
+ if ((!option (OPTPGPLONGIDS)) && (strlen (s) == 16))
+ /* Return only the short keyID. */
+ s += 8;
+ }
return s;
}
/* Return the hexstring fingerprint from the key K. */
-static const char *crypt_fpr (crypt_key_t *k)
+static const char *crypt_fpr (crypt_key_t * k)
{
const char *s = "";
return 'd';
else if (flags & KEYFLAG_CRITICAL)
return 'c';
- else
+ else
return ' ';
}
/* Return a copy of KEY. */
-static crypt_key_t *crypt_copy_key (crypt_key_t *key)
+static crypt_key_t *crypt_copy_key (crypt_key_t * key)
{
crypt_key_t *k;
/* Release all the keys at the address of KEYLIST and set the address
to NULL. */
-static void crypt_free_key (crypt_key_t **keylist)
+static void crypt_free_key (crypt_key_t ** keylist)
{
- while (*keylist)
- {
- crypt_key_t *k = (*keylist)->next;
- FREE (&k);
- *keylist = k;
- }
+ while (*keylist) {
+ crypt_key_t *k = (*keylist)->next;
+
+ FREE (&k);
+ *keylist = k;
+ }
}
/* Return trute when key K is valid. */
-static int crypt_key_is_valid (crypt_key_t *k)
+static int crypt_key_is_valid (crypt_key_t * k)
{
if (k->flags & KEYFLAG_CANTUSE)
return 0;
}
/* Return true whe validity of KEY is sufficient. */
-static int crypt_id_is_strong (crypt_key_t *key)
+static int crypt_id_is_strong (crypt_key_t * key)
{
gpgme_validity_t val = GPGME_VALIDITY_UNKNOWN;
gpgme_user_id_t uid = NULL;
return 1;
for (i = 0, uid = key->kobj->uids; (i < key->idx) && uid;
- i++, uid = uid->next)
- ;
+ i++, uid = uid->next);
if (uid)
val = uid->validity;
- switch (val)
- {
- case GPGME_VALIDITY_UNKNOWN:
- case GPGME_VALIDITY_UNDEFINED:
- case GPGME_VALIDITY_NEVER:
- case GPGME_VALIDITY_MARGINAL:
- is_strong = 0;
- break;
+ switch (val) {
+ case GPGME_VALIDITY_UNKNOWN:
+ case GPGME_VALIDITY_UNDEFINED:
+ case GPGME_VALIDITY_NEVER:
+ case GPGME_VALIDITY_MARGINAL:
+ is_strong = 0;
+ break;
- case GPGME_VALIDITY_FULL:
- case GPGME_VALIDITY_ULTIMATE:
- is_strong = 1;
- break;
- }
+ case GPGME_VALIDITY_FULL:
+ case GPGME_VALIDITY_ULTIMATE:
+ is_strong = 1;
+ break;
+ }
return is_strong;
}
/* Return true when the KEY is valid, i.e. not marked as unusable. */
-static int crypt_id_is_valid (crypt_key_t *key)
+static int crypt_id_is_valid (crypt_key_t * key)
{
- return ! (key->flags & KEYFLAG_CANTUSE);
+ return !(key->flags & KEYFLAG_CANTUSE);
}
/* Return a bit vector describing how well the addresses ADDR and
U_ADDR match and whether KEY is valid. */
-static int crypt_id_matches_addr (ADDRESS *addr, ADDRESS *u_addr,
- crypt_key_t *key)
+static int crypt_id_matches_addr (ADDRESS * addr, ADDRESS * u_addr,
+ crypt_key_t * key)
{
int rv = 0;
-
+
if (crypt_id_is_valid (key))
rv |= CRYPT_KV_VALID;
if (crypt_id_is_strong (key))
rv |= CRYPT_KV_STRONGID;
-
+
if (addr->mailbox && u_addr->mailbox
&& mutt_strcasecmp (addr->mailbox, u_addr->mailbox) == 0)
rv |= CRYPT_KV_ADDR;
-
+
if (addr->personal && u_addr->personal
&& mutt_strcasecmp (addr->personal, u_addr->personal) == 0)
rv |= CRYPT_KV_STRING;
-
+
return rv;
}
gpgme_ctx_t ctx;
err = gpgme_new (&ctx);
- if (err)
- {
- mutt_error ("error creating gpgme context: %s\n", gpgme_strerror (err));
+ if (err) {
+ mutt_error ("error creating gpgme context: %s\n", gpgme_strerror (err));
+ sleep (2);
+ mutt_exit (1);
+ }
+
+ if (for_smime) {
+ err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
+ if (err) {
+ mutt_error ("error enabling CMS protocol: %s\n", gpgme_strerror (err));
sleep (2);
mutt_exit (1);
}
-
- if (for_smime)
- {
- err = gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
- if (err)
- {
- mutt_error ("error enabling CMS protocol: %s\n",
- gpgme_strerror (err));
- sleep (2);
- mutt_exit (1);
- }
- }
+ }
return ctx;
}
gpgme_data_t data;
err = gpgme_data_new (&data);
- if (err)
- {
- mutt_error ("error creating gpgme data object: %s\n",
- gpgme_strerror (err));
- sleep (2);
- mutt_exit (1);
- }
+ if (err) {
+ mutt_error ("error creating gpgme data object: %s\n",
+ gpgme_strerror (err));
+ sleep (2);
+ mutt_exit (1);
+ }
return data;
}
/* Create a new GPGME Data object from the mail body A. With CONVERT
passed as true, the lines are converted to CR,LF if required.
Return NULL on error or the gpgme_data_t object on success. */
-static gpgme_data_t body_to_data_object (BODY *a, int convert)
+static gpgme_data_t body_to_data_object (BODY * a, int convert)
{
char tempfile[_POSIX_PATH_MAX];
FILE *fptmp;
int err = 0;
gpgme_data_t data;
-
+
mutt_mktemp (tempfile);
fptmp = safe_fopen (tempfile, "w+");
- if (!fptmp)
- {
- mutt_perror (tempfile);
- return NULL;
- }
+ if (!fptmp) {
+ mutt_perror (tempfile);
+ return NULL;
+ }
mutt_write_mime_header (a, fptmp);
fputc ('\n', fptmp);
mutt_write_mime_body (a, fptmp);
- if (convert)
- {
- int c, hadcr = 0;
- unsigned char buf[1];
-
- data = create_gpgme_data ();
- rewind (fptmp);
- while ((c = fgetc (fptmp)) != EOF)
- {
- if (c == '\r')
- hadcr = 1;
- else
- {
- if (c == '\n' && !hadcr)
- {
- buf[0] = '\r';
- gpgme_data_write (data, buf, 1);
- }
-
- hadcr = 0;
- }
- /* FIXME: This is quite suboptimal */
- buf[0] = c;
+ if (convert) {
+ int c, hadcr = 0;
+ unsigned char buf[1];
+
+ data = create_gpgme_data ();
+ rewind (fptmp);
+ while ((c = fgetc (fptmp)) != EOF) {
+ if (c == '\r')
+ hadcr = 1;
+ else {
+ if (c == '\n' && !hadcr) {
+ buf[0] = '\r';
gpgme_data_write (data, buf, 1);
}
- fclose(fptmp);
- gpgme_data_seek (data, 0, SEEK_SET);
- }
- else
- {
- fclose(fptmp);
- err = gpgme_data_new_from_file (&data, tempfile, 1);
+
+ hadcr = 0;
+ }
+ /* FIXME: This is quite suboptimal */
+ buf[0] = c;
+ gpgme_data_write (data, buf, 1);
}
+ fclose (fptmp);
+ gpgme_data_seek (data, 0, SEEK_SET);
+ }
+ else {
+ fclose (fptmp);
+ err = gpgme_data_new_from_file (&data, tempfile, 1);
+ }
unlink (tempfile);
- if (err)
- {
- mutt_error ("error allocating data object: %s\n", gpgme_strerror (err));
- return NULL;
- }
+ if (err) {
+ mutt_error ("error allocating data object: %s\n", gpgme_strerror (err));
+ return NULL;
+ }
return data;
}
/* Create a GPGME data object from the stream FP but limit the object
to LENGTH bytes starting at OFFSET bytes from the beginning of the
file. */
-static gpgme_data_t file_to_data_object (FILE *fp, long offset, long length)
+static gpgme_data_t file_to_data_object (FILE * fp, long offset, long length)
{
int err = 0;
gpgme_data_t data;
-
+
err = gpgme_data_new_from_filepart (&data, NULL, fp, offset, length);
- if (err)
- {
- mutt_error ("error allocating data object: %s\n", gpgme_strerror (err));
- return NULL;
- }
+ if (err) {
+ mutt_error ("error allocating data object: %s\n", gpgme_strerror (err));
+ return NULL;
+ }
return data;
}
/* Write a GPGME data object to the stream FP. */
-static int data_object_to_stream (gpgme_data_t data, FILE *fp)
+static int data_object_to_stream (gpgme_data_t data, FILE * fp)
{
int err;
char buf[4096], *p;
err = ((gpgme_data_seek (data, 0, SEEK_SET) == -1)
? gpgme_error_from_errno (errno) : 0);
- if (err)
- {
- mutt_error ("error rewinding data object: %s\n", gpgme_strerror (err));
- return -1;
- }
-
- while ((nread = gpgme_data_read (data, buf, sizeof (buf))))
- {
- /* fixme: we are not really converting CRLF to LF but just
- skipping CR. Doing it correctly needs a more complex logic */
- for (p=buf; nread; p++, nread--)
- {
- if (*p != '\r')
- putc (*p, fp);
- }
+ if (err) {
+ mutt_error ("error rewinding data object: %s\n", gpgme_strerror (err));
+ return -1;
+ }
- if (ferror (fp))
- {
- mutt_perror ("[tempfile]");
- return -1;
- }
+ while ((nread = gpgme_data_read (data, buf, sizeof (buf)))) {
+ /* fixme: we are not really converting CRLF to LF but just
+ skipping CR. Doing it correctly needs a more complex logic */
+ for (p = buf; nread; p++, nread--) {
+ if (*p != '\r')
+ putc (*p, fp);
}
- if (nread == -1)
- {
- mutt_error ("error reading data object: %s\n", strerror (errno));
+
+ if (ferror (fp)) {
+ mutt_perror ("[tempfile]");
return -1;
}
+ }
+ if (nread == -1) {
+ mutt_error ("error reading data object: %s\n", strerror (errno));
+ return -1;
+ }
return 0;
}
/* Copy a data object to a newly created temporay file and return that
filename. Caller must free. With RET_FP not NULL, don't close the
stream but return it there. */
-static char *data_object_to_tempfile (gpgme_data_t data, FILE **ret_fp)
+static char *data_object_to_tempfile (gpgme_data_t data, FILE ** ret_fp)
{
int err;
char tempfile[_POSIX_PATH_MAX];
mutt_mktemp (tempfile);
fp = safe_fopen (tempfile, "w+");
- if (!fp)
- {
- mutt_perror (tempfile);
- return NULL;
- }
+ if (!fp) {
+ mutt_perror (tempfile);
+ return NULL;
+ }
err = ((gpgme_data_seek (data, 0, SEEK_SET) == -1)
? gpgme_error_from_errno (errno) : 0);
- if (!err)
- {
- char buf[4096];
-
- while ((nread = gpgme_data_read (data, buf, sizeof (buf))))
- {
- if (fwrite (buf, nread, 1, fp) != 1)
- {
- mutt_perror (tempfile);
- fclose (fp);
- unlink (tempfile);
- return NULL;
- }
- }
+ if (!err) {
+ char buf[4096];
+
+ while ((nread = gpgme_data_read (data, buf, sizeof (buf)))) {
+ if (fwrite (buf, nread, 1, fp) != 1) {
+ mutt_perror (tempfile);
+ fclose (fp);
+ unlink (tempfile);
+ return NULL;
+ }
}
+ }
if (ret_fp)
rewind (fp);
else
fclose (fp);
- if (nread == -1)
- {
- mutt_error ("error reading data object: %s\n", gpgme_strerror (err));
- unlink (tempfile);
- fclose (fp);
- return NULL;
- }
+ if (nread == -1) {
+ mutt_error ("error reading data object: %s\n", gpgme_strerror (err));
+ unlink (tempfile);
+ fclose (fp);
+ return NULL;
+ }
if (ret_fp)
*ret_fp = fp;
return safe_strdup (tempfile);
gpgme_ctx_t context = NULL;
err = gpgme_new (&context);
- if (! err)
+ if (!err)
err = gpgme_set_protocol (context, protocol);
- if (! err)
- {
- s = keylist;
- do {
- while (*s == ' ')
- s++;
- for (i=0; *s && *s != ' ' && i < sizeof(buf)-1;)
- buf[i++] = *s++;
- buf[i] = 0;
- if (*buf)
- {
- if (i>1 && buf[i-1] == '!')
- {
- /* The user selected to override the valididy of that
- key. */
- buf[i-1] = 0;
-
- err = gpgme_get_key (context, buf, &key, 0);
- if (! err)
- key->uids->validity = GPGME_VALIDITY_FULL;
- buf[i-1] = '!';
- }
- else
- err = gpgme_get_key (context, buf, &key, 0);
-
- if (! err)
- {
- safe_realloc (&rset, sizeof (*rset) * (rset_n + 1));
- rset[rset_n++] = key;
- }
- else
- {
- mutt_error ("error adding recipient `%s': %s\n",
- buf, gpgme_strerror (err));
- FREE (&rset);
- return NULL;
- }
- }
- } while (*s);
- }
+ if (!err) {
+ s = keylist;
+ do {
+ while (*s == ' ')
+ s++;
+ for (i = 0; *s && *s != ' ' && i < sizeof (buf) - 1;)
+ buf[i++] = *s++;
+ buf[i] = 0;
+ if (*buf) {
+ if (i > 1 && buf[i - 1] == '!') {
+ /* The user selected to override the valididy of that
+ key. */
+ buf[i - 1] = 0;
+
+ err = gpgme_get_key (context, buf, &key, 0);
+ if (!err)
+ key->uids->validity = GPGME_VALIDITY_FULL;
+ buf[i - 1] = '!';
+ }
+ else
+ err = gpgme_get_key (context, buf, &key, 0);
+
+ if (!err) {
+ safe_realloc (&rset, sizeof (*rset) * (rset_n + 1));
+ rset[rset_n++] = key;
+ }
+ else {
+ mutt_error ("error adding recipient `%s': %s\n",
+ buf, gpgme_strerror (err));
+ FREE (&rset);
+ return NULL;
+ }
+ }
+ } while (*s);
+ }
/* NULL terminate. */
safe_realloc (&rset, sizeof (*rset) * (rset_n + 1));
rset[rset_n++] = NULL;
-
+
if (context)
gpgme_release (context);
/* Make sure that the correct signer is set. Returns 0 on success. */
static int set_signer (gpgme_ctx_t ctx, int for_smime)
{
- char *signid = for_smime ? SmimeDefaultKey: PgpSignAs;
+ char *signid = for_smime ? SmimeDefaultKey : PgpSignAs;
gpgme_error_t err;
gpgme_ctx_t listctx;
gpgme_key_t key, key2;
err = gpgme_op_keylist_start (listctx, signid, 1);
if (!err)
err = gpgme_op_keylist_next (listctx, &key);
- if (err)
- {
- gpgme_release (listctx);
- mutt_error (_("secret key `%s' not found: %s\n"),
- signid, gpgme_strerror (err));
- return -1;
- }
+ if (err) {
+ gpgme_release (listctx);
+ mutt_error (_("secret key `%s' not found: %s\n"),
+ signid, gpgme_strerror (err));
+ return -1;
+ }
err = gpgme_op_keylist_next (listctx, &key2);
- if (!err)
- {
- gpgme_key_release (key);
- gpgme_key_release (key2);
- gpgme_release (listctx);
- mutt_error (_("ambiguous specfication of secret key `%s'\n"),
- signid);
- return -1;
- }
+ if (!err) {
+ gpgme_key_release (key);
+ gpgme_key_release (key2);
+ gpgme_release (listctx);
+ mutt_error (_("ambiguous specfication of secret key `%s'\n"), signid);
+ return -1;
+ }
gpgme_op_keylist_end (listctx);
gpgme_release (listctx);
gpgme_signers_clear (ctx);
err = gpgme_signers_add (ctx, key);
gpgme_key_release (key);
- if (err)
- {
- mutt_error (_("error setting secret key `%s': %s\n"),
- signid, gpgme_strerror (err));
- return -1;
- }
+ if (err) {
+ mutt_error (_("error setting secret key `%s': %s\n"),
+ signid, gpgme_strerror (err));
+ return -1;
+ }
return 0;
}
enciphered text. With USE_SMIME set to true, the smime backend is
used. With COMBINED_SIGNED a PGP message is signed and
encrypted. Returns NULL in case of error */
-static char *encrypt_gpgme_object (gpgme_data_t plaintext, gpgme_key_t *rset,
+static char *encrypt_gpgme_object (gpgme_data_t plaintext, gpgme_key_t * rset,
int use_smime, int combined_signed)
{
int err;
char *outfile;
ctx = create_gpgme_context (use_smime);
- if (!use_smime)
- gpgme_set_armor (ctx, 1);
+ if (!use_smime)
+ gpgme_set_armor (ctx, 1);
ciphertext = create_gpgme_data ();
- if (combined_signed)
- {
- if (set_signer (ctx, use_smime))
- {
- gpgme_data_release (ciphertext);
- gpgme_release (ctx);
- return NULL;
- }
- err = gpgme_op_encrypt_sign (ctx, rset, GPGME_ENCRYPT_ALWAYS_TRUST,
- plaintext, ciphertext);
+ if (combined_signed) {
+ if (set_signer (ctx, use_smime)) {
+ gpgme_data_release (ciphertext);
+ gpgme_release (ctx);
+ return NULL;
}
+ err = gpgme_op_encrypt_sign (ctx, rset, GPGME_ENCRYPT_ALWAYS_TRUST,
+ plaintext, ciphertext);
+ }
else
err = gpgme_op_encrypt (ctx, rset, GPGME_ENCRYPT_ALWAYS_TRUST,
plaintext, ciphertext);
mutt_need_hard_redraw ();
- if (err)
- {
- mutt_error ("error encrypting data: %s\n", gpgme_strerror (err));
- gpgme_data_release (ciphertext);
- gpgme_release (ctx);
- return NULL;
- }
+ if (err) {
+ mutt_error ("error encrypting data: %s\n", gpgme_strerror (err));
+ gpgme_data_release (ciphertext);
+ gpgme_release (ctx);
+ return NULL;
+ }
gpgme_release (ctx);
*buf = 0;
result = gpgme_op_sign_result (ctx);
- if (result)
- {
- algorithm_name = gpgme_hash_algo_name (result->signatures->hash_algo);
- if (algorithm_name)
- {
- strncpy (buf, algorithm_name, buflen - 1);
- buf[buflen - 1] = 0;
- }
+ if (result) {
+ algorithm_name = gpgme_hash_algo_name (result->signatures->hash_algo);
+ if (algorithm_name) {
+ strncpy (buf, algorithm_name, buflen - 1);
+ buf[buflen - 1] = 0;
}
+ }
- return *buf? 0:-1;
+ return *buf ? 0 : -1;
}
-static void print_time(time_t t, STATE *s)
+static void print_time (time_t t, STATE * s)
{
char p[STRING];
/* Sign the MESSAGE in body A either using OpenPGP or S/MIME when
USE_SMIME is passed as true. Returns the new body or NULL on
error. */
-static BODY *sign_message (BODY *a, int use_smime)
+static BODY *sign_message (BODY * a, int use_smime)
{
BODY *t;
char *sigfile;
gpgme_ctx_t ctx;
gpgme_data_t message, signature;
- convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */
+ convert_to_7bit (a); /* Signed data _must_ be in 7-bit format. */
message = body_to_data_object (a, 1);
if (!message)
- return NULL;
+ return NULL;
signature = create_gpgme_data ();
ctx = create_gpgme_context (use_smime);
if (!use_smime)
gpgme_set_armor (ctx, 1);
- if (set_signer (ctx, use_smime))
- {
- gpgme_data_release (signature);
- gpgme_release (ctx);
- return NULL;
- }
+ if (set_signer (ctx, use_smime)) {
+ gpgme_data_release (signature);
+ gpgme_release (ctx);
+ return NULL;
+ }
- err = gpgme_op_sign (ctx, message, signature, GPGME_SIG_MODE_DETACH );
+ err = gpgme_op_sign (ctx, message, signature, GPGME_SIG_MODE_DETACH);
mutt_need_hard_redraw ();
gpgme_data_release (message);
- if (err)
- {
- gpgme_data_release (signature);
- gpgme_release (ctx);
- mutt_error ("error signing data: %s\n", gpgme_strerror (err));
- return NULL;
- }
+ if (err) {
+ gpgme_data_release (signature);
+ gpgme_release (ctx);
+ mutt_error ("error signing data: %s\n", gpgme_strerror (err));
+ return NULL;
+ }
sigfile = data_object_to_tempfile (signature, NULL);
gpgme_data_release (signature);
- if (!sigfile)
- {
- gpgme_release (ctx);
- return NULL;
- }
+ if (!sigfile) {
+ gpgme_release (ctx);
+ return NULL;
+ }
t = mutt_new_body ();
t->type = TYPEMULTIPART;
mutt_generate_boundary (&t->parameter);
mutt_set_parameter ("protocol",
- use_smime? "application/pkcs7-signature"
- : "application/pgp-signature",
- &t->parameter);
+ use_smime ? "application/pkcs7-signature"
+ : "application/pgp-signature", &t->parameter);
/* Get the micalg from gpgme. Old gpgme versions don't support this
for S/MIME so we assume sha-1 in this case. */
if (!get_micalg (ctx, buf, sizeof buf))
t->parts->next = mutt_new_body ();
t = t->parts->next;
t->type = TYPEAPPLICATION;
- if (use_smime)
- {
- t->subtype = safe_strdup ("pkcs7-signature");
- mutt_set_parameter ("name", "smime.p7s", &t->parameter);
- t->encoding = ENCBASE64;
- t->use_disp = 1;
- t->disposition = DISPATTACH;
- t->d_filename = safe_strdup ("smime.p7s");
- }
- else
- {
- t->subtype = safe_strdup ("pgp-signature");
- t->use_disp = 0;
- t->disposition = DISPINLINE;
- t->encoding = ENC7BIT;
- }
+ if (use_smime) {
+ t->subtype = safe_strdup ("pkcs7-signature");
+ mutt_set_parameter ("name", "smime.p7s", &t->parameter);
+ t->encoding = ENCBASE64;
+ t->use_disp = 1;
+ t->disposition = DISPATTACH;
+ t->d_filename = safe_strdup ("smime.p7s");
+ }
+ else {
+ t->subtype = safe_strdup ("pgp-signature");
+ t->use_disp = 0;
+ t->disposition = DISPINLINE;
+ t->encoding = ENC7BIT;
+ }
t->filename = sigfile;
- t->unlink = 1; /* ok to remove this file after sending. */
+ t->unlink = 1; /* ok to remove this file after sending. */
return a;
}
-BODY *pgp_gpgme_sign_message (BODY *a)
+BODY *pgp_gpgme_sign_message (BODY * a)
{
return sign_message (a, 0);
}
-BODY *smime_gpgme_sign_message (BODY *a)
+BODY *smime_gpgme_sign_message (BODY * a)
{
return sign_message (a, 1);
}
/* Encrypt the mail body A to all keys given as space separated keyids
or fingerprints in KEYLIST and return the encrypted body. */
-BODY *pgp_gpgme_encrypt_message (BODY *a, char *keylist, int sign)
+BODY *pgp_gpgme_encrypt_message (BODY * a, char *keylist, int sign)
{
char *outfile = NULL;
BODY *t;
gpgme_key_t *rset = NULL;
gpgme_data_t plaintext;
-
+
rset = create_recipient_set (keylist, GPGME_PROTOCOL_OpenPGP);
if (!rset)
return NULL;
-
+
if (sign)
convert_to_7bit (a);
plaintext = body_to_data_object (a, 0);
- if (!plaintext)
- {
- FREE (&rset);
- return NULL;
- }
-
+ if (!plaintext) {
+ FREE (&rset);
+ return NULL;
+ }
+
outfile = encrypt_gpgme_object (plaintext, rset, 0, sign);
gpgme_data_release (plaintext);
FREE (&rset);
if (!outfile)
- return NULL;
+ return NULL;
t = mutt_new_body ();
t->type = TYPEMULTIPART;
t->use_disp = 0;
t->disposition = DISPINLINE;
- mutt_generate_boundary(&t->parameter);
- mutt_set_parameter("protocol", "application/pgp-encrypted", &t->parameter);
-
+ mutt_generate_boundary (&t->parameter);
+ mutt_set_parameter ("protocol", "application/pgp-encrypted", &t->parameter);
+
t->parts = mutt_new_body ();
t->parts->type = TYPEAPPLICATION;
t->parts->subtype = safe_strdup ("pgp-encrypted");
t->parts->next->filename = outfile;
t->parts->next->use_disp = 1;
t->parts->next->disposition = DISPINLINE;
- t->parts->next->unlink = 1; /* delete after sending the message */
+ t->parts->next->unlink = 1; /* delete after sending the message */
t->parts->next->d_filename = safe_strdup ("msg.asc"); /* non pgp/mime
can save */
/* Encrypt the mail body A to all keys given as space separated
fingerprints in KEYLIST and return the S/MIME encrypted body. */
-BODY *smime_gpgme_build_smime_entity (BODY *a, char *keylist)
+BODY *smime_gpgme_build_smime_entity (BODY * a, char *keylist)
{
char *outfile = NULL;
BODY *t;
return NULL;
plaintext = body_to_data_object (a, 0);
- if (!plaintext)
- {
- FREE (&rset);
- return NULL;
- }
+ if (!plaintext) {
+ FREE (&rset);
+ return NULL;
+ }
outfile = encrypt_gpgme_object (plaintext, rset, 1, 0);
gpgme_data_release (plaintext);
FREE (&rset);
- if (!outfile)
- return NULL;
+ if (!outfile)
+ return NULL;
t = mutt_new_body ();
t->type = TYPEAPPLICATION;
t->subtype = safe_strdup ("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 = outfile;
- t->unlink = 1; /*delete after sending the message */
- t->parts=0;
- t->next=0;
-
+ t->unlink = 1; /*delete after sending the message */
+ t->parts = 0;
+ t->next = 0;
+
return t;
}
Return 1 if there is is a severe warning.
*/
static int show_sig_summary (unsigned long sum,
- gpgme_ctx_t ctx, gpgme_key_t key, int idx,
- STATE *s)
+ gpgme_ctx_t ctx, gpgme_key_t key, int idx,
+ STATE * s)
{
int severe = 0;
- if ((sum & GPGME_SIGSUM_KEY_REVOKED))
- {
- state_attach_puts (_("Warning: One of the keys has been revoked\n"),s);
- severe = 1;
- }
+ if ((sum & GPGME_SIGSUM_KEY_REVOKED)) {
+ state_attach_puts (_("Warning: One of the keys has been revoked\n"), s);
+ severe = 1;
+ }
- if ((sum & GPGME_SIGSUM_KEY_EXPIRED))
- {
- time_t at = key->subkeys->expires ? key->subkeys->expires : 0;
- if (at)
- {
- state_attach_puts (_("Warning: The key used to create the "
- "signature expired at: "), s);
- print_time (at , s);
- state_attach_puts ("\n", s);
- }
- else
- state_attach_puts (_("Warning: At least one certification key "
- "has expired\n"), s);
- }
+ if ((sum & GPGME_SIGSUM_KEY_EXPIRED)) {
+ time_t at = key->subkeys->expires ? key->subkeys->expires : 0;
- if ((sum & GPGME_SIGSUM_SIG_EXPIRED))
- {
- gpgme_verify_result_t result;
- gpgme_signature_t sig;
- unsigned int i;
-
- result = gpgme_op_verify_result (ctx);
-
- for (sig = result->signatures, i = 0; sig && (i < idx);
- sig = sig->next, i++)
- ;
-
- state_attach_puts (_("Warning: The signature expired at: "), s);
- print_time (sig ? sig->exp_timestamp : 0, s);
+ if (at) {
+ state_attach_puts (_("Warning: The key used to create the "
+ "signature expired at: "), s);
+ print_time (at, s);
state_attach_puts ("\n", s);
}
+ else
+ state_attach_puts (_("Warning: At least one certification key "
+ "has expired\n"), s);
+ }
+
+ if ((sum & GPGME_SIGSUM_SIG_EXPIRED)) {
+ gpgme_verify_result_t result;
+ gpgme_signature_t sig;
+ unsigned int i;
+
+ result = gpgme_op_verify_result (ctx);
+
+ for (sig = result->signatures, i = 0; sig && (i < idx);
+ sig = sig->next, i++);
+
+ state_attach_puts (_("Warning: The signature expired at: "), s);
+ print_time (sig ? sig->exp_timestamp : 0, s);
+ state_attach_puts ("\n", s);
+ }
if ((sum & GPGME_SIGSUM_KEY_MISSING))
state_attach_puts (_("Can't verify due to a missing "
"key or certificate\n"), s);
- if ((sum & GPGME_SIGSUM_CRL_MISSING))
- {
- state_attach_puts (_("The CRL is not available\n"), s);
- severe = 1;
- }
+ if ((sum & GPGME_SIGSUM_CRL_MISSING)) {
+ state_attach_puts (_("The CRL is not available\n"), s);
+ severe = 1;
+ }
- if ((sum & GPGME_SIGSUM_CRL_TOO_OLD))
- {
- state_attach_puts (_("Available CRL is too old\n"), s);
- severe = 1;
- }
+ if ((sum & GPGME_SIGSUM_CRL_TOO_OLD)) {
+ state_attach_puts (_("Available CRL is too old\n"), s);
+ severe = 1;
+ }
if ((sum & GPGME_SIGSUM_BAD_POLICY))
state_attach_puts (_("A policy requirement was not met\n"), s);
- if ((sum & GPGME_SIGSUM_SYS_ERROR))
- {
- const char *t0 = NULL, *t1 = NULL;
- gpgme_verify_result_t result;
- gpgme_signature_t sig;
- unsigned int i;
-
- state_attach_puts (_("A system error occured"), s );
-
- /* Try to figure out some more detailed system error information. */
- result = gpgme_op_verify_result (ctx);
- for (sig = result->signatures, i = 0; sig && (i < idx);
- sig = sig->next, i++)
- ;
- if (sig)
- {
- t0 = "";
- t1 = sig->wrong_key_usage ? "Wrong_Key_Usage" : "";
- }
-
- if (t0 || t1)
- {
- state_attach_puts (": ", s);
- if (t0)
- state_attach_puts (t0, s);
- if (t1 && !(t0 && !strcmp (t0, t1)))
- {
- if (t0)
- state_attach_puts (",", s);
- state_attach_puts (t1, s);
- }
- }
- state_attach_puts ("\n", s);
+ if ((sum & GPGME_SIGSUM_SYS_ERROR)) {
+ const char *t0 = NULL, *t1 = NULL;
+ gpgme_verify_result_t result;
+ gpgme_signature_t sig;
+ unsigned int i;
+
+ state_attach_puts (_("A system error occured"), s);
+
+ /* Try to figure out some more detailed system error information. */
+ result = gpgme_op_verify_result (ctx);
+ for (sig = result->signatures, i = 0; sig && (i < idx);
+ sig = sig->next, i++);
+ if (sig) {
+ t0 = "";
+ t1 = sig->wrong_key_usage ? "Wrong_Key_Usage" : "";
+ }
+
+ if (t0 || t1) {
+ state_attach_puts (": ", s);
+ if (t0)
+ state_attach_puts (t0, s);
+ if (t1 && !(t0 && !strcmp (t0, t1))) {
+ if (t0)
+ state_attach_puts (",", s);
+ state_attach_puts (t1, s);
+ }
}
+ state_attach_puts ("\n", s);
+ }
return severe;
}
-static void show_fingerprint (gpgme_key_t key, STATE *state)
+static void show_fingerprint (gpgme_key_t key, STATE * state)
{
const char *s;
int i, is_pgp;
return;
is_pgp = (key->protocol == GPGME_PROTOCOL_OpenPGP);
- buf = safe_malloc ( strlen (prefix) + strlen(s) * 4 + 2 );
- strcpy (buf, prefix); /* __STRCPY_CHECKED__ */
+ buf = safe_malloc (strlen (prefix) + strlen (s) * 4 + 2);
+ strcpy (buf, prefix); /* __STRCPY_CHECKED__ */
p = buf + strlen (buf);
- if (is_pgp && strlen (s) == 40)
- { /* PGP v4 style formatted. */
- for (i=0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++)
- {
- *p++ = s[0];
- *p++ = s[1];
- *p++ = s[2];
- *p++ = s[3];
- *p++ = ' ';
- if (i == 4)
- *p++ = ' ';
- }
+ if (is_pgp && strlen (s) == 40) { /* PGP v4 style formatted. */
+ for (i = 0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++) {
+ *p++ = s[0];
+ *p++ = s[1];
+ *p++ = s[2];
+ *p++ = s[3];
+ *p++ = ' ';
+ if (i == 4)
+ *p++ = ' ';
}
- else
- {
- for (i=0; *s && s[1] && s[2]; s += 2, i++)
- {
- *p++ = s[0];
- *p++ = s[1];
- *p++ = is_pgp? ' ':':';
- if (is_pgp && i == 7)
- *p++ = ' ';
- }
+ }
+ else {
+ for (i = 0; *s && s[1] && s[2]; s += 2, i++) {
+ *p++ = s[0];
+ *p++ = s[1];
+ *p++ = is_pgp ? ' ' : ':';
+ if (is_pgp && i == 7)
+ *p++ = ' ';
}
+ }
/* just in case print remaining odd digits */
for (; *s; s++)
}
/* Show the valididy of a key used for one signature. */
-static void show_one_sig_validity (gpgme_ctx_t ctx, int idx, STATE *s)
+static void show_one_sig_validity (gpgme_ctx_t ctx, int idx, STATE * s)
{
gpgme_verify_result_t result = NULL;
gpgme_signature_t sig = NULL;
if (result)
for (sig = result->signatures; sig && (idx > 0); sig = sig->next, idx--);
- switch (sig ? sig->validity : 0)
- {
- case GPGME_VALIDITY_UNKNOWN:
- txt = _("WARNING: We have NO indication whether "
- "the key belongs to the person named "
- "as shown above\n");
- break;
- case GPGME_VALIDITY_UNDEFINED:
- break;
- case GPGME_VALIDITY_NEVER:
- txt = _("WARNING: The key does NOT BELONG to "
- "the person named as shown above\n");
- break;
- case GPGME_VALIDITY_MARGINAL:
- txt = _("WARNING: It is NOT certain that the key "
- "belongs to the person named as shown above\n");
- break;
- case GPGME_VALIDITY_FULL:
- case GPGME_VALIDITY_ULTIMATE:
- txt = NULL;
- break;
- }
+ switch (sig ? sig->validity : 0) {
+ case GPGME_VALIDITY_UNKNOWN:
+ txt = _("WARNING: We have NO indication whether "
+ "the key belongs to the person named " "as shown above\n");
+ break;
+ case GPGME_VALIDITY_UNDEFINED:
+ break;
+ case GPGME_VALIDITY_NEVER:
+ txt = _("WARNING: The key does NOT BELONG to "
+ "the person named as shown above\n");
+ break;
+ case GPGME_VALIDITY_MARGINAL:
+ txt = _("WARNING: It is NOT certain that the key "
+ "belongs to the person named as shown above\n");
+ break;
+ case GPGME_VALIDITY_FULL:
+ case GPGME_VALIDITY_ULTIMATE:
+ txt = NULL;
+ break;
+ }
if (txt)
state_attach_puts (txt, s);
}
Return values are: 0 for normal procession, 1 for a bad signature,
2 for a signature with a warning or -1 for no more signature. */
-static int show_one_sig_status (gpgme_ctx_t ctx, int idx, STATE *s)
+static int show_one_sig_status (gpgme_ctx_t ctx, int idx, STATE * s)
{
time_t created;
const char *fpr, *uid;
gpgme_error_t err = GPG_ERR_NO_ERROR;
result = gpgme_op_verify_result (ctx);
- if (result)
- {
- /* FIXME: this code should use a static variable and remember
- the current position in the list of signatures, IMHO.
- -moritz. */
-
- for (i = 0, sig = result->signatures; sig && (i < idx);
- i++, sig = sig->next)
- ;
- if (! sig)
- return -1; /* Signature not found. */
-
- if (signature_key)
- {
- gpgme_key_release (signature_key);
- signature_key = NULL;
- }
-
- created = sig->timestamp;
- fpr = sig->fpr;
- sum = sig->summary;
-
- if (gpg_err_code (sig->status) != GPG_ERR_NO_ERROR)
- anybad = 1;
-
- err = gpgme_get_key (ctx, fpr, &key, 0); /* secret key? */
- if (! err)
- {
- uid = (key->uids && key->uids->uid) ? key->uids->uid : "[?]";
- if (! signature_key)
- signature_key = key;
- }
- else
- {
- key = NULL; /* Old gpgme versions did not set KEY to NULL on
- error. Do it here to avoid a double free. */
- uid = "[?]";
- }
-
- if (!s || !s->fpout || !(s->flags & M_DISPLAY))
- ; /* No state information so no way to print anything. */
- else if (err)
- {
- state_attach_puts (_("Error getting key information: "), s);
- state_attach_puts ( gpg_strerror (err), s );
- state_attach_puts ("\n", s);
- anybad = 1;
- }
- else if ((sum & GPGME_SIGSUM_GREEN))
- {
- state_attach_puts (_("Good signature from: "), s);
- state_attach_puts (uid, s);
- state_attach_puts ("\n", s);
- for (i = 1, uids = key->uids; uids; i++, uids = uids->next)
- {
- if (i == 1)
- /* Skip primary UID. */
- continue;
- if (uids->revoked)
- continue;
- state_attach_puts (_(" aka: "), s);
- state_attach_puts (uids->uid, s);
- state_attach_puts ("\n", s);
- }
- state_attach_puts (_(" created: "), s);
- print_time (created, s);
- state_attach_puts ("\n", s);
- if (show_sig_summary (sum, ctx, key, idx, s))
- anywarn = 1;
- show_one_sig_validity (ctx, idx, s);
- }
- else if ((sum & GPGME_SIGSUM_RED))
- {
- state_attach_puts (_("*BAD* signature claimed to be from: "), s);
- state_attach_puts (uid, s);
- state_attach_puts ("\n", s);
- show_sig_summary (sum, ctx, key, idx, s);
- }
- else if (!anybad && key && (key->protocol == GPGME_PROTOCOL_OpenPGP))
- { /* We can't decide (yellow) but this is a PGP key with a good
- signature, so we display what a PGP user expects: The name,
- fingerprint and the key validity (which is neither fully or
- ultimate). */
- state_attach_puts (_("Good signature from: "), s);
- state_attach_puts (uid, s);
- state_attach_puts ("\n", s);
- state_attach_puts (_(" created: "), s);
- print_time (created, s);
- state_attach_puts ("\n", s);
- show_one_sig_validity (ctx, idx, s);
- show_fingerprint (key,s);
- if (show_sig_summary (sum, ctx, key, idx, s))
- anywarn = 1;
- }
- else /* can't decide (yellow) */
- {
- state_attach_puts (_("Error checking signature"), s);
- state_attach_puts ("\n", s);
- show_sig_summary (sum, ctx, key, idx, s);
- }
-
- if (key != signature_key)
- gpgme_key_release (key);
- }
+ if (result) {
+ /* FIXME: this code should use a static variable and remember
+ the current position in the list of signatures, IMHO.
+ -moritz. */
- return anybad ? 1 : anywarn ? 2 : 0;
+ for (i = 0, sig = result->signatures; sig && (i < idx);
+ i++, sig = sig->next);
+ if (!sig)
+ return -1; /* Signature not found. */
+
+ if (signature_key) {
+ gpgme_key_release (signature_key);
+ signature_key = NULL;
+ }
+
+ created = sig->timestamp;
+ fpr = sig->fpr;
+ sum = sig->summary;
+
+ if (gpg_err_code (sig->status) != GPG_ERR_NO_ERROR)
+ anybad = 1;
+
+ err = gpgme_get_key (ctx, fpr, &key, 0); /* secret key? */
+ if (!err) {
+ uid = (key->uids && key->uids->uid) ? key->uids->uid : "[?]";
+ if (!signature_key)
+ signature_key = key;
+ }
+ else {
+ key = NULL; /* Old gpgme versions did not set KEY to NULL on
+ error. Do it here to avoid a double free. */
+ uid = "[?]";
+ }
+
+ if (!s || !s->fpout || !(s->flags & M_DISPLAY)); /* No state information so no way to print anything. */
+ else if (err) {
+ state_attach_puts (_("Error getting key information: "), s);
+ state_attach_puts (gpg_strerror (err), s);
+ state_attach_puts ("\n", s);
+ anybad = 1;
+ }
+ else if ((sum & GPGME_SIGSUM_GREEN)) {
+ state_attach_puts (_("Good signature from: "), s);
+ state_attach_puts (uid, s);
+ state_attach_puts ("\n", s);
+ for (i = 1, uids = key->uids; uids; i++, uids = uids->next) {
+ if (i == 1)
+ /* Skip primary UID. */
+ continue;
+ if (uids->revoked)
+ continue;
+ state_attach_puts (_(" aka: "), s);
+ state_attach_puts (uids->uid, s);
+ state_attach_puts ("\n", s);
+ }
+ state_attach_puts (_(" created: "), s);
+ print_time (created, s);
+ state_attach_puts ("\n", s);
+ if (show_sig_summary (sum, ctx, key, idx, s))
+ anywarn = 1;
+ show_one_sig_validity (ctx, idx, s);
+ }
+ else if ((sum & GPGME_SIGSUM_RED)) {
+ state_attach_puts (_("*BAD* signature claimed to be from: "), s);
+ state_attach_puts (uid, s);
+ state_attach_puts ("\n", s);
+ show_sig_summary (sum, ctx, key, idx, s);
+ }
+ else if (!anybad && key && (key->protocol == GPGME_PROTOCOL_OpenPGP)) { /* We can't decide (yellow) but this is a PGP key with a good
+ signature, so we display what a PGP user expects: The name,
+ fingerprint and the key validity (which is neither fully or
+ ultimate). */
+ state_attach_puts (_("Good signature from: "), s);
+ state_attach_puts (uid, s);
+ state_attach_puts ("\n", s);
+ state_attach_puts (_(" created: "), s);
+ print_time (created, s);
+ state_attach_puts ("\n", s);
+ show_one_sig_validity (ctx, idx, s);
+ show_fingerprint (key, s);
+ if (show_sig_summary (sum, ctx, key, idx, s))
+ anywarn = 1;
+ }
+ else { /* can't decide (yellow) */
+
+ state_attach_puts (_("Error checking signature"), s);
+ state_attach_puts ("\n", s);
+ show_sig_summary (sum, ctx, key, idx, s);
+ }
+
+ if (key != signature_key)
+ gpgme_key_release (key);
+ }
+
+ return anybad ? 1 : anywarn ? 2 : 0;
}
/* Do the actual verification step. With IS_SMIME set to true we
assume S/MIME (surprise!) */
-static int verify_one (BODY *sigbdy, STATE *s,
+static int verify_one (BODY * sigbdy, STATE * s,
const char *tempfile, int is_smime)
{
int badsig = -1;
gpgme_data_set_encoding (signature, GPGME_DATA_ENCODING_BASE64);
err = gpgme_data_new_from_file (&message, tempfile, 1);
- if (err)
- {
- gpgme_data_release (signature);
- mutt_error ("error allocating data object: %s\n", gpgme_strerror (err));
- return -1;
- }
+ if (err) {
+ gpgme_data_release (signature);
+ mutt_error ("error allocating data object: %s\n", gpgme_strerror (err));
+ return -1;
+ }
ctx = create_gpgme_context (is_smime);
/* Note: We don't need a current time output because GPGME avoids
err = gpgme_op_verify (ctx, signature, message, NULL);
mutt_need_hard_redraw ();
- if (err)
- {
- char buf[200];
-
- snprintf (buf, sizeof(buf)-1,
- _("Error: verification failed: %s\n"),
- gpgme_strerror (err));
- state_attach_puts (buf, s);
- }
- else
- { /* Verification succeeded, see what the result is. */
- int res, idx;
- int anybad = 0;
-
- if (signature_key)
- {
- gpgme_key_release (signature_key);
- signature_key = NULL;
- }
-
- for(idx=0; (res = show_one_sig_status (ctx, idx, s)) != -1; idx++)
- {
- if (res == 1)
- anybad = 1;
- else if (res == 2)
- anywarn = 2;
- }
- if (!anybad)
- badsig = 0;
+ if (err) {
+ char buf[200];
+
+ snprintf (buf, sizeof (buf) - 1,
+ _("Error: verification failed: %s\n"), gpgme_strerror (err));
+ state_attach_puts (buf, s);
+ }
+ else { /* Verification succeeded, see what the result is. */
+ int res, idx;
+ int anybad = 0;
+
+ if (signature_key) {
+ gpgme_key_release (signature_key);
+ signature_key = NULL;
}
- if (!badsig)
- {
- gpgme_verify_result_t result;
- gpgme_sig_notation_t notation;
- gpgme_signature_t signature;
+ for (idx = 0; (res = show_one_sig_status (ctx, idx, s)) != -1; idx++) {
+ if (res == 1)
+ anybad = 1;
+ else if (res == 2)
+ anywarn = 2;
+ }
+ if (!anybad)
+ badsig = 0;
+ }
- result = gpgme_op_verify_result (ctx);
- if (result)
- {
- for (signature = result->signatures; signature;
- signature = signature->next)
- {
- if (signature->notations)
- {
- state_attach_puts ("*** Begin Notation (signature by: ", s);
- state_attach_puts (signature->fpr, s);
- state_attach_puts (") ***\n", s);
- for (notation = signature->notations; notation;
- notation = notation->next)
- {
- if (notation->name)
- {
- state_attach_puts (notation->name, s);
- state_attach_puts ("=", s);
- }
- if (notation->value)
- {
- state_attach_puts (notation->value, s);
- if (!(*notation->value
- && (notation->value[strlen (notation->value)-1]=='\n')))
- state_attach_puts ("\n", s);
- }
- }
- state_attach_puts ("*** End Notation ***\n", s);
- }
- }
+ if (!badsig) {
+ gpgme_verify_result_t result;
+ gpgme_sig_notation_t notation;
+ gpgme_signature_t signature;
+
+ result = gpgme_op_verify_result (ctx);
+ if (result) {
+ for (signature = result->signatures; signature;
+ signature = signature->next) {
+ if (signature->notations) {
+ state_attach_puts ("*** Begin Notation (signature by: ", s);
+ state_attach_puts (signature->fpr, s);
+ state_attach_puts (") ***\n", s);
+ for (notation = signature->notations; notation;
+ notation = notation->next) {
+ if (notation->name) {
+ state_attach_puts (notation->name, s);
+ state_attach_puts ("=", s);
+ }
+ if (notation->value) {
+ state_attach_puts (notation->value, s);
+ if (!(*notation->value
+ && (notation->value[strlen (notation->value) - 1] ==
+ '\n')))
+ state_attach_puts ("\n", s);
+ }
+ }
+ state_attach_puts ("*** End Notation ***\n", s);
+ }
}
}
+ }
gpgme_release (ctx);
-
+
state_attach_puts (_("[-- End signature information --]\n\n"), s);
dprint (1, (debugfile, "verify_one: returning %d.\n", badsig));
-
- return badsig? 1: anywarn? 2 : 0;
+
+ return badsig ? 1 : anywarn ? 2 : 0;
}
-int pgp_gpgme_verify_one (BODY *sigbdy, STATE *s, const char *tempfile)
+int pgp_gpgme_verify_one (BODY * sigbdy, STATE * s, const char *tempfile)
{
return verify_one (sigbdy, s, tempfile, 0);
}
-int smime_gpgme_verify_one (BODY *sigbdy, STATE *s, const char *tempfile)
+int smime_gpgme_verify_one (BODY * sigbdy, STATE * s, const char *tempfile)
{
return verify_one (sigbdy, s, tempfile, 1);
}
a flag in R_IS_SIGNED to indicate whether this is a combined
encrypted and signed message, for S/MIME it returns true when it is
not a encrypted but a signed message. */
-static BODY *decrypt_part (BODY *a, STATE *s, FILE *fpout, int is_smime,
+static BODY *decrypt_part (BODY * a, STATE * s, FILE * fpout, int is_smime,
int *r_is_signed)
{
struct stat info;
ctx = create_gpgme_context (is_smime);
- restart:
+restart:
/* Make a data object from the body, create context etc. */
ciphertext = file_to_data_object (s->fpin, a->offset, a->length);
if (!ciphertext)
plaintext = create_gpgme_data ();
/* Do the decryption or the verification in case of the S/MIME hack. */
- if ((! is_smime) || maybe_signed)
+ if ((!is_smime) || maybe_signed) {
+ if (!is_smime)
+ err = gpgme_op_decrypt_verify (ctx, ciphertext, plaintext);
+ else if (maybe_signed)
+ err = gpgme_op_verify (ctx, ciphertext, NULL, plaintext);
+
{
- if (! is_smime)
- err = gpgme_op_decrypt_verify (ctx, ciphertext, plaintext);
- else if (maybe_signed)
- err = gpgme_op_verify (ctx, ciphertext, NULL, plaintext);
+ /* Check wether signatures have been verified. */
+ gpgme_verify_result_t verify_result = gpgme_op_verify_result (ctx);
- {
- /* Check wether signatures have been verified. */
- gpgme_verify_result_t verify_result = gpgme_op_verify_result (ctx);
- if (verify_result->signatures)
- sig_stat = 1;
- }
+ if (verify_result->signatures)
+ sig_stat = 1;
}
+ }
else
err = gpgme_op_decrypt (ctx, ciphertext, plaintext);
gpgme_data_release (ciphertext);
- if (err)
- {
- if (is_smime && !maybe_signed
- && gpg_err_code (err) == GPG_ERR_NO_DATA)
- {
- /* Check whether this might be a signed message despite what
- the mime header told us. Retry then. gpgsm returns the
- error information "unsupported Algorithm '?'" but gpgme
- will not store this unknown algorithm, thus we test that
- it has not been set. */
- gpgme_decrypt_result_t result;
-
- result = gpgme_op_decrypt_result (ctx);
- if (!result->unsupported_algorithm)
- {
- maybe_signed = 1;
- gpgme_data_release (plaintext);
- goto restart;
- }
- }
- mutt_need_hard_redraw ();
- if ((s->flags & M_DISPLAY))
- {
- char buf[200];
-
- snprintf (buf, sizeof(buf)-1,
- _("[-- Error: decryption failed: %s --]\n\n"),
- gpgme_strerror (err));
- state_attach_puts (buf, s);
- }
- gpgme_data_release (plaintext);
- gpgme_release (ctx);
- return NULL;
+ if (err) {
+ if (is_smime && !maybe_signed && gpg_err_code (err) == GPG_ERR_NO_DATA) {
+ /* Check whether this might be a signed message despite what
+ the mime header told us. Retry then. gpgsm returns the
+ error information "unsupported Algorithm '?'" but gpgme
+ will not store this unknown algorithm, thus we test that
+ it has not been set. */
+ gpgme_decrypt_result_t result;
+
+ result = gpgme_op_decrypt_result (ctx);
+ if (!result->unsupported_algorithm) {
+ maybe_signed = 1;
+ gpgme_data_release (plaintext);
+ goto restart;
+ }
+ }
+ mutt_need_hard_redraw ();
+ if ((s->flags & M_DISPLAY)) {
+ char buf[200];
+
+ snprintf (buf, sizeof (buf) - 1,
+ _("[-- Error: decryption failed: %s --]\n\n"),
+ gpgme_strerror (err));
+ state_attach_puts (buf, s);
+ }
+ gpgme_data_release (plaintext);
+ gpgme_release (ctx);
+ return NULL;
}
mutt_need_hard_redraw ();
/* Read the output from GPGME, and make sure to change CRLF to LF,
otherwise read_mime_header has a hard time parsing the message. */
- if (data_object_to_stream (plaintext, fpout))
- {
- gpgme_data_release (plaintext);
- gpgme_release (ctx);
- return NULL;
- }
+ if (data_object_to_stream (plaintext, fpout)) {
+ gpgme_data_release (plaintext);
+ gpgme_release (ctx);
+ return NULL;
+ }
gpgme_data_release (plaintext);
a->is_signed_data = 0;
- if (sig_stat)
- {
- int res, idx;
- int anybad = 0;
-
- if (maybe_signed)
- a->is_signed_data = 1;
- if(r_is_signed)
- *r_is_signed = -1; /* A signature exists. */
-
- if ((s->flags & M_DISPLAY))
- state_attach_puts (_("[-- Begin signature "
- "information --]\n"), s);
- for(idx = 0; (res = show_one_sig_status (ctx, idx, s)) != -1; idx++)
- {
- if (res == 1)
- anybad = 1;
- else if (res == 2)
- anywarn = 1;
- }
- if (!anybad && idx && r_is_signed && *r_is_signed)
- *r_is_signed = anywarn? 2:1; /* Good signature. */
-
- if ((s->flags & M_DISPLAY))
- state_attach_puts (_("[-- End signature "
- "information --]\n\n"), s);
- }
- gpgme_release (ctx); ctx = NULL;
+ if (sig_stat) {
+ int res, idx;
+ int anybad = 0;
+
+ if (maybe_signed)
+ a->is_signed_data = 1;
+ if (r_is_signed)
+ *r_is_signed = -1; /* A signature exists. */
+
+ if ((s->flags & M_DISPLAY))
+ state_attach_puts (_("[-- Begin signature " "information --]\n"), s);
+ for (idx = 0; (res = show_one_sig_status (ctx, idx, s)) != -1; idx++) {
+ if (res == 1)
+ anybad = 1;
+ else if (res == 2)
+ anywarn = 1;
+ }
+ if (!anybad && idx && r_is_signed && *r_is_signed)
+ *r_is_signed = anywarn ? 2 : 1; /* Good signature. */
+
+ if ((s->flags & M_DISPLAY))
+ state_attach_puts (_("[-- End signature " "information --]\n\n"), s);
+ }
+ gpgme_release (ctx);
+ ctx = NULL;
fflush (fpout);
rewind (fpout);
tattach = mutt_read_mime_header (fpout, 0);
- if (tattach)
- {
- /*
- * Need to set the length of this body part.
- */
- fstat (fileno (fpout), &info);
- tattach->length = info.st_size - tattach->offset;
-
- tattach->warnsig = anywarn;
+ if (tattach) {
+ /*
+ * Need to set the length of this body part.
+ */
+ fstat (fileno (fpout), &info);
+ tattach->length = info.st_size - tattach->offset;
- /* See if we need to recurse on this MIME part. */
- mutt_parse_part (fpout, tattach);
- }
+ tattach->warnsig = anywarn;
+
+ /* See if we need to recurse on this MIME part. */
+ mutt_parse_part (fpout, tattach);
+ }
return tattach;
}
/* Decrypt a PGP/MIME message in FPIN and B and return a new body and
the stream in CUR and FPOUT. Returns 0 on success. */
-int pgp_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
+int pgp_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur)
{
char tempfile[_POSIX_PATH_MAX];
STATE s;
BODY *first_part = b;
int is_signed;
-
+
first_part->goodsig = 0;
first_part->warnsig = 0;
- if(!mutt_is_multipart_encrypted(b))
+ if (!mutt_is_multipart_encrypted (b))
return -1;
- if(!b->parts || !b->parts->next)
+ if (!b->parts || !b->parts->next)
return -1;
-
+
b = b->parts->next;
-
+
memset (&s, 0, sizeof (s));
s.fpin = fpin;
mutt_mktemp (tempfile);
- if (!(*fpout = safe_fopen (tempfile, "w+")))
- {
+ if (!(*fpout = safe_fopen (tempfile, "w+"))) {
mutt_perror (tempfile);
return -1;
}
rewind (*fpout);
if (is_signed > 0)
first_part->goodsig = 1;
-
- return *cur? 0:-1;
+
+ return *cur ? 0 : -1;
}
/* Decrypt a S/MIME message in FPIN and B and return a new body and
the stream in CUR and FPOUT. Returns 0 on success. */
-int smime_gpgme_decrypt_mime (FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
+int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b,
+ BODY ** cur)
{
char tempfile[_POSIX_PATH_MAX];
STATE s;
- FILE *tmpfp=NULL;
+ FILE *tmpfp = NULL;
int is_signed;
long saved_b_offset;
size_t saved_b_length;
if (b->parts)
return -1;
-
+
/* Decode the body - we need to pass binary CMS to the
backend. The backend allows for Base64 encoded data but it does
not allow for QP which I have seen in some messages. So better
saved_b_length = b->length;
memset (&s, 0, sizeof (s));
s.fpin = fpin;
- fseek (s.fpin, b->offset, 0);
+ fseek (s.fpin, b->offset, 0);
mutt_mktemp (tempfile);
- if (!(tmpfp = safe_fopen (tempfile, "w+")))
- {
- mutt_perror (tempfile);
- return -1;
- }
+ if (!(tmpfp = safe_fopen (tempfile, "w+"))) {
+ mutt_perror (tempfile);
+ return -1;
+ }
mutt_unlink (tempfile);
s.fpout = tmpfp;
s.fpin = tmpfp;
s.fpout = 0;
mutt_mktemp (tempfile);
- if (!(*fpout = safe_fopen (tempfile, "w+")))
- {
- mutt_perror (tempfile);
- return -1;
- }
+ if (!(*fpout = safe_fopen (tempfile, "w+"))) {
+ mutt_perror (tempfile);
+ return -1;
+ }
mutt_unlink (tempfile);
*cur = decrypt_part (b, &s, *fpout, 1, &is_signed);
b->offset = saved_b_offset;
fclose (tmpfp);
rewind (*fpout);
- if (*cur && !is_signed && !(*cur)->parts && mutt_is_application_smime (*cur))
- {
- /* Assume that this is a opaque signed s/mime message. This is
- an ugly way of doing it but we have anyway a problem with
- arbitrary encoded S/MIME messages: Only the outer part may be
- encrypted. The entire mime parsing should be revamped,
- probably by keeping the temportary files so that we don't
- need to decrypt them all the time. Inner parts of an
- encrypted part can then pint into this file and tehre won't
- never be a need to decrypt again. This needs a partial
- rewrite of the MIME engine. */
- BODY *bb = *cur;
- BODY *tmp_b;
-
- saved_b_type = bb->type;
- saved_b_offset = bb->offset;
- saved_b_length = bb->length;
- memset (&s, 0, sizeof (s));
- s.fpin = *fpout;
- fseek (s.fpin, bb->offset, 0);
- mutt_mktemp (tempfile);
- if (!(tmpfp = safe_fopen (tempfile, "w+")))
- {
- mutt_perror (tempfile);
- return -1;
- }
- mutt_unlink (tempfile);
-
- s.fpout = tmpfp;
- mutt_decode_attachment (bb, &s);
- fflush (tmpfp);
- bb->length = ftell (s.fpout);
- bb->offset = 0;
- rewind (tmpfp);
- fclose (*fpout);
-
- memset (&s, 0, sizeof (s));
- s.fpin = tmpfp;
- s.fpout = 0;
- mutt_mktemp (tempfile);
- if (!(*fpout = safe_fopen (tempfile, "w+")))
- {
- mutt_perror (tempfile);
- return -1;
- }
- mutt_unlink (tempfile);
-
- tmp_b = decrypt_part (bb, &s, *fpout, 1, &is_signed);
- if (tmp_b)
- tmp_b->goodsig = is_signed > 0;
- bb->type = saved_b_type;
- bb->length = saved_b_length;
- bb->offset = saved_b_offset;
- fclose (tmpfp);
- rewind (*fpout);
- mutt_free_body (cur);
- *cur = tmp_b;
+ if (*cur && !is_signed && !(*cur)->parts
+ && mutt_is_application_smime (*cur)) {
+ /* Assume that this is a opaque signed s/mime message. This is
+ an ugly way of doing it but we have anyway a problem with
+ arbitrary encoded S/MIME messages: Only the outer part may be
+ encrypted. The entire mime parsing should be revamped,
+ probably by keeping the temportary files so that we don't
+ need to decrypt them all the time. Inner parts of an
+ encrypted part can then pint into this file and tehre won't
+ never be a need to decrypt again. This needs a partial
+ rewrite of the MIME engine. */
+ BODY *bb = *cur;
+ BODY *tmp_b;
+
+ saved_b_type = bb->type;
+ saved_b_offset = bb->offset;
+ saved_b_length = bb->length;
+ memset (&s, 0, sizeof (s));
+ s.fpin = *fpout;
+ fseek (s.fpin, bb->offset, 0);
+ mutt_mktemp (tempfile);
+ if (!(tmpfp = safe_fopen (tempfile, "w+"))) {
+ mutt_perror (tempfile);
+ return -1;
+ }
+ mutt_unlink (tempfile);
+
+ s.fpout = tmpfp;
+ mutt_decode_attachment (bb, &s);
+ fflush (tmpfp);
+ bb->length = ftell (s.fpout);
+ bb->offset = 0;
+ rewind (tmpfp);
+ fclose (*fpout);
+
+ memset (&s, 0, sizeof (s));
+ s.fpin = tmpfp;
+ s.fpout = 0;
+ mutt_mktemp (tempfile);
+ if (!(*fpout = safe_fopen (tempfile, "w+"))) {
+ mutt_perror (tempfile);
+ return -1;
}
- return *cur? 0:-1;
+ mutt_unlink (tempfile);
+
+ tmp_b = decrypt_part (bb, &s, *fpout, 1, &is_signed);
+ if (tmp_b)
+ tmp_b->goodsig = is_signed > 0;
+ bb->type = saved_b_type;
+ bb->length = saved_b_length;
+ bb->offset = saved_b_offset;
+ fclose (tmpfp);
+ rewind (*fpout);
+ mutt_free_body (cur);
+ *cur = tmp_b;
+ }
+ return *cur ? 0 : -1;
}
* Implementation of `pgp_check_traditional'.
*/
-static int pgp_check_traditional_one_body (FILE *fp, BODY *b, int tagged_only)
+static int pgp_check_traditional_one_body (FILE * fp, BODY * b,
+ int tagged_only)
{
char tempfile[_POSIX_PATH_MAX];
char buf[HUGE_STRING];
FILE *tfp;
-
+
short sgn = 0;
short enc = 0;
-
+
if (b->type != TYPETEXT)
return 0;
return 0;
mutt_mktemp (tempfile);
- if (mutt_decode_save_attachment (fp, b, tempfile, 0, 0) != 0)
- {
+ if (mutt_decode_save_attachment (fp, b, tempfile, 0, 0) != 0) {
unlink (tempfile);
return 0;
}
-
- if ((tfp = fopen (tempfile, "r")) == NULL)
- {
+
+ if ((tfp = fopen (tempfile, "r")) == NULL) {
unlink (tempfile);
return 0;
}
-
- while (fgets (buf, sizeof (buf), tfp))
- {
- if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15))
- {
+
+ while (fgets (buf, sizeof (buf), tfp)) {
+ if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15)) {
if (!mutt_strcmp ("MESSAGE-----\n", buf + 15))
- enc = 1;
+ enc = 1;
else if (!mutt_strcmp ("SIGNED MESSAGE-----\n", buf + 15))
- sgn = 1;
+ sgn = 1;
}
}
safe_fclose (&tfp);
return 0;
/* fix the content type */
-
+
mutt_set_parameter ("format", "fixed", &b->parameter);
mutt_set_parameter ("x-action", enc ? "pgp-encrypted" : "pgp-signed",
&b->parameter);
-
+
return 1;
}
-int pgp_gpgme_check_traditional (FILE *fp, BODY *b, int tagged_only)
+int pgp_gpgme_check_traditional (FILE * fp, BODY * b, int tagged_only)
{
int rv = 0;
int r;
- for (; b; b = b->next)
- {
+
+ for (; b; b = b->next) {
if (is_multipart (b))
rv = (pgp_gpgme_check_traditional (fp, b->parts, tagged_only) || rv);
- else if (b->type == TYPETEXT)
- {
+ else if (b->type == TYPETEXT) {
if ((r = mutt_is_application_pgp (b)))
- rv = (rv || r);
+ rv = (rv || r);
else
- rv = (pgp_check_traditional_one_body (fp, b, tagged_only) || rv);
+ rv = (pgp_check_traditional_one_body (fp, b, tagged_only) || rv);
}
}
return rv;
note that we can successfully handle anything produced by any
existing versions of mutt.) */
-static void copy_clearsigned (gpgme_data_t data, STATE *s, char *charset)
+static void copy_clearsigned (gpgme_data_t data, STATE * s, char *charset)
{
char buf[HUGE_STRING];
short complete, armor_header;
return;
unlink (fname);
FREE (&fname);
-
+
fc = fgetconv_open (fp, charset, Charset, M_ICONV_HOOK_FROM);
-
+
for (complete = 1, armor_header = 1;
fgetconvs (buf, sizeof (buf), fc) != NULL;
- complete = strchr (buf, '\n') != NULL)
- {
- if (!complete)
- {
+ complete = strchr (buf, '\n') != NULL) {
+ if (!complete) {
if (!armor_header)
- state_puts (buf, s);
+ state_puts (buf, s);
continue;
}
if (!mutt_strcmp (buf, "-----BEGIN PGP SIGNATURE-----\n"))
break;
-
- if (armor_header)
- {
- if (buf[0] == '\n')
- armor_header = 0;
+
+ if (armor_header) {
+ if (buf[0] == '\n')
+ armor_header = 0;
continue;
}
-
- if (s->prefix)
+
+ if (s->prefix)
state_puts (s->prefix, s);
-
+
if (buf[0] == '-' && buf[1] == ' ')
state_puts (buf + 2, s);
else
state_puts (buf, s);
}
-
+
fgetconv_close (&fc);
fclose (fp);
}
/* Support for classic_application/pgp */
-void pgp_gpgme_application_handler (BODY *m, STATE *s)
+void pgp_gpgme_application_handler (BODY * m, STATE * s)
{
int needpass = -1, pgp_keyblock = 0;
int clearsign = 0;
short maybe_goodsig = 1;
short have_any_sigs = 0;
- char body_charset[STRING]; /* Only used for clearsigned messages. */
+ char body_charset[STRING]; /* Only used for clearsigned messages. */
dprint (2, (debugfile, "Entering pgp_application_pgp handler\n"));
fseek (s->fpin, m->offset, 0);
last_pos = m->offset;
-
- for (bytes = m->length; bytes > 0;)
- {
- if (fgets (buf, sizeof (buf), s->fpin) == NULL)
- break;
-
- offset = ftell (s->fpin);
- bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */
- last_pos = offset;
-
- if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15))
- {
- clearsign = 0;
- start_pos = last_pos;
-
- if (!mutt_strcmp ("MESSAGE-----\n", buf + 15))
- needpass = 1;
- else if (!mutt_strcmp ("SIGNED MESSAGE-----\n", buf + 15))
- {
- clearsign = 1;
- needpass = 0;
- }
- else if (!option (OPTDONTHANDLEPGPKEYS) &&
- !mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15))
- {
- needpass = 0;
- pgp_keyblock =1;
- }
- else
- {
- /* XXX - we may wish to recode here */
- if (s->prefix)
- state_puts (s->prefix, s);
- state_puts (buf, s);
- continue;
- }
-
- have_any_sigs = (have_any_sigs
- || (clearsign && (s->flags & M_VERIFY)));
-
- /* Copy PGP material to an data container */
- armored_data = create_gpgme_data ();
- gpgme_data_write (armored_data, buf, strlen (buf));
- while (bytes > 0 && fgets (buf, sizeof (buf) - 1, s->fpin) != NULL)
- {
- offset = ftell (s->fpin);
- bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf)*/
- last_pos = offset;
-
- gpgme_data_write (armored_data, buf, strlen (buf));
-
- if ((needpass
- && !mutt_strcmp ("-----END PGP MESSAGE-----\n", buf))
- || (!needpass
- && (!mutt_strcmp ("-----END PGP SIGNATURE-----\n", buf)
- || !mutt_strcmp (
- "-----END PGP PUBLIC KEY BLOCK-----\n",buf))))
- break;
- }
-
- /* Invoke PGP if needed */
- if (!clearsign || (s->flags & M_VERIFY))
- {
- unsigned int sig_stat = 0;
- gpgme_data_t plaintext;
- gpgme_ctx_t ctx;
-
- plaintext = create_gpgme_data ();
- ctx = create_gpgme_context (0);
-
- if (clearsign)
- err = gpgme_op_verify (ctx, armored_data, NULL, plaintext);
- else
- {
- err = gpgme_op_decrypt_verify (ctx, armored_data, plaintext);
- if (gpg_err_code (err) == GPG_ERR_NO_DATA)
- {
- /* Decrypt verify can't handle signed only messages. */
- err = (gpgme_data_seek (armored_data, 0, SEEK_SET) == -1)
- ? gpgme_error_from_errno (errno) : 0;
- /* Must release plaintext so that we supply an
- uninitialized object. */
- gpgme_data_release (plaintext);
- plaintext = create_gpgme_data ();
- err = gpgme_op_verify (ctx, armored_data,
- NULL, plaintext);
- }
- }
-
- if (err)
- {
- char errbuf[200];
-
- snprintf (errbuf, sizeof(errbuf)-1,
- _("Error: decryption/verification failed: %s\n"),
- gpgme_strerror (err));
- state_attach_puts (errbuf, s);
- }
- else
- { /* Decryption/Verification succeeded */
- char *tmpfname;
-
- {
- /* Check wether signatures have been verified. */
- gpgme_verify_result_t verify_result;
-
- verify_result = gpgme_op_verify_result (ctx);
- if (verify_result->signatures)
- sig_stat = 1;
- }
-
- have_any_sigs = 0;
- maybe_goodsig = 0;
- if ((s->flags & M_DISPLAY) && sig_stat)
- {
- int res, idx;
- int anybad = 0;
- int anywarn = 0;
-
- state_attach_puts (_("[-- Begin signature "
- "information --]\n"), s);
- have_any_sigs = 1;
- for(idx=0;
- (res = show_one_sig_status (ctx, idx, s)) != -1;
- idx++)
- {
- if (res == 1)
- anybad = 1;
- else if (res == 2)
- anywarn = 1;
- }
- if (!anybad && idx)
- maybe_goodsig = 1;
-
- state_attach_puts (_("[-- End signature "
- "information --]\n\n"), s);
- }
-
- tmpfname = data_object_to_tempfile (plaintext, &pgpout);
- if (!tmpfname)
- {
- pgpout = NULL;
- state_attach_puts (_("Error: copy data failed\n"), s);
- }
- else
- {
- unlink (tmpfname);
- FREE (&tmpfname);
- }
- }
- gpgme_release (ctx);
- }
-
- /*
- * Now, copy cleartext to the screen. NOTE - we expect that PGP
- * outputs utf-8 cleartext. This may not always be true, but it
- * seems to be a reasonable guess.
- */
-
- if(s->flags & M_DISPLAY)
- {
- if (needpass)
- state_attach_puts (_("[-- BEGIN PGP MESSAGE --]\n\n"), s);
- else if (pgp_keyblock)
- state_attach_puts (_("[-- BEGIN PGP PUBLIC KEY BLOCK --]\n"),
- s);
- else
- state_attach_puts (_("[-- BEGIN PGP SIGNED MESSAGE --]\n\n"),
- s);
- }
-
- if (clearsign)
- {
- copy_clearsigned (armored_data, s, body_charset);
- }
- else if (pgpout)
- {
- FGETCONV *fc;
- int c;
- rewind (pgpout);
- fc = fgetconv_open (pgpout, "utf-8", Charset, 0);
- while ((c = fgetconv (fc)) != EOF)
- {
- state_putc (c, s);
- if (c == '\n' && s->prefix)
- state_puts (s->prefix, s);
- }
- fgetconv_close (&fc);
- }
-
- if (s->flags & M_DISPLAY)
- {
- state_putc ('\n', s);
- if (needpass)
- state_attach_puts (_("[-- END PGP MESSAGE --]\n"), s);
- else if (pgp_keyblock)
- state_attach_puts (_("[-- END PGP PUBLIC KEY BLOCK --]\n"), s);
- else
- state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s);
- }
-
- if (pgpout)
- {
- safe_fclose (&pgpout);
+
+ for (bytes = m->length; bytes > 0;) {
+ if (fgets (buf, sizeof (buf), s->fpin) == NULL)
+ break;
+
+ offset = ftell (s->fpin);
+ bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */
+ last_pos = offset;
+
+ if (!mutt_strncmp ("-----BEGIN PGP ", buf, 15)) {
+ clearsign = 0;
+ start_pos = last_pos;
+
+ if (!mutt_strcmp ("MESSAGE-----\n", buf + 15))
+ needpass = 1;
+ else if (!mutt_strcmp ("SIGNED MESSAGE-----\n", buf + 15)) {
+ clearsign = 1;
+ needpass = 0;
+ }
+ else if (!option (OPTDONTHANDLEPGPKEYS) &&
+ !mutt_strcmp ("PUBLIC KEY BLOCK-----\n", buf + 15)) {
+ needpass = 0;
+ pgp_keyblock = 1;
+ }
+ else {
+ /* XXX - we may wish to recode here */
+ if (s->prefix)
+ state_puts (s->prefix, s);
+ state_puts (buf, s);
+ continue;
+ }
+
+ have_any_sigs = (have_any_sigs || (clearsign && (s->flags & M_VERIFY)));
+
+ /* Copy PGP material to an data container */
+ armored_data = create_gpgme_data ();
+ gpgme_data_write (armored_data, buf, strlen (buf));
+ while (bytes > 0 && fgets (buf, sizeof (buf) - 1, s->fpin) != NULL) {
+ offset = ftell (s->fpin);
+ bytes -= (offset - last_pos); /* don't rely on mutt_strlen(buf) */
+ last_pos = offset;
+
+ gpgme_data_write (armored_data, buf, strlen (buf));
+
+ if ((needpass && !mutt_strcmp ("-----END PGP MESSAGE-----\n", buf))
+ || (!needpass
+ && (!mutt_strcmp ("-----END PGP SIGNATURE-----\n", buf)
+ || !mutt_strcmp ("-----END PGP PUBLIC KEY BLOCK-----\n",
+ buf))))
+ break;
+ }
+
+ /* Invoke PGP if needed */
+ if (!clearsign || (s->flags & M_VERIFY)) {
+ unsigned int sig_stat = 0;
+ gpgme_data_t plaintext;
+ gpgme_ctx_t ctx;
+
+ plaintext = create_gpgme_data ();
+ ctx = create_gpgme_context (0);
+
+ if (clearsign)
+ err = gpgme_op_verify (ctx, armored_data, NULL, plaintext);
+ else {
+ err = gpgme_op_decrypt_verify (ctx, armored_data, plaintext);
+ if (gpg_err_code (err) == GPG_ERR_NO_DATA) {
+ /* Decrypt verify can't handle signed only messages. */
+ err = (gpgme_data_seek (armored_data, 0, SEEK_SET) == -1)
+ ? gpgme_error_from_errno (errno) : 0;
+ /* Must release plaintext so that we supply an
+ uninitialized object. */
+ gpgme_data_release (plaintext);
+ plaintext = create_gpgme_data ();
+ err = gpgme_op_verify (ctx, armored_data, NULL, plaintext);
+ }
+ }
+
+ if (err) {
+ char errbuf[200];
+
+ snprintf (errbuf, sizeof (errbuf) - 1,
+ _("Error: decryption/verification failed: %s\n"),
+ gpgme_strerror (err));
+ state_attach_puts (errbuf, s);
+ }
+ else { /* Decryption/Verification succeeded */
+ char *tmpfname;
+
+ {
+ /* Check wether signatures have been verified. */
+ gpgme_verify_result_t verify_result;
+
+ verify_result = gpgme_op_verify_result (ctx);
+ if (verify_result->signatures)
+ sig_stat = 1;
+ }
+
+ have_any_sigs = 0;
+ maybe_goodsig = 0;
+ if ((s->flags & M_DISPLAY) && sig_stat) {
+ int res, idx;
+ int anybad = 0;
+ int anywarn = 0;
+
+ state_attach_puts (_("[-- Begin signature "
+ "information --]\n"), s);
+ have_any_sigs = 1;
+ for (idx = 0;
+ (res = show_one_sig_status (ctx, idx, s)) != -1; idx++) {
+ if (res == 1)
+ anybad = 1;
+ else if (res == 2)
+ anywarn = 1;
}
+ if (!anybad && idx)
+ maybe_goodsig = 1;
+
+ state_attach_puts (_("[-- End signature "
+ "information --]\n\n"), s);
+ }
+
+ tmpfname = data_object_to_tempfile (plaintext, &pgpout);
+ if (!tmpfname) {
+ pgpout = NULL;
+ state_attach_puts (_("Error: copy data failed\n"), s);
+ }
+ else {
+ unlink (tmpfname);
+ FREE (&tmpfname);
+ }
}
- else
- {
- /* XXX - we may wish to recode here */
- if (s->prefix)
+ gpgme_release (ctx);
+ }
+
+ /*
+ * Now, copy cleartext to the screen. NOTE - we expect that PGP
+ * outputs utf-8 cleartext. This may not always be true, but it
+ * seems to be a reasonable guess.
+ */
+
+ if (s->flags & M_DISPLAY) {
+ if (needpass)
+ state_attach_puts (_("[-- BEGIN PGP MESSAGE --]\n\n"), s);
+ else if (pgp_keyblock)
+ state_attach_puts (_("[-- BEGIN PGP PUBLIC KEY BLOCK --]\n"), s);
+ else
+ state_attach_puts (_("[-- BEGIN PGP SIGNED MESSAGE --]\n\n"), s);
+ }
+
+ if (clearsign) {
+ copy_clearsigned (armored_data, s, body_charset);
+ }
+ else if (pgpout) {
+ FGETCONV *fc;
+ int c;
+
+ rewind (pgpout);
+ fc = fgetconv_open (pgpout, "utf-8", Charset, 0);
+ while ((c = fgetconv (fc)) != EOF) {
+ state_putc (c, s);
+ if (c == '\n' && s->prefix)
state_puts (s->prefix, s);
- state_puts (buf, s);
}
+ fgetconv_close (&fc);
+ }
+
+ if (s->flags & M_DISPLAY) {
+ state_putc ('\n', s);
+ if (needpass)
+ state_attach_puts (_("[-- END PGP MESSAGE --]\n"), s);
+ else if (pgp_keyblock)
+ state_attach_puts (_("[-- END PGP PUBLIC KEY BLOCK --]\n"), s);
+ else
+ state_attach_puts (_("[-- END PGP SIGNED MESSAGE --]\n"), s);
+ }
+
+ if (pgpout) {
+ safe_fclose (&pgpout);
+ }
}
+ else {
+ /* XXX - we may wish to recode here */
+ if (s->prefix)
+ state_puts (s->prefix, s);
+ state_puts (buf, s);
+ }
+ }
m->goodsig = (maybe_goodsig && have_any_sigs);
-
- if (needpass == -1)
- {
- state_attach_puts (_("[-- Error: could not find beginning"
- " of PGP message! --]\n\n"), s);
- return;
- }
+
+ if (needpass == -1) {
+ state_attach_puts (_("[-- Error: could not find beginning"
+ " of PGP message! --]\n\n"), s);
+ return;
+ }
dprint (2, (debugfile, "Leaving pgp_application_pgp handler\n"));
}
*/
/* MIME handler for pgp/mime encrypted messages. */
-void pgp_gpgme_encrypted_handler (BODY *a, STATE *s)
+void pgp_gpgme_encrypted_handler (BODY * a, STATE * s)
{
char tempfile[_POSIX_PATH_MAX];
FILE *fpout;
BODY *tattach;
BODY *orig_body = a;
int is_signed;
-
+
dprint (2, (debugfile, "Entering pgp_encrypted handler\n"));
a = a->parts;
if (!a || a->type != TYPEAPPLICATION || !a->subtype
- || ascii_strcasecmp ("pgp-encrypted", a->subtype)
+ || ascii_strcasecmp ("pgp-encrypted", a->subtype)
|| !a->next || a->next->type != TYPEAPPLICATION || !a->next->subtype
- || ascii_strcasecmp ("octet-stream", a->next->subtype) )
- {
- if (s->flags & M_DISPLAY)
- state_attach_puts (_("[-- Error: malformed PGP/MIME message! --]\n\n"),
- s);
- return;
- }
+ || ascii_strcasecmp ("octet-stream", a->next->subtype)) {
+ if (s->flags & M_DISPLAY)
+ state_attach_puts (_("[-- Error: malformed PGP/MIME message! --]\n\n"),
+ s);
+ return;
+ }
/* Move forward to the application/pgp-encrypted body. */
a = a->next;
mutt_mktemp (tempfile);
- if (!(fpout = safe_fopen (tempfile, "w+")))
- {
- if (s->flags & M_DISPLAY)
- state_attach_puts (_("[-- Error: could not create temporary file! "
- "--]\n"), s);
- return;
- }
+ if (!(fpout = safe_fopen (tempfile, "w+"))) {
+ if (s->flags & M_DISPLAY)
+ state_attach_puts (_("[-- Error: could not create temporary file! "
+ "--]\n"), s);
+ return;
+ }
tattach = decrypt_part (a, s, fpout, 0, &is_signed);
- if (tattach)
+ if (tattach) {
+ tattach->goodsig = is_signed > 0;
+
+ if (s->flags & M_DISPLAY)
+ state_attach_puts (is_signed ?
+ _
+ ("[-- The following data is PGP/MIME signed and encrypted --]\n\n")
+ :
+ _
+ ("[-- The following data is PGP/MIME encrypted --]\n\n"),
+ s);
+
{
- tattach->goodsig = is_signed > 0;
-
- if (s->flags & M_DISPLAY)
- state_attach_puts (is_signed?
- _("[-- The following data is PGP/MIME signed and encrypted --]\n\n"):
- _("[-- The following data is PGP/MIME encrypted --]\n\n"),
- s);
-
- {
- FILE *savefp = s->fpin;
- s->fpin = fpout;
- mutt_body_handler (tattach, s);
- s->fpin = savefp;
- }
+ FILE *savefp = s->fpin;
- /*
- * if a multipart/signed is the _only_ sub-part of a
- * multipart/encrypted, cache signature verification
- * status.
- */
- if (mutt_is_multipart_signed (tattach) && !tattach->next)
- orig_body->goodsig |= tattach->goodsig;
-
- if (s->flags & M_DISPLAY)
- {
- state_puts ("\n", s);
- state_attach_puts (is_signed?
- _("[-- End of PGP/MIME signed and encrypted data --]\n"):
- _("[-- End of PGP/MIME encrypted data --]\n"),
- s);
- }
+ s->fpin = fpout;
+ mutt_body_handler (tattach, s);
+ s->fpin = savefp;
+ }
+
+ /*
+ * if a multipart/signed is the _only_ sub-part of a
+ * multipart/encrypted, cache signature verification
+ * status.
+ */
+ if (mutt_is_multipart_signed (tattach) && !tattach->next)
+ orig_body->goodsig |= tattach->goodsig;
- mutt_free_body (&tattach);
+ if (s->flags & M_DISPLAY) {
+ state_puts ("\n", s);
+ state_attach_puts (is_signed ?
+ _
+ ("[-- End of PGP/MIME signed and encrypted data --]\n")
+ : _("[-- End of PGP/MIME encrypted data --]\n"), s);
}
-
+
+ mutt_free_body (&tattach);
+ }
+
fclose (fpout);
- mutt_unlink(tempfile);
+ mutt_unlink (tempfile);
dprint (2, (debugfile, "Leaving pgp_encrypted handler\n"));
}
/* Support for application/smime */
-void smime_gpgme_application_handler (BODY *a, STATE *s)
+void smime_gpgme_application_handler (BODY * a, STATE * s)
{
char tempfile[_POSIX_PATH_MAX];
FILE *fpout;
dprint (2, (debugfile, "Entering smime_encrypted handler\n"));
-
+
a->warnsig = 0;
mutt_mktemp (tempfile);
- if (!(fpout = safe_fopen (tempfile, "w+")))
- {
- if (s->flags & M_DISPLAY)
- state_attach_puts (_("[-- Error: could not create temporary file! "
- "--]\n"), s);
- return;
- }
+ if (!(fpout = safe_fopen (tempfile, "w+"))) {
+ if (s->flags & M_DISPLAY)
+ state_attach_puts (_("[-- Error: could not create temporary file! "
+ "--]\n"), s);
+ return;
+ }
tattach = decrypt_part (a, s, fpout, 1, &is_signed);
- if (tattach)
+ if (tattach) {
+ tattach->goodsig = is_signed > 0;
+
+ if (s->flags & M_DISPLAY)
+ state_attach_puts (is_signed ?
+ _("[-- The following data is S/MIME signed --]\n\n")
+ :
+ _
+ ("[-- The following data is S/MIME encrypted --]\n\n"),
+ s);
+
{
- tattach->goodsig = is_signed > 0;
-
- if (s->flags & M_DISPLAY)
- state_attach_puts (is_signed?
- _("[-- The following data is S/MIME signed --]\n\n"):
- _("[-- The following data is S/MIME encrypted --]\n\n"),
- s);
-
- {
- FILE *savefp = s->fpin;
- s->fpin = fpout;
- mutt_body_handler (tattach, s);
- s->fpin = savefp;
- }
+ FILE *savefp = s->fpin;
- /*
- * if a multipart/signed is the _only_ sub-part of a
- * multipart/encrypted, cache signature verification
- * status.
- */
- if (mutt_is_multipart_signed (tattach) && !tattach->next)
- {
- if (!(a->goodsig = tattach->goodsig))
- a->warnsig = tattach->warnsig;
- }
- else if (tattach->goodsig)
- {
- a->goodsig = 1;
- a->warnsig = tattach->warnsig;
- }
+ s->fpin = fpout;
+ mutt_body_handler (tattach, s);
+ s->fpin = savefp;
+ }
- if (s->flags & M_DISPLAY)
- {
- state_puts ("\n", s);
- state_attach_puts (is_signed?
- _("[-- End of S/MIME signed data --]\n"):
- _("[-- End of S/MIME encrypted data --]\n"),
- s);
- }
+ /*
+ * if a multipart/signed is the _only_ sub-part of a
+ * multipart/encrypted, cache signature verification
+ * status.
+ */
+ if (mutt_is_multipart_signed (tattach) && !tattach->next) {
+ if (!(a->goodsig = tattach->goodsig))
+ a->warnsig = tattach->warnsig;
+ }
+ else if (tattach->goodsig) {
+ a->goodsig = 1;
+ a->warnsig = tattach->warnsig;
+ }
- mutt_free_body (&tattach);
+ if (s->flags & M_DISPLAY) {
+ state_puts ("\n", s);
+ state_attach_puts (is_signed ?
+ _("[-- End of S/MIME signed data --]\n") :
+ _("[-- End of S/MIME encrypted data --]\n"), s);
}
-
+
+ mutt_free_body (&tattach);
+ }
+
fclose (fpout);
- mutt_unlink(tempfile);
+ mutt_unlink (tempfile);
dprint (2, (debugfile, "Leaving smime_encrypted handler\n"));
}
const char *prefix,
const char *ifstring,
const char *elsestring,
- unsigned long data,
- format_flag flags)
+ unsigned long data, format_flag flags)
{
char fmt[16];
crypt_entry_t *entry;
unsigned long val;
entry = (crypt_entry_t *) data;
- key = entry->key;
+ key = entry->key;
/* if (isupper ((unsigned char) op)) */
/* key = pkey; */
- kflags = (key->flags /*| (pkey->flags & KEYFLAG_RESTRICTIONS)
- | uid->flags*/);
-
- switch (ascii_tolower (op))
+ kflags = (key->flags /*| (pkey->flags & KEYFLAG_RESTRICTIONS)
+ | uid->flags */ );
+
+ switch (ascii_tolower (op)) {
+ case '[':
{
- case '[':
- {
- const char *cp;
- char buf2[SHORT_STRING], *p;
- int do_locales;
- struct tm *tm;
- size_t len;
-
- p = dest;
-
- cp = src;
- if (*cp == '!')
- {
- do_locales = 0;
- cp++;
- }
- else
- do_locales = 1;
-
- len = destlen - 1;
- while (len > 0 && *cp != ']')
- {
- if (*cp == '%')
- {
- cp++;
- if (len >= 2)
- {
- *p++ = '%';
- *p++ = *cp;
- len -= 2;
- }
- else
- break; /* not enough space */
- cp++;
- }
- else
- {
- *p++ = *cp++;
- len--;
- }
- }
- *p = 0;
-
- if (do_locales && Locale)
- setlocale (LC_TIME, Locale);
-
- {
- time_t tt = 0;
-
- if (key->kobj->subkeys && (key->kobj->subkeys->timestamp > 0))
- tt = key->kobj->subkeys->timestamp;
-
- tm = localtime (&tt);
- }
- strftime (buf2, sizeof (buf2), dest, tm);
-
- if (do_locales)
- setlocale (LC_TIME, "C");
-
- snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
- snprintf (dest, destlen, fmt, buf2);
- if (len > 0)
- src = cp + 1;
- }
- break;
- case 'n':
- if (!optional)
- {
- snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
- snprintf (dest, destlen, fmt, entry->num);
- }
- break;
- case 'k':
- if (!optional)
- {
- /* fixme: we need a way to distinguish between main and subkeys.
- Store the idx in entry? */
- snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
- snprintf (dest, destlen, fmt, crypt_keyid (key));
- }
- break;
- case 'u':
- if (!optional)
- {
- snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
- snprintf (dest, destlen, fmt, key->uid);
- }
- break;
- case 'a':
- if (!optional)
- {
- snprintf (fmt, sizeof (fmt), "%%%s.3s", prefix);
- if (key->kobj->subkeys)
- s = gpgme_pubkey_algo_name (key->kobj->subkeys->pubkey_algo);
- else
- s = "?";
- snprintf (dest, destlen, fmt, s);
- }
- break;
- case 'l':
- if (!optional)
- {
- snprintf (fmt, sizeof (fmt), "%%%slu", prefix);
- if (key->kobj->subkeys)
- val = key->kobj->subkeys->length;
- else
- val = 0;
- snprintf (dest, destlen, fmt, val);
+ const char *cp;
+ char buf2[SHORT_STRING], *p;
+ int do_locales;
+ struct tm *tm;
+ size_t len;
+
+ p = dest;
+
+ cp = src;
+ if (*cp == '!') {
+ do_locales = 0;
+ cp++;
}
- break;
- case 'f':
- if (!optional)
- {
- snprintf (fmt, sizeof (fmt), "%%%sc", prefix);
- snprintf (dest, destlen, fmt, crypt_flags (kflags));
+ else
+ do_locales = 1;
+
+ len = destlen - 1;
+ while (len > 0 && *cp != ']') {
+ if (*cp == '%') {
+ cp++;
+ if (len >= 2) {
+ *p++ = '%';
+ *p++ = *cp;
+ len -= 2;
+ }
+ else
+ break; /* not enough space */
+ cp++;
+ }
+ else {
+ *p++ = *cp++;
+ len--;
+ }
}
- else if (!(kflags & (KEYFLAG_RESTRICTIONS)))
- optional = 0;
- break;
- case 'c':
- if (!optional)
+ *p = 0;
+
+ if (do_locales && Locale)
+ setlocale (LC_TIME, Locale);
+
{
- snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
- snprintf (dest, destlen, fmt, crypt_key_abilities (kflags));
+ time_t tt = 0;
+
+ if (key->kobj->subkeys && (key->kobj->subkeys->timestamp > 0))
+ tt = key->kobj->subkeys->timestamp;
+
+ tm = localtime (&tt);
}
- else if (!(kflags & (KEYFLAG_ABILITIES)))
- optional = 0;
- break;
- case 't':
- if ((kflags & KEYFLAG_ISX509))
- s = "x";
+ strftime (buf2, sizeof (buf2), dest, tm);
+
+ if (do_locales)
+ setlocale (LC_TIME, "C");
+
+ snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+ snprintf (dest, destlen, fmt, buf2);
+ if (len > 0)
+ src = cp + 1;
+ }
+ break;
+ case 'n':
+ if (!optional) {
+ snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
+ snprintf (dest, destlen, fmt, entry->num);
+ }
+ break;
+ case 'k':
+ if (!optional) {
+ /* fixme: we need a way to distinguish between main and subkeys.
+ Store the idx in entry? */
+ snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+ snprintf (dest, destlen, fmt, crypt_keyid (key));
+ }
+ break;
+ case 'u':
+ if (!optional) {
+ snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+ snprintf (dest, destlen, fmt, key->uid);
+ }
+ break;
+ case 'a':
+ if (!optional) {
+ snprintf (fmt, sizeof (fmt), "%%%s.3s", prefix);
+ if (key->kobj->subkeys)
+ s = gpgme_pubkey_algo_name (key->kobj->subkeys->pubkey_algo);
+ else
+ s = "?";
+ snprintf (dest, destlen, fmt, s);
+ }
+ break;
+ case 'l':
+ if (!optional) {
+ snprintf (fmt, sizeof (fmt), "%%%slu", prefix);
+ if (key->kobj->subkeys)
+ val = key->kobj->subkeys->length;
else
- {
- gpgme_user_id_t uid = NULL;
- unsigned int i = 0;
-
- for (i = 0, uid = key->kobj->uids; uid && (i < key->idx);
- i++, uid = uid->next)
- ;
- if (uid)
- switch (uid->validity)
- {
- case GPGME_VALIDITY_UNDEFINED:
- s = "q";
- break;
- case GPGME_VALIDITY_NEVER:
- s = "n";
- break;
- case GPGME_VALIDITY_MARGINAL:
- s = "m";
- break;
- case GPGME_VALIDITY_FULL:
- s = "f";
- break;
- case GPGME_VALIDITY_ULTIMATE:
- s = "u";
- break;
- case GPGME_VALIDITY_UNKNOWN:
- default:
- s = "?";
- break;
- }
- }
+ val = 0;
+ snprintf (dest, destlen, fmt, val);
+ }
+ break;
+ case 'f':
+ if (!optional) {
snprintf (fmt, sizeof (fmt), "%%%sc", prefix);
- snprintf (dest, destlen, fmt, s? *s: 'B');
- break;
- case 'p':
+ snprintf (dest, destlen, fmt, crypt_flags (kflags));
+ }
+ else if (!(kflags & (KEYFLAG_RESTRICTIONS)))
+ optional = 0;
+ break;
+ case 'c':
+ if (!optional) {
snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
- snprintf (dest, destlen, fmt,
- gpgme_get_protocol_name (key->kobj->protocol));
- break;
+ snprintf (dest, destlen, fmt, crypt_key_abilities (kflags));
+ }
+ else if (!(kflags & (KEYFLAG_ABILITIES)))
+ optional = 0;
+ break;
+ case 't':
+ if ((kflags & KEYFLAG_ISX509))
+ s = "x";
+ else {
+ gpgme_user_id_t uid = NULL;
+ unsigned int i = 0;
+
+ for (i = 0, uid = key->kobj->uids; uid && (i < key->idx);
+ i++, uid = uid->next);
+ if (uid)
+ switch (uid->validity) {
+ case GPGME_VALIDITY_UNDEFINED:
+ s = "q";
+ break;
+ case GPGME_VALIDITY_NEVER:
+ s = "n";
+ break;
+ case GPGME_VALIDITY_MARGINAL:
+ s = "m";
+ break;
+ case GPGME_VALIDITY_FULL:
+ s = "f";
+ break;
+ case GPGME_VALIDITY_ULTIMATE:
+ s = "u";
+ break;
+ case GPGME_VALIDITY_UNKNOWN:
+ default:
+ s = "?";
+ break;
+ }
+ }
+ snprintf (fmt, sizeof (fmt), "%%%sc", prefix);
+ snprintf (dest, destlen, fmt, s ? *s : 'B');
+ break;
+ case 'p':
+ snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
+ snprintf (dest, destlen, fmt,
+ gpgme_get_protocol_name (key->kobj->protocol));
+ break;
- default:
- *dest = '\0';
+ default:
+ *dest = '\0';
}
if (optional)
mutt_FormatString (dest, destlen, elsestring, mutt_attach_fmt, data, 0);
return (src);
}
-
+
/* Used by the display fucntion to format a line. */
static void crypt_entry (char *s, size_t l, MUTTMENU * menu, int num)
{
crypt_key_t **key_table = (crypt_key_t **) menu->data;
crypt_entry_t entry;
-
+
entry.key = key_table[num];
entry.num = num + 1;
- mutt_FormatString (s, l, NONULL (PgpEntryFormat), crypt_entry_fmt,
- (unsigned long) &entry, M_FORMAT_ARROWCURSOR);
+ mutt_FormatString (s, l, NONULL (PgpEntryFormat), crypt_entry_fmt,
+ (unsigned long) &entry, M_FORMAT_ARROWCURSOR);
}
/* Compare two addresses and the keyid to be used for sorting. */
static int crypt_compare_address (const void *a, const void *b)
{
return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_address (a, b)
- : _crypt_compare_address (a, b));
+ : _crypt_compare_address (a, b));
}
static int crypt_compare_keyid (const void *a, const void *b)
{
return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_keyid (a, b)
- : _crypt_compare_keyid (a, b));
+ : _crypt_compare_keyid (a, b));
}
/* Compare 2 creation dates and the addresses. For sorting. */
static int crypt_compare_date (const void *a, const void *b)
{
return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_date (a, b)
- : _crypt_compare_date (a, b));
+ : _crypt_compare_date (a, b));
}
/* Compare two trust values, the key length, the creation dates. the
int r;
if ((r = (((*s)->flags & (KEYFLAG_RESTRICTIONS))
- - ((*t)->flags & (KEYFLAG_RESTRICTIONS)))))
+ - ((*t)->flags & (KEYFLAG_RESTRICTIONS)))))
return r > 0;
if ((*s)->kobj->uids)
static int crypt_compare_trust (const void *a, const void *b)
{
return ((PgpSortKeys & SORT_REVERSE) ? !_crypt_compare_trust (a, b)
- : _crypt_compare_trust (a, b));
+ : _crypt_compare_trust (a, b));
}
/* Print the X.500 Distinguished Name part KEY from the array of parts
DN to FP. */
-static int
-print_dn_part (FILE *fp, struct dn_array_s *dn, const char *key)
+static int print_dn_part (FILE * fp, struct dn_array_s *dn, const char *key)
{
int any = 0;
- for (; dn->key; dn++)
- {
- if (!strcmp (dn->key, key))
- {
- if (any)
- fputs (" + ", fp);
- print_utf8 (fp, dn->value, strlen (dn->value));
- any = 1;
- }
+ for (; dn->key; dn++) {
+ if (!strcmp (dn->key, key)) {
+ if (any)
+ fputs (" + ", fp);
+ print_utf8 (fp, dn->value, strlen (dn->value));
+ any = 1;
}
+ }
return any;
}
/* Print all parts of a DN in a standard sequence. */
-static void
-print_dn_parts (FILE *fp, struct dn_array_s *dn)
+static void print_dn_parts (FILE * fp, struct dn_array_s *dn)
{
const char *stdpart[] = {
- "CN", "OU", "O", "STREET", "L", "ST", "C", NULL
+ "CN", "OU", "O", "STREET", "L", "ST", "C", NULL
};
- int any=0, any2=0, i;
-
- for (i=0; stdpart[i]; i++)
- {
+ int any = 0, any2 = 0, i;
+
+ for (i = 0; stdpart[i]; i++) {
+ if (any)
+ fputs (", ", fp);
+ any = print_dn_part (fp, dn, stdpart[i]);
+ }
+ /* now print the rest without any specific ordering */
+ for (; dn->key; dn++) {
+ for (i = 0; stdpart[i]; i++) {
+ if (!strcmp (dn->key, stdpart[i]))
+ break;
+ }
+ if (!stdpart[i]) {
if (any)
fputs (", ", fp);
- any = print_dn_part (fp, dn, stdpart[i]);
- }
- /* now print the rest without any specific ordering */
- for (; dn->key; dn++)
- {
- for (i=0; stdpart[i]; i++)
- {
- if (!strcmp (dn->key, stdpart[i]))
- break;
- }
- if (!stdpart[i])
- {
- if (any)
- fputs (", ", fp);
- if (!any2)
- fputs ("(", fp);
- any = print_dn_part (fp, dn, dn->key);
- any2 = 1;
- }
+ if (!any2)
+ fputs ("(", fp);
+ any = print_dn_part (fp, dn, dn->key);
+ any2 = 1;
}
+ }
if (any2)
fputs (")", fp);
}
/* Parse an RDN; this is a helper to parse_dn(). */
-static const unsigned char *
-parse_dn_part (struct dn_array_s *array, const unsigned char *string)
+static const unsigned char *parse_dn_part (struct dn_array_s *array,
+ const unsigned char *string)
{
const unsigned char *s, *s1;
size_t n;
unsigned char *p;
/* parse attributeType */
- for (s = string+1; *s && *s != '='; s++)
- ;
+ for (s = string + 1; *s && *s != '='; s++);
if (!*s)
- return NULL; /* error */
+ return NULL; /* error */
n = s - string;
if (!n)
- return NULL; /* empty key */
- array->key = safe_malloc (n+1);
- p = (unsigned char *)array->key;
- memcpy (p, string, n); /* fixme: trim trailing spaces */
+ return NULL; /* empty key */
+ array->key = safe_malloc (n + 1);
+ p = (unsigned char *) array->key;
+ memcpy (p, string, n); /* fixme: trim trailing spaces */
p[n] = 0;
string = s + 1;
- if (*string == '#')
- { /* hexstring */
- string++;
- for (s=string; hexdigitp (s); s++)
+ if (*string == '#') { /* hexstring */
+ string++;
+ for (s = string; hexdigitp (s); s++)
+ s++;
+ n = s - string;
+ if (!n || (n & 1))
+ return NULL; /* empty or odd number of digits */
+ n /= 2;
+ p = safe_malloc (n + 1);
+ array->value = (char *) p;
+ for (s1 = string; n; s1 += 2, n--)
+ *p++ = xtoi_2 (s1);
+ *p = 0;
+ }
+ else { /* regular v3 quoted string */
+ for (n = 0, s = string; *s; s++) {
+ if (*s == '\\') { /* pair */
s++;
- n = s - string;
- if (!n || (n & 1))
- return NULL; /* empty or odd number of digits */
- n /= 2;
- p = safe_malloc (n+1);
- array->value = (char*)p;
- for (s1=string; n; s1 += 2, n--)
- *p++ = xtoi_2 (s1);
- *p = 0;
- }
- else
- { /* regular v3 quoted string */
- for (n=0, s=string; *s; s++)
- {
- if (*s == '\\')
- { /* pair */
- s++;
- if (*s == ',' || *s == '=' || *s == '+'
- || *s == '<' || *s == '>' || *s == '#' || *s == ';'
- || *s == '\\' || *s == '\"' || *s == ' ')
- n++;
- else if (hexdigitp (s) && hexdigitp (s+1))
- {
- s++;
- n++;
- }
- else
- return NULL; /* invalid escape sequence */
- }
- else if (*s == '\"')
- return NULL; /* invalid encoding */
- else if (*s == ',' || *s == '=' || *s == '+'
- || *s == '<' || *s == '>' || *s == '#' || *s == ';' )
- break;
- else
- n++;
+ if (*s == ',' || *s == '=' || *s == '+'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';'
+ || *s == '\\' || *s == '\"' || *s == ' ')
+ n++;
+ else if (hexdigitp (s) && hexdigitp (s + 1)) {
+ s++;
+ n++;
}
+ else
+ return NULL; /* invalid escape sequence */
+ }
+ else if (*s == '\"')
+ return NULL; /* invalid encoding */
+ else if (*s == ',' || *s == '=' || *s == '+'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';')
+ break;
+ else
+ n++;
+ }
- p = safe_malloc (n+1);
- array->value = (char*)p;
- for (s=string; n; s++, n--)
- {
- if (*s == '\\')
- {
- s++;
- if (hexdigitp (s))
- {
- *p++ = xtoi_2 (s);
- s++;
- }
- else
- *p++ = *s;
- }
- else
- *p++ = *s;
+ p = safe_malloc (n + 1);
+ array->value = (char *) p;
+ for (s = string; n; s++, n--) {
+ if (*s == '\\') {
+ s++;
+ if (hexdigitp (s)) {
+ *p++ = xtoi_2 (s);
+ s++;
}
- *p = 0;
+ else
+ *p++ = *s;
+ }
+ else
+ *p++ = *s;
}
+ *p = 0;
+ }
return s;
}
/* Parse a DN and return an array-ized one. This is not a validating
parser and it does not support any old-stylish syntax; gpgme is
expected to return only rfc2253 compatible strings. */
-static struct dn_array_s *
-parse_dn (const unsigned char *string)
+static struct dn_array_s *parse_dn (const unsigned char *string)
{
struct dn_array_s *array;
size_t arrayidx, arraysize;
int i;
- arraysize = 7; /* C,ST,L,O,OU,CN,email */
- array = safe_malloc ((arraysize+1) * sizeof *array);
+ arraysize = 7; /* C,ST,L,O,OU,CN,email */
+ array = safe_malloc ((arraysize + 1) * sizeof *array);
arrayidx = 0;
- while (*string)
- {
- while (*string == ' ')
- string++;
- if (!*string)
- break; /* ready */
- if (arrayidx >= arraysize)
- { /* mutt lacks a real safe_realoc - so we need to copy */
- struct dn_array_s *a2;
-
- arraysize += 5;
- a2 = safe_malloc ((arraysize+1) * sizeof *array);
- for (i=0; i < arrayidx; i++)
- {
- a2[i].key = array[i].key;
- a2[i].value = array[i].value;
- }
- FREE (&array);
- array = a2;
- }
- array[arrayidx].key = NULL;
- array[arrayidx].value = NULL;
- string = parse_dn_part (array+arrayidx, string);
- arrayidx++;
- if (!string)
- goto failure;
- while (*string == ' ')
- string++;
- if (*string && *string != ',' && *string != ';' && *string != '+')
- goto failure; /* invalid delimiter */
- if (*string)
- string++;
- }
+ while (*string) {
+ while (*string == ' ')
+ string++;
+ if (!*string)
+ break; /* ready */
+ if (arrayidx >= arraysize) { /* mutt lacks a real safe_realoc - so we need to copy */
+ struct dn_array_s *a2;
+
+ arraysize += 5;
+ a2 = safe_malloc ((arraysize + 1) * sizeof *array);
+ for (i = 0; i < arrayidx; i++) {
+ a2[i].key = array[i].key;
+ a2[i].value = array[i].value;
+ }
+ FREE (&array);
+ array = a2;
+ }
+ array[arrayidx].key = NULL;
+ array[arrayidx].value = NULL;
+ string = parse_dn_part (array + arrayidx, string);
+ arrayidx++;
+ if (!string)
+ goto failure;
+ while (*string == ' ')
+ string++;
+ if (*string && *string != ',' && *string != ';' && *string != '+')
+ goto failure; /* invalid delimiter */
+ if (*string)
+ string++;
+ }
array[arrayidx].key = NULL;
array[arrayidx].value = NULL;
return array;
- failure:
- for (i=0; i < arrayidx; i++)
- {
- FREE (&array[i].key);
- FREE (&array[i].value);
- }
+failure:
+ for (i = 0; i < arrayidx; i++) {
+ FREE (&array[i].key);
+ FREE (&array[i].value);
+ }
FREE (&array);
return NULL;
}
displayed in a proper way, which does mean to reorder some parts
for S/MIME's DNs. USERID is a string as returned by the gpgme key
functions. It is utf-8 encoded. */
-static void
-parse_and_print_user_id (FILE *fp, const char *userid)
+static void parse_and_print_user_id (FILE * fp, const char *userid)
{
const char *s;
int i;
- if (*userid == '<')
- {
- s = strchr (userid+1, '>');
- if (s)
- print_utf8 (fp, userid+1, s-userid-1);
- }
+ if (*userid == '<') {
+ s = strchr (userid + 1, '>');
+ if (s)
+ print_utf8 (fp, userid + 1, s - userid - 1);
+ }
else if (*userid == '(')
fputs (_("[Can't display this user ID (unknown encoding)]"), fp);
- else if (!digit_or_letter ((const unsigned char *)userid))
+ else if (!digit_or_letter ((const unsigned char *) userid))
fputs (_("[Can't display this user ID (invalid encoding)]"), fp);
- else
- {
- struct dn_array_s *dn = parse_dn ((const unsigned char *)userid);
- if (!dn)
- fputs (_("[Can't display this user ID (invalid DN)]"), fp);
- else
- {
- print_dn_parts (fp, dn);
- for (i=0; dn[i].key; i++)
- {
- FREE (&dn[i].key);
- FREE (&dn[i].value);
- }
- FREE (&dn);
- }
+ else {
+ struct dn_array_s *dn = parse_dn ((const unsigned char *) userid);
+
+ if (!dn)
+ fputs (_("[Can't display this user ID (invalid DN)]"), fp);
+ else {
+ print_dn_parts (fp, dn);
+ for (i = 0; dn[i].key; i++) {
+ FREE (&dn[i].key);
+ FREE (&dn[i].value);
+ }
+ FREE (&dn);
}
+ }
}
-typedef enum
- {
- KEY_CAP_CAN_ENCRYPT,
- KEY_CAP_CAN_SIGN,
- KEY_CAP_CAN_CERTIFY
- }
-key_cap_t;
+typedef enum {
+ KEY_CAP_CAN_ENCRYPT,
+ KEY_CAP_CAN_SIGN,
+ KEY_CAP_CAN_CERTIFY
+} key_cap_t;
-static unsigned int
-key_check_cap (gpgme_key_t key, key_cap_t cap)
+static unsigned int key_check_cap (gpgme_key_t key, key_cap_t cap)
{
gpgme_subkey_t subkey = NULL;
unsigned int ret = 0;
- switch (cap)
- {
- case KEY_CAP_CAN_ENCRYPT:
- if (! (ret = key->can_encrypt))
- for (subkey = key->subkeys; subkey; subkey = subkey->next)
- if ((ret = subkey->can_encrypt))
- break;
- break;
- case KEY_CAP_CAN_SIGN:
- if (! (ret = key->can_sign))
- for (subkey = key->subkeys; subkey; subkey = subkey->next)
- if ((ret = subkey->can_sign))
- break;
- break;
- case KEY_CAP_CAN_CERTIFY:
- if (! (ret = key->can_certify))
- for (subkey = key->subkeys; subkey; subkey = subkey->next)
- if ((ret = subkey->can_certify))
- break;
- break;
- }
+ switch (cap) {
+ case KEY_CAP_CAN_ENCRYPT:
+ if (!(ret = key->can_encrypt))
+ for (subkey = key->subkeys; subkey; subkey = subkey->next)
+ if ((ret = subkey->can_encrypt))
+ break;
+ break;
+ case KEY_CAP_CAN_SIGN:
+ if (!(ret = key->can_sign))
+ for (subkey = key->subkeys; subkey; subkey = subkey->next)
+ if ((ret = subkey->can_sign))
+ break;
+ break;
+ case KEY_CAP_CAN_CERTIFY:
+ if (!(ret = key->can_certify))
+ for (subkey = key->subkeys; subkey; subkey = subkey->next)
+ if ((ret = subkey->can_certify))
+ break;
+ break;
+ }
return ret;
}
/* Print verbose information about a key or certificate to FP. */
-static void print_key_info (gpgme_key_t key, FILE *fp)
+static void print_key_info (gpgme_key_t key, FILE * fp)
{
int idx;
const char *s = NULL, *s2 = NULL;
is_pgp = key->protocol == GPGME_PROTOCOL_OpenPGP;
- for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
- {
- if (uid->revoked)
- continue;
+ for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next) {
+ if (uid->revoked)
+ continue;
- s = uid->uid;
- fprintf (fp, "%s ......: ", idx ? _(" aka") :_("Name"));
- if (uid->invalid)
- {
- fputs (_("[Invalid]"), fp);
- putc (' ', fp);
- }
- if (is_pgp)
- print_utf8 (fp, s, strlen(s));
- else
- parse_and_print_user_id (fp, s);
- putc ('\n', fp);
+ s = uid->uid;
+ fprintf (fp, "%s ......: ", idx ? _(" aka") : _("Name"));
+ if (uid->invalid) {
+ fputs (_("[Invalid]"), fp);
+ putc (' ', fp);
}
+ if (is_pgp)
+ print_utf8 (fp, s, strlen (s));
+ else
+ parse_and_print_user_id (fp, s);
+ putc ('\n', fp);
+ }
- if (key->subkeys && (key->subkeys->timestamp > 0))
- {
- tt = key->subkeys->timestamp;
+ if (key->subkeys && (key->subkeys->timestamp > 0)) {
+ tt = key->subkeys->timestamp;
- tm = localtime (&tt);
+ tm = localtime (&tt);
#ifdef HAVE_LANGINFO_D_T_FMT
- strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
+ strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
#else
- strftime (shortbuf, sizeof shortbuf, "%c", tm);
+ strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
- fprintf (fp, "Valid From : %s\n", shortbuf);
- }
-
- if (key->subkeys && (key->subkeys->expires > 0))
- {
- tt = key->subkeys->expires;
-
- tm = localtime (&tt);
+ fprintf (fp, "Valid From : %s\n", shortbuf);
+ }
+
+ if (key->subkeys && (key->subkeys->expires > 0)) {
+ tt = key->subkeys->expires;
+
+ tm = localtime (&tt);
#ifdef HAVE_LANGINFO_D_T_FMT
- strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
+ strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
#else
- strftime (shortbuf, sizeof shortbuf, "%c", tm);
+ strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
- fprintf (fp, "Valid To ..: %s\n", shortbuf);
- }
+ fprintf (fp, "Valid To ..: %s\n", shortbuf);
+ }
if (key->subkeys)
s = gpgme_pubkey_algo_name (key->subkeys->pubkey_algo);
fprintf (fp, "Key Usage .: ");
delim = "";
- if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT))
- {
- fprintf (fp, "%s%s", delim, _("encryption"));
- delim = ", ";
- }
- if (key_check_cap (key, KEY_CAP_CAN_SIGN))
- {
- fprintf (fp, "%s%s", delim, _("signing"));
- delim = ", ";
- }
- if (key_check_cap (key, KEY_CAP_CAN_CERTIFY))
- {
- fprintf (fp, "%s%s", delim, _("certification"));
- delim = ", ";
- }
+ if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT)) {
+ fprintf (fp, "%s%s", delim, _("encryption"));
+ delim = ", ";
+ }
+ if (key_check_cap (key, KEY_CAP_CAN_SIGN)) {
+ fprintf (fp, "%s%s", delim, _("signing"));
+ delim = ", ";
+ }
+ if (key_check_cap (key, KEY_CAP_CAN_CERTIFY)) {
+ fprintf (fp, "%s%s", delim, _("certification"));
+ delim = ", ";
+ }
putc ('\n', fp);
- if (key->subkeys)
- {
- s = key->subkeys->fpr;
- fputs (_("Fingerprint: "), fp);
- if (is_pgp && strlen (s) == 40)
- {
- for (i=0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++)
- {
- putc (*s, fp);
- putc (s[1], fp);
- putc (s[2], fp);
- putc (s[3], fp);
- putc (is_pgp? ' ':':', fp);
- if (is_pgp && i == 4)
- putc (' ', fp);
- }
- }
- else
- {
- for (i=0; *s && s[1] && s[2]; s += 2, i++)
- {
- putc (*s, fp);
- putc (s[1], fp);
- putc (is_pgp? ' ':':', fp);
- if (is_pgp && i == 7)
- putc (' ', fp);
- }
- }
- fprintf (fp, "%s\n", s);
+ if (key->subkeys) {
+ s = key->subkeys->fpr;
+ fputs (_("Fingerprint: "), fp);
+ if (is_pgp && strlen (s) == 40) {
+ for (i = 0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++) {
+ putc (*s, fp);
+ putc (s[1], fp);
+ putc (s[2], fp);
+ putc (s[3], fp);
+ putc (is_pgp ? ' ' : ':', fp);
+ if (is_pgp && i == 4)
+ putc (' ', fp);
+ }
}
-
- if (key->issuer_serial)
- {
- s = key->issuer_serial;
- if (s)
- fprintf (fp, "Serial-No .: 0x%s\n", s);
+ else {
+ for (i = 0; *s && s[1] && s[2]; s += 2, i++) {
+ putc (*s, fp);
+ putc (s[1], fp);
+ putc (is_pgp ? ' ' : ':', fp);
+ if (is_pgp && i == 7)
+ putc (' ', fp);
+ }
}
+ fprintf (fp, "%s\n", s);
+ }
- if (key->issuer_name)
- {
- s = key->issuer_name;
- if (s)
- {
- fprintf (fp, "Issued By .: ");
- parse_and_print_user_id (fp, s);
- putc ('\n', fp);
- }
+ if (key->issuer_serial) {
+ s = key->issuer_serial;
+ if (s)
+ fprintf (fp, "Serial-No .: 0x%s\n", s);
+ }
+
+ if (key->issuer_name) {
+ s = key->issuer_name;
+ if (s) {
+ fprintf (fp, "Issued By .: ");
+ parse_and_print_user_id (fp, s);
+ putc ('\n', fp);
}
+ }
/* For PGP we list all subkeys. */
- if (is_pgp)
- {
- gpgme_subkey_t subkey = NULL;
-
- for (idx = 1, subkey = key->subkeys; subkey;
- idx++, subkey = subkey->next)
- {
- s = subkey->keyid;
-
- putc ('\n', fp);
- if ( strlen (s) == 16)
- s += 8; /* display only the short keyID */
- fprintf (fp, "Subkey ....: 0x%s", s);
- if (subkey->revoked)
- {
- putc (' ', fp);
- fputs (_("[Revoked]"), fp);
- }
- if (subkey->invalid)
- {
- putc (' ', fp);
- fputs (_("[Invalid]"), fp);
- }
- if (subkey->expired)
- {
- putc (' ', fp);
- fputs (_("[Expired]"), fp);
- }
- if (subkey->disabled)
- {
- putc (' ', fp);
- fputs (_("[Disabled]"), fp);
- }
- putc ('\n', fp);
+ if (is_pgp) {
+ gpgme_subkey_t subkey = NULL;
+
+ for (idx = 1, subkey = key->subkeys; subkey; idx++, subkey = subkey->next) {
+ s = subkey->keyid;
+
+ putc ('\n', fp);
+ if (strlen (s) == 16)
+ s += 8; /* display only the short keyID */
+ fprintf (fp, "Subkey ....: 0x%s", s);
+ if (subkey->revoked) {
+ putc (' ', fp);
+ fputs (_("[Revoked]"), fp);
+ }
+ if (subkey->invalid) {
+ putc (' ', fp);
+ fputs (_("[Invalid]"), fp);
+ }
+ if (subkey->expired) {
+ putc (' ', fp);
+ fputs (_("[Expired]"), fp);
+ }
+ if (subkey->disabled) {
+ putc (' ', fp);
+ fputs (_("[Disabled]"), fp);
+ }
+ putc ('\n', fp);
- if (subkey->timestamp > 0)
- {
- tt = subkey->timestamp;
+ if (subkey->timestamp > 0) {
+ tt = subkey->timestamp;
- tm = localtime (&tt);
+ tm = localtime (&tt);
#ifdef HAVE_LANGINFO_D_T_FMT
- strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
+ strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
#else
- strftime (shortbuf, sizeof shortbuf, "%c", tm);
+ strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
- fprintf (fp, "Valid From : %s\n", shortbuf);
- }
+ fprintf (fp, "Valid From : %s\n", shortbuf);
+ }
- if (subkey->expires > 0)
- {
- tt = subkey->expires;
+ if (subkey->expires > 0) {
+ tt = subkey->expires;
- tm = localtime (&tt);
+ tm = localtime (&tt);
#ifdef HAVE_LANGINFO_D_T_FMT
- strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
+ strftime (shortbuf, sizeof shortbuf, nl_langinfo (D_T_FMT), tm);
#else
- strftime (shortbuf, sizeof shortbuf, "%c", tm);
+ strftime (shortbuf, sizeof shortbuf, "%c", tm);
#endif
- fprintf (fp, "Valid To ..: %s\n", shortbuf);
- }
+ fprintf (fp, "Valid To ..: %s\n", shortbuf);
+ }
- if (subkey)
- s = gpgme_pubkey_algo_name (subkey->pubkey_algo);
- else
- s = "?";
+ if (subkey)
+ s = gpgme_pubkey_algo_name (subkey->pubkey_algo);
+ else
+ s = "?";
- if (subkey)
- aval = subkey->length;
- else
- aval = 0;
+ if (subkey)
+ aval = subkey->length;
+ else
+ aval = 0;
- fprintf (fp, "Key Type ..: %s, %lu bit %s\n", "PGP", aval, s);
+ fprintf (fp, "Key Type ..: %s, %lu bit %s\n", "PGP", aval, s);
- fprintf (fp, "Key Usage .: ");
- delim = "";
+ fprintf (fp, "Key Usage .: ");
+ delim = "";
- if (subkey->can_encrypt)
- {
- fprintf (fp, "%s%s", delim, _("encryption"));
- delim = ", ";
- }
- if (subkey->can_sign)
- {
- fprintf (fp, "%s%s", delim, _("signing"));
- delim = ", ";
- }
- if (subkey->can_certify)
- {
- fprintf (fp, "%s%s", delim, _("certification"));
- delim = ", ";
- }
- putc ('\n', fp);
- }
+ if (subkey->can_encrypt) {
+ fprintf (fp, "%s%s", delim, _("encryption"));
+ delim = ", ";
+ }
+ if (subkey->can_sign) {
+ fprintf (fp, "%s%s", delim, _("signing"));
+ delim = ", ";
+ }
+ if (subkey->can_certify) {
+ fprintf (fp, "%s%s", delim, _("certification"));
+ delim = ", ";
+ }
+ putc ('\n', fp);
}
+ }
if (Locale)
setlocale (LC_TIME, "C");
/* Show detailed information about the selected key */
-static void
-verify_key (crypt_key_t *key)
+static void verify_key (crypt_key_t * key)
{
FILE *fp;
char cmd[LONG_STRING], tempfile[_POSIX_PATH_MAX];
int maxdepth = 100;
mutt_mktemp (tempfile);
- if (!(fp = safe_fopen (tempfile, "w")))
- {
- mutt_perror _("Can't create temporary file");
- return;
- }
+ if (!(fp = safe_fopen (tempfile, "w"))) {
+ mutt_perror _("Can't create temporary file");
+
+ return;
+ }
mutt_message _("Collecting data...");
print_key_info (key->kobj, fp);
err = gpgme_new (&listctx);
- if (err)
- {
- fprintf (fp, "Internal error: can't create gpgme context: %s\n",
- gpgme_strerror (err));
- goto leave;
- }
+ if (err) {
+ fprintf (fp, "Internal error: can't create gpgme context: %s\n",
+ gpgme_strerror (err));
+ goto leave;
+ }
if ((key->flags & KEYFLAG_ISX509))
- gpgme_set_protocol (listctx, GPGME_PROTOCOL_CMS);
+ gpgme_set_protocol (listctx, GPGME_PROTOCOL_CMS);
k = key->kobj;
gpgme_key_ref (k);
- while ((s = k->chain_id) && k->subkeys && strcmp (s, k->subkeys->fpr) )
- {
+ while ((s = k->chain_id) && k->subkeys && strcmp (s, k->subkeys->fpr)) {
+ putc ('\n', fp);
+ err = gpgme_op_keylist_start (listctx, s, 0);
+ gpgme_key_release (k);
+ k = NULL;
+ if (!err)
+ err = gpgme_op_keylist_next (listctx, &k);
+ if (err) {
+ fprintf (fp, _("Error finding issuer key: %s\n"), gpgme_strerror (err));
+ goto leave;
+ }
+ gpgme_op_keylist_end (listctx);
+
+ print_key_info (k, fp);
+ if (!--maxdepth) {
putc ('\n', fp);
- err = gpgme_op_keylist_start (listctx, s, 0);
- gpgme_key_release (k);
- k = NULL;
- if (!err)
- err = gpgme_op_keylist_next (listctx, &k);
- if (err)
- {
- fprintf (fp, _("Error finding issuer key: %s\n"),
- gpgme_strerror (err));
- goto leave;
- }
- gpgme_op_keylist_end (listctx);
-
- print_key_info (k, fp);
- if (!--maxdepth)
- {
- putc ('\n', fp);
- fputs (_("Error: certification chain to long - stopping here\n"),
- fp);
- break;
- }
+ fputs (_("Error: certification chain to long - stopping here\n"), fp);
+ break;
}
+ }
- leave:
+leave:
gpgme_key_release (k);
gpgme_release (listctx);
fclose (fp);
mutt_clear_error ();
- snprintf (cmd, sizeof (cmd), _("Key ID: 0x%s"), crypt_keyid (key));
+ snprintf (cmd, sizeof (cmd), _("Key ID: 0x%s"), crypt_keyid (key));
mutt_do_pager (cmd, tempfile, 0, NULL);
}
/* Convert LIST into a pattern string suitable to be passed to GPGME.
We need to convert spaces in an item into a '+' and '%' into
"%25". */
-static char *list_to_pattern (LIST *list)
+static char *list_to_pattern (LIST * list)
{
LIST *l;
char *pattern, *p;
size_t n;
n = 0;
- for(l=list; l; l = l->next)
- {
- for(s = l->data; *s; s++)
- {
- if (*s == '%')
- n += 2;
- n++;
- }
- n++; /* delimiter or end of string */
+ for (l = list; l; l = l->next) {
+ for (s = l->data; *s; s++) {
+ if (*s == '%')
+ n += 2;
+ n++;
}
- n++; /* make sure to allocate at least one byte */
- pattern = p = safe_calloc (1,n);
- for(l=list; l; l = l->next)
- {
- s = l->data;
- if (*s)
- {
- if (l != list)
- *p++ = ' ';
- for(s = l->data; *s; s++)
- {
- if (*s == '%')
- {
- *p++ = '%';
- *p++ = '2';
- *p++ = '5';
- }
- else if (*s == '+')
- {
- *p++ = '%';
- *p++ = '2';
- *p++ = 'B';
- }
- else if (*s == ' ')
- *p++ = '+';
- else
- *p++ = *s;
- }
+ n++; /* delimiter or end of string */
+ }
+ n++; /* make sure to allocate at least one byte */
+ pattern = p = safe_calloc (1, n);
+ for (l = list; l; l = l->next) {
+ s = l->data;
+ if (*s) {
+ if (l != list)
+ *p++ = ' ';
+ for (s = l->data; *s; s++) {
+ if (*s == '%') {
+ *p++ = '%';
+ *p++ = '2';
+ *p++ = '5';
}
+ else if (*s == '+') {
+ *p++ = '%';
+ *p++ = '2';
+ *p++ = 'B';
+ }
+ else if (*s == ' ')
+ *p++ = '+';
+ else
+ *p++ = *s;
+ }
}
+ }
*p = 0;
return pattern;
}
/* Return a list of keys which are candidates for the selection.
Select by looking at the HINTS list. */
-static crypt_key_t *get_candidates (LIST * hints, unsigned int app, int secret)
+static crypt_key_t *get_candidates (LIST * hints, unsigned int app,
+ int secret)
{
crypt_key_t *db, *k, **kend;
char *pattern;
pattern = list_to_pattern (hints);
if (!pattern)
return NULL;
-
+
err = gpgme_new (&ctx);
- if (err)
- {
- mutt_error ("gpgme_new failed: %s", gpgme_strerror (err));
+ if (err) {
+ mutt_error ("gpgme_new failed: %s", gpgme_strerror (err));
+ FREE (&pattern);
+ return NULL;
+ }
+
+ db = NULL;
+ kend = &db;
+
+ if ((app & APPLICATION_PGP)) {
+ /* Its all a mess. That old GPGME expects different things
+ depending on the protocol. For gpg we don' t need percent
+ escaped pappert but simple strings passed in an array to the
+ keylist_ext_start function. */
+ LIST *l;
+ size_t n;
+ char **patarr;
+
+ for (l = hints, n = 0; l; l = l->next) {
+ if (l->data && *l->data)
+ n++;
+ }
+ if (!n)
+ goto no_pgphints;
+
+ patarr = safe_calloc (n + 1, sizeof *patarr);
+ for (l = hints, n = 0; l; l = l->next) {
+ if (l->data && *l->data)
+ patarr[n++] = safe_strdup (l->data);
+ }
+ patarr[n] = NULL;
+ err = gpgme_op_keylist_ext_start (ctx, (const char **) patarr, secret, 0);
+ for (n = 0; patarr[n]; n++)
+ FREE (&patarr[n]);
+ FREE (&patarr);
+ if (err) {
+ mutt_error ("gpgme_op_keylist_start failed: %s", gpgme_strerror (err));
+ gpgme_release (ctx);
FREE (&pattern);
return NULL;
}
- db = NULL;
- kend = &db;
-
- if ((app & APPLICATION_PGP))
- {
- /* Its all a mess. That old GPGME expects different things
- depending on the protocol. For gpg we don' t need percent
- escaped pappert but simple strings passed in an array to the
- keylist_ext_start function. */
- LIST *l;
- size_t n;
- char **patarr;
-
- for(l=hints, n=0; l; l = l->next)
- {
- if (l->data && *l->data)
- n++;
- }
- if (!n)
- goto no_pgphints;
-
- patarr = safe_calloc (n+1, sizeof *patarr);
- for(l=hints, n=0; l; l = l->next)
- {
- if (l->data && *l->data)
- patarr[n++] = safe_strdup (l->data);
- }
- patarr[n] = NULL;
- err = gpgme_op_keylist_ext_start (ctx, (const char**)patarr, secret, 0);
- for (n=0; patarr[n]; n++)
- FREE (&patarr[n]);
- FREE (&patarr);
- if (err)
- {
- mutt_error ("gpgme_op_keylist_start failed: %s",
- gpgme_strerror (err));
- gpgme_release (ctx);
- FREE (&pattern);
- return NULL;
- }
+ while (!(err = gpgme_op_keylist_next (ctx, &key))) {
+ unsigned int flags = 0;
- while (!(err = gpgme_op_keylist_next (ctx, &key)) )
- {
- unsigned int flags = 0;
-
- if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT))
- flags |= KEYFLAG_CANENCRYPT;
- if (key_check_cap (key, KEY_CAP_CAN_SIGN))
- flags |= KEYFLAG_CANSIGN;
-
-#if 0 /* DISABLED code */
- if (!flags)
- {
- /* Bug in gpg. Capabilities are not listed for secret
- keys. Try to deduce them from the algorithm. */
-
- switch (key->subkeys[0].pubkey_algo)
- {
- case GPGME_PK_RSA:
- flags |= KEYFLAG_CANENCRYPT;
- flags |= KEYFLAG_CANSIGN;
- break;
- case GPGME_PK_ELG_E:
- flags |= KEYFLAG_CANENCRYPT;
- break;
- case GPGME_PK_DSA:
- flags |= KEYFLAG_CANSIGN;
- break;
- }
- }
-#endif /* DISABLED code */
+ if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT))
+ flags |= KEYFLAG_CANENCRYPT;
+ if (key_check_cap (key, KEY_CAP_CAN_SIGN))
+ flags |= KEYFLAG_CANSIGN;
- for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
- {
- k = safe_calloc (1, sizeof *k);
- k->kobj = key;
- k->idx = idx;
- k->uid = uid->uid;
- k->flags = flags;
- *kend = k;
- kend = &k->next;
- }
+#if 0 /* DISABLED code */
+ if (!flags) {
+ /* Bug in gpg. Capabilities are not listed for secret
+ keys. Try to deduce them from the algorithm. */
+
+ switch (key->subkeys[0].pubkey_algo) {
+ case GPGME_PK_RSA:
+ flags |= KEYFLAG_CANENCRYPT;
+ flags |= KEYFLAG_CANSIGN;
+ break;
+ case GPGME_PK_ELG_E:
+ flags |= KEYFLAG_CANENCRYPT;
+ break;
+ case GPGME_PK_DSA:
+ flags |= KEYFLAG_CANSIGN;
+ break;
}
- if (gpg_err_code (err) != GPG_ERR_EOF)
- mutt_error ("gpgme_op_keylist_next failed: %s", gpgme_strerror (err));
- gpgme_op_keylist_end (ctx);
- no_pgphints:
- ;
+ }
+#endif /* DISABLED code */
+
+ for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next) {
+ k = safe_calloc (1, sizeof *k);
+ k->kobj = key;
+ k->idx = idx;
+ k->uid = uid->uid;
+ k->flags = flags;
+ *kend = k;
+ kend = &k->next;
+ }
}
+ if (gpg_err_code (err) != GPG_ERR_EOF)
+ mutt_error ("gpgme_op_keylist_next failed: %s", gpgme_strerror (err));
+ gpgme_op_keylist_end (ctx);
+ no_pgphints:
+ ;
+ }
- if ((app & APPLICATION_SMIME))
- {
- /* and now look for x509 certificates */
- gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
- err = gpgme_op_keylist_start (ctx, pattern, 0);
- if (err)
- {
- mutt_error ("gpgme_op_keylist_start failed: %s",
- gpgme_strerror (err));
- gpgme_release (ctx);
- FREE (&pattern);
- return NULL;
- }
+ if ((app & APPLICATION_SMIME)) {
+ /* and now look for x509 certificates */
+ gpgme_set_protocol (ctx, GPGME_PROTOCOL_CMS);
+ err = gpgme_op_keylist_start (ctx, pattern, 0);
+ if (err) {
+ mutt_error ("gpgme_op_keylist_start failed: %s", gpgme_strerror (err));
+ gpgme_release (ctx);
+ FREE (&pattern);
+ return NULL;
+ }
- while (!(err = gpgme_op_keylist_next (ctx, &key)) )
- {
- unsigned int flags = KEYFLAG_ISX509;
-
- if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT))
- flags |= KEYFLAG_CANENCRYPT;
- if (key_check_cap (key, KEY_CAP_CAN_SIGN))
- flags |= KEYFLAG_CANSIGN;
-
- for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
- {
- k = safe_calloc (1, sizeof *k);
- k->kobj = key;
- k->idx = idx;
- k->uid = uid->uid;
- k->flags = flags;
- *kend = k;
- kend = &k->next;
- }
- }
- if (gpg_err_code (err) != GPG_ERR_EOF)
- mutt_error ("gpgme_op_keylist_next failed: %s", gpgme_strerror (err));
- gpgme_op_keylist_end (ctx);
+ while (!(err = gpgme_op_keylist_next (ctx, &key))) {
+ unsigned int flags = KEYFLAG_ISX509;
+
+ if (key_check_cap (key, KEY_CAP_CAN_ENCRYPT))
+ flags |= KEYFLAG_CANENCRYPT;
+ if (key_check_cap (key, KEY_CAP_CAN_SIGN))
+ flags |= KEYFLAG_CANSIGN;
+
+ for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next) {
+ k = safe_calloc (1, sizeof *k);
+ k->kobj = key;
+ k->idx = idx;
+ k->uid = uid->uid;
+ k->flags = flags;
+ *kend = k;
+ kend = &k->next;
+ }
}
+ if (gpg_err_code (err) != GPG_ERR_EOF)
+ mutt_error ("gpgme_op_keylist_next failed: %s", gpgme_strerror (err));
+ gpgme_op_keylist_end (ctx);
+ }
gpgme_release (ctx);
FREE (&pattern);
/* Add the string STR to the list HINTS. This list is later used to
match addresses. */
-static LIST *crypt_add_string_to_hints (LIST *hints, const char *str)
+static LIST *crypt_add_string_to_hints (LIST * hints, const char *str)
{
char *scratch;
char *t;
return hints;
for (t = strtok (scratch, " ,.:\"()<>\n"); t;
- t = strtok (NULL, " ,.:\"()<>\n"))
- {
- if (strlen (t) > 3)
- hints = mutt_add_list (hints, t);
- }
-
+ t = strtok (NULL, " ,.:\"()<>\n")) {
+ if (strlen (t) > 3)
+ hints = mutt_add_list (hints, t);
+ }
+
FREE (&scratch);
return hints;
}
/* Display a menu to select a key from the array KEYS. FORCED_VALID
will be set to true on return if the user did override the the
key's validity. */
-static crypt_key_t *crypt_select_key (crypt_key_t *keys,
- ADDRESS * p, const char *s,
+static crypt_key_t *crypt_select_key (crypt_key_t * keys,
+ ADDRESS * p, const char *s,
unsigned int app, int *forced_valid)
{
int keymax;
/* build the key table */
keymax = i = 0;
key_table = NULL;
- for (k = keys; k; k = k->next)
- {
- if (!option (OPTPGPSHOWUNUSABLE) && (k->flags & KEYFLAG_CANTUSE))
- {
- unusable = 1;
- continue;
- }
-
- if (i == keymax)
- {
- keymax += 20;
- safe_realloc (&key_table, sizeof (crypt_key_t*)*keymax);
- }
-
- key_table[i++] = k;
+ for (k = keys; k; k = k->next) {
+ if (!option (OPTPGPSHOWUNUSABLE) && (k->flags & KEYFLAG_CANTUSE)) {
+ unusable = 1;
+ continue;
}
- if (!i && unusable)
- {
- mutt_error _("All matching keys are marked expired/revoked.");
- mutt_sleep (1);
- return NULL;
+ if (i == keymax) {
+ keymax += 20;
+ safe_realloc (&key_table, sizeof (crypt_key_t *) * keymax);
}
- switch (PgpSortKeys & SORT_MASK)
- {
- case SORT_DATE:
- f = crypt_compare_date;
- break;
- case SORT_KEYID:
- f = crypt_compare_keyid;
- break;
- case SORT_ADDRESS:
- f = crypt_compare_address;
- break;
- case SORT_TRUST:
- default:
- f = crypt_compare_trust;
- break;
+ key_table[i++] = k;
+ }
+
+ if (!i && unusable) {
+ mutt_error _("All matching keys are marked expired/revoked.");
+
+ mutt_sleep (1);
+ return NULL;
+ }
+
+ switch (PgpSortKeys & SORT_MASK) {
+ case SORT_DATE:
+ f = crypt_compare_date;
+ break;
+ case SORT_KEYID:
+ f = crypt_compare_keyid;
+ break;
+ case SORT_ADDRESS:
+ f = crypt_compare_address;
+ break;
+ case SORT_TRUST:
+ default:
+ f = crypt_compare_trust;
+ break;
}
- qsort (key_table, i, sizeof (crypt_key_t*), f);
+ qsort (key_table, i, sizeof (crypt_key_t *), f);
if (app & APPLICATION_PGP)
menu_to_use = MENU_KEY_SELECT_PGP;
helpstr[0] = 0;
mutt_make_help (buf, sizeof (buf), _("Exit "), menu_to_use, OP_EXIT);
- strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
+ strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
mutt_make_help (buf, sizeof (buf), _("Select "), menu_to_use,
- OP_GENERIC_SELECT_ENTRY);
- strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
+ OP_GENERIC_SELECT_ENTRY);
+ strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
mutt_make_help (buf, sizeof (buf), _("Check key "),
menu_to_use, OP_VERIFY_KEY);
- strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
+ strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
mutt_make_help (buf, sizeof (buf), _("Help"), menu_to_use, OP_HELP);
- strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
+ strcat (helpstr, buf); /* __STRCAT_CHECKED__ */
menu = mutt_new_menu ();
menu->max = i;
{
const char *ts;
- if ((app & APPLICATION_PGP) && (app & APPLICATION_SMIME))
+ if ((app & APPLICATION_PGP) && (app & APPLICATION_SMIME))
ts = _("PGP and S/MIME keys matching");
else if ((app & APPLICATION_PGP))
ts = _("PGP keys matching");
snprintf (buf, sizeof (buf), _("%s <%s>."), ts, p->mailbox);
else
snprintf (buf, sizeof (buf), _("%s \"%s\"."), ts, s);
- menu->title = buf;
+ menu->title = buf;
}
mutt_clear_error ();
k = NULL;
- while (!done)
- {
- *forced_valid = 0;
- switch (mutt_menuLoop (menu))
- {
- case OP_VERIFY_KEY:
- verify_key (key_table[menu->current]);
- menu->redraw = REDRAW_FULL;
- break;
-
- case OP_VIEW_ID:
- mutt_message ("%s", key_table[menu->current]->uid);
- break;
-
- case OP_GENERIC_SELECT_ENTRY:
- /* FIXME make error reporting more verbose - this should be
- easy because gpgme provides more information */
- if (option (OPTPGPCHECKTRUST))
- {
- if (!crypt_key_is_valid (key_table[menu->current]))
- {
- mutt_error _("This key can't be used: "
- "expired/disabled/revoked.");
- break;
- }
- }
-
- if (option (OPTPGPCHECKTRUST) &&
- (!crypt_id_is_valid (key_table[menu->current])
- || !crypt_id_is_strong (key_table[menu->current])))
- {
- const char *warn_s;
- char buff[LONG_STRING];
-
- if (key_table[menu->current]->flags & KEYFLAG_CANTUSE)
- s = N_("ID is expired/disabled/revoked.");
- else
- {
- gpgme_validity_t val = GPGME_VALIDITY_UNKNOWN;
- gpgme_user_id_t uid = NULL;
- unsigned int j = 0;
-
- warn_s = "??";
-
- uid = key_table[menu->current]->kobj->uids;
- for (j = 0; (j < key_table[menu->current]->idx) && uid;
- j++, uid = uid->next)
- ;
- if (uid)
- val = uid->validity;
-
- switch (val)
- {
- case GPGME_VALIDITY_UNKNOWN:
- case GPGME_VALIDITY_UNDEFINED:
- warn_s = N_("ID has undefined validity.");
- break;
- case GPGME_VALIDITY_NEVER:
- warn_s = N_("ID is not valid.");
- break;
- case GPGME_VALIDITY_MARGINAL:
- warn_s = N_("ID is only marginally valid.");
- break;
- case GPGME_VALIDITY_FULL:
- case GPGME_VALIDITY_ULTIMATE:
- break;
- }
-
- snprintf (buff, sizeof (buff),
- _("%s Do you really want to use the key?"),
- _(warn_s));
-
- if (mutt_yesorno (buff, 0) != 1)
- {
- mutt_clear_error ();
- break;
- }
- *forced_valid = 1;
- }
- }
-
- k = crypt_copy_key (key_table[menu->current]);
- done = 1;
- break;
-
- case OP_EXIT:
- k = NULL;
- done = 1;
+ while (!done) {
+ *forced_valid = 0;
+ switch (mutt_menuLoop (menu)) {
+ case OP_VERIFY_KEY:
+ verify_key (key_table[menu->current]);
+ menu->redraw = REDRAW_FULL;
+ break;
+
+ case OP_VIEW_ID:
+ mutt_message ("%s", key_table[menu->current]->uid);
+ break;
+
+ case OP_GENERIC_SELECT_ENTRY:
+ /* FIXME make error reporting more verbose - this should be
+ easy because gpgme provides more information */
+ if (option (OPTPGPCHECKTRUST)) {
+ if (!crypt_key_is_valid (key_table[menu->current])) {
+ mutt_error _("This key can't be used: "
+ "expired/disabled/revoked.");
break;
}
+ }
+
+ if (option (OPTPGPCHECKTRUST) &&
+ (!crypt_id_is_valid (key_table[menu->current])
+ || !crypt_id_is_strong (key_table[menu->current]))) {
+ const char *warn_s;
+ char buff[LONG_STRING];
+
+ if (key_table[menu->current]->flags & KEYFLAG_CANTUSE)
+ s = N_("ID is expired/disabled/revoked.");
+ else {
+ gpgme_validity_t val = GPGME_VALIDITY_UNKNOWN;
+ gpgme_user_id_t uid = NULL;
+ unsigned int j = 0;
+
+ warn_s = "??";
+
+ uid = key_table[menu->current]->kobj->uids;
+ for (j = 0; (j < key_table[menu->current]->idx) && uid;
+ j++, uid = uid->next);
+ if (uid)
+ val = uid->validity;
+
+ switch (val) {
+ case GPGME_VALIDITY_UNKNOWN:
+ case GPGME_VALIDITY_UNDEFINED:
+ warn_s = N_("ID has undefined validity.");
+ break;
+ case GPGME_VALIDITY_NEVER:
+ warn_s = N_("ID is not valid.");
+ break;
+ case GPGME_VALIDITY_MARGINAL:
+ warn_s = N_("ID is only marginally valid.");
+ break;
+ case GPGME_VALIDITY_FULL:
+ case GPGME_VALIDITY_ULTIMATE:
+ break;
+ }
+
+ snprintf (buff, sizeof (buff),
+ _("%s Do you really want to use the key?"), _(warn_s));
+
+ if (mutt_yesorno (buff, 0) != 1) {
+ mutt_clear_error ();
+ break;
+ }
+ *forced_valid = 1;
+ }
+ }
+
+ k = crypt_copy_key (key_table[menu->current]);
+ done = 1;
+ break;
+
+ case OP_EXIT:
+ k = NULL;
+ done = 1;
+ break;
}
-
+ }
+
mutt_menuDestroy (&menu);
FREE (&key_table);
set_option (OPTNEEDREDRAW);
-
+
return k;
}
static crypt_key_t *crypt_getkeybyaddr (ADDRESS * a, short abilities,
- unsigned int app, int *forced_valid)
+ unsigned int app, int *forced_valid)
{
ADDRESS *r, *p;
LIST *hints = NULL;
- int weak = 0;
+ int weak = 0;
int invalid = 0;
- int multi = 0;
+ int multi = 0;
int this_key_has_strong;
int this_key_has_weak;
int this_key_has_invalid;
crypt_key_t *the_valid_key = NULL;
crypt_key_t *matches = NULL;
crypt_key_t **matches_endp = &matches;
-
+
*forced_valid = 0;
if (a && a->mailbox)
hints = crypt_add_string_to_hints (hints, a->personal);
mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox);
- keys = get_candidates (hints, app, (abilities & KEYFLAG_CANSIGN) );
+ keys = get_candidates (hints, app, (abilities & KEYFLAG_CANSIGN));
mutt_free_list (&hints);
-
+
if (!keys)
return NULL;
-
+
dprint (5, (debugfile, "crypt_getkeybyaddr: looking for %s <%s>.",
- a->personal, a->mailbox));
+ a->personal, a->mailbox));
- for (k = keys; k; k = k->next)
- {
- dprint (5, (debugfile, " looking at key: %s `%.15s'\n",
- crypt_keyid (k), k->uid));
-
- if (abilities && !(k->flags & abilities))
- {
- dprint (5, (debugfile, " insufficient abilities: Has %x, want %x\n",
- k->flags, abilities));
- continue;
- }
+ for (k = keys; k; k = k->next) {
+ dprint (5, (debugfile, " looking at key: %s `%.15s'\n",
+ crypt_keyid (k), k->uid));
- this_key_has_weak = 0; /* weak but valid match */
- this_key_has_invalid = 0; /* invalid match */
- this_key_has_strong = 0; /* strong and valid match */
- match = 0; /* any match */
-
- r = rfc822_parse_adrlist (NULL, k->uid);
- for (p = r; p; p = p->next)
- {
- int validity = crypt_id_matches_addr (a, p, k);
-
- if (validity & CRYPT_KV_MATCH) /* something matches */
- match = 1;
-
- /* is this key a strong candidate? */
- if ((validity & CRYPT_KV_VALID)
- && (validity & CRYPT_KV_STRONGID)
- && (validity & CRYPT_KV_ADDR))
- {
- if (the_valid_key && the_valid_key != k)
- multi = 1;
- the_valid_key = k;
- this_key_has_strong = 1;
- }
- else if ((validity & CRYPT_KV_MATCH)
- && !(validity & CRYPT_KV_VALID))
- this_key_has_invalid = 1;
- else if ((validity & CRYPT_KV_MATCH)
- && (!(validity & CRYPT_KV_STRONGID)
- || !(validity & CRYPT_KV_ADDR)))
- this_key_has_weak = 1;
- }
- rfc822_free_address (&r);
-
- if (match)
- {
- crypt_key_t *tmp;
-
- if (!this_key_has_strong && this_key_has_invalid)
- invalid = 1;
- if (!this_key_has_strong && this_key_has_weak)
- weak = 1;
-
- *matches_endp = tmp = crypt_copy_key (k);
- matches_endp = &tmp->next;
- the_valid_key = tmp;
- }
+ if (abilities && !(k->flags & abilities)) {
+ dprint (5, (debugfile, " insufficient abilities: Has %x, want %x\n",
+ k->flags, abilities));
+ continue;
}
-
+
+ this_key_has_weak = 0; /* weak but valid match */
+ this_key_has_invalid = 0; /* invalid match */
+ this_key_has_strong = 0; /* strong and valid match */
+ match = 0; /* any match */
+
+ r = rfc822_parse_adrlist (NULL, k->uid);
+ for (p = r; p; p = p->next) {
+ int validity = crypt_id_matches_addr (a, p, k);
+
+ if (validity & CRYPT_KV_MATCH) /* something matches */
+ match = 1;
+
+ /* is this key a strong candidate? */
+ if ((validity & CRYPT_KV_VALID)
+ && (validity & CRYPT_KV_STRONGID)
+ && (validity & CRYPT_KV_ADDR)) {
+ if (the_valid_key && the_valid_key != k)
+ multi = 1;
+ the_valid_key = k;
+ this_key_has_strong = 1;
+ }
+ else if ((validity & CRYPT_KV_MATCH)
+ && !(validity & CRYPT_KV_VALID))
+ this_key_has_invalid = 1;
+ else if ((validity & CRYPT_KV_MATCH)
+ && (!(validity & CRYPT_KV_STRONGID)
+ || !(validity & CRYPT_KV_ADDR)))
+ this_key_has_weak = 1;
+ }
+ rfc822_free_address (&r);
+
+ if (match) {
+ crypt_key_t *tmp;
+
+ if (!this_key_has_strong && this_key_has_invalid)
+ invalid = 1;
+ if (!this_key_has_strong && this_key_has_weak)
+ weak = 1;
+
+ *matches_endp = tmp = crypt_copy_key (k);
+ matches_endp = &tmp->next;
+ the_valid_key = tmp;
+ }
+ }
+
crypt_free_key (&keys);
-
- if (matches)
- {
- if (the_valid_key && !multi && !weak
- && !(invalid && option (OPTPGPSHOWUNUSABLE)))
- {
- /*
- * There was precisely one strong match on a valid ID, there
- * were no valid keys with weak matches, and we aren't
- * interested in seeing invalid keys.
- *
- * Proceed without asking the user.
- */
- k = crypt_copy_key (the_valid_key);
- }
- else
- {
- /*
- * Else: Ask the user.
- */
- k = crypt_select_key (matches, a, NULL, app, forced_valid);
- }
- crypt_free_key (&matches);
+
+ if (matches) {
+ if (the_valid_key && !multi && !weak
+ && !(invalid && option (OPTPGPSHOWUNUSABLE))) {
+ /*
+ * There was precisely one strong match on a valid ID, there
+ * were no valid keys with weak matches, and we aren't
+ * interested in seeing invalid keys.
+ *
+ * Proceed without asking the user.
+ */
+ k = crypt_copy_key (the_valid_key);
+ }
+ else {
+ /*
+ * Else: Ask the user.
+ */
+ k = crypt_select_key (matches, a, NULL, app, forced_valid);
}
- else
+ crypt_free_key (&matches);
+ }
+ else
k = NULL;
-
+
return k;
}
static crypt_key_t *crypt_getkeybystr (char *p, short abilities,
- unsigned int app, int *forced_valid)
+ unsigned int app, int *forced_valid)
{
LIST *hints = NULL;
crypt_key_t *keys;
if (!keys)
return NULL;
-
- for (k = keys; k; k = k->next)
- {
- if (abilities && !(k->flags & abilities))
- continue;
- match = 0;
- dprint (5, (debugfile, "crypt_getkeybystr: matching \"%s\" against "
- "key %s, \"%s\": ", p, crypt_keyid (k), k->uid));
-
- if (!*p
- || !mutt_strcasecmp (p, crypt_keyid (k))
- || (!mutt_strncasecmp (p, "0x", 2)
- && !mutt_strcasecmp (p + 2, crypt_keyid (k)))
- || (option (OPTPGPLONGIDS)
- && !mutt_strncasecmp (p, "0x", 2)
- && !mutt_strcasecmp (p + 2, crypt_keyid (k) + 8))
- || mutt_stristr (k->uid, p))
- {
- crypt_key_t *tmp;
-
- dprint (5, (debugfile, "match.\n"));
-
- *matches_endp = tmp = crypt_copy_key (k);
- matches_endp = &tmp->next;
- }
+ for (k = keys; k; k = k->next) {
+ if (abilities && !(k->flags & abilities))
+ continue;
+
+ match = 0;
+ dprint (5, (debugfile, "crypt_getkeybystr: matching \"%s\" against "
+ "key %s, \"%s\": ", p, crypt_keyid (k), k->uid));
+
+ if (!*p || !mutt_strcasecmp (p, crypt_keyid (k))
+ || (!mutt_strncasecmp (p, "0x", 2)
+ && !mutt_strcasecmp (p + 2, crypt_keyid (k)))
+ || (option (OPTPGPLONGIDS)
+ && !mutt_strncasecmp (p, "0x", 2)
+ && !mutt_strcasecmp (p + 2, crypt_keyid (k) + 8))
+ || mutt_stristr (k->uid, p)) {
+ crypt_key_t *tmp;
+
+ dprint (5, (debugfile, "match.\n"));
+
+ *matches_endp = tmp = crypt_copy_key (k);
+ matches_endp = &tmp->next;
}
-
+ }
+
crypt_free_key (&keys);
-
- if (matches)
- {
- k = crypt_select_key (matches, NULL, p, app, forced_valid);
- crypt_free_key (&matches);
- return k;
- }
-
+
+ if (matches) {
+ k = crypt_select_key (matches, NULL, p, app, forced_valid);
+ crypt_free_key (&matches);
+ return k;
+ }
+
return NULL;
}
default. ABILITIES describe the required key abilities (sign,
encrypt) and APP the type of the requested key; ether S/MIME or
PGP. Return a copy of the key or NULL if not found. */
-static crypt_key_t *crypt_ask_for_key (char *tag,
- char *whatfor,
+static crypt_key_t *crypt_ask_for_key (char *tag,
+ char *whatfor,
short abilities,
- unsigned int app,
- int *forced_valid)
+ unsigned int app, int *forced_valid)
{
crypt_key_t *key;
char resp[SHORT_STRING];
*forced_valid = 0;
resp[0] = 0;
- if (whatfor)
- {
-
- for (l = id_defaults; l; l = l->next)
- if (!mutt_strcasecmp (whatfor, l->what))
- {
- strfcpy (resp, NONULL (l->dflt), sizeof (resp));
- break;
- }
- }
+ if (whatfor) {
+ for (l = id_defaults; l; l = l->next)
+ if (!mutt_strcasecmp (whatfor, l->what)) {
+ strfcpy (resp, NONULL (l->dflt), sizeof (resp));
+ break;
+ }
+ }
- for (;;)
- {
- resp[0] = 0;
- if (mutt_get_field (tag, resp, sizeof (resp), M_CLEAR) != 0)
- return NULL;
-
- if (whatfor)
- {
- if (l)
- mutt_str_replace (&l->dflt, resp);
- else
- {
- l = safe_malloc (sizeof (struct crypt_cache));
- l->next = id_defaults;
- id_defaults = l;
- l->what = safe_strdup (whatfor);
- l->dflt = safe_strdup (resp);
- }
- }
-
- if ((key = crypt_getkeybystr (resp, abilities, app, forced_valid)))
- return key;
-
- BEEP ();
+
+ for (;;) {
+ resp[0] = 0;
+ if (mutt_get_field (tag, resp, sizeof (resp), M_CLEAR) != 0)
+ return NULL;
+
+ if (whatfor) {
+ if (l)
+ mutt_str_replace (&l->dflt, resp);
+ else {
+ l = safe_malloc (sizeof (struct crypt_cache));
+ l->next = id_defaults;
+ id_defaults = l;
+ l->what = safe_strdup (whatfor);
+ l->dflt = safe_strdup (resp);
+ }
}
+
+ if ((key = crypt_getkeybystr (resp, abilities, app, forced_valid)))
+ return key;
+
+ BEEP ();
+ }
/* not reached */
}
/* This routine attempts to find the keyids of the recipients of a
message. It returns NULL if any of the keys can not be found. */
-static char *find_keys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc,
+static char *find_keys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc,
unsigned int app)
{
char *keyID, *keylist = NULL, *t;
const char *fqdn = mutt_fqdn (1);
#if 0
- *r_application = APPLICATION_PGP|APPLICATION_SMIME;
+ *r_application = APPLICATION_PGP | APPLICATION_SMIME;
#endif
-
- 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);
+
+ 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);
+ }
+
if (fqdn)
rfc822_qualify (tmp, fqdn);
-
+
tmp = mutt_remove_duplicates (tmp);
-
- for (p = tmp; p ; p = p->next)
- {
- char buf[LONG_STRING];
- int forced_valid = 0;
-
- q = p;
- k_info = NULL;
-
- if ((keyID = mutt_crypt_hook (p)) != NULL)
- {
- int r;
- snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"),
- keyID, p->mailbox);
- if ((r = mutt_yesorno (buf, M_YES)) == M_YES)
- {
- /* check for e-mail address */
- if ((t = strchr (keyID, '@')) &&
- (addr = rfc822_parse_adrlist (NULL, keyID)))
- {
- if (fqdn)
- rfc822_qualify (addr, fqdn);
- q = addr;
- }
- else
- {
-#if 0
- k_info = crypt_getkeybystr (keyID, KEYFLAG_CANENCRYPT,
- *r_application, &forced_valid);
+
+ for (p = tmp; p; p = p->next) {
+ char buf[LONG_STRING];
+ int forced_valid = 0;
+
+ q = p;
+ k_info = NULL;
+
+ if ((keyID = mutt_crypt_hook (p)) != NULL) {
+ int r;
+
+ snprintf (buf, sizeof (buf), _("Use keyID = \"%s\" for %s?"),
+ keyID, p->mailbox);
+ if ((r = mutt_yesorno (buf, M_YES)) == M_YES) {
+ /* check for e-mail address */
+ if ((t = strchr (keyID, '@')) &&
+ (addr = rfc822_parse_adrlist (NULL, keyID))) {
+ if (fqdn)
+ rfc822_qualify (addr, fqdn);
+ q = addr;
+ }
+ else {
+#if 0
+ k_info = crypt_getkeybystr (keyID, KEYFLAG_CANENCRYPT,
+ *r_application, &forced_valid);
#else
- k_info = crypt_getkeybystr (keyID, KEYFLAG_CANENCRYPT,
- app, &forced_valid);
+ k_info = crypt_getkeybystr (keyID, KEYFLAG_CANENCRYPT,
+ app, &forced_valid);
#endif
- }
- }
- else if (r == -1)
- {
- FREE (&keylist);
- rfc822_free_address (&tmp);
- rfc822_free_address (&addr);
- return NULL;
- }
}
+ }
+ else if (r == -1) {
+ FREE (&keylist);
+ rfc822_free_address (&tmp);
+ rfc822_free_address (&addr);
+ return NULL;
+ }
+ }
- if (k_info == NULL
- && (k_info = crypt_getkeybyaddr (q, KEYFLAG_CANENCRYPT,
- app, &forced_valid)) == NULL)
- {
- snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
-
- if ((key = crypt_ask_for_key (buf, q->mailbox,
- KEYFLAG_CANENCRYPT,
+ if (k_info == NULL
+ && (k_info = crypt_getkeybyaddr (q, KEYFLAG_CANENCRYPT,
+ app, &forced_valid)) == NULL) {
+ snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox);
+
+ if ((key = crypt_ask_for_key (buf, q->mailbox, KEYFLAG_CANENCRYPT,
#if 0
- *r_application,
+ *r_application,
#else
- app,
+ app,
#endif
- &forced_valid)) == NULL)
- {
- FREE (&keylist);
- rfc822_free_address (&tmp);
- rfc822_free_address (&addr);
- return NULL;
- }
- }
- else
- key = k_info;
+ &forced_valid)) == NULL) {
+ FREE (&keylist);
+ rfc822_free_address (&tmp);
+ rfc822_free_address (&addr);
+ return NULL;
+ }
+ }
+ else
+ key = k_info;
- {
- const char *s = crypt_fpr (key);
+ {
+ const char *s = crypt_fpr (key);
#if 0
- if (key->flags & KEYFLAG_ISX509)
- *r_application &= ~APPLICATION_PGP;
- if (!(key->flags & KEYFLAG_ISX509))
- *r_application &= ~APPLICATION_SMIME;
+ if (key->flags & KEYFLAG_ISX509)
+ *r_application &= ~APPLICATION_PGP;
+ if (!(key->flags & KEYFLAG_ISX509))
+ *r_application &= ~APPLICATION_SMIME;
#endif
-
- keylist_size += mutt_strlen (s) + 4 + 1;
- safe_realloc (&keylist, keylist_size);
- sprintf (keylist + keylist_used, "%s0x%s%s", /* __SPRINTF_CHECKED__ */
- keylist_used ? " " : "", s,
- forced_valid? "!":"");
- }
- keylist_used = mutt_strlen (keylist);
-
- crypt_free_key (&key);
- rfc822_free_address (&addr);
+
+ keylist_size += mutt_strlen (s) + 4 + 1;
+ safe_realloc (&keylist, keylist_size);
+ sprintf (keylist + keylist_used, "%s0x%s%s", /* __SPRINTF_CHECKED__ */
+ keylist_used ? " " : "", s, forced_valid ? "!" : "");
}
+ keylist_used = mutt_strlen (keylist);
+
+ crypt_free_key (&key);
+ rfc822_free_address (&addr);
+ }
rfc822_free_address (&tmp);
return (keylist);
}
-char *pgp_gpgme_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
+char *pgp_gpgme_findkeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc)
{
return find_keys (to, cc, bcc, APPLICATION_PGP);
}
-char *smime_gpgme_findkeys (ADDRESS *to, ADDRESS *cc, ADDRESS *bcc)
+char *smime_gpgme_findkeys (ADDRESS * to, ADDRESS * cc, ADDRESS * bcc)
{
return find_keys (to, cc, bcc, APPLICATION_SMIME);
}
static void init_gpgme (void)
{
/* Make sure that gpg-agent is running. */
- if (! getenv ("GPG_AGENT_INFO"))
- {
- mutt_error ("\nUsing GPGME backend, although no gpg-agent is running");
- if (mutt_any_key_to_continue (NULL) == -1)
- mutt_exit(1);
- }
+ if (!getenv ("GPG_AGENT_INFO")) {
+ mutt_error ("\nUsing GPGME backend, although no gpg-agent is running");
+ if (mutt_any_key_to_continue (NULL) == -1)
+ mutt_exit (1);
+ }
}
void pgp_gpgme_init (void)
{
}
-static int gpgme_send_menu (HEADER *msg, int *redraw, int is_smime)
+static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime)
{
crypt_key_t *p;
char input_signas[SHORT_STRING];
is_smime = 1;
if (is_smime)
- choice = mutt_multi_choice (
- _("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (t)oggle or (f)orget it?"),
- _("esabtf"));
- else
- choice = mutt_multi_choice (
- _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (t)oggle or (f)orget it?"),
- _("esabtf"));
-
- switch (choice)
- {
- case 1: /* (e)ncrypt */
+ choice =
+ mutt_multi_choice (_
+ ("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (t)oggle or (f)orget it?"),
+ _("esabtf"));
+ else
+ choice =
+ mutt_multi_choice (_
+ ("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (t)oggle or (f)orget it?"),
+ _("esabtf"));
+
+ switch (choice) {
+ case 1: /* (e)ncrypt */
msg->security |= (is_smime ? SMIMEENCRYPT : PGPENCRYPT);
break;
- case 2: /* (s)ign */
- msg->security |= (is_smime? SMIMESIGN :PGPSIGN);
+ case 2: /* (s)ign */
+ msg->security |= (is_smime ? SMIMESIGN : PGPSIGN);
break;
- case 3: /* sign (a)s */
+ case 3: /* sign (a)s */
/* unset_option(OPTCRYPTCHECKTRUST); */
if ((p = crypt_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN,
- is_smime? APPLICATION_SMIME:APPLICATION_PGP,
- NULL)))
- {
+ is_smime ? APPLICATION_SMIME :
+ APPLICATION_PGP, NULL))) {
snprintf (input_signas, sizeof (input_signas), "0x%s", crypt_keyid (p));
- mutt_str_replace (is_smime? &SmimeDefaultKey : &PgpSignAs, input_signas);
- crypt_free_key (&p);
-
- msg->security |= (is_smime? SMIMESIGN:PGPSIGN);
+ mutt_str_replace (is_smime ? &SmimeDefaultKey : &PgpSignAs,
+ input_signas);
+ crypt_free_key (&p);
+
+ msg->security |= (is_smime ? SMIMESIGN : PGPSIGN);
}
- else
- {
- msg->security &= (is_smime? ~SMIMESIGN : ~PGPSIGN);
+ else {
+ msg->security &= (is_smime ? ~SMIMESIGN : ~PGPSIGN);
}
*redraw = REDRAW_FULL;
break;
- case 4: /* (b)oth */
- msg->security = (is_smime? (SMIMEENCRYPT|SMIMESIGN):(PGPENCRYPT|PGPSIGN));
+ case 4: /* (b)oth */
+ msg->security =
+ (is_smime ? (SMIMEENCRYPT | SMIMESIGN) : (PGPENCRYPT | PGPSIGN));
break;
- case 5: /* (t)oggle */
+ case 5: /* (t)oggle */
is_smime = !is_smime;
break;
- case 6: /* (f)orget it */
+ case 6: /* (f)orget it */
msg->security = 0;
break;
}
- if (choice == 6)
- ;
- else if (is_smime)
- {
- msg->security &= ~APPLICATION_PGP;
- msg->security |= APPLICATION_SMIME;
- }
- else
- {
- msg->security &= ~APPLICATION_SMIME;
- msg->security |= APPLICATION_PGP;
- }
-
+ if (choice == 6);
+ else if (is_smime) {
+ msg->security &= ~APPLICATION_PGP;
+ msg->security |= APPLICATION_SMIME;
+ }
+ else {
+ msg->security &= ~APPLICATION_SMIME;
+ msg->security |= APPLICATION_PGP;
+ }
+
return (msg->security);
}
-int pgp_gpgme_send_menu (HEADER *msg, int *redraw)
+int pgp_gpgme_send_menu (HEADER * msg, int *redraw)
{
return gpgme_send_menu (msg, redraw, 0);
}
-int smime_gpgme_send_menu (HEADER *msg, int *redraw)
+int smime_gpgme_send_menu (HEADER * msg, int *redraw)
{
return gpgme_send_menu (msg, redraw, 1);
}
-static int verify_sender (HEADER *h, gpgme_protocol_t protocol)
+static int verify_sender (HEADER * h, gpgme_protocol_t protocol)
{
ADDRESS *sender = NULL;
unsigned int ret = 1;
- if (h->env->from)
- {
- h->env->from = mutt_expand_aliases (h->env->from);
- sender = h->env->from;
- }
- else if (h->env->sender)
- {
- h->env->sender = mutt_expand_aliases (h->env->sender);
- sender = h->env->sender;
- }
+ if (h->env->from) {
+ h->env->from = mutt_expand_aliases (h->env->from);
+ sender = h->env->from;
+ }
+ else if (h->env->sender) {
+ h->env->sender = mutt_expand_aliases (h->env->sender);
+ sender = h->env->sender;
+ }
- if (sender)
- {
- if (signature_key)
- {
- gpgme_key_t key = signature_key;
- gpgme_user_id_t uid = NULL;
- int sender_length = 0;
- int uid_length = 0;
-
- sender_length = strlen (sender->mailbox);
- for (uid = key->uids; uid && ret; uid = uid->next)
- {
- uid_length = strlen (uid->email);
- if (1
- && (uid->email[0] == '<')
- && (uid->email[uid_length - 1] == '>')
- && (uid_length == sender_length + 2)
- && (! strncmp (uid->email + 1, sender->mailbox, sender_length)))
- ret = 0;
- }
- }
- else
- mutt_any_key_to_continue ("Failed to verify sender");
+ if (sender) {
+ if (signature_key) {
+ gpgme_key_t key = signature_key;
+ gpgme_user_id_t uid = NULL;
+ int sender_length = 0;
+ int uid_length = 0;
+
+ sender_length = strlen (sender->mailbox);
+ for (uid = key->uids; uid && ret; uid = uid->next) {
+ uid_length = strlen (uid->email);
+ if (1 && (uid->email[0] == '<')
+ && (uid->email[uid_length - 1] == '>')
+ && (uid_length == sender_length + 2)
+ && (!strncmp (uid->email + 1, sender->mailbox, sender_length)))
+ ret = 0;
+ }
}
+ else
+ mutt_any_key_to_continue ("Failed to verify sender");
+ }
else
mutt_any_key_to_continue ("Failed to figure out sender");
- if (signature_key)
- {
- gpgme_key_release (signature_key);
- signature_key = NULL;
- }
+ if (signature_key) {
+ gpgme_key_release (signature_key);
+ signature_key = NULL;
+ }
return ret;
}
-int smime_gpgme_verify_sender (HEADER *h)
+int smime_gpgme_verify_sender (HEADER * h)
{
return verify_sender (h, GPGME_PROTOCOL_CMS);
}