From: Joe Orton Date: Wed, 18 Aug 2004 11:05:22 +0000 (+0000) Subject: * modules/ssl/ssl_engine_vars.c (ssl_var_lookup_ssl_cert_remain): New X-Git-Tag: STRIKER_2_1_0_RC1~98 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5afedd0422e7a931fd0c3c98b23c9a903763c14a;p=apache * modules/ssl/ssl_engine_vars.c (ssl_var_lookup_ssl_cert_remain): New function. (ssl_var_lookup_ssl_cert): Support _V_REMAIN suffix for SSL_{SERVER,CLIENT} as number of days until certificate expires. * modules/ssl_engine_kernel.c: Export SSL_CLIENT_V_REMAIN if +StdEnvVars is configured. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@104700 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index c394379a26..eb1e5d62ec 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.1.0-dev [Remove entries to the current 2.0 section below, when backported] + *) mod_ssl: Add SSL_CLIENT_V_REMAIN variable, representing the + number of days until the client cert expires. [Joe Orton] + *) mod_userdir: Ensure that the userdir identity is used for suexec userdir access in a virtual host which has suexec configured. PR 18156. [Joshua Slive] diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c index a71d829e66..f137223284 100644 --- a/modules/ssl/ssl_engine_kernel.c +++ b/modules/ssl/ssl_engine_kernel.c @@ -934,6 +934,7 @@ static const char *ssl_hook_Fixup_vars[] = { "SSL_CLIENT_M_SERIAL", "SSL_CLIENT_V_START", "SSL_CLIENT_V_END", + "SSL_CLIENT_V_REMAIN", "SSL_CLIENT_S_DN", "SSL_CLIENT_S_DN_C", "SSL_CLIENT_S_DN_ST", diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c index 9dc7aecd74..ab1d98a25b 100644 --- a/modules/ssl/ssl_engine_vars.c +++ b/modules/ssl/ssl_engine_vars.c @@ -29,6 +29,8 @@ #include "ssl_private.h" #include "mod_ssl.h" +#include "apr_time.h" + /* _________________________________________________________________ ** ** Variable Lookup @@ -39,6 +41,7 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var); static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var); static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *var); static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm); +static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_UTCTIME *tm); static char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs); static char *ssl_var_lookup_ssl_cert_chain(apr_pool_t *p, STACK_OF(X509) *sk, char *var); static char *ssl_var_lookup_ssl_cert_PEM(apr_pool_t *p, X509 *xs); @@ -318,6 +321,10 @@ static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var) else if (strcEQ(var, "V_END")) { result = ssl_var_lookup_ssl_cert_valid(p, X509_get_notAfter(xs)); } + else if (strcEQ(var, "V_REMAIN")) { + result = ssl_var_lookup_ssl_cert_remain(p, X509_get_notAfter(xs)); + resdup = FALSE; + } else if (strcEQ(var, "S_DN")) { xsname = X509_get_subject_name(xs); cp = X509_NAME_oneline(xsname, NULL, 0); @@ -449,6 +456,41 @@ static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm) return result; } +#define DIGIT2NUM(x) (((x)[0] - '0') * 10 + (x)[1] - '0') + +/* Return a string giving the number of days remaining until 'tm', or + * "0" if this can't be determined. */ +static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_UTCTIME *tm) +{ + apr_time_t then, now = apr_time_now(); + apr_time_exp_t exp = {0}; + long diff; + + /* Fail if the time isn't a valid ASN.1 UTCTIME; RFC3280 mandates + * that the seconds digits are present even though ASN.1 + * doesn't. */ + if (tm->length < 11 || !ASN1_UTCTIME_check(tm)) { + return apr_pstrdup(p, "0"); + } + + exp.tm_year = DIGIT2NUM(tm->data); + exp.tm_mon = DIGIT2NUM(tm->data + 2) - 1; + exp.tm_mday = DIGIT2NUM(tm->data + 4) + 1; + exp.tm_hour = DIGIT2NUM(tm->data + 6); + exp.tm_min = DIGIT2NUM(tm->data + 8); + exp.tm_sec = DIGIT2NUM(tm->data + 10); + + if (exp.tm_year <= 50) exp.tm_year += 100; + + if (apr_time_exp_gmt_get(&then, &exp) != APR_SUCCESS) { + return apr_pstrdup(p, "0"); + } + + diff = (apr_time_sec(then) - apr_time_sec(now)) / (60*60*24); + + return diff > 0 ? apr_ltoa(p, diff) : apr_pstrdup(p, "0"); +} + static char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs) { char *result;