75#define CRYPT_KV_VALID (1 << 0)
76#define CRYPT_KV_ADDR (1 << 1)
77#define CRYPT_KV_STRING (1 << 2)
78#define CRYPT_KV_STRONGID (1 << 3)
79#define CRYPT_KV_MATCH (CRYPT_KV_ADDR | CRYPT_KV_STRING)
92#define PKA_NOTATION_NAME "pka-address@gnupg.org"
94#define _LINE_COMPARE(_x, _y) line_compare(_x, sizeof(_x) - 1, _y)
95#define MESSAGE(_y) _LINE_COMPARE("MESSAGE-----", _y)
96#define SIGNED_MESSAGE(_y) _LINE_COMPARE("SIGNED MESSAGE-----", _y)
97#define PUBLIC_KEY_BLOCK(_y) _LINE_COMPARE("PUBLIC KEY BLOCK-----", _y)
98#define BEGIN_PGP_SIGNATURE(_y) \
99 _LINE_COMPARE("-----BEGIN PGP SIGNATURE-----", _y)
117 const char *s = gpgme_get_ctx_flag(ctx,
"redraw");
134 const char *s =
"????????";
138 s = k->
kobj->subkeys->keyid;
140 if ((!c_pgp_long_ids) && (strlen(s) == 16))
159 const char *s =
"????????????????";
163 s = k->
kobj->subkeys->keyid;
176 const char *s =
"????????";
180 s = k->
kobj->subkeys->keyid;
198 s = k->
kobj->subkeys->fpr;
210 const char *s =
"????????????????";
214 if (k->
kobj->subkeys->fpr)
215 s = k->
kobj->subkeys->fpr;
217 s = k->
kobj->subkeys->keyid;
234 gpgme_key_ref(key->
kobj);
257 *keylist = (*keylist)->
next;
259 gpgme_key_unref(k->
kobj);
274 bool is_strong =
false;
281 case GPGME_VALIDITY_MARGINAL:
282 case GPGME_VALIDITY_NEVER:
283 case GPGME_VALIDITY_UNDEFINED:
284 case GPGME_VALIDITY_UNKNOWN:
288 case GPGME_VALIDITY_FULL:
289 case GPGME_VALIDITY_ULTIMATE:
357 gpgme_ctx_t ctx = NULL;
359 gpgme_error_t err = gpgme_new(&ctx);
364 err = gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_OpenPGP, NULL, c_autocrypt_dir);
367 if (err != GPG_ERR_NO_ERROR)
369 mutt_error(
_(
"error creating GPGME context: %s"), gpgme_strerror(err));
375 err = gpgme_set_protocol(ctx, GPGME_PROTOCOL_CMS);
376 if (err != GPG_ERR_NO_ERROR)
378 mutt_error(
_(
"error enabling CMS protocol: %s"), gpgme_strerror(err));
396 gpgme_data_t data = NULL;
398 gpgme_error_t err = gpgme_data_new(&data);
399 if (err != GPG_ERR_NO_ERROR)
401 mutt_error(
_(
"error creating GPGME data object: %s"), gpgme_strerror(err));
415 gpgme_error_t err = GPG_ERR_NO_ERROR;
416 gpgme_data_t data = NULL;
435 unsigned char buf[1] = { 0 };
438 fseek(fp_tmp, 0, SEEK_SET);
440 while ((c = fgetc(fp_tmp)) != EOF)
448 if ((c ==
'\n') && !hadcr)
451 gpgme_data_write(
data, buf, 1);
458 gpgme_data_write(
data, buf, 1);
461 gpgme_data_seek(
data, 0, SEEK_SET);
467 if (err != GPG_ERR_NO_ERROR)
469 mutt_error(
_(
"error allocating data object: %s"), gpgme_strerror(err));
470 gpgme_data_release(
data);
491 gpgme_data_t
data = NULL;
493 gpgme_error_t err = gpgme_data_new_from_filepart(&
data, NULL, fp, offset, length);
494 if (err != GPG_ERR_NO_ERROR)
496 mutt_error(
_(
"error allocating data object: %s"), gpgme_strerror(err));
512 char buf[4096] = { 0 };
515 gpgme_error_t err = ((gpgme_data_seek(
data, 0, SEEK_SET) == -1) ?
516 gpgme_error_from_errno(errno) :
518 if (err != GPG_ERR_NO_ERROR)
520 mutt_error(
_(
"error rewinding data object: %s"), gpgme_strerror(err));
524 while ((nread = gpgme_data_read(
data, buf,
sizeof(buf))) > 0)
528 for (
char *p = buf; nread; p++, nread--)
542 mutt_error(
_(
"error reading data object: %s"), strerror(errno));
574 gpgme_error_t err = ((gpgme_data_seek(
data, 0, SEEK_SET) == -1) ?
575 gpgme_error_from_errno(errno) :
577 if (err == GPG_ERR_NO_ERROR)
579 char buf[4096] = { 0 };
581 while ((nread = gpgme_data_read(
data, buf,
sizeof(buf))) > 0)
583 if (fwrite(buf, nread, 1, fp) != 1)
594 fseek(fp, 0, SEEK_SET);
601 mutt_error(
_(
"error reading data object: %s"), gpgme_strerror(err));
625 const char *s = keylist;
643 while ((*s !=
'\0') && (*s !=
' '))
646 }
while (*s !=
'\0');
659 gpgme_key_t key = NULL;
660 gpgme_key_t key2 = NULL;
663 gpgme_error_t err = gpgme_op_keylist_start(listctx, address, 1);
664 if (err == GPG_ERR_NO_ERROR)
665 err = gpgme_op_keylist_next(listctx, &key);
666 if (err != GPG_ERR_NO_ERROR)
668 gpgme_release(listctx);
669 mutt_error(
_(
"secret key '%s' not found: %s"), address, gpgme_strerror(err));
675 fpr = key->subkeys->fpr ? key->subkeys->fpr : key->subkeys->keyid;
676 while (gpgme_op_keylist_next(listctx, &key2) == 0)
680 fpr2 = key2->subkeys->fpr ? key2->subkeys->fpr : key2->subkeys->keyid;
683 gpgme_key_unref(key);
684 gpgme_key_unref(key2);
685 gpgme_release(listctx);
686 mutt_error(
_(
"ambiguous specification of secret key '%s'"), address);
691 gpgme_key_unref(key2);
694 gpgme_op_keylist_end(listctx);
695 gpgme_release(listctx);
697 gpgme_signers_clear(ctx);
698 err = gpgme_signers_add(ctx, key);
699 gpgme_key_unref(key);
700 if (err != GPG_ERR_NO_ERROR)
702 mutt_error(
_(
"error setting secret key '%s': %s"), address, gpgme_strerror(err));
716static int set_signer(gpgme_ctx_t ctx,
const struct AddressList *al,
bool for_smime)
718 const char *signid = NULL;
726 signid = c_smime_sign_as ? c_smime_sign_as : c_smime_default_key;
739 signid = c_pgp_sign_as ? c_pgp_sign_as : c_pgp_default_key;
761 return (!signid && !al) ? 0 : -1;
774 if (err != GPG_ERR_NO_ERROR)
776 mutt_error(
_(
"error setting PKA signature notation: %s"), gpgme_strerror(err));
792 bool combined_signed,
const struct AddressList *from)
794 gpgme_error_t err = GPG_ERR_NO_ERROR;
795 gpgme_ctx_t ctx = NULL;
796 gpgme_data_t ciphertext = NULL;
797 char *outfile = NULL;
809 gpgme_set_armor(ctx, 1);
822 if (err != GPG_ERR_NO_ERROR)
826 err = gpgme_op_encrypt_sign_ext(ctx, NULL,
buf_string(recpstring),
827 GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext);
831 err = gpgme_op_encrypt_ext(ctx, NULL,
buf_string(recpstring),
832 GPGME_ENCRYPT_ALWAYS_TRUST, plaintext, ciphertext);
836 if (err != GPG_ERR_NO_ERROR)
838 mutt_error(
_(
"error encrypting data: %s"), gpgme_strerror(err));
847 gpgme_data_release(ciphertext);
863static int get_micalg(gpgme_ctx_t ctx,
int use_smime,
char *buf,
size_t buflen)
865 gpgme_sign_result_t result = NULL;
866 const char *algorithm_name = NULL;
872 result = gpgme_op_sign_result(ctx);
873 if (result && result->signatures)
875 algorithm_name = gpgme_hash_algo_name(result->signatures->hash_algo);
881 snprintf(buf, buflen,
"%s", algorithm_name);
887 snprintf(buf, buflen,
"pgp-%s", algorithm_name);
893 return (buf[0] !=
'\0') ? 0 : -1;
918 struct Body *b_sign = NULL;
919 char *sigfile = NULL;
920 gpgme_error_t err = GPG_ERR_NO_ERROR;
921 char buf[100] = { 0 };
922 gpgme_ctx_t ctx = NULL;
923 gpgme_data_t message = NULL;
924 gpgme_data_t signature = NULL;
925 gpgme_sign_result_t sigres = NULL;
936 gpgme_set_armor(ctx, 1);
940 gpgme_data_release(signature);
941 gpgme_data_release(message);
950 if (err != GPG_ERR_NO_ERROR)
952 gpgme_data_release(signature);
953 gpgme_data_release(message);
959 err = gpgme_op_sign(ctx, message, signature, GPGME_SIG_MODE_DETACH);
961 gpgme_data_release(message);
962 if (err != GPG_ERR_NO_ERROR)
964 gpgme_data_release(signature);
966 mutt_error(
_(
"error signing data: %s"), gpgme_strerror(err));
971 sigres = gpgme_op_sign_result(ctx);
972 if (!sigres->signatures)
974 gpgme_data_release(signature);
976 mutt_error(
_(
"$pgp_sign_as unset and no default key specified in ~/.gnupg/gpg.conf"));
981 gpgme_data_release(signature);
997 use_smime ?
"application/pkcs7-signature" :
"application/pgp-signature");
1000 if (
get_micalg(ctx, use_smime, buf,
sizeof(buf)) == 0)
1055 const struct AddressList *from)
1064 gpgme_data_release(plaintext);
1110 gpgme_data_release(plaintext);
1145 int idx,
struct State *state, gpgme_signature_t sig)
1150 bool severe =
false;
1152 if ((sum & GPGME_SIGSUM_KEY_REVOKED))
1154 state_puts(state,
_(
"Warning: One of the keys has been revoked\n"));
1158 if ((sum & GPGME_SIGSUM_KEY_EXPIRED))
1160 time_t at = (key->subkeys && key->subkeys->expires) ? key->subkeys->expires : 0;
1163 state_puts(state,
_(
"Warning: The key used to create the signature expired at: "));
1169 state_puts(state,
_(
"Warning: At least one certification key has expired\n"));
1173 if ((sum & GPGME_SIGSUM_SIG_EXPIRED))
1175 gpgme_signature_t sig2 = NULL;
1178 gpgme_verify_result_t result = gpgme_op_verify_result(ctx);
1180 for (sig2 = result->signatures, i = 0; sig2 && (i < idx); sig2 = sig2->next, i++)
1183 state_puts(state,
_(
"Warning: The signature expired at: "));
1184 print_time(sig2 ? sig2->exp_timestamp : 0, state);
1188 if ((sum & GPGME_SIGSUM_KEY_MISSING))
1190 state_puts(state,
_(
"Can't verify due to a missing key or certificate\n"));
1193 if ((sum & GPGME_SIGSUM_CRL_MISSING))
1195 state_puts(state,
_(
"The CRL is not available\n"));
1199 if ((sum & GPGME_SIGSUM_CRL_TOO_OLD))
1201 state_puts(state,
_(
"Available CRL is too old\n"));
1205 if ((sum & GPGME_SIGSUM_BAD_POLICY))
1206 state_puts(state,
_(
"A policy requirement was not met\n"));
1208 if ((sum & GPGME_SIGSUM_SYS_ERROR))
1210 const char *t0 = NULL;
1211 const char *t1 = NULL;
1212 gpgme_verify_result_t result = NULL;
1213 gpgme_signature_t sig2 = NULL;
1219 result = gpgme_op_verify_result(ctx);
1220 for (sig2 = result->signatures, i = 0; sig2 && (i < idx); sig2 = sig2->next, i++)
1226 t1 = sig2->wrong_key_usage ?
"Wrong_Key_Usage" :
"";
1245 if (c_crypt_use_pka)
1247 if ((sig->pka_trust == 1) && sig->pka_address)
1249 state_puts(state,
_(
"WARNING: PKA entry does not match signer's address: "));
1253 else if ((sig->pka_trust == 2) && sig->pka_address)
1255 state_puts(state,
_(
"PKA verified signer's address is: "));
1274 const char *prefix =
_(
"Fingerprint: ");
1276 const char *s = key->subkeys ? key->subkeys->fpr : NULL;
1279 bool is_pgp = (key->protocol == GPGME_PROTOCOL_OpenPGP);
1281 char *buf =
MUTT_MEM_MALLOC(strlen(prefix) + strlen(s) * 4 + 2,
char);
1282 strcpy(buf, prefix);
1283 char *p = buf + strlen(buf);
1284 if (is_pgp && (strlen(s) == 40))
1286 for (
int i = 0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++)
1299 for (
int i = 0; *s && s[1] && s[2]; s += 2, i++)
1303 *p++ = is_pgp ?
' ' :
':';
1304 if (is_pgp && (i == 7))
1326 gpgme_signature_t sig = NULL;
1327 const char *txt = NULL;
1329 gpgme_verify_result_t result = gpgme_op_verify_result(ctx);
1331 for (sig = result->signatures; sig && (idx > 0); sig = sig->next, idx--)
1334 switch (sig ? sig->validity : 0)
1336 case GPGME_VALIDITY_UNKNOWN:
1337 txt =
_(
"WARNING: We have NO indication whether the key belongs to the person named as shown above\n");
1339 case GPGME_VALIDITY_UNDEFINED:
1341 case GPGME_VALIDITY_NEVER:
1342 txt =
_(
"WARNING: The key does NOT BELONG to the person named as shown above\n");
1344 case GPGME_VALIDITY_MARGINAL:
1345 txt =
_(
"WARNING: It is NOT certain that the key belongs to the person named as shown above\n");
1347 case GPGME_VALIDITY_FULL:
1348 case GPGME_VALIDITY_ULTIMATE:
1366 gpgme_key_t key,
struct State *state)
1376 for (gpgme_user_id_t uids = key->uids; uids; uids = uids->next)
1385 for (
int i = 0; i < msgwid; i++)
1406 state_puts(state,
_(
"no signature fingerprint available"));
1418 for (
int i = 0; i < msgwid; i++)
1433 const char *algo = gpgme_pubkey_algo_name(r->pubkey_algo);
1439 state_printf(state,
_(
"Recipient: %s key, ID %s\n"), algo, r->keyid);
1454 for (gpgme_recipient_t r = result->recipients; r; r = r->next)
1475 const char *fpr = NULL;
1476 gpgme_key_t key = NULL;
1477 bool anybad =
false, anywarn =
false;
1478 gpgme_signature_t sig = NULL;
1479 gpgme_error_t err = GPG_ERR_NO_ERROR;
1481 gpgme_verify_result_t result = gpgme_op_verify_result(ctx);
1488 for (i = 0, sig = result->signatures; sig && (i < idx); i++, sig = sig->next)
1501 const unsigned int sum = sig->summary;
1503 if (gpg_err_code(sig->status) != GPG_ERR_NO_ERROR)
1506 if (gpg_err_code(sig->status) != GPG_ERR_NO_PUBKEY)
1508 err = gpgme_get_key(ctx, fpr, &key, 0);
1509 if (err == GPG_ERR_NO_ERROR)
1513 if (!mod_data->
signature_key && key && (key->protocol == GPGME_PROTOCOL_CMS))
1531 else if (err != GPG_ERR_NO_ERROR)
1533 char buf[1024] = { 0 };
1534 snprintf(buf,
sizeof(buf),
_(
"Error getting key information for KeyID %s: %s\n"),
1535 fpr, gpgme_strerror(err));
1539 else if ((sum & GPGME_SIGSUM_GREEN))
1546 else if ((sum & GPGME_SIGSUM_RED))
1551 else if (!anybad && key && (key->protocol == GPGME_PROTOCOL_OpenPGP))
1566 if (sig->exp_timestamp)
1579 gpgme_key_unref(key);
1582 return anybad ? 1 : anywarn ? 2 : 0;
1603 gpgme_ctx_t ctx = NULL;
1604 gpgme_data_t message = NULL;
1613 gpgme_data_set_encoding(signature, GPGME_DATA_ENCODING_BASE64);
1615 gpgme_error_t err = gpgme_data_new_from_file(&message, tempfile, 1);
1616 if (err != GPG_ERR_NO_ERROR)
1618 gpgme_data_release(signature);
1619 mutt_error(
_(
"error allocating data object: %s"), gpgme_strerror(err));
1628 err = gpgme_op_verify(ctx, signature, message, NULL);
1629 gpgme_data_release(message);
1630 gpgme_data_release(signature);
1633 if (err != GPG_ERR_NO_ERROR)
1635 char buf[200] = { 0 };
1637 snprintf(buf,
sizeof(buf) - 1,
_(
"Error: verification failed: %s\n"),
1638 gpgme_strerror(err));
1643 gpgme_verify_result_t verify_result = NULL;
1651 verify_result = gpgme_op_verify_result(ctx);
1652 if (verify_result && verify_result->signatures)
1654 bool anybad =
false;
1670 gpgme_verify_result_t result = NULL;
1671 gpgme_sig_notation_t notation = NULL;
1672 gpgme_signature_t sig = NULL;
1674 result = gpgme_op_verify_result(ctx);
1677 for (sig = result->signatures; sig; sig = sig->next)
1679 int non_pka_notations = 0;
1680 for (notation = sig->notations; notation; notation = notation->next)
1682 non_pka_notations++;
1684 if (non_pka_notations)
1686 char buf[128] = { 0 };
1687 snprintf(buf,
sizeof(buf),
1688 _(
"*** Begin Notation (signature by: %s) ***\n"), sig->fpr);
1690 for (notation = sig->notations; notation; notation = notation->next)
1700 if (notation->value)
1703 if (!(*notation->value && (notation->value[strlen(notation->value) - 1] ==
'\n')))
1718 return badsig ? 1 : anywarn ? 2 : 0;
1726 return verify_one(b, state, tempfile,
false);
1751 FILE *fp_out,
bool is_smime,
int *r_is_signed)
1753 if (!b || !state || !fp_out)
1756 struct Body *tattach = NULL;
1757 gpgme_error_t err = GPG_ERR_NO_ERROR;
1758 gpgme_data_t ciphertext = NULL;
1759 gpgme_data_t plaintext = NULL;
1760 gpgme_decrypt_result_t result = NULL;
1761 bool maybe_signed =
false;
1762 bool anywarn =
false;
1768 gpgme_ctx_t ctx = NULL;
1781 if ((!is_smime) || maybe_signed)
1784 err = gpgme_op_decrypt_verify(ctx, ciphertext, plaintext);
1785 else if (maybe_signed)
1786 err = gpgme_op_verify(ctx, ciphertext, NULL, plaintext);
1788 if (err == GPG_ERR_NO_ERROR)
1791 gpgme_verify_result_t verify_result = gpgme_op_verify_result(ctx);
1792 if (verify_result->signatures)
1798 err = gpgme_op_decrypt(ctx, ciphertext, plaintext);
1800 gpgme_data_release(ciphertext);
1809 result = gpgme_op_decrypt_result(ctx);
1813 if (err != GPG_ERR_NO_ERROR)
1815 if (is_smime && !maybe_signed && (gpg_err_code(err) == GPG_ERR_NO_DATA))
1821 if (result && !result->unsupported_algorithm)
1823 maybe_signed =
true;
1824 gpgme_data_release(plaintext);
1834 char buf[200] = { 0 };
1836 snprintf(buf,
sizeof(buf) - 1,
1837 _(
"[-- Error: decryption failed: %s --]\n\n"), gpgme_strerror(err));
1850 gpgme_data_release(plaintext);
1873 if (!anybad && idx && r_is_signed && *r_is_signed)
1874 *r_is_signed = anywarn ? 2 : 1;
1885 fseek(fp_out, 0, SEEK_SET);
1905 gpgme_data_release(ciphertext);
1906 gpgme_data_release(plaintext);
1917 struct State state = { 0 };
1918 struct Body *first_part = b;
1920 bool need_decode =
false;
1921 LOFF_T saved_offset = 0;
1922 size_t saved_length = 0;
1923 FILE *fp_decoded = NULL;
1946 state.
fp_in = fp_in;
1950 saved_offset = b->
offset;
1951 saved_length = b->
length;
1965 state.
fp_out = fp_decoded;
1970 b->
length = ftello(fp_decoded);
1972 fseek(fp_decoded, 0, SEEK_SET);
1973 clearerr(fp_decoded);
1974 state.
fp_in = fp_decoded;
1986 *b_dec =
decrypt_part(b, &state, *fp_out,
false, &is_signed);
1989 fseek(*fp_out, 0, SEEK_SET);
2003 b->
length = saved_length;
2004 b->
offset = saved_offset;
2016 struct State state = { 0 };
2018 LOFF_T saved_b_offset;
2019 size_t saved_b_length;
2031 saved_b_offset = b->
offset;
2032 saved_b_length = b->
length;
2050 fseek(fp_tmp, 0, SEEK_SET);
2053 memset(&state, 0,
sizeof(state));
2054 state.
fp_in = fp_tmp;
2066 (*b_dec)->goodsig = is_signed > 0;
2067 b->
length = saved_b_length;
2068 b->
offset = saved_b_offset;
2070 fseek(*
fp_out, 0, SEEK_SET);
2081 struct Body *bb = *b_dec;
2083 saved_b_offset = bb->
offset;
2084 saved_b_length = bb->
length;
2085 memset(&state, 0,
sizeof(state));
2086 state.
fp_in = *fp_out;
2103 fseek(fp_tmp2, 0, SEEK_SET);
2107 memset(&state, 0,
sizeof(state));
2108 state.
fp_in = fp_tmp2;
2120 b_tmp->
goodsig = is_signed > 0;
2121 bb->
length = saved_b_length;
2122 bb->
offset = saved_b_offset;
2124 fseek(*fp_out, 0, SEEK_SET);
2129 return *b_dec ? 0 : -1;
2141 gpgme_ctx_t tmpctx = NULL;
2142 gpgme_key_t key = NULL;
2143 gpgme_user_id_t uid = NULL;
2144 gpgme_subkey_t subkey = NULL;
2145 const char *shortid = NULL;
2147 char date[256] = { 0 };
2161 gpgme_error_t err = gpgme_op_keylist_from_data_start(tmpctx, keydata, 0);
2162 while (err == GPG_ERR_NO_ERROR)
2164 err = gpgme_op_keylist_next(tmpctx, &key);
2165 if (err != GPG_ERR_NO_ERROR)
2168 subkey = key->subkeys;
2172 shortid = subkey->keyid;
2176 tt = subkey->timestamp;
2179 fprintf(*fp,
"%s %5.5s %u/%8s %s\n", more ?
"sub" :
"pub",
2180 gpgme_pubkey_algo_name(subkey->pubkey_algo), subkey->length, shortid, date);
2185 fprintf(*fp,
"uid %s\n",
NONULL(uid->uid));
2189 subkey = subkey->next;
2192 gpgme_key_unref(key);
2194 if (gpg_err_code(err) != GPG_ERR_EOF)
2206 gpgme_release(tmpctx);
2227 if ((b[n] ==
'\n') || ((b[n] ==
'\r') && (b[n + 1] ==
'\n')))
2242 char buf[8192] = { 0 };
2266 while (fgets(buf,
sizeof(buf), fp_tmp))
2307 for (; b; b = b->
next)
2334 gpgme_data_t keydata = NULL;
2335 gpgme_import_result_t impres = NULL;
2336 gpgme_import_status_t st = NULL;
2347 gpgme_error_t err = gpgme_data_new_from_stream(&keydata, fp_in);
2348 if (err != GPG_ERR_NO_ERROR)
2350 mutt_error(
_(
"error allocating data object: %s"), gpgme_strerror(err));
2354 err = gpgme_op_import(ctx, keydata);
2355 if (err != GPG_ERR_NO_ERROR)
2357 mutt_error(
_(
"Error importing key: %s"), gpgme_strerror(err));
2362 impres = gpgme_op_import_result(ctx);
2365 fputs(
"oops: no import result returned\n", stdout);
2369 for (st = impres->imports; st; st = st->next)
2373 printf(
"key %s imported (",
NONULL(st->fpr));
2377 if (st->status & GPGME_IMPORT_SECRET)
2379 printf(
"secret parts");
2382 if ((st->status & GPGME_IMPORT_NEW))
2384 printf(
"%snew key", any ?
", " :
"");
2387 if ((st->status & GPGME_IMPORT_UID))
2389 printf(
"%snew uid", any ?
", " :
"");
2392 if ((st->status & GPGME_IMPORT_SIG))
2394 printf(
"%snew sig", any ?
", " :
"");
2397 if ((st->status & GPGME_IMPORT_SUBKEY))
2399 printf(
"%snew subkey", any ?
", " :
"");
2402 printf(
"%s)\n", any ?
"" :
"not changed");
2411 for (st = impres->imports; st; st = st->next)
2413 if (st->result == 0)
2415 printf(
"key %s import failed: %s\n",
NONULL(st->fpr), gpgme_strerror(st->result));
2421 gpgme_data_release(keydata);
2442 char buf[8192] = { 0 };
2443 bool complete, armor_header;
2460 for (complete =
true, armor_header =
true;
2476 armor_header =
false;
2483 if ((buf[0] ==
'-') && (buf[1] ==
' '))
2499 bool pgp_keyblock =
false;
2500 bool clearsign =
false;
2505 char buf[8192] = { 0 };
2506 FILE *fp_out = NULL;
2508 gpgme_error_t err = GPG_ERR_NO_ERROR;
2509 gpgme_data_t armored_data = NULL;
2511 bool maybe_goodsig =
true;
2512 bool have_any_sigs =
false;
2514 char body_charset[256] = { 0 };
2515 char *gpgcharset = NULL;
2522 mutt_str_copy(body_charset,
"iso-8859-1",
sizeof(body_charset));
2530 for (bytes = b->
length; bytes > 0;)
2533 block_begin = last_pos;
2535 if (!fgets(buf,
sizeof(buf), state->
fp_in))
2538 LOFF_T offset = ftello(state->
fp_in);
2544 bytes -= (offset - last_pos);
2552 pgp_keyblock =
false;
2564 pgp_keyblock =
true;
2576 while ((bytes > 0) && (fgets(buf,
sizeof(buf) - 1, state->
fp_in) != NULL))
2578 offset = ftello(state->
fp_in);
2584 bytes -= (offset - last_pos);
2587 if (needpass &&
mutt_str_equal(
"-----END PGP MESSAGE-----\n", buf))
2592 if (!needpass && (
mutt_str_equal(
"-----END PGP SIGNATURE-----\n", buf) ||
2604 if ((l =
mutt_str_len(gpgcharset)) > 0 && gpgcharset[l - 1] ==
'\n')
2605 gpgcharset[l - 1] = 0;
2610 block_end = ftello(state->
fp_in);
2617 have_any_sigs = (have_any_sigs || (clearsign && (state->
flags &
STATE_VERIFY)));
2621 fseeko(state->
fp_in, block_end, 0);
2635 err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
2639 err = gpgme_op_decrypt_verify(ctx, armored_data, plaintext);
2640 if (gpg_err_code(err) == GPG_ERR_NO_DATA)
2643 gpgme_data_seek(armored_data, 0, SEEK_SET);
2645 gpgme_data_release(plaintext);
2647 err = gpgme_op_verify(ctx, armored_data, NULL, plaintext);
2652 gpgme_decrypt_result_t result = gpgme_op_decrypt_result(ctx);
2656 if (err != GPG_ERR_NO_ERROR)
2658 char errbuf[200] = { 0 };
2660 snprintf(errbuf,
sizeof(errbuf) - 1,
2661 _(
"Error: decryption/verification failed: %s\n"), gpgme_strerror(err));
2670 bool sig_stat =
false;
2671 char *tmpfname = NULL;
2674 gpgme_verify_result_t verify_result = gpgme_op_verify_result(ctx);
2675 if (verify_result->signatures)
2678 have_any_sigs =
false;
2679 maybe_goodsig =
false;
2684 bool anybad =
false;
2687 have_any_sigs =
true;
2694 maybe_goodsig =
true;
2708 state_puts(state,
_(
"Error: copy data failed\n"));
2711 gpgme_data_release(plaintext);
2722 else if (pgp_keyblock)
2735 char *expected_charset = gpgcharset && *gpgcharset ? gpgcharset :
"utf-8";
2736 fseek(fp_out, 0, SEEK_SET);
2743 if ((c ==
'\n') && state->
prefix)
2754 else if (pgp_keyblock)
2761 gpgme_data_release(armored_data);
2775 b->
goodsig = (maybe_goodsig && have_any_sigs);
2779 state_attach_puts(state,
_(
"[-- Error: could not find beginning of PGP message --]\n\n"));
2814 tattach->
goodsig = is_signed > 0;
2819 _(
"[-- The following data is PGP/MIME signed and encrypted --]\n") :
2820 _(
"[-- The following data is PGP/MIME encrypted --]\n"));
2832 FILE *fp_save = state->
fp_in;
2833 state->
fp_in = fp_out;
2835 state->
fp_in = fp_save;
2856 _(
"[-- End of PGP/MIME signed and encrypted data --]\n") :
2857 _(
"[-- End of PGP/MIME encrypted data --]\n"));
2907 tattach->
goodsig = is_signed > 0;
2912 _(
"[-- The following data is S/MIME signed --]\n") :
2913 _(
"[-- The following data is S/MIME encrypted --]\n"));
2925 FILE *fp_save = state->
fp_in;
2926 state->
fp_in = fp_out;
2928 state->
fp_in = fp_save;
2957 _(
"[-- End of S/MIME encrypted data --]\n"));
2977 unsigned int rc = 0;
2982 rc = key->can_encrypt;
2985 for (gpgme_subkey_t subkey = key->subkeys; subkey; subkey = subkey->next)
2987 rc = subkey->can_encrypt;
2997 for (gpgme_subkey_t subkey = key->subkeys; subkey; subkey = subkey->next)
2999 rc = subkey->can_sign;
3006 rc = key->can_certify;
3009 for (gpgme_subkey_t subkey = key->subkeys; subkey; subkey = subkey->next)
3011 rc = subkey->can_certify;
3033 char *pattern = NULL;
3035 const char *s = NULL;
3042 for (s = np->
data; *s; s++)
3044 if ((*s ==
'%') || (*s ==
'+'))
3060 for (s = np->
data; *s; s++)
3104 gpgme_error_t err = GPG_ERR_NO_ERROR;
3105 gpgme_ctx_t ctx = NULL;
3106 gpgme_key_t key = NULL;
3108 gpgme_user_id_t
uid = NULL;
3141 err = gpgme_op_keylist_ext_start(ctx, (
const char **) patarr, secret, 0);
3142 for (n = 0; patarr[n]; n++)
3145 if (err != GPG_ERR_NO_ERROR)
3147 mutt_error(
_(
"gpgme_op_keylist_start failed: %s"), gpgme_strerror(err));
3153 while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR)
3169 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
3173 gpgme_key_ref(k->
kobj);
3183 gpgme_key_unref(key);
3185 if (gpg_err_code(err) != GPG_ERR_EOF)
3186 mutt_error(
_(
"gpgme_op_keylist_next failed: %s"), gpgme_strerror(err));
3187 gpgme_op_keylist_end(ctx);
3194 gpgme_set_protocol(ctx, GPGME_PROTOCOL_CMS);
3195 err = gpgme_op_keylist_start(ctx, pattern, 0);
3196 if (err != GPG_ERR_NO_ERROR)
3198 mutt_error(
_(
"gpgme_op_keylist_start failed: %s"), gpgme_strerror(err));
3204 while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR)
3220 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
3224 gpgme_key_ref(k->
kobj);
3234 gpgme_key_unref(key);
3236 if (gpg_err_code(err) != GPG_ERR_EOF)
3237 mutt_error(
_(
"gpgme_op_keylist_next failed: %s"), gpgme_strerror(err));
3238 gpgme_op_keylist_end(ctx);
3260 for (
char *t = strtok(scratch,
" ,.:\"()<>\n"); t; t = strtok(NULL,
" ,.:\"()<>\n"))
3279 KeyFlags abilities,
unsigned int app,
3280 bool *forced_valid,
bool oppenc_mode)
3285 int this_key_has_strong =
false;
3286 int this_key_has_addr_match =
false;
3313 for (k = keys; k; k = k->
next)
3317 if (abilities && !(k->
flags & abilities))
3323 this_key_has_strong =
false;
3324 this_key_has_addr_match =
false;
3342 if (the_strong_valid_key && (the_strong_valid_key->
kobj != k->
kobj))
3344 this_key_has_strong =
true;
3348 this_key_has_addr_match =
true;
3358 *matches_endp = tmp;
3359 matches_endp = &tmp->
next;
3361 if (this_key_has_strong)
3362 the_strong_valid_key = tmp;
3363 else if (this_key_has_addr_match)
3364 a_valid_addrmatch_key = tmp;
3372 if (oppenc_mode || !isatty(STDIN_FILENO))
3374 const bool c_crypt_opportunistic_encrypt_strong_keys =
3376 if (the_strong_valid_key)
3378 else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
3383 else if (the_strong_valid_key && !multi)
3392 k =
dlg_gpgme(matches, a, NULL, app, forced_valid);
3414 unsigned int app,
bool *forced_valid)
3420 const char *ps = NULL;
3421 const char *pl = NULL;
3422 const char *phint = NULL;
3437 for (k = keys; k; k = k->
next)
3439 if (abilities && !(k->
flags & abilities))
3452 *matches_endp = tmp;
3453 matches_endp = &tmp->
next;
3466 if (isatty(STDIN_FILENO))
3468 k =
dlg_gpgme(matches, NULL, p, app, forced_valid);
3500 unsigned int app,
bool *forced_valid)
3571static char *
find_keys(
const struct AddressList *addrlist,
unsigned int app,
bool oppenc_mode)
3574 struct ListNode *crypt_hook = NULL;
3575 const char *keyid = NULL;
3576 char *keylist = NULL;
3577 size_t keylist_size = 0;
3578 size_t keylist_used = 0;
3582 char buf[1024] = { 0 };
3583 bool forced_valid =
false;
3592 key_selected =
false;
3599 forced_valid =
false;
3606 keyid = crypt_hook->
data;
3608 if (!oppenc_mode && c_crypt_confirm_hook && isatty(STDIN_FILENO))
3610 snprintf(buf,
sizeof(buf),
_(
"Use keyID = \"%s\" for %s?"), keyid,
3620 goto bypass_selection;
3630 else if (!oppenc_mode)
3637 if (key_selected ||
STAILQ_NEXT(crypt_hook, entries))
3659 if (!k_info && !oppenc_mode && isatty(STDIN_FILENO))
3681 sprintf(keylist + keylist_used,
"%s0x%s%s", keylist_used ?
" " :
"",
3682 keyid, forced_valid ?
"!" :
"");
3685 key_selected =
true;
3693 }
while (crypt_hook);
3732 gpgme_error_t err = GPG_ERR_NO_ERROR;
3733 gpgme_key_t key = NULL;
3734 gpgme_user_id_t uid = NULL;
3743 if (gpgme_op_keylist_start(ctx, NULL, 1))
3748 while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR)
3769 gpgme_key_ref(k->
kobj);
3779 gpgme_key_unref(key);
3781 if (gpg_err_code(err) != GPG_ERR_EOF)
3782 mutt_error(
_(
"gpgme_op_keylist_next failed: %s"), gpgme_strerror(err));
3783 gpgme_op_keylist_end(ctx);
3794 if (!(choice && choice->
kobj && choice->
kobj->subkeys && choice->
kobj->subkeys->fpr))
3813 gpgme_ctx_t ctx = NULL;
3814 gpgme_key_t export_keys[2] = { 0 };
3815 gpgme_data_t keydata = NULL;
3816 struct Body *att = NULL;
3817 char buf[1024] = { 0 };
3825 export_keys[0] = key->
kobj;
3826 export_keys[1] = NULL;
3829 gpgme_set_armor(ctx, 1);
3831 gpgme_error_t err = gpgme_op_export_keys(ctx, export_keys, 0, keydata);
3832 if (err != GPG_ERR_NO_ERROR)
3834 mutt_error(
_(
"Error exporting key: %s"), gpgme_strerror(err));
3852 snprintf(buf,
sizeof(buf),
_(
"PGP Key 0x%s"),
crypt_keyid(key));
3860 gpgme_data_release(keydata);
3873 static bool has_run =
false;
3877 gpgme_check_version(NULL);
3878 gpgme_set_locale(NULL, LC_CTYPE, setlocale(LC_CTYPE, NULL));
3880 gpgme_set_locale(NULL, LC_MESSAGES, setlocale(LC_MESSAGES, NULL));
3890 if (gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP) != GPG_ERR_NO_ERROR)
3892 mutt_error(
_(
"GPGME: OpenPGP protocol not available"));
3901 if (gpgme_engine_check_version(GPGME_PROTOCOL_CMS) != GPG_ERR_NO_ERROR)
3903 mutt_error(
_(
"GPGME: CMS protocol not available"));
3934 const char *prompt = NULL;
3935 const char *letters = NULL;
3936 const char *choices = NULL;
3954 prompt =
_(
"S/MIME (s)ign, sign (a)s, (p)gp, (c)lear, or (o)ppenc mode off?");
3956 letters =
_(
"sapco");
3962 prompt =
_(
"PGP (s)ign, sign (a)s, s/(m)ime, (c)lear, or (o)ppenc mode off?");
3964 letters =
_(
"samco");
3968 else if (c_crypt_opportunistic_encrypt)
3974 prompt =
_(
"S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp, (c)lear, or (o)ppenc mode?");
3976 letters =
_(
"esabpco");
3977 choices =
"esabpcO";
3982 prompt =
_(
"PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime, (c)lear, or (o)ppenc mode?");
3984 letters =
_(
"esabmco");
3985 choices =
"esabmcO";
3994 prompt =
_(
"S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp or (c)lear?");
3996 letters =
_(
"esabpc");
4002 prompt =
_(
"PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime or (c)lear?");
4004 letters =
_(
"esabmc");
4012 switch (choices[choice - 1])
4019 char input_signas[128] = { 0 };
4052 is_smime = !is_smime;
4116 struct Address *sender = NULL;
4135 gpgme_user_id_t uid = NULL;
4137 for (uid = key->uids; uid && rc; uid = uid->next)
4139 int uid_length = strlen(uid->email);
4140 if ((uid->email[0] ==
'<') && (uid->email[uid_length - 1] ==
'>') &&
4141 (uid_length == (sender_length + 2)))
4143 const char *at_sign = strchr(uid->email + 1,
'@');
4149 const char *tmp_email = uid->email + 1;
4152 int mailbox_length = at_sign - tmp_email + 1;
4153 int domainname_length = sender_length - mailbox_length;
4155 int domainname_match;
4157 mailbox_match =
mutt_strn_equal(tmp_email, tmp_sender, mailbox_length);
4158 tmp_email += mailbox_length;
4159 tmp_sender += mailbox_length;
4160 domainname_match = (
mutt_istrn_cmp(tmp_email, tmp_sender, domainname_length) == 0);
4161 if (mailbox_match && domainname_match)
4216 return GPGME_VERSION;
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
GUI display the mailboxes in a side panel.
Autocrypt end-to-end encryption.
bool buf_istr_equal(const struct Buffer *a, const struct Buffer *b)
Return if two buffers are equal, case insensitive.
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
const char * cs_subset_path(const struct ConfigSubset *sub, const char *name)
Get a path config item by name.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Convenience wrapper for the config headers.
const char * cc_charset(void)
Get the cached value of $charset.
Convenience wrapper for the core headers.
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
bool crypt_is_numerical_keyid(const char *s)
Is this a numerical keyid.
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
const char * crypt_get_fingerprint_or_id(const char *p, const char **pphint, const char **ppl, const char **pps)
Get the fingerprint or long key ID.
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
void crypt_convert_to_7bit(struct Body *b)
Convert an email to 7bit encoding.
SecurityFlags mutt_is_application_pgp(const struct Body *b)
Does the message use PGP?
Signing/encryption multiplexor.
static const char * crypt_short_keyid(struct CryptKeyInfo *k)
Get the short keyID for a key.
static gpgme_error_t set_pka_sig_notation(gpgme_ctx_t ctx)
Set the signature notation.
static struct CryptKeyInfo * crypt_getkeybyaddr(struct Address *a, KeyFlags abilities, unsigned int app, bool *forced_valid, bool oppenc_mode)
Find a key by email address.
static char * find_keys(const struct AddressList *addrlist, unsigned int app, bool oppenc_mode)
Find keys of the recipients of the message.
static bool verify_sender(struct Email *e)
Verify the sender of a message.
static void init_common(void)
Initialise code common to PGP and SMIME parts of GPGME.
struct CryptKeyInfo * crypt_copy_key(struct CryptKeyInfo *key)
Return a copy of KEY.
static int verify_one(struct Body *b, struct State *state, const char *tempfile, bool is_smime)
Do the actual verification step.
int mutt_gpgme_select_secret_key(struct Buffer *keyid)
Select a private Autocrypt key for a new account.
const char * mutt_gpgme_print_version(void)
Get version of GPGME.
void gpgme_id_defaults_cleanup(struct NcryptModuleData *mod_data)
Free the GPGME IdDefaults cache.
static void show_encryption_info(struct State *state, gpgme_decrypt_result_t result)
Show encryption information.
static gpgme_data_t body_to_data_object(struct Body *b, bool convert)
Create GPGME object from the mail body.
static gpgme_data_t create_gpgme_data(void)
Create a new GPGME data object.
bool crypt_id_is_valid(struct CryptKeyInfo *key)
Is key ID valid.
static int show_sig_summary(unsigned long sum, gpgme_ctx_t ctx, gpgme_key_t key, int idx, struct State *state, gpgme_signature_t sig)
Show a signature summary.
static void show_fingerprint(gpgme_key_t key, struct State *state)
Write a key's fingerprint.
gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
static void create_recipient_string(const char *keylist, struct Buffer *recpstring, int use_smime)
Create a string of recipients.
static struct CryptKeyInfo * crypt_getkeybystr(const char *p, KeyFlags abilities, unsigned int app, bool *forced_valid)
Find a key by string.
static void print_smime_keyinfo(const char *msg, gpgme_signature_t sig, gpgme_key_t key, struct State *state)
Print key info about an SMIME key.
static int crypt_id_matches_addr(struct Address *addr, struct Address *u_addr, struct CryptKeyInfo *key)
Does the key ID match the address.
bool crypt_id_is_strong(struct CryptKeyInfo *key)
Is the key strong.
static void crypt_add_string_to_hints(const char *str, struct ListHead *hints)
Split a string and add the parts to a List.
const char * crypt_fpr_or_lkeyid(struct CryptKeyInfo *k)
Find the fingerprint of a key.
static char * encrypt_gpgme_object(gpgme_data_t plaintext, char *keylist, bool use_smime, bool combined_signed, const struct AddressList *from)
Encrypt the GPGPME data object.
static void show_one_recipient(struct State *state, gpgme_recipient_t r)
Show information about one encryption recipient.
#define BEGIN_PGP_SIGNATURE(_y)
#define SIGNED_MESSAGE(_y)
#define PKA_NOTATION_NAME
static char * list_to_pattern(struct ListHead *list)
Convert STailQ to GPGME-compatible pattern.
static int get_micalg(gpgme_ctx_t ctx, int use_smime, char *buf, size_t buflen)
Find the "micalg" parameter from the last GPGME operation.
static int data_object_to_stream(gpgme_data_t data, FILE *fp)
Write a GPGME data object to a file.
static int pgp_check_traditional_one_body(FILE *fp, struct Body *b)
Check one inline PGP body part.
static const char * crypt_long_keyid(struct CryptKeyInfo *k)
Find the Long ID for the key.
#define CRYPT_KV_STRONGID
static struct CryptKeyInfo * get_candidates(struct ListHead *hints, SecurityFlags app, int secret)
Get a list of keys which are candidates for the selection.
static gpgme_data_t file_to_data_object(FILE *fp, long offset, size_t length)
Create GPGME data object from file.
static struct Body * decrypt_part(struct Body *b, struct State *state, FILE *fp_out, bool is_smime, int *r_is_signed)
Decrypt a PGP or SMIME message.
#define PUBLIC_KEY_BLOCK(_y)
static int set_signer(gpgme_ctx_t ctx, const struct AddressList *al, bool for_smime)
Make sure that the correct signer is set.
static char * data_object_to_tempfile(gpgme_data_t data, FILE **fp_ret)
Copy a data object to a temporary file.
static void show_one_sig_validity(gpgme_ctx_t ctx, int idx, struct State *state)
Show the validity of a key used for one signature.
static void init_smime(void)
Initialise the SMIME crypto backend.
static struct CryptKeyInfo * crypt_ask_for_key(const char *tag, const char *whatfor, KeyFlags abilities, unsigned int app, bool *forced_valid)
Ask the user for a key.
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
static const char * crypt_fpr(struct CryptKeyInfo *k)
Get the hexstring fingerprint from a key.
const char * crypt_keyid(struct CryptKeyInfo *k)
Find the ID for the key.
static SecurityFlags gpgme_send_menu(struct Email *e, bool is_smime)
Show the user the encryption/signing menu.
static struct Body * sign_message(struct Body *b, const struct AddressList *from, bool use_smime)
Sign a message.
static bool is_pka_notation(gpgme_sig_notation_t notation)
Is this the standard pka email address.
static void redraw_if_needed(gpgme_ctx_t ctx)
Accommodate for a redraw if needed.
static int pgp_gpgme_extract_keys(gpgme_data_t keydata, FILE **fp)
Write PGP keys to a file.
static int line_compare(const char *a, size_t n, const char *b)
Compare two strings ignore line endings.
static void crypt_key_free(struct CryptKeyInfo **keylist)
Release all the keys in a list.
static bool set_signer_from_address(gpgme_ctx_t ctx, const char *address, bool for_smime)
Try to set the context's signer from the address.
static void init_pgp(void)
Initialise the PGP crypto backend.
static void copy_clearsigned(gpgme_data_t data, struct State *state, char *charset)
Copy a clearsigned message.
static int show_one_sig_status(gpgme_ctx_t ctx, int idx, struct State *state)
Show information about one signature.
static void print_time(time_t t, struct State *state)
Print the date/time according to the locale.
Wrapper for PGP/SMIME calls to GPGME.
KeyCap
PGP/SMIME Key Capabilities.
@ KEY_CAP_CAN_CERTIFY
Key can be used to certify.
@ KEY_CAP_CAN_ENCRYPT
Key can be used for encryption.
@ KEY_CAP_CAN_SIGN
Key can be used for signing.
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
void mutt_need_hard_redraw(void)
Force a hard refresh.
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
@ MUTT_COMP_NONE
No flags are set.
void mutt_body_free(struct Body **ptr)
Free a Body.
struct Body * mutt_body_new(void)
Create a new Body.
char * mutt_body_get_charset(struct Body *b, char *buf, size_t buflen)
Get a body's character set.
Structs that make up an email.
void mutt_parse_part(FILE *fp, struct Body *b)
Parse a MIME part.
struct Body * mutt_read_mime_header(FILE *fp, bool digest)
Parse a MIME header.
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
void mutt_exit(int code)
Leave NeoMutt NOW.
long mutt_file_get_size_fp(FILE *fp)
Get the size of a file.
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
long mutt_file_get_size(const char *path)
Get the size of a file.
#define mutt_file_fclose(FP)
#define mutt_file_fopen(PATH, MODE)
bool crypt_keys_are_valid(struct CryptKeyInfo *keys)
Are all these keys valid?
bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
bool OptPgpCheckTrust
(pseudo) used by dlg_pgp()
int pgp_gpgme_application_handler(struct Body *b, struct State *state)
Manage the MIME type "application/pgp" or "application/smime" - Implements CryptModuleSpecs::applicat...
int smime_gpgme_application_handler(struct Body *b, struct State *state)
Manage the MIME type "application/pgp" or "application/smime" - Implements CryptModuleSpecs::applicat...
int smime_gpgme_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.
int pgp_gpgme_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.
int pgp_gpgme_encrypted_handler(struct Body *b, struct State *state)
Manage a PGP or S/MIME encrypted MIME part - Implements CryptModuleSpecs::encrypted_handler() -.
char * smime_gpgme_find_keys(const struct AddressList *addrlist, bool oppenc_mode)
Find the keyids of the recipients of a message - Implements CryptModuleSpecs::find_keys() -.
char * pgp_gpgme_find_keys(const struct AddressList *addrlist, bool oppenc_mode)
Find the keyids of the recipients of a message - Implements CryptModuleSpecs::find_keys() -.
void smime_gpgme_init(void)
Initialise the crypto module - Implements CryptModuleSpecs::init() -.
void pgp_gpgme_init(void)
Initialise the crypto module - Implements CryptModuleSpecs::init() -.
bool pgp_gpgme_check_traditional(FILE *fp, struct Body *b, bool just_one)
Look for inline (non-MIME) PGP content - Implements CryptModuleSpecs::pgp_check_traditional() -.
struct Body * pgp_gpgme_encrypt_message(struct Body *b, char *keylist, bool sign, const struct AddressList *from)
PGP encrypt an email - Implements CryptModuleSpecs::pgp_encrypt_message() -.
void pgp_gpgme_invoke_import(const char *fname)
Import a key from a message into the user's public key ring - Implements CryptModuleSpecs::pgp_invoke...
struct Body * pgp_gpgme_make_key_attachment(void)
Generate a public key attachment - Implements CryptModuleSpecs::pgp_make_key_attachment() -.
void pgp_gpgme_set_sender(const char *sender)
Set the sender of the email - Implements CryptModuleSpecs::set_sender() -.
struct Body * smime_gpgme_sign_message(struct Body *b, const struct AddressList *from)
Cryptographically sign the Body of a message - Implements CryptModuleSpecs::sign_message() -.
struct Body * pgp_gpgme_sign_message(struct Body *b, const struct AddressList *from)
Cryptographically sign the Body of a message - Implements CryptModuleSpecs::sign_message() -.
struct Body * smime_gpgme_build_smime_entity(struct Body *b, char *keylist)
Encrypt the email body to all recipients - Implements CryptModuleSpecs::smime_build_smime_entity() -.
int smime_gpgme_verify_sender(struct Email *e, struct Message *msg)
Does the sender match the certificate?
int pgp_gpgme_verify_one(struct Body *b, struct State *state, const char *tempfile)
Check a signed MIME part against a signature - Implements CryptModuleSpecs::verify_one() -.
int smime_gpgme_verify_one(struct Body *b, struct State *state, const char *tempfile)
Check a signed MIME part against a signature - Implements CryptModuleSpecs::verify_one() -.
struct CryptKeyInfo * dlg_gpgme(struct CryptKeyInfo *keys, struct Address *p, const char *s, unsigned int app, bool *forced_valid)
Get the user to select a key -.
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
int mw_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question -.
int mutt_protected_headers_handler(struct Body *b_email, struct State *state)
Handler for protected headers - Implements handler_t -.
#define mutt_message(...)
#define mutt_debug(LEVEL,...)
Convenience wrapper for the gui headers.
int mutt_body_handler(struct Body *b, struct State *state)
Handler for the Body of an email.
void mutt_decode_attachment(const struct Body *b, struct State *state)
Decode an email's attachment.
Read/write command history from/to a file.
@ HC_OTHER
Miscellaneous strings.
void mutt_crypt_hook(struct ListHead *list, struct Address *addr)
Find crypto hooks for an Address.
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
@ LL_DEBUG5
Log at debug level 5.
@ LL_DEBUG2
Log at debug level 2.
@ LL_DEBUG1
Log at debug level 1.
#define FREE(x)
Free memory and set the pointer to NULL.
#define MUTT_MEM_CALLOC(n, type)
#define MUTT_MEM_REALLOC(pptr, n, type)
#define MUTT_MEM_MALLOC(n, type)
@ ENC_BASE64
Base-64 encoded text.
@ TYPE_MULTIPART
Type: 'multipart/*'.
@ TYPE_APPLICATION
Type: 'application/*'.
@ TYPE_TEXT
Type: 'text/*'.
@ DISP_ATTACH
Content is attached.
@ DISP_INLINE
Content is inline.
@ DISP_NONE
No preferred disposition.
#define is_multipart(body)
Check if a body part is multipart or a message container.
@ MODULE_ID_AUTOCRYPT
ModuleAutocrypt, Autocrypt
@ MODULE_ID_NCRYPT
ModuleNcrypt, Ncrypt
void mutt_generate_boundary(struct ParameterList *pl)
Create a unique boundary id for a MIME part.
bool mutt_ch_check_charset(const char *cs, bool strict)
Does iconv understand a character set?
int mutt_ch_fgetconv(struct FgetConv *fc)
Convert a file's character set.
struct FgetConv * mutt_ch_fgetconv_open(FILE *fp, const char *from, const char *to, uint8_t flags)
Prepare a file for charset conversion.
char * mutt_ch_fgetconvs(char *buf, size_t buflen, struct FgetConv *fc)
Convert a file's charset into a string buffer.
void mutt_ch_fgetconv_close(struct FgetConv **ptr)
Close an fgetconv handle.
#define MUTT_ICONV_HOOK_FROM
apply charset-hooks to fromcode
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Convenience wrapper for the library headers.
void state_attach_puts(struct State *state, const char *t)
Write a string to the state.
int state_printf(struct State *state, const char *fmt,...)
Write a formatted string to the State.
#define state_puts(STATE, STR)
#define state_putc(STATE, STR)
@ STATE_NONE
No flags are set.
@ STATE_VERIFY
Perform signature verification.
@ STATE_DISPLAY
Output is displayed to the user.
int mutt_istrn_cmp(const char *a, const char *b, size_t num)
Compare two strings ignoring case (to a maximum), safely.
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
char * mutt_str_dup(const char *str)
Copy a string, safely.
char * mutt_str_lower(char *str)
Convert all characters in the string to lowercase.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case).
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination).
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Many unsorted constants and some structs.
int mutt_decode_save_attachment(FILE *fp, struct Body *b, const char *path, StateFlags flags, enum SaveAttach opt)
Decode, then save an attachment.
@ MUTT_SAVE_NONE
Overwrite existing file (the default).
void mutt_clear_error(void)
Clear the message line (bottom line of screen).
API for encryption/signing of emails.
@ SEC_NONE
No flags are set.
@ SEC_OPPENCRYPT
Opportunistic encrypt mode.
@ SEC_SIGN
Email is signed.
@ SEC_ENCRYPT
Email is encrypted.
#define APPLICATION_PGP
Use PGP to encrypt/sign.
#define PGP_ENCRYPT
Email is PGP encrypted.
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
@ KEYFLAG_REVOKED
Key is revoked.
@ KEYFLAG_NONE
No flags are set.
@ KEYFLAG_CANSIGN
Key is suitable for signing.
@ KEYFLAG_ISX509
Key is an X.509 key.
@ KEYFLAG_EXPIRED
Key is expired.
@ KEYFLAG_CANENCRYPT
Key is suitable for encryption.
@ KEYFLAG_DISABLED
Key is marked disabled.
Ncrypt private Module data.
Shared constants/structs that are private to libconn.
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
QuadOption
Possible values for a quad-option.
@ MUTT_ABORT
User aborted the question (with Ctrl-G).
@ MUTT_NO
User answered 'No', or assume 'No'.
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
enum QuadOption query_yesorno_help(const char *prompt, enum QuadOption def, struct ConfigSubset *sub, const char *name)
Ask the user a Yes/No question offering help.
#define TAILQ_FOREACH(var, head, field)
#define STAILQ_HEAD_INITIALIZER(head)
#define STAILQ_FIRST(head)
#define STAILQ_FOREACH(var, head, field)
#define TAILQ_FIRST(head)
#define TAILQ_HEAD_INITIALIZER(head)
#define TAILQ_EMPTY(head)
#define STAILQ_NEXT(elm, field)
int mutt_write_mime_body(struct Body *b, FILE *fp, struct ConfigSubset *sub)
Write a MIME part.
Convenience wrapper for the send headers.
void mutt_update_encoding(struct Body *b, struct ConfigSubset *sub)
Update the encoding type.
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
struct Buffer * personal
Real name of address.
struct Buffer * mailbox
Mailbox and host address.
Autocrypt private Module data.
char * autocrypt_sign_as
Autocrypt Key id to sign as.
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
struct Body * parts
parts of a multipart or message/rfc822
LOFF_T offset
offset where the actual data begins
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
struct Envelope * mime_headers
Memory hole protected headers.
LOFF_T length
length (in bytes) of attachment
struct ParameterList parameter
Parameters of the content-type.
bool use_disp
Content-Disposition uses filename= ?
char * description
content-description
unsigned int disposition
content-disposition, ContentDisposition
struct Body * next
next attachment in the list
char * subtype
content-type subtype
unsigned int encoding
content-transfer-encoding, ContentEncoding
bool goodsig
Good cryptographic signature.
bool warnsig
Maybe good signature.
unsigned int type
content-type primary type, ContentType
char * filename
When sending a message, this is the file to which this structure refers.
String manipulation buffer.
char * data
Pointer to data.
Internal cache for GPGME.
char * what
Cached key identifier.
char * dflt
Default key ID.
struct CryptCache * next
Linked list.
gpgme_validity_t validity
uid validity (cached for convenience)
KeyFlags flags
global and per uid flags (for convenience)
int idx
and the user ID at this index
struct CryptKeyInfo * next
Linked list.
const char * uid
and for convenience point to this user ID
gpgme_key_t kobj
GPGME key object.
The envelope/body of an email.
struct Envelope * env
Envelope information.
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
struct AddressList sender
Email's sender.
struct AddressList from
Email's 'From' list.
Cursor for converting a file's encoding.
FILE * fp
File to read from.
A local copy of an email.
Ncrypt private Module data.
struct CryptCache * gpgme_id_defaults
GPGME IdDefaults cache.
gpgme_key_t signature_key
GPGME Signature key.
char * current_sender
Current sender for GPGME.
Container for Accounts, Notifications.
struct ConfigSubset * sub
Inherited config items.
Keep track when processing files.
StateFlags flags
Flags, e.g. STATE_DISPLAY.
FILE * fp_out
File to write to.
FILE * fp_in
File to read from.
const char * prefix
String to add to the beginning of each output line.
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
#define mutt_file_mkstemp()