summaryrefslogtreecommitdiffstats
path: root/mod_nss-reverseproxy.patch
blob: 928c92f150499e85640580be234e012f76fb441c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
mod_proxy now sets the requested remote host name. Use this to compare
to the CN value of the peer certificate and reject the request if they 
do not match (and we are have NSSProxyCheckPeerCN set to on).

diff -u --recursive mod_nss-1.0.8.orig/docs/mod_nss.html mod_nss-1.0.8/docs/mod_nss.html
--- mod_nss-1.0.8.orig/docs/mod_nss.html	2006-09-05 10:58:56.000000000 -0400
+++ mod_nss-1.0.8/docs/mod_nss.html	2010-05-13 11:25:42.000000000 -0400
@@ -1028,7 +1028,21 @@
 <br>
 <span style="font-weight: bold;">Example</span><br>
 <br>
-<code>NSSProxyNickname beta</code><br>
+<code>NSSProxyNickname beta<br>
+<br>
+</code><big><big>NSSProxyCheckPeerCN</big></big><br>
+<br>
+Compare the CN value of the peer certificate with the hostname being
+requested. If this is set to on, the default, then the request will
+fail if they do not match. If this is set to off then this comparison
+is not done. Note that this test is your only protection against a
+man-in-the-middle attack so leaving this as on is strongly recommended.<br>
+<br>
+<span style="font-weight: bold;">Example</span><br>
+<br>
+<span style="font-family: monospace;">NSSProcyCheckPeerCN</span><code>
+on<br>
+</code><br>
 <h1><a name="Environment"></a>Environment Variables</h1>
 Quite a few environment variables (for CGI and SSI) may be set
 depending on the NSSOptions configuration. It can be expensive to set
@@ -1435,42 +1449,9 @@
 <h1><a name="FAQ"></a>Frequently Asked Questions</h1>
 Q. Does mod_nss support mod_proxy?<br>
 <br>
-A. In order to use the mod_nss proxy support you will need to build
-your own mod_proxy by applying a patch found in bug <a
- href="http://issues.apache.org/bugzilla/show_bug.cgi?id=36468">36468</a>.
-The patch is needed so we can compare the hostname contained in the
-remote certificate with the hostname you meant to visit. This prevents
-man-in-the-middle attacks.<br>
-<br>
-You also have to change the SSL functions that mod_proxy looks to use.
-You'll need to apply this patch:<br>
-<br>
-<code>1038,1039c1038,1039<br>
-&lt; APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));<br>
-&lt; APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));<br>
----<br>
-&gt; APR_DECLARE_OPTIONAL_FN(int, nss_proxy_enable, (conn_rec *));<br>
-&gt; APR_DECLARE_OPTIONAL_FN(int, nss_engine_disable, (conn_rec *));<br>
-1041,1042c1041,1042<br>
-&lt; static APR_OPTIONAL_FN_TYPE(ssl_proxy_enable) *proxy_ssl_enable =
-NULL;<br>
-&lt; static APR_OPTIONAL_FN_TYPE(ssl_engine_disable) *proxy_ssl_disable
-= NULL;<br>
----<br>
-&gt; static APR_OPTIONAL_FN_TYPE(nss_proxy_enable) *proxy_ssl_enable =
-NULL;<br>
-&gt; static APR_OPTIONAL_FN_TYPE(nss_engine_disable) *proxy_ssl_disable
-= NULL;<br>
-1069,1070c1069,1070<br>
-&lt;&nbsp;&nbsp;&nbsp;&nbsp; proxy_ssl_enable =
-APR_RETRIEVE_OPTIONAL_FN(ssl_proxy_enable);<br>
-&lt;&nbsp;&nbsp;&nbsp;&nbsp; proxy_ssl_disable =
-APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);<br>
----<br>
-&gt;&nbsp;&nbsp;&nbsp;&nbsp; proxy_ssl_enable =
-APR_RETRIEVE_OPTIONAL_FN(nss_proxy_enable);<br>
-&gt;&nbsp;&nbsp;&nbsp;&nbsp; proxy_ssl_disable =
-APR_RETRIEVE_OPTIONAL_FN(nss_engine_disable);<br>
-</code><br>
+A. Yes but you need to make sure that mod_ssl is not loaded. mod_proxy
+provides a single interface for SSL providers and mod_nss defers to
+mod_ssl
+if it is loaded.
 </body>
 </html>
diff -u --recursive mod_nss-1.0.8.orig/mod_nss.c mod_nss-1.0.8/mod_nss.c
--- mod_nss-1.0.8.orig/mod_nss.c	2010-05-13 11:24:49.000000000 -0400
+++ mod_nss-1.0.8/mod_nss.c	2010-05-13 11:25:42.000000000 -0400
@@ -142,6 +142,8 @@
     SSL_CMD_SRV(ProxyNickname, TAKE1,
                "SSL Proxy: client certificate Nickname to be for proxy connections "
                "(`nickname')")
+    SSL_CMD_SRV(ProxyCheckPeerCN, FLAG,
+                "SSL Proxy: check the peers certificate CN")
 
 #ifdef IGNORE
     /* Deprecated directives. */
@@ -238,23 +240,30 @@
 SECStatus NSSBadCertHandler(void *arg, PRFileDesc * socket)
 {
     conn_rec *c = (conn_rec *)arg;
+    SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
     PRErrorCode err = PR_GetError();
     SECStatus rv = SECFailure;
     CERTCertificate *peerCert = SSL_PeerCertificate(socket);
+    const char *hostname_note;
                                                                                 
     switch (err) {
         case SSL_ERROR_BAD_CERT_DOMAIN:
-            if (c->remote_host != NULL) {
-                rv = CERT_VerifyCertName(peerCert, c->remote_host);
-                if (rv != SECSuccess) {
-                    char *remote = CERT_GetCommonName(&peerCert->subject);
+            if (sc->proxy_ssl_check_peer_cn == TRUE) {
+                if ((hostname_note = apr_table_get(c->notes, "proxy-request-hostname")) != NULL) {
+                    apr_table_unset(c->notes, "proxy-request-hostname");
+                    rv = CERT_VerifyCertName(peerCert, hostname_note);
+                    if (rv != SECSuccess) {
+                        char *remote = CERT_GetCommonName(&peerCert->subject);
+                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+                            "SSL Proxy: Possible man-in-the-middle attack. The remove server is %s, we expected %s", remote, hostname_note);
+                        PORT_Free(remote);
+                    }
+                } else {
                     ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
-                        "SSL Proxy: Possible man-in-the-middle attack. The remove server is %s, we expected %s", remote, c->remote_host);
-                    PORT_Free(remote);
+                        "SSL Proxy: I don't have the name of the host we're supposed to connect to so I can't verify that we are connecting to who we think we should be. Giving up.");
                 }
             } else {
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
-                    "SSL Proxy: I don't have the name of the host we're supposed to connect to so I can't verify that we are connecting to who we think we should be. Giving up. Hint: See Apache bug 36468.");
+                rv = SECSuccess;
             }
             break;
         default:
diff -u --recursive mod_nss-1.0.8.orig/mod_nss.h mod_nss-1.0.8/mod_nss.h
--- mod_nss-1.0.8.orig/mod_nss.h	2010-05-13 11:24:49.000000000 -0400
+++ mod_nss-1.0.8/mod_nss.h	2010-05-13 11:25:42.000000000 -0400
@@ -306,6 +306,7 @@
     int              vhost_id_len;
     modnss_ctx_t    *server;
     modnss_ctx_t    *proxy;
+    BOOL             proxy_ssl_check_peer_cn;
 };
 
 /*
@@ -410,6 +411,7 @@
 const char *nss_cmd_NSSProxyProtocol(cmd_parms *, void *, const char *);
 const char *nss_cmd_NSSProxyCipherSuite(cmd_parms *, void *, const char *);
 const char *nss_cmd_NSSProxyNickname(cmd_parms *cmd, void *dcfg, const char *arg);
+const char *nss_cmd_NSSProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
 
 /*  module initialization  */
 int  nss_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *);
diff -u --recursive mod_nss-1.0.8.orig/nss_engine_config.c mod_nss-1.0.8/nss_engine_config.c
--- mod_nss-1.0.8.orig/nss_engine_config.c	2010-05-13 11:24:49.000000000 -0400
+++ mod_nss-1.0.8/nss_engine_config.c	2010-05-13 11:25:42.000000000 -0400
@@ -140,6 +140,7 @@
     sc->vhost_id_len                = 0;     /* set during module init */
     sc->proxy                       = NULL;
     sc->server                      = NULL;
+    sc->proxy_ssl_check_peer_cn     = TRUE;
 
     modnss_ctx_init_proxy(sc, p);
 
@@ -214,6 +215,7 @@
     cfgMergeBool(fips);
     cfgMergeBool(enabled);
     cfgMergeBool(proxy_enabled);
+    cfgMergeBool(proxy_ssl_check_peer_cn);
 
     modnss_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
 
@@ -544,6 +546,15 @@
     return NULL;
 }
 
+const char *nss_cmd_NSSProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
+{
+    SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+    sc->proxy_ssl_check_peer_cn = flag ? TRUE : FALSE;
+
+    return NULL;
+}
+
 const char *nss_cmd_NSSEnforceValidCerts(cmd_parms *cmd,
                                          void *dcfg,
                                          int flag)