From b8466bf029ea6ec1c409c65b75e6b7a1820b9635 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. --- doc/makedoc.c | 2 ++ doc/manual.xml.head | 8 ++++++++ globals.h | 4 ++-- init.c | 39 +++++++++++++++++++++++++++++++++++++++ init.h | 4 ++-- mutt/date.c | 19 +++++++++++++++++++ mutt/date.h | 2 ++ mutt_options.h | 5 +++-- ncrypt/pgp.c | 2 +- ncrypt/smime.c | 2 +- 10 files changed, 79 insertions(+), 8 deletions(-) diff --git a/doc/makedoc.c b/doc/makedoc.c index f756acc7d..e13103cbf 100644 --- a/doc/makedoc.c +++ b/doc/makedoc.c @@ -950,6 +950,7 @@ enum DataType DT_NONE = 0, DT_BOOL, DT_NUMBER, + DT_LONG, DT_STRING, DT_PATH, DT_QUAD, @@ -969,6 +970,7 @@ struct VariableTypes { "DT_NONE", "-none-" }, { "DT_BOOL", "boolean" }, { "DT_NUMBER", "number" }, + { "DT_LONG", "number (long)" }, { "DT_STRING", "string" }, { "DT_PATH", "path" }, { "DT_QUAD", "quadoption" }, diff --git a/doc/manual.xml.head b/doc/manual.xml.head index 5982670ed..798f16416 100644 --- a/doc/manual.xml.head +++ b/doc/manual.xml.head @@ -5914,6 +5914,14 @@ set spam_separator=", " + + number (long) + + + A signed integer number in the range -2147483648 to 2147483647. + + + string diff --git a/globals.h b/globals.h index 688aad233..ef60480dc 100644 --- a/globals.h +++ b/globals.h @@ -264,7 +264,7 @@ WHERE struct Regex *PgpGoodSign; WHERE struct Regex *PgpDecryptionOkay; WHERE char *PgpDefaultKey; WHERE char *PgpSignAs; -WHERE short PgpTimeout; +WHERE long PgpTimeout; WHERE char *PgpEntryFormat; WHERE char *PgpClearsignCommand; WHERE char *PgpDecodeCommand; @@ -283,7 +283,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 *SmimeEncryptWith; diff --git a/init.c b/init.c index 8e061150f..9f5be9b48 100644 --- a/init.c +++ b/init.c @@ -1116,6 +1116,9 @@ static void restore_default(struct Option *p) else *((short *) p->var) = p->initial; break; + case DT_LONG: + *((long *) p->var) = p->initial; + break; case DT_REGEX: { struct Regex **ptr = (struct Regex **) p->var; @@ -2383,6 +2386,36 @@ static int parse_set(struct Buffer *buf, struct Buffer *s, unsigned long data, } #endif } + else if (DTYPE(MuttVars[idx].type) == DT_LONG) + { + long *ptr = (long *) MuttVars[idx].var; + long val; + + if (query || *s->dptr != '=') + { + val = *ptr; + + /* user requested the value of this variable */ + snprintf(err->data, err->dsize, "%s=%ld", MuttVars[idx].name, val); + break; + } + + CHECK_PAGER; + s->dptr++; + + mutt_extract_token(buf, s, 0); + int rc = mutt_str_atol(buf->data, (long *) &val); + + if (rc < 0 || !*buf->data) + { + snprintf(err->data, err->dsize, _("%s: invalid value (%s)"), buf->data, + rc == -1 ? _("format error") : _("number overflow")); + r = -1; + break; + } + else + *ptr = val; + } else if ((idx >= 0) && (DTYPE(MuttVars[idx].type) == DT_QUAD)) { if (query) @@ -4432,6 +4465,12 @@ int var_to_string(int idx, char *val, size_t len) snprintf(tmp, sizeof(tmp), "%d", sval); } + else if (DTYPE(MuttVars[idx].type) == DT_LONG) + { + long sval = *((long *) MuttVars[idx].var); + + snprintf(tmp, sizeof(tmp), "%ld", sval); + } else if (DTYPE(MuttVars[idx].type) == DT_SORT) { const struct Mapping *map = NULL; diff --git a/init.h b/init.h index f5e797007..4691cd16d 100644 --- a/init.h +++ b/init.h @@ -2599,7 +2599,7 @@ struct Option MuttVars[] = { ** this if you know what you are doing. ** (PGP only) */ - { "pgp_timeout", DT_NUMBER, R_NONE, &PgpTimeout, 300 }, + { "pgp_timeout", DT_LONG, R_NONE, &PgpTimeout, 300 }, /* ** .pp ** The number of seconds after which a cached passphrase will expire if @@ -3705,7 +3705,7 @@ struct Option MuttVars[] = { ** Valid choices are ``md5'', ``sha1'', ``sha224'', ``sha256'', ``sha384'', ``sha512''. ** (S/MIME only) */ - { "smime_timeout", DT_NUMBER, R_NONE, &SmimeTimeout, 300 }, + { "smime_timeout", DT_LONG, R_NONE, &SmimeTimeout, 300 }, /* ** .pp ** The number of seconds after which a cached passphrase will expire if diff --git a/mutt/date.c b/mutt/date.c index 79bb9836f..f6ab10834 100644 --- a/mutt/date.c +++ b/mutt/date.c @@ -682,3 +682,22 @@ time_t mutt_date_parse_imap(char *s) return (mutt_date_make_time(&t, 0) + tz); } + +/** + * mutt_date_add_timeout - Safely add a timeout to a given time_t value + * @param now Time now + * @param timeout Timeout in seconds + * @retval num Unix time to timeout + * + * This will truncate instead of overflowing. + */ +time_t mutt_date_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); +} diff --git a/mutt/date.h b/mutt/date.h index 0204f0e1b..be9fa1834 100644 --- a/mutt/date.h +++ b/mutt/date.h @@ -47,5 +47,7 @@ int mutt_date_make_tls(char *buf, size_t buflen, time_t timestamp); void mutt_date_normalize_time(struct tm *tm); time_t mutt_date_parse_date(const char *s, struct Tz *tz_out); time_t mutt_date_parse_imap(char *s); +time_t mutt_date_add_timeout(time_t now, long timeout); + #endif /* _MUTT_DATE_H */ diff --git a/mutt_options.h b/mutt_options.h index 2021cf7ac..20ce047c1 100644 --- a/mutt_options.h +++ b/mutt_options.h @@ -30,7 +30,7 @@ struct Buffer; #define DT_MASK 0x0f #define DT_BOOL 1 /**< boolean option */ -#define DT_NUMBER 2 /**< a number */ +#define DT_NUMBER 2 /**< a number (short) */ #define DT_STRING 3 /**< a string */ #define DT_PATH 4 /**< a pathname */ #define DT_QUAD 5 /**< quad-option (yes/no/ask-yes/ask-no) */ @@ -40,7 +40,8 @@ struct Buffer; #define DT_SYNONYM 9 /**< synonym for another variable */ #define DT_ADDRESS 10 /**< e-mail address */ #define DT_MBTABLE 11 /**< multibyte char table */ -#define DT_HCACHE 12 /**< header cache backend */ +#define DT_LONG 12 /* a number (long) */ +#define DT_HCACHE 13 /**< header cache backend */ #define DTYPE(x) ((x) &DT_MASK) diff --git a/ncrypt/pgp.c b/ncrypt/pgp.c index f03c30f16..26465b002 100644 --- a/ncrypt/pgp.c +++ b/ncrypt/pgp.c @@ -95,7 +95,7 @@ int pgp_class_valid_passphrase(void) if (mutt_get_password(_("Enter PGP passphrase:"), PgpPass, sizeof(PgpPass)) == 0) { - PgpExptime = time(NULL) + PgpTimeout; + PgpExptime = mutt_date_add_timeout(time(NULL), PgpTimeout); return 1; } else diff --git a/ncrypt/smime.c b/ncrypt/smime.c index 1c0988a5f..459e517ab 100644 --- a/ncrypt/smime.c +++ b/ncrypt/smime.c @@ -148,7 +148,7 @@ int smime_class_valid_passphrase(void) if (mutt_get_password(_("Enter S/MIME passphrase:"), SmimePass, sizeof(SmimePass)) == 0) { - SmimeExptime = time(NULL) + SmimeTimeout; + SmimeExptime = mutt_date_add_timeout(time(NULL), SmimeTimeout); return 1; } else -- 2.40.0