Rebase to PKI 10.11.0-alpha1

Resolves: #1952530
This commit is contained in:
Endi S. Dewata 2021-05-18 16:59:39 -05:00
parent 0661fcdd41
commit f377a866d7
6 changed files with 14 additions and 312 deletions

1
.gitignore vendored
View File

@ -80,3 +80,4 @@
/pki-10.10.2.tar.gz
/pki-10.10.3.tar.gz
/pki-10.10.5.tar.gz
/pki-10.11.0-alpha1.tar.gz

View File

@ -1,170 +0,0 @@
From 34c492c30f49ee9feaa1332db91b56e55efc7994 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftweedal@redhat.com>
Date: Wed, 13 Jan 2021 18:27:46 +1100
Subject: [PATCH] Fix renewal profile approval process
Due to a recent change in PKI CLI, the CLI now passes along user
authentication with submissions to the renewal endpoint. Unlike the EE
pages, the REST API has passed along this authentication for a while.
Due to a bug in the RenewalProcessor, requests with credentials against
profiles with no authentication method and no ACLs result in the
certificiate automatically being approved. This occurs because, when
an earlier commit (cb9eb967b5e24f5fde8bbf8ae87aa615b7033db7) modified
the code to allow Light-Weight SubCAs to issue certificates, validation
wasn't done on the passed principal, to see if it was a trusted agent.
Because profiles requring Agent approval have an empty ACL list (as, no
user should be able to submit a certificate request and have it
automatically signed without agent approval), authorize allows any user
to approve this request and thus accepts the AuthToken.
Critical analysis: the RenewalProcessor code interprets (authToken
!= null) as evidence that the authenticated user is /authorized/ to
immediately issue the certificate. This mismatch of concerns (authn
vs authz) resulted in a misunderstanding of system behaviour. The
"latent" AuthToken (from the HTTP request) was assigned to authToken
without realising that authorization needed to be performed.
We fix this by splitting the logic on whether the profile defines an
authenticator. If so, we (re)authenticate and authorize the user
according to the profile configuration.
If the profile does not define an authenticator but there is a
principal in the HTTP request, if (and only if) the user has
permission to approve certificate requests *and* the requested
renewal profile is caManualRenewal (which is hardcoded to be used
for LWCA renewal), then we issue the certificate immediately. This
special case ensures that LWCA renewal keeps working.
Otherwise, if there is no principal in the HTTP request or the
principal does not have permission to approve certificate requests,
we leave the authToken unset. The resulting renewal request will be
created with status PENDING, i.e. enqueued for agent review.
Signed-off-by: Fraser Tweedale <ftweedal@redhat.com>
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
---
.../com/netscape/ca/CertificateAuthority.java | 10 +++
.../cms/servlet/cert/RenewalProcessor.java | 75 +++++++++++++++++--
2 files changed, 79 insertions(+), 6 deletions(-)
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java
index 560507168..431ce9ff7 100644
--- a/base/ca/src/com/netscape/ca/CertificateAuthority.java
+++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java
@@ -1929,6 +1929,16 @@ public class CertificateAuthority
}
ProfileSubsystem ps = engine.getProfileSubsystem();
+ /* NOTE: hard-coding the profile to use for Lightweight CA renewal
+ * might be OK, but caManualRenewal was not the right one to use.
+ * As a consequence, we have an undesirable special case in
+ * RenewalProcessor.processRenewal().
+ *
+ * We should introduce a new profile specifically for LWCA renewal,
+ * with an authenticator and ACLs to match the authz requirements
+ * for the renewAuthority REST resource itself. Then we can use
+ * it here, and remove the workaround from RenewalProcessor.
+ */
Profile profile = ps.getProfile("caManualRenewal");
CertEnrollmentRequest req = CertEnrollmentRequestFactory.create(
new ArgBlock(), profile, httpReq.getLocale());
diff --git a/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java b/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
index 4293cdd06..fd20f4826 100644
--- a/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
+++ b/base/ca/src/com/netscape/cms/servlet/cert/RenewalProcessor.java
@@ -32,6 +32,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.dogtagpki.server.ca.CAEngine;
+import org.dogtagpki.server.authorization.AuthzToken;
import org.mozilla.jss.netscape.security.x509.BasicConstraintsExtension;
import org.mozilla.jss.netscape.security.x509.X509CertImpl;
@@ -267,16 +268,78 @@ public class RenewalProcessor extends CertProcessor {
// before creating the request, authenticate the request
IAuthToken authToken = null;
- Principal principal = request.getUserPrincipal();
- if (principal instanceof PKIPrincipal)
- authToken = ((PKIPrincipal) principal).getAuthToken();
- if (authToken == null && authenticator != null) {
- authToken = authenticate(request, origReq, authenticator, context, true, credentials);
+
+ if (authenticator != null) {
+ /* The profile specifies an authenticator. Use it to
+ * authenticate the user. Ignore the "latent" session
+ * principal (if any).
+ */
+ authToken = authenticate(
+ request,
+ origReq,
+ authenticator,
+ context,
+ true /* isRenewal */,
+ credentials);
+ } else {
+ /* When authenticator is null, we expect manual agent
+ * review (leave authToken as null).
+ *
+ * But as a special case to ensure Lightweight CA (LWCA)
+ * renewal works, if there is a latent user in the HTTP
+ * request, we use that user (i.e. set authToken to the
+ * principal's IAuthToken) if and only if:
+ *
+ * - The renewal profile is caManualRenewal (LWCA renewal
+ * is hardcoded to use this profile); AND
+ *
+ * - The latent user is authorized to "execute"
+ * certificate requests (i.e. agent approval)
+ *
+ * See also CertificateAuthority.renewAuthority().
+ */
+
+ Principal principal = request.getUserPrincipal();
+ if (
+ renewProfileId.equals("caManualRenewal")
+ && principal instanceof PKIPrincipal
+ ) {
+ IAuthToken latentToken = ((PKIPrincipal) principal).getAuthToken();
+ AuthzToken authzToken = authorize(
+ "DirAclAuthz", latentToken, "certServer.ca.certrequests", "execute");
+ if (authzToken != null) {
+ // Success (no exception); user is authorized to approve
+ // cert requests. Set the authToken.
+ //
+ // NOTE: This authz does not replace or subsume the
+ // profile-specific authz check below.
+ authToken = latentToken;
+ } else {
+ // leave authToken as null to enqueue a pending request.
+ }
+ } else {
+ // not caManualRenewal or no latent principal;
+ // leave authToken as null to enqueue a pending request.
+ }
}
- // authentication success, now authorize
+ /* Authorize the request.
+ *
+ * If authToken != null, it will be checked against ACLs specified
+ * in the profile (if any). If ACLs are defined and authToken does
+ * not match, throws an authorization exception.
+ *
+ * If authToken == null, no check is performed (even if the profile
+ * defines ACLs). This is fine, because null authToken will cause
+ * the request status to be 'pending' [agent approval].
+ */
authorize(profileId, renewProfile, authToken);
+ /* At this point, the request will be created. If authToken
+ * is non-null, then the certificate will be issued
+ * immediately. Otherwise the request will be pending. */
+
+
///////////////////////////////////////////////
// create and populate requests
///////////////////////////////////////////////
--
2.29.2

View File

@ -1,23 +0,0 @@
From ab8b87af09b26c3c7ec257e0fb8e5ae931153120 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Sat, 8 Feb 2020 21:56:41 -0600
Subject: [PATCH] Removed dependency on pytest-runner
---
base/server/healthcheck/setup.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/base/server/healthcheck/setup.py b/base/server/healthcheck/setup.py
index 22db8bd0f..c629e34c0 100644
--- a/base/server/healthcheck/setup.py
+++ b/base/server/healthcheck/setup.py
@@ -32,6 +32,5 @@ setup(
'Programming Language :: Python :: 3.6',
],
python_requires='!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*',
- setup_requires=['pytest-runner'],
tests_require=['pytest'],
)
--
2.21.0

View File

@ -1,78 +0,0 @@
diff --git a/.classpath b/.classpath
index 010483ca2..b7324e612 100644
--- a/.classpath
+++ b/.classpath
@@ -30,7 +30,6 @@
<classpathentry kind="lib" path="/usr/share/java/idm-console-base.jar"/>
<classpathentry kind="lib" path="/usr/share/java/idm-console-mcc.jar"/>
<classpathentry kind="lib" path="/usr/share/java/idm-console-nmclf.jar"/>
- <classpathentry kind="lib" path="/usr/share/java/jakarta-commons-httpclient.jar"/>
<classpathentry kind="lib" path="/usr/share/java/junit.jar"/>
<classpathentry kind="lib" path="/usr/share/java/ldapjdk.jar"/>
<classpathentry kind="lib" path="/usr/share/java/jaxb-api.jar"/>
diff --git a/base/common/src/main/java/com/netscape/certsrv/client/PKIConnection.java b/base/common/src/main/java/com/netscape/certsrv/client/PKIConnection.java
index 769a640cd..4f5d4f97c 100644
--- a/base/common/src/main/java/com/netscape/certsrv/client/PKIConnection.java
+++ b/base/common/src/main/java/com/netscape/certsrv/client/PKIConnection.java
@@ -33,7 +33,6 @@ import java.util.List;
import javax.ws.rs.client.WebTarget;
-import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
@@ -288,8 +287,7 @@ public class PKIConnection {
InetSocketAddress localAddress,
HttpParams params)
throws IOException,
- UnknownHostException,
- ConnectTimeoutException {
+ UnknownHostException {
// Make sure certificate database is already initialized,
// otherwise SSLSocket will throw UnsatisfiedLinkError.
diff --git a/pki.spec b/pki.spec
index 50484a71d..542b5b101 100644
--- a/pki.spec
+++ b/pki.spec
@@ -172,7 +172,6 @@ BuildRequires: apache-commons-codec
BuildRequires: apache-commons-io
BuildRequires: apache-commons-lang3 >= 3.2
BuildRequires: apache-commons-net
-BuildRequires: jakarta-commons-httpclient
BuildRequires: glassfish-jaxb-api
BuildRequires: slf4j
BuildRequires: slf4j-jdk14
@@ -421,7 +420,6 @@ Requires: apache-commons-io
Requires: apache-commons-lang3 >= 3.2
Requires: apache-commons-logging
Requires: apache-commons-net
-Requires: jakarta-commons-httpclient
Requires: glassfish-jaxb-api
Requires: slf4j
Requires: slf4j-jdk14
diff --git a/scripts/compose_pki_test_package b/scripts/compose_pki_test_package
index 9a43baefe..1e4ac1a8f 100755
--- a/scripts/compose_pki_test_package
+++ b/scripts/compose_pki_test_package
@@ -116,7 +116,6 @@ CLASSPATH=$CLASSPATH:/usr/share/java/commons-httpclient.jar
CLASSPATH=$CLASSPATH:/usr/share/java/idm-console-base-1.1.7.jar
CLASSPATH=$CLASSPATH:/usr/share/java/idm-console-mcc.jar
CLASSPATH=$CLASSPATH:/usr/share/java/idm-console-nmclf.jar
-CLASSPATH=$CLASSPATH:/usr/share/java/jakarta-commons-httpclient.jar
CLASSPATH=$CLASSPATH:/usr/share/java/jaxb-api.jar
CLASSPATH=$CLASSPATH:/usr/share/java/jaxb/jaxb-impl.jar
CLASSPATH=$CLASSPATH:/usr/share/java/jakarta-activation/jakarta.activation.jar
diff --git a/tests/dogtag/dev_java_tests/run_junit_tests.sh b/tests/dogtag/dev_java_tests/run_junit_tests.sh
index 86fe71864..55df6c391 100644
--- a/tests/dogtag/dev_java_tests/run_junit_tests.sh
+++ b/tests/dogtag/dev_java_tests/run_junit_tests.sh
@@ -52,7 +52,6 @@ run_dev_junit_tests() {
CLASSPATH=$CLASSPATH:/usr/share/java/idm-console-base-1.1.7.jar
CLASSPATH=$CLASSPATH:/usr/share/java/idm-console-mcc.jar
CLASSPATH=$CLASSPATH:/usr/share/java/idm-console-nmclf.jar
- CLASSPATH=$CLASSPATH:/usr/share/java/jakarta-commons-httpclient.jar
CLASSPATH=$CLASSPATH:/usr/share/java/jaxb-api.jar
CLASSPATH=$CLASSPATH:/usr/share/java/jakarta-activation/jakarta.activation.jar
CLASSPATH=$CLASSPATH:/usr/share/java/ldapjdk.jar

View File

@ -2,8 +2,8 @@
Name: pki-core
################################################################################
%global vendor_id dogtag
%global brand Dogtag
%global vendor_id redhat
%global brand Red Hat
Summary: %{brand} PKI Core Package
URL: https://www.dogtagpki.org
@ -12,9 +12,9 @@ License: GPLv2 and LGPLv2
# For development (i.e. unsupported) releases, use x.y.z-0.n.<phase>.
# For official (i.e. supported) releases, use x.y.z-r where r >=1.
Version: 10.10.5
Release: 9%{?_timestamp}%{?_commit_id}%{?dist}
#global _phase -beta1
Version: 10.11.0
Release: 0.1.alpha1%{?_timestamp}%{?_commit_id}%{?dist}
%global _phase -alpha1
# To create a tarball from a version tag:
# $ git archive \
@ -31,14 +31,6 @@ Source: https://github.com/dogtagpki/pki/archive/v%{version}%{?_phase}/pki-%{ver
# > pki-VERSION-RELEASE.patch
# Patch: pki-VERSION-RELEASE.patch
# Do not remove this!! pytest-runner isn't available on RHEL. Removing this
# patch will break RHEL builds. The error message is:
# BUILDSTDERR: Download error on https://pypi.org/simple/pytest-runner/:
# [Errno 111] Connection refused -- Some packages may not be found!
Patch1: 0001-Removed-dependency-on-pytest-runner.patch
Patch2: 0001-Fix-renewal-profile-approval-process.patch
Patch3: 0001-remove-jakarta-commons-httpclient.patch
# md2man isn't available on i686. Additionally, we aren't generally multi-lib
# compatible (https://fedoraproject.org/wiki/Packaging:Java)
# so dropping i686 everywhere but RHEL-8 (which we've already shipped) seems
@ -141,8 +133,6 @@ ExcludeArch: i686
%define debug_package %{nil}
%endif
%bcond_without sdnotify
# ignore unpackaged files from native 'tpsclient'
# REMINDER: Remove this '%%define' once 'tpsclient' is rewritten as a Java app
%define _unpackaged_files_terminate_build 0
@ -209,7 +199,6 @@ BuildRequires: policycoreutils
BuildRequires: python3-lxml
BuildRequires: python3-sphinx
BuildRequires: velocity
BuildRequires: xalan-j2
BuildRequires: xerces-j2
@ -219,7 +208,6 @@ BuildRequires: resteasy >= 3.0.26
BuildRequires: jboss-annotations-1.2-api
BuildRequires: jboss-jaxrs-2.0-api
BuildRequires: jboss-logging
BuildRequires: resteasy-atom-provider >= 3.0.17-1
BuildRequires: resteasy-client >= 3.0.17-1
BuildRequires: resteasy-jaxb-provider >= 3.0.17-1
BuildRequires: resteasy-core >= 3.0.17-1
@ -233,7 +221,6 @@ BuildRequires: python3-cryptography
BuildRequires: python3-lxml
BuildRequires: python3-ldap
BuildRequires: python3-libselinux
BuildRequires: python3-nss
BuildRequires: python3-requests >= 2.6.0
BuildRequires: python3-six
@ -243,13 +230,9 @@ BuildRequires: python3-pytest-runner
BuildRequires: junit
BuildRequires: jpackage-utils >= 0:1.7.5-10
BuildRequires: jss >= 4.8.1
BuildRequires: jss >= 4.9.0
BuildRequires: tomcatjss >= 7.6.1
# JNA is used to bind to libsystemd
%if %{with sdnotify}
BuildRequires: jna
%endif
BuildRequires: systemd-units
%if 0%{?rhel} && ! 0%{?eln}
@ -370,7 +353,7 @@ Summary: PKI Symmetric Key Package
Requires: %java_headless >= %{min_java_version}
Requires: jpackage-utils >= 0:1.7.5-10
Requires: jss >= 4.8.0
Requires: jss >= 4.9.0
Requires: nss >= 3.38.0
# Ensure we end up with a useful installation
@ -423,7 +406,6 @@ Requires: python3 >= 3.5
Requires: python3-cryptography
Requires: python3-ldap
Requires: python3-lxml
Requires: python3-nss
Requires: python3-requests >= 2.6.0
Requires: python3-six
@ -448,14 +430,13 @@ Requires: glassfish-jaxb-api
Requires: slf4j
Requires: slf4j-jdk14
Requires: jpackage-utils >= 0:1.7.5-10
Requires: jss >= 4.7.0
Requires: jss >= 4.9.0
Requires: ldapjdk >= 4.22.0
Requires: pki-base = %{version}-%{release}
%if 0%{?rhel} && 0%{?rhel} <= 8
Requires: resteasy >= 3.0.26
%else
Requires: resteasy-atom-provider >= 3.0.17-1
Requires: resteasy-client >= 3.0.17-1
Requires: resteasy-jaxb-provider >= 3.0.17-1
Requires: resteasy-core >= 3.0.17-1
@ -469,7 +450,6 @@ Requires: jakarta-activation >= 1.2.2
Requires: xalan-j2
Requires: xerces-j2
Requires: xml-commons-apis
Requires: xml-commons-resolver
%description -n pki-base-java
@ -531,7 +511,6 @@ Requires: pki-servlet-engine
Requires: tomcat >= 1:9.0.7
%endif
Requires: velocity
Requires: sudo
Requires: systemd
Requires(post): systemd-units
@ -540,11 +519,6 @@ Requires(postun): systemd-units
Requires(pre): shadow-utils
Requires: tomcatjss >= 7.6.1
# JNA is used to bind to libsystemd
%if %{with sdnotify}
Requires: jna
%endif
# pki-healthcheck depends on the following library
%if 0%{?rhel}
Requires: ipa-healthcheck-core
@ -871,7 +845,7 @@ java_version=`%{java_home}/bin/java -XshowSettings:properties -version 2>&1 | se
java_version=`echo $java_version | sed -e 's/^1\.//' -e 's/\..*$//'`
# assume tomcat app_server
app_server=tomcat-8.5
app_server=tomcat-9.0
%if 0%{?rhel} && 0%{?rhel} <= 8
%{__mkdir_p} build
@ -903,7 +877,6 @@ cd build
-DWITH_TKS:BOOL=%{?with_tks:ON}%{!?with_tks:OFF} \
-DWITH_TPS:BOOL=%{?with_tps:ON}%{!?with_tps:OFF} \
-DWITH_ACME:BOOL=%{?with_acme:ON}%{!?with_acme:OFF} \
-DWITH_SYSTEMD_NOTIFICATION:BOOL=%{?with_sdnotify:ON}%{!?with_sdnotify:OFF} \
-DWITH_JAVADOC:BOOL=%{?with_javadoc:ON}%{!?with_javadoc:OFF} \
-DWITH_TEST:BOOL=%{?with_test:ON}%{!?with_test:OFF} \
-DBUILD_PKI_CONSOLE:BOOL=%{?with_console:ON}%{!?with_console:OFF} \
@ -1243,10 +1216,6 @@ fi
%{_datadir}/pki/setup/
%{_datadir}/pki/server/
%if %{with sdnotify}
%{_javadir}/pki/pki-systemd.jar
%endif
# with server
%endif
@ -1394,6 +1363,9 @@ fi
################################################################################
%changelog
* Tue May 18 2021 Red Hat PKI Team <rhcs-maint@redhat.com> 10.11.0-0.1
- Rebase to PKI 10.11.0-alpha1
* Thu Apr 29 2021 Red Hat PKI Team <rhcs-maint@redhat.com> 10.10.5-9
- Disable non-core packages

View File

@ -1 +1 @@
SHA512 (pki-10.10.5.tar.gz) = 2a70a4dc152e10eb27be7620e876db8237b97af0d3c1d56f840e68ea6035c01f5801318f371ec65d3aa24f505db373b77e6635ba8ed1a95d20a9fc657e9977d5
SHA512 (pki-10.11.0-alpha1.tar.gz) = e35a30879c47df96400e40d817e722270027c681b92d6032330fc787b603a4550a08e0d440113250a79c46dc96d1cdf6e9fe8fb1374264a721d23630585a0cea