[exim-cvs] Handle UTC vs specified-timezone for certificate …

Startseite
Nachricht löschen
Nachricht beantworten
Autor: Exim Git Commits Mailing List
Datum:  
To: exim-cvs
Betreff: [exim-cvs] Handle UTC vs specified-timezone for certificate extractors. Bug 1541
Gitweb: http://git.exim.org/exim.git/commitdiff/e9477a08d2d1f528b1f127f1d563d77e2cf24a22
Commit:     e9477a08d2d1f528b1f127f1d563d77e2cf24a22
Parent:     a163908a12546834f355c40c87b6cb859302b1c6
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Mon Nov 10 16:41:12 2014 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Tue Nov 11 23:28:58 2014 +0000


    Handle UTC vs specified-timezone for certificate extractors.  Bug 1541
---
 doc/doc-docbook/spec.xfpt |    6 ++-
 doc/doc-txt/ChangeLog     |    4 ++
 src/src/os.c              |   33 --------------------
 src/src/tls.c             |   22 +++++++++++++
 src/src/tlscert-gnu.c     |   15 ++++++---
 src/src/tlscert-openssl.c |   73 +++++++++++++++++++++++++++++++++------------
 test/confs/2002           |    1 +
 test/confs/2102           |    4 ++-
 test/confs/5750           |    1 +
 test/confs/5760           |    1 +
 test/log/2102             |    5 ++-
 test/log/5760             |    8 ++--
 12 files changed, 107 insertions(+), 66 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 20bfb40..8b1a17b 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -8939,8 +8939,10 @@ a right angle-bracket followed immediately by the new separator.
Recognised RDN type labels include "CN", "O", "OU" and "DC".

The field selectors marked as "time" above
-may output a number of seconds since epoch
-if the modifier "int" is used.
+take an optional modifier of "int"
+for which the result is the number of seconds since epoch.
+Otherwise the result is a human-readable string
+in the timezone selected by the main "timezone" option.

 The field selectors marked as "list" above return a list,
 newline-separated by default,
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 997a459..ae7a06a 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -67,6 +67,10 @@ JH/09 When compiled with OpenSSL and EXPERIMENTAL_CERTNAMES, the checks on
       "tls_verify_cert_hostname" now do not permit multi-component wildcard
       matches.


+JH/10 Time-related extraction expansions from certificates now use the main
+      option "timezone" setting for output formatting, and are consistent
+      between OpenSSL and GnuTLS compilations.  Bug 1541.
+


Exim version 4.84
-----------------
diff --git a/src/src/os.c b/src/src/os.c
index 2b6f79c..6e02b8f 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 f2ab567..305eaa4 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 3261c4e..c0ca7c9 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 9444b6d..8f0fb4d 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 *
diff --git a/test/confs/2002 b/test/confs/2002
index 9f664e8..69fc749 100644
--- a/test/confs/2002
+++ b/test/confs/2002
@@ -8,6 +8,7 @@ spool_directory = DIR/spool
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+timezone = UTC

# ----- Main settings -----

diff --git a/test/confs/2102 b/test/confs/2102
index 7d5d13a..88453ed 100644
--- a/test/confs/2102
+++ b/test/confs/2102
@@ -8,6 +8,7 @@ spool_directory = DIR/spool
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+timezone = UTC

# ----- Main settings -----

@@ -53,7 +54,8 @@ check_recipient:
       logwrite =  SN  <${certextract {subject}    {$tls_in_peercert}}>
           logwrite =  IN  <${certextract {issuer}    {$tls_in_peercert}}>
           logwrite =  IN/O <${certextract {issuer,O}    {$tls_in_peercert}}>
-          logwrite =  NB  <${certextract {notbefore}    {$tls_in_peercert}}>
+          logwrite =  NB/r <${certextract {notbefore,raw}    {$tls_in_peercert}}>
+          logwrite =  NB   <${certextract {notbefore}    {$tls_in_peercert}}>
           logwrite =  NB/i <${certextract {notbefore,int}{$tls_in_peercert}}>
           logwrite =  NA  <${certextract {notafter}    {$tls_in_peercert}}>
           logwrite =  SA  <${certextract {sig_algorithm}{$tls_in_peercert}}>
diff --git a/test/confs/5750 b/test/confs/5750
index 3898530..a0bce02 100644
--- a/test/confs/5750
+++ b/test/confs/5750
@@ -11,6 +11,7 @@ spool_directory = DIR/spool
 log_file_path = DIR/spool/log/SERVER%slog
 gecos_pattern = ""
 gecos_name = CALLER_NAME
+timezone = UTC


# ----- Main settings -----

diff --git a/test/confs/5760 b/test/confs/5760
index d07aa8d..3417a2d 100644
--- a/test/confs/5760
+++ b/test/confs/5760
@@ -11,6 +11,7 @@ spool_directory = DIR/spool
log_file_path = DIR/spool/log/SERVER%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
+timezone = UTC

# ----- Main settings -----

diff --git a/test/log/2102 b/test/log/2102
index 68a21bb..da79a81 100644
--- a/test/log/2102
+++ b/test/log/2102
@@ -14,9 +14,10 @@
 1999-03-02 09:44:33 SN  <CN=server2.example.com>
 1999-03-02 09:44:33 IN  <CN=clica Signing Cert,O=example.com>
 1999-03-02 09:44:33 IN/O <example.com>
-1999-03-02 09:44:33 NB  <Nov  1 12:34:06 2012 GMT>
+1999-03-02 09:44:33 NB/r <Nov  1 12:34:06 2012 GMT>
+1999-03-02 09:44:33 NB   <Nov  1 12:34:06 2012 +0000>
 1999-03-02 09:44:33 NB/i <1351773246>
-1999-03-02 09:44:33 NA  <Jan  1 12:34:06 2038 GMT>
+1999-03-02 09:44:33 NA  <Jan  1 12:34:06 2038 +0000>
 1999-03-02 09:44:33 SA  <sha1WithRSAEncryption>
 1999-03-02 09:44:33 SG  <         6c:37:41:26:4d:5d:f4:b5:31:10:67:ca:fb:64:b6:22:98:62:\n         f7:1e:95:7b:6c:e6:74:47:21:f4:5e:89:36:3e:b9:9c:8a:c5:\n         52:bb:c4:af:12:93:26:3b:d7:3d:e0:56:71:1e:1d:21:20:02:\n         ed:f0:4e:d5:5e:45:42:fd:3c:38:41:54:83:86:0b:3b:bf:c5:\n         47:39:ff:15:ea:93:dc:fd:c7:3d:18:58:59:ca:dd:2a:d8:b9:\n         f9:2f:b9:76:93:f4:ae:e3:91:56:80:2f:8c:04:2f:ad:57:ef:\n         d2:51:19:f4:b4:ef:32:9c:ac:3a:7c:0d:b8:39:db:b1:e3:30:\n         73:1a\n>
 1999-03-02 09:44:33 SAN <DNS=server2.example.com>
diff --git a/test/log/5760 b/test/log/5760
index 691ccda..3775779 100644
--- a/test/log/5760
+++ b/test/log/5760
@@ -9,8 +9,8 @@
 1999-03-02 09:44:33 10HmaX-0005vi-00 ver <2>
 1999-03-02 09:44:33 10HmaX-0005vi-00 SN  <CN=clica CA,O=example.com>
 1999-03-02 09:44:33 10HmaX-0005vi-00 IN  <CN=clica CA,O=example.com>
-1999-03-02 09:44:33 10HmaX-0005vi-00 NB  <Nov  1 12:34:04 2012 GMT>
-1999-03-02 09:44:33 10HmaX-0005vi-00 NA  <Jan  1 12:34:04 2038 GMT>
+1999-03-02 09:44:33 10HmaX-0005vi-00 NB  <Nov  1 12:34:04 2012 +0000>
+1999-03-02 09:44:33 10HmaX-0005vi-00 NA  <Jan  1 12:34:04 2038 +0000>
 1999-03-02 09:44:33 10HmaX-0005vi-00 SA  <sha1WithRSAEncryption>
 1999-03-02 09:44:33 10HmaX-0005vi-00 SG  <         89:fd:fb:cb:b2:42:d6:aa:f2:c0:44:a2:14:e5:ab:22:50:41:\n         e6:64:e7:1c:5a:20:b6:0f:fe:b0:88:c5:cf:b3:e5:f8:0e:87:\n         eb:ac:07:d6:9d:6a:20:f6:dd:13:ee:b8:3f:cf:d9:cd:d4:a8:\n         72:50:5a:a2:14:4e:ee:3a:78:e2:a7:f4:ae:d7:ee:77:48:1f:\n         75:a7:68:2f:ee:e2:7c:ac:2f:e4:88:02:e8:3b:db:f9:35:04:\n         05:46:35:0b:f2:35:03:21:b6:1e:82:7d:94:e0:63:4b:60:71:\n         2d:19:45:21:f2:85:b4:c3:d0:77:a2:24:32:36:f3:50:68:38:\n         98:e6\n>
 1999-03-02 09:44:33 10HmaX-0005vi-00 (no SAN)
@@ -32,8 +32,8 @@
 1999-03-02 09:44:33 10HmaY-0005vi-00 ver <2>
 1999-03-02 09:44:33 10HmaY-0005vi-00 SN  <CN=server1.example.com>
 1999-03-02 09:44:33 10HmaY-0005vi-00 IN  <CN=clica Signing Cert,O=example.com>
-1999-03-02 09:44:33 10HmaY-0005vi-00 NB  <Nov  1 12:34:05 2012 GMT>
-1999-03-02 09:44:33 10HmaY-0005vi-00 NA  <Jan  1 12:34:05 2038 GMT>
+1999-03-02 09:44:33 10HmaY-0005vi-00 NB  <Nov  1 12:34:05 2012 +0000>
+1999-03-02 09:44:33 10HmaY-0005vi-00 NA  <Jan  1 12:34:05 2038 +0000>
 1999-03-02 09:44:33 10HmaY-0005vi-00 SA  <sha1WithRSAEncryption>
 1999-03-02 09:44:33 10HmaY-0005vi-00 SG  <         56:3a:a4:3c:cb:eb:b8:27:c2:90:08:74:13:88:dc:48:c6:b5:\n         2c:e5:26:be:5b:91:d4:67:e7:3c:49:12:d7:47:30:df:98:db:\n         58:ed:18:a8:7d:4b:db:97:48:f5:5c:7f:70:b9:37:63:33:f1:\n         24:62:72:92:60:f5:6e:da:b6:bc:73:c8:c2:dc:d6:95:9a:bd:\n         16:16:a2:ef:0a:f1:d7:41:68:f6:ad:98:5a:d0:ff:d9:1b:51:\n         9f:59:ce:2f:3d:84:d0:ee:e8:2b:eb:9b:32:1a:0e:02:3e:cc:\n         30:89:44:09:2a:75:81:46:a7:b6:ed:7d:41:eb:5a:63:fa:9c:\n         58:ef\n>
 1999-03-02 09:44:33 10HmaY-0005vi-00 SAN <DNS=server1.example.com;DNS=alternatename2.server1.example.com;DNS=alternatename.server1.example.com>