summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2012-10-10 04:38:05 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2012-11-08 11:20:05 -0500
commitcb209df95c4dee11f2a912e20b417fa3bc41c88f (patch)
treeb50824cdfd3bc4ec3db905b94ef7750d9ff74844
parent906acfd2c82d195a7c55a2af7c4d7abe8ed2655a (diff)
downloadpki-cb209df95c4dee11f2a912e20b417fa3bc41c88f.zip
pki-cb209df95c4dee11f2a912e20b417fa3bc41c88f.tar.gz
pki-cb209df95c4dee11f2a912e20b417fa3bc41c88f.tar.xz
Added ACLInterceptor.
Previously ACL checking was done in PKIRealm by matching the URL. This code has been replaced by ACLInterceptor which will intercept RESTEasy method invocations. This allows more precise mapping of REST methods to ACL entries in acl.ldif. Ticket #287
-rw-r--r--base/ca/shared/webapps/ca/WEB-INF/auth.properties18
-rw-r--r--base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java4
-rw-r--r--base/common/src/com/netscape/certsrv/account/AccountResource.java4
-rw-r--r--base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java154
-rw-r--r--base/common/src/com/netscape/certsrv/acls/ACLMapping.java31
-rw-r--r--base/common/src/com/netscape/certsrv/ca/CAClient.java2
-rw-r--r--base/common/src/com/netscape/certsrv/cert/CertRequestResource.java24
-rw-r--r--base/common/src/com/netscape/certsrv/cert/CertResource.java4
-rw-r--r--base/common/src/com/netscape/certsrv/group/GroupMemberResource.java3
-rw-r--r--base/common/src/com/netscape/certsrv/group/GroupResource.java3
-rw-r--r--base/common/src/com/netscape/certsrv/key/KeyRequestResource.java2
-rw-r--r--base/common/src/com/netscape/certsrv/key/KeyResource.java3
-rw-r--r--base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java9
-rw-r--r--base/common/src/com/netscape/certsrv/system/SecurityDomainResource.java3
-rw-r--r--base/common/src/com/netscape/certsrv/user/UserCertResource.java3
-rw-r--r--base/common/src/com/netscape/certsrv/user/UserResource.java3
-rw-r--r--base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java9
-rw-r--r--base/common/src/com/netscape/cms/servlet/key/KeyService.java2
-rw-r--r--base/common/src/com/netscape/cms/servlet/request/CertRequestService.java15
-rw-r--r--base/common/src/com/netscape/cmscore/realm/PKIRealm.java221
-rw-r--r--base/kra/shared/webapps/kra/WEB-INF/auth.properties16
-rw-r--r--base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java3
-rw-r--r--base/ocsp/shared/webapps/ocsp/WEB-INF/auth.properties12
-rw-r--r--base/ocsp/src/com/netscape/ocsp/OCSPApplication.java4
-rw-r--r--base/tks/shared/webapps/tks/WEB-INF/auth.properties12
-rw-r--r--base/tks/src/com/netscape/tks/TKSApplication.java4
26 files changed, 299 insertions, 269 deletions
diff --git a/base/ca/shared/webapps/ca/WEB-INF/auth.properties b/base/ca/shared/webapps/ca/WEB-INF/auth.properties
index 116bc94..08f5bea 100644
--- a/base/ca/shared/webapps/ca/WEB-INF/auth.properties
+++ b/base/ca/shared/webapps/ca/WEB-INF/auth.properties
@@ -1,13 +1,13 @@
# Restful API auth/authz mapping info
#
# Format:
-# <Rest API URL> = <ACL Resource ID>,<ACL resource operation>
-# ex: /ca/pki/users = certServer.ca.users,read
+# <ACL Mapping> = <ACL Resource ID>,<ACL Resource Operation>
+# ex: admin.users = certServer.ca.users,read
-/ca/rest/account/login = certServer.ca.account,login
-/ca/rest/account/logout = certServer.ca.account,logout
-/ca/rest/admin/users = certServer.ca.users,execute
-/ca/rest/admin/groups = certServer.ca.groups,execute
-/ca/rest/agent/certrequests = certServer.ca.certrequests,execute
-/ca/rest/agent/certs = certServer.ca.certs,execute
-/ca/rest/securityDomain/installToken = certServer.securitydomain.domainxml,read
+account.login = certServer.ca.account,login
+account.logout = certServer.ca.account,logout
+admin.users = certServer.ca.users,execute
+admin.groups = certServer.ca.groups,execute
+agent.certrequests = certServer.ca.certrequests,execute
+agent.certs = certServer.ca.certs,execute
+securityDomain.installToken = certServer.securitydomain.domainxml,read
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java b/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java
index 42fd439..bc6dd71 100644
--- a/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java
+++ b/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java
@@ -5,6 +5,7 @@ import java.util.Set;
import javax.ws.rs.core.Application;
+import com.netscape.certsrv.acls.ACLInterceptor;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IConfigStore;
@@ -79,6 +80,9 @@ public class CertificateAuthorityApplication extends Application {
// exception mapper
classes.add(PKIException.Mapper.class);
+
+ // ACL interceptor
+ singletons.add(new ACLInterceptor());
}
public Set<Class<?>> getClasses() {
diff --git a/base/common/src/com/netscape/certsrv/account/AccountResource.java b/base/common/src/com/netscape/certsrv/account/AccountResource.java
index ee40b24..a69a3d1 100644
--- a/base/common/src/com/netscape/certsrv/account/AccountResource.java
+++ b/base/common/src/com/netscape/certsrv/account/AccountResource.java
@@ -21,6 +21,8 @@ package com.netscape.certsrv.account;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
+import com.netscape.certsrv.acls.ACLMapping;
+
/**
* @author Endi S. Dewata
*/
@@ -29,9 +31,11 @@ public interface AccountResource {
@GET
@Path("login")
+ @ACLMapping("account.login")
public void login();
@GET
@Path("logout")
+ @ACLMapping("account.logout")
public void logout();
}
diff --git a/base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java b/base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java
new file mode 100644
index 0000000..bcb0b80
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/ACLInterceptor.java
@@ -0,0 +1,154 @@
+//--- BEGIN COPYRIGHT BLOCK ---
+//This program is free software; you can redistribute it and/or modify
+//it under the terms of the GNU General Public License as published by
+//the Free Software Foundation; version 2 of the License.
+//
+//This program is distributed in the hope that it will be useful,
+//but WITHOUT ANY WARRANTY; without even the implied warranty of
+//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//GNU General Public License for more details.
+//
+//You should have received a copy of the GNU General Public License along
+//with this program; if not, write to the Free Software Foundation, Inc.,
+//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+//(C) 2012 Red Hat, Inc.
+//All rights reserved.
+//--- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.acls;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.security.Principal;
+import java.util.Properties;
+
+import javax.servlet.ServletContext;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.ext.Provider;
+
+import org.jboss.resteasy.annotations.interception.Precedence;
+import org.jboss.resteasy.annotations.interception.ServerInterceptor;
+import org.jboss.resteasy.core.ResourceMethod;
+import org.jboss.resteasy.core.ServerResponse;
+import org.jboss.resteasy.spi.Failure;
+import org.jboss.resteasy.spi.HttpRequest;
+import org.jboss.resteasy.spi.interception.PreProcessInterceptor;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.AuthzToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.cmscore.realm.PKIPrincipal;
+
+
+/**
+ * @author Endi S. Dewata
+ */
+@Provider
+@ServerInterceptor
+@Precedence("SECURITY")
+public class ACLInterceptor implements PreProcessInterceptor {
+
+ Properties authProperties;
+
+ @Context
+ ServletContext servletContext;
+
+ @Context
+ SecurityContext securityContext;
+
+ public synchronized void loadAuthProperties() throws IOException {
+
+ if (authProperties != null) return;
+
+ URL url = servletContext.getResource("/WEB-INF/auth.properties");
+ authProperties = new Properties();
+ authProperties.load(url.openStream());
+ }
+
+ @Override
+ public ServerResponse preProcess(
+ HttpRequest request,
+ ResourceMethod resourceMethod
+ ) throws Failure, WebApplicationException {
+
+ // Get ACL mapping for the method.
+ Method method = resourceMethod.getMethod();
+ ACLMapping aclMapping = method.getAnnotation(ACLMapping.class);
+
+ // If not available, get ACL mapping for the class.
+ if (aclMapping == null) {
+ Class<?> clazz = method.getDeclaringClass();
+ aclMapping = clazz.getAnnotation(ACLMapping.class);
+ }
+
+ // If still not available, it's unprotected, allow request.
+ if (aclMapping == null) return null;
+
+ Principal principal = securityContext.getUserPrincipal();
+
+ // If unauthenticated, reject request.
+ if (principal == null) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ // If unrecognized principal, reject request.
+ if (!(principal instanceof PKIPrincipal)) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ PKIPrincipal pkiPrincipal = (PKIPrincipal)principal;
+ IAuthToken authToken = pkiPrincipal.getAuthToken();
+
+ // If missing auth token, reject request.
+ if (authToken == null) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ try {
+ loadAuthProperties();
+
+ String name = aclMapping.value();
+ String value = authProperties.getProperty(name);
+
+ // If no property defined, allow request.
+ if (value == null) return null;
+
+ String values[] = value.split(",");
+
+ // If invalid mapping, reject request.
+ if (values.length != 2) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ // Check authorization.
+ IAuthzSubsystem mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+ AuthzToken authzToken = mAuthz.authorize(
+ "DirAclAuthz",
+ authToken,
+ values[0], // resource
+ values[1]); // operation
+
+ // If not authorized, reject request.
+ if (authzToken == null) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+ }
+
+ } catch (EAuthzAccessDenied e) {
+ throw new WebApplicationException(Response.Status.FORBIDDEN);
+
+ } catch (IOException|EBaseException e) {
+ e.printStackTrace();
+ throw new Failure(e);
+ }
+
+ // Allow request.
+ return null;
+ }
+}
diff --git a/base/common/src/com/netscape/certsrv/acls/ACLMapping.java b/base/common/src/com/netscape/certsrv/acls/ACLMapping.java
new file mode 100644
index 0000000..a78ffae
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/acls/ACLMapping.java
@@ -0,0 +1,31 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.certsrv.acls;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+
+/**
+ * @author Endi S. Dewata
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ACLMapping {
+ public String value();
+}
diff --git a/base/common/src/com/netscape/certsrv/ca/CAClient.java b/base/common/src/com/netscape/certsrv/ca/CAClient.java
index 2c026b7..93d50b6 100644
--- a/base/common/src/com/netscape/certsrv/ca/CAClient.java
+++ b/base/common/src/com/netscape/certsrv/ca/CAClient.java
@@ -64,7 +64,7 @@ public class CAClient extends PKIClient {
CertRequestInfos infos = null;
Collection<CertRequestInfo> list = null;
infos = certRequestClient.listRequests(
- requestState, requestType, new RequestId(0), 100, 100, 10);
+ requestState, requestType, null, null, null, null);
list = infos.getRequests();
return list;
diff --git a/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java b/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java
index 1a186f6..0bd2851 100644
--- a/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java
+++ b/base/common/src/com/netscape/certsrv/cert/CertRequestResource.java
@@ -18,7 +18,6 @@
package com.netscape.certsrv.cert;
import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -28,28 +27,25 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import com.netscape.certsrv.acls.ACLMapping;
import com.netscape.certsrv.request.RequestId;
@Path("")
public interface CertRequestResource {
- public static final int DEFAULT_START = 0;
- public static final int DEFAULT_PAGESIZE = 20;
- public static final int DEFAULT_MAXRESULTS = 100;
- public static final int DEFAULT_MAXTIME = 10;
-
/**
* Used to generate list of cert requests based on the search parameters
*/
@GET
@Path("agent/certrequests")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public CertRequestInfos listRequests(@QueryParam("requestState") String requestState,
@QueryParam("requestType") String requestType,
- @DefaultValue("" + DEFAULT_START) @QueryParam("start") RequestId start,
- @DefaultValue("" + DEFAULT_PAGESIZE) @QueryParam("pageSize") int pageSize,
- @DefaultValue("" + DEFAULT_MAXRESULTS) @QueryParam("maxResults") int maxResults,
- @DefaultValue("" + DEFAULT_MAXTIME) @QueryParam("maxTime") int maxTime);
+ @QueryParam("start") RequestId start,
+ @QueryParam("pageSize") Integer pageSize,
+ @QueryParam("maxResults") Integer maxResults,
+ @QueryParam("maxTime") Integer maxTime);
/**
* Used to retrieve cert request info for a specific request
@@ -62,6 +58,7 @@ public interface CertRequestResource {
@GET
@Path("agent/certrequests/{id}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public CertReviewResponse reviewRequest(@PathParam("id") RequestId id);
// Enrollment - used to test integration with a browser
@@ -80,35 +77,42 @@ public interface CertRequestResource {
@POST
@Path("agent/certrequests/{id}/approve")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public void approveRequest(@PathParam("id") RequestId id, CertReviewResponse data);
@POST
@Path("agent/certrequests/{id}/reject")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public void rejectRequest(@PathParam("id") RequestId id, CertReviewResponse data);
@POST
@Path("agent/certrequests/{id}/cancel")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public void cancelRequest(@PathParam("id") RequestId id, CertReviewResponse data);
@POST
@Path("agent/certrequests/{id}/update")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public void updateRequest(@PathParam("id") RequestId id, CertReviewResponse data);
@POST
@Path("agent/certrequests/{id}/validate")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public void validateRequest(@PathParam("id") RequestId id, CertReviewResponse data);
@POST
@Path("agent/certrequests/{id}/unassign")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public void unassignRequest(@PathParam("id") RequestId id, CertReviewResponse data);
@POST
@Path("agent/certrequests/{id}/assign")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certrequests")
public void assignRequest(@PathParam("id") RequestId id, CertReviewResponse data);
}
diff --git a/base/common/src/com/netscape/certsrv/cert/CertResource.java b/base/common/src/com/netscape/certsrv/cert/CertResource.java
index 1d59588..53e06ca 100644
--- a/base/common/src/com/netscape/certsrv/cert/CertResource.java
+++ b/base/common/src/com/netscape/certsrv/cert/CertResource.java
@@ -10,6 +10,7 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+import com.netscape.certsrv.acls.ACLMapping;
import com.netscape.certsrv.dbs.certdb.CertId;
@Path("")
@@ -44,17 +45,20 @@ public interface CertResource {
@Path("agent/certs/{id}/revoke-ca")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certs")
public CertRequestInfo revokeCACert(@PathParam("id") CertId id, CertRevokeRequest request);
@POST
@Path("agent/certs/{id}/revoke")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certs")
public CertRequestInfo revokeCert(@PathParam("id") CertId id, CertRevokeRequest request);
@POST
@Path("agent/certs/{id}/unrevoke")
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("agent.certs")
public CertRequestInfo unrevokeCert(@PathParam("id") CertId id, CertUnrevokeRequest request);
}
diff --git a/base/common/src/com/netscape/certsrv/group/GroupMemberResource.java b/base/common/src/com/netscape/certsrv/group/GroupMemberResource.java
index fb4293f..c984daa 100644
--- a/base/common/src/com/netscape/certsrv/group/GroupMemberResource.java
+++ b/base/common/src/com/netscape/certsrv/group/GroupMemberResource.java
@@ -31,10 +31,13 @@ import javax.ws.rs.core.Response;
import org.jboss.resteasy.annotations.ClientResponseType;
+import com.netscape.certsrv.acls.ACLMapping;
+
/**
* @author Endi S. Dewata
*/
@Path("admin/groups/{groupID}/members")
+@ACLMapping("admin.groups")
public interface GroupMemberResource {
@GET
diff --git a/base/common/src/com/netscape/certsrv/group/GroupResource.java b/base/common/src/com/netscape/certsrv/group/GroupResource.java
index e0110e6..17728dd 100644
--- a/base/common/src/com/netscape/certsrv/group/GroupResource.java
+++ b/base/common/src/com/netscape/certsrv/group/GroupResource.java
@@ -31,10 +31,13 @@ import javax.ws.rs.core.Response;
import org.jboss.resteasy.annotations.ClientResponseType;
+import com.netscape.certsrv.acls.ACLMapping;
+
/**
* @author Endi S. Dewata
*/
@Path("admin/groups")
+@ACLMapping("admin.groups")
public interface GroupResource {
@GET
diff --git a/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java b/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java
index 356fd15..9f1ffbe 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyRequestResource.java
@@ -10,9 +10,11 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import com.netscape.certsrv.acls.ACLMapping;
import com.netscape.certsrv.request.RequestId;
@Path("agent/keyrequests")
+@ACLMapping("agent.keyrequests")
public interface KeyRequestResource {
public final String SYMMETRIC_KEY_TYPE = "symmetricKey";
diff --git a/base/common/src/com/netscape/certsrv/key/KeyResource.java b/base/common/src/com/netscape/certsrv/key/KeyResource.java
index 50fe82c..da7f220 100644
--- a/base/common/src/com/netscape/certsrv/key/KeyResource.java
+++ b/base/common/src/com/netscape/certsrv/key/KeyResource.java
@@ -9,8 +9,11 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
+import com.netscape.certsrv.acls.ACLMapping;
+
@Path("agent/keys")
+@ACLMapping("agent.keys")
public interface KeyResource {
@GET
diff --git a/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java b/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java
index 553e849..5ecd560 100644
--- a/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java
+++ b/base/common/src/com/netscape/certsrv/system/SecurityDomainClient.java
@@ -21,6 +21,7 @@ import java.net.URISyntaxException;
import com.netscape.certsrv.client.ClientConfig;
import com.netscape.certsrv.client.PKIClient;
+import com.netscape.certsrv.client.PKIConnection;
/**
@@ -30,9 +31,17 @@ public class SecurityDomainClient extends PKIClient {
private SecurityDomainResource client;
+ public SecurityDomainClient(PKIConnection connection) throws URISyntaxException {
+ super(connection);
+ init();
+ }
+
public SecurityDomainClient(ClientConfig config) throws URISyntaxException {
super(config);
+ init();
+ }
+ public void init() throws URISyntaxException {
client = createProxy(SecurityDomainResource.class);
}
diff --git a/base/common/src/com/netscape/certsrv/system/SecurityDomainResource.java b/base/common/src/com/netscape/certsrv/system/SecurityDomainResource.java
index 1805d15..b34d9fe 100644
--- a/base/common/src/com/netscape/certsrv/system/SecurityDomainResource.java
+++ b/base/common/src/com/netscape/certsrv/system/SecurityDomainResource.java
@@ -23,6 +23,8 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
+import com.netscape.certsrv.acls.ACLMapping;
+
/**
* @author alee
*/
@@ -32,6 +34,7 @@ public interface SecurityDomainResource {
@GET
@Path("installToken")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @ACLMapping("securityDomain.installToken")
public InstallToken getInstallToken(
@QueryParam("hostname") String hostname,
@QueryParam("subsystem") String subsystem);
diff --git a/base/common/src/com/netscape/certsrv/user/UserCertResource.java b/base/common/src/com/netscape/certsrv/user/UserCertResource.java
index db463ea..d85abd6 100644
--- a/base/common/src/com/netscape/certsrv/user/UserCertResource.java
+++ b/base/common/src/com/netscape/certsrv/user/UserCertResource.java
@@ -31,10 +31,13 @@ import javax.ws.rs.core.Response;
import org.jboss.resteasy.annotations.ClientResponseType;
+import com.netscape.certsrv.acls.ACLMapping;
+
/**
* @author Endi S. Dewata
*/
@Path("admin/users/{userID}/certs")
+@ACLMapping("admin.users")
public interface UserCertResource {
@GET
diff --git a/base/common/src/com/netscape/certsrv/user/UserResource.java b/base/common/src/com/netscape/certsrv/user/UserResource.java
index 4a83716..e72bb0c 100644
--- a/base/common/src/com/netscape/certsrv/user/UserResource.java
+++ b/base/common/src/com/netscape/certsrv/user/UserResource.java
@@ -31,10 +31,13 @@ import javax.ws.rs.core.Response;
import org.jboss.resteasy.annotations.ClientResponseType;
+import com.netscape.certsrv.acls.ACLMapping;
+
/**
* @author Endi S. Dewata
*/
@Path("admin/users")
+@ACLMapping("admin.users")
public interface UserResource {
@GET
diff --git a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
index 2a2c3b3..a7ec566 100644
--- a/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
+++ b/base/common/src/com/netscape/cms/servlet/csadmin/ConfigurationUtils.java
@@ -129,6 +129,7 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
+import com.netscape.certsrv.account.AccountClient;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.authentication.EAuthException;
import com.netscape.certsrv.authentication.IAuthSubsystem;
@@ -325,10 +326,14 @@ public class ConfigurationUtils {
config.setUsername(user);
config.setPassword(passwd);
- SecurityDomainClient client = new SecurityDomainClient(config);
+ PKIConnection connection = new PKIConnection(config);
+ AccountClient accountClient = new AccountClient(connection);
+ SecurityDomainClient sdClient = new SecurityDomainClient(connection);
try {
- InstallToken token = client.getInstallToken(sdhost, csType);
+ accountClient.login();
+ InstallToken token = sdClient.getInstallToken(sdhost, csType);
+ accountClient.logout();
return token.getToken();
} catch (ClientResponseFailure e) {
diff --git a/base/common/src/com/netscape/cms/servlet/key/KeyService.java b/base/common/src/com/netscape/cms/servlet/key/KeyService.java
index fe82d5f..01c8a0e 100644
--- a/base/common/src/com/netscape/cms/servlet/key/KeyService.java
+++ b/base/common/src/com/netscape/cms/servlet/key/KeyService.java
@@ -52,7 +52,7 @@ import com.netscape.cmsutil.ldap.LDAPUtil;
* @author alee
*
*/
-public class KeyService extends PKIService implements KeyResource{
+public class KeyService extends PKIService implements KeyResource {
public static final int DEFAULT_MAXRESULTS = 100;
public static final int DEFAULT_MAXTIME = 10;
diff --git a/base/common/src/com/netscape/cms/servlet/request/CertRequestService.java b/base/common/src/com/netscape/cms/servlet/request/CertRequestService.java
index a809900..dba6d9c 100644
--- a/base/common/src/com/netscape/cms/servlet/request/CertRequestService.java
+++ b/base/common/src/com/netscape/cms/servlet/request/CertRequestService.java
@@ -50,6 +50,11 @@ import com.netscape.cmsutil.ldap.LDAPUtil;
*/
public class CertRequestService extends PKIService implements CertRequestResource {
+ public static final int DEFAULT_START = 0;
+ public static final int DEFAULT_PAGESIZE = 20;
+ public static final int DEFAULT_MAXRESULTS = 100;
+ public static final int DEFAULT_MAXTIME = 10;
+
/**
* Used to retrieve key request info for a specific request
*/
@@ -194,17 +199,17 @@ public class CertRequestService extends PKIService implements CertRequestResourc
* Used to generate list of cert requests based on the search parameters
*/
public CertRequestInfos listRequests(String requestState, String requestType,
- RequestId start, int pageSize, int maxResults, int maxTime) {
+ RequestId start, Integer pageSize, Integer maxResults, Integer maxTime) {
// auth and authz
// get ldap filter
String filter = createSearchFilter(requestState, requestType);
CMS.debug("listRequests: filter is " + filter);
- // get start marker
- if (start == null) {
- start = new RequestId(CertRequestResource.DEFAULT_START);
- }
+ start = start == null ? new RequestId(CertRequestService.DEFAULT_START) : start;
+ pageSize = pageSize == null ? DEFAULT_PAGESIZE : pageSize;
+ maxResults = maxResults == null ? DEFAULT_MAXRESULTS : maxResults;
+ maxTime = maxTime == null ? DEFAULT_MAXTIME : maxTime;
CertRequestDAO reqDAO = new CertRequestDAO();
CertRequestInfos requests;
diff --git a/base/common/src/com/netscape/cmscore/realm/PKIRealm.java b/base/common/src/com/netscape/cmscore/realm/PKIRealm.java
index 9b4b97c..5e9ae41 100644
--- a/base/common/src/com/netscape/cmscore/realm/PKIRealm.java
+++ b/base/common/src/com/netscape/cmscore/realm/PKIRealm.java
@@ -1,31 +1,19 @@
package com.netscape.cmscore.realm;
-import java.io.IOException;
-import java.io.InputStream;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
-import java.util.Properties;
-
-import javax.servlet.http.HttpServletResponse;
import netscape.security.x509.X509CertImpl;
-import org.apache.catalina.Context;
-import org.apache.catalina.LifecycleException;
-import org.apache.catalina.connector.Request;
-import org.apache.catalina.connector.Response;
-import org.apache.catalina.deploy.SecurityConstraint;
import org.apache.catalina.realm.RealmBase;
import com.netscape.certsrv.apps.CMS;
import com.netscape.certsrv.authentication.IAuthManager;
import com.netscape.certsrv.authentication.IAuthSubsystem;
import com.netscape.certsrv.authentication.IAuthToken;
-import com.netscape.certsrv.authorization.AuthzToken;
-import com.netscape.certsrv.authorization.IAuthzSubsystem;
import com.netscape.certsrv.usrgrp.EUsrGrpException;
import com.netscape.certsrv.usrgrp.IGroup;
import com.netscape.certsrv.usrgrp.IUGSubsystem;
@@ -44,27 +32,6 @@ import com.netscape.cmscore.authentication.PasswdUserDBAuthentication;
public class PKIRealm extends RealmBase {
- public final static String PROP_AUTH_FILE_PATH = "/WEB-INF/auth.properties";
- public final static int EXPRESSION_SIZE = 2;
-
- Properties authzProperties;
-
- public PKIRealm() {
- logDebug("Creating PKI realm");
- }
-
- @Override
- protected void initInternal() throws LifecycleException {
- logDebug("Initializing PKI realm");
- super.initInternal();
- }
-
- @Override
- protected void startInternal() throws LifecycleException {
- logDebug("Starting PKI realm");
- super.startInternal();
- }
-
@Override
protected String getName() {
return "PKIRealm";
@@ -180,194 +147,6 @@ public class PKIRealm extends RealmBase {
return null;
}
- /**
- * Perform access control based on the specified authorization constraint.
- * Return <code>true</code> if this constraint is satisfied and processing
- * should continue, or <code>false</code> otherwise.
- * override to check for custom PKI ACL's authz permissions.
- *
- * @param request Request we are processing
- * @param response Response we are creating
- * @param constraints Security constraint we are enforcing
- * @param context The Context to which client of this class is attached.
- *
- * @exception IOException if an input/output error occurs
- */
- @Override
- public boolean hasResourcePermission(Request request,
- Response response,
- SecurityConstraint[] constraints,
- Context context)
- throws IOException {
-
- String requestURI = request.getDecodedRequestURI();
- logDebug("Checking permission: "+requestURI);
-
- boolean allowed = super.hasResourcePermission(request, response, constraints, context);
- logDebug("Resource permission: "+allowed);
-
- if (allowed) {
- allowed = checkACL(request, response, constraints, context);
- logDebug("ACL permission: "+allowed);
- }
-
- if (!allowed) {
- response.sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("realmBase.forbidden"));
- }
-
- return allowed;
- }
-
- public boolean checkACL(Request request,
- Response response,
- SecurityConstraint[] constraints,
- Context context) {
-
- try {
- loadAuthzProperties(context);
- if (!hasAuthzProperties()) return false;
-
- String requestURI = request.getDecodedRequestURI();
- String match = getACLEntry(requestURI);
- if (match == null) return false;
-
- logDebug("ACL: "+match);
- String[] authzParams = match.split("\\,");
-
- String resource = null;
- String operation = null;
-
- if (authzParams.length >= EXPRESSION_SIZE) {
- resource = authzParams[0];
- operation = authzParams[1];
-
- if (resource != null) {
- resource = resource.trim();
- }
-
- if (operation != null) {
- operation = operation.trim();
- }
- }
-
- Principal principal = request.getUserPrincipal();
- if (principal instanceof PKIPrincipal) {
- PKIPrincipal pkiPrincipal = (PKIPrincipal)principal;
- IAuthToken authToken = pkiPrincipal.getAuthToken();
-
- logDebug("Auth token:");
- Enumeration<String> names = authToken.getElements();
- while (names.hasMoreElements()) {
- String name = names.nextElement();
- Object value = authToken.get(name);
- logDebug(" " + name +": " + value);
- }
-
- logDebug("Resource: " + resource);
- logDebug("Operation: " + operation);
-
- IAuthzSubsystem mAuthz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
- AuthzToken authzToken = mAuthz.authorize("DirAclAuthz", authToken, resource, operation);
- if (authzToken != null) return true;
- }
-
- } catch (Throwable e) {
- e.printStackTrace();
- }
-
- return false;
- }
-
- // Search for the proper auth.properties entry corresponding
- // to a particular incoming URL
- // TODO: In the admin interface, often the operation is sent
- // as one of the parameters to the message.
- // There may be a way to extract this information at this level.
- // The parameter name to scan for could be configured with the Realm.
-
- public String getACLEntry(String requestURI) {
-
- if (!hasAuthzProperties()) {
- return null;
- }
-
- logDebug("Checking path: "+requestURI);
- String aclEntryData = authzProperties.getProperty(requestURI);
-
- if (aclEntryData != null) {
- logDebug("Found exact match: "+aclEntryData);
- return aclEntryData;
- }
-
- // Check for a partial match such as
- // ex: /kra/pki/keyrequest/2
- // TODO: Check into more sophisticated
- // methods of doing this mapping.
- // Perhaps Rest gives us this more
- // sophisticated mapping ability.
-
- Properties props = authzProperties;
- Enumeration<?> e = props.propertyNames();
-
- while (e.hasMoreElements()) {
- String key = (String) e.nextElement();
- if (requestURI.startsWith(key)) {
- aclEntryData = props.getProperty(key);
- logDebug("Found partial match ["+key+"]: "+aclEntryData);
- break;
- }
- }
-
- if (aclEntryData == null) {
- logDebug("No match found");
- }
-
- return aclEntryData;
-
- }
-
- // Check to see if we have read in the auth properties file
- public boolean hasAuthzProperties() {
-
- if (authzProperties != null) {
- return true;
- } else {
- return false;
- }
- }
-
- // Load the custom mapping file auth.properties, which maps urls to acl resourceID and operation value
- // example entry: /kra/pki/config/cert/transport = certServer.kra.pki.config.cert.transport,read
- // TODO: Look into a more sophisticated method than this simple properties file if appropriate.
- public synchronized void loadAuthzProperties(Context context) throws IOException {
-
- if (authzProperties == null && context != null) {
-
- InputStream inputStream = context.getServletContext().getResourceAsStream(PROP_AUTH_FILE_PATH);
-
- if (inputStream == null) {
- logDebug("Resource "+PROP_AUTH_FILE_PATH+" not found.");
- throw new IOException("Resource "+PROP_AUTH_FILE_PATH+" not found.");
- }
-
- try {
- logDebug("Loading authorization properties");
-
- Properties properties = new Properties();
- properties.load(inputStream);
-
- authzProperties = properties;
-
- } finally {
- try {
- inputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
-
/*
* TODO: Figure out how to do real logging
*/
diff --git a/base/kra/shared/webapps/kra/WEB-INF/auth.properties b/base/kra/shared/webapps/kra/WEB-INF/auth.properties
index 0a529f0..567747f 100644
--- a/base/kra/shared/webapps/kra/WEB-INF/auth.properties
+++ b/base/kra/shared/webapps/kra/WEB-INF/auth.properties
@@ -1,12 +1,12 @@
# Restful API auth/authz mapping info
#
# Format:
-# <Rest API URL> = <ACL Resource ID>,<ACL resource operation>
-# ex: /kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute
+# <ACL Mapping> = <ACL Resource ID>,<ACL Resource Operation>
+# ex: admin.users = certServer.ca.users,read
-/kra/rest/account/login = certServer.kra.account,login
-/kra/rest/account/logout = certServer.kra.account,logout
-/kra/rest/admin/users = certServer.kra.users,execute
-/kra/rest/admin/groups = certServer.kra.groups,execute
-/kra/rest/agent/keys = certServer.kra.keys,execute
-/kra/rest/agent/keyrequests = certServer.kra.keyrequests,execute
+account.login = certServer.kra.account,login
+account.logout = certServer.kra.account,logout
+admin.users = certServer.kra.users,execute
+admin.groups = certServer.kra.groups,execute
+agent.keys = certServer.kra.keys,execute
+agent.keyrequests = certServer.kra.keyrequests,execute
diff --git a/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java b/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java
index 280ffe1..0ed23f6 100644
--- a/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java
+++ b/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java
@@ -5,6 +5,7 @@ import java.util.Set;
import javax.ws.rs.core.Application;
+import com.netscape.certsrv.acls.ACLInterceptor;
import com.netscape.certsrv.base.PKIException;
import com.netscape.cms.servlet.account.AccountService;
import com.netscape.cms.servlet.admin.GroupMemberService;
@@ -45,6 +46,8 @@ public class KeyRecoveryAuthorityApplication extends Application {
// exception mapper
classes.add(PKIException.Mapper.class);
+ // ACL interceptor
+ singletons.add(new ACLInterceptor());
}
public Set<Class<?>> getClasses() {
diff --git a/base/ocsp/shared/webapps/ocsp/WEB-INF/auth.properties b/base/ocsp/shared/webapps/ocsp/WEB-INF/auth.properties
index 8eda09b..cd2e140 100644
--- a/base/ocsp/shared/webapps/ocsp/WEB-INF/auth.properties
+++ b/base/ocsp/shared/webapps/ocsp/WEB-INF/auth.properties
@@ -1,10 +1,10 @@
# Restful API auth/authz mapping info
#
# Format:
-# <Rest API URL> = <ACL Resource ID>,<ACL resource operation>
-# ex: /kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute
+# <ACL Mapping> = <ACL Resource ID>,<ACL Resource Operation>
+# ex: admin.users = certServer.ca.users,read
-/ocsp/rest/account/login = certServer.ocsp.account,login
-/ocsp/rest/account/logout = certServer.ocsp.account,logout
-/ocsp/rest/admin/users = certServer.ocsp.users,execute
-/ocsp/rest/admin/groups = certServer.ocsp.groups,execute
+account.login = certServer.ocsp.account,login
+account.logout = certServer.ocsp.account,logout
+admin.users = certServer.ocsp.users,execute
+admin.groups = certServer.ocsp.groups,execute
diff --git a/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java b/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java
index e681672..21b37f8 100644
--- a/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java
+++ b/base/ocsp/src/com/netscape/ocsp/OCSPApplication.java
@@ -5,6 +5,7 @@ import java.util.Set;
import javax.ws.rs.core.Application;
+import com.netscape.certsrv.acls.ACLInterceptor;
import com.netscape.certsrv.base.PKIException;
import com.netscape.cms.servlet.account.AccountService;
import com.netscape.cms.servlet.admin.GroupMemberService;
@@ -38,6 +39,9 @@ public class OCSPApplication extends Application {
// exception mapper
classes.add(PKIException.Mapper.class);
+
+ // ACL interceptor
+ singletons.add(new ACLInterceptor());
}
public Set<Class<?>> getClasses() {
diff --git a/base/tks/shared/webapps/tks/WEB-INF/auth.properties b/base/tks/shared/webapps/tks/WEB-INF/auth.properties
index 9089768..6de7f08 100644
--- a/base/tks/shared/webapps/tks/WEB-INF/auth.properties
+++ b/base/tks/shared/webapps/tks/WEB-INF/auth.properties
@@ -1,10 +1,10 @@
# Restful API auth/authz mapping info
#
# Format:
-# <Rest API URL> = <ACL Resource ID>,<ACL resource operation>
-# ex: /kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute
+# <ACL Mapping> = <ACL Resource ID>,<ACL Resource Operation>
+# ex: admin.users = certServer.ca.users,read
-/tks/rest/account/login = certServer.tks.account,login
-/tks/rest/account/logout = certServer.tks.account,logout
-/tks/rest/admin/users = certServer.tks.users,execute
-/tks/rest/admin/groups = certServer.tks.groups,execute
+account.login = certServer.tks.account,login
+account.logout = certServer.tks.account,logout
+admin.users = certServer.tks.users,execute
+admin.groups = certServer.tks.groups,execute
diff --git a/base/tks/src/com/netscape/tks/TKSApplication.java b/base/tks/src/com/netscape/tks/TKSApplication.java
index 5493bb4..229a64c 100644
--- a/base/tks/src/com/netscape/tks/TKSApplication.java
+++ b/base/tks/src/com/netscape/tks/TKSApplication.java
@@ -5,6 +5,7 @@ import java.util.Set;
import javax.ws.rs.core.Application;
+import com.netscape.certsrv.acls.ACLInterceptor;
import com.netscape.certsrv.base.PKIException;
import com.netscape.cms.servlet.account.AccountService;
import com.netscape.cms.servlet.admin.GroupMemberService;
@@ -38,6 +39,9 @@ public class TKSApplication extends Application {
// exception mapper
classes.add(PKIException.Mapper.class);
+
+ // ACL interceptor
+ singletons.add(new ACLInterceptor());
}
public Set<Class<?>> getClasses() {