From fb318cf248b783d6a23d5af445fda4d58419485c Mon Sep 17 00:00:00 2001 From: Bradley Nicholes Date: Sun, 7 Mar 2004 03:08:21 +0000 Subject: [PATCH] Add the ssl_is_https() and ssl_var_lookup() optional functions to the mod_nw_ssl module for Netware git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@102877 13f79535-47bb-0310-9956-ffa450edef68 --- modules/arch/netware/mod_nw_ssl.c | 241 +++++++++++++++++++++++++++++- 1 file changed, 238 insertions(+), 3 deletions(-) diff --git a/modules/arch/netware/mod_nw_ssl.c b/modules/arch/netware/mod_nw_ssl.c index 1ef27f4db7..0eb914ad2f 100644 --- a/modules/arch/netware/mod_nw_ssl.c +++ b/modules/arch/netware/mod_nw_ssl.c @@ -41,6 +41,8 @@ #include "httpd.h" #include "http_config.h" #include "http_log.h" +#include "http_protocol.h" +#include "http_core.h" #include "ap_listen.h" #include "apr_strings.h" #include "apr_portable.h" @@ -50,9 +52,36 @@ #define SO_TLS_UNCLEAN_SHUTDOWN 0 #endif +/* The ssl_var_lookup() optional function retrieves SSL environment + * variables. */ +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, + (apr_pool_t *, server_rec *, + conn_rec *, request_rec *, + char *)); + +/* An optional function which returns non-zero if the given connection + * is using SSL/TLS. */ +APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); + +/* The ssl_proxy_enable() and ssl_engine_disable() optional functions + * are used by mod_proxy to enable use of SSL for outgoing + * connections. */ APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *)); APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *)); +#define strEQ(s1,s2) (strcmp(s1,s2) == 0) +#define strNE(s1,s2) (strcmp(s1,s2) != 0) +#define strEQn(s1,s2,n) (strncmp(s1,s2,n) == 0) +#define strNEn(s1,s2,n) (strncmp(s1,s2,n) != 0) + +#define strcEQ(s1,s2) (strcasecmp(s1,s2) == 0) +#define strcNE(s1,s2) (strcasecmp(s1,s2) != 0) +#define strcEQn(s1,s2,n) (strncasecmp(s1,s2,n) == 0) +#define strcNEn(s1,s2,n) (strncasecmp(s1,s2,n) != 0) + +#define strIsEmpty(s) (s == NULL || s[0] == NUL) + + module AP_MODULE_DECLARE_DATA nwssl_module; typedef struct NWSSLSrvConfigRec NWSSLSrvConfigRec; @@ -71,6 +100,7 @@ struct seclisten_rec { struct NWSSLSrvConfigRec { apr_table_t *sltable; + apr_pool_t *pPool; }; static apr_array_header_t *certlist = NULL; @@ -478,14 +508,14 @@ static void *nwssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) return merged; } -static int isSecure (const request_rec *r) +static int isSecureConn (const server_rec *s, const conn_rec *c) { - NWSSLSrvConfigRec *sc = get_nwssl_cfg(r->server); + NWSSLSrvConfigRec *sc = get_nwssl_cfg(s); const char *s_secure = NULL; char port[8]; int ret = 0; - itoa(((r->connection)->local_addr)->port, port, 10); + itoa((c->local_addr)->port, port, 10); s_secure = apr_table_get(sc->sltable, port); if (s_secure) ret = 1; @@ -493,6 +523,11 @@ static int isSecure (const request_rec *r) return ret; } +static int isSecure (const request_rec *r) +{ + return isSecureConn (r->server, r->connection); +} + static int nwssl_hook_Fixup(request_rec *r) { int i; @@ -533,6 +568,203 @@ int ssl_engine_disable(conn_rec *c) return 1; } +static int ssl_is_https(conn_rec *c) +{ + return isSecureConn (c->base_server, c); +} + +/* This function must remain safe to use for a non-SSL connection. */ +char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, char *var) +{ + NWSSLSrvConfigRec *mc = get_nwssl_cfg(s); + const char *result; + BOOL resdup; + apr_time_exp_t tm; + + result = NULL; + resdup = TRUE; + + /* + * 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 + p = mc->pPool; + } + + /* + * Request dependent stuff + */ + if (r != NULL) { + switch (var[0]) { + case 'H': + case 'h': + if (strcEQ(var, "HTTP_USER_AGENT")) + result = apr_table_get(r->headers_in, "User-Agent"); + else if (strcEQ(var, "HTTP_REFERER")) + result = apr_table_get(r->headers_in, "Referer"); + else if (strcEQ(var, "HTTP_COOKIE")) + result = apr_table_get(r->headers_in, "Cookie"); + else if (strcEQ(var, "HTTP_FORWARDED")) + result = apr_table_get(r->headers_in, "Forwarded"); + else if (strcEQ(var, "HTTP_HOST")) + result = apr_table_get(r->headers_in, "Host"); + else if (strcEQ(var, "HTTP_PROXY_CONNECTION")) + result = apr_table_get(r->headers_in, "Proxy-Connection"); + else if (strcEQ(var, "HTTP_ACCEPT")) + result = apr_table_get(r->headers_in, "Accept"); + else if (strlen(var) > 5 && strcEQn(var, "HTTP:", 5)) + /* all other headers from which we are still not know about */ + result = apr_table_get(r->headers_in, var+5); + break; + + case 'R': + case 'r': + if (strcEQ(var, "REQUEST_METHOD")) + result = r->method; + else if (strcEQ(var, "REQUEST_SCHEME")) + result = ap_http_method(r); + else if (strcEQ(var, "REQUEST_URI")) + result = r->uri; + else if (strcEQ(var, "REQUEST_FILENAME")) + result = r->filename; + else if (strcEQ(var, "REMOTE_HOST")) + result = ap_get_remote_host(r->connection, r->per_dir_config, + REMOTE_NAME, NULL); + else if (strcEQ(var, "REMOTE_IDENT")) + result = ap_get_remote_logname(r); + else if (strcEQ(var, "REMOTE_USER")) + result = r->user; + break; + + case 'S': + case 's': + if (strcEQn(var, "SSL", 3)) break; /* shortcut common case */ + + if (strcEQ(var, "SERVER_ADMIN")) + result = r->server->server_admin; + else if (strcEQ(var, "SERVER_NAME")) + result = ap_get_server_name(r); + else if (strcEQ(var, "SERVER_PORT")) + result = apr_psprintf(p, "%u", ap_get_server_port(r)); + else if (strcEQ(var, "SERVER_PROTOCOL")) + result = r->protocol; + else if (strcEQ(var, "SCRIPT_FILENAME")) + result = r->filename; + break; + + default: + if (strcEQ(var, "PATH_INFO")) + result = r->path_info; + else if (strcEQ(var, "QUERY_STRING")) + result = r->args; + else if (strcEQ(var, "IS_SUBREQ")) + result = (r->main != NULL ? "true" : "false"); + else if (strcEQ(var, "DOCUMENT_ROOT")) + result = ap_document_root(r); + else if (strcEQ(var, "AUTH_TYPE")) + result = r->ap_auth_type; + else if (strcEQ(var, "THE_REQUEST")) + result = r->the_request; + break; + } + } + + /* + * Connection stuff + */ + if (result == NULL && c != NULL) { + + /* XXX-Can't get specific SSL info from NetWare */ + /* SSLConnRec *sslconn = myConnConfig(c); + if (strlen(var) > 4 && strcEQn(var, "SSL_", 4) + && sslconn && sslconn->ssl) + result = ssl_var_lookup_ssl(p, c, var+4);*/ + + if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)) + result = NULL; + else if (strcEQ(var, "REMOTE_ADDR")) + result = c->remote_ip; + else if (strcEQ(var, "HTTPS")) { + if (isSecureConn (s, c)) + result = "on"; + else + result = "off"; + } + } + + /* + * Totally independent stuff + */ + if (result == NULL) { + if (strlen(var) > 12 && strcEQn(var, "SSL_VERSION_", 12)) + result = NULL; + /* XXX-Can't get specific SSL info from NetWare */ + /*result = ssl_var_lookup_ssl_version(p, var+12);*/ + else if (strcEQ(var, "SERVER_SOFTWARE")) + result = ap_get_server_version(); + else if (strcEQ(var, "API_VERSION")) { + result = apr_itoa(p, MODULE_MAGIC_NUMBER); + resdup = FALSE; + } + else if (strcEQ(var, "TIME_YEAR")) { + apr_time_exp_lt(&tm, apr_time_now()); + result = apr_psprintf(p, "%02d%02d", + (tm.tm_year / 100) + 19, tm.tm_year % 100); + resdup = FALSE; + } +#define MKTIMESTR(format, tmfield) \ + apr_time_exp_lt(&tm, apr_time_now()); \ + result = apr_psprintf(p, format, tm.tmfield); \ + resdup = FALSE; + else if (strcEQ(var, "TIME_MON")) { + MKTIMESTR("%02d", tm_mon+1) + } + else if (strcEQ(var, "TIME_DAY")) { + MKTIMESTR("%02d", tm_mday) + } + else if (strcEQ(var, "TIME_HOUR")) { + MKTIMESTR("%02d", tm_hour) + } + else if (strcEQ(var, "TIME_MIN")) { + MKTIMESTR("%02d", tm_min) + } + else if (strcEQ(var, "TIME_SEC")) { + MKTIMESTR("%02d", tm_sec) + } + else if (strcEQ(var, "TIME_WDAY")) { + MKTIMESTR("%d", tm_wday) + } + else if (strcEQ(var, "TIME")) { + apr_time_exp_lt(&tm, apr_time_now()); + result = apr_psprintf(p, + "%02d%02d%02d%02d%02d%02d%02d", (tm.tm_year / 100) + 19, + (tm.tm_year % 100), tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + resdup = FALSE; + } + /* all other env-variables from the parent Apache process */ + else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) { + result = apr_table_get(r->notes, var+4); + if (result == NULL) + result = apr_table_get(r->subprocess_env, var+4); + if (result == NULL) + result = getenv(var+4); + } + } + + if (result != NULL && resdup) + result = apr_pstrdup(p, result); + if (result == NULL) + result = ""; + return (char *)result; +} + + static const command_rec nwssl_module_cmds[] = { AP_INIT_TAKE23("SecureListen", set_secure_listener, NULL, RSRC_CONF, @@ -552,6 +784,9 @@ static void register_hooks(apr_pool_t *p) ap_hook_http_method(nwssl_hook_http_method, NULL,NULL, APR_HOOK_MIDDLE); ap_hook_default_port (nwssl_hook_default_port, NULL,NULL, APR_HOOK_MIDDLE); + APR_REGISTER_OPTIONAL_FN(ssl_is_https); + APR_REGISTER_OPTIONAL_FN(ssl_var_lookup); + APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable); APR_REGISTER_OPTIONAL_FN(ssl_engine_disable); } -- 2.50.1