File mod_nss-SNI-checks.patch of Package apache2-mod_nss

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);