NeoMutt  2023-05-17-33-gce4425
Teaching an old dog new tricks
DOXYGEN
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 *a)
 Convert an email to 7bit encoding. More...
 
void crypt_current_time (struct State *state, const char *app_name)
 Print the current time. More...
 
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. More...
 
bool crypt_is_numerical_keyid (const char *s)
 Is this a numerical keyid. More...
 
int crypt_write_signed (struct Body *a, struct State *state, const char *tempfile)
 Write the message body/part. More...
 

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 a)

Convert an email to 7bit encoding.

Parameters
aBody of email to convert

Definition at line 799 of file crypt.c.

800{
801 if (!WithCrypto)
802 return;
803
804 const bool c_pgp_strict_enc = cs_subset_bool(NeoMutt->sub, "pgp_strict_enc");
805 while (a)
806 {
807 if (a->type == TYPE_MULTIPART)
808 {
809 if (a->encoding != ENC_7BIT)
810 {
811 a->encoding = ENC_7BIT;
813 }
814 else if (((WithCrypto & APPLICATION_PGP) != 0) && c_pgp_strict_enc)
815 {
817 }
818 }
819 else if ((a->type == TYPE_MESSAGE) && !mutt_istr_equal(a->subtype, "delivery-status"))
820 {
821 if (a->encoding != ENC_7BIT)
823 }
824 else if (a->encoding == ENC_8BIT)
825 {
827 }
828 else if (a->encoding == ENC_BINARY)
829 {
830 a->encoding = ENC_BASE64;
831 }
832 else if (a->content && (a->encoding != ENC_BASE64) &&
833 (a->content->from || (a->content->space && c_pgp_strict_enc)))
834 {
836 }
837 a = a->next;
838 }
839}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:799
@ 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:810
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define WithCrypto
Definition: lib.h:116
void mutt_message_to_7bit(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Convert an email's MIME parts to 7-bit.
Definition: sendlib.c:253
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:72
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:69
struct Body * next
next attachment in the list
Definition: body.h:71
char * subtype
content-type subtype
Definition: body.h:60
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:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 69 of file crypt.c.

70{
71 char p[256], tmp[256];
72
73 if (!WithCrypto)
74 return;
75
76 const bool c_crypt_timestamp = cs_subset_bool(NeoMutt->sub, "crypt_timestamp");
77 if (c_crypt_timestamp)
78 {
79 mutt_date_localtime_format(p, sizeof(p), _(" (current time: %c)"), mutt_date_now());
80 }
81 else
82 {
83 *p = '\0';
84 }
85
86 snprintf(tmp, sizeof(tmp), _("[-- %s output follows%s --]\n"), NONULL(app_name), p);
87 state_attach_puts(state, tmp);
88}
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:924
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:446
#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:102
#define NONULL(x)
Definition: string2.h:37
+ 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 1278 of file crypt.c.

1280{
1281 const char *ps = NULL, *pl = NULL, *phint = NULL;
1282 char *pfcopy = NULL, *s1 = NULL, *s2 = NULL;
1283 char c;
1284 int isid;
1285 size_t hexdigits;
1286
1287 /* User input may be partial name, fingerprint or short or long key ID,
1288 * independent of `$pgp_long_ids`.
1289 * Fingerprint without spaces is 40 hex digits (SHA-1) or 32 hex digits (MD5).
1290 * Strip leading "0x" for key ID detection and prepare pl and ps to indicate
1291 * if an ID was found and to simplify logic in the key loop's inner
1292 * condition of the caller. */
1293
1294 char *pf = mutt_str_skip_whitespace(p);
1295 if (mutt_istr_startswith(pf, "0x"))
1296 pf += 2;
1297
1298 /* Check if a fingerprint is given, must be hex digits only, blanks
1299 * separating groups of 4 hex digits are allowed. Also pre-check for ID. */
1300 isid = 2; /* unknown */
1301 hexdigits = 0;
1302 s1 = pf;
1303 do
1304 {
1305 c = *(s1++);
1306 if ((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) ||
1307 (('a' <= c) && (c <= 'f')))
1308 {
1309 hexdigits++;
1310 if (isid == 2)
1311 isid = 1; /* it is an ID so far */
1312 }
1313 else if (c)
1314 {
1315 isid = 0; /* not an ID */
1316 if ((c == ' ') && ((hexdigits % 4) == 0))
1317 ; /* skip blank before or after 4 hex digits */
1318 else
1319 break; /* any other character or position */
1320 }
1321 } while (c);
1322
1323 /* If at end of input, check for correct fingerprint length and copy if. */
1324 pfcopy = (!c && ((hexdigits == 40) || (hexdigits == 32)) ? mutt_str_dup(pf) : NULL);
1325
1326 if (pfcopy)
1327 {
1328 /* Use pfcopy to strip all spaces from fingerprint and as hint. */
1329 s1 = pfcopy;
1330 s2 = pfcopy;
1331 do
1332 {
1333 *(s1++) = *(s2 = mutt_str_skip_whitespace(s2));
1334 } while (*(s2++));
1335
1336 phint = pfcopy;
1337 ps = NULL;
1338 pl = NULL;
1339 }
1340 else
1341 {
1342 phint = p;
1343 ps = NULL;
1344 pl = NULL;
1345 if (isid == 1)
1346 {
1347 if (mutt_str_len(pf) == 16)
1348 pl = pf; /* long key ID */
1349 else if (mutt_str_len(pf) == 8)
1350 ps = pf; /* short key ID */
1351 }
1352 }
1353
1354 *pphint = phint;
1355 *ppl = pl;
1356 *pps = ps;
1357 return pfcopy;
1358}
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
Definition: string.c:623
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:568
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:240
+ 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 1367 of file crypt.c.

1368{
1369 /* or should we require the "0x"? */
1370 if (mutt_strn_equal(s, "0x", 2))
1371 s += 2;
1372 if (strlen(s) % 8)
1373 return false;
1374 while (*s)
1375 if (!strchr("0123456789ABCDEFabcdef", *s++))
1376 return false;
1377
1378 return true;
1379}
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:497
+ 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 a,
struct State state,
const char *  tempfile 
)

Write the message body/part.

Parameters
aBody 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 749 of file crypt.c.

750{
751 if (!WithCrypto)
752 return -1;
753
754 FILE *fp = mutt_file_fopen(tempfile, "w");
755 if (!fp)
756 {
757 mutt_perror(tempfile);
758 return -1;
759 }
760
761 if (!mutt_file_seek(state->fp_in, a->hdr_offset, SEEK_SET))
762 {
763 mutt_file_fclose(&fp);
764 return -1;
765 }
766 size_t bytes = a->length + a->offset - a->hdr_offset;
767 bool hadcr = false;
768 while (bytes > 0)
769 {
770 const int c = fgetc(state->fp_in);
771 if (c == EOF)
772 break;
773
774 bytes--;
775
776 if (c == '\r')
777 {
778 hadcr = true;
779 }
780 else
781 {
782 if ((c == '\n') && !hadcr)
783 fputc('\r', fp);
784
785 hadcr = false;
786 }
787
788 fputc(c, fp);
789 }
790 mutt_file_fclose(&fp);
791
792 return 0;
793}
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:634
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:708
#define mutt_perror(...)
Definition: logging2.h:88
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:80
FILE * fp_in
File to read from.
Definition: state.h:48
+ Here is the call graph for this function:
+ Here is the caller graph for this function: