Changeset a4839ae in mod_gnutls for src/gnutls_hooks.c
- Timestamp:
- Jan 11, 2013, 12:55:44 AM (8 years ago)
- Branches:
- debian/master, debian/stretch-backports, jessie-backports, upstream
- Children:
- 2a2272d, 9a9f943
- Parents:
- ec06980
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/gnutls_hooks.c
rec06980 ra4839ae 38 38 /* use side==0 for server and side==1 for client */ 39 39 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, 40 int side, int export_certificates_enabled); 40 int side, 41 int export_certificates_enabled); 41 42 42 43 static apr_status_t mgs_cleanup_pre_config(void *data) … … 84 85 } 85 86 86 87 static gnutls_datum88 load_params(const char *file, server_rec * s, apr_pool_t * pool)89 {90 gnutls_datum ret = { NULL, 0 };91 apr_file_t *fp;92 apr_finfo_t finfo;93 apr_status_t rv;94 apr_size_t br = 0;95 96 rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT,97 pool);98 if (rv != APR_SUCCESS) {99 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,100 "GnuTLS failed to load params file at: %s. Will use internal params.", file);101 return ret;102 }103 104 rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);105 106 if (rv != APR_SUCCESS) {107 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,108 "GnuTLS failed to stat params file at: %s", file);109 return ret;110 }111 112 ret.data = apr_palloc(pool, finfo.size + 1);113 rv = apr_file_read_full(fp, ret.data, finfo.size, &br);114 115 if (rv != APR_SUCCESS) {116 ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s,117 "GnuTLS failed to read params file at: %s", file);118 return ret;119 }120 apr_file_close(fp);121 ret.data[br] = '\0';122 ret.size = br;123 124 return ret;125 }126 127 87 /* We don't support openpgp certificates, yet */ 128 88 const static int cert_type_prio[2] = { GNUTLS_CRT_X509, 0 }; 129 89 130 static int mgs_select_virtual_server_cb( 90 static int mgs_select_virtual_server_cb(gnutls_session_t session) 131 91 { 132 92 mgs_handle_t *ctxt; … … 143 103 144 104 gnutls_certificate_server_set_request(session, 145 105 ctxt->sc->client_verify_mode); 146 106 147 107 /* set the new server credentials … … 149 109 150 110 gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, 151 152 153 gnutls_credentials_set(session, GNUTLS_CRD_ANON, 154 ctxt->sc->anon_creds); 155 156 if ( ctxt->sc->srp_tpasswd_conf_file != NULL&& ctxt->sc->srp_tpasswd_file != NULL) {157 158 111 ctxt->sc->certs); 112 113 gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds); 114 115 if (ctxt->sc->srp_tpasswd_conf_file != NULL 116 && ctxt->sc->srp_tpasswd_file != NULL) { 117 gnutls_credentials_set(session, GNUTLS_CRD_SRP, 118 ctxt->sc->srp_creds); 159 119 } 160 120 … … 163 123 * negotiation. 164 124 */ 165 ret = gnutls_priority_set( 166 gnutls_certificate_type_set_priority( 167 168 125 ret = gnutls_priority_set(session, ctxt->sc->priorities); 126 gnutls_certificate_type_set_priority(session, cert_type_prio); 127 128 169 129 /* actually it shouldn't fail since we have checked at startup */ 170 if (ret < 0) return ret; 130 if (ret < 0) 131 return ret; 171 132 172 133 /* allow separate caches per virtual host. Actually allowing the same is a … … 194 155 195 156 const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" 196 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n" 197 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n" 198 "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n" 199 "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n" 200 "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n" 201 "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n" 202 "-----END DH PARAMETERS-----\n"; 157 "MIIBBwKCAQCsa9tBMkqam/Fm3l4TiVgvr3K2ZRmH7gf8MZKUPbVgUKNzKcu0oJnt\n" 158 "gZPgdXdnoT3VIxKrSwMxDc1/SKnaBP1Q6Ag5ae23Z7DPYJUXmhY6s2YaBfvV+qro\n" 159 "KRipli8Lk7hV+XmT7Jde6qgNdArb9P90c1nQQdXDPqcdKB5EaxR3O8qXtDoj+4AW\n" 160 "dr0gekNsZIHx0rkHhxdGGludMuaI+HdIVEUjtSSw1X1ep3onddLs+gMs+9v1L7N4\n" 161 "YWAnkATleuavh05zA85TKZzMBBx7wwjYKlaY86jQw4JxrjX46dv7tpS1yAPYn3rk\n" 162 "Nd4jbVJfVHWbZeNy/NaO8g+nER+eSv9zAgEC\n" 163 "-----END DH PARAMETERS-----\n"; 164 165 /* Read the common name or the alternative name of the certificate. 166 * We only support a single name per certificate. 167 * 168 * Returns negative on error. 169 */ 170 static int read_crt_cn(server_rec * s, apr_pool_t * p, 171 gnutls_x509_crt cert, char **cert_cn) 172 { 173 int rv = 0, i; 174 size_t data_len; 175 176 177 *cert_cn = NULL; 178 179 rv = gnutls_x509_crt_get_dn_by_oid(cert, 180 GNUTLS_OID_X520_COMMON_NAME, 181 0, 0, NULL, &data_len); 182 183 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { 184 *cert_cn = apr_palloc(p, data_len); 185 rv = gnutls_x509_crt_get_dn_by_oid(cert, 186 GNUTLS_OID_X520_COMMON_NAME, 0, 187 0, *cert_cn, &data_len); 188 } else { /* No CN return subject alternative name */ 189 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 190 "No common name found in certificate for '%s:%d'. Looking for subject alternative name.", 191 s->server_hostname, s->port); 192 rv = 0; 193 /* read subject alternative name */ 194 for (i = 0; !(rv < 0); i++) { 195 data_len = 0; 196 rv = gnutls_x509_crt_get_subject_alt_name(cert, i, 197 NULL, &data_len, 198 NULL); 199 200 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { 201 /* FIXME: not very efficient. What if we have several alt names 202 * before DNSName? 203 */ 204 *cert_cn = apr_palloc(p, data_len + 1); 205 206 rv = gnutls_x509_crt_get_subject_alt_name(cert, i, 207 *cert_cn, 208 &data_len, NULL); 209 (*cert_cn)[data_len] = 0; 210 211 if (rv == GNUTLS_SAN_DNSNAME) 212 break; 213 } 214 } 215 } 216 217 return rv; 218 219 } 203 220 204 221 int … … 207 224 { 208 225 int rv; 209 size_t data_len;210 226 server_rec *s; 211 gnutls_dh_params_t dh_params ;212 gnutls_rsa_params_t rsa_params ;227 gnutls_dh_params_t dh_params = NULL; 228 gnutls_rsa_params_t rsa_params = NULL; 213 229 mgs_srvconf_rec *sc; 214 230 mgs_srvconf_rec *sc_base; … … 227 243 228 244 { 229 gnutls_datum pdata;230 apr_pool_t *tpool;231 245 s = base_server; 232 246 sc_base = … … 234 248 &gnutls_module); 235 249 236 apr_pool_create(&tpool, p);237 238 250 gnutls_dh_params_init(&dh_params); 239 251 240 pdata = load_params(sc_base->dh_params_file, s, tpool);241 242 if (pdata.size != 0) { 243 252 if (sc_base->dh_params == NULL) { 253 gnutls_datum pdata = { (void *) static_dh_params, sizeof(static_dh_params) }; 254 /* loading defaults */ 255 rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, 244 256 GNUTLS_X509_FMT_PEM); 245 if (rv != 0) {246 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,247 "GnuTLS: Unable to load DH Params: (%d) %s",248 rv, gnutls_strerror(rv));249 exit(rv);250 }251 } else {252 /* If the file does not exist use internal parameters253 */254 pdata.data = (void*)static_dh_params;255 pdata.size = sizeof( static_dh_params);256 rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata,257 GNUTLS_X509_FMT_PEM);258 257 259 258 if (rv < 0) { 260 261 "GnuTLS: Unable to load internal DH Params."262 " Shutting down.");263 exit(-1);259 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 260 "GnuTLS: Unable to load DH Params: (%d) %s", 261 rv, gnutls_strerror(rv)); 262 exit(rv); 264 263 } 265 } 266 apr_pool_clear(tpool); 267 268 rsa_params = NULL; 269 270 pdata = load_params(sc_base->rsa_params_file, s, tpool); 271 272 if (pdata.size != 0) { 273 gnutls_rsa_params_init(&rsa_params); 274 rv = gnutls_rsa_params_import_pkcs1(rsa_params, &pdata, 275 GNUTLS_X509_FMT_PEM); 276 if (rv != 0) { 277 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 278 "GnuTLS: Unable to load RSA Params: (%d) %s", 279 rv, gnutls_strerror(rv)); 280 exit(rv); 281 } 282 } 283 /* not an error but RSA-EXPORT ciphersuites are not available 284 */ 285 286 apr_pool_destroy(tpool); 264 } else dh_params = sc_base->dh_params; 265 266 if (sc_base->rsa_params != NULL) 267 rsa_params = sc_base->rsa_params; 268 269 /* else not an error but RSA-EXPORT ciphersuites are not available 270 */ 271 287 272 rv = mgs_cache_post_config(p, s, sc_base); 288 273 if (rv != 0) { … … 294 279 295 280 for (s = base_server; s; s = s->next) { 281 void *load = NULL; 296 282 sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, 297 283 &gnutls_module); … … 299 285 sc->cache_config = sc_base->cache_config; 300 286 301 if (rsa_params != NULL) 302 gnutls_certificate_set_rsa_export_params(sc->certs, 303 rsa_params); 304 gnutls_certificate_set_dh_params(sc->certs, dh_params); 305 306 gnutls_anon_set_server_dh_params( sc->anon_creds, dh_params); 307 308 gnutls_certificate_server_set_retrieve_function(sc->certs, 309 cert_retrieve_fn); 310 311 if ( sc->srp_tpasswd_conf_file != NULL && sc->srp_tpasswd_file != NULL) { 312 gnutls_srp_set_server_credentials_file( sc->srp_creds, 313 sc->srp_tpasswd_file, sc->srp_tpasswd_conf_file); 287 /* Check if the priorities have been set */ 288 if (sc->priorities == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { 289 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, 290 "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!", 291 s->server_hostname, s->port); 292 exit(-1); 314 293 } 315 294 295 /* Check if DH or RSA params have been set per host */ 296 if (sc->rsa_params != NULL) 297 load = sc->rsa_params; 298 else if (rsa_params) load = rsa_params; 299 300 if (load != NULL) 301 gnutls_certificate_set_rsa_export_params(sc->certs, load); 302 303 304 load = NULL; 305 if (sc->dh_params != NULL) 306 load = sc->dh_params; 307 else if (dh_params) load = dh_params; 308 309 if (load != NULL) { /* not needed but anyway */ 310 gnutls_certificate_set_dh_params(sc->certs, load); 311 gnutls_anon_set_server_dh_params(sc->anon_creds, load); 312 } 313 314 gnutls_certificate_server_set_retrieve_function(sc->certs, 315 cert_retrieve_fn); 316 317 if (sc->srp_tpasswd_conf_file != NULL 318 && sc->srp_tpasswd_file != NULL) { 319 rv = gnutls_srp_set_server_credentials_file(sc->srp_creds, 320 sc-> 321 srp_tpasswd_file, 322 sc-> 323 srp_tpasswd_conf_file); 324 325 if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { 326 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 327 "[GnuTLS] - Host '%s:%d' is missing a " 328 "SRP password or conf File!", 329 s->server_hostname, s->port); 330 exit(-1); 331 } 332 } 333 316 334 if (sc->cert_x509 == NULL 317 335 && sc->enabled == GNUTLS_ENABLED_TRUE) { … … 333 351 334 352 if (sc->enabled == GNUTLS_ENABLED_TRUE) { 335 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,336 GNUTLS_OID_X520_COMMON_NAME,337 0, 0, NULL, &data_len);338 339 if (data_len < 1) {340 sc->enabled = GNUTLS_ENABLED_FALSE;341 sc->cert_cn = NULL;342 continue;353 rv = read_crt_cn(s, p, sc->cert_x509, &sc->cert_cn); 354 if (rv < 0) { 355 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, 356 "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", 357 s->server_hostname, s->port); 358 sc->cert_cn = NULL; 359 continue; 360 } 343 361 } 344 345 sc->cert_cn = apr_palloc(p, data_len);346 rv = gnutls_x509_crt_get_dn_by_oid(sc->cert_x509,347 GNUTLS_OID_X520_COMMON_NAME,348 0, 0, sc->cert_cn,349 &data_len);350 }351 362 } 352 363 } … … 440 451 */ 441 452 return 1; 453 } else { 454 #if MOD_GNUTLS_DEBUG 455 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, 456 x->ctxt->c->base_server, 457 "GnuTLS: Virtual Host CB: " 458 "'%s' != '%s'", tsc->cert_cn, x->sni_name); 459 #endif 460 442 461 } 443 462 return 0; … … 533 552 534 553 static const int protocol_priority[] = { 535 GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 }; 536 554 GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 555 }; 556 537 557 538 558 static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c) … … 559 579 560 580 gnutls_init(&ctxt->session, GNUTLS_SERVER); 561 562 /* This is not very good as it trades security for compatibility, 563 * but it is the only way to be ultra-portable. 564 */ 565 gnutls_session_enable_compatibility_mode( ctxt->session); 566 581 567 582 /* because we don't set any default priorities here (we set later at 568 583 * the user hello callback) we need to at least set this in order for 569 584 * gnutls to be able to read packets. 570 585 */ 571 gnutls_protocol_set_priority( ctxt->session, protocol_priority); 572 573 gnutls_handshake_set_post_client_hello_function( ctxt->session, mgs_select_virtual_server_cb); 586 gnutls_protocol_set_priority(ctxt->session, protocol_priority); 587 588 gnutls_handshake_set_post_client_hello_function(ctxt->session, 589 mgs_select_virtual_server_cb); 574 590 575 591 return ctxt; … … 624 640 apr_table_setn(env, "HTTPS", "on"); 625 641 626 apr_table_setn(env, "SSL_VERSION_LIBRARY", "GnuTLS/"LIBGNUTLS_VERSION); 627 apr_table_setn(env, "SSL_VERSION_INTERFACE", "mod_gnutls/"MOD_GNUTLS_VERSION); 642 apr_table_setn(env, "SSL_VERSION_LIBRARY", 643 "GnuTLS/" LIBGNUTLS_VERSION); 644 apr_table_setn(env, "SSL_VERSION_INTERFACE", 645 "mod_gnutls/" MOD_GNUTLS_VERSION); 628 646 629 647 apr_table_setn(env, "SSL_PROTOCOL", … … 631 649 (ctxt->session))); 632 650 633 /* should have been called SSL_CIPHERSUITE instead */ 651 /* should have been called SSL_CIPHERSUITE instead */ 634 652 apr_table_setn(env, "SSL_CIPHER", 635 gnutls_cipher_suite_get_name( 636 gnutls_kx_get(ctxt->session), gnutls_cipher_get(ctxt->session), 637 gnutls_mac_get(ctxt->session))); 653 gnutls_cipher_suite_get_name(gnutls_kx_get 654 (ctxt->session), 655 gnutls_cipher_get(ctxt-> 656 session), 657 gnutls_mac_get(ctxt-> 658 session))); 638 659 639 660 apr_table_setn(env, "SSL_COMPRESS_METHOD", 640 661 gnutls_compression_get_name(gnutls_compression_get 641 (ctxt->session)));662 (ctxt->session))); 642 663 643 664 apr_table_setn(env, "SSL_SRP_USER", 644 gnutls_srp_server_get_username(ctxt->session));665 gnutls_srp_server_get_username(ctxt->session)); 645 666 646 667 if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL) … … 663 684 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); 664 685 665 mgs_add_common_cert_vars(r, ctxt->sc->cert_x509, 0, ctxt->sc->export_certificates_enabled); 686 mgs_add_common_cert_vars(r, ctxt->sc->cert_x509, 0, 687 ctxt->sc->export_certificates_enabled); 666 688 667 689 return rv; … … 724 746 #define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT") 725 747 static void 726 mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side, int export_certificates_enabled) 748 mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side, 749 int export_certificates_enabled) 727 750 { 728 751 unsigned char sbuf[64]; /* buffer to hold serials */ 729 752 char buf[AP_IOBUFSIZE]; 730 753 const char *tmp; 754 char *tmp2; 731 755 size_t len; 732 int alg;756 int ret, i; 733 757 734 758 apr_table_t *env = r->subprocess_env; 735 759 736 760 if (export_certificates_enabled != 0) { 737 char cert_buf[10*1024]; 738 len = sizeof(cert_buf); 739 740 if (gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0) 741 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL), 742 apr_pstrmemdup(r->pool, cert_buf, len)); 743 761 char cert_buf[10 * 1024]; 762 len = sizeof(cert_buf); 763 764 if (gnutls_x509_crt_export 765 (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0) 766 apr_table_setn(env, 767 apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL), 768 apr_pstrmemdup(r->pool, cert_buf, len)); 769 744 770 } 745 771 … … 760 786 apr_pstrdup(r->pool, tmp)); 761 787 788 ret = gnutls_x509_crt_get_version(cert); 789 if (ret > 0) 790 apr_table_setn(env, 791 apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL), 792 apr_psprintf(r->pool, "%u", ret)); 793 794 apr_table_setn(env, 795 apr_pstrcat(r->pool, MGS_SIDE, "_S_TYPE", NULL), "X.509"); 796 762 797 tmp = 763 798 mgs_time2sz(gnutls_x509_crt_get_expiration_time … … 772 807 apr_pstrdup(r->pool, tmp)); 773 808 774 alg = gnutls_x509_crt_get_signature_algorithm( cert); 775 if (alg >= 0) { 776 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL), 777 gnutls_sign_algorithm_get_name( alg)); 778 } 779 780 alg = gnutls_x509_crt_get_pk_algorithm( cert, NULL); 781 if (alg >= 0) { 782 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL), 783 gnutls_pk_algorithm_get_name( alg)); 809 ret = gnutls_x509_crt_get_signature_algorithm(cert); 810 if (ret >= 0) { 811 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL), 812 gnutls_sign_algorithm_get_name(ret)); 813 } 814 815 ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL); 816 if (ret >= 0) { 817 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL), 818 gnutls_pk_algorithm_get_name(ret)); 819 } 820 821 /* export all the alternative names (DNS, RFC822 and URI) */ 822 for (i = 0; !(ret < 0); i++) { 823 len = 0; 824 ret = gnutls_x509_crt_get_subject_alt_name(cert, i, 825 NULL, &len, NULL); 826 827 if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) { 828 tmp2 = apr_palloc(r->pool, len + 1); 829 830 ret = 831 gnutls_x509_crt_get_subject_alt_name(cert, i, tmp2, &len, 832 NULL); 833 tmp2[len] = 0; 834 835 if (ret == GNUTLS_SAN_DNSNAME) { 836 apr_table_setn(env, 837 apr_psprintf(r->pool, "%s_S_SAN%u", MGS_SIDE, i), 838 apr_psprintf(r->pool, "DNSNAME:%s", tmp2)); 839 } else if (ret == GNUTLS_SAN_RFC822NAME) { 840 apr_table_setn(env, 841 apr_psprintf(r->pool, "%s_S_SAN%u", MGS_SIDE, i), 842 apr_psprintf(r->pool, "RFC822NAME:%s", tmp2)); 843 } else if (ret == GNUTLS_SAN_URI) { 844 apr_table_setn(env, 845 apr_psprintf(r->pool, "%s_S_SAN%u", MGS_SIDE, i), 846 apr_psprintf(r->pool, "URI:%s", tmp2)); 847 } else { 848 apr_table_setn(env, 849 apr_psprintf(r->pool, "%s_S_SAN%u", MGS_SIDE, i), 850 "UNSUPPORTED"); 851 } 852 } 784 853 } 785 854 … … 888 957 // rv = mgs_authz_lua(r); 889 958 890 mgs_add_common_cert_vars(r, cert, 1, ctxt->sc->export_certificates_enabled); 959 mgs_add_common_cert_vars(r, cert, 1, 960 ctxt->sc->export_certificates_enabled); 891 961 892 962 { 893 /* days remaining */ 894 unsigned long remain = (apr_time_sec(expiration_time) - apr_time_sec(cur_time))/86400; 895 apr_table_setn(r->subprocess_env, "SSL_CLIENT_V_REMAIN", 896 apr_psprintf(r->pool, "%lu", remain)); 963 /* days remaining */ 964 unsigned long remain = 965 (apr_time_sec(expiration_time) - 966 apr_time_sec(cur_time)) / 86400; 967 apr_table_setn(r->subprocess_env, "SSL_CLIENT_V_REMAIN", 968 apr_psprintf(r->pool, "%lu", remain)); 897 969 } 898 970
Note: See TracChangeset
for help on using the changeset viewer.