str_conv.c (krb5_string_to_timestamp, strptime): Fix routines to be
authorTheodore Tso <tytso@mit.edu>
Sat, 9 May 1998 03:19:46 +0000 (03:19 +0000)
committerTheodore Tso <tytso@mit.edu>
Sat, 9 May 1998 03:19:46 +0000 (03:19 +0000)
able to properly parse Y2K dates.

t_kerb.c: Add ability to test krb5_string_to_timestamp

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10559 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/str_conv.c
src/lib/krb5/krb/t_kerb.c

index 434459f9ac33dc6708f46b3aa453fccfed0d1818..9cc9d761c428ba85b47c5a9c328eca8276a5cde1 100644 (file)
@@ -1,3 +1,10 @@
+1998-05-08  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+
+       * str_conv.c (krb5_string_to_timestamp, strptime): Fix routines to
+               be able to properly parse Y2K dates.  
+
+       * t_kerb.c: Add ability to test krb5_string_to_timestamp
+
 1998-05-06  Theodore Ts'o  <tytso@rsts-11.mit.edu>
 
        * t_ser.c (main): POSIX states that getopt returns -1
index a13099cf52e5a6885bdd359916736ce92c5fec4d..ec6384e0724ab818d71ea344089e340a26218063 100644 (file)
@@ -268,7 +268,7 @@ COMERRLIB=$(TOPLIBD)/libcom_err.a
 T_WALK_RTREE_OBJS= t_walk_rtree.o walk_rtree.o tgtname.o unparse.o \
        free_rtree.o bld_pr_ext.o 
 
-T_KERB_OBJS= t_kerb.o conv_princ.o unparse.o set_realm.o
+T_KERB_OBJS= t_kerb.o conv_princ.o unparse.o set_realm.o str_conv.o
 
 T_SER_OBJS= t_ser.o ser_actx.o ser_adata.o ser_addr.o ser_auth.o ser_cksum.o \
        ser_ctx.o ser_eblk.o ser_key.o ser_princ.o serialize.o 
index d8b2e6d94d8ee0b1ec2d144edc063ee87be35ffc..c059f838e09549f9404913c376ab048969461701 100644 (file)
@@ -133,6 +133,8 @@ static const char cstype_hmacsha_out[]      = "HMAC-SHA";
 /* Absolute time strings */
 static const char atime_full_digits[]  = "%y%m%d%H%M%S";
 static const char atime_full_digits_d[]        = "%y.%m.%d.%H.%M.%S";
+static const char atime_full_digits_Y[]        = "%Y%m%d%H%M%S";
+static const char atime_full_digits_Yd[]= "%Y.%m.%d.%H.%M.%S";
 static const char atime_nsec_digits[]  = "%y%m%d%H%M";
 static const char atime_rel_hms[]      = "%H%M%S";
 static const char atime_rel_hm[]       = "%H%M";
@@ -144,6 +146,8 @@ static const char atime_full_text_nos[]     = "%d-%b-%Y:%R";
 #if    !HAVE_STRPTIME
 static const char ascan_full_digits[]  = "%02d%02d%02d%02d%02d%02d";
 static const char ascan_full_digits_d[]        = "%02d.%02d.%02d.%02d.%02d.%02d";
+static const char ascan_full_digits_Y[]        = "%4d%02d%02d%02d%02d%02d";
+static const char ascan_full_digits_Yd[]= "%4d.%02d.%02d.%02d.%02d.%02d";
 static const char ascan_nsec_digits[]  = "%02d%02d%02d%02d%02d";
 static const char ascan_rel_hms[]      = "%02d%02d%02d";
 static const char ascan_rel_hm[]       = "%02d%02d";
@@ -223,6 +227,8 @@ static const int cksumtype_table_nents = sizeof(cksumtype_table)/
                                         sizeof(cksumtype_table[0]);
 
 static const char * const atime_format_table[] = {
+atime_full_digits_Y,   /* yyyymmddhhmmss               */
+atime_full_digits_Yd,  /* yyyy.mm.dd.hh.mm.ss          */
 atime_full_digits,     /* yymmddhhmmss                 */
 atime_full_digits_d,   /* yy.mm.dd.hh.mm.ss            */
 atime_nsec_digits,     /* yymmddhhmm                   */
@@ -282,6 +288,8 @@ strptime(buf, format, tm)
     
     /*
      * We only understand the following fixed formats:
+     *    %Y%m%d%H%M%S
+     *    %Y.%m.%d.%H.%M.%S
      *    %y%m%d%H%M%S
      *    %y.%m.%d.%H.%M.%S
      *    %y%m%d%H%M
@@ -291,9 +299,37 @@ strptime(buf, format, tm)
      *    %R
      */
     bp = (char *) NULL;
-    if (!strcmp(format, atime_full_digits) &&
+    if (!strcmp(format, atime_full_digits_Y) &&
+       (sscanf(buf, ascan_full_digits_Y,
+               &year, &month, &day, &hour, &minute, &second) == 6)) {
+       if (year < 1900)
+               return NULL;
+       tm->tm_year = year-1900;
+       tm->tm_mon = month - 1;
+       tm->tm_mday = day;
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       tm->tm_sec = second;
+       bp = &buf[strlen(atime_full_digits)];
+    }
+    else if (!strcmp(format,atime_full_digits_Yd) &&
+            (sscanf(buf, ascan_full_digits_Yd,
+                    &year, &month, &day, &hour, &minute, &second) == 6)) {
+       if (year < 1900)
+               return NULL;
+       tm->tm_year = year-1900;
+       tm->tm_mon = month - 1;
+       tm->tm_mday = day;
+       tm->tm_hour = hour;
+       tm->tm_min = minute;
+       tm->tm_sec = second;
+       bp = &buf[strlen(atime_full_digits_d)];
+    }
+    else if (!strcmp(format, atime_full_digits) &&
        (sscanf(buf, ascan_full_digits,
                &year, &month, &day, &hour, &minute, &second) == 6)) {
+       if (year <= 68)
+               year += 100;
        tm->tm_year = year;
        tm->tm_mon = month - 1;
        tm->tm_mday = day;
@@ -305,6 +341,8 @@ strptime(buf, format, tm)
     else if (!strcmp(format,atime_full_digits_d) &&
             (sscanf(buf, ascan_full_digits_d,
                     &year, &month, &day, &hour, &minute, &second) == 6)) {
+       if (year <= 68)
+               year += 100;
        tm->tm_year = year;
        tm->tm_mon = month - 1;
        tm->tm_mday = day;
@@ -316,6 +354,8 @@ strptime(buf, format, tm)
     else if (!strcmp(format, atime_nsec_digits) &&
             (sscanf(buf, ascan_nsec_digits,
                &year, &month, &day, &hour, &minute) == 5)) {
+       if (year <= 68)
+               year += 100;
        tm->tm_year = year;
        tm->tm_mon = month - 1;
        tm->tm_mday = day;
@@ -357,8 +397,9 @@ strptime(buf, format, tm)
        tm->tm_hour = hour;
        tm->tm_min = minute;
        bp = &buf[strlen(atime_rel_col_hm)];
-    }
-    return(bp);
+    } else
+           return NULL;
+    return bp;
 }
 #endif /* HAVE_STRPTIME */
 \f
@@ -430,12 +471,10 @@ krb5_string_to_timestamp(string, timestampp)
     krb5_timestamp     FAR * timestampp;
 {
     int i;
-    int found;
     struct tm timebuf;
-    time_t now;
+    time_t now, ret_time;
     char *s;
 
-    found = 0;
     now = time((time_t *) NULL);
     for (i=0; i<atime_format_table_nents; i++) {
         /* We reset every time throughout the loop as the manual page
@@ -445,13 +484,16 @@ krb5_string_to_timestamp(string, timestampp)
        memcpy(&timebuf, localtime(&now), sizeof(timebuf));
        if ((s = strptime(string, atime_format_table[i], &timebuf))
            && (s != string)) {
-           found = 1;
-           break;
+           if (timebuf.tm_year <= 0)
+               continue;       /* clearly confused */
+           ret_time = mktime(&timebuf);
+           if (ret_time == (time_t) -1)
+               continue;       /* clearly confused */
+           *timestampp = (krb5_timestamp) ret_time;
+           return 0;
        }
     }
-    if (found)
-       *timestampp = (krb5_timestamp) mktime(&timebuf);
-    return((found) ? 0 : EINVAL);
+    return(EINVAL);
 }
 
 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
@@ -590,18 +632,23 @@ krb5_timestamp_to_string(timestamp, buffer, buflen)
     size_t             buflen;
 {
 #if    HAVE_STRFTIME
-    if (strftime(buffer, buflen, "%c", localtime((time_t *) &timestamp)))
-       return(0);
-    else
+    int ret;
+       
+    ret = strftime(buffer, buflen, "%c", localtime((time_t *) &timestamp));
+    if (ret == 0 || ret == buflen)
        return(ENOMEM);
+    return(0);
 #else  /* HAVE_STRFTIME */
-    if (strlen(ctime((time_t *) &timestamp)) <= buflen) {
-       strcpy(buffer, ctime((time_t *) &timestamp));
-       /* ctime returns <datestring>\n\0 */
-       buffer[strlen(buffer)-1] = '\0';
-       return(0);
-    }
-    return(ENOMEM);
+    char *cp;
+    time_t t = timestamp;
+    
+    cp = ctime(&t);
+    if (strlen(cp) >= buflen)
+       return ENOMEM;
+    strcpy(buffer, cp);
+    /* ctime returns <datestring>\n\0 */
+    buffer[strlen(buffer)-1] = '\0';
+    return(0);
 #endif /* HAVE_STRFTIME */
 }
 
index 45c5e2e2d1721792ff70459a88d3be53a5b3f989..2feef39dd6e0f57d87e5abb90c5f62c13ae0b802 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <time.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 
 #include "com_err.h"
 
+void test_string_to_timestamp(ctx, time)
+       krb5_context ctx;
+       char *time;
+{
+    krb5_timestamp     timestamp;
+    time_t             t;
+    krb5_error_code    retval;
+
+    retval = krb5_string_to_timestamp(time, &timestamp);
+    if (retval) {
+       com_err("krb5_string_to_timestamp", retval, 0);
+       return;
+    }
+    t = (time_t) timestamp;
+    printf("Parsed time was %s", ctime(&t));
+}
 
 void test_425_conv_principal(ctx, name, inst, realm)
     krb5_context ctx;
@@ -116,6 +133,7 @@ void usage(progname)
                progname, progname);
        fprintf(stderr, "\t%s parse_name <name>\n", progname);
        fprintf(stderr, "\t%s set_realm <name> <realm>\n", progname);
+       fprintf(stderr, "\t%s string_to_timestamp <time>\n", progname);
        exit(1);
 }
 
@@ -164,6 +182,10 @@ main(argc, argv)
                  if (!argc) usage(progname);
                  realm = *argv;
                  test_set_realm(ctx, name, realm);
+         } else if (strcmp(*argv, "string_to_timestamp") == 0) {
+                 argc--; argv++;
+                 if (!argc) usage(progname);
+                 test_string_to_timestamp(ctx, *argv);
          }
          else
              usage(progname);