📄 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 + -