From 4bc76c2f3d425a95b30b06cc73cb7c73f34f26db Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Mon, 18 Jun 2018 22:04:47 +0200 Subject: [PATCH] Allow larger passphrase timeout values This came up in the comp.mail.mutt newsgroup where a user wasn't satisfied with the SHORT_MAX seconds ~9 hours limit on passphrase timeouts. For the first time made it necessary for the options parser to be able to parse numbers as long values. Also, introduced mutt_add_timeout() to detect possible overflow before adding a timeout to a time_t value and truncate to TIME_T_MAX instead. --- date.c | 13 +++++++++++++ doc/makedoc.c | 2 ++ doc/manual.xml.head | 8 ++++++++ globals.h | 4 ++-- init.c | 41 +++++++++++++++++++++++++++++++++++++++++ init.h | 7 ++++--- pgp.c | 2 +- protos.h | 1 + smime.c | 2 +- 9 files changed, 73 insertions(+), 7 deletions(-) diff --git a/date.c b/date.c index 2a8d4b47..497ffdd4 100644 --- a/date.c +++ b/date.c @@ -120,6 +120,19 @@ time_t mutt_mktime (struct tm *t, int local) return (g); } +/* Safely add a timeout to a given time_t value, truncating instead of + * overflowing. */ +time_t mutt_add_timeout (time_t now, long timeout) +{ + if (timeout < 0) + return now; + + if (TIME_T_MAX - now < timeout) + return TIME_T_MAX; + + return now + timeout; +} + /* Return 1 if month is February of leap year, else 0 */ static int isLeapYearFeb (struct tm *tm) { diff --git a/doc/makedoc.c b/doc/makedoc.c index 8b12d7f7..a84554b7 100644 --- a/doc/makedoc.c +++ b/doc/makedoc.c @@ -351,6 +351,7 @@ enum DT_NONE = 0, DT_BOOL, DT_NUM, + DT_LNUM, DT_STR, DT_PATH, DT_QUAD, @@ -372,6 +373,7 @@ types[] = { "DT_NONE", "-none-" }, { "DT_BOOL", "boolean" }, { "DT_NUM", "number" }, + { "DT_LNUM", "number (long)" }, { "DT_STR", "string" }, { "DT_PATH", "path" }, { "DT_QUAD", "quadoption" }, diff --git a/doc/manual.xml.head b/doc/manual.xml.head index 2f4bc5cc..8ac8fd9d 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -4144,6 +4144,14 @@ A signed integer number in the range -32768 to 32767. +number (long) + + +A signed integer number in the range -2147483648 to 2147483647. + + + + string diff --git a/globals.h b/globals.h index 2aa96f90..116ba60b 100644 --- a/globals.h +++ b/globals.h @@ -254,7 +254,7 @@ WHERE REGEXP PgpGoodSign; WHERE REGEXP PgpDecryptionOkay; WHERE char *PgpDefaultKey; WHERE char *PgpSignAs; -WHERE short PgpTimeout; +WHERE long PgpTimeout; WHERE char *PgpEntryFormat; WHERE char *PgpClearSignCommand; WHERE char *PgpDecodeCommand; @@ -273,7 +273,7 @@ WHERE char *PgpGetkeysCommand; /*-- formerly in smime.h --*/ WHERE char *SmimeDefaultKey; WHERE char *SmimeSignAs; -WHERE short SmimeTimeout; +WHERE long SmimeTimeout; WHERE char *SmimeCertificates; WHERE char *SmimeKeys; WHERE char *SmimeCryptAlg; diff --git a/init.c b/init.c index 2e010674..60808003 100644 --- a/init.c +++ b/init.c @@ -1766,6 +1766,9 @@ static void mutt_restore_default (struct option_t *p) case DT_MAGIC: *((short *) p->data) = p->init; break; + case DT_LNUM: + *((long *) p->data) = p->init; + break; case DT_RX: { REGEXP *pp = (REGEXP *) p->data; @@ -2492,6 +2495,38 @@ static int parse_set (BUFFER *tmp, BUFFER *s, unsigned long data, BUFFER *err) *ptr = 0; } #endif + } + else if (DTYPE(MuttVars[idx].type) == DT_LNUM) + { + long *ptr = (long *) MuttVars[idx].data; + long val; + int rc; + + if (query || *s->dptr != '=') + { + val = *ptr; + + /* user requested the value of this variable */ + snprintf (err->data, err->dsize, "%s=%ld", MuttVars[idx].option, val); + break; + } + + CHECK_PAGER; + s->dptr++; + + mutt_extract_token (tmp, s, 0); + rc = mutt_atol (tmp->data, (long *) &val); + + if (rc < 0 || !*tmp->data) + { + snprintf (err->data, err->dsize, _("%s: invalid value (%s)"), tmp->data, + rc == -1 ? _("format error") : _("number overflow")); + r = -1; + break; + } + else + *ptr = val; + } else if (DTYPE (MuttVars[idx].type) == DT_QUAD) { @@ -3065,6 +3100,12 @@ static int var_to_string (int idx, char* val, size_t len) snprintf (tmp, sizeof (tmp), "%d", sval); } + else if (DTYPE (MuttVars[idx].type) == DT_LNUM) + { + long sval = *((long *) MuttVars[idx].data); + + snprintf (tmp, sizeof (tmp), "%ld", sval); + } else if (DTYPE (MuttVars[idx].type) == DT_SORT) { const struct mapping_t *map; diff --git a/init.h b/init.h index 983fde4b..9858a50c 100644 --- a/init.h +++ b/init.h @@ -29,7 +29,7 @@ #ifndef _MAKEDOC #define DT_MASK 0x0f #define DT_BOOL 1 /* boolean option */ -#define DT_NUM 2 /* a number */ +#define DT_NUM 2 /* a number (short) */ #define DT_STR 3 /* a string */ #define DT_PATH 4 /* a pathname */ #define DT_QUAD 5 /* quad-option (yes/no/ask-yes/ask-no) */ @@ -39,6 +39,7 @@ #define DT_SYN 9 /* synonym for another variable */ #define DT_ADDR 10 /* e-mail address */ #define DT_MBCHARTBL 11 /* multibyte char table */ +#define DT_LNUM 12 /* a number (long) */ #define DTYPE(x) ((x) & DT_MASK) @@ -2265,7 +2266,7 @@ struct option_t MuttVars[] = { ** this if you know what you are doing. ** (PGP only) */ - { "pgp_timeout", DT_NUM, R_NONE, UL &PgpTimeout, 300 }, + { "pgp_timeout", DT_LNUM, R_NONE, UL &PgpTimeout, 300 }, /* ** .pp ** The number of seconds after which a cached passphrase will expire if @@ -3306,7 +3307,7 @@ struct option_t MuttVars[] = { ** possible \fCprintf(3)\fP-like sequences. ** (S/MIME only) */ - { "smime_timeout", DT_NUM, R_NONE, UL &SmimeTimeout, 300 }, + { "smime_timeout", DT_LNUM, R_NONE, UL &SmimeTimeout, 300 }, /* ** .pp ** The number of seconds after which a cached passphrase will expire if diff --git a/pgp.c b/pgp.c index 60971119..776af84e 100644 --- a/pgp.c +++ b/pgp.c @@ -90,7 +90,7 @@ int pgp_valid_passphrase (void) if (mutt_get_password (_("Enter PGP passphrase:"), PgpPass, sizeof (PgpPass)) == 0) { - PgpExptime = time (NULL) + PgpTimeout; + PgpExptime = mutt_add_timeout (time (NULL), PgpTimeout); return (1); } else diff --git a/protos.h b/protos.h index 4076d861..432304e5 100644 --- a/protos.h +++ b/protos.h @@ -121,6 +121,7 @@ time_t mutt_decrease_mtime (const char *, struct stat *); time_t mutt_local_tz (time_t); time_t mutt_mktime (struct tm *, int); time_t mutt_parse_date (const char *, HEADER *); +time_t mutt_add_timeout (time_t, long); int is_from (const char *, char *, size_t, time_t *); void mutt_touch_atime (int); int mutt_timespec_compare (struct timespec *a, struct timespec *b); diff --git a/smime.c b/smime.c index 823fc73d..13a3e2cc 100644 --- a/smime.c +++ b/smime.c @@ -140,7 +140,7 @@ int smime_valid_passphrase (void) if (mutt_get_password (_("Enter S/MIME passphrase:"), SmimePass, sizeof (SmimePass)) == 0) { - SmimeExptime = time (NULL) + SmimeTimeout; + SmimeExptime = mutt_add_timeout (time (NULL), SmimeTimeout); return (1); } else -- 2.50.0