📄 mod_nw_ssl.c
字号:
}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};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -