diff options
author | Andrew Bartlett <abartlet@samba.org> | 2010-10-02 16:32:56 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-10-03 01:15:04 +0000 |
commit | 21460dfc14acdeef69b6cd910da80f261316be63 (patch) | |
tree | fcc7b9c9b03331ae6a1117a9688fc957868e942b /source4/heimdal/lib/asn1 | |
parent | a2c4f54dfb47fa73c12ba305d52574aeb6baedd9 (diff) | |
download | samba-21460dfc14acdeef69b6cd910da80f261316be63.tar.gz samba-21460dfc14acdeef69b6cd910da80f261316be63.tar.bz2 samba-21460dfc14acdeef69b6cd910da80f261316be63.zip |
s4:heimdal: import lorikeet-heimdal-201010022046 (commit 1bea031b9404b14114b0272ecbe56e60c567af5c)
Diffstat (limited to 'source4/heimdal/lib/asn1')
-rw-r--r-- | source4/heimdal/lib/asn1/der_locl.h | 1 | ||||
-rw-r--r-- | source4/heimdal/lib/asn1/der_put.c | 12 | ||||
-rw-r--r-- | source4/heimdal/lib/asn1/timegm.c | 62 |
3 files changed, 60 insertions, 15 deletions
diff --git a/source4/heimdal/lib/asn1/der_locl.h b/source4/heimdal/lib/asn1/der_locl.h index 0f65c50a22..a086e18fa4 100644 --- a/source4/heimdal/lib/asn1/der_locl.h +++ b/source4/heimdal/lib/asn1/der_locl.h @@ -56,6 +56,7 @@ #include "asn1-template.h" time_t _der_timegm (struct tm *); +struct tm * _der_gmtime(time_t t, struct tm *); size_t _heim_len_unsigned (unsigned); size_t _heim_len_int (int); diff --git a/source4/heimdal/lib/asn1/der_put.c b/source4/heimdal/lib/asn1/der_put.c index c8192f25fe..b8101458ad 100644 --- a/source4/heimdal/lib/asn1/der_put.c +++ b/source4/heimdal/lib/asn1/der_put.c @@ -426,22 +426,22 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val, int _heim_time2generalizedtime (time_t t, heim_octet_string *s, int gtimep) { - struct tm *tm; + struct tm tm; const size_t len = gtimep ? 15 : 13; s->data = malloc(len + 1); if (s->data == NULL) return ENOMEM; s->length = len; - tm = gmtime (&t); + _der_gmtime(t, &tm); if (gtimep) snprintf (s->data, len + 1, "%04d%02d%02d%02d%02d%02dZ", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); else snprintf (s->data, len + 1, "%02d%02d%02d%02d%02d%02dZ", - tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); + tm.tm_year % 100, tm.tm_mon + 1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); return 0; } diff --git a/source4/heimdal/lib/asn1/timegm.c b/source4/heimdal/lib/asn1/timegm.c index 83f0e33fb8..b569478413 100644 --- a/source4/heimdal/lib/asn1/timegm.c +++ b/source4/heimdal/lib/asn1/timegm.c @@ -42,6 +42,10 @@ is_leap(unsigned y) return (y % 4) == 0 && ((y % 100) != 0 || (y % 400) == 0); } +static const unsigned ndays[2][12] ={ + {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; + /* * This is a simplifed version of timegm(3) that doesn't accept out of * bound values that timegm(3) normally accepts but those are not @@ -51,9 +55,8 @@ is_leap(unsigned y) time_t _der_timegm (struct tm *tm) { - static const unsigned ndays[2][12] ={ - {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; + time_t res = 0; + unsigned i; if (tm->tm_year < 0) return -1; @@ -68,10 +71,51 @@ _der_timegm (struct tm *tm) if (tm->tm_sec < 0 || tm->tm_sec > 59) return -1; - /* now call to the libc timegm(). This code used to do the - * calculation itself, but that calculation didn't account for the - * difference between UTC and GMT, which is 24 seconds in 2010. That - * caused a mutual authentication failure - */ - return timegm(tm); + for (i = 70; i < tm->tm_year; ++i) + res += is_leap(i) ? 366 : 365; + + for (i = 0; i < tm->tm_mon; ++i) + res += ndays[is_leap(tm->tm_year)][i]; + res += tm->tm_mday - 1; + res *= 24; + res += tm->tm_hour; + res *= 60; + res += tm->tm_min; + res *= 60; + res += tm->tm_sec; + return res; +} + +struct tm * +_der_gmtime(time_t t, struct tm *tm) +{ + time_t secday = t % (3600 * 24); + time_t days = t / (3600 * 24); + + memset(tm, 0, sizeof(*tm)); + + tm->tm_sec = secday % 60; + tm->tm_min = (secday % 3600) / 60; + tm->tm_hour = secday / 3600; + + tm->tm_year = 70; + while(1) { + unsigned dayinyear = (is_leap(tm->tm_year) ? 366 : 365); + if (days < dayinyear) + break; + tm->tm_year += 1; + days -= dayinyear; + } + tm->tm_mon = 0; + + while (1) { + unsigned daysinmonth = ndays[is_leap(tm->tm_year)][tm->tm_mon]; + if (days < daysinmonth) + break; + days -= daysinmonth; + tm->tm_mon++; + } + tm->tm_mday = days + 1; + + return tm; } |