diff options
Diffstat (limited to 'rubbos/app/httpd-2.0.64/modules/arch/netware')
30 files changed, 1474 insertions, 0 deletions
diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/libprews.c b/rubbos/app/httpd-2.0.64/modules/arch/netware/libprews.c new file mode 100644 index 00000000..5ac5e54c --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/libprews.c @@ -0,0 +1,70 @@ +/* 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/*------------------------------------------------------------------ + These functions are to be called when the shared NLM starts and + stops. By using these functions instead of defining a main() + and calling ExitThread(TSR_THREAD, 0), the load time of the + shared NLM is faster and memory size reduced. + + You may also want to override these in your own Apache module + to do any cleanup other than the mechanism Apache modules + provide. +------------------------------------------------------------------*/ +#include <netware.h> +//#include "stddef.h" +#include "novsock2.h" + +int _NonAppStart +( + void *NLMHandle, + void *errorScreen, + const char *cmdLine, + const char *loadDirPath, + size_t uninitializedDataLength, + void *NLMFileHandle, + int (*readRoutineP)( int conn, void *fileHandle, size_t offset, + size_t nbytes, size_t *bytesRead, void *buffer ), + size_t customDataOffset, + size_t customDataSize, + int messageCount, + const char **messages +) +{ +#pragma unused(cmdLine) +#pragma unused(loadDirPath) +#pragma unused(uninitializedDataLength) +#pragma unused(NLMFileHandle) +#pragma unused(readRoutineP) +#pragma unused(customDataOffset) +#pragma unused(customDataSize) +#pragma unused(messageCount) +#pragma unused(messages) + + WSADATA wsaData; + + return WSAStartup((WORD) MAKEWORD(2, 0), &wsaData); +} + +void _NonAppStop( void ) +{ + WSACleanup(); +} + +int _NonAppCheckUnload( void ) +{ + return 0; +} diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_anon.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_anon.def new file mode 100644 index 00000000..ab6b138f --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_anon.def @@ -0,0 +1 @@ +EXPORT auth_anon_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_basic.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_basic.def new file mode 100644 index 00000000..0a6f81aa --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_basic.def @@ -0,0 +1 @@ +EXPORT auth_basic_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_dbm.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_dbm.def new file mode 100644 index 00000000..830f194d --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_dbm.def @@ -0,0 +1 @@ +EXPORT auth_dbm_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_digest.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_digest.def new file mode 100644 index 00000000..6a3aa085 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_auth_digest.def @@ -0,0 +1 @@ +EXPORT auth_digest_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_cache.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_cache.def new file mode 100644 index 00000000..6fd6423b --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_cache.def @@ -0,0 +1,5 @@ +EXPORT cache_module +EXPORT @mod_cache.imp + + + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_cern_meta.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_cern_meta.def new file mode 100644 index 00000000..5638325b --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_cern_meta.def @@ -0,0 +1 @@ +EXPORT cern_meta_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_dav.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_dav.def new file mode 100644 index 00000000..fb56c92f --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_dav.def @@ -0,0 +1,3 @@ +EXPORT dav_module +EXPORT @dav.imp + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_disk_cache.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_disk_cache.def new file mode 100644 index 00000000..0a9440ad --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_disk_cache.def @@ -0,0 +1,3 @@ +IMPORT @mod_cache.imp +EXPORT disk_cache_module + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_echo.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_echo.def new file mode 100644 index 00000000..694135a5 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_echo.def @@ -0,0 +1,2 @@ +EXPORT echo_module + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_expires.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_expires.def new file mode 100644 index 00000000..bc416630 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_expires.def @@ -0,0 +1 @@ +EXPORT expires_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_file_cache.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_file_cache.def new file mode 100644 index 00000000..8ab98cfb --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_file_cache.def @@ -0,0 +1,2 @@ +EXPORT file_cache_module + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_headers.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_headers.def new file mode 100644 index 00000000..2fe35a85 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_headers.def @@ -0,0 +1 @@ +EXPORT headers_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_info.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_info.def new file mode 100644 index 00000000..ce71cb37 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_info.def @@ -0,0 +1 @@ +EXPORT info_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_logio.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_logio.def new file mode 100644 index 00000000..68c70891 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_logio.def @@ -0,0 +1,2 @@ +EXPORT logio_module + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_mem_cache.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_mem_cache.def new file mode 100644 index 00000000..531d6871 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_mem_cache.def @@ -0,0 +1,3 @@ +IMPORT @mod_cache.imp +EXPORT mem_cache_module + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_mime_magic.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_mime_magic.def new file mode 100644 index 00000000..95307476 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_mime_magic.def @@ -0,0 +1 @@ +EXPORT mime_magic_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_netware.c b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_netware.c new file mode 100644 index 00000000..3fec8cc4 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_netware.c @@ -0,0 +1,194 @@ +/* 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +#include "apr_strings.h" +#include "apr_portable.h" +#include "apr_buckets.h" +#include "ap_config.h" +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_protocol.h" +#include "http_request.h" +#include "http_log.h" +#include "util_script.h" +#include "mod_core.h" +#include "apr_optional.h" +#include "apr_lib.h" +#include "mod_cgi.h" + +#ifdef NETWARE + + +module AP_MODULE_DECLARE_DATA netware_module; + +typedef struct { + apr_table_t *file_type_handlers; /* CGI map from file types to CGI modules */ + apr_table_t *file_handler_mode; /* CGI module mode (spawn in same address space or not) */ + apr_table_t *extra_env_vars; /* Environment variables to be added to the CGI environment */ +} netware_dir_config; + + +static void *create_netware_dir_config(apr_pool_t *p, char *dir) +{ + netware_dir_config *new = (netware_dir_config*) apr_palloc(p, sizeof(netware_dir_config)); + + new->file_type_handlers = apr_table_make(p, 10); + new->file_handler_mode = apr_table_make(p, 10); + new->extra_env_vars = apr_table_make(p, 10); + + apr_table_set(new->file_type_handlers, "NLM", "OS"); + + return new; +} + +static void *merge_netware_dir_configs(apr_pool_t *p, void *basev, void *addv) +{ + netware_dir_config *base = (netware_dir_config *) basev; + netware_dir_config *add = (netware_dir_config *) addv; + netware_dir_config *new = (netware_dir_config *) apr_palloc(p, sizeof(netware_dir_config)); + + new->file_type_handlers = apr_table_overlay(p, add->file_type_handlers, base->file_type_handlers); + new->file_handler_mode = apr_table_overlay(p, add->file_handler_mode, base->file_handler_mode); + new->extra_env_vars = apr_table_overlay(p, add->extra_env_vars, base->extra_env_vars); + + return new; +} + +static const char *set_extension_map(cmd_parms *cmd, netware_dir_config *m, + char *CGIhdlr, char *ext, char *detach) +{ + int i, len; + + if (*ext == '.') + ++ext; + + if (CGIhdlr != NULL) { + len = strlen(CGIhdlr); + for (i=0; i<len; i++) { + if (CGIhdlr[i] == '\\') { + CGIhdlr[i] = '/'; + } + } + } + + apr_table_set(m->file_type_handlers, ext, CGIhdlr); + if (detach) { + apr_table_set(m->file_handler_mode, ext, "y"); + } + + return NULL; +} + +static apr_status_t ap_cgi_build_command(const char **cmd, const char ***argv, + request_rec *r, apr_pool_t *p, + cgi_exec_info_t *e_info) +{ + char *ext = NULL; + char *cmd_only, *ptr; + const char *new_cmd; + netware_dir_config *d; + apr_file_t *fh; + const char *args = ""; + + d = (netware_dir_config *)ap_get_module_config(r->per_dir_config, + &netware_module); + + if (e_info->process_cgi) { + /* Handle the complete file name, we DON'T want to follow suexec, since + * an unrooted command is as predictable as shooting craps in Win32. + * + * Notice that unlike most mime extension parsing, we have to use the + * win32 parsing here, therefore the final extension is the only one + * we will consider + */ + *cmd = r->filename; + if (r->args && r->args[0] && !ap_strchr_c(r->args, '=')) { + args = r->args; + } + } + + cmd_only = apr_pstrdup(p, *cmd); + e_info->cmd_type = APR_PROGRAM; + + /* truncate any arguments from the cmd */ + for (ptr = cmd_only; *ptr && (*ptr != ' '); ptr++); + *ptr = '\0'; + + /* Figure out what the extension is so that we can matche it. */ + ext = strrchr(apr_filepath_name_get(cmd_only), '.'); + + /* If there isn't an extension then give it an empty string */ + if (!ext) { + ext = ""; + } + + /* eliminate the '.' if there is one */ + if (*ext == '.') + ++ext; + + /* check if we have a registered command for the extension*/ + new_cmd = apr_table_get(d->file_type_handlers, ext); + e_info->detached = AP_PROC_DETACHED; + if (new_cmd == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "Could not find a command associated with the %s extension", ext); + return APR_EBADF; + } + if (stricmp(new_cmd, "OS")) { + /* If we have a registered command then add the file that was passed in as a + parameter to the registered command. */ + *cmd = apr_pstrcat (p, new_cmd, " ", cmd_only, NULL); + + /* Run in its own address space if specified */ + if(apr_table_get(d->file_handler_mode, ext)) + e_info->detached |= AP_PROC_NEWADDRSPACE; + } + + /* Tokenize the full command string into its arguments */ + apr_tokenize_to_argv(*cmd, (char***)argv, p); + + /* The first argument should be the executible */ + *cmd = ap_server_root_relative(p, *argv[0]); + + return APR_SUCCESS; +} + +static void register_hooks(apr_pool_t *p) +{ + APR_REGISTER_OPTIONAL_FN(ap_cgi_build_command); +} + +static const command_rec netware_cmds[] = { +AP_INIT_TAKE23("CGIMapExtension", set_extension_map, NULL, OR_FILEINFO, + "Full path to the CGI NLM module followed by a file extension. If the " + "first parameter is set to \"OS\" then the following file extension is " + "treated as NLM. The optional parameter \"detach\" can be specified if " + "the NLM should be launched in its own address space."), +{ NULL } +}; + +module AP_MODULE_DECLARE_DATA netware_module = { + STANDARD20_MODULE_STUFF, + create_netware_dir_config, /* create per-dir config */ + merge_netware_dir_configs, /* merge per-dir config */ + NULL, /* server config */ + NULL, /* merge server config */ + netware_cmds, /* command apr_table_t */ + register_hooks /* register hooks */ +}; + +#endif diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_nw_ssl.c b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_nw_ssl.c new file mode 100644 index 00000000..3d45f149 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_nw_ssl.c @@ -0,0 +1,1151 @@ +/* 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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_tls.c - Apache SSL/TLS module for NetWare by Mike Gardiner. + * + * This module gives Apache the ability to do SSL/TLS with a minimum amount + * of effort. All of the SSL/TLS logic is already on NetWare versions 5 and + * above and is interfaced through WinSock on NetWare. As you can see in + * the code below SSL/TLS sockets can be created with three WinSock calls. + * + * To load, simply place the module in the modules directory under the main + * apache tree. Then add a "SecureListen" with two arguments. The first + * argument is an address and/or port. The second argument is the key pair + * name as created in ConsoleOne. + * + * Examples: + * + * SecureListen 443 "SSL CertificateIP" + * SecureListen 123.45.67.89:443 mycert + */ + +#define WS_SSL + +#define MAX_ADDRESS 512 +#define MAX_KEY 80 + + +#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" +#include "apr_optional.h" + +#include <unilib.h> + +#ifndef SO_TLS_UNCLEAN_SHUTDOWN +#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; +typedef struct seclisten_rec seclisten_rec; +typedef struct seclistenup_rec seclistenup_rec; +typedef struct secsocket_data secsocket_data; + +struct seclisten_rec { + seclisten_rec *next; + struct sockaddr_in local_addr; /* local IP address and port */ + int fd; + int used; /* Only used during restart */ + char key[MAX_KEY]; + int mutual; + char *addr; + apr_port_t port; +}; + +struct seclistenup_rec { + seclistenup_rec *next; + char key[MAX_KEY]; + char *addr; + apr_port_t port; +}; + +struct NWSSLSrvConfigRec { + apr_table_t *sltable; + apr_table_t *slutable; + apr_pool_t *pPool; +}; + +struct secsocket_data { + apr_socket_t* csd; + int is_secure; +}; + +static apr_array_header_t *certlist = NULL; +static unicode_t** certarray = NULL; +static int numcerts = 0; +static seclisten_rec* ap_seclisteners = NULL; +static seclistenup_rec* ap_seclistenersup = NULL; + +#define get_nwssl_cfg(srv) (NWSSLSrvConfigRec *) ap_get_module_config(srv->module_config, &nwssl_module) + + +static void build_cert_list (apr_pool_t *p) +{ + int i; + char **rootcerts = (char **)certlist->elts; + + numcerts = certlist->nelts; + certarray = apr_palloc(p, sizeof(unicode_t*)*numcerts); + + for (i = 0; i < numcerts; ++i) { + unicode_t *unistr; + unistr = (unicode_t*)apr_palloc(p, strlen(rootcerts[i])*4); + loc2uni (UNI_LOCAL_DEFAULT, unistr, rootcerts[i], 0, 2); + certarray[i] = unistr; + } +} + +/* + * Parses a host of the form <address>[:port] + * :port is permitted if 'port' is not NULL + */ +static unsigned long parse_addr(const char *w, unsigned short *ports) +{ + struct hostent *hep; + unsigned long my_addr; + char *p; + + p = strchr(w, ':'); + if (ports != NULL) { + *ports = 0; + if (p != NULL && strcmp(p + 1, "*") != 0) + *ports = atoi(p + 1); + } + + if (p != NULL) + *p = '\0'; + if (strcmp(w, "*") == 0) { + if (p != NULL) + *p = ':'; + return htonl(INADDR_ANY); + } + + my_addr = apr_inet_addr((char *)w); + if (my_addr != INADDR_NONE) { + if (p != NULL) + *p = ':'; + return my_addr; + } + + hep = gethostbyname(w); + + if ((!hep) || (hep->h_addrtype != AF_INET || !hep->h_addr_list[0])) { + /* XXX Should be echoing by h_errno the actual failure, no? + * ap_log_error would be good here. Better yet - APRize. + */ + fprintf(stderr, "Cannot resolve host name %s --- exiting!\n", w); + exit(1); + } + + if (hep->h_addr_list[1]) { + fprintf(stderr, "Host %s has multiple addresses ---\n", w); + fprintf(stderr, "you must choose one explicitly for use as\n"); + fprintf(stderr, "a secure port. Exiting!!!\n"); + exit(1); + } + + if (p != NULL) + *p = ':'; + + return ((struct in_addr *) (hep->h_addr))->s_addr; +} + +static int find_secure_listener(seclisten_rec *lr) +{ + seclisten_rec *sl; + + for (sl = ap_seclisteners; sl; sl = sl->next) { + if (!memcmp(&sl->local_addr, &lr->local_addr, sizeof(sl->local_addr))) { + sl->used = 1; + return sl->fd; + } + } + return -1; +} + +static char *get_port_key(conn_rec *c) +{ + seclistenup_rec *sl; + + for (sl = ap_seclistenersup; sl; sl = sl->next) { + if ((sl->port == (c->local_addr)->port) && + ((strcmp(sl->addr, "0.0.0.0") == 0) || (strcmp(sl->addr, c->local_ip) == 0))) { + return sl->key; + } + } + return NULL; +} + +static int make_secure_socket(apr_pool_t *pconf, const struct sockaddr_in *server, + char* key, int mutual, server_rec *sconf) +{ + int s; + int one = 1; + char addr[MAX_ADDRESS]; + struct sslserveropts opts; + unsigned int optParam; + WSAPROTOCOL_INFO SecureProtoInfo; + int no = 1; + + if (server->sin_addr.s_addr != htonl(INADDR_ANY)) + apr_snprintf(addr, sizeof(addr), "address %s port %d", + inet_ntoa(server->sin_addr), ntohs(server->sin_port)); + else + apr_snprintf(addr, sizeof(addr), "port %d", ntohs(server->sin_port)); + + /* note that because we're about to slack we don't use psocket */ + memset(&SecureProtoInfo, 0, sizeof(WSAPROTOCOL_INFO)); + + SecureProtoInfo.iAddressFamily = AF_INET; + SecureProtoInfo.iSocketType = SOCK_STREAM; + SecureProtoInfo.iProtocol = IPPROTO_TCP; + SecureProtoInfo.iSecurityScheme = SECURITY_PROTOCOL_SSL; + + s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, + (LPWSAPROTOCOL_INFO)&SecureProtoInfo, 0, 0); + + if (s == INVALID_SOCKET) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: failed to get a socket for %s", + addr); + return -1; + } + + if (!mutual) { + optParam = SO_SSL_ENABLE | SO_SSL_SERVER; + + if (WSAIoctl(s, SO_SSL_SET_FLAGS, (char *)&optParam, + sizeof(optParam), NULL, 0, NULL, NULL, NULL)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: for %s, WSAIoctl: " + "(SO_SSL_SET_FLAGS)", addr); + return -1; + } + } + + opts.cert = key; + opts.certlen = strlen(key); + opts.sidtimeout = 0; + opts.sidentries = 0; + opts.siddir = NULL; + + if (WSAIoctl(s, SO_SSL_SET_SERVER, (char *)&opts, sizeof(opts), + NULL, 0, NULL, NULL, NULL) != 0) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: for %s, WSAIoctl: " + "(SO_SSL_SET_SERVER)", addr); + return -1; + } + + if (mutual) { + optParam = 0x07; // SO_SSL_AUTH_CLIENT + + if(WSAIoctl(s, SO_SSL_SET_FLAGS, (char*)&optParam, + sizeof(optParam), NULL, 0, NULL, NULL, NULL)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, WSAGetLastError(), sconf, + "make_secure_socket: for %s, WSAIoctl: " + "(SO_SSL_SET_FLAGS)", addr); + return -1; + } + } + + optParam = SO_TLS_UNCLEAN_SHUTDOWN; + WSAIoctl(s, SO_SSL_SET_FLAGS, (char *)&optParam, sizeof(optParam), + NULL, 0, NULL, NULL, NULL); + + return s; +} + +int convert_secure_socket(conn_rec *c, apr_socket_t *csd) +{ + int rcode; + struct tlsclientopts sWS2Opts; + struct nwtlsopts sNWTLSOpts; + struct sslserveropts opts; + unsigned long ulFlags; + SOCKET sock; + unicode_t keyFileName[60]; + + apr_os_sock_get(&sock, csd); + + /* zero out buffers */ + memset((char *)&sWS2Opts, 0, sizeof(struct tlsclientopts)); + memset((char *)&sNWTLSOpts, 0, sizeof(struct nwtlsopts)); + + /* turn on ssl for the socket */ + ulFlags = (numcerts ? SO_TLS_ENABLE : SO_TLS_ENABLE | SO_TLS_BLIND_ACCEPT); + rcode = WSAIoctl(sock, SO_TLS_SET_FLAGS, &ulFlags, sizeof(unsigned long), + NULL, 0, NULL, NULL, NULL); + if (SOCKET_ERROR == rcode) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, + "Error: %d with ioctlsocket(flag SO_TLS_ENABLE)", WSAGetLastError()); + return rcode; + } + + ulFlags = SO_TLS_UNCLEAN_SHUTDOWN; + WSAIoctl(sock, SO_TLS_SET_FLAGS, &ulFlags, sizeof(unsigned long), + NULL, 0, NULL, NULL, NULL); + + /* setup the socket for SSL */ + memset (&sWS2Opts, 0, sizeof(sWS2Opts)); + memset (&sNWTLSOpts, 0, sizeof(sNWTLSOpts)); + sWS2Opts.options = &sNWTLSOpts; + + if (numcerts) { + sNWTLSOpts.walletProvider = WAL_PROV_DER; //the wallet provider defined in wdefs.h + sNWTLSOpts.TrustedRootList = certarray; //array of certs in UNICODE format + sNWTLSOpts.numElementsInTRList = numcerts; //number of certs in TRList + } + else { + /* setup the socket for SSL */ + unicpy(keyFileName, L"SSL CertificateIP"); + sWS2Opts.wallet = keyFileName; /* no client certificate */ + sWS2Opts.walletlen = unilen(keyFileName); + + sNWTLSOpts.walletProvider = WAL_PROV_KMO; //the wallet provider defined in wdefs.h + } + + /* make the IOCTL call */ + rcode = WSAIoctl(sock, SO_TLS_SET_CLIENT, &sWS2Opts, + sizeof(struct tlsclientopts), NULL, 0, NULL, + NULL, NULL); + + /* make sure that it was successfull */ + if(SOCKET_ERROR == rcode ){ + ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, + "Error: %d with ioctl (SO_TLS_SET_CLIENT)", WSAGetLastError()); + } + return rcode; +} + +int SSLize_Socket(SOCKET socketHnd, char *key, request_rec *r) +{ + int rcode; + struct tlsserveropts sWS2Opts; + struct nwtlsopts sNWTLSOpts; + unicode_t SASKey[512]; + unsigned long ulFlag; + + memset((char *)&sWS2Opts, 0, sizeof(struct tlsserveropts)); + memset((char *)&sNWTLSOpts, 0, sizeof(struct nwtlsopts)); + + + ulFlag = SO_TLS_ENABLE; + rcode = WSAIoctl(socketHnd, SO_TLS_SET_FLAGS, &ulFlag, sizeof(unsigned long), NULL, 0, NULL, NULL, NULL); + if(rcode) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error: %d with WSAIoctl(SO_TLS_SET_FLAGS, SO_TLS_ENABLE)", WSAGetLastError()); + goto ERR; + } + + + ulFlag = SO_TLS_SERVER; + rcode = WSAIoctl(socketHnd, SO_TLS_SET_FLAGS, &ulFlag, sizeof(unsigned long),NULL, 0, NULL, NULL, NULL); + + if(rcode) + { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error: %d with WSAIoctl(SO_TLS_SET_FLAGS, SO_TLS_SERVER)", WSAGetLastError()); + goto ERR; + } + + loc2uni(UNI_LOCAL_DEFAULT, SASKey, key, 0, 0); + + //setup the tlsserveropts struct + sWS2Opts.wallet = SASKey; + sWS2Opts.walletlen = unilen(SASKey); + sWS2Opts.sidtimeout = 0; + sWS2Opts.sidentries = 0; + sWS2Opts.siddir = NULL; + sWS2Opts.options = &sNWTLSOpts; + + //setup the nwtlsopts structure + + sNWTLSOpts.walletProvider = WAL_PROV_KMO; + sNWTLSOpts.keysList = NULL; + sNWTLSOpts.numElementsInKeyList = 0; + sNWTLSOpts.reservedforfutureuse = NULL; + sNWTLSOpts.reservedforfutureCRL = NULL; + sNWTLSOpts.reservedforfutureCRLLen = 0; + sNWTLSOpts.reserved1 = NULL; + sNWTLSOpts.reserved2 = NULL; + sNWTLSOpts.reserved3 = NULL; + + + rcode = WSAIoctl(socketHnd, + SO_TLS_SET_SERVER, + &sWS2Opts, + sizeof(struct tlsserveropts), + NULL, + 0, + NULL, + NULL, + NULL); + if(SOCKET_ERROR == rcode) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Error: %d with WSAIoctl(SO_TLS_SET_SERVER)", WSAGetLastError()); + goto ERR; + } + +ERR: + return rcode; +} + +static const char *set_secure_listener(cmd_parms *cmd, void *dummy, + const char *ips, const char* key, + const char* mutual) +{ + NWSSLSrvConfigRec* sc = get_nwssl_cfg(cmd->server); + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + char *ports, *addr; + unsigned short port; + seclisten_rec *new; + + + if (err != NULL) + return err; + + ports = strchr(ips, ':'); + + if (ports != NULL) { + if (ports == ips) + return "Missing IP address"; + else if (ports[1] == '\0') + return "Address must end in :<port-number>"; + + *(ports++) = '\0'; + } + else { + ports = (char*)ips; + } + + new = apr_pcalloc(cmd->pool, sizeof(seclisten_rec)); + new->local_addr.sin_family = AF_INET; + + if (ports == ips) { + new->local_addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr = apr_pstrdup(cmd->pool, "0.0.0.0"); + } + else { + new->local_addr.sin_addr.s_addr = parse_addr(ips, NULL); + addr = apr_pstrdup(cmd->pool, ips); + } + + port = atoi(ports); + + if (!port) + return "Port must be numeric"; + + apr_table_add(sc->sltable, ports, addr); + + new->local_addr.sin_port = htons(port); + new->fd = -1; + new->used = 0; + new->next = ap_seclisteners; + strcpy(new->key, key); + new->mutual = (mutual) ? 1 : 0; + new->addr = addr; + new->port = port; + ap_seclisteners = new; + return NULL; +} + +static const char *set_secure_upgradeable_listener(cmd_parms *cmd, void *dummy, + const char *ips, const char* key) +{ + NWSSLSrvConfigRec* sc = get_nwssl_cfg(cmd->server); + seclistenup_rec *listen_node; + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + char *ports, *addr; + unsigned short port; + seclistenup_rec *new; + + if (err != NULL) + return err; + + ports = strchr(ips, ':'); + + if (ports != NULL) { + if (ports == ips) + return "Missing IP address"; + else if (ports[1] == '\0') + return "Address must end in :<port-number>"; + + *(ports++) = '\0'; + } + else { + ports = (char*)ips; + } + + if (ports == ips) { + addr = apr_pstrdup(cmd->pool, "0.0.0.0"); + } + else { + addr = apr_pstrdup(cmd->pool, ips); + } + + port = atoi(ports); + + if (!port) + return "Port must be numeric"; + + apr_table_set(sc->slutable, ports, addr); + + new = apr_pcalloc(cmd->pool, sizeof(seclistenup_rec)); + new->next = ap_seclistenersup; + strcpy(new->key, key); + new->addr = addr; + new->port = port; + ap_seclistenersup = new; + + return err; +} + +static apr_status_t nwssl_socket_cleanup(void *data) +{ + ap_listen_rec* slr = (ap_listen_rec*)data; + ap_listen_rec* lr; + + /* Remove our secure listener from the listener list */ + for (lr = ap_listeners; lr; lr = lr->next) { + /* slr is at the head of the list */ + if (lr == slr) { + ap_listeners = slr->next; + break; + } + /* slr is somewhere in between or at the end*/ + if (lr->next == slr) { + lr->next = slr->next; + break; + } + } + return APR_SUCCESS; +} + +static const char *set_trusted_certs(cmd_parms *cmd, void *dummy, char *arg) +{ + char **ptr = (char **)apr_array_push(certlist); + + *ptr = apr_pstrdup(cmd->pool, arg); + return NULL; +} + +static int nwssl_pre_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp) +{ + ap_seclisteners = NULL; + ap_seclistenersup = NULL; + certlist = apr_array_make(pconf, 1, sizeof(char *)); + + return OK; +} + +static int nwssl_pre_connection(conn_rec *c, void *csd) +{ + + if (apr_table_get(c->notes, "nwconv-ssl")) { + convert_secure_socket(c, (apr_socket_t*)csd); + } + else { + secsocket_data *csd_data = apr_palloc(c->pool, sizeof(secsocket_data)); + + csd_data->csd = (apr_socket_t*)csd; + csd_data->is_secure = 0; + ap_set_module_config(c->conn_config, &nwssl_module, (void*)csd_data); + } + + return OK; +} + +static int nwssl_post_config(apr_pool_t *pconf, apr_pool_t *plog, + apr_pool_t *ptemp, server_rec *s) +{ + seclisten_rec* sl; + ap_listen_rec* lr; + apr_socket_t* sd; + apr_status_t status; + seclistenup_rec *slu; + int found; + + for (sl = ap_seclisteners; sl != NULL; sl = sl->next) { + sl->fd = find_secure_listener(sl); + + if (sl->fd < 0) + sl->fd = make_secure_socket(pconf, &sl->local_addr, sl->key, sl->mutual, s); + + if (sl->fd >= 0) { + apr_os_sock_info_t sock_info; + + sock_info.os_sock = &(sl->fd); + sock_info.local = (struct sockaddr*)&(sl->local_addr); + sock_info.remote = NULL; + sock_info.family = APR_INET; + sock_info.type = SOCK_STREAM; + + apr_os_sock_make(&sd, &sock_info, pconf); + + lr = apr_pcalloc(pconf, sizeof(ap_listen_rec)); + + if (lr) { + lr->sd = sd; + if ((status = apr_sockaddr_info_get(&lr->bind_addr, sl->addr, APR_UNSPEC, sl->port, 0, + pconf)) != APR_SUCCESS) { + ap_log_perror(APLOG_MARK, APLOG_CRIT, status, pconf, + "alloc_listener: failed to set up sockaddr for %s:%d", sl->addr, sl->port); + return HTTP_INTERNAL_SERVER_ERROR; + } + lr->next = ap_listeners; + ap_listeners = lr; + apr_pool_cleanup_register(pconf, lr, nwssl_socket_cleanup, apr_pool_cleanup_null); + } + } else { + return HTTP_INTERNAL_SERVER_ERROR; + } + } + + for (slu = ap_seclistenersup; slu; slu = slu->next) { + /* Check the listener list for a matching upgradeable listener */ + found = 0; + for (lr = ap_listeners; lr; lr = lr->next) { + if (slu->port == lr->bind_addr->port) { + found = 1; + break; + } + } + if (!found) { + ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, plog, + "No Listen directive found for upgradeable listener %s:%d", slu->addr, slu->port); + } + } + + build_cert_list(pconf); + + return OK; +} + +static void *nwssl_config_server_create(apr_pool_t *p, server_rec *s) +{ + NWSSLSrvConfigRec *new = apr_palloc(p, sizeof(NWSSLSrvConfigRec)); + new->sltable = apr_table_make(p, 5); + new->slutable = apr_table_make(p, 5); + return new; +} + +static void *nwssl_config_server_merge(apr_pool_t *p, void *basev, void *addv) +{ + NWSSLSrvConfigRec *base = (NWSSLSrvConfigRec *)basev; + NWSSLSrvConfigRec *add = (NWSSLSrvConfigRec *)addv; + NWSSLSrvConfigRec *merged = (NWSSLSrvConfigRec *)apr_palloc(p, sizeof(NWSSLSrvConfigRec)); + return merged; +} + +static int compare_ipports(void *rec, const char *key, const char *value) +{ + conn_rec *c = (conn_rec*)rec; + + if (value && + ((strcmp(value, "0.0.0.0") == 0) || (strcmp(value, c->local_ip) == 0))) + { + return 0; + } + return 1; +} + +static int isSecureConnEx (const server_rec *s, const conn_rec *c, const apr_table_t *t) +{ + char port[8]; + + itoa((c->local_addr)->port, port, 10); + if (!apr_table_do(compare_ipports, (void*)c, t, port, NULL)) + { + return 1; + } + + return 0; +} + +static int isSecureConn (const server_rec *s, const conn_rec *c) +{ + NWSSLSrvConfigRec *sc = get_nwssl_cfg(s); + + return isSecureConnEx (s, c, sc->sltable); +} + +static int isSecureConnUpgradeable (const server_rec *s, const conn_rec *c) +{ + NWSSLSrvConfigRec *sc = get_nwssl_cfg(s); + + return isSecureConnEx (s, c, sc->slutable); +} + +static int isSecure (const request_rec *r) +{ + return isSecureConn (r->server, r->connection); +} + +static int isSecureUpgradeable (const request_rec *r) +{ + return isSecureConnUpgradeable (r->server, r->connection); +} + +static int isSecureUpgraded (const request_rec *r) +{ + secsocket_data *csd_data = (secsocket_data*)ap_get_module_config(r->connection->conn_config, &nwssl_module); + + return csd_data->is_secure; +} + +static int nwssl_hook_Fixup(request_rec *r) +{ + int i; + + if (!isSecure(r) && !isSecureUpgraded(r)) + return DECLINED; + + apr_table_set(r->subprocess_env, "HTTPS", "on"); + + return DECLINED; +} + +static const char *nwssl_hook_http_method (const request_rec *r) +{ + if (isSecure(r) && !isSecureUpgraded(r)) + return "https"; + + return NULL; +} + +static apr_port_t nwssl_hook_default_port(const request_rec *r) +{ + if (isSecure(r)) + return DEFAULT_HTTPS_PORT; + + return 0; +} + +int ssl_proxy_enable(conn_rec *c) +{ + apr_table_set(c->notes, "nwconv-ssl", "Y"); + + return 1; +} + +int ssl_engine_disable(conn_rec *c) +{ + return 1; +} + +static int ssl_is_https(conn_rec *c) +{ + secsocket_data *csd_data = (secsocket_data*)ap_get_module_config(c->conn_config, &nwssl_module); + + return isSecureConn (c->base_server, c) || (csd_data && csd_data->is_secure); +} + +/* 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 (strcEQ(var, "HTTPS")) { + if (isSecure(r) || isSecureUpgraded(r)) + result = "on"; + else + result = "off"; + } + 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; + } + + /* + * 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 apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f, + apr_bucket_brigade *bb) + +{ +#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols" +#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1" +#define CONNECTION_HEADER "Connection: Upgrade" + const char *upgrade; + const char *connection; + apr_bucket_brigade *upgradebb; + request_rec *r = f->r; + apr_socket_t *csd = NULL; + char *key; + unicode_t keyFileName[512]; + int ret; + char *token_string; + char *token; + char *token_state; + secsocket_data *csd_data; + + /* Just remove the filter, if it doesn't work the first time, it won't + * work at all for this request. + */ + ap_remove_output_filter(f); + + /* No need to ensure that this is a server with optional SSL, the filter + * is only inserted if that is true. + */ + + upgrade = apr_table_get(r->headers_in, "Upgrade"); + if (upgrade == NULL) { + return ap_pass_brigade(f->next, bb); + } + token_string = apr_pstrdup(r->pool,upgrade); + token = apr_strtok(token_string,", ",&token_state); + while (token && strcmp(token,"TLS/1.0")) { + apr_strtok(NULL,", ",&token_state); + } + // "Upgrade: TLS/1.0" header not found, don't do Upgrade + if (!token) { + return ap_pass_brigade(f->next, bb); + } + + connection = apr_table_get(r->headers_in, "Connection"); + token_string = apr_pstrdup(r->pool,connection); + token = apr_strtok(token_string,",",&token_state); + while (token && strcmp(token,"Upgrade")) { + apr_strtok(NULL,",",&token_state); + } + // "Connection: Upgrade" header not found, don't do Upgrade + if (!token) { + return ap_pass_brigade(f->next, bb); + } + + apr_table_unset(r->headers_out, "Upgrade"); + + if (r) { + csd_data = (secsocket_data*)ap_get_module_config(r->connection->conn_config, &nwssl_module); + csd = csd_data->csd; + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Unable to get upgradeable socket handle"); + return ap_pass_brigade(f->next, bb); + } + + + if (r->method_number == M_OPTIONS) { + apr_bucket *b = NULL; + /* This is a mandatory SSL upgrade. */ + + upgradebb = apr_brigade_create(r->pool, f->c->bucket_alloc); + + ap_fputstrs(f->next, upgradebb, SWITCH_STATUS_LINE, CRLF, + UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL); + + b = apr_bucket_flush_create(f->c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(upgradebb, b); + ap_pass_brigade(f->next, upgradebb); + } + else { + /* This is optional, and should be configurable, for now don't bother + * doing anything. + */ + return ap_pass_brigade(f->next, bb); + } + + key = get_port_key(r->connection); + + if (csd && key) { + int sockdes; + apr_os_sock_get(&sockdes, csd); + + + ret = SSLize_Socket(sockdes, key, r); + if (!ret) { + csd_data->is_secure = 1; + } + } + else { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, + "Upgradeable socket handle not found"); + return ap_pass_brigade(f->next, bb); + } + + ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server, + "Awaiting re-negotiation handshake"); + + return ap_pass_brigade(f->next, bb); +} + +static void ssl_hook_Insert_Filter(request_rec *r) +{ + NWSSLSrvConfigRec *sc = get_nwssl_cfg(r->server); + + if (isSecureUpgradeable (r)) { + ap_add_output_filter("UPGRADE_FILTER", NULL, r, r->connection); + } +} + +static const command_rec nwssl_module_cmds[] = +{ + AP_INIT_TAKE23("SecureListen", set_secure_listener, NULL, RSRC_CONF, + "specify an address and/or port with a key pair name.\n" + "Optional third parameter of MUTUAL configures the port for mutual authentication."), + AP_INIT_TAKE2("NWSSLUpgradeable", set_secure_upgradeable_listener, NULL, RSRC_CONF, + "specify an address and/or port with a key pair name, that can be upgraded to an SSL connection.\n" + "The address and/or port must have already be defined using a Listen directive."), + AP_INIT_ITERATE("NWSSLTrustedCerts", set_trusted_certs, NULL, RSRC_CONF, + "Adds trusted certificates that are used to create secure connections to proxied servers"), + {NULL} +}; + +static void register_hooks(apr_pool_t *p) +{ + ap_register_output_filter ("UPGRADE_FILTER", ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5); + + ap_hook_pre_config(nwssl_pre_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_pre_connection(nwssl_pre_connection, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_post_config(nwssl_post_config, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_fixups(nwssl_hook_Fixup, NULL, NULL, APR_HOOK_MIDDLE); + 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); + ap_hook_insert_filter (ssl_hook_Insert_Filter, 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); +} + +module AP_MODULE_DECLARE_DATA nwssl_module = +{ + STANDARD20_MODULE_STUFF, + NULL, /* dir config creater */ + NULL, /* dir merger --- default is to override */ + nwssl_config_server_create, /* server config */ + nwssl_config_server_merge, /* merge server config */ + nwssl_module_cmds, /* command apr_table_t */ + register_hooks +}; + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy.def new file mode 100644 index 00000000..ab02a53c --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy.def @@ -0,0 +1,6 @@ +EXPORT proxy_module +EXPORT proxy_hook_scheme_handler +EXPORT proxy_hook_canon_handler +EXPORT ap_proxy_ssl_enable +EXPORT ap_proxy_ssl_disable +EXPORT proxy_run_fixups diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_connect.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_connect.def new file mode 100644 index 00000000..13611140 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_connect.def @@ -0,0 +1,4 @@ +EXPORT proxy_connect_module +IMPORT proxy_module +IMPORT proxy_hook_scheme_handler +IMPORT proxy_hook_canon_handler diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_ftp.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_ftp.def new file mode 100644 index 00000000..f2dba7d6 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_ftp.def @@ -0,0 +1,4 @@ +EXPORT proxy_ftp_module +IMPORT proxy_module +IMPORT proxy_hook_scheme_handler +IMPORT proxy_hook_canon_handler diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_http.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_http.def new file mode 100644 index 00000000..b24358b1 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_proxy_http.def @@ -0,0 +1,7 @@ +EXPORT proxy_http_module +IMPORT proxy_module +IMPORT proxy_hook_scheme_handler +IMPORT proxy_run_fixups +IMPORT proxy_hook_canon_handler +IMPORT ap_proxy_ssl_enable +IMPORT ap_proxy_ssl_disable diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_rewrite.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_rewrite.def new file mode 100644 index 00000000..cfdcf6b1 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_rewrite.def @@ -0,0 +1 @@ +EXPORT rewrite_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_speling.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_speling.def new file mode 100644 index 00000000..3d45a6aa --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_speling.def @@ -0,0 +1 @@ +EXPORT speling_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_status.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_status.def new file mode 100644 index 00000000..9a5a32d4 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_status.def @@ -0,0 +1,2 @@ +EXPORT status_module + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_unique_id.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_unique_id.def new file mode 100644 index 00000000..0b72c1ec --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_unique_id.def @@ -0,0 +1 @@ +EXPORT unique_id_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_usertrack.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_usertrack.def new file mode 100644 index 00000000..7264c41e --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_usertrack.def @@ -0,0 +1 @@ +EXPORT usertrack_module diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_vhost_alias.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_vhost_alias.def new file mode 100644 index 00000000..574b85f9 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/mod_vhost_alias.def @@ -0,0 +1,2 @@ +EXPORT vhost_alias_module + diff --git a/rubbos/app/httpd-2.0.64/modules/arch/netware/moddavfs.def b/rubbos/app/httpd-2.0.64/modules/arch/netware/moddavfs.def new file mode 100644 index 00000000..67ec3117 --- /dev/null +++ b/rubbos/app/httpd-2.0.64/modules/arch/netware/moddavfs.def @@ -0,0 +1 @@ +EXPORT dav_fs_module |