Bug 1347298

Summary: mod_nss sets r->user in fixup even if it was long ago changed by other module
Product: Red Hat Enterprise Linux 7 Reporter: Jan Pazdziora <jpazdziora>
Component: mod_nssAssignee: Matthew Harmsen <mharmsen>
Status: CLOSED ERRATA QA Contact: Kaleem <ksiddiqu>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 7.2CC: jpazdziora, rcritten, spoore
Target Milestone: rc   
Target Release: 7.3   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: mod_nss-1.0.14-2.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1431206 (view as bug list) Environment:
Last Closed: 2016-11-03 21:20:44 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1431206    
Attachments:
Description Flags
Remove setting 'r->user' in nss_hook_Fixup()
rcritten: review+
mod_nss.spec file diffs rcritten: review-

Description Jan Pazdziora 2016-06-16 13:17:27 UTC
Description of problem:

mod_nss has two places where it sets r->user, aka REMOTE_USER: nss_hook_Access where it is run under condition of

  if ((dc->nOptions & SSL_OPT_FAKEBASICAUTH) == 0 && dc->szUserName) {

and nss_hook_Fixup where the condition is

    if (dc->szUserName) {

When mod_nss is used together with mod_lookup_identity and its LookupUserByCertificate functionality, the value of r->user is modified (or cleared) based on the lookup via certificate right in the access phase. Other modules then can make decision or other actions of this new value set by mod_lookup_identity. There might even be action of mod_auth_gssapi to modify the r->user value further.

However, in the fixup phase, mod_nss comes and resets the value with its idea of r->user, which then ends up in the access_log. That does not seem correct.

Version-Release number of selected component (if applicable):

mod_nss-1.0.11-6.el7.x86_64

How reproducible:

Deterministic.

Steps to Reproduce:
1. Have IPA-enrolled machine with mod_nss and mod_lookup_identity, with client certificate added to some user record in IPA server, and with NSSVerifyClient require, NSSUserName SSL_CLIENT_CERT, and LookupUserByCertificate On set.
2. Run HTTP request with that client certificate.

Actual results:

==> /var/log/httpd/access_log <==
2620:52:0:1322:221:5eff:fe20:2f4e - -----BEGIN CERTIFICATE-----\nMIICeDCCAeGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MQswCQYDVQQGEwJVUzEU\nMBIGA1UEChMLZXhhbXBsZS5jb20xGjAYBgNVBAMTEUNlcnRpZmljYXRlIFNoYWNr\nMB4XDTE2MDYxNjA4NTM0MVoXDTIwMDYxNjA4NTM0MVowgaAxCzAJBgNVBAYTAlVT\nMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEPMA0GA1UECxMGUGVvcGxlMRUwEwYKCZIm\niZPyLGQBARMFYWxwaGExFDASBgNVBAMTC0ZyYW5rIEFscGhhMT0wOwYJKoZIhvcN\nAQkBFi5hbHBoYUBxZS1ibGFkZS0xMC5pZG1xZS5sYWIuZW5nLmJvcy5yZWRoYXQu\nY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7XmqZ98Ohbom0YHr8yr5M\nvMeuEju+uVmv2vNEjAzrK3bdKcvqVHcx9sGJz376X6PrJxOthFiItxKpEWxshadK\nDwxrz0JPiDyZQW5FPYIuFx/vH8hnPE5LetTw7rf1ukUU4CpfnonLuH7LBwGmpUIl\neRV4ATUb0GYIF/P8gdtOZwIDAQABoyIwIDARBglghkgBhvhCAQEEBAMCB4AwCwYD\nVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4GBAGVMJU24Cjz9CPBmiW61l4B+ufI7\nLvyxCQirRq4rkus0fmkYFHd3+zB40dUcnM/o1Vv5dV3uCxPOjiZz72Ur/bVG3Igw\nI02zZc86+jV9mO5FSfu10myoUNExnsR3uKYWZUW/5rl4GRMtFa8Gruk4cFa0+DJx\nL/dRR/x2uOqDY0Rb\n-----END CERTIFICATE-----\n [16/Jun/2016:08:36:27 -0400] "GET /cgi-bin/set.cgi HTTP/1.1" 200 4196

Expected results:

==> /var/log/httpd/access_log <==
2620:52:0:1322:221:5eff:fe20:2f4e - bob [16/Jun/2016:08:36:27 -0400] "GET /cgi-bin/set.cgi HTTP/1.1" 200 4196

Additional info:

Comment 1 Jan Pazdziora 2016-06-16 13:19:04 UTC
The proposed patch is:

diff --git a/nss_engine_kernel.c b/nss_engine_kernel.c
index b35ba6a..fe02337 100644
--- a/nss_engine_kernel.c
+++ b/nss_engine_kernel.c
@@ -953,9 +953,9 @@ int nss_hook_Fixup(request_rec *r)
     }
 
     /*
-     * Set r->user if requested
+     * Set r->user if requested and if not set earlier in access phase
      */
-    if (dc->szUserName) {
+    if ((dc->nOptions & SSL_OPT_FAKEBASICAUTH) == 1 && dc->szUserName) {
         val = nss_var_lookup(r->pool, r->server, r->connection,
                              r, (char *)dc->szUserName);
         if (val && val[0]) {

Comment 2 Jan Pazdziora 2016-06-16 13:24:14 UTC
The expression will likely never be 1 -- let's make it

diff --git a/nss_engine_kernel.c b/nss_engine_kernel.c
index b35ba6a..f6d119d 100644
--- a/nss_engine_kernel.c
+++ b/nss_engine_kernel.c
@@ -953,9 +953,9 @@ int nss_hook_Fixup(request_rec *r)
     }
 
     /*
-     * Set r->user if requested
+     * Set r->user if requested and if not set earlier in access phase
      */
-    if (dc->szUserName) {
+    if ((dc->nOptions & SSL_OPT_FAKEBASICAUTH) && dc->szUserName) {
         val = nss_var_lookup(r->pool, r->server, r->connection,
                              r, (char *)dc->szUserName);
         if (val && val[0]) {

Comment 4 Jan Pazdziora 2016-06-17 12:05:33 UTC
This is not just cosmetic issue, it actually breaks mod_lookup_identity when it tries to lookup attributes and group membership later in the fixup phase.

Comment 5 Jan Pazdziora 2016-06-17 12:06:12 UTC
(In reply to Jan Pazdziora from comment #4)
> This is not just cosmetic issue, it actually breaks mod_lookup_identity when
> it tries to lookup attributes and group membership later in the fixup phase.

Patch from comment 2 fixes that as well.

Comment 6 Rob Crittenden 2016-06-27 18:42:58 UTC
mod_ssl dropped setting r->user in the Fixup hook altogether. mod_nss should do the same IMHO.

Comment 7 Matthew Harmsen 2016-06-28 22:46:40 UTC
Created attachment 1173551 [details]
Remove setting 'r->user' in nss_hook_Fixup()

Comment 8 Matthew Harmsen 2016-06-28 22:49:01 UTC
Created attachment 1173552 [details]
mod_nss.spec file diffs

Comment 9 Rob Crittenden 2016-06-30 14:35:46 UTC
Comment on attachment 1173551 [details]
Remove setting 'r->user' in nss_hook_Fixup()

Re-confirmed that mod_ssl works in the same way.
Confirmed that all tests pass.
Confirmed that the access log correctly records users authenticated with certificates.

Comment 10 Rob Crittenden 2016-06-30 14:37:46 UTC
Comment on attachment 1173552 [details]
mod_nss.spec file diffs

You should use your name in the changelog for this (and perhaps set the date to the 28th).

Comment 12 Scott Poore 2016-09-20 23:22:18 UTC
Verified.

Version ::

Results ::

# Note: vm1.example.com is IPA Master
#       vm3.example.com is IPA Client for test


[root@vm3 ~]# kinit admin
Password for admin: 

[root@vm3 ~]# ipa service-add HTTP/$(hostname) --force
------------------------------------------------
Added service "HTTP/vm3.example.com"
------------------------------------------------
  Principal name: HTTP/vm3.example.com
  Principal alias: HTTP/vm3.example.com
  Managed by: vm3.example.com

[root@vm3 ~]# CERTSUBJ=$(ipa config-show | grep 'Certificate Subject base'|awk '{print $4}')

[root@vm3 ~]# echo $CERTSUBJ
O=EXAMPLE.COM

[root@vm3 alias]# certutil -R -s "CN=$(hostname),$CERTSUBJ" -d . -a -z /etc/group > /tmp/$(hostname).csr


Generating key.  This may take a few moments...


[root@vm3 alias]# ipa cert-request --principal=HTTP/$(hostname) /tmp/$(hostname).csr
  Issuing CA: ipa
  Certificate: MIIED....cert truncated...
  Subject: CN=vm3.example.com,O=EXAMPLE.COM
  Issuer: CN=Certificate Authority,O=EXAMPLE.COM
  Not Before: Tue Sep 20 22:53:06 2016 UTC
  Not After: Fri Sep 21 22:53:06 2018 UTC
  Fingerprint (MD5): 3b:45:b8:a6:c6:d4:14:67:e6:61:76:0f:b0:86:a6:98
  Fingerprint (SHA1): ae:5e:7d:14:08:93:ed:e0:98:13:63:12:ab:99:23:24:4f:73:52:f7
  Serial number: 11
  Serial number (hex): 0xB

[root@vm3 alias]# ipa service-show HTTP/$(hostname) --out=/tmp/$(hostname).crt
--------------------------------------------------------
Certificate(s) stored in file '/tmp/vm3.example.com.crt'
--------------------------------------------------------
  Principal name: HTTP/vm3.example.com
  Principal alias: HTTP/vm3.example.com
  Certificate: MIIED...cert truncated...
  Subject: CN=vm3.example.com,O=EXAMPLE.COM
  Serial Number: 11
  Serial Number (hex): 0xB
  Issuer: CN=Certificate Authority,O=EXAMPLE.COM
  Not Before: Tue Sep 20 22:53:06 2016 UTC
  Not After: Fri Sep 21 22:53:06 2018 UTC
  Fingerprint (MD5): 3b:45:b8:a6:c6:d4:14:67:e6:61:76:0f:b0:86:a6:98
  Fingerprint (SHA1): ae:5e:7d:14:08:93:ed:e0:98:13:63:12:ab:99:23:24:4f:73:52:f7
  Keytab: False
  Managed by: vm3.example.com


[root@vm3 alias]# wget http://vm1.example.com/ipa/config/ca.crt
--2016-09-20 17:53:29--  http://vm1.example.com/ipa/config/ca.crt
Resolving vm1.example.com (vm1.example.com)... 192.168.122.151
Connecting to vm1.example.com (vm1.example.com)|192.168.122.151|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1307 (1.3K) [application/x-x509-ca-cert]
Saving to: ‘ca.crt’

100%[=============================================================>] 1,307       --.-K/s   in 0s      

2016-09-20 17:53:29 (350 MB/s) - ‘ca.crt’ saved [1307/1307]


[root@vm3 alias]# certutil -A -n $(hostname) -d . -t u,u,u -a < /tmp/$(hostname).crt

Notice: Trust flag u is set automatically if the private key is present.
[root@vm3 alias]# certutil -d . -L

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

cacert                                                       CTu,Cu,Cu
beta                                                         u,pu,u
vm3.example.com                                              u,u,u
alpha                                                        u,pu,u
Server-Cert                                                  u,u,u
[root@vm3 alias]# certutil -V -u V -d . -n $(hostname)
certutil: certificate is valid

[root@vm3 alias]# sed -ie "s/Server-Cert/$(hostname)/g" /etc/httpd/conf.d/nss.conf

[root@vm3 alias]# sed -ie "s/^\(NSSRenegotiation\).*$/\1 on/g" /etc/httpd/conf.d/nss.conf

[root@vm3 alias]# service httpd restart
Redirecting to /bin/systemctl restart  httpd.service

[root@vm3 alias]# sed -i 's/\(services = .*$\)/\1, ifp/' /etc/sssd/sssd.conf

[root@vm3 alias]# cat >> /etc/sssd/sssd.conf <<EOF
> allowed_uids = apache, root
> EOF

[root@vm3 alias]# yum -y install sssd-dbus
Loaded plugins: product-id, search-disabled-repos, subscription-manager
This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.
...yum truncated...

[root@vm3 alias]# systemctl restart sssd

[root@vm3 alias]# cat > /etc/httpd/conf.d/mywebapp.conf <<EOF
> LoadModule lookup_identity_module modules/mod_lookup_identity.so
> <Location /mywebapp>
>     NSSVerifyClient require
>     NSSUserName SSL_CLIENT_CERT
>     LookupUserByCertificate On
> </Location>
> EOF


[root@vm3 alias]# mkdir /var/www/html/mywebapp

[root@vm3 alias]# setsebool -P httpd_dbus_sssd 1


[root@vm3 alias]# echo PASS > /var/www/html/mywebapp/index.html

[root@vm3 alias]# systemctl restart httpd

[root@vm3 alias]# ipa user-add testuser --first=test --last=user
---------------------
Added user "testuser"
---------------------
  User login: testuser
  First name: test
  Last name: user
  Full name: test user
  Display name: test user
  Initials: tu
  Home directory: /home/testuser
  GECOS: test user
  Login shell: /bin/sh
  Principal name: testuser
  Principal alias: testuser
  Email address: testuser
  UID: 635200001
  GID: 635200001
  Password: False
  Member of groups: ipausers
  Kerberos keys available: False

[root@vm3 ~]# openssl req -new -newkey rsa:2048 -days 365 -nodes     -keyout testuser.key -out testuser.csr -subj '/CN=testuser'
Generating a 2048 bit RSA private key
.............+++
.....................................................................................................................................+++
writing new private key to 'testuser.key'
-----


[root@vm3 ~]# ipa cert-request testuser.csr --principal testuser
  Issuing CA: ipa
  Certificate: MIIEB...cert truncated...
  Subject: CN=testuser,O=EXAMPLE.COM
  Issuer: CN=Certificate Authority,O=EXAMPLE.COM
  Not Before: Tue Sep 20 23:02:46 2016 UTC
  Not After: Fri Sep 21 23:02:46 2018 UTC
  Fingerprint (MD5): 8d:62:80:40:f3:a5:21:76:3e:2d:c8:2b:aa:17:5f:ff
  Fingerprint (SHA1): f0:6b:16:d7:b4:33:e7:b1:60:7e:bd:69:0f:7a:fc:26:15:30:9d:55
  Serial number: 12
  Serial number (hex): 0xC

[root@vm3 ~]# ipa user-show testuser --out=testuser.crt
--------------------------------------------
Certificate(s) stored in file 'testuser.crt'
--------------------------------------------
  User login: testuser
  First name: test
  Last name: user
  Home directory: /home/testuser
  Login shell: /bin/sh
  Principal name: testuser
  Principal alias: testuser
  Email address: testuser
  UID: 635200001
  GID: 635200001
  Certificate: MIIEB...cert truncated...
  Account disabled: False
  Password: False
  Member of groups: ipausers
  Kerberos keys available: False

[root@vm3 ~]# cd /etc/httpd/alias/

[root@vm3 alias]# chown apache /etc/http.keytab

[root@vm3 alias]# chmod 600 /etc/http.keytab

[root@vm3 alias]# service httpd restart
Redirecting to /bin/systemctl restart  httpd.service

[root@vm3 alias]# setsebool -P httpd_dbus_sssd 1


[root@vm3 alias]# curl --key /root/testuser.key --cert /root/testuser.crt -ki https://$( hostname ):8443/mywebapp/
HTTP/1.1 200 OK
Date: Tue, 20 Sep 2016 23:14:16 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux) mod_nss/1.0.14 NSS/3.21 Basic ECC
Last-Modified: Tue, 20 Sep 2016 23:00:52 GMT
ETag: "5-53cf8667b6ccf"
Accept-Ranges: bytes
Content-Length: 5
Content-Type: text/html; charset=UTF-8

PASS

[root@vm3 alias]# tail -1 /var/log/httpd/access_log 
192.168.122.153 - testuser [20/Sep/2016:18:14:16 -0500] "GET /mywebapp/ HTTP/1.1" 200 5

Comment 13 Scott Poore 2016-09-20 23:22:50 UTC
Forgot to add version.

mod_nss-1.0.14-5.el7.x86_64

Comment 15 errata-xmlrpc 2016-11-03 21:20:44 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHSA-2016-2602.html