/* Parse FLAGS and return a statically allocated(!) string with them. */
static char *crypt_key_abilities (int flags)
{
- static char buff[3];
+ static char buff[3] = "es";
- if (!(flags & KEYFLAG_CANENCRYPT))
- buff[0] = '-';
- else if (flags & KEYFLAG_PREFER_SIGNING)
- buff[0] = '.';
- else
- buff[0] = 'e';
-
- if (!(flags & KEYFLAG_CANSIGN))
- buff[1] = '-';
- else if (flags & KEYFLAG_PREFER_ENCRYPTION)
- buff[1] = '.';
- else
- buff[1] = 's';
+ if (!(flags & KEYFLAG_CANENCRYPT))
+ buff[0] = '-';
+ else if (flags & KEYFLAG_PREFER_SIGNING)
+ buff[0] = '.';
- buff[2] = '\0';
+ if (!(flags & KEYFLAG_CANSIGN))
+ buff[1] = '-';
+ else if (flags & KEYFLAG_PREFER_ENCRYPTION)
+ buff[1] = '.';
- return buff;
+ return buff;
}
/* Parse FLAGS and return a character describing the most important flag. */
-static char crypt_flags (int flags)
-{
- if (flags & KEYFLAG_REVOKED)
- return 'R';
- else if (flags & KEYFLAG_EXPIRED)
- return 'X';
- else if (flags & KEYFLAG_DISABLED)
- return 'd';
- else if (flags & KEYFLAG_CRITICAL)
- return 'c';
- else
+static char crypt_flags(int flags)
+{
+ if (flags & KEYFLAG_REVOKED)
+ return 'R';
+ if (flags & KEYFLAG_EXPIRED)
+ return 'X';
+ if (flags & KEYFLAG_DISABLED)
+ return 'd';
+ if (flags & KEYFLAG_CRITICAL)
+ return 'c';
return ' ';
}
}
/* 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));
+ mutt_error (_("error rewinding data object: %s\n"),
+ gpgme_strerror(err));
return -1;
}
- while ((nread = gpgme_data_read(data, buf, sizeof (buf)))) {
+ 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--) {
putc (*p, fp);
}
- if (ferror (fp)) {
+ if (ferror(fp)) {
mutt_perror ("[tempfile]");
return -1;
}
}
if (nread == -1) {
- mutt_error (_("error reading data object: %s\n"), strerror (errno));
+ 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];
/* Create a GpgmeRecipientSet from the keys in the string KEYLIST.
The keys must be space delimited. */
-static gpgme_key_t *
-create_recipient_set(const char *keylist, gpgme_protocol_t protocol)
+static gpgme_key_t *create_recipient_set(const char *s, int smime)
{
- int err;
- const char *s;
- char buf[100];
- int i;
- gpgme_key_t *rset = NULL;
- unsigned int rset_n = 0;
- gpgme_key_t key = NULL;
- gpgme_ctx_t context = NULL;
+ gpgme_ctx_t ctx = create_gpgme_context(smime);
+ gpgme_key_t *rset = NULL;
+ int rset_n = 0;
- err = gpgme_new (&context);
- if (!err)
- err = gpgme_set_protocol (context, protocol);
-
- if (!err) {
- s = keylist;
- do {
- while (*s == ' ')
- s++;
- for (i = 0; *s && *s != ' ' && i < ssizeof(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_key2 (context, buf, &key, 0);
- if (!err)
- key->uids->validity = GPGME_VALIDITY_FULL;
- buf[i - 1] = '!';
+ s = skipspaces(s);
+ while (*s) {
+ gpgme_error_t err;
+ gpgme_key_t key;
+ const char *p = m_strnextsp(s);
+ char buf[100];
+
+ m_strncpy(buf, sizeof(buf), s, p - s);
+ if (p - s > 1 && p[-1] == '!') {
+ /* user wants to override the valididy of that key. */
+
+ buf[p - s - 1] = '\0';
+ err = gpgme_get_key2(ctx, buf, &key, 0);
+ if (!err)
+ key->uids->validity = GPGME_VALIDITY_FULL;
+ } else {
+ err = gpgme_get_key2(ctx, buf, &key, 0);
}
- else
- err = gpgme_get_key2 (context, buf, &key, 0);
- if (!err) {
- p_realloc(&rset, rset_n + 1);
- rset[rset_n++] = key;
- }
- else {
- mutt_error (_("error adding recipient `%s': %s\n"),
- buf, gpgme_strerror (err));
- p_delete(&rset);
- return NULL;
+ if (err) {
+ mutt_error(_("error adding recipient `%.*s': %s\n"),
+ (int)(p - s), s, gpgme_strerror(err));
+ p_delete(&rset);
+ break;
}
- }
- } while (*s);
- }
- /* NULL terminate. */
- p_realloc(&rset, rset_n + 1);
- rset[rset_n++] = NULL;
+ p_realloc(&rset, rset_n + 1);
+ rset[rset_n++] = key;
+ s = skipspaces(p);
+ }
- if (context)
- gpgme_release (context);
+ if (rset) {
+ /* NULL terminate. */
+ p_realloc(&rset, rset_n + 1);
+ rset[rset_n++] = NULL;
+ }
- return rset;
+ gpgme_release(ctx);
+ return rset;
}
/* Make sure that the correct signer is set. Returns 0 on success. */
-static int set_signer (gpgme_ctx_t ctx, int for_smime)
+static int set_signer(gpgme_ctx_t ctx, int for_smime)
{
- char *signid = for_smime ? SmimeDefaultKey : PgpSignAs;
- gpgme_error_t err;
- gpgme_ctx_t listctx;
- gpgme_key_t key, key2;
+ const char *signid = for_smime ? SmimeDefaultKey : PgpSignAs;
+ gpgme_error_t err;
+ gpgme_key_t key;
- if (!signid || !*signid)
- return 0;
+ if (m_strisempty(signid))
+ return 0;
- listctx = create_gpgme_context (for_smime);
- 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;
- }
- err = gpgme_op_keylist_next (listctx, &key2);
- if (!err) {
- gpgme_key_unref(key);
- gpgme_key_unref(key2);
- gpgme_release (listctx);
- mutt_error (_("ambiguous specification of secret key `%s'\n"), signid);
- return -1;
- }
- gpgme_op_keylist_end (listctx);
- gpgme_release (listctx);
+ err = gpgme_get_key(ctx, signid, &key, 1);
+ if (err) {
+ mutt_error(_("error getting secret key `%s': %s\n"), signid,
+ gpgme_strerror(err));
+ return -1;
+ }
- gpgme_signers_clear (ctx);
- err = gpgme_signers_add (ctx, key);
- gpgme_key_unref(key);
- if (err) {
- mutt_error (_("error setting secret key `%s': %s\n"),
- signid, gpgme_strerror (err));
- return -1;
- }
- return 0;
+ gpgme_signers_clear(ctx);
+ err = gpgme_signers_add(ctx, key);
+ gpgme_key_unref(key);
+ 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,
- int use_smime, int combined_signed)
+static char *encrypt_gpgme_object(gpgme_data_t plaintext, gpgme_key_t *rset,
+ int use_smime, int combined_signed)
{
- int err;
- gpgme_ctx_t ctx;
- gpgme_data_t ciphertext;
- char *outfile;
+ int err;
+ gpgme_ctx_t ctx;
+ gpgme_data_t ciphertext;
+ char *outfile;
- ctx = create_gpgme_context (use_smime);
- if (!use_smime)
- gpgme_set_armor (ctx, 1);
+ ctx = create_gpgme_context (use_smime);
+ if (!use_smime)
+ gpgme_set_armor (ctx, 1);
- ciphertext = create_gpgme_data ();
+ ciphertext = create_gpgme_data ();
- if (combined_signed) {
- if (set_signer (ctx, use_smime)) {
- gpgme_data_release (ciphertext);
- gpgme_release (ctx);
- return NULL;
+ 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);
}
- 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;
- }
- gpgme_release (ctx);
+ 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;
+ }
- outfile = data_object_to_tempfile (ciphertext, NULL);
- gpgme_data_release (ciphertext);
- return outfile;
+ gpgme_release(ctx);
+
+ outfile = data_object_to_tempfile(ciphertext, NULL);
+ gpgme_data_release(ciphertext);
+ return outfile;
}
/* Find the "micalg" parameter from the last Gpgme operation on
which must have been allocated by the caller with size BUFLEN.
Returns 0 on success or -1 in case of an error. The return string
is truncted to BUFLEN - 1. */
-static int get_micalg (gpgme_ctx_t ctx, char *buf, ssize_t buflen)
+static int get_micalg(gpgme_ctx_t ctx, char *buf, ssize_t buflen)
{
- gpgme_sign_result_t result = NULL;
- const char *algorithm_name = NULL;
-
- if (!buflen)
- return -1;
+ gpgme_sign_result_t result = NULL;
+ const char *algorithm_name = NULL;
- *buf = 0;
- result = gpgme_op_sign_result (ctx);
- if (result) {
- algorithm_name = gpgme_hash_algo_name (result->signatures->hash_algo);
- if (algorithm_name) {
- m_strcpy(buf, buflen, algorithm_name);
+ *buf = '\0';
+ result = gpgme_op_sign_result(ctx);
+ if (result) {
+ algorithm_name = gpgme_hash_algo_name (result->signatures->hash_algo);
+ if (algorithm_name) {
+ m_strcpy(buf, buflen, algorithm_name);
+ }
}
- }
- 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];
+ char p[STRING];
- setlocale (LC_TIME, "");
+ setlocale(LC_TIME, "");
#ifdef HAVE_LANGINFO_D_T_FMT
- strftime (p, sizeof (p), nl_langinfo (D_T_FMT), localtime (&t));
+ strftime(p, sizeof(p), nl_langinfo(D_T_FMT), localtime(&t));
#else
- strftime (p, sizeof (p), "%c", localtime (&t));
+ strftime(p, sizeof(p), "%c", localtime(&t));
#endif
- setlocale (LC_TIME, "C");
- state_attach_puts (p, s);
+ setlocale(LC_TIME, "C");
+ state_attach_puts(p, s);
}
/* Implementation of `sign_message'. */
return NULL;
}
- sigfile = data_object_to_tempfile (signature, NULL);
+ sigfile = data_object_to_tempfile(signature, NULL);
gpgme_data_release (signature);
if (!sigfile) {
gpgme_release (ctx);
gpgme_key_t *rset = NULL;
gpgme_data_t plaintext;
- rset = create_recipient_set (keylist, GPGME_PROTOCOL_OpenPGP);
+ rset = create_recipient_set(keylist, 0);
if (!rset)
return NULL;
gpgme_key_t *rset = NULL;
gpgme_data_t plaintext;
- rset = create_recipient_set (keylist, GPGME_PROTOCOL_CMS);
+ rset = create_recipient_set(keylist, 1);
if (!rset)
return NULL;
/* 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 crypt_pgp_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur)
+int crypt_pgp_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))
- return -1;
+ STATE s;
+ BODY *first_part = b;
+ int is_signed;
- if (!b->parts || !b->parts->next)
- return -1;
+ first_part->goodsig = 0;
+ first_part->warnsig = 0;
- b = b->parts->next;
+ if (!mutt_is_multipart_encrypted(b) || !b->parts || !b->parts->next)
+ return -1;
- p_clear(&s, 1);
- s.fpin = fpin;
- *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL);
- if (!*fpout) {
- mutt_perror (_("Can't create temporary file"));
- return -1;
- }
- unlink (tempfile);
+ b = b->parts->next;
- *cur = decrypt_part (b, &s, *fpout, 0, &is_signed);
- rewind (*fpout);
- if (is_signed > 0)
- first_part->goodsig = 1;
+ p_clear(&s, 1);
+ s.fpin = fpin;
+ *fpout = tmpfile();
+ if (!*fpout) {
+ mutt_perror (_("Can't create temporary file"));
+ return -1;
+ }
- return *cur ? 0 : -1;
+ *cur = decrypt_part(b, &s, *fpout, 0, &is_signed);
+ rewind(*fpout);
+ first_part->goodsig = is_signed > 0;
+ return *cur ? 0 : -1;
}
the stream in CUR and FPOUT. Returns 0 on success. */
int crypt_smime_decrypt_mime(FILE *fpin, FILE **fpout, BODY *b, BODY **cur)
{
- char tempfile[_POSIX_PATH_MAX];
STATE s;
FILE *tmpfp = NULL;
int is_signed;
p_clear(&s, 1);
s.fpin = fpin;
fseeko (s.fpin, b->offset, 0);
- tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL);
+ tmpfp = tmpfile();
if (!tmpfp) {
mutt_perror (_("Can't create temporary file"));
return -1;
}
- mutt_unlink (tempfile);
s.fpout = tmpfp;
mutt_decode_attachment (b, &s);
p_clear(&s, 1);
s.fpin = tmpfp;
s.fpout = 0;
- *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL);
+ *fpout = tmpfile();
if (!*fpout) {
mutt_perror (_("Can't create temporary file"));
return -1;
}
- mutt_unlink (tempfile);
*cur = decrypt_part (b, &s, *fpout, 1, &is_signed);
if (*cur)
p_clear(&s, 1);
s.fpin = *fpout;
fseeko (s.fpin, bb->offset, 0);
- tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL);
+ tmpfp = tmpfile();
if (!tmpfp) {
mutt_perror (_("Can't create temporary file"));
return -1;
}
- mutt_unlink (tempfile);
s.fpout = tmpfp;
mutt_decode_attachment (bb, &s);
p_clear(&s, 1);
s.fpin = tmpfp;
s.fpout = 0;
- *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL);
+ *fpout = tmpfile();
if (!*fpout) {
mutt_perror (_("Can't create temporary file"));
return -1;
}
- mutt_unlink (tempfile);
tmp_b = decrypt_part (bb, &s, *fpout, 1, &is_signed);
if (tmp_b)
int crypt_pgp_check_traditional(FILE *fp, BODY *b, int tagged_only)
{
- int rv = 0;
- int r;
+ int rv = 0;
- for (; b; b = b->next) {
- if (is_multipart (b))
- rv = (crypt_pgp_check_traditional (fp, b->parts, tagged_only) || rv);
- else if (b->type == TYPETEXT) {
- if ((r = mutt_is_application_pgp (b)))
- rv = (rv || r);
- else
- rv = (pgp_check_traditional_one_body (fp, b, tagged_only) || rv);
+ for (; b; b = b->next) {
+ if (is_multipart(b))
+ rv |= crypt_pgp_check_traditional(fp, b->parts, tagged_only);
+ if (b->type == TYPETEXT) {
+ int r;
+ if ((r = mutt_is_application_pgp(b))) {
+ rv |= r;
+ } else {
+ rv |= pgp_check_traditional_one_body(fp, b, tagged_only);
+ }
+ }
}
- }
- return rv;
+
+ return rv;
}
/*
char *fname;
FILE *fp;
- fname = data_object_to_tempfile (data, &fp);
+ fname = data_object_to_tempfile(data, &fp);
if (!fname)
return;
unlink (fname);
clearsign = 1;
needpass = 0;
}
- else if (!option (OPTDONTHANDLEPGPKEYS) &&
- !m_strcmp("PUBLIC KEY BLOCK-----\n", buf + 15)) {
+ else if (!m_strcmp("PUBLIC KEY BLOCK-----\n", buf + 15)) {
needpass = 0;
pgp_keyblock = 1;
}
"information --]\n\n"), s);
}
- tmpfname = data_object_to_tempfile (plaintext, &pgpout);
+ tmpfname = data_object_to_tempfile(plaintext, &pgpout);
if (!tmpfname) {
pgpout = NULL;
state_attach_puts (_("Error: copy data failed\n"), s);
return k;
}
-static cryptkey_t *crypt_getkeybyaddr (address_t * a, short abilities,
- unsigned int app, int *forced_valid)
+static cryptkey_t *
+crypt_getkeybyaddr(address_t * a, int abilities, int app, int *forced_valid)
{
address_t *r, *p;
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 = cryptkey_dup(the_valid_key);
+ /*
+ * 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 = cryptkey_dup(the_valid_key);
+ } else {
+ /*
+ * Else: Ask the user.
+ */
+ k = crypt_select_key (matches, a, NULL, app, forced_valid);
+ }
+ key_list_wipe(&matches);
} else {
- /*
- * Else: Ask the user.
- */
- k = crypt_select_key (matches, a, NULL, app, forced_valid);
+ k = NULL;
}
- key_list_wipe(&matches);
- } else {
- k = NULL;
- }
- return k;
+ return k;
}
-static cryptkey_t *crypt_getkeybystr (const char *p, short abilities,
- unsigned int app, int *forced_valid)
+static cryptkey_t *
+crypt_getkeybystr(const char *p, int abilities, int app, int *forced_valid)
{
cryptkey_t *keys;
cryptkey_t *matches = NULL;
void crypt_pgp_extract_keys_from_attachment_list(FILE * fp, int tag, BODY * top)
{
- mutt_endwin (NULL);
- set_option (OPTDONTHANDLEPGPKEYS);
+ mutt_endwin (NULL);
- for (; top; top = top->next) {
- if (!tag || top->tagged)
- pgp_extract_keys_from_attachment (fp, top);
+ for (; top; top = top->next) {
+ if (!tag || top->tagged)
+ pgp_extract_keys_from_attachment (fp, top);
- if (!tag)
- break;
- }
-
- unset_option (OPTDONTHANDLEPGPKEYS);
+ if (!tag)
+ break;
+ }
}
void crypt_invoke_message (int type)
return;
}
- set_option(OPTDONTHANDLEPGPKEYS);
if (!h) {
int i;
for (i = 0; i < Context->vcount; i++) {
} else {
extract_keys_aux(tmpfp, h);
}
- unset_option(OPTDONTHANDLEPGPKEYS);
m_fclose(&tmpfp);
if (isendwin())
mutt_any_key_to_continue(NULL);
}
-
-
-static void crypt_fetch_signatures (BODY ***signatures, BODY * a, int *n)
+static void crypt_fetch_signatures(BODY ***signatures, BODY * a, int *n)
{
- for (; a; a = a->next) {
- if (a->type == TYPEMULTIPART)
- crypt_fetch_signatures (signatures, a->parts, n);
- else {
- if ((*n % 5) == 0)
- p_realloc(signatures, *n + 6);
+ for (; a; a = a->next) {
+ if (a->type == TYPEMULTIPART) {
+ crypt_fetch_signatures(signatures, a->parts, n);
+ } else {
+ if ((*n % 5) == 0)
+ p_realloc(signatures, *n + 6);
- (*signatures)[(*n)++] = a;
+ (*signatures)[(*n)++] = a;
+ }
}
- }
}
-
-/*
- * This routine verifies a "multipart/signed" body.
- */
-
-int mutt_signed_handler (BODY * a, STATE * s)
+int mutt_signed_handler(BODY *a, STATE *s)
{
unsigned major, minor;
char *protocol;