forked from pool/apache2-mod_nss
156 lines
4.9 KiB
Diff
156 lines
4.9 KiB
Diff
|
diff -rNU 30 ../mod_nss-1.0.8-o/nss_engine_kernel.c ./nss_engine_kernel.c
|
||
|
--- ../mod_nss-1.0.8-o/nss_engine_kernel.c 2014-06-25 19:13:26.000000000 +0200
|
||
|
+++ ./nss_engine_kernel.c 2014-06-27 13:57:40.000000000 +0200
|
||
|
@@ -1,102 +1,151 @@
|
||
|
/* Copyright 2001-2004 The Apache Software Foundation
|
||
|
*
|
||
|
* Licensed 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 "mod_nss.h"
|
||
|
#include "secerr.h"
|
||
|
|
||
|
static void HandshakeDone(PRFileDesc *fd, void *doneflag);
|
||
|
|
||
|
+extern void * sni_callback_arg;
|
||
|
+
|
||
|
/*
|
||
|
* Post Read Request Handler
|
||
|
*/
|
||
|
int nss_hook_ReadReq(request_rec *r)
|
||
|
{
|
||
|
SSLConnRec *sslconn = myConnConfig(r->connection);
|
||
|
PRFileDesc *ssl = sslconn ? sslconn->ssl : NULL;
|
||
|
|
||
|
if (!sslconn) {
|
||
|
return DECLINED;
|
||
|
}
|
||
|
|
||
|
if (sslconn->non_nss_request) {
|
||
|
const char *errmsg;
|
||
|
char *thisurl;
|
||
|
char *thisport = "";
|
||
|
int port = ap_get_server_port(r);
|
||
|
|
||
|
if (!ap_is_default_port(port, r)) {
|
||
|
thisport = apr_psprintf(r->pool, ":%u", port);
|
||
|
}
|
||
|
|
||
|
thisurl = ap_escape_html(r->pool,
|
||
|
apr_psprintf(r->pool, "https://%s%s/",
|
||
|
ap_get_server_name(r),
|
||
|
thisport));
|
||
|
|
||
|
errmsg = apr_psprintf(r->pool,
|
||
|
"Reason: You're speaking plain HTTP "
|
||
|
"to an SSL-enabled server port.<br />\n"
|
||
|
"Instead use the HTTPS scheme to access "
|
||
|
"this URL, please.<br />\n"
|
||
|
"<blockquote>Hint: "
|
||
|
"<a href=\"%s\"><b>%s</b></a></blockquote>",
|
||
|
thisurl, thisurl);
|
||
|
|
||
|
apr_table_setn(r->notes, "error-notes", errmsg);
|
||
|
/* Now that we have caught this error, forget it. we are done
|
||
|
* with using SSL on this request.
|
||
|
*/
|
||
|
sslconn->non_nss_request = 0;
|
||
|
|
||
|
|
||
|
return HTTP_BAD_REQUEST;
|
||
|
}
|
||
|
|
||
|
/* Get the SSL connection structure and perform the
|
||
|
* delayed interlinking from SSL back to request_rec
|
||
|
*/
|
||
|
if (!ssl) {
|
||
|
return DECLINED;
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+ /*
|
||
|
+ * SNI.
|
||
|
+ *
|
||
|
+ * global pool-allocated char * sni_callback_arg contains SNI name
|
||
|
+ * coming from mod_nss_SSLSNISocketConfig() callback by nss as soon as
|
||
|
+ * SNI extension information was supplied by the client.
|
||
|
+ *
|
||
|
+ * With the SNI provided servername, this is now widely analogous
|
||
|
+ * to mod_ssl; the same checks apply.
|
||
|
+ *
|
||
|
+ */
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
+ char *servername;
|
||
|
+ servername = (char *) sni_callback_arg;
|
||
|
+
|
||
|
+ if(servername[0] != '\0') {
|
||
|
+ char *host, *scope_id;
|
||
|
+ apr_port_t port;
|
||
|
+ apr_status_t rv;
|
||
|
+
|
||
|
+ if (!r->hostname) {
|
||
|
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
|
||
|
+ "Hostname %s provided via SNI, but no hostname"
|
||
|
+ " provided in HTTP request", servername);
|
||
|
+ return HTTP_BAD_REQUEST;
|
||
|
+ }
|
||
|
+
|
||
|
+ rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
|
||
|
+ if (rv != APR_SUCCESS || scope_id) {
|
||
|
+ return HTTP_BAD_REQUEST;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (strcasecmp(host, servername)) {
|
||
|
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
|
||
|
+ "Hostname %s provided via SNI and hostname %s provided"
|
||
|
+ " via HTTP are different", servername, host);
|
||
|
+ return HTTP_BAD_REQUEST;
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+ }
|
||
|
+
|
||
|
+
|
||
|
+
|
||
|
/*
|
||
|
* Log information about incoming HTTPS requests
|
||
|
*/
|
||
|
if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) {
|
||
|
ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
|
||
|
"%s HTTPS request received for child %ld (server %s)",
|
||
|
(r->connection->keepalives <= 0 ?
|
||
|
"Initial (No.1)" :
|
||
|
apr_psprintf(r->pool, "Subsequent (No.%d)",
|
||
|
r->connection->keepalives+1)),
|
||
|
r->connection->id,
|
||
|
nss_util_vhostid(r->pool, r->server));
|
||
|
}
|
||
|
|
||
|
if (sslconn->client_cert != NULL)
|
||
|
CERT_DestroyCertificate(sslconn->client_cert);
|
||
|
sslconn->client_cert = SSL_PeerCertificate(ssl);
|
||
|
sslconn->client_dn = NULL;
|
||
|
|
||
|
return DECLINED;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Access Handler
|
||
|
*/
|
||
|
int nss_hook_Access(request_rec *r)
|
||
|
{
|
||
|
SSLDirConfigRec *dc = myDirConfig(r);
|
||
|
SSLSrvConfigRec *sc = mySrvConfig(r->server);
|
||
|
SSLConnRec *sslconn = myConnConfig(r->connection);
|