summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrcritten <>2010-05-13 15:21:25 +0000
committerrcritten <>2010-05-13 15:21:25 +0000
commit04119e74a69dc2b340373c4ae79d45615492a5b1 (patch)
tree0d18e3664be3adb51bb0e725afa6c7ab4b0985bb
parent00dd8c4916c32c986150e747326f5a5ee1c6ab04 (diff)
downloadmod_nss-04119e74a69dc2b340373c4ae79d45615492a5b1.tar.gz
mod_nss-04119e74a69dc2b340373c4ae79d45615492a5b1.tar.xz
mod_nss-04119e74a69dc2b340373c4ae79d45615492a5b1.zip
Compare CN value of remote host with requested host in reverse proxy.
Add configuration option to disable this, defaulting to on. 591224
-rw-r--r--TODO5
-rw-r--r--docs/mod_nss.html57
-rw-r--r--mod_nss.c25
-rw-r--r--mod_nss.h2
-rw-r--r--nss_engine_config.c11
5 files changed, 50 insertions, 50 deletions
diff --git a/TODO b/TODO
index ee1b8e0..824375d 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,2 @@
-- Offer to automatically generate a self-signed cert using gencert during
- install?
-- Should gencert create a database with an empty password or continue
- to create a protected on?
- Once NSS fully supports the SNI TLS extension, add that.
+- Add support for OCSP stapling
diff --git a/docs/mod_nss.html b/docs/mod_nss.html
index 75d6162..2bd4bd6 100644
--- a/docs/mod_nss.html
+++ b/docs/mod_nss.html
@@ -1028,7 +1028,21 @@ requests client authentication.<br>
<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 @@ authentication.
<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 --git a/mod_nss.c b/mod_nss.c
index 9337d30..7dfbc6f 100644
--- a/mod_nss.c
+++ b/mod_nss.c
@@ -142,6 +142,8 @@ static const command_rec nss_config_cmds[] = {
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 @@ int ssl_engine_disable(conn_rec *c) {
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 --git a/mod_nss.h b/mod_nss.h
index 3d69a44..30a3680 100644
--- a/mod_nss.h
+++ b/mod_nss.h
@@ -306,6 +306,7 @@ struct SSLSrvConfigRec {
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_NSSProxyEngine(cmd_parms *cmd, void *dcfg, int flag);
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 --git a/nss_engine_config.c b/nss_engine_config.c
index d6fd3c5..64ec447 100644
--- a/nss_engine_config.c
+++ b/nss_engine_config.c
@@ -140,6 +140,7 @@ static SSLSrvConfigRec *nss_config_server_new(apr_pool_t *p)
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 @@ void *nss_config_server_merge(apr_pool_t *p, void *basev, void *addv) {
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 @@ const char *nss_cmd_NSSProxyNickname(cmd_parms *cmd,
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)