diff options
author | Jeremy Harris <jgh146exb@wizmail.org> | 2014-11-10 16:41:12 +0000 |
---|---|---|
committer | Jeremy Harris <jgh146exb@wizmail.org> | 2014-11-11 23:28:58 +0000 |
commit | e9477a08d2d1f528b1f127f1d563d77e2cf24a22 (patch) | |
tree | 9e2c278792c869e0b3b5a9e4c81a1afa1b8e2ab4 /src | |
parent | a163908a12546834f355c40c87b6cb859302b1c6 (diff) |
Handle UTC vs specified-timezone for certificate extractors. Bug 1541
Diffstat (limited to 'src')
-rw-r--r-- | src/src/os.c | 33 | ||||
-rw-r--r-- | src/src/tls.c | 22 | ||||
-rw-r--r-- | src/src/tlscert-gnu.c | 15 | ||||
-rw-r--r-- | src/src/tlscert-openssl.c | 73 |
4 files changed, 86 insertions, 57 deletions
diff --git a/src/src/os.c b/src/src/os.c index 2b6f79c3f..6e02b8fe2 100644 --- a/src/src/os.c +++ b/src/src/os.c @@ -836,39 +836,6 @@ os_get_dns_resolver_res(void) /* ----------------------------------------------------------------------- */ -/*********************************************************** -* Time-related functions * -***********************************************************/ - -/* At least Solaris, and probably others, don't have this */ - -#ifndef _BSD_SOURCE - -# include <time.h> -# include <stdlib.h> - -time_t -timegm(struct tm * tm) -{ -time_t ret; -char *tz; - -tz = getenv("TZ"); -setenv("TZ", "", 1); -tzset(); -ret = mktime(tm); -if (tz) - setenv("TZ", tz, 1); -else - unsetenv("TZ"); -tzset(); -return ret; -} - -#endif - -/* ----------------------------------------------------------------------- */ - diff --git a/src/src/tls.c b/src/src/tls.c index f2ab56706..305eaa410 100644 --- a/src/src/tls.c +++ b/src/src/tls.c @@ -81,6 +81,28 @@ return TRUE; /************************************************* +* Timezone environment flipping * +*************************************************/ + +static uschar * +to_tz(uschar * tz) +{ + uschar * old = US getenv("TZ"); + setenv("TZ", CS tz, 1); + tzset(); + return old; +} +static void +restore_tz(uschar * tz) +{ + if (tz) + setenv("TZ", CS tz, 1); + else + unsetenv("TZ"); + tzset(); +} + +/************************************************* * Many functions are package-specific * *************************************************/ diff --git a/src/src/tlscert-gnu.c b/src/src/tlscert-gnu.c index 3261c4e8d..c0ca7c935 100644 --- a/src/src/tlscert-gnu.c +++ b/src/src/tlscert-gnu.c @@ -98,15 +98,20 @@ static uschar * time_copy(time_t t, uschar * mod) { uschar * cp; -struct tm * tp; -size_t len; +size_t len = 32; if (mod && Ustrcmp(mod, "int") == 0) return string_sprintf("%u", (unsigned)t); -cp = store_get(32); -tp = gmtime(&t); -len = strftime(CS cp, 32, "%b %e %T %Y %Z", tp); +cp = store_get(len); +if (timestamps_utc) + { + char * tz = to_tz("GMT0"); + len = strftime(CS cp, len, "%b %e %T %Y %Z", gmtime(&t)); + restore_tz(tz); + } +else + len = strftime(CS cp, len, "%b %e %T %Y %Z", localtime(&t)); return len > 0 ? cp : NULL; } diff --git a/src/src/tlscert-openssl.c b/src/src/tlscert-openssl.c index 9444b6d7c..8f0fb4d91 100644 --- a/src/src/tlscert-openssl.c +++ b/src/src/tlscert-openssl.c @@ -103,30 +103,65 @@ return cp; } static uschar * -bio_string_time_to_int(BIO * bp, int len) -{ -uschar * cp = US""; -struct tm t; -len = len > 0 ? (int) BIO_get_mem_data(bp, &cp) : 0; -/*XXX %Z might be glibc-specific? */ -(void) strptime(CS cp, "%b%t%e%t%T%t%Y%t%Z", &t); -BIO_free(bp); -/*XXX timegm might not be portable? */ -return string_sprintf("%u", (unsigned) timegm(&t)); -} - -static uschar * -asn1_time_copy(const ASN1_TIME * time, uschar * mod) +asn1_time_copy(const ASN1_TIME * asntime, uschar * mod) { +uschar * s = NULL; BIO * bp = BIO_new(BIO_s_mem()); int len; -if (!bp) return badalloc(); +if (!bp) + return badalloc(); +len = ASN1_TIME_print(bp, asntime); +len = len > 0 ? (int) BIO_get_mem_data(bp, &s) : 0; -len = ASN1_TIME_print(bp, time); -return mod && Ustrcmp(mod, "int") == 0 - ? bio_string_time_to_int(bp, len) - : bio_string_copy(bp, len); +if (mod && Ustrcmp(mod, "raw") == 0) /* native ASN */ + s = string_copyn(s, len); +else + { + struct tm tm; + struct tm * tm_p = &tm; + BOOL mod_tz; + char * tz = to_tz("GMT0"); /* need to call strptime with baseline TZ */ + + /* Parse OpenSSL ASN1_TIME_print output. A shame there seems to + be no other interface for the times. + */ + + /*XXX %Z might be glibc-specific? Solaris has it, at least*/ + /*XXX should we switch to POSIX locale for this? */ + tm.tm_isdst = 0; + if (!strptime(CCS s, "%b %e %T %Y %Z", &tm)) + expand_string_message = US"failed time conversion"; + + else + { + time_t t = mktime(&tm); /* make the tm self-consistent */ + + if (mod && Ustrcmp(mod, "int") == 0) /* seconds since epoch */ + s = string_sprintf("%u", t); + + else + { + if (!timestamps_utc) /* decoded string in local TZ */ + { /* shift to local TZ */ + restore_tz(tz); + mod_tz = FALSE; + tm_p = localtime(&t); + } + /* "utc" is default, and rfc5280 says cert times should be Zulu */ + + /* convert to string in our format */ + len = 32; + s = store_get(len); + strftime(CS s, (size_t)len, "%b %e %T %Y %z", tm_p); + } + } + + if (mod_tz); + restore_tz(tz); + } +BIO_free(bp); +return s; } static uschar * |