- stevesk@cvs.openbsd.org 2001/05/19 19:43:57
     [misc.c misc.h servconf.c sshd.8 sshd.c]
     sshd command-line arguments and configuration file options that
     specify time may be expressed using a sequence of the form:
     time[qualifier], where time is a positive integer value and qualifier
     is one of the following:
         <none>,s,m,h,d,w
     Examples:
         600     600 seconds (10 minutes)
         10m     10 minutes
         1h30m   1 hour 30 minutes (90 minutes)
     ok markus@
diff --git a/ChangeLog b/ChangeLog
index 69a9b6f..c0f0510 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -27,6 +27,18 @@
    - markus@cvs.openbsd.org 2001/05/19 16:46:19
      [ssh.1 sshd.8]                            
      document MACs defaults with .Dq           
+   - stevesk@cvs.openbsd.org 2001/05/19 19:43:57                          
+     [misc.c misc.h servconf.c sshd.8 sshd.c]                             
+     sshd command-line arguments and configuration file options that      
+     specify time may be expressed using a sequence of the form:          
+     time[qualifier], where time is a positive integer value and qualifier
+     is one of the following:                                             
+         <none>,s,m,h,d,w                                                 
+     Examples:                                                            
+         600     600 seconds (10 minutes)                                 
+         10m     10 minutes                                               
+         1h30m   1 hour 30 minutes (90 minutes)                           
+     ok markus@                                                           
 
 20010528
  - (tim) [conifgure.in] add setvbuf test needed for sftp-int.c
@@ -5457,4 +5469,4 @@
  - Wrote replacements for strlcpy and mkdtemp
  - Released 1.0pre1
 
-$Id: ChangeLog,v 1.1233 2001/06/05 19:52:52 mouring Exp $
+$Id: ChangeLog,v 1.1234 2001/06/05 19:59:08 mouring Exp $
diff --git a/misc.c b/misc.c
index b0fdbe0..208819c 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/*	$OpenBSD: misc.c,v 1.8 2001/05/11 14:59:56 markus Exp $	*/
+/*	$OpenBSD: misc.c,v 1.9 2001/05/19 19:43:57 stevesk Exp $	*/
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: misc.c,v 1.8 2001/05/11 14:59:56 markus Exp $");
+RCSID("$OpenBSD: misc.c,v 1.9 2001/05/19 19:43:57 stevesk Exp $");
 
 #include "misc.h"
 #include "log.h"
@@ -154,6 +154,66 @@
 	return port;
 }
 
+#define SECONDS		1
+#define MINUTES		(SECONDS * 60)
+#define HOURS		(MINUTES * 60)
+#define DAYS		(HOURS * 24)
+#define WEEKS		(DAYS * 7)
+
+long convtime(const char *s)
+{
+	long total, secs;
+	const char *p;
+	char *endp;
+
+	errno = 0;
+	total = 0;
+	p = s;
+
+	if (p == NULL || *p == '\0')
+		return -1;
+
+	while (*p) {
+		secs = strtol(p, &endp, 10);
+		if (p == endp ||
+		    (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
+		    secs < 0)
+			return -1;
+
+		switch (*endp++) {
+		case '\0':
+			endp--;
+		case 's':
+		case 'S':
+			break;
+		case 'm':
+		case 'M':
+			secs *= MINUTES;
+			break;
+		case 'h':
+		case 'H':
+			secs *= HOURS;
+			break;
+		case 'd':
+		case 'D':
+			secs *= DAYS;
+			break;
+		case 'w':
+		case 'W':
+			secs *= WEEKS;
+			break;
+		default:
+			return -1;
+		}
+		total += secs;
+		if (total < 0)
+			return -1;
+		p = endp;
+	}
+
+	return total;
+}
+
 char *
 cleanhostname(char *host)
 {
diff --git a/misc.h b/misc.h
index 01a736c..086f98e 100644
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: misc.h,v 1.7 2001/05/11 14:59:56 markus Exp $	*/
+/*	$OpenBSD: misc.h,v 1.8 2001/05/19 19:43:57 stevesk Exp $	*/
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -34,6 +34,30 @@
 char *cleanhostname(char *host);
 char *colon(char *cp);
 
+/*
+ * Convert a time string into seconds; format is
+ * a sequence of:
+ *	time[qualifier]
+ *
+ * Valid time qualifiers are:
+ *	<none>	seconds
+ *	s|S	seconds
+ *	m|M	minutes
+ *	h|H	hours
+ *	d|D	days
+ *	w|W	weeks
+ *
+ * Examples:
+ *	90m	90 minutes
+ *	1h30m	90 minutes
+ *	2d	2 days
+ *	1w	1 week
+ *
+ * Return -1 if time string is invalid.
+ */
+
+long convtime(const char *s);
+
 /* function to assist building execv() arguments */
 typedef struct arglist arglist;
 struct arglist {
diff --git a/servconf.c b/servconf.c
index 02d06bd..2d10963 100644
--- a/servconf.c
+++ b/servconf.c
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: servconf.c,v 1.80 2001/05/18 14:13:29 markus Exp $");
+RCSID("$OpenBSD: servconf.c,v 1.81 2001/05/19 19:43:57 stevesk Exp $");
 
 #ifdef KRB4
 #include <krb.h>
@@ -429,11 +429,21 @@
 
 		case sLoginGraceTime:
 			intptr = &options->login_grace_time;
-			goto parse_int;
+parse_time:
+			arg = strdelim(&cp);
+			if (!arg || *arg == '\0')
+				fatal("%s line %d: missing time value.",
+				    filename, linenum);
+			if ((value = convtime(arg)) == -1)
+				fatal("%s line %d: invalid time value.",
+				    filename, linenum);
+			if (*intptr == -1)
+				*intptr = value;
+			break;
 
 		case sKeyRegenerationTime:
 			intptr = &options->key_regeneration_time;
-			goto parse_int;
+			goto parse_time;
 
 		case sListenAddress:
 			arg = strdelim(&cp);
@@ -792,12 +802,15 @@
 		case sBanner:
 			charptr = &options->banner;
 			goto parse_filename;
+
 		case sClientAliveInterval:
 			intptr = &options->client_alive_interval;
-			goto parse_int;
+			goto parse_time;
+
 		case sClientAliveCountMax:
 			intptr = &options->client_alive_count_max;
 			goto parse_int;
+
 		case sPAMAuthenticationViaKbdInt:
 			intptr = &options->pam_authentication_via_kbd_int;
 			goto parse_flag;
diff --git a/sshd.8 b/sshd.8
index 2620152..02960b7 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,7 +34,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd.8,v 1.123 2001/05/19 16:46:19 markus Exp $
+.\" $OpenBSD: sshd.8,v 1.124 2001/05/19 19:43:57 stevesk Exp $
 .Dd September 25, 1999
 .Dt SSHD 8
 .Os
@@ -794,6 +794,49 @@
 The default is
 .Pa /usr/X11R6/bin/xauth .
 .El
+.Ss Time Formats
+.Pp
+.Nm
+command-line arguments and configuration file options that specify time
+may be expressed using a sequence of the form:
+.Sm off
+.Ar time Oo Ar qualifier Oc ,
+.Sm on
+where
+.Ar time
+is a positive integer value and
+.Ar qualifier
+is one of the following:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It Cm <none>
+seconds
+.It Cm s | Cm S
+seconds
+.It Cm m | Cm M
+minutes
+.It Cm h | Cm H
+hours
+.It Cm d | Cm D
+days
+.It Cm w | Cm W
+weeks
+.El
+.Pp
+Each member of the sequence is added together to calculate
+the total time value.
+.Pp
+Time format examples:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It 600
+600 seconds (10 minutes)
+.It 10m
+10 minutes
+.It 1h30m
+1 hour 30 minutes (90 minutes)
+.El
+
 .Sh LOGIN PROCESS
 When a user successfully logs in,
 .Nm
diff --git a/sshd.c b/sshd.c
index a20b81c..135c08b 100644
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.196 2001/05/18 14:13:29 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.197 2001/05/19 19:43:57 stevesk Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -618,10 +618,16 @@
 			}
 			break;
 		case 'g':
-			options.login_grace_time = atoi(optarg);
+			if ((options.login_grace_time = convtime(optarg)) == -1) {
+				fprintf(stderr, "Invalid login grace time.\n");
+				exit(1);
+			}
 			break;
 		case 'k':
-			options.key_regeneration_time = atoi(optarg);
+			if ((options.key_regeneration_time = convtime(optarg)) == -1) {
+				fprintf(stderr, "Invalid key regeneration interval.\n");
+				exit(1);
+			}
 			break;
 		case 'h':
 			if (options.num_host_key_files >= MAX_HOSTKEYS) {