[Pkg-fedora-ds-maintainers] libapache2-mod-nss: Changes to 'upstream'

Timo Aaltonen tjaalton at moszumanska.debian.org
Mon Sep 19 14:13:55 UTC 2016


 AUTHORS                |    6 
 ChangeLog              |   68 ++++++++++
 Makefile.am            |    2 
 README                 |    5 
 configure.ac           |   15 +-
 docs/mod_nss.html      |   93 ++++++++++++++
 gencert.in             |   76 ++++++++++--
 migrate.pl             |  286 +++++++++++++++++++--------------------------
 mod_nss.c              |    3 
 mod_nss.h              |   15 ++
 nss.conf.in            |    9 -
 nss_engine_cipher.c    |   69 ++++++++--
 nss_engine_cipher.h    |    2 
 nss_engine_config.c    |   31 ++++
 nss_engine_init.c      |  309 ++++++++++++++++++++++++++++++++----------------
 nss_engine_io.c        |    2 
 nss_engine_kernel.c    |   55 +++++++-
 nss_engine_pphrase.c   |   50 +++++--
 nss_engine_vars.c      |  215 +++++++++++++++++++++++++++++++++
 nss_pcache.c           |   39 ++++--
 nss_util.c             |  111 +++++++++++++++++
 test/createinstance.sh |   17 ++
 test/mod_nss.supp      |  310 +++++++++++++++++++++++++++++++++++++++++++++++++
 test/msupn.py          |   27 ++++
 test/nss_pcache.supp   |   19 +++
 test/setup.sh          |    5 
 test/suite1.tmpl       |    7 +
 test/test.py           |   26 ++++
 test/test_cipher.py    |  166 +++++++++++++++-----------
 test_cipher.c          |    4 
 30 files changed, 1637 insertions(+), 405 deletions(-)

New commits:
commit fe74ab673869dfcf6a8b9163b78f96af7e17cf09
Author: Rob Crittenden <rcritten at redhat.com>
Date:   Fri Apr 15 14:27:59 2016 -0400

    Become 1.0.14

diff --git a/configure.ac b/configure.ac
index 7b9b84e..b5acc11 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 # Required initializer
-AC_INIT([mod_nss],[1.0.13])
+AC_INIT([mod_nss],[1.0.14])
 
 m4_include([acinclude.m4])
 

commit 77116e9a95db306a624f6b58cf37d1da8c7534d9
Author: Rob Crittenden <rcritten at redhat.com>
Date:   Fri Apr 15 14:26:21 2016 -0400

    Update CL: migration, FILTER type, valgrind, ciphers CVE
    
    * Become 1.0.14
    * Created valgrind suppression files to ease debugging
    * Implement SSL_PPTYPE_FILTER to call executables to get
      the key password pins. Can be used to prompt with systemd.
    * Improvements to migrate.pl
    * OpenSSL ciphers stopped parsing at +, CVE-2016-3099

diff --git a/ChangeLog b/ChangeLog
index c45ff41..f881126 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,19 @@
+2016-04-15  Rob Crittenden <rcritten at redhat.com>
+    * Become 1.0.14
+
+2016-03-31  Rob Crittenden <rcritten at redhat.com>
+    * Created valgrind suppression files to ease debugging
+
+2016-03-30  Rob Crittenden <rcritten at redhat.com>
+    * Implement SSL_PPTYPE_FILTER to call executables to get
+      the key password pins. Can be used to prompt with systemd.
+
 2016-03-30  Vitezslav Cizek <vcizek at suse.com>
     * Improvements to migrate.pl
 
+2016-03-17  Rob Crittenden <rcritten at redhat.com>
+    * OpenSSL ciphers stopped parsing at +, CVE-2016-3099
+
 2016-03-04  Rob Crittenden <rcritten at redhat.com>
 
     * Fix a number of issues discovered by clang-analyzer

commit 2127071fa8aad7ba0f7e648be855bcfaae9fe013
Author: Rob Crittenden <rcritten at redhat.com>
Date:   Thu Mar 17 15:44:04 2016 -0400

    Properly handle +CIPHER operation in OpenSSL compat
    
    This would previously cause the parser to immediately return
    which could cause unexpected results. This was the case with
    the Fedora OpenSSL system defaults which had +DES before
    !aNULL:!eNULL which would result in NULL ciphers being enabled
    if this string were used.
    
    Switched to using defines for the cipher actions instead of
    integers.
    
    Fixed up some tests. More recent OpenSSL has disabled LOW
    and DES ciphers by default.
    
    CVE-2016-3099

diff --git a/nss_engine_cipher.c b/nss_engine_cipher.c
index 3c034a2..714c4ed 100644
--- a/nss_engine_cipher.c
+++ b/nss_engine_cipher.c
@@ -20,6 +20,12 @@
 #include <stdlib.h>
 #include <sslproto.h>
 
+/* Cipher actions */
+#define PERMANENTLY_DISABLE_CIPHER   -1 /* !CIPHER */
+#define SUBTRACT_CIPHER               0 /* -CIPHER */
+#define ENABLE_CIPHER                 1 /* CIPHER */
+#define REORDER_CIPHER                2 /* +CIPHER */
+
 /* ciphernum is defined in nss_engine_cipher.h */
 cipher_properties ciphers_def[] =
 {
@@ -181,14 +187,18 @@ static void set_cipher_value(PRBool cipher_list[ciphernum], int index, int actio
 {
     int i;
 
+    if (action == REORDER_CIPHER)
+        /* NSS doesn't allow ordering so do nothing */
+        return;
+
     for (i = 0; i < skip_ciphers; i++) {
         if (ciphers_def[index].num == ciphers_not_in_openssl[i]) {
-            cipher_list[index] = -1;
+            cipher_list[index] = PERMANENTLY_DISABLE_CIPHER;
             return;
         }
     }
 
-    if (cipher_list[index] != -1) /* cipher is disabled */
+    if (cipher_list[index] != PERMANENTLY_DISABLE_CIPHER)
         cipher_list[index] = action;
 }
 
@@ -207,23 +217,24 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
         while ((*cipher) && (isspace(*cipher)))
             ++cipher;
 
-        action = 1; /* default to enable */
+        action = ENABLE_CIPHER; /* default to enable */
         switch(*cipher)
         {
-            case '+': /* Add something */
+            case '+':
                 /* Cipher ordering is not supported in NSS */
-                return 0;
+                action = REORDER_CIPHER;
+                cipher++;
                 break;
-            case '-': /* Subtract something */
-                action = 0;
+            case '-':
+                action = SUBTRACT_CIPHER;
                 cipher++;
                 break;
-            case '!':  /* Disable something */
-                action = -1;
+            case '!':
+                action = PERMANENTLY_DISABLE_CIPHER;
                 cipher++;
                 break;
             default:
-               /* do nothing */
+                /* Add the cipher */
                 break;
         }
 
@@ -253,12 +264,13 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
             int mask = SSL_aNULL | SSL_eNULL;
             found = PR_TRUE;
             for (i=0; i < ciphernum; i++) {
-                if (cipher_list[i] != -1)
+                if (cipher_list[i] != PERMANENTLY_DISABLE_CIPHER)
                     SSL_CipherPrefGetDefault(ciphers_def[i].num,
                                              &cipher_list[i]);
                 if (PR_TRUE == first) {
                     if (ciphers_def[i].attr & mask) {
-                        set_cipher_value(cipher_list, i, -1);
+                        set_cipher_value(cipher_list, i,
+                                         PERMANENTLY_DISABLE_CIPHER);
                     }
                 }
             }
@@ -414,7 +426,7 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
                         if (((ciphers_def[i].attr & mask) ||
                          (ciphers_def[i].strength & strength) ||
                          (ciphers_def[i].version & protocol)) &&
-                         (cipher_list[i] != -1)) {
+                         (cipher_list[i] != PERMANENTLY_DISABLE_CIPHER)) {
                             if (amask != 0) {
                                 PRBool match = PR_FALSE;
                                 if (ciphers_def[i].attr & amask) {
diff --git a/test/test_cipher.py b/test/test_cipher.py
index f1d39df..1cce9e4 100644
--- a/test/test_cipher.py
+++ b/test/test_cipher.py
@@ -6,6 +6,15 @@ from nose.tools import make_decorator
 # This file is auto-generated by configure
 from variable import ENABLE_SHA384, ENABLE_GCM, ENABLE_SERVER_DHE
 
+# Things to be aware of if some tests fail:
+#
+# OpenSSL 1.0.2g
+#    removed LOW from the DEFAULT cipher list
+# OpenSSL 1.0.2f
+#     doesn't provide EXPORT or LOW ciphers unless built that way
+#
+# See https://www.openssl.org/news/cl102.txt for more details
+
 cwd = os.getcwd()
 srcdir = os.path.dirname(cwd)
 exe = "%s/test_cipher" % srcdir
@@ -31,7 +40,7 @@ if ENABLE_SERVER_DHE == 0:
     OPENSSL_CIPHERS_IGNORE += ':-DH'
 
 def assert_equal_openssl(ciphers):
-    nss_ciphers = ciphers
+    nss_ciphers = ciphers + ":-EXP:-LOW"
     ossl_ciphers = ciphers + OPENSSL_CIPHERS_IGNORE
     (nss, err, rc) = run([exe, "--o", nss_ciphers])
     assert rc == 0
@@ -99,8 +108,9 @@ class test_ciphers(object):
     def test_RC4(self):
         assert_equal_openssl("RC4")
 
-    def test_RC2(self):
-        assert_equal_openssl("RC2")
+# OpenSSL 1.0.2f disabled LOW ciphers by default
+#    def test_RC2(self):
+#        assert_equal_openssl("RC2")
 
     def test_AES(self):
         assert_equal_openssl("AES")
@@ -126,8 +136,9 @@ class test_ciphers(object):
     def test_3DES(self):
         assert_equal_openssl("3DES")
 
-    def test_DES(self):
-        assert_equal_openssl("DES")
+# OpenSSL 1.0.2f disabled LOW ciphers by default
+#    def test_DES(self):
+#        assert_equal_openssl("DES")
 
     def test_ALL(self):
         assert_equal_openssl("ALL")
@@ -163,14 +174,15 @@ class test_ciphers(object):
         assert rc == 0
         assert_equal(out, 'rsa_rc4_128_md5, rsa_rc4_128_sha')
 
-    def test_EXP(self):
-        assert_equal_openssl("EXP")
-
-    def test_EXPORT(self):
-        assert_equal_openssl("EXPORT")
-
-    def test_EXPORT40(self):
-        assert_equal_openssl("EXPORT40")
+# OpenSSL 1.0.2g disabled export ciphers by default
+#    def test_EXP(self):
+#        assert_equal_openssl("EXP")
+#
+#    def test_EXPORT(self):
+#        assert_equal_openssl("EXPORT")
+#
+#    def test_EXPORT40(self):
+#        assert_equal_openssl("EXPORT40")
 
     def test_MD5(self):
         assert_equal_openssl("MD5")
@@ -184,8 +196,9 @@ class test_ciphers(object):
     def test_MEDIUM(self):
         assert_equal_openssl("MEDIUM")
 
-    def test_LOW(self):
-        assert_equal_openssl("LOW")
+# OpenSSL 1.0.2f disabled LOW ciphers by default
+#    def test_LOW(self):
+#        assert_equal_openssl("LOW")
 
     def test_SHA256(self):
         assert_equal_openssl("SHA256")
@@ -256,6 +269,14 @@ class test_ciphers(object):
     def test_DEFAULT_aRSA(self):
         assert_no_NULL("DEFAULT:aRSA")
 
+    def test_SYSTEM_DEFAULT(self):
+         # I've added in !DHE here which differs from F-23 default
+         assert_equal_openssl("!SSLv2:kEECDH:kRSA:kEDH:kPSK:+3DES:!aNULL:!eNULL:!MD5:!EXP:!RC4:!SEED:!IDEA:!DES:!DHE")
+
+    def test_cipher_reorder(self):
+        # re-ordering now allowed but shouldn't blow up either
+        assert_equal_openssl("3DES:RC4:AES:+3DES:MD5")
+
     def test_nss_subtraction(self):
         (out, err, rc) = run([exe, "+rsa_rc4_128_md5,+rsa_rc4_128_sha,-rsa_rc4_128_md5"])
         assert rc == 0

commit a62db8e554c90cfa5b171cba86914242aa9fbf9d
Author: Rob Crittenden <rcritten at redhat.com>
Date:   Thu Mar 31 09:29:35 2016 -0400

    Add valgrind suppression files for mod_nss and nss_pcache
    
    I tried to be conservative enough so future real memory leaks
    and issues won't be missed.
    
    I left in a few one-time-per-start leaks so the mod_nss
    output is not completely empty.

diff --git a/test/createinstance.sh b/test/createinstance.sh
index f07f6a3..aee1a92 100755
--- a/test/createinstance.sh
+++ b/test/createinstance.sh
@@ -88,7 +88,7 @@ cat << EOF >  start
 MALLOC_CHECK_=2
 MALLOC_PERTURB=\$((\$RANDOM % 255 + 1))
 HTTPD=/usr/sbin/httpd
-#valgrind --leak-check=full --log-file=valgrind.out.%p --trace-children=yes --track-origins=yes \$HTTPD -X -k start -d . -f ./conf/httpd.conf
+#valgrind --suppressions=../../mod_nss.supp --suppressions=../../nss_pcache.supp --leak-check=full --log-file=valgrind.out.%p --trace-children=yes --track-origins=yes \$HTTPD -X -k start -d . -f ./conf/httpd.conf
 \$HTTPD -k start -d . -f ./conf/httpd.conf
 EOF
 
diff --git a/test/mod_nss.supp b/test/mod_nss.supp
new file mode 100644
index 0000000..08b4d0d
--- /dev/null
+++ b/test/mod_nss.supp
@@ -0,0 +1,310 @@
+{
+   <NSS I/O Layer>
+   Memcheck:Leak
+   ...
+   fun:PR_CreateIOLayerStub
+}
+{
+   <PK11_ConfigurePKCS11>
+   Memcheck:Leak
+   ...
+   fun:PK11_ConfigurePKCS11
+}
+{
+   <NSS_Initialize>
+   Memcheck:Leak
+   ...
+   fun:NSS_Initialize
+}
+{
+   <PK11_GetAllTokens>
+   Memcheck:Leak
+   ...
+   fun:PK11_GetAllTokens
+}
+{
+   <NSSTrustDomain_TraverseCertificates>
+   Memcheck:Leak
+   ...
+   fun:NSSTrustDomain_TraverseCertificates
+}
+{
+   <nssDecodedPKIXCertificate_Create>
+   Memcheck:Leak
+   ...
+   fun:nssDecodedPKIXCertificate_Create
+}
+{
+   <serverCAListSetup>
+   Memcheck:Leak
+   ...
+   fun:serverCAListSetup
+}
+{
+   <Apache resource_config>
+   Memcheck:Leak
+   ...
+   fun:ap_process_resource_config
+}
+{
+   <Apache leak ap_process_config_tree>
+   Memcheck:Leak
+   ...
+   fun:ap_process_config_tree
+}
+{
+   <Apache proxy initialize>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_pool_create_ex
+   ...
+   fun:ap_proxy_initialize_worker
+   fun:child_init
+   fun:ap_run_child_init
+   fun:child_main
+   fun:make_child
+   fun:prefork_run
+   fun:ap_run_mpm
+   fun:main
+}
+{
+   <Apache build config>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:apr_pmemdup
+   fun:ap_build_config_sub
+   fun:ap_build_config
+   fun:ap_process_resource_config
+   fun:ap_read_config
+   fun:main
+}
+{
+   <Apache build config open include file>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:apr_file_open
+   fun:ap_pcfg_openfile
+   fun:ap_process_resource_config
+   fun:process_resource_config_nofnmatch
+   fun:ap_process_fnmatch_configs
+   fun:include_config
+   fun:invoke_cmd
+   fun:execute_now
+   fun:ap_build_config_sub
+   fun:ap_build_config
+   fun:ap_process_resource_config
+}
+{
+   <Apache build config include>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:ap_build_config_sub
+   fun:ap_build_config
+   fun:ap_process_resource_config
+   fun:process_resource_config_nofnmatch
+   fun:ap_process_fnmatch_configs
+   fun:include_config
+   fun:invoke_cmd
+   fun:execute_now
+   fun:ap_build_config_sub
+   fun:ap_build_config
+   fun:ap_process_resource_config
+}
+{
+   <Apache process config>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:apr_strmatch_precompile
+   fun:add_setenvif_core
+   fun:invoke_cmd
+   fun:ap_walk_config_sub
+   fun:ap_walk_config
+   fun:ap_process_config_tree
+   fun:main
+}
+{
+   <Apache config VirtualHost>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:create_empty_config
+   fun:urlsection
+   fun:invoke_cmd
+   fun:ap_walk_config_sub
+   fun:ap_walk_config
+   fun:virtualhost_section
+   fun:invoke_cmd
+   fun:ap_walk_config_sub
+   fun:ap_walk_config
+   fun:ap_process_config_tree
+   fun:main
+}
+{
+   <Apache virtualhost reorder>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_pool_create_ex
+   fun:ap_core_reorder_directories
+   fun:ap_fixup_virtual_hosts
+   fun:main
+}
+{
+   <Apache init pool allocator>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_pool_create_ex
+   ...
+   fun:apr_initialize
+   fun:init_process
+   fun:main
+}
+{
+   <Apache init pool allocator>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_pool_create_ex
+   fun:init_process
+   fun:main
+}
+{
+   <Apache init pool allocator>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:init_process
+   fun:main
+}
+{
+   <Apache apr_pool_create_ex>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_pool_create_ex
+   fun:main
+}
+{
+   <Apache ap_setup_prelinked_modules>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   ...
+   fun:ap_setup_prelinked_modules
+   fun:main
+}
+{
+   <Apache init server config>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:make_array_core
+   fun:apr_array_make
+   fun:so_sconf_create
+   fun:create_server_config
+   fun:init_server_config
+   fun:ap_read_config
+   fun:main
+}
+{
+   <Apache register hooks>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   ...
+   fun:ap_add_module
+   fun:ap_add_loaded_module
+   fun:load_module
+   fun:invoke_cmd
+   fun:execute_now
+   fun:ap_build_config_sub
+   fun:ap_build_config
+}
+{  
+   <Apache apr_sort_hook_all>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   ...
+   fun:apr_hook_sort_all
+   fun:main
+}
+{
+   <Apache apr_strmatch_precompile>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:apr_strmatch_precompile
+   fun:ap_setup_make_content_type
+   fun:core_post_config
+   fun:ap_run_post_config
+   fun:main
+}
+{
+   <Apache rewritelock mutex>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:proc_mutex_sysv_create
+   fun:proc_mutex_create
+   fun:apr_proc_mutex_create
+   fun:apr_global_mutex_create
+   fun:ap_global_mutex_create
+   fun:rewritelock_create
+   fun:post_config
+   fun:ap_run_post_config
+   fun:main
+}
+{
+   <Apache ap_init_rng>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   fun:apr_random_add_entropy
+   fun:ap_init_rng
+   fun:main
+}
+{
+   <Apache mime_post_config>
+   Memcheck:Leak
+   match-leak-kinds: possible
+   fun:malloc
+   fun:allocator_alloc
+   fun:apr_palloc
+   ...
+   fun:mime_post_config
+   fun:ap_run_post_config
+   fun:main
+}
diff --git a/test/nss_pcache.supp b/test/nss_pcache.supp
new file mode 100644
index 0000000..ff28180
--- /dev/null
+++ b/test/nss_pcache.supp
@@ -0,0 +1,19 @@
+{
+   <NSS_Initialize>
+   Memcheck:Leak
+   ...
+   fun:NSS_Initialize
+   fun:main
+}
+{
+   <secmod_ModuleInit>
+   Memcheck:Leak
+   ...
+   fun:secmod_ModuleInit
+}
+{
+   <nsc_CommonInitialize>
+   Memcheck:Leak
+   ...
+   fun:nsc_CommonInitialize
+}

commit dc77e14f08a0862ccec2aaeec3cae6206114f28f
Author: Rob Crittenden <rcritten at redhat.com>
Date:   Thu Mar 31 09:28:03 2016 -0400

    In nss_pcache only get needed parts for each command
    
    I was previously always fetching the command, token name and
    password which wasn't appropriate. Now only fetch those parts
    needed per command.

diff --git a/nss_pcache.c b/nss_pcache.c
index 37a9ceb..a8b15f7 100644
--- a/nss_pcache.c
+++ b/nss_pcache.c
@@ -387,8 +387,6 @@ int main(int argc, char ** argv)
                 break;
             }
             command = getstr(buf, 0);
-            tokenName = getstr(buf, 1);
-            tokenpw = getstr(buf, 2);
 
             if (command && !strcmp(command, "QUIT")) {
                 break;
@@ -396,6 +394,9 @@ int main(int argc, char ** argv)
                 PRInt32 err = PIN_SUCCESS;
                 Node *node = NULL;
 
+                tokenName = getstr(buf, 1);
+                tokenpw = getstr(buf, 2);
+
                 if (tokenName && tokenpw) {
                     node = (Node*)malloc(sizeof (Node));
                     if (!node) {
@@ -431,6 +432,8 @@ int main(int argc, char ** argv)
                 char *pin = 0;
                 PRBool found = PR_FALSE;
 
+                tokenName = getstr(buf, 1);
+
                 for (node = pinList; node != NULL; node = node->next) {
                     if (!strcmp(node->tokenName, tokenName)) {
                         if (Pk11StoreGetPin(&pin, node->store) == SECSuccess) {

commit e92ef6fba67472b6c4a9feec599e4123bbffa74b
Author: Rob Crittenden <rcritten at redhat.com>
Date:   Wed Mar 30 18:37:41 2016 -0400

    Implement pass phrase dialog SSL_PPTYPE_FILTER type for systemd
    
    With systemd you have to use their password prompting scheme or
    you get nothing. Implement the SSL_PPTYPE_FILTER type so we can
    call out to /bin/systemd-ask-password (or other things as the
    user might need).
    
    Note that calling /bin/systemd-ask-password ONLY works for
    the root user. It will silently fail with permissions otherwise.
    
    I tested on Fedora using the mod_ssl-provided
    /usr/libexec/httpd-ssl-pass-dialog
    
    https://fedorahosted.org/mod_nss/ticket/24

diff --git a/docs/mod_nss.html b/docs/mod_nss.html
index bf3dbe7..65d0bd8 100644
--- a/docs/mod_nss.html
+++ b/docs/mod_nss.html
@@ -255,6 +255,8 @@ To avoid being prompted for a startup password you can either:<br>
 <ul>
   <li>Use a password file that contains your token passwords. See
 NSSPassPhraseDialog for details.</li>
+  <li>Exec a program which provides the token password (either by
+asking the user or other means.</li>
   <li>Change the internal token password to a blank with:</li>
 </ul>
 <div style="margin-left: 40px;">
@@ -320,10 +322,38 @@ without user intervention. The format of this file is:<br>
 </div>
 <div style="margin-left: 80px;"><code>internal:secret12</code><br>
 </div>
+<ul>
+  <li><code>exec:/path/to/executable</code></li>
+</ul>
+<div style="margin-left: 40px;">The listed program will be executed.
+The only argument is the NSS token name to be authenticated.
+The return value of the program is ignored. Only what is printed on
+stdout is passed along as the password.
+</div>
+<br>
+<div style="margin-left: 40px;">A trivial example script is:<br>
+<br>
+</div>
+<div style="margin-left: 80px;"><code>
+#!/bin/sh<br>
+echo "secret123"
+</code><br>
+</div>
+<br>
+<div style="margin-left: 40px;">To prompt using systemd (as root):<br>
+<br>
+</div>
+<div style="margin-left: 80px;"><code>
+#!/bin/sh<br>
+exec /bin/systemd-ask-password "Enter SSL pass phrase for $1: "
+</code><br>
+</div>
 <br>
 <span style="font-weight: bold;">Example</span><br>
 <br>
 <code>NSSPassPhraseDialog builtin</code><br>
+<code>NSSPassPhraseDialog file:/etc/httpd/alias/password.conf</code><br>
+<code>NSSPassPhraseDialog exec:/usr/libexec/httpd/httpd-ssl-pass-dialog</code><br>
 <div style="margin-left: 80px;"><br>
 </div>
 <font size="+2">NSSPassPhraseHelper</font> <br>
diff --git a/mod_nss.h b/mod_nss.h
index f3c0970..226f7a8 100644
--- a/mod_nss.h
+++ b/mod_nss.h
@@ -221,6 +221,7 @@ typedef enum {
     SSL_PPTYPE_BUILTIN = 0,
     SSL_PPTYPE_FILE    = 1,
     SSL_PPTYPE_DEFER   = 2,
+    SSL_PPTYPE_FILTER  = 3,
 } nss_pphrase_t;
 
 /*
diff --git a/nss_engine_config.c b/nss_engine_config.c
index 4adff52..e1fbe41 100644
--- a/nss_engine_config.c
+++ b/nss_engine_config.c
@@ -692,7 +692,27 @@ const char *nss_cmd_NSSPassPhraseDialog(cmd_parms *cmd,
                                "' does not exist", NULL);
         }
     }
+    else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
+        apr_finfo_t finfo;
+        apr_status_t rc;
 
+        mc->pphrase_dialog_type  = SSL_PPTYPE_FILTER;
+        mc->pphrase_dialog_path =
+            ap_server_root_relative(cmd->pool, arg+5);
+        if (!mc->pphrase_dialog_path) {
+            return apr_pstrcat(cmd->pool,
+                               "Invalid NSSPassPhraseDialog exec: path ",
+                               arg+5, NULL);
+        }
+        rc = apr_stat(&finfo, mc->pphrase_dialog_path,
+             APR_FINFO_TYPE|APR_FINFO_SIZE, cmd->pool);
+        if ((rc != APR_SUCCESS) || (finfo.filetype != APR_REG)) {
+            return apr_pstrcat(cmd->pool,
+                               "NSSPassPhraseDialog: file '",
+                               mc->pphrase_dialog_path,
+                               "' does not exist", NULL);
+        }
+    }
     return NULL;
 }
 
diff --git a/nss_engine_pphrase.c b/nss_engine_pphrase.c
index 2d04c32..5f5498c 100644
--- a/nss_engine_pphrase.c
+++ b/nss_engine_pphrase.c
@@ -19,6 +19,7 @@
 
 typedef struct {
     SSLModConfigRec *mc;
+    server_rec *s;
     PRInt32 retryCount;
 } pphrase_arg_t;
 
@@ -51,6 +52,7 @@ SECStatus nss_Init_Tokens(server_rec *s)
     parg = (pphrase_arg_t*)malloc(sizeof(*parg));
     parg->mc = mc;
     parg->retryCount = 0;
+    parg->s = s;
 
     PK11_SetPasswordFunc(nss_password_prompt);
 
@@ -149,7 +151,7 @@ static char * nss_password_prompt(PK11SlotInfo *slot, PRBool retry, void *arg)
         snprintf(buf, 1024, "STOR\t%s\t%s", PK11_GetTokenName(slot), passwd);
         rv = apr_file_write_full(parg->mc->proc.in, buf, strlen(buf), NULL);
         if (rv != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                 "Unable to write to pin store for slot: %s APR err: %d",  PK11_GetTokenName(slot), rv);
             nss_die();
         }
@@ -166,7 +168,7 @@ static char * nss_password_prompt(PK11SlotInfo *slot, PRBool retry, void *arg)
             res = atoi(buf);
         if (rv != APR_SUCCESS ||
            (res != PIN_SUCCESS && res != PIN_INCORRECTPW)) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                 "Unable to read from pin store for slot: %s APR err: %d pcache: %d",  PK11_GetTokenName(slot), rv, res);
             nss_die();
         }
@@ -216,9 +218,9 @@ static char * nss_no_password(PK11SlotInfo *slot, PRBool retry, void *arg)
  * exists then it may be used to store the token password(s).
  */
 static char *nss_get_password(FILE *input, FILE *output,
-                                       PK11SlotInfo *slot,
-                                       PRBool (*ok)(unsigned char *),
-                                       pphrase_arg_t *parg)
+                              PK11SlotInfo *slot,
+                              PRBool (*ok)(unsigned char *),
+                              pphrase_arg_t *parg)
 {
     char *pwdstr = NULL;
     char *token_name = NULL;
@@ -248,7 +250,7 @@ static char *nss_get_password(FILE *input, FILE *output,
                     line[tmp+1] = '\0';
                     ptr = PL_strchr(line, ':');
                     if (ptr == NULL) {
-                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+                        ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                            "Malformed password entry for token %s. Format should be token:password", token_name);
                         continue;
                     }
@@ -258,10 +260,32 @@ static char *nss_get_password(FILE *input, FILE *output,
             }
             fclose(pwd_fileptr);
         } else {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                  "Unable to open password file %s", parg->mc->pphrase_dialog_path);
             nss_die();
         }
+    } else if ((parg->mc->pphrase_dialog_type == SSL_PPTYPE_FILTER) &&
+                (parg->mc->nInitCount == 1)) {
+        /* We only have tty during first module load */
+        const char *cmd = parg->mc->pphrase_dialog_path;
+        const char **argv = apr_palloc(parg->mc->pPool, sizeof(char *) * 4);
+        char *result;
+        int i;
+
+        ap_log_error(APLOG_MARK, APLOG_INFO, 0, parg->s,
+                     "Requesting pass phrase from dialog filter "
+                     "program (%s)", cmd);
+
+        argv[0] = cmd;
+        argv[1] = token_name;
+        argv[2] = "NSS";
+        argv[3] = NULL;
+
+        result = nss_util_readfilter(NULL, parg->mc->pPool, cmd, argv);
+
+        /* readfilter returns NULL in case of ANY error */
+        if (NULL != result)
+            pwdstr = strdup(result);
     }
 
     /* For SSL_PPTYPE_DEFER we only want to authenticate passwords found
@@ -286,14 +310,14 @@ static char *nss_get_password(FILE *input, FILE *output,
         sb.sem_op = -1;
         sb.sem_flg = SEM_UNDO;
         if (semop(parg->mc->semid, &sb, 1) == -1) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                 "Unable to reserve semaphore resource");
         }
 
         snprintf(buf, 1024, "RETR\t%s", token_name);
         rv = apr_file_write_full(parg->mc->proc.in, buf, strlen(buf), NULL);
         if (rv != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                 "Unable to write to pin store for slot: %s APR err: %d",  PK11_GetTokenName(slot), rv);
             nss_die();
         }
@@ -305,13 +329,13 @@ static char *nss_get_password(FILE *input, FILE *output,
         rv = apr_file_read(parg->mc->proc.out, buf, &nBytes);
         sb.sem_op = 1;
         if (semop(parg->mc->semid, &sb, 1) == -1) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                 "Unable to free semaphore resource");
             /* perror("semop free resource id"); */
         }
 
         if (rv != APR_SUCCESS) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                 "Unable to read from pin store for slot: %s APR err: %d",  PK11_GetTokenName(slot), rv);
             nss_die();
         }
@@ -353,7 +377,7 @@ static char *nss_get_password(FILE *input, FILE *output,
             continue;
         }
         if (PK11_IsFIPS() && strlen((char *)phrase) == 0) {
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, parg->s,
                 "The FIPS security policy requires that a password be set.");
             nss_die();
         } else

commit d3cc93eb78af3976f4d5f00b7d4874e3a7c8d477
Author: Rob Crittenden <rcritten at redhat.com>
Date:   Fri Mar 18 18:16:50 2016 -0400

    Handle migrating Fedora-specific policy, cleanup output
    
    * SSLRandomSeed connect isn't supported, exclude it
    * If the ciphers are PROFILE=SYSTEM try reading them
    * Clean up output, remove distro-specific paths
    * Add -r/-w to help output
    
    https://fedorahosted.org/mod_nss/ticket/25

diff --git a/ChangeLog b/ChangeLog
index 2332753..c45ff41 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+2016-03-30  Vitezslav Cizek <vcizek at suse.com>
+    * Improvements to migrate.pl
+
 2016-03-04  Rob Crittenden <rcritten at redhat.com>
 
     * Fix a number of issues discovered by clang-analyzer
diff --git a/migrate.pl b/migrate.pl
index cf9c328..d367633 100755
--- a/migrate.pl
+++ b/migrate.pl



More information about the Pkg-fedora-ds-maintainers mailing list