NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
crypt.h File Reference

Signing/encryption multiplexor. More...

#include <stdbool.h>
+ Include dependency graph for crypt.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void crypt_convert_to_7bit (struct Body *b)
 Convert an email to 7bit encoding.
 
void crypt_current_time (struct State *state, const char *app_name)
 Print the current time.
 
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.
 
bool crypt_is_numerical_keyid (const char *s)
 Is this a numerical keyid.
 
int crypt_write_signed (struct Body *b, struct State *state, const char *tempfile)
 Write the message body/part.
 

Detailed Description

Signing/encryption multiplexor.

Authors
  • Richard Russon
  • Pietro Cerutti

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, see http://www.gnu.org/licenses/.

Definition in file crypt.h.

Function Documentation

◆ crypt_convert_to_7bit()

void crypt_convert_to_7bit ( struct Body * b)

Convert an email to 7bit encoding.

Parameters
bBody of email to convert

Definition at line 815 of file crypt.c.

816{
817 if (!WithCrypto)
818 return;
819
820 const bool c_pgp_strict_enc = cs_subset_bool(NeoMutt->sub, "pgp_strict_enc");
821 while (b)
822 {
823 if (b->type == TYPE_MULTIPART)
824 {
825 if (b->encoding != ENC_7BIT)
826 {
827 b->encoding = ENC_7BIT;
829 }
830 else if (((WithCrypto & APPLICATION_PGP) != 0) && c_pgp_strict_enc)
831 {
833 }
834 }
835 else if ((b->type == TYPE_MESSAGE) && !mutt_istr_equal(b->subtype, "delivery-status"))
836 {
837 if (b->encoding != ENC_7BIT)
839 }
840 else if (b->encoding == ENC_8BIT)
841 {
843 }
844 else if (b->encoding == ENC_BINARY)
845 {
846 b->encoding = ENC_BASE64;
847 }
848 else if (b->content && (b->encoding != ENC_BASE64) &&
849 (b->content->from || (b->content->space && c_pgp_strict_enc)))
850 {
852 }
853 b = b->next;
854 }
855}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
void crypt_convert_to_7bit(struct Body *b)
Convert an email to 7bit encoding.
Definition crypt.c:815
@ ENC_7BIT
7-bit text
Definition mime.h:49
@ ENC_BINARY
Binary.
Definition mime.h:53
@ ENC_BASE64
Base-64 encoded text.
Definition mime.h:52
@ ENC_8BIT
8-bit text
Definition mime.h:50
@ ENC_QUOTED_PRINTABLE
Quoted-printable text.
Definition mime.h:51
@ TYPE_MESSAGE
Type: 'message/*'.
Definition mime.h:35
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition mime.h:37
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:678
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:106
#define WithCrypto
Definition lib.h:132
void mutt_message_to_7bit(struct Body *b, FILE *fp, struct ConfigSubset *sub)
Convert an email's MIME parts to 7-bit.
Definition sendlib.c:261
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
struct Content * content
Detailed info about the content of the attachment.
Definition body.h:70
struct Body * next
next attachment in the list
Definition body.h:72
char * subtype
content-type subtype
Definition body.h:61
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
unsigned int type
content-type primary type, ContentType
Definition body.h:40
bool space
Whitespace at the end of lines?
Definition content.h:42
bool from
Has a line beginning with "From "?
Definition content.h:44
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_current_time()

void crypt_current_time ( struct State * state,
const char * app_name )

Print the current time.

Parameters
stateState to use
app_nameApp name, e.g. "PGP"

print the current time to avoid spoofing of the signature output

Definition at line 64 of file crypt.c.

65{
66 char p[256] = { 0 };
67 char tmp[512] = { 0 };
68
69 if (!WithCrypto)
70 return;
71
72 const bool c_crypt_timestamp = cs_subset_bool(NeoMutt->sub, "crypt_timestamp");
73 if (c_crypt_timestamp)
74 {
75 mutt_date_localtime_format(p, sizeof(p), _(" (current time: %c)"), mutt_date_now());
76 }
77 else
78 {
79 *p = '\0';
80 }
81
82 snprintf(tmp, sizeof(tmp), _("[-- %s output follows%s --]\n"), NONULL(app_name), p);
83 state_attach_puts(state, tmp);
84}
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition date.c:957
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition date.c:459
#define _(a)
Definition message.h:28
void state_attach_puts(struct State *state, const char *t)
Write a string to the state.
Definition state.c:104
#define NONULL(x)
Definition string2.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_get_fingerprint_or_id()

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.

Parameters
[in]pString to examine
[out]pphintStart of string to be passed to pgp_add_string_to_hints() or crypt_add_string_to_hints()
[out]pplStart of long key ID if detected, else NULL
[out]ppsStart of short key ID if detected, else NULL
Return values
ptrCopy of fingerprint, if any, stripped of all spaces. Must be FREE'd by caller
NULLOtherwise

Obtain pointers to fingerprint or short or long key ID, if any.

Upon return, at most one of return, *ppl and *pps pointers is non-NULL, indicating the longest fingerprint or ID found, if any.

Definition at line 1396 of file crypt.c.

1398{
1399 const char *ps = NULL;
1400 const char *pl = NULL;
1401 const char *phint = NULL;
1402 char *pfcopy = NULL;
1403 char *s1 = NULL;
1404 char *s2 = NULL;
1405 char c;
1406 int isid;
1407 size_t hexdigits;
1408
1409 /* User input may be partial name, fingerprint or short or long key ID,
1410 * independent of `$pgp_long_ids`.
1411 * Fingerprint without spaces is 40 hex digits (SHA-1) or 32 hex digits (MD5).
1412 * Strip leading "0x" for key ID detection and prepare pl and ps to indicate
1413 * if an ID was found and to simplify logic in the key loop's inner
1414 * condition of the caller. */
1415
1416 char *pf = mutt_str_skip_whitespace(p);
1417 if (mutt_istr_startswith(pf, "0x"))
1418 pf += 2;
1419
1420 /* Check if a fingerprint is given, must be hex digits only, blanks
1421 * separating groups of 4 hex digits are allowed. Also pre-check for ID. */
1422 isid = 2; /* unknown */
1423 hexdigits = 0;
1424 s1 = pf;
1425 do
1426 {
1427 c = *(s1++);
1428 if ((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) ||
1429 (('a' <= c) && (c <= 'f')))
1430 {
1431 hexdigits++;
1432 if (isid == 2)
1433 isid = 1; /* it is an ID so far */
1434 }
1435 else if (c)
1436 {
1437 isid = 0; /* not an ID */
1438 if ((c == ' ') && ((hexdigits % 4) == 0))
1439 ; /* skip blank before or after 4 hex digits */
1440 else
1441 break; /* any other character or position */
1442 }
1443 } while (c);
1444
1445 /* If at end of input, check for correct fingerprint length and copy if. */
1446 pfcopy = (!c && ((hexdigits == 40) || (hexdigits == 32)) ? mutt_str_dup(pf) : NULL);
1447
1448 if (pfcopy)
1449 {
1450 /* Use pfcopy to strip all spaces from fingerprint and as hint. */
1451 s1 = pfcopy;
1452 s2 = pfcopy;
1453 do
1454 {
1455 *(s1++) = *(s2 = mutt_str_skip_whitespace(s2));
1456 } while (*(s2++));
1457
1458 phint = pfcopy;
1459 ps = NULL;
1460 pl = NULL;
1461 }
1462 else
1463 {
1464 phint = p;
1465 ps = NULL;
1466 pl = NULL;
1467 if (isid == 1)
1468 {
1469 if (mutt_str_len(pf) == 16)
1470 pl = pf; /* long key ID */
1471 else if (mutt_str_len(pf) == 8)
1472 ps = pf; /* short key ID */
1473 }
1474 }
1475
1476 *pphint = phint;
1477 *ppl = pl;
1478 *pps = ps;
1479 return pfcopy;
1480}
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
Definition string.c:557
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition string.c:246
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_is_numerical_keyid()

bool crypt_is_numerical_keyid ( const char * s)

Is this a numerical keyid.

Parameters
sKey to test
Return values
trueKeyid is numeric

Check if a crypt-hook value is a key id.

Definition at line 1489 of file crypt.c.

1490{
1491 /* or should we require the "0x"? */
1492 if (mutt_strn_equal(s, "0x", 2))
1493 s += 2;
1494 if (strlen(s) % 8)
1495 return false;
1496 while (*s)
1497 if (!strchr("0123456789ABCDEFabcdef", *s++))
1498 return false;
1499
1500 return true;
1501}
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition string.c:429
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_write_signed()

int crypt_write_signed ( struct Body * b,
struct State * state,
const char * tempfile )

Write the message body/part.

Parameters
bBody to write
stateState to use
tempfileFile to write to
Return values
0Success
-1Error

Body/part A described by state state to the given TEMPFILE.

Definition at line 765 of file crypt.c.

766{
767 if (!WithCrypto)
768 return -1;
769
770 FILE *fp = mutt_file_fopen(tempfile, "w");
771 if (!fp)
772 {
773 mutt_perror("%s", tempfile);
774 return -1;
775 }
776
777 if (!mutt_file_seek(state->fp_in, b->hdr_offset, SEEK_SET))
778 {
779 mutt_file_fclose(&fp);
780 return -1;
781 }
782 size_t bytes = b->length + b->offset - b->hdr_offset;
783 bool hadcr = false;
784 while (bytes > 0)
785 {
786 const int c = fgetc(state->fp_in);
787 if (c == EOF)
788 break;
789
790 bytes--;
791
792 if (c == '\r')
793 {
794 hadcr = true;
795 }
796 else
797 {
798 if ((c == '\n') && !hadcr)
799 fputc('\r', fp);
800
801 hadcr = false;
802 }
803
804 fputc(c, fp);
805 }
806 mutt_file_fclose(&fp);
807
808 return 0;
809}
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition file.c:648
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
#define mutt_perror(...)
Definition logging2.h:95
LOFF_T offset
offset where the actual data begins
Definition body.h:52
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
long hdr_offset
Offset in stream where the headers begin.
Definition body.h:81
FILE * fp_in
File to read from.
Definition state.h:55
+ Here is the call graph for this function:
+ Here is the caller graph for this function: