]> granicus.if.org Git - neomutt/commitdiff
Allow larger passphrase timeout values
authorEike Rathke <erack@erack.de>
Mon, 18 Jun 2018 20:04:47 +0000 (22:04 +0200)
committerRichard Russon <rich@flatcap.org>
Wed, 20 Jun 2018 15:18:41 +0000 (16:18 +0100)
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
doc/manual.xml.head
globals.h
init.c
init.h
mutt/date.c
mutt/date.h
mutt_options.h
ncrypt/pgp.c
ncrypt/smime.c

index f756acc7d7e4455190704450339d9643281572a4..e13103cbfbcc5101d338793bbb4e7e7268611214 100644 (file)
@@ -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" },
index 5982670eddd31a18d73b8d87746c3d1179aed025..798f164164b6043461ec74ab14416af816978911 100644 (file)
@@ -5914,6 +5914,14 @@ set spam_separator=", "
               </para>
             </listitem>
           </varlistentry>
+          <varlistentry>
+            <term>number (long)</term>
+            <listitem>
+              <para>
+                A signed integer number in the range -2147483648 to 2147483647.
+              </para>
+            </listitem>
+          </varlistentry>
           <varlistentry>
             <term>string</term>
             <listitem>
index 688aad23362da1cfb77396c25ecc0fcc7383023f..ef60480dc4621927e73e64e13b23987890fb0202 100644 (file)
--- 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 8e061150f84827889880b712e15bb94e3c4a4475..9f5be9b4884ed14980e8887ae7cdb743ffc78361 100644 (file)
--- 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 f5e797007d4657bd2d001f697b33aa1552a91e57..4691cd16defec167358c84db8cea7595cd5b7f62 100644 (file)
--- 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
index 79bb9836f684b30a034fa1c5dc6bd005934da852..f6ab10834952678b371515f6e55d6c3ab55b0fbe 100644 (file)
@@ -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);
+}
index 0204f0e1b61beb4b8dbe1abe501474830ed44c50..be9fa183457ea2f09d35f162361daf4de945a805 100644 (file)
@@ -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 */
index 2021cf7acf034ef1ac12d5dca06e98fc96e0985c..20ce047c1d68ce836c097576083aa5b92277a5e6 100644 (file)
@@ -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)
 
index f03c30f16b5b85381e871f14850687ce5b30ced3..26465b002a84a50bedb0d26e1815f88ec8f6dae9 100644 (file)
@@ -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
index 1c0988a5f70005d759f0a7ea22dc6477de3faf27..459e517abd49369ac640a7fa46c82563ba273ad4 100644 (file)
@@ -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