ssl_engine_vars.c revision ac0c8366f49659958162b4bfb3d625a77343eda3
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* _ _
* _ __ ___ ___ __| | ___ ___| | mod_ssl
* | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
* | | | | | | (_) | (_| | \__ \__ \ |
* |_| |_| |_|\___/ \__,_|___|___/___/_|
* |_____|
* Variable Lookup Facility
*/
/* ``Those of you who think they
know everything are very annoying
to those of us who do.''
-- Unknown */
#include "ssl_private.h"
#include "mod_ssl.h"
#include "ap_expr.h"
#include "apr_time.h"
/* _________________________________________________________________
**
** Variable Lookup
** _________________________________________________________________
*/
static int ssl_is_https(conn_rec *c)
{
}
static char var_library_interface[] = SSL_LIBRARY_TEXT;
static char *var_library = NULL;
const void *dummy,
const char *arg)
{
}
{
}
{
case AP_EXPR_FUNC_VAR:
/* for now, we just handle everything that starts with SSL_, but
* register our hook as APR_HOOK_LAST
* XXX: This can be optimized
*/
return OK;
}
break;
case AP_EXPR_FUNC_LIST:
return OK;
}
break;
}
return DECLINED;
}
void ssl_var_register(apr_pool_t *p)
{
/* Perform once-per-process library version determination: */
*cp = '/';
}
*cp = '/';
}
}
/* This function must remain safe to use for a non-SSL connection. */
{
const char *result;
/*
* When no pool is given try to find one
*/
if (p == NULL) {
if (r != NULL)
p = r->pool;
else if (c != NULL)
p = c->pool;
else
}
/*
* Request dependent stuff
*/
if (r != NULL) {
switch (var[0]) {
case 'H':
case 'h':
/* all other headers from which we are still not know about */
break;
case 'R':
case 'r':
result = ap_http_scheme(r);
result = r->useragent_ip;
REMOTE_NAME, NULL);
result = ap_get_remote_logname(r);
break;
case 'S':
case 's':
break;
default:
result = ap_document_root(r);
result = r->ap_auth_type;
result = r->the_request;
}
break;
}
}
/*
* Connection stuff
*/
result = "on";
else
result = "off";
}
}
/*
* Totally independent stuff
*/
}
}
}
}
}
}
}
}
result = apr_psprintf(p,
}
/* all other env-variables from the parent Apache process */
}
}
result = "";
return (char *)result;
}
char *var)
{
char *result;
}
}
char buf[SSL_SESSION_ID_STRING_LEN];
if (pSession) {
unsigned char *id;
unsigned int idlen;
#ifdef OPENSSL_NO_SSL_INTERN
#else
#endif
}
}
result = "Resumed";
else
result = "Initial";
}
}
}
result = ssl_var_lookup_ssl_cert_verify(p, c);
}
}
}
/* SSL_get_certificate is different from SSL_get_peer_certificate.
* No need to X509_free(xs).
*/
}
}
}
#ifdef HAVE_TLSEXT
}
#endif
int flag = 0;
#endif
}
#ifdef HAVE_SRP
}
}
}
}
#endif
return result;
}
{
int legacy_format = 0;
if (r) {
dc = myDirConfig(r);
}
if (legacy_format) {
}
else {
int n;
return NULL;
n = BIO_pending(bio);
if (n > 0) {
}
}
return result;
}
char *var)
{
char *result;
int nid;
}
}
}
}
}
if (*var == 'S')
else if (*var == 'I')
else
return NULL;
}
if (*var == 'S')
else if (*var == 'I')
else
return NULL;
}
result = apr_pstrdup(p,
}
result = apr_pstrdup(p,
}
}
if (resdup)
return result;
}
/* In this table, .extract is non-zero if RDNs using the NID should be
* extracted to for the SSL_{CLIENT,SERVER}_{I,S}_DN_* environment
* variables. */
static const struct {
char *name;
int nid;
int extract;
} ssl_var_lookup_ssl_cert_dn_rec[] = {
#ifdef NID_userId
#endif
{ NULL, 0, 0 }
};
{
int i, j, n, idx = 0;
/* if an _N suffix is used, find the Nth attribute of given name */
} else {
}
j++) {
break;
}
}
break;
}
}
return result;
}
{
char *result;
int n;
return NULL;
n = BIO_pending(bio);
return result;
}
/* Return a string giving the number of days remaining until 'tm', or
* "0" if this can't be determined. */
{
apr_time_exp_t exp = {0};
long diff;
unsigned char *dp;
/* Fail if the time isn't a valid ASN.1 TIME; RFC3280 mandates
* that the seconds digits are present even though ASN.1
* doesn't. */
!ASN1_TIME_check(tm)) {
return apr_pstrdup(p, "0");
}
} else {
}
return apr_pstrdup(p, "0");
}
}
{
char *result;
int n;
return NULL;
n = BIO_pending(bio);
return result;
}
{
char *result;
int n;
if (n < sk_X509_num(sk)) {
}
}
return result;
}
{
char *result;
int n;
return NULL;
n = BIO_pending(bio);
return result;
}
{
char *result;
long vrc;
const char *verr;
const char *vinfo;
/* no client verification done at all */
result = "NONE";
/* client verification done successful */
result = "SUCCESS";
/* client verification done in generous way */
result = "GENEROUS";
else
/* client verification failed */
if (xs)
return result;
}
{
char *result;
int usekeysize, algkeysize;
}
}
}
return result;
}
{
*usekeysize = 0;
*algkeysize = 0;
return;
}
{
return apr_pstrdup(p, var_interface);
}
return apr_pstrdup(p, var_library_interface);
}
return apr_pstrdup(p, var_library);
}
return NULL;
}
/* Add each RDN in 'xn' to the table 't' where the NID is present in
* 'nids', using key prefix 'pfx'. */
{
int i, nid;
/* Hash of (int) NID -> (int *) counter to count each time an RDN
* with the given NID has been seen. */
count = apr_hash_make(p);
/* For each RDN... */
for (i = 0; i < sk_X509_NAME_ENTRY_num(ents); i++) {
const char *tag;
/* Retrieve the nid, and check whether this is one of the nids
* which are to be extracted. */
if (tag) {
const char *key;
int *dup;
char *value;
/* Check whether a variable with this nid was already
* been used; if so, use the foo_N=bar syntax. */
if (dup) {
}
else {
/* Otherwise, use the plain foo=bar syntax. */
}
}
}
}
{
unsigned n;
/* Build up a hash table of (int *)NID->(char *)short-name for all
* the tags which are to be extracted: */
nids = apr_hash_make(p);
for (n = 0; ssl_var_lookup_ssl_cert_dn_rec[n].name; n++) {
if (ssl_var_lookup_ssl_cert_dn_rec[n].extract) {
sizeof(ssl_var_lookup_ssl_cert_dn_rec[0].nid),
}
}
/* Extract the server cert DNS -- note that the refcount does NOT
* increase: */
if (xs) {
}
/* Extract the client cert DNs -- note that the refcount DOES
* increase: */
if (xs) {
}
}
/* For an extension type which OpenSSL does not recognize, attempt to
* parse the extension type as a primitive string. This will fail for
* any structured extension type per the docs. Returns non-zero on
* success and writes the string to the given bio. */
{
int rv = 0;
/* This allows UTF8String, IA5String, VisibleString, or BMPString;
* conversion to UTF-8 is forced. */
rv = 1;
}
return rv;
}
const char *extension)
{
int count = 0, j;
return NULL;
}
/* We accept the "extension" string to be converted as
* a long name (nsComment), short name (DN) or
* numeric OID (1.2.3.4).
*/
if (!oid) {
"could not parse OID '%s'", extension);
return NULL;
}
return NULL;
}
/* Create an array large enough to accomodate every extension. This is
* likely overkill, but safe.
*/
for (j = 0; j < count; j++) {
/* We want to obtain a string representation of the extensions
* value and add it to the array we're building.
* X509V3_EXT_print() doesn't know about all the possible
* data types, but the value is stored as an ASN1_OCTET_STRING
* allowing us a fallback in case of X509V3_EXT_print
* not knowing how to handle the data.
*/
} else {
"Found an extension '%s', but failed to "
"create a string from it", extension);
}
}
}
if (peer) {
/* only SSL_get_peer_certificate raises the refcount */
}
return array;
}
{
char *result = "NULL";
#ifndef OPENSSL_NO_COMP
if (pSession) {
#ifdef OPENSSL_NO_SSL_INTERN
switch (SSL_SESSION_get_compress_id(pSession)) {
#else
switch (pSession->compress_meth) {
#endif
case 0:
/* default "NULL" already set */
break;
/* Defined by RFC 3749, deflate is coded by "1" */
case 1:
result = "DEFLATE";
break;
/* IANA assigned compression number for LZS */
case 0x40:
result = "LZS";
break;
default:
result = "UNKNOWN";
break;
}
}
#endif
return result;
}
/* _________________________________________________________________
**
** SSL Extension to mod_log_config
** _________________________________________________________________
*/
#include "../../modules/loggers/mod_log_config.h"
static const char *ssl_var_log_handler_c(request_rec *r, char *a);
static const char *ssl_var_log_handler_x(request_rec *r, char *a);
/*
* register us for the mod_log_config function registering phase
* to establish %{...}c and to be able to expand %{...}x variables.
*/
void ssl_var_log_config_register(apr_pool_t *p)
{
if (log_pfn_register) {
}
return;
}
/*
* implement the %{..}c log function
* (we are the only function)
*/
static const char *ssl_var_log_handler_c(request_rec *r, char *a)
{
char *result;
return NULL;
if (strEQ(a, "version"))
else if (strEQ(a, "cipher"))
else if (strEQ(a, "errcode"))
result = "-";
else if (strEQ(a, "errstr"))
return result;
}
/*
* extend the implementation of the %{..}x log function
* (there can be more functions)
*/
static const char *ssl_var_log_handler_x(request_rec *r, char *a)
{
char *result;
return result;
}