forked from pool/apache2-mod_nss
ce9f02cd08
- mod_nss-bnc863518-reopen_dev_tty.diff: close(0) and open("/dev/tty", ...) to make sure that stdin can be read from. startproc may inherit wrongly opened file descriptors to httpd. (Note: An analogous fix exists in startproc(8), too.) [bnc#863518] - VirtualHost part in /etc/apache2/conf.d/mod_nss.conf is now externalized to /etc/apache2/conf.d/vhost-nss.template and not activated/read by default. [bnc#878681] - NSSCipherSuite update following additional ciphers of Feb 18 change. [bnc#878681] - mod_nss-SNI-callback.patch, mod_nss-SNI-checks.patch: server side SNI was not implemented when mod_nss was made; patches implement SNI with checks if SNI provided hostname equals Host: field in http request header. OBS-URL: https://build.opensuse.org/request/show/242385 OBS-URL: https://build.opensuse.org/package/show/mozilla:Factory/apache2-mod_nss?expand=0&rev=10
242 lines
8.7 KiB
Diff
242 lines
8.7 KiB
Diff
diff -rNU 30 ../mod_nss-1.0.8-o/mod_nss.h ./mod_nss.h
|
|
--- ../mod_nss-1.0.8-o/mod_nss.h 2014-06-23 12:23:17.000000000 +0200
|
|
+++ ./mod_nss.h 2014-06-25 15:43:14.000000000 +0200
|
|
@@ -459,31 +459,37 @@
|
|
APR_DECLARE_OPTIONAL_FN(int, nss_engine_disable, (conn_rec *));
|
|
|
|
/* I/O */
|
|
PRFileDesc * nss_io_new_fd();
|
|
int nss_io_layer_init();
|
|
void nss_io_filter_init(conn_rec *c, PRFileDesc *ssl);
|
|
void nss_io_filter_register(apr_pool_t *p);
|
|
|
|
/* Utility Functions */
|
|
char *nss_util_vhostid(apr_pool_t *, server_rec *);
|
|
apr_file_t *nss_util_ppopen(server_rec *, apr_pool_t *, const char *,
|
|
const char * const *);
|
|
void nss_util_ppclose(server_rec *, apr_pool_t *, apr_file_t *);
|
|
char *nss_util_readfilter(server_rec *, apr_pool_t *, const char *,
|
|
const char * const *);
|
|
/* ssl_io_buffer_fill fills the setaside buffering of the HTTP request
|
|
* to allow an SSL renegotiation to take place. */
|
|
int nss_io_buffer_fill(request_rec *r);
|
|
|
|
int nss_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix);
|
|
|
|
/* Pass Phrase Handling */
|
|
SECStatus nss_Init_Tokens(server_rec *s);
|
|
|
|
/* Logging */
|
|
void nss_log_nss_error(const char *file, int line, int level, server_rec *s);
|
|
void nss_die(void);
|
|
|
|
/* NSS callback */
|
|
SECStatus nss_AuthCertificate(void *arg, PRFileDesc *socket, PRBool checksig, PRBool isServer);
|
|
+
|
|
+
|
|
+#define SNIMAXNAMELEN 100
|
|
+PRInt32 mod_nss_SSLSNISocketConfig(PRFileDesc *, const SECItem *, PRUint32, void *);
|
|
+
|
|
+
|
|
#endif /* __MOD_NSS_H__ */
|
|
diff -rNU 30 ../mod_nss-1.0.8-o/nss_engine_init.c ./nss_engine_init.c
|
|
--- ../mod_nss-1.0.8-o/nss_engine_init.c 2014-06-23 12:23:17.000000000 +0200
|
|
+++ ./nss_engine_init.c 2014-06-25 18:33:19.000000000 +0200
|
|
@@ -5,60 +5,62 @@
|
|
* 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 "apr_thread_proc.h"
|
|
#include "ap_mpm.h"
|
|
#include "secmod.h"
|
|
#include "sslerr.h"
|
|
#include "pk11func.h"
|
|
#include "ocsp.h"
|
|
#include "keyhi.h"
|
|
#include "cert.h"
|
|
|
|
static SECStatus ownBadCertHandler(void *arg, PRFileDesc * socket);
|
|
static SECStatus ownHandshakeCallback(PRFileDesc * socket, void *arg);
|
|
static SECStatus NSSHandshakeCallback(PRFileDesc *socket, void *arg);
|
|
static CERTCertificate* FindServerCertFromNickname(const char* name, const CERTCertList* clist);
|
|
SECStatus nss_AuthCertificate(void *arg, PRFileDesc *socket, PRBool checksig, PRBool isServer);
|
|
|
|
/*
|
|
* Global variables defined in this file.
|
|
*/
|
|
+void * sni_callback_arg;
|
|
+
|
|
char* INTERNAL_TOKEN_NAME = "internal ";
|
|
|
|
cipher_properties ciphers_def[ciphernum] =
|
|
{
|
|
/* SSL2 cipher suites */
|
|
{"rc4", SSL_EN_RC4_128_WITH_MD5, 0, SSL2},
|
|
{"rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5, 0, SSL2},
|
|
{"rc2", SSL_EN_RC2_128_CBC_WITH_MD5, 0, SSL2},
|
|
{"rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, 0, SSL2},
|
|
{"des", SSL_EN_DES_64_CBC_WITH_MD5, 0, SSL2},
|
|
{"desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5, 0, SSL2},
|
|
/* SSL3/TLS cipher suites */
|
|
{"rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5, 0, SSL3 | TLS},
|
|
{"rsa_rc4_128_sha", SSL_RSA_WITH_RC4_128_SHA, 0, SSL3 | TLS},
|
|
{"rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA, 0, SSL3 | TLS},
|
|
{"rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA, 0, SSL3 | TLS},
|
|
{"rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5, 0, SSL3 | TLS},
|
|
{"rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 0, SSL3 | TLS},
|
|
{"rsa_null_md5", SSL_RSA_WITH_NULL_MD5, 0, SSL3 | TLS},
|
|
{"rsa_null_sha", SSL_RSA_WITH_NULL_SHA, 0, SSL3 | TLS},
|
|
{"fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, 0, SSL3 | TLS},
|
|
{"fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA, 0, SSL3 | TLS},
|
|
{"fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, 1, SSL3 | TLS},
|
|
{"fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, 1, SSL3 | TLS},
|
|
{"fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA, 1, SSL3 | TLS},
|
|
/* TLS 1.0: Exportable 56-bit Cipher Suites. */
|
|
{"rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, 0, SSL3 | TLS},
|
|
{"rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, 0, SSL3 | TLS},
|
|
/* AES ciphers.*/
|
|
{"rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA, 0, SSL3 | TLS},
|
|
@@ -850,60 +852,78 @@
|
|
|
|
static void nss_init_ctx_callbacks(server_rec *s,
|
|
apr_pool_t *p,
|
|
apr_pool_t *ptemp,
|
|
modnss_ctx_t *mctx)
|
|
{
|
|
if (SSL_AuthCertificateHook(mctx->model, nss_AuthCertificate, (void *)CERT_GetDefaultCertDB()) != SECSuccess) {
|
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
|
"SSL_AuthCertificateHook failed.");
|
|
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
|
|
nss_die();
|
|
}
|
|
if (SSL_BadCertHook(mctx->model, (SSLBadCertHandler) ownBadCertHandler, NULL) != SECSuccess) {
|
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
|
"SSL_BadCertHook failed");
|
|
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
|
|
nss_die();
|
|
}
|
|
if (SSL_HandshakeCallback(mctx->model, (SSLHandshakeCallback) ownHandshakeCallback, NULL) != SECSuccess) {
|
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
|
"SSL_HandshakeCallback failed");
|
|
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
|
|
nss_die();
|
|
}
|
|
if (SSL_GetClientAuthDataHook(mctx->model, NSS_GetClientAuthData, (void *)mctx->nickname) != SECSuccess) {
|
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
|
"SSL_GetClientAuthDataHook failed");
|
|
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
|
|
nss_die();
|
|
}
|
|
+
|
|
+ sni_callback_arg = apr_pcalloc(p, SNIMAXNAMELEN + 1);
|
|
+ if(sni_callback_arg) {
|
|
+ if(SSL_SNISocketConfigHook(mctx->model, mod_nss_SSLSNISocketConfig,
|
|
+ sni_callback_arg)) {
|
|
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
|
+ "SSL_SNISocketConfigHook failed");
|
|
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
|
|
+ nss_die();
|
|
+ }
|
|
+ } else {
|
|
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
|
+ "apr_palloc returned NULL for sni_callback_arg");
|
|
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
|
|
+ nss_die();
|
|
+ }
|
|
+
|
|
+
|
|
}
|
|
|
|
static void nss_init_ctx_verify(server_rec *s,
|
|
apr_pool_t *p,
|
|
apr_pool_t *ptemp,
|
|
modnss_ctx_t *mctx)
|
|
{
|
|
if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
|
|
SSL_OptionSet(mctx->model, SSL_REQUEST_CERTIFICATE, PR_TRUE);
|
|
SSL_OptionSet(mctx->model, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_ALWAYS);
|
|
} else if (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) {
|
|
SSL_OptionSet(mctx->model, SSL_REQUEST_CERTIFICATE, PR_TRUE);
|
|
SSL_OptionSet(mctx->model, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER);
|
|
} else {
|
|
SSL_OptionSet(mctx->model, SSL_REQUEST_CERTIFICATE, PR_FALSE);
|
|
SSL_OptionSet(mctx->model, SSL_REQUIRE_CERTIFICATE, SSL_REQUIRE_NEVER);
|
|
}
|
|
}
|
|
|
|
static int countciphers(PRBool cipher_state[ciphernum], int version) {
|
|
int ciphercount = 0;
|
|
int i;
|
|
|
|
for (i = 0; i < ciphernum; i++)
|
|
{
|
|
if ((cipher_state[i] == PR_TRUE) &&
|
|
(ciphers_def[i].version & version)) {
|
|
ciphercount++;
|
|
}
|
|
}
|
|
@@ -1702,30 +1722,54 @@
|
|
return -1;
|
|
}
|
|
|
|
if ((ciphers = strchr(cipher, ','))) {
|
|
*ciphers++ = '\0';
|
|
}
|
|
|
|
found = PR_FALSE;
|
|
|
|
for (i = 0; i < ciphernum; i++)
|
|
{
|
|
if (!strcasecmp(cipher, ciphers_def[i].name)) {
|
|
cipher_list[i] = active;
|
|
found = PR_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found == PR_FALSE) {
|
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
|
"Unknown cipher %s", cipher);
|
|
}
|
|
|
|
if (ciphers) {
|
|
cipher = ciphers;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
+
|
|
+
|
|
+
|
|
+
|
|
+PRInt32 mod_nss_SSLSNISocketConfig(PRFileDesc *fd, const SECItem *sniNameArr,
|
|
+ PRUint32 sniNameArrSize, void *arg)
|
|
+{
|
|
+ /*
|
|
+ arg is apr pool memory from apr_palloc(), SNIMAXNAMELEN+1 bytes long.
|
|
+ initialized zero.
|
|
+ */
|
|
+
|
|
+ char * retptr = NULL;
|
|
+ const SECItem *mysni = sniNameArr;
|
|
+
|
|
+ if(mysni) {
|
|
+ retptr = apr_cpystrn(arg, mysni[0].data,
|
|
+ ( mysni[0].len + 1 < SNIMAXNAMELEN ) ? mysni[0].len + 1 : SNIMAXNAMELEN );
|
|
+ return 0;
|
|
+ } else {
|
|
+ /* no SNI provided... Well. */
|
|
+ return SSL_SNI_CURRENT_CONFIG_IS_USED;
|
|
+ }
|
|
+}
|