diff options
Diffstat (limited to 'base')
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 116bc94bf..08f5bea50 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 42fd439de..bc6dd71a6 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 ee40b24a8..a69a3d122 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 000000000..bcb0b80a2 --- /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 000000000..a78ffaee0 --- /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 2c026b799..93d50b670 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 1a186f627..0bd285136 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 1d5958824..53e06ca6e 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 fb4293ffe..c984daa65 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 e0110e6a8..17728dd13 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 356fd1569..9f1ffbe02 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 50fe82cc3..da7f22031 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 553e849fa..5ecd56092 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 1805d15c4..b34d9fe13 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 db463ea59..d85abd6e0 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 4a837165f..e72bb0cef 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 2a2c3b3ab..a7ec566ce 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 fe82d5fcd..01c8a0ee9 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 a8099003f..dba6d9c01 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 9b4b97c2a..5e9ae4116 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 0a529f060..567747f5b 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 280ffe1dc..0ed23f697 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 8eda09bc3..cd2e14058 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 e6816721c..21b37f801 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 90897683e..6de7f08e5 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 5493bb4da..229a64c95 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() { |