diff options
author | Ade Lee <alee@redhat.com> | 2012-05-31 15:29:30 -0400 |
---|---|---|
committer | Ade Lee <alee@redhat.com> | 2012-06-13 10:50:38 -0400 |
commit | ee8a68af9a4bd1fede9d5ca52f3d4bfa05525477 (patch) | |
tree | aaed4c6129c4e82c9de7716290f1672a1598f6b7 /base | |
parent | ae87af5d0234c4ae6a25ae596ea4f3828af52b17 (diff) | |
download | pki-alee_profilesubmit_0613.tar.gz pki-alee_profilesubmit_0613.tar.xz pki-alee_profilesubmit_0613.zip |
Add code to do cert approvalsalee_profilesubmit_0613
Diffstat (limited to 'base')
26 files changed, 2752 insertions, 652 deletions
diff --git a/base/ca/functional/src/com/netscape/cms/servlet/test/CARestClient.java b/base/ca/functional/src/com/netscape/cms/servlet/test/CARestClient.java index 078e7da8..5c20d404 100644 --- a/base/ca/functional/src/com/netscape/cms/servlet/test/CARestClient.java +++ b/base/ca/functional/src/com/netscape/cms/servlet/test/CARestClient.java @@ -36,6 +36,7 @@ import com.netscape.cms.servlet.profile.model.ProfileData; import com.netscape.cms.servlet.profile.model.ProfileDataInfos; import com.netscape.cms.servlet.request.CertRequestResource; import com.netscape.cms.servlet.request.CertRequestsResource; +import com.netscape.cms.servlet.request.model.AgentEnrollmentRequestData; import com.netscape.cms.servlet.request.model.CertRequestInfo; import com.netscape.cms.servlet.request.model.CertRequestInfos; import com.netscape.cms.servlet.request.model.EnrollmentRequestData; @@ -120,4 +121,35 @@ public class CARestClient extends CMSRestClient { return certRequestClient.getRequestInfo(id); } + public AgentEnrollmentRequestData reviewRequest(RequestId id) { + if ( id == null) { + return null; + } + return certRequestClient.reviewRequest(id); + } + + public void approveRequest(AgentEnrollmentRequestData data) { + certRequestClient.approveRequest(data); + } + + public void rejectRequest(AgentEnrollmentRequestData data) { + certRequestClient.rejectRequest(data); + } + + public void cancelRequest(AgentEnrollmentRequestData data) { + certRequestClient.cancelRequest(data); + } + + public void updateRequest(AgentEnrollmentRequestData data) { + certRequestClient.updateRequest(data); + } + + public void validateRequest(AgentEnrollmentRequestData data) { + certRequestClient.validateRequest(data); + } + + public void unassignRequest(AgentEnrollmentRequestData data) { + certRequestClient.unassignRequest(data); + } + } diff --git a/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java b/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java index 397122a4..732b682a 100644 --- a/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java +++ b/base/ca/functional/src/com/netscape/cms/servlet/test/CATest.java @@ -17,11 +17,15 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.test; +import java.io.ByteArrayOutputStream; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; + import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; @@ -45,6 +49,7 @@ import com.netscape.cms.servlet.profile.model.ProfileDataInfo; import com.netscape.cms.servlet.profile.model.ProfileDataInfos; import com.netscape.cms.servlet.profile.model.ProfileInput; import com.netscape.cms.servlet.request.RequestNotFoundException; +import com.netscape.cms.servlet.request.model.AgentEnrollmentRequestData; import com.netscape.cms.servlet.request.model.CertRequestInfo; import com.netscape.cms.servlet.request.model.CertRequestInfos; import com.netscape.cms.servlet.request.model.EnrollmentRequestData; @@ -210,13 +215,13 @@ public class CATest { //Simulate a "caUserCert" Profile enrollment - ProfileInput certReq = data.addInput("Key Generation"); + ProfileInput certReq = data.createInput("Key Generation"); certReq.setInputAttr("cert_request_type", "crmf"); certReq.setInputAttr( "cert_request", "MIIBozCCAZ8wggEFAgQBMQp8MIHHgAECpQ4wDDEKMAgGA1UEAxMBeKaBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2NgaPHp0jiohcP4M+ufrJOZEqH8GV+liu5JLbT8nWpkfhC+8EUBqT6g+n3qroSxIcNVGNdcsBEqs1utvpItzyslAbpdyat3WwQep1dWMzo6RHrPDuIoxNA0Yka1n3qEX4U//08cLQtUv2bYglYgN/hOCNQemLV6vZWAv0n7zelkCAwEAAakQMA4GA1UdDwEB/wQEAwIF4DAzMBUGCSsGAQUFBwUBAQwIcmVnVG9rZW4wGgYJKwYBBQUHBQECDA1hdXRoZW50aWNhdG9yoYGTMA0GCSqGSIb3DQEBBQUAA4GBAJ1VOQcaSEhdHa94s8kifVbSZ2WZeYE5//qxL6wVlEst20vq4ybj13CetnbN3+WT49Zkwp7Fg+6lALKgSk47suTg3EbbQDm+8yOrC0nc/q4PTRoHl0alMmUxIhirYc1t3xoCMqJewmjX1bNP8lpVIZAYFZo4eZCpZaiSkM5BeHhz"); - ProfileInput subjectName = data.addInput("Subject Name"); + ProfileInput subjectName = data.createInput("Subject Name"); subjectName.setInputAttr("sn_uid", "jmagne"); subjectName.setInputAttr("sn_e", "jmagne@redhat.com"); subjectName.setInputAttr("sn_c", "US"); @@ -227,7 +232,7 @@ public class CATest { subjectName.setInputAttr("sn_cn", "Common"); subjectName.setInputAttr("sn_o", "RedHat"); - ProfileInput submitter = data.addInput("Requestor Information"); + ProfileInput submitter = data.createInput("Requestor Information"); submitter.setInputAttr("requestor_name", "admin"); submitter.setInputAttr("requestor_email", "admin@redhat.com"); submitter.setInputAttr("requestor_phone", "650-555-5555"); @@ -243,6 +248,12 @@ public class CATest { for (CertRequestInfo info : reqInfo.getRequests()) { printRequestInfo(info); + + AgentEnrollmentRequestData reviewData = client.reviewRequest(info.getRequestId()); + printAgentEnrollmentRequestData(reviewData); + + reviewData.setRequestNotes("This is an approval message"); + client.approveRequest(reviewData); } //Perform a sample certificate search with advanced search terms @@ -296,6 +307,27 @@ public class CATest { } + private static void printAgentEnrollmentRequestData(AgentEnrollmentRequestData reviewData) { + if (reviewData == null) { + log("No reviewData found. \n"); + return; + } + try { + JAXBContext context = JAXBContext.newInstance(AgentEnrollmentRequestData.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + marshaller.marshal(reviewData, stream); + + log("ReviewData: \n"); + log(stream.toString()); + } catch (Exception e) { + e.printStackTrace(); + } + } + private static void printProfileInfos(ProfileDataInfos pInfos) { if (pInfos == null) { @@ -454,11 +486,11 @@ public class CATest { } log("CertRequestURL: " + info.getRequestURL()); - log("CertId: " + info.getCertId()); + log("CertId: " + ((info.getCertId() != null) ? info.getCertId() : "")); log("RequestType: " + info.getCertRequestType()); log("Status: " + info.getRequestStatus()); log("Type: " + info.getRequestType()); - log("CertURL: " + info.getCertURL() + "\n"); + log("CertURL: " + ((info.getCertURL() != null) ? info.getCertURL(): "") + "\n"); } private static void log(String string) { diff --git a/base/ca/shared/conf/CS.cfg.in b/base/ca/shared/conf/CS.cfg.in index ada97c4f..808f8127 100644 --- a/base/ca/shared/conf/CS.cfg.in +++ b/base/ca/shared/conf/CS.cfg.in @@ -1056,6 +1056,15 @@ profile.caEncUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caEncUserCert.cfg profile.caEncECUserCert.class_id=caEnrollImpl profile.caEncECUserCert.config=[PKI_INSTANCE_PATH]/profiles/ca/caEncECUserCert.cfg registry.file=[PKI_INSTANCE_PATH]/conf/registry.cfg +profile.caProfileSubmit.GetClientCert=false +profile.caProfileSubmit.authzMgr=BasicAclAuthz +profile.caProfileSubmit.authorityId=ca +profile.caProfileSubmit.resourceID=certServer.ee.profile +profile.caProfileProcess.GetClientCert=true +profile.caProfileProcess.authzMgr=BasicAclAuthz +profile.caProfileProcess.authorityId=ca +profile.caProfileProcess.resourceID=certServer.ca.request.profile +profile.caProfileProcess.authMgr=certUserDBAuthMgr request.assignee.enable=true selftests._000=## selftests._001=## Self Tests diff --git a/base/common/src/CMakeLists.txt b/base/common/src/CMakeLists.txt index 7b73a853..2af0a6a7 100644 --- a/base/common/src/CMakeLists.txt +++ b/base/common/src/CMakeLists.txt @@ -251,6 +251,7 @@ set(pki-certsrv_java_SRCS com/netscape/certsrv/base/IAttrSet.java com/netscape/certsrv/base/ICRLPrettyPrint.java com/netscape/certsrv/base/ICertPrettyPrint.java + com/netscape/certsrv/base/BadRequestDataException.java com/netscape/certsrv/dbs/IDBRegistry.java com/netscape/certsrv/dbs/IDBAttrMapper.java com/netscape/certsrv/dbs/IElementProcessor.java @@ -776,8 +777,10 @@ set(pki-cms_java_SRCS com/netscape/cms/servlet/request/model/CertRequestInfo.java com/netscape/cms/servlet/request/model/CertRequestInfos.java com/netscape/cms/servlet/request/model/CertRetrievalRequestData.java + com/netscape/cms/servlet/request/model/AgentEnrollmentRequestData.java com/netscape/cms/servlet/request/model/EnrollmentRequestData.java com/netscape/cms/servlet/request/model/ProfileRetrievalRequestData.java + com/netscape/cms/servlet/request/model/ExtendableHttpRequest.java com/netscape/cms/servlet/tks/TokenServlet.java com/netscape/cms/servlet/connector/CloneServlet.java com/netscape/cms/servlet/connector/TokenKeyRecoveryServlet.java @@ -790,6 +793,7 @@ set(pki-cms_java_SRCS com/netscape/cms/servlet/ocsp/RemoveCAServlet.java com/netscape/cms/servlet/ocsp/GetOCSPInfo.java com/netscape/cms/servlet/ocsp/AddCAServlet.java + com/netscape/cms/servlet/profile/ProfileConfig.java com/netscape/cms/servlet/profile/ProfileSubmitServlet.java com/netscape/cms/servlet/profile/ProfileSubmitCMCServlet.java com/netscape/cms/servlet/profile/ProfileSelectServlet.java @@ -804,11 +808,19 @@ set(pki-cms_java_SRCS com/netscape/cms/servlet/profile/ProfileResourceService.java com/netscape/cms/servlet/profile/ProfilesResource.java com/netscape/cms/servlet/profile/ProfilesResourceService.java + com/netscape/cms/servlet/profile/ProfileProcessor.java com/netscape/cms/servlet/profile/model/ProfileDAO.java com/netscape/cms/servlet/profile/model/ProfileData.java com/netscape/cms/servlet/profile/model/ProfileDataInfo.java com/netscape/cms/servlet/profile/model/ProfileDataInfos.java com/netscape/cms/servlet/profile/model/ProfileInput.java + com/netscape/cms/servlet/profile/model/PolicyAttribute.java + com/netscape/cms/servlet/profile/model/PolicyConstraint.java + com/netscape/cms/servlet/profile/model/PolicyConstraintValue.java + com/netscape/cms/servlet/profile/model/PolicyDefault.java + com/netscape/cms/servlet/profile/model/ProfileInput.java + com/netscape/cms/servlet/profile/model/ProfilePolicy.java + com/netscape/cms/servlet/profile/model/ProfilePolicySet.java com/netscape/cms/authentication/AgentCertAuthentication.java com/netscape/cms/authentication/PortalEnroll.java com/netscape/cms/authentication/UdnPwdDirAuthentication.java diff --git a/base/common/src/com/netscape/certsrv/base/BadRequestDataException.java b/base/common/src/com/netscape/certsrv/base/BadRequestDataException.java new file mode 100644 index 00000000..268221ea --- /dev/null +++ b/base/common/src/com/netscape/certsrv/base/BadRequestDataException.java @@ -0,0 +1,24 @@ +package com.netscape.certsrv.base; + +public class BadRequestDataException extends EBaseException { + + private static final long serialVersionUID = -8401421856920994265L; + + + public BadRequestDataException(String msgFormat) { + super(msgFormat); + } + + public BadRequestDataException(String msgFormat, Exception param) { + super(msgFormat, param); + } + + public BadRequestDataException(String msgFormat, Object[] params) { + super(msgFormat, params); + } + + public BadRequestDataException(String msgFormat, String param) { + super(msgFormat, param); + } + +} diff --git a/base/common/src/com/netscape/certsrv/property/Descriptor.java b/base/common/src/com/netscape/certsrv/property/Descriptor.java index 4b2baf56..d3048e0b 100644 --- a/base/common/src/com/netscape/certsrv/property/Descriptor.java +++ b/base/common/src/com/netscape/certsrv/property/Descriptor.java @@ -19,12 +19,19 @@ package com.netscape.certsrv.property; import java.util.Locale; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + + /** * This interface represents a property descriptor. A descriptor * includes information that describe a property. * * @version $Revision$, $Date$ */ +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) public class Descriptor implements IDescriptor { protected String mSyntax = null; @@ -32,6 +39,10 @@ public class Descriptor implements IDescriptor { protected String mDescription = null; protected String mDef = null; + public Descriptor() { + // required for JAX-B + } + /** * Constructs a descriptor. * @@ -90,4 +101,10 @@ public class Descriptor implements IDescriptor { public String getDescription(Locale locale) { return mDescription; } + + @Override + public String toString() { + return "Descriptor [mSyntax=" + mSyntax + ", mConstraint=" + mConstraint + ", mDescription=" + mDescription + + ", mDef=" + mDef + "]"; + } } diff --git a/base/common/src/com/netscape/certsrv/request/RequestId.java b/base/common/src/com/netscape/certsrv/request/RequestId.java index 795fdaa2..8cd8c571 100644 --- a/base/common/src/com/netscape/certsrv/request/RequestId.java +++ b/base/common/src/com/netscape/certsrv/request/RequestId.java @@ -31,6 +31,10 @@ public class RequestId { protected BigInteger value; + public RequestId() { + // required for jaxb + } + /** * Creates a new RequestId from its string representation. * <p> diff --git a/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java b/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java index 15791492..0300b656 100644 --- a/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java +++ b/base/common/src/com/netscape/cms/profile/common/ProfilePolicy.java @@ -17,6 +17,11 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.profile.common; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAnyElement; +import javax.xml.bind.annotation.XmlRootElement; + import com.netscape.certsrv.profile.IPolicyConstraint; import com.netscape.certsrv.profile.IPolicyDefault; import com.netscape.certsrv.profile.IProfilePolicy; @@ -28,9 +33,13 @@ import com.netscape.certsrv.profile.IProfilePolicy; * * @version $Revision$, $Date$ */ +@XmlRootElement +@XmlAccessorType( XmlAccessType.FIELD ) public class ProfilePolicy implements IProfilePolicy { private String mId = null; + @XmlAnyElement private IPolicyDefault mDefault = null; + @XmlAnyElement private IPolicyConstraint mConstraint = null; public ProfilePolicy(String id, IPolicyDefault def, IPolicyConstraint constraint) { diff --git a/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java index 118fc865..d6b4a9e4 100644 --- a/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java +++ b/base/common/src/com/netscape/cms/servlet/base/CMSResourceService.java @@ -17,18 +17,27 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.base; +import java.lang.reflect.Method; import java.security.cert.CertificateEncodingException; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.FormParam; import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.Context; import javax.ws.rs.core.EntityTag; +import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; -import javax.ws.rs.core.UriInfo; import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.UriInfo; import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.logging.IAuditor; +import com.netscape.certsrv.logging.ILogger; import com.netscape.cms.servlet.cert.model.CertificateData; /** @@ -49,8 +58,17 @@ public class CMSResourceService { protected UriInfo uriInfo; @Context + protected HttpHeaders headers; + + @Context protected Request request; + @Context + protected HttpServletRequest servletRequest; + + public ILogger logger = CMS.getLogger(); + public IAuditor auditor = CMS.getAuditor(); + public Response createOKResponse(Object object) { return Response.ok(object).build(); } @@ -80,4 +98,71 @@ public class CMSResourceService { return data; } + public Locale getLocale() { + + if (headers == null) return Locale.getDefault(); + + List<Locale> locales = headers.getAcceptableLanguages(); + if (locales == null || locales.isEmpty()) return Locale.getDefault(); + + return locales.get(0); + } + + public String getUserMessage(String messageId, String... params) { + return CMS.getUserMessage(getLocale(), messageId, params); + } + + public void log(int source, int level, String message) { + + if (logger == null) return; + + logger.log(ILogger.EV_SYSTEM, + null, + source, + level, + getClass().getSimpleName()+": " + message); + } + + public void audit(String message, String scope, String type, String id, Map<String, String> params, String status) { + + if (auditor == null) return; + + String auditMessage = CMS.getLogMessage( + message, + auditor.getSubjectID(), + status, + auditor.getParamString(scope, type, id, params)); + + auditor.log(auditMessage); + } + + /** + * Get the values of the fields annotated with @FormParam. + */ + public Map<String, String> getParams(Object object) { + + Map<String, String> map = new HashMap<String, String>(); + + // for each fields in the object + for (Method method : object.getClass().getMethods()) { + FormParam element = method.getAnnotation(FormParam.class); + if (element == null) continue; + + String name = element.value(); + + try { + // get the value from the object + Object value = method.invoke(object); + + // put the value in the map + map.put(name, value == null ? null : value.toString()); + + } catch (Exception e) { + // ignore inaccessible fields + e.printStackTrace(); + } + } + + return map; + } } diff --git a/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java b/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java index f01d75c9..32ae0fcc 100644 --- a/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java +++ b/base/common/src/com/netscape/cms/servlet/common/AuthCredentials.java @@ -20,8 +20,8 @@ package com.netscape.cms.servlet.common; import java.util.Enumeration; import java.util.Hashtable; +import com.netscape.certsrv.authentication.EAuthException; import com.netscape.certsrv.authentication.IAuthCredentials; -import com.netscape.certsrv.base.EBaseException; import com.netscape.certsrv.base.IArgBlock; /** @@ -52,9 +52,9 @@ public class AuthCredentials implements IAuthCredentials { * @param cred credential * @exception com.netscape.certsrv.base.EBaseException NullPointerException */ - public void set(String name, Object cred) throws EBaseException { + public void set(String name, Object cred) throws EAuthException { if (cred == null) { - throw new EBaseException("AuthCredentials.set()"); + throw new EAuthException("AuthCredentials.set()"); } authCreds.put(name, cred); diff --git a/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java b/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java index 1306b168..a709b6b0 100644 --- a/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java +++ b/base/common/src/com/netscape/cms/servlet/common/ServletUtils.java @@ -104,12 +104,10 @@ public class ServletUtils { } } - public static String getACLMethod(String id) throws ServletException { + public static String getACLMethod(String aclInfo, String authzMgr, String id) throws EBaseException { String srcType = AUTHZ_SRC_LDAP; IAuthzSubsystem authz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ); - IConfigStore cs = CMS.getConfigStore(); - try { IConfigStore authzConfig = CMS.getConfigStore().getSubStore(AUTHZ_CONFIG_STORE); srcType = authzConfig.getString(AUTHZ_SRC_TYPE, AUTHZ_SRC_LDAP); @@ -122,31 +120,15 @@ public class ServletUtils { if (srcType.equalsIgnoreCase(AUTHZ_SRC_XML)) { CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_INITED", "")); try { - aclMethod = cs.getString(id + "." + PROP_AUTHZ_MGR); + aclMethod = authzMgr; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } - if (aclMethod != null && - aclMethod.equalsIgnoreCase(AUTHZ_MGR_BASIC)) { - String aclInfo = null; - try { - aclInfo = cs.getString(id + "." + PROP_ACL); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - + if (aclMethod != null && aclMethod.equalsIgnoreCase(AUTHZ_MGR_BASIC)) { if (aclInfo != null) { - try { - addACLInfo(authz, aclMethod, aclInfo); - } catch (EBaseException ee) { - throw new ServletException( - "failed to init authz info from xml config file"); - } - - CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_MGR_INIT_DONE", - id)); + addACLInfo(authz, aclMethod, aclInfo); + CMS.debug(CMS.getLogMessage("ADMIN_SRVLT_AUTHZ_MGR_INIT_DONE", id)); } else { CMS.debug(CMS.getLogMessage( "ADMIN_SRVLT_PROP_ACL_NOT_SPEC", PROP_ACL, id, diff --git a/base/common/src/com/netscape/cms/servlet/profile/ProfileConfig.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileConfig.java new file mode 100644 index 00000000..2562f8c6 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileConfig.java @@ -0,0 +1,147 @@ +// --- 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.cms.servlet.profile; + +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.profile.IProfileSubsystem; +import com.netscape.cms.servlet.common.ServletUtils; + +public class ProfileConfig { + public static final String PROFILE_ID = "profileId"; + public static final String AUTH_ID = "authId"; + public static final String ACL_METHOD = "aclMethod"; + public static final String AUTHZ_RESOURCE_NAME = "authzResourceName"; + public static final String AUTH_MGR = "authMgr"; + public static final String AUTHZ_MGR = "authzMgr"; + public static final String GET_CLIENT_CERT = "getClientCert"; + public static final String ACL_INFO = "ACLinfo"; + public static final String AUTHORITY_ID = "authorityId"; + public static final String PROFILE_SUB_ID = "profileSubId"; + + private String profileId; + private String authId; + private String aclMethod; + private String authzResourceName; + private String authMgr; + private String authzMgr; + private String getClientCert; + private String aclInfo; + private String authorityId; + private String profileSubId; + + public ProfileConfig(String id) throws EBaseException { + IConfigStore cs = CMS.getConfigStore().getSubStore("profile." + id); + try { + profileId = cs.getString(PROFILE_ID, "").isEmpty() ? null : cs.getString(PROFILE_ID); + authId = cs.getString(AUTH_ID, "").isEmpty() ? null : cs.getString(AUTH_ID); + aclInfo = cs.getString(ACL_INFO, "").isEmpty() ? null : cs.getString(ACL_INFO); + authzResourceName = cs.getString(AUTHZ_RESOURCE_NAME, "").isEmpty() ? null : cs.getString(AUTHZ_RESOURCE_NAME); + authMgr = cs.getString(AUTH_MGR, "").isEmpty() ? null : cs.getString(AUTH_MGR); + authzMgr = cs.getString(AUTHZ_MGR, "").isEmpty() ? null : cs.getString(AUTHZ_MGR); + getClientCert = cs.getString(GET_CLIENT_CERT, "").isEmpty() ? "false" : cs.getString(GET_CLIENT_CERT); + authorityId = cs.getString(AUTHORITY_ID, "").isEmpty() ? null : cs.getString(AUTHORITY_ID); + profileSubId = cs.getString(PROFILE_SUB_ID, "").isEmpty() ? IProfileSubsystem.ID : cs.getString(PROFILE_SUB_ID); + } catch (EBaseException e) { + e.printStackTrace(); + CMS.debug("Error in getting profile config for profile." + id); + } + aclMethod = ServletUtils.getACLMethod(aclInfo, authzMgr, id); + } + + public String getProfileId() { + return profileId; + } + + public void setProfileId(String profileId) { + this.profileId = profileId; + } + + public String getAuthId() { + return authId; + } + + public void setAuthId(String authId) { + this.authId = authId; + } + + public String getAclMethod() { + return aclMethod; + } + + public void setAclMethod(String aclMethod) { + this.aclMethod = aclMethod; + } + + public String getAuthzResourceName() { + return authzResourceName; + } + + public void setAuthzResourceName(String authzResourceName) { + this.authzResourceName = authzResourceName; + } + + public String getAuthMgr() { + return authMgr; + } + + public void setAuthMgr(String authMgr) { + this.authMgr = authMgr; + } + + public String getGetClientCert() { + return getClientCert; + } + + public void setGetClientCert(String getClientCert) { + this.getClientCert = getClientCert; + } + + public String getAuthzMgr() { + return authzMgr; + } + + public void setAuthzMgr(String authzMgr) { + this.authzMgr = authzMgr; + } + + public String getAclInfo() { + return aclInfo; + } + + public void setAclInfo(String aclInfo) { + this.aclInfo = aclInfo; + } + + public String getAuthorityId() { + return authorityId; + } + + public void setAuthorityId(String authorityId) { + this.authorityId = authorityId; + } + + public String getProfileSubId() { + return profileSubId; + } + + public void setProfileSubId(String profileSubId) { + this.profileSubId = profileSubId; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java index 7fafb016..567ecf01 100644 --- a/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java +++ b/base/common/src/com/netscape/cms/servlet/profile/ProfileProcessor.java @@ -1,27 +1,53 @@ +// --- 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.cms.servlet.profile; import java.math.BigInteger; import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; +import java.util.Hashtable; import java.util.LinkedHashSet; import java.util.Locale; import java.util.StringTokenizer; +import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import netscape.security.x509.BasicConstraintsExtension; import netscape.security.x509.X509CertImpl; import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.AuthToken; import com.netscape.certsrv.authentication.IAuthToken; import com.netscape.certsrv.authority.IAuthority; import com.netscape.certsrv.authorization.AuthzToken; +import com.netscape.certsrv.authorization.EAuthzException; import com.netscape.certsrv.authorization.IAuthzSubsystem; +import com.netscape.certsrv.base.BadRequestDataException; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.base.IArgBlock; +import com.netscape.certsrv.base.IConfigStore; import com.netscape.certsrv.base.MetaInfo; +import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.base.SessionContext; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.dbs.certdb.ICertRecord; @@ -31,29 +57,35 @@ import com.netscape.certsrv.profile.EDeferException; import com.netscape.certsrv.profile.EProfileException; import com.netscape.certsrv.profile.ERejectException; import com.netscape.certsrv.profile.IEnrollProfile; +import com.netscape.certsrv.profile.IPolicyConstraint; +import com.netscape.certsrv.profile.IPolicyDefault; import com.netscape.certsrv.profile.IProfile; import com.netscape.certsrv.profile.IProfileAuthenticator; import com.netscape.certsrv.profile.IProfileContext; import com.netscape.certsrv.profile.IProfileInput; +import com.netscape.certsrv.profile.IProfilePolicy; import com.netscape.certsrv.profile.IProfileSubsystem; +import com.netscape.certsrv.property.EPropertyException; import com.netscape.certsrv.request.INotify; import com.netscape.certsrv.request.IRequest; import com.netscape.certsrv.request.IRequestQueue; import com.netscape.certsrv.request.RequestId; import com.netscape.certsrv.request.RequestStatus; +import com.netscape.certsrv.usrgrp.IGroup; +import com.netscape.certsrv.usrgrp.IUGSubsystem; import com.netscape.certsrv.util.IStatsSubsystem; +import com.netscape.cms.profile.common.ProfilePolicy; import com.netscape.cms.servlet.base.UserInfo; import com.netscape.cms.servlet.common.AuthCredentials; +import com.netscape.cms.servlet.common.CMSGateway; +import com.netscape.cms.servlet.common.CMSRequest; import com.netscape.cmsutil.util.Utils; public class ProfileProcessor { - /** - * - */ - private static final String ARG_AUTH_TOKEN = "auth_token"; - private static final String ARG_REQUEST_OWNER = "requestOwner"; - private final static String HDR_LANG = "accept-language"; + public final static String ARG_AUTH_TOKEN = "auth_token"; + public final static String ARG_REQUEST_OWNER = "requestOwner"; + public final static String HDR_LANG = "accept-language"; public final static String ARG_PROFILE = "profile"; public final static String ARG_REQUEST_NOTES = "requestNotes"; public final static String ARG_PROFILE_ID = "profileId"; @@ -67,19 +99,39 @@ public class ProfileProcessor { public final static String ARG_PROFILE_REMOTE_HOST = "profileRemoteHost"; public final static String ARG_PROFILE_REMOTE_ADDR = "profileRemoteAddr"; public final static String ARG_PROFILE_SET_ID = "profileSetId"; - + public final static String ARG_OUTPUT_LIST = "outputList"; + public final static String ARG_OUTPUT_ID = "outputId"; + public final static String ARG_OUTPUT_SYNTAX = "outputSyntax"; + public final static String ARG_OUTPUT_CONSTRAINT = "outputConstraint"; + public final static String ARG_OUTPUT_NAME = "outputName"; + public final static String ARG_OUTPUT_VAL = "outputVal"; + public final static String ARG_REQUEST_LIST = "requestList"; + public final static String ARG_REQUEST_ID = "requestId"; + public final static String ARG_REQUEST_TYPE = "requestType"; + public final static String ARG_REQUEST_STATUS = "requestStatus"; + public final static String ARG_REQUEST_CREATION_TIME = "requestCreationTime"; + public final static String ARG_REQUEST_MODIFICATION_TIME = "requestModificationTime"; + public final static String ARG_REQUEST_NONCE = "nonce"; + public final static String ARG_OP = "op"; public final static String ARG_REQUESTS = "requests"; public final static String ARG_ERROR_CODE = "errorCode"; public final static String ARG_ERROR_REASON = "errorReason"; + public final static String CERT_ATTR = "javax.servlet.request.X509Certificate"; private String profileID = null; - private String mProfileSubId = null; + private String profileSubId = null; private String authorityId = null; private String aclMethod = null; + private String authzResourceName = null; + private String authMgr = null; + private String getClientCert = "false"; + private Nonces nonces = null; private Locale locale = null; - private IAuthority authority = null; - private IAuthzSubsystem authz = null; + // subsystems + private ICertificateAuthority authority = null; + private IAuthzSubsystem authz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ); + private IUGSubsystem ug = (IUGSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_UG); //logging and stats protected ILogger signedAuditLogger = CMS.getSignedAuditLogger(); @@ -97,17 +149,24 @@ public class ProfileProcessor { "LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS_4"; private final static String LOGGING_SIGNED_AUDIT_ROLE_ASSUME = "LOGGING_SIGNED_AUDIT_ROLE_ASSUME_3"; + private final static String SIGNED_AUDIT_CERT_REQUEST_REASON = + "requestNotes"; - public ProfileProcessor(String authorityId, String profileID, String aclMethod, Locale locale) { - this.authorityId = authorityId; - this.profileID = profileID; - this.aclMethod = aclMethod; + public ProfileProcessor(ProfileConfig config, Locale locale) { + this.authorityId = config.getAuthorityId(); + this.profileID = config.getProfileId(); + this.aclMethod = config.getAclMethod(); this.locale = locale; - - if (authorityId != null) - authority = (IAuthority) CMS.getSubsystem(authorityId); - - authz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ); + this.authzResourceName = config.getAuthzResourceName(); + this.authMgr = config.getAuthMgr(); + this.getClientCert = config.getGetClientCert(); + + if (authorityId != null) { + authority = (ICertificateAuthority) CMS.getSubsystem(authorityId); + if (authority.noncesEnabled()) { + nonces = authority.getNonces(); + } + } } private void setInputsIntoContext(HttpServletRequest request, IProfile profile, IProfileContext ctx) { @@ -196,120 +255,6 @@ public class ProfileProcessor { } } - String getUidFromDN(String userdn) { - StringTokenizer st = new StringTokenizer(userdn, ","); - while (st.hasMoreTokens()) { - String t = st.nextToken(); - int i = t.indexOf("="); - - if (i == -1) { - continue; - } - String n = t.substring(0, i); - if (n.equalsIgnoreCase("uid")) { - String v = t.substring(i + 1); - CMS.debug("ProfileProcessor:: getUidFromDN(): uid found:" + v); - return v; - } else { - continue; - } - } - return null; - } - - /* - * authenticate for renewal - more to add necessary params/values - * to the session context - */ - public IAuthToken authenticate(IProfileAuthenticator authenticator, - HttpServletRequest request, IRequest origReq, SessionContext context) - throws EBaseException { - IAuthToken authToken = authenticate(authenticator, request); - // For renewal, fill in necessary params - if (authToken != null) { - String ouid = origReq.getExtDataInString("auth_token.uid"); - // if the orig cert was manually approved, then there was - // no auth token uid. Try to get the uid from the cert dn - // itself, if possible - if (ouid == null) { - String sdn = (String) context.get("origSubjectDN"); - if (sdn != null) { - ouid = getUidFromDN(sdn); - if (ouid != null) - CMS.debug("ProfileProcessor: renewal: authToken original uid not found"); - } - } else { - CMS.debug("ProfileProcessor: renewal: authToken original uid found in orig request auth_token"); - } - String auid = authToken.getInString("uid"); - if (auid != null) { // not through ssl client auth - CMS.debug("ProfileProcessor: renewal: authToken uid found:" + auid); - // authenticated with uid - // put "orig_req.auth_token.uid" so that authz with - // UserOrigReqAccessEvaluator will work - if (ouid != null) { - context.put("orig_req.auth_token.uid", ouid); - CMS.debug("ProfileProcessor: renewal: authToken original uid found:" + ouid); - } else { - CMS.debug("ProfileProcessor: renewal: authToken original uid not found"); - } - } else { // through ssl client auth? - CMS.debug("ProfileProcessor: renewal: authToken uid not found:"); - // put in orig_req's uid - if (ouid != null) { - CMS.debug("ProfileProcessor: renewal: origReq uid not null:" + ouid + ". Setting authtoken"); - authToken.set("uid", ouid); - context.put(SessionContext.USER_ID, ouid); - } else { - CMS.debug("ProfileProcessor: renewal: origReq uid not found"); - // throw new EBaseException("origReq uid not found"); - } - } - - String userdn = origReq.getExtDataInString("auth_token.userdn"); - if (userdn != null) { - CMS.debug("ProfileProcessor: renewal: origReq userdn not null:" + userdn + ". Setting authtoken"); - authToken.set("userdn", userdn); - } else { - CMS.debug("ProfileProcessor: renewal: origReq userdn not found"); - // throw new EBaseException("origReq userdn not found"); - } - } else { - CMS.debug("ProfileProcessor: renewal: authToken null"); - } - return authToken; - } - - public IAuthToken authenticate(IProfileAuthenticator authenticator, - HttpServletRequest request) throws EBaseException { - AuthCredentials credentials = new AuthCredentials(); - - // build credential - Enumeration<String> authNames = authenticator.getValueNames(); - - if (authNames != null) { - while (authNames.hasMoreElements()) { - String authName = authNames.nextElement(); - - credentials.set(authName, request.getParameter(authName)); - } - } - - credentials.set("clientHost", request.getRemoteHost()); - IAuthToken authToken = authenticator.authenticate(credentials); - - SessionContext sc = SessionContext.getContext(); - if (sc != null) { - sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName()); - String userid = authToken.getInString(IAuthToken.USER_ID); - if (userid != null) { - sc.put(SessionContext.USER_ID, userid); - } - } - - return authToken; - } - private void setInputsIntoRequest(HttpServletRequest request, IProfile profile, IRequest req) { Enumeration<String> inputIds = profile.getProfileInputIds(); @@ -375,16 +320,32 @@ public class ProfileProcessor { } + private void errorExit(String message) throws EBaseException { + CMS.debug(message); + for (String event : statEvents) { + endTiming(event); + } + throw new EBaseException(message); + } - private void errorExit(String message) - throws EBaseException { + private void authzErrorExit(String message) throws EAuthzException { CMS.debug(message); for (String event : statEvents) { endTiming(event); } - throw new EBaseException(message); + throw new EAuthzException(message); + } + + private void badRequestDataErrorExit(String message) throws BadRequestDataException { + CMS.debug(message); + + for (String event : statEvents) { + endTiming(event); + } + + throw new BadRequestDataException(message); } /** @@ -427,17 +388,10 @@ public class ProfileProcessor { CMS.debug("ProfileProcessor: set Inputs into profile Context"); setInputsIntoContext(request, profile, ctx); - IProfileAuthenticator authenticator = null; - try { - authenticator = profile.getAuthenticator(); - if (authenticator != null) { - CMS.debug("ProfileProcessor: authenticator " + authenticator.getName() + " found"); - setCredentialsIntoContext(request, authenticator, ctx); - } - } catch (EProfileException e) { - // authenticator not installed correctly - CMS.debug("ProfileProcessor: processEnrollment: exception:" + e.toString()); - errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR")); + IProfileAuthenticator authenticator = profile.getAuthenticator(); + if (authenticator != null) { + CMS.debug("ProfileProcessor: authenticator " + authenticator.getName() + " found"); + setCredentialsIntoContext(request, authenticator, ctx); } // for ssl authentication; pass in servlet for retrieving ssl client certificates @@ -448,42 +402,18 @@ public class ProfileProcessor { CMS.debug("ProfileProcessor: set sslClientCertProvider"); // before creating the request, authenticate the request - IAuthToken authToken = null; - try { - authToken = authenticate(request, null, authenticator, context, false); - } catch (EBaseException e) { - errorExit(CMS.getUserMessage(locale, "CMS_AUTHENTICATION_ERROR")); - } + IAuthToken authToken = authenticate(request, null, authenticator, context, false); // authentication success, now authorize - try { - authorize(profileId, profile, authToken); - } catch (EBaseException e) { - e.printStackTrace(); - errorExit(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR")); - } + authorize(profileId, profile, authToken); /////////////////////////////////////////////// // create and populate request /////////////////////////////////////////////// startTiming("request_population"); - IRequest reqs[] = null; - try { - reqs = profile.createRequests(ctx, locale); - } catch (Exception e) { - CMS.debug(e); - e.printStackTrace(); - CMS.debug("ProfileProcessor: createRequests " + e.toString()); - errorExit(e.toString()); - } - - try { - populateRequests(request, false, locale, null, null, null, profileId, profile, - ctx, authenticator, authToken, reqs); - } catch (EBaseException e) { - CMS.debug("Error in populating request: " + e); - errorExit(e.toString()); - } + IRequest[] reqs = profile.createRequests(ctx, locale); + populateRequests(request, false, locale, null, null, null, profileId, profile, + ctx, authenticator, authToken, reqs); endTiming("request_population"); /////////////////////////////////////////////// @@ -598,29 +528,19 @@ public class ProfileProcessor { } IProfileContext ctx = profile.createContext(); + IProfileAuthenticator authenticator = renewProfile.getAuthenticator(); + IProfileAuthenticator origAuthenticator = profile.getAuthenticator(); - IProfileAuthenticator authenticator = null; - IProfileAuthenticator origAuthenticator = null; - try { - authenticator = renewProfile.getAuthenticator(); - origAuthenticator = profile.getAuthenticator(); - - if (authenticator != null) { - CMS.debug("ProfileProcessor: authenticator " + authenticator.getName() + " found"); - setCredentialsIntoContext(request, authenticator, ctx); - } - - // for renewal, this will override or add auth info to the profile context - if (origAuthenticator != null) { - CMS.debug("ProfileProcessor: for renewal, original authenticator " + - origAuthenticator.getName() + " found"); - setCredentialsIntoContext(request, origAuthenticator, ctx); - } + if (authenticator != null) { + CMS.debug("ProfileProcessor: authenticator " + authenticator.getName() + " found"); + setCredentialsIntoContext(request, authenticator, ctx); + } - } catch (EProfileException e) { - // authenticator not installed correctly - CMS.debug("processRenewal: exception:" + e.toString()); - errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR")); + // for renewal, this will override or add auth info to the profile context + if (origAuthenticator != null) { + CMS.debug("ProfileProcessor: for renewal, original authenticator " + + origAuthenticator.getName() + " found"); + setCredentialsIntoContext(request, origAuthenticator, ctx); } // for renewal, input needs to be retrieved from the orig req record @@ -640,47 +560,18 @@ public class ProfileProcessor { context.put("origSubjectDN", origSubjectDN); // before creating the request, authenticate the request - IAuthToken authToken = null; - try { - authToken = authenticate(request, origReq, authenticator, context, true); - } catch (EBaseException e) { - errorExit(CMS.getUserMessage(locale, "CMS_AUTHENTICATION_ERROR")); - } + IAuthToken authToken = authenticate(request, origReq, authenticator, context, true); // authentication success, now authorize - try { - authorize(profileId, renewProfile, authToken); - } catch (EBaseException e) { - e.printStackTrace(); - errorExit(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR")); - } + authorize(profileId, renewProfile, authToken); /////////////////////////////////////////////// // create and populate requests /////////////////////////////////////////////// startTiming("request_population"); - IRequest reqs[] = null; - - try { - reqs = profile.createRequests(ctx, locale); - } catch (EProfileException e) { - CMS.debug(e); - CMS.debug("ProfileProcessor: createRequests " + e.toString()); - errorExit(e.toString()); - } catch (Throwable e) { - CMS.debug(e); - CMS.debug("ProfileProcessor: createRequests " + e.toString()); - errorExit(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR")); - } - - try { - populateRequests(request, true, locale, origNotAfter, origSubjectDN, origReq, profileId, profile, - ctx, authenticator, authToken, reqs); - } catch (EBaseException e) { - CMS.debug("Error in populating request: " + e); - errorExit(e.toString()); - } - + IRequest[] reqs = profile.createRequests(ctx, locale); + populateRequests(request, true, locale, origNotAfter, origSubjectDN, origReq, profileId, + profile, ctx, authenticator, authToken, reqs); endTiming("request_population"); /////////////////////////////////////////////// @@ -701,52 +592,6 @@ public class ProfileProcessor { return ret; } - private void authorize(String profileId, IProfile profile, IAuthToken authToken) throws EBaseException { - if (authToken != null) { - CMS.debug("ProfileProcessor authToken not null"); - - String acl = profile.getAuthzAcl(); - CMS.debug("ProfileProcessor: authz using acl: " + acl); - if (acl != null && acl.length() > 0) { - String resource = profileId + ".authz.acl"; - authorize(aclMethod, resource, authToken, acl); - } - } - } - - private IProfile getProfile(String profileId) { - if (mProfileSubId == null || mProfileSubId.equals("")) { - mProfileSubId = IProfileSubsystem.ID; - } - CMS.debug("ProfileProcessor: SubId=" + mProfileSubId); - - IProfileSubsystem ps = (IProfileSubsystem) CMS.getSubsystem(mProfileSubId); - if (ps == null) { - CMS.debug("getProfile: Profile Subsystem not found"); - return null; - } - - IProfile profile = null; - - try { - profile = ps.getProfile(profileId); - } catch (EProfileException e) { - if (profile == null) { - CMS.debug("ProfileProcessor: profile not found profileId " + profileId + " " + e.toString()); - } - } - if (profile == null) { - CMS.debug("getProfile: Profile not found: " + profileId); - return null; - } - - if (!ps.isProfileEnable(profileId)) { - CMS.debug("ProfileProcessor: Profile " + profileId + " not enabled"); - return null; - } - return profile; - } - private String codeToReason(Locale locale, String errorCode) { if (errorCode.equals("1")) { return CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR"); @@ -937,109 +782,14 @@ public class ProfileProcessor { CMS.debug("ProfileProcessor: request " + req.getRequestId().toString()); - try { - CMS.debug("ProfileProcessor: populating request inputs"); - // give authenticator a chance to populate the request - if (authenticator != null) { - authenticator.populate(authToken, req); - } - profile.populateInput(ctx, req); - profile.populate(req); - } catch (EProfileException e) { - e.printStackTrace(); - CMS.debug("ProfileProcessor: EProfileException for " + req.getRequestId().toString() - + ": " + e.toString()); - throw new EBaseException(e.toString()); - } catch (Throwable e) { - CMS.debug("ProfileProcessor: populate " + e.toString()); - throw new EBaseException(CMS.getUserMessage(locale, "CMS_INTERNAL_ERROR")); - } - } - } - - private IAuthToken authenticate(HttpServletRequest request, IRequest origReq, IProfileAuthenticator authenticator, - SessionContext context, boolean isRenewal) throws EBaseException { - startTiming("profile_authentication"); - - IAuthToken authToken = null; - if (authenticator != null) { - CMS.debug("authenticate: authentication required."); - String uid_cred = "Unidentified"; - String uid_attempted_cred = "Unidentified"; - Enumeration<String> authIds = authenticator.getValueNames(); - //Attempt to possibly fetch attempted uid, may not always be available. - if (authIds != null) { - while (authIds.hasMoreElements()) { - String authName = authIds.nextElement(); - String value = request.getParameter(authName); - if (value != null) { - if (authName.equals("uid")) { - uid_attempted_cred = value; - } - } - } - } - - String authSubjectID = auditSubjectID(); - String authMgrID = authenticator.getName(); - String auditMessage = null; - try { - if (isRenewal) { - authToken = authenticate(authenticator, request, origReq, context); - } else { - authToken = authenticate(authenticator, request); - } - } catch (EBaseException e) { - CMS.debug("ProfileProcessor: authentication error " + e.toString()); - - authSubjectID += " : " + uid_cred; - auditMessage = CMS.getLogMessage( - LOGGING_SIGNED_AUDIT_AUTH_FAIL, - authSubjectID, - ILogger.FAILURE, - authMgrID, - uid_attempted_cred); - audit(auditMessage); - - throw e; - } - - //Log successful authentication - //Attempt to get uid from authToken, most tokens respond to the "uid" cred. - uid_cred = authToken.getInString("uid"); - - if (uid_cred == null || uid_cred.length() == 0) { - uid_cred = "Unidentified"; + CMS.debug("ProfileProcessor: populating request inputs"); + // give authenticator a chance to populate the request + if (authenticator != null) { + authenticator.populate(authToken, req); } - - authSubjectID = authSubjectID + " : " + uid_cred; - - // store a message in the signed audit log file - auditMessage = CMS.getLogMessage( - LOGGING_SIGNED_AUDIT_AUTH_SUCCESS, - authSubjectID, - ILogger.SUCCESS, - authMgrID); - - audit(auditMessage); + profile.populateInput(ctx, req); + profile.populate(req); } - endTiming("profile_authentication"); - return authToken; - } - - protected void audit(String msg) { - // in this case, do NOT strip preceding/trailing whitespace - // from passed-in String parameters - - if (signedAuditLogger == null) { - return; - } - - signedAuditLogger.log(ILogger.EV_SIGNED_AUDIT, - null, - ILogger.S_SIGNED_AUDIT, - ILogger.LL_SECURITY, - msg); } private BigInteger getSerialNumberFromCert(HttpServletRequest request) throws EBaseException { @@ -1103,19 +853,432 @@ public class ProfileProcessor { return certSerial; } - private IRequest getOriginalRequest(BigInteger certSerial, ICertRecord rec) throws EBaseException { + public void processRequest(CMSRequest cmsReq) throws EBaseException { + HttpServletRequest request = cmsReq.getHttpReq(); + + startTiming("approval"); + + IAuthToken authToken = null; + + printParameterValues(request); + + if (authMgr != null) { + // TODO - remove the try-catch block once we figure out client auth + try { + authToken = authenticate(cmsReq); + } catch (EBaseException e) { + CMS.debug("Authentication error .. continuing anyways"); + //authErrorExit(CMS.getUserMessage(locale, "CMS_AUTHENTICATION_ERROR")); + } + } + + AuthzToken authzToken = authorize(aclMethod, authToken, authzResourceName, "approve"); + if (authzToken == null) { + // TODO - throw exception here - once we go this working + //authzErrorExit(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR")); + CMS.debug("authToken is null: continuing anyways"); + } + + if (nonces != null) { + String requestNonce = request.getParameter(ARG_REQUEST_NONCE); + boolean nonceVerified = false; + if (requestNonce != null) { + long nonce = Long.parseLong(requestNonce.trim()); + X509Certificate cert1 = nonces.getCertificate(nonce); + X509Certificate cert2 = getSSLClientCertificate(request); + if (cert1 == null) { + CMS.debug("ProfileProcessServlet: Unknown nonce"); + } else if (cert1 != null && cert2 != null && cert1.equals(cert2)) { + nonceVerified = true; + nonces.removeNonce(nonce); + } + } else { + CMS.debug("ProfileProcessServlet: Missing nonce"); + } + CMS.debug("ProfileProcessServlet: nonceVerified=" + nonceVerified); + if (!nonceVerified) { + CMS.debug("nonce not verified"); + authzErrorExit(CMS.getUserMessage(locale, "CMS_AUTHORIZATION_ERROR")); + } + } + + CMS.debug("ProfileProcessor: processRequest: start serving"); + + String requestId = request.getParameter("requestId"); + if (requestId == null || requestId.equals("")) { + badRequestDataErrorExit(CMS.getUserMessage(locale, "CMS_REQUEST_ID_NOT_FOUND")); + } + CMS.debug("ProfileProcessServlet: requestId=" + requestId); + + IRequestQueue queue = getRequestQueue(); + IRequest req = getRequest(new RequestId(requestId)); + if (req == null) { + errorExit(CMS.getUserMessage(locale, "CMS_REQUEST_NOT_FOUND", requestId)); + } + + // check if the request is in one of the terminal states + if (!req.getRequestStatus().equals(RequestStatus.PENDING)) { + badRequestDataErrorExit(CMS.getUserMessage(locale, "CMS_REQUEST_NOT_PENDING", requestId)); + } + + String profileId = req.getExtDataInString("profileId"); + if (profileId == null || profileId.equals("")) { + CMS.debug("ProfileProcessServlet: Profile Id not found in request"); + errorExit(CMS.getUserMessage(locale, "CMS_PROFILE_ID_NOT_FOUND")); + } + CMS.debug("ProfileProcessServlet: profileId=" + profileId); + + IProfile profile = getProfile(profileId); + if (profile == null) { + errorExit(CMS.getUserMessage(locale, "CMS_PROFILE_NOT_FOUND", profileId)); + } + + String op = request.getParameter("op"); + if (op == null) { + badRequestDataErrorExit(CMS.getUserMessage(locale, "CMS_OP_NOT_FOUND")); + } + + if (op.equals("assign")) { + String owner = req.getRequestOwner(); + + // assigned owner + if (owner != null && owner.length() > 0) { + if (!grantPermission(req, authToken)) { + CMS.debug("ProfileProcessServlet: Permission not granted to assign request."); + authzErrorExit(CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION")); + } + } + String id = auditSubjectID(); + req.setRequestOwner(id); + } else { + if (grantPermission(req, authToken)) { + if (op.equals("approve")) { + checkProfileVersion(profile, req); + updateValues(request, req, profile, locale); + updateNotes(request, req); + approveRequest(request, req, profile, locale); + } else if (op.equals("reject")) { + updateNotes(request, req); + rejectRequest(req); + } else if (op.equals("cancel")) { + updateNotes(request, req); + cancelRequest(req); + } else if (op.equals("update")) { + checkProfileVersion(profile, req); + updateValues(request, req, profile, locale); + updateNotes(request, req); + } else if (op.equals("validate")) { + updateValues(request, req, profile, locale); + } else if (op.equals("unassign")) { + req.setRequestOwner(""); + } + } else { + CMS.debug("ProfileProcessServlet: Permission not granted to approve/reject/cancel/update/validate/unassign request."); + authzErrorExit(CMS.getUserMessage(locale, "CMS_PROFILE_DENY_OPERATION")); + } + } + + // commit request to the storage + if (!op.equals("validate")) { + if (op.equals("approve")) { + queue.markAsServiced(req); + } else { + queue.updateRequest(req); + } + } + endTiming("approval"); + } + + public boolean grantPermission(IRequest req, IAuthToken token) { + boolean enable = false; + try { + enable = CMS.getConfigStore().getBoolean("request.assignee.enable", false); + } catch (EBaseException e) { + } + + if (!enable) + return true; + String owner = req.getRequestOwner(); + + // unassigned owner + if (owner == null || owner.length() == 0) + return true; + String uid = token.getInString(IAuthToken.USER_ID); + if (uid.equals(owner)) + return true; + + return false; + } + + /** + * Check if the request creation time is older than the profile + * lastModified attribute. + */ + protected void checkProfileVersion(IProfile profile, IRequest req) throws EProfileException { + IConfigStore profileConfig = profile.getConfigStore(); + if (profileConfig != null) { + String lastModified = null; + + try { + lastModified = profileConfig.getString("lastModified", ""); + } catch (EBaseException e) { + } + + if (!lastModified.equals("")) { + Date profileModifiedAt = new Date(Long.parseLong(lastModified)); + CMS.debug("ProfileProcessServlet: Profile Last Modified=" + + profileModifiedAt); + Date reqCreatedAt = req.getCreationTime(); + CMS.debug("ProfileProcessServlet: Request Created At=" + + reqCreatedAt); + if (profileModifiedAt.after(reqCreatedAt)) { + CMS.debug("Profile Newer Than Request"); + throw new ERejectException("Profile Newer Than Request"); + } + } + } + } + + /** + * Cancel request + * <P> + * + * (Certificate Request Processed - a manual "agent" profile based cert cancellation) + * <P> + * + * <ul> + * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been + * through the approval process + * </ul> + * + * + * @param req the certificate request + * @exception EProfileException an error related to this profile has + * occurred + */ + protected void cancelRequest(IRequest req) throws EProfileException { + String auditMessage = null; + String auditSubjectID = auditSubjectID(); + String auditRequesterID = auditRequesterID(req); + String auditInfoValue = auditInfoValue(req); + + req.setRequestStatus(RequestStatus.CANCELED); + + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, + auditSubjectID, + ILogger.SUCCESS, + auditRequesterID, + ILogger.SIGNED_AUDIT_CANCELLATION, + auditInfoValue); + + audit(auditMessage); + } + + /** + * Reject request + * <P> + * + * (Certificate Request Processed - a manual "agent" profile based cert rejection) + * <P> + * + * <ul> + * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been + * through the approval process + * </ul> + * + * @param req the certificate request + * @exception EProfileException an error related to this profile has + * occurred + */ + protected void rejectRequest(IRequest req) throws EProfileException { + String auditMessage = null; + String auditSubjectID = auditSubjectID(); + String auditRequesterID = auditRequesterID(req); + String auditInfoValue = auditInfoValue(req); + + req.setRequestStatus(RequestStatus.REJECTED); + + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, + auditSubjectID, + ILogger.SUCCESS, + auditRequesterID, + ILogger.SIGNED_AUDIT_REJECTION, + auditInfoValue); + + audit(auditMessage); + } + + /** + * Approve request + * <P> + * + * (Certificate Request Processed - a manual "agent" profile based cert acceptance) + * <P> + * + * <ul> + * <li>signed.audit LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED used when a certificate request has just been + * through the approval process + * </ul> + * + * @param request the servlet request + * @param req the certificate request + * @param profile this profile + * @param locale the system locale + * @exception EProfileException an error related to this profile has + * occurred + */ + protected void approveRequest(ServletRequest request, IRequest req, IProfile profile, Locale locale) + throws EProfileException { + String auditMessage = null; + String auditSubjectID = auditSubjectID(); + String auditRequesterID = auditRequesterID(req); + + try { + profile.execute(req); + req.setRequestStatus(RequestStatus.COMPLETE); + + // TODO - populate and return outputs? + + // retrieve the certificate + X509CertImpl theCert = req.getExtDataInCert( + IEnrollProfile.REQUEST_ISSUED_CERT); + + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, + auditSubjectID, + ILogger.SUCCESS, + auditRequesterID, + ILogger.SIGNED_AUDIT_ACCEPTANCE, + auditInfoCertValue(theCert)); + + audit(auditMessage); + + } catch (EProfileException eAudit1) { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_CERT_REQUEST_PROCESSED, + auditSubjectID, + ILogger.FAILURE, + auditRequesterID, + ILogger.SIGNED_AUDIT_ACCEPTANCE, + ILogger.SIGNED_AUDIT_EMPTY_VALUE); + + audit(auditMessage); + + CMS.debug("ProfileProcessServlet: about to throw EProfileException because of bad profile execute."); + throw eAudit1; + } + } + + protected void updateValues(ServletRequest request, IRequest req, + IProfile profile, Locale locale) + throws ERejectException, EDeferException, EPropertyException { + String profileSetId = req.getExtDataInString("profileSetId"); + + Enumeration<ProfilePolicy> policies = profile.getProfilePolicies(profileSetId); + int count = 0; + + while (policies.hasMoreElements()) { + ProfilePolicy policy = policies.nextElement(); + + setValue(locale, count, policy, req, request); + count++; + } + + policies = profile.getProfilePolicies(profileSetId); + count = 0; + while (policies.hasMoreElements()) { + ProfilePolicy policy = policies.nextElement(); + + validate(count, policy, req); + count++; + } + + } + + protected void updateNotes(ServletRequest request, IRequest req) { + String notes = request.getParameter(ARG_REQUEST_NOTES); + + if (notes != null) { + req.setExtData("requestNotes", notes); + } + } + + protected void validate(int count, IProfilePolicy policy, IRequest req) + throws ERejectException, EDeferException { + IPolicyConstraint con = policy.getConstraint(); + + con.validate(req); + } + + protected void setValue(Locale locale, int count, IProfilePolicy policy, IRequest req, ServletRequest request) + throws EPropertyException { + // handle default policy + IPolicyDefault def = policy.getDefault(); + Enumeration<String> defNames = def.getValueNames(); + + while (defNames.hasMoreElements()) { + String defName = defNames.nextElement(); + String defValue = request.getParameter(defName); + + def.setValue(defName, locale, req, defValue); + } + } + + /****************************************** + * Stats - to be moved to Stats module + ******************************************/ + + public void startTiming(String event) { + IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats"); + if (statsSub != null) { + statsSub.startTiming(event, true); + } + if (statEvents == null) { + statEvents = new LinkedHashSet<String>(); + } + statEvents.add(event); + } + + public void endTiming(String event) { + IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats"); + if (statsSub != null) { + statsSub.endTiming(event); + } + if (statEvents != null) { + statEvents.remove(event); + } + } + + /****************************************** + * Utility Functions + ******************************************/ + private IRequestQueue getRequestQueue() throws EBaseException { IAuthority authority = (IAuthority) CMS.getSubsystem(authorityId); if (authority == null) { - CMS.debug("getOriginalRequest: Authority " + authorityId + " not found"); - return null; + throw new EBaseException("getRequest: Authority " + authorityId + " not found"); } - IRequestQueue queue = authority.getRequestQueue(); + IRequestQueue queue = authority.getRequestQueue(); if (queue == null) { - CMS.debug("getOriginalRequest: Request Queue of " + authorityId + " not found"); - return null; + throw new EBaseException( + "getOriginalRequest: Request Queue of " + authorityId + " not found"); } + return queue; + } + private IRequest getRequest(RequestId rid) throws EBaseException { + IRequestQueue queue = getRequestQueue(); + IRequest request = queue.findRequest(rid); + return request; + } + + private IRequest getOriginalRequest(BigInteger certSerial, ICertRecord rec) throws EBaseException { MetaInfo metaInfo = (MetaInfo) rec.get(ICertRecord.ATTR_META_INFO); if (metaInfo == null) { CMS.debug("getOriginalRequest: cert record locating MetaInfo failed for serial number " @@ -1130,9 +1293,8 @@ public class ProfileProcessor { return null; } - CMS.debug("getOriginalRequest: request id is " + rid); - IRequest origReq = queue.findRequest(new RequestId(rid)); - return origReq; + IRequest request = getRequest(new RequestId(rid)); + return request; } private void printParameterValues(HttpServletRequest request) { @@ -1172,99 +1334,6 @@ public class ProfileProcessor { CMS.debug("End of ProfileProcessor Input Parameters"); } - /** - * Signed Audit Log Requester ID - * - * This method is called to obtain the "RequesterID" for - * a signed audit log message. - * <P> - * - * @param request the actual request - * @return id string containing the signed audit log message RequesterID - */ - private String auditRequesterID(IRequest request) { - // if no signed audit object exists, bail - if (signedAuditLogger == null) { - return null; - } - - String requesterID = ILogger.UNIDENTIFIED; - - if (request != null) { - // overwrite "requesterID" if and only if "id" != null - String id = request.getRequestId().toString(); - - if (id != null) { - requesterID = id.trim(); - } - } - - return requesterID; - } - - /** - * Signed Audit Log Info Certificate Value - * - * This method is called to obtain the certificate from the passed in - * "X509CertImpl" for a signed audit log message. - * <P> - * - * @param request request containing an X509CertImpl - * @return cert string containing the certificate - */ - private String auditInfoCertValue(IRequest request) { - // if no signed audit object exists, bail - if (signedAuditLogger == null) { - return null; - } - - X509CertImpl x509cert = request.getExtDataInCert( - IEnrollProfile.REQUEST_ISSUED_CERT); - - if (x509cert == null) { - return ILogger.SIGNED_AUDIT_EMPTY_VALUE; - } - - byte rawData[] = null; - - try { - rawData = x509cert.getEncoded(); - } catch (CertificateEncodingException e) { - return ILogger.SIGNED_AUDIT_EMPTY_VALUE; - } - - String cert = null; - - // convert "rawData" into "base64Data" - if (rawData != null) { - String base64Data = null; - - base64Data = Utils.base64encode(rawData).trim(); - - // extract all line separators from the "base64Data" - StringBuffer sb = new StringBuffer(); - for (int i = 0; i < base64Data.length(); i++) { - if (!Character.isWhitespace(base64Data.charAt(i))) { - sb.append(base64Data.charAt(i)); - - } - } - cert = sb.toString(); - } - - if (cert != null) { - cert = cert.trim(); - - if (cert.equals("")) { - return ILogger.SIGNED_AUDIT_EMPTY_VALUE; - } else { - return cert; - } - } else { - return ILogger.SIGNED_AUDIT_EMPTY_VALUE; - } - } - protected StringBuffer escapeValueRfc1779(String v, boolean doubleEscape) { StringBuffer result = new StringBuffer(); @@ -1277,9 +1346,9 @@ public class ProfileProcessor { if ((c == 0x5c) && ((i + 1) < v.length())) { int nextC = v.charAt(i + 1); if ((c == 0x5c) && (nextC == ',' || nextC == '=' || nextC == '+' || - nextC == '<' || nextC == '>' || nextC == '#' || - nextC == ';' || nextC == '\r' || nextC == '\n' || - nextC == '\\' || nextC == '"')) { + nextC == '<' || nextC == '>' || nextC == '#' || + nextC == ';' || nextC == '\r' || nextC == '\n' || + nextC == '\\' || nextC == '"')) { if (doubleEscape) result.append('\\'); } else { @@ -1304,27 +1373,6 @@ public class ProfileProcessor { return result; } - public void startTiming(String event) { - IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats"); - if (statsSub != null) { - statsSub.startTiming(event, true); - } - if (statEvents == null) { - statEvents = new LinkedHashSet<String>(); - } - statEvents.add(event); - } - - public void endTiming(String event) { - IStatsSubsystem statsSub = (IStatsSubsystem) CMS.getSubsystem("stats"); - if (statsSub != null) { - statsSub.endTiming(event); - } - if (statEvents != null) { - statEvents.remove(event); - } - } - protected Locale getLocale(HttpServletRequest req) { Locale locale = null; String lang = req.getHeader(HDR_LANG); @@ -1334,7 +1382,7 @@ public class ProfileProcessor { locale = Locale.getDefault(); } else { locale = new Locale(UserInfo.getUserLanguage(lang), - UserInfo.getUserCountry(lang)); + UserInfo.getUserCountry(lang)); } return locale; } @@ -1346,7 +1394,7 @@ public class ProfileProcessor { return null; } - ICertificateRepository certdb = ((ICertificateAuthority) authority).getCertificateRepository(); + ICertificateRepository certdb = authority.getCertificateRepository(); if (certdb == null) { CMS.debug(CMS.getLogMessage("CMSGW_CERT_DB_NULL", authority.toString())); return null; @@ -1362,37 +1410,444 @@ public class ProfileProcessor { return certRecord; } - protected String auditSubjectID() { - // if no signed audit object exists, bail - if (signedAuditLogger == null) { + private IProfile getProfile(String profileId) throws EBaseException { + if (profileSubId == null || profileSubId.equals("")) { + profileSubId = IProfileSubsystem.ID; + } + CMS.debug("getProfile: SubId=" + profileSubId); + + IProfileSubsystem ps = (IProfileSubsystem) CMS.getSubsystem(profileSubId); + if (ps == null) { + throw new EBaseException("getProfile: Profile Subsystem not found"); + } + + IProfile profile = null; + + try { + profile = ps.getProfile(profileId); + } catch (EProfileException e) { + if (profile == null) { + CMS.debug("ProfileProcessor: profile not found profileId " + profileId + " " + e.toString()); + } + } + if (profile == null) { + CMS.debug("getProfile: Profile not found: " + profileId); return null; } - CMS.debug("CMSServlet: in auditSubjectID"); - String subjectID = null; + if (!ps.isProfileEnable(profileId)) { + CMS.debug("ProfileProcessor: Profile " + profileId + " not enabled"); + return null; + } + return profile; + } - // Initialize subjectID - SessionContext auditContext = SessionContext.getExistingContext(); + /** + * get ssl client authenticated certificate + */ + public static X509Certificate getSSLClientCertificate(HttpServletRequest httpReq) + throws EBaseException { + X509Certificate cert = null; - CMS.debug("CMSServlet: auditSubjectID auditContext " + auditContext); - if (auditContext != null) { - subjectID = (String) - auditContext.get(SessionContext.USER_ID); + CMS.debug(CMS.getLogMessage("CMSGW_GETTING_SSL_CLIENT_CERT")); - CMS.debug("CMSServlet auditSubjectID: subjectID: " + subjectID); - if (subjectID != null) { - subjectID = subjectID.trim(); + // iws60 support Java Servlet Spec V2.2, attribute + // javax.servlet.request.X509Certificate now contains array + // of X509Certificates instead of one X509Certificate object + X509Certificate[] allCerts = (X509Certificate[]) httpReq.getAttribute(CERT_ATTR); + + if (allCerts == null || allCerts.length == 0) { + throw new EBaseException("You did not provide a valid certificate for this operation"); + } + + cert = allCerts[0]; + + if (cert == null) { + // just don't have a cert. + CMS.debug(CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL")); + return null; + } + + // convert to sun's x509 cert interface. + try { + byte[] certEncoded = cert.getEncoded(); + cert = new X509CertImpl(certEncoded); + } catch (CertificateEncodingException e) { + CMS.debug(CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_ENCODE", e.getMessage())); + return null; + } catch (CertificateException e) { + CMS.debug(CMS.getLogMessage("CMSGW_SSL_CL_CERT_FAIL_DECODE", e.getMessage())); + return null; + } + return cert; + } + + public static Hashtable<String, String> toHashtable(HttpServletRequest req) { + Hashtable<String, String> httpReqHash = new Hashtable<String, String>(); + Enumeration<?> names = req.getParameterNames(); + + while (names.hasMoreElements()) { + String name = (String) names.nextElement(); + + httpReqHash.put(name, req.getParameter(name)); + } + return httpReqHash; + } + + /****************************************** + * AUTHENTICATION FUNCTIONS (move to Realm?) + ******************************************/ + + /* + * authenticate for renewal - more to add necessary params/values + * to the session context + */ + public IAuthToken authenticate(IProfileAuthenticator authenticator, + HttpServletRequest request, IRequest origReq, SessionContext context) throws EBaseException + { + IAuthToken authToken = authenticate(authenticator, request); + // For renewal, fill in necessary params + if (authToken != null) { + String ouid = origReq.getExtDataInString("auth_token.uid"); + // if the orig cert was manually approved, then there was + // no auth token uid. Try to get the uid from the cert dn + // itself, if possible + if (ouid == null) { + String sdn = (String) context.get("origSubjectDN"); + if (sdn != null) { + ouid = getUidFromDN(sdn); + if (ouid != null) + CMS.debug("ProfileProcessor: renewal: authToken original uid not found"); + } } else { - subjectID = ILogger.NONROLEUSER; + CMS.debug("ProfileProcessor: renewal: authToken original uid found in orig request auth_token"); + } + String auid = authToken.getInString("uid"); + if (auid != null) { // not through ssl client auth + CMS.debug("ProfileProcessor: renewal: authToken uid found:" + auid); + // authenticated with uid + // put "orig_req.auth_token.uid" so that authz with + // UserOrigReqAccessEvaluator will work + if (ouid != null) { + context.put("orig_req.auth_token.uid", ouid); + CMS.debug("ProfileProcessor: renewal: authToken original uid found:" + ouid); + } else { + CMS.debug("ProfileProcessor: renewal: authToken original uid not found"); + } + } else { // through ssl client auth? + CMS.debug("ProfileProcessor: renewal: authToken uid not found:"); + // put in orig_req's uid + if (ouid != null) { + CMS.debug("ProfileProcessor: renewal: origReq uid not null:" + ouid + ". Setting authtoken"); + authToken.set("uid", ouid); + context.put(SessionContext.USER_ID, ouid); + } else { + CMS.debug("ProfileProcessor: renewal: origReq uid not found"); + // throw new EBaseException("origReq uid not found"); + } + } + + String userdn = origReq.getExtDataInString("auth_token.userdn"); + if (userdn != null) { + CMS.debug("ProfileProcessor: renewal: origReq userdn not null:" + userdn + ". Setting authtoken"); + authToken.set("userdn", userdn); + } else { + CMS.debug("ProfileProcessor: renewal: origReq userdn not found"); + // throw new EBaseException("origReq userdn not found"); } } else { - subjectID = ILogger.UNIDENTIFIED; + CMS.debug("ProfileProcessor: renewal: authToken null"); } + return authToken; + } - return subjectID; + public IAuthToken authenticate(IProfileAuthenticator authenticator, + HttpServletRequest request) throws EBaseException { + AuthCredentials credentials = new AuthCredentials(); + + // build credential + Enumeration<String> authNames = authenticator.getValueNames(); + + if (authNames != null) { + while (authNames.hasMoreElements()) { + String authName = authNames.nextElement(); + + credentials.set(authName, request.getParameter(authName)); + } + } + + credentials.set("clientHost", request.getRemoteHost()); + IAuthToken authToken = authenticator.authenticate(credentials); + + SessionContext sc = SessionContext.getContext(); + if (sc != null) { + sc.put(SessionContext.AUTH_MANAGER_ID, authenticator.getName()); + String userid = authToken.getInString(IAuthToken.USER_ID); + if (userid != null) { + sc.put(SessionContext.USER_ID, userid); + } + } + + return authToken; + } + + private IAuthToken authenticate(HttpServletRequest request, IRequest origReq, IProfileAuthenticator authenticator, + SessionContext context, boolean isRenewal) throws EBaseException { + startTiming("profile_authentication"); + + IAuthToken authToken = null; + if (authenticator != null) { + CMS.debug("authenticate: authentication required."); + String uid_cred = "Unidentified"; + String uid_attempted_cred = "Unidentified"; + Enumeration<String> authIds = authenticator.getValueNames(); + //Attempt to possibly fetch attempted uid, may not always be available. + if (authIds != null) { + while (authIds.hasMoreElements()) { + String authName = authIds.nextElement(); + String value = request.getParameter(authName); + if (value != null) { + if (authName.equals("uid")) { + uid_attempted_cred = value; + } + } + } + } + + String authSubjectID = auditSubjectID(); + String authMgrID = authenticator.getName(); + String auditMessage = null; + try { + if (isRenewal) { + authToken = authenticate(authenticator, request, origReq, context); + } else { + authToken = authenticate(authenticator, request); + } + } catch (EBaseException e) { + CMS.debug("ProfileProcessor: authentication error " + e.toString()); + + authSubjectID += " : " + uid_cred; + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_AUTH_FAIL, + authSubjectID, + ILogger.FAILURE, + authMgrID, + uid_attempted_cred); + audit(auditMessage); + + throw e; + } + + //Log successful authentication + //Attempt to get uid from authToken, most tokens respond to the "uid" cred. + uid_cred = authToken.getInString("uid"); + + if (uid_cred == null || uid_cred.length() == 0) { + uid_cred = "Unidentified"; + } + + authSubjectID = authSubjectID + " : " + uid_cred; + + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_AUTH_SUCCESS, + authSubjectID, + ILogger.SUCCESS, + authMgrID); + + audit(auditMessage); + } + endTiming("profile_authentication"); + return authToken; + } + + public IAuthToken authenticate(CMSRequest req) + throws EBaseException { + return authenticate(req, authMgr); + } + + public IAuthToken authenticate(HttpServletRequest httpReq) + throws EBaseException { + return authenticate(httpReq, authMgr); + } + + public IAuthToken authenticate(CMSRequest req, String authMgrName) + throws EBaseException { + IAuthToken authToken = authenticate(req.getHttpReq(), + authMgrName); + + saveAuthToken(authToken, req.getIRequest()); + return authToken; + } + + public static void saveAuthToken(IAuthToken token, IRequest req) { + if (token != null && req != null) + req.setExtData(IRequest.AUTH_TOKEN, token); + + // # 56230 - expose auth token parameters to the policy predicate + if (token != null && req != null) { + Enumeration<String> e = token.getElements(); + while (e.hasMoreElements()) { + String n = e.nextElement(); + String[] x1 = token.getInStringArray(n); + if (x1 != null) { + for (int i = 0; i < x1.length; i++) { + CMS.debug("Setting " + IRequest.AUTH_TOKEN + "-" + n + + "(" + i + ")=" + x1[i]); + req.setExtData(IRequest.AUTH_TOKEN + "-" + n + "(" + i + ")", + x1[i]); + } + } else { + String x = token.getInString(n); + if (x != null) { + CMS.debug("Setting " + IRequest.AUTH_TOKEN + "-" + n + "=" + x); + req.setExtData(IRequest.AUTH_TOKEN + "-" + n, x); + } + } + } // while + } // if } + public IAuthToken authenticate(HttpServletRequest httpReq, String authMgrName) + throws EBaseException { + String auditMessage = null; + String auditSubjectID = ILogger.UNIDENTIFIED; + String auditAuthMgrID = ILogger.UNIDENTIFIED; + String auditUID = ILogger.UNIDENTIFIED; + + // ensure that any low-level exceptions are reported + // to the signed audit log and stored as failures + try { + IArgBlock httpArgs = CMS.createArgBlock(toHashtable(httpReq)); + SessionContext ctx = SessionContext.getContext(); + String ip = httpReq.getRemoteAddr(); + CMS.debug("IP: " + ip); + + if (ip != null) { + ctx.put(SessionContext.IPADDRESS, ip); + } + if (authMgrName != null) { + CMS.debug("AuthMgrName: " + authMgrName); + ctx.put(SessionContext.AUTH_MANAGER_ID, authMgrName); + } + // put locale into session context + ctx.put(SessionContext.LOCALE, getLocale(httpReq)); + + // + // check ssl client authentication if specified. + // + X509Certificate clientCert = null; + + if (getClientCert != null && getClientCert.equals("true")) { + CMS.debug("CMSServlet: retrieving SSL certificate"); + clientCert = getSSLClientCertificate(httpReq); + } + + // + // check authentication by auth manager if any. + // + if (authMgrName == null) { + + // Fixed Blackflag Bug #613900: Since this code block does + // NOT actually constitute an authentication failure, but + // rather the case in which a given servlet has been correctly + // configured to NOT require an authentication manager, the + // audit message called LOGGING_SIGNED_AUDIT_AUTH_FAIL has + // been removed. + + CMS.debug("CMSServlet: no authMgrName"); + return null; + } else { + // save the "Subject DN" of this certificate in case it + // must be audited as an authentication failure + if (clientCert == null) { + CMS.debug("CMSServlet: no client certificate found"); + } else { + String certUID = clientCert.getSubjectDN().getName(); + CMS.debug("CMSServlet: certUID=" + certUID); + + if (certUID != null) { + certUID = certUID.trim(); + + if (!(certUID.equals(""))) { + // reset the "auditUID" + auditUID = certUID; + } + } + } + // reset the "auditAuthMgrID" + auditAuthMgrID = authMgrName; + } + AuthToken authToken = CMSGateway.checkAuthManager(httpReq, + httpArgs, + clientCert, + authMgrName); + if (authToken == null) { + return null; + } + String userid = authToken.getInString(IAuthToken.USER_ID); + + CMS.debug("CMSServlet: userid=" + userid); + + if (userid != null) { + ctx.put(SessionContext.USER_ID, userid); + } + + // reset the "auditSubjectID" + auditSubjectID = auditSubjectID(); + + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_AUTH_SUCCESS, + auditSubjectID, + ILogger.SUCCESS, + auditAuthMgrID); + + audit(auditMessage); + + return authToken; + } catch (EBaseException eAudit1) { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_AUTH_FAIL, + auditSubjectID, + ILogger.FAILURE, + auditAuthMgrID, + auditUID); + audit(auditMessage); + + // rethrow the specific exception to be handled later + throw eAudit1; + } + } + + String getUidFromDN(String userdn) { + StringTokenizer st = new StringTokenizer(userdn, ","); + while (st.hasMoreTokens()) { + String t = st.nextToken(); + int i = t.indexOf("="); + + if (i == -1) { + continue; + } + String n = t.substring(0, i); + if (n.equalsIgnoreCase("uid")) { + String v = t.substring(i + 1); + CMS.debug("ProfileProcessor:: getUidFromDN(): uid found:" + v); + return v; + } else { + continue; + } + } + return null; + } + + /****************************************** + * AUTHZ FNCTIONS (to be moved to Realm? + * + * @throws EBaseException + *****************************************/ public AuthzToken authorize(String authzMgrName, String resource, IAuthToken authToken, String exp) throws EBaseException { AuthzToken authzToken = null; @@ -1406,62 +1861,355 @@ public class ProfileProcessor { authzToken = authz.authorize(authzMgrName, authToken, exp); if (authzToken != null) { auditMessage = CMS.getLogMessage( - LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS, - auditSubjectID, - ILogger.SUCCESS, - auditACLResource, - auditOperation); + LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS, + auditSubjectID, + ILogger.SUCCESS, + auditACLResource, + auditOperation); audit(auditMessage); // store a message in the signed audit log file auditMessage = CMS.getLogMessage( - LOGGING_SIGNED_AUDIT_ROLE_ASSUME, - auditSubjectID, - ILogger.SUCCESS, - auditGroupID); + LOGGING_SIGNED_AUDIT_ROLE_ASSUME, + auditSubjectID, + ILogger.SUCCESS, + auditGroupID); audit(auditMessage); } else { auditMessage = CMS.getLogMessage( - LOGGING_SIGNED_AUDIT_AUTHZ_FAIL, - auditSubjectID, - ILogger.FAILURE, - auditACLResource, - auditOperation); + LOGGING_SIGNED_AUDIT_AUTHZ_FAIL, + auditSubjectID, + ILogger.FAILURE, + auditACLResource, + auditOperation); audit(auditMessage); auditMessage = CMS.getLogMessage( - LOGGING_SIGNED_AUDIT_ROLE_ASSUME, - auditSubjectID, - ILogger.FAILURE, - auditGroupID); + LOGGING_SIGNED_AUDIT_ROLE_ASSUME, + auditSubjectID, + ILogger.FAILURE, + auditGroupID); audit(auditMessage); } return authzToken; - } catch (Exception e) { + } catch (EBaseException e) { auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_AUTHZ_FAIL, + auditSubjectID, + ILogger.FAILURE, + auditACLResource, + auditOperation); + + audit(auditMessage); + + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_ROLE_ASSUME, + auditSubjectID, + ILogger.FAILURE, + auditGroupID); + + audit(auditMessage); + throw e; + } + } + + /** + * Authorize must occur after Authenticate + * <P> + * + * <ul> + * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_FAIL used when authorization has failed + * <li>signed.audit LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS used when authorization is successful + * <li>signed.audit LOGGING_SIGNED_AUDIT_ROLE_ASSUME used when user assumes a role (in current CS that's when one + * accesses a role port) + * </ul> + * + * @param authzMgrName string representing the name of the authorization + * manager + * @param authToken the authentication token + * @param resource a string representing the ACL resource id as defined in + * the ACL resource list + * @param operation a string representing one of the operations as defined + * within the ACL statement (e. g. - "read" for an ACL statement containing + * "(read,write)") + * @exception EBaseException an error has occurred + * @return the authorization token + */ + public AuthzToken authorize(String authzMgrName, IAuthToken authToken, + String resource, String operation) { + String auditMessage = null; + String auditSubjectID = auditSubjectID(); + String auditGroupID = auditGroupID(); + String auditID = auditSubjectID; + String auditACLResource = resource; + String auditOperation = operation; + + SessionContext auditContext = SessionContext.getExistingContext(); + String authManagerId = null; + + if (auditContext != null) { + authManagerId = (String) auditContext.get(SessionContext.AUTH_MANAGER_ID); + + if (authManagerId != null && authManagerId.equals("TokenAuth")) { + if (auditSubjectID.equals(ILogger.NONROLEUSER) || + auditSubjectID.equals(ILogger.UNIDENTIFIED)) { + CMS.debug("CMSServlet: in authorize... TokenAuth auditSubjectID unavailable, changing to auditGroupID"); + auditID = auditGroupID; + } + } + } + + // "normalize" the "auditACLResource" value + if (auditACLResource != null) { + auditACLResource = auditACLResource.trim(); + } + + // "normalize" the "auditOperation" value + if (auditOperation != null) { + auditOperation = auditOperation.trim(); + } + + if (authzMgrName == null) { + // Fixed Blackflag Bug #613900: Since this code block does + // NOT actually constitute an authorization failure, but + // rather the case in which a given servlet has been correctly + // configured to NOT require an authorization manager, the + // audit message called LOGGING_SIGNED_AUDIT_AUTHZ_FAIL and + // the audit message called LOGGING_SIGNED_AUDIT_ROLE_ASSUME + // (marked as a failure) have been removed. + + return null; + } + + try { + AuthzToken authzTok = authz.authorize(authzMgrName, + authToken, + resource, + operation); + + if (authzTok != null) { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_AUTHZ_SUCCESS, + auditSubjectID, + ILogger.SUCCESS, + auditACLResource, + auditOperation); + + audit(auditMessage); + + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_ROLE_ASSUME, + auditID, + ILogger.SUCCESS, + auditGroups(auditSubjectID)); + + audit(auditMessage); + } else { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_AUTHZ_FAIL, auditSubjectID, ILogger.FAILURE, auditACLResource, auditOperation); - audit(auditMessage); + audit(auditMessage); - auditMessage = CMS.getLogMessage( + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( LOGGING_SIGNED_AUDIT_ROLE_ASSUME, - auditSubjectID, + auditID, ILogger.FAILURE, - auditGroupID); + auditGroups(auditSubjectID)); + + audit(auditMessage); + } + + return authzTok; + } catch (Exception eAudit1) { + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_AUTHZ_FAIL, + auditSubjectID, + ILogger.FAILURE, + auditACLResource, + auditOperation); audit(auditMessage); - throw new EBaseException(e.toString()); + + // store a message in the signed audit log file + auditMessage = CMS.getLogMessage( + LOGGING_SIGNED_AUDIT_ROLE_ASSUME, + auditID, + ILogger.FAILURE, + auditGroups(auditSubjectID)); + + audit(auditMessage); + + return null; + } + } + + private void authorize(String profileId, IProfile profile, IAuthToken authToken) throws EBaseException { + if (authToken != null) { + CMS.debug("ProfileProcessor authToken not null"); + + String acl = profile.getAuthzAcl(); + CMS.debug("ProfileProcessor: authz using acl: " + acl); + if (acl != null && acl.length() > 0) { + String resource = profileId + ".authz.acl"; + authorize(aclMethod, resource, authToken, acl); + } } } + /****************************************** + * AUDIT FUNCTIONS (to be moved to Auditor?) + ******************************************/ + protected void audit(String msg) { + // in this case, do NOT strip preceding/trailing whitespace + // from passed-in String parameters + + if (signedAuditLogger == null) { + return; + } + + signedAuditLogger.log(ILogger.EV_SIGNED_AUDIT, + null, + ILogger.S_SIGNED_AUDIT, + ILogger.LL_SECURITY, + msg); + } + + /** + * Signed Audit Log Requester ID + * + * This method is called to obtain the "RequesterID" for + * a signed audit log message. + * <P> + * + * @param request the actual request + * @return id string containing the signed audit log message RequesterID + */ + private String auditRequesterID(IRequest request) { + // if no signed audit object exists, bail + if (signedAuditLogger == null) { + return null; + } + + String requesterID = ILogger.UNIDENTIFIED; + + if (request != null) { + // overwrite "requesterID" if and only if "id" != null + String id = request.getRequestId().toString(); + + if (id != null) { + requesterID = id.trim(); + } + } + + return requesterID; + } + + /** + * Signed Audit Log Info Certificate Value + * + * This method is called to obtain the certificate from the passed in + * "X509CertImpl" for a signed audit log message. + * <P> + * + * @param request request containing an X509CertImpl + * @return cert string containing the certificate + */ + private String auditInfoCertValue(IRequest request) { + // if no signed audit object exists, bail + if (signedAuditLogger == null) { + return null; + } + + X509CertImpl x509cert = request.getExtDataInCert( + IEnrollProfile.REQUEST_ISSUED_CERT); + + if (x509cert == null) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + byte rawData[] = null; + + try { + rawData = x509cert.getEncoded(); + } catch (CertificateEncodingException e) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + String cert = null; + + // convert "rawData" into "base64Data" + if (rawData != null) { + String base64Data = null; + + base64Data = Utils.base64encode(rawData).trim(); + + // extract all line separators from the "base64Data" + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < base64Data.length(); i++) { + if (!Character.isWhitespace(base64Data.charAt(i))) { + sb.append(base64Data.charAt(i)); + + } + } + cert = sb.toString(); + } + + if (cert != null) { + cert = cert.trim(); + + if (cert.equals("")) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } else { + return cert; + } + } else { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + } + + protected String auditSubjectID() { + // if no signed audit object exists, bail + if (signedAuditLogger == null) { + return null; + } + + CMS.debug("CMSServlet: in auditSubjectID"); + String subjectID = null; + + // Initialize subjectID + SessionContext auditContext = SessionContext.getExistingContext(); + + CMS.debug("CMSServlet: auditSubjectID auditContext " + auditContext); + if (auditContext != null) { + subjectID = (String) + auditContext.get(SessionContext.USER_ID); + + CMS.debug("CMSServlet auditSubjectID: subjectID: " + subjectID); + if (subjectID != null) { + subjectID = subjectID.trim(); + } else { + subjectID = ILogger.NONROLEUSER; + } + } else { + subjectID = ILogger.UNIDENTIFIED; + } + + return subjectID; + } + protected String auditGroupID() { // if no signed audit object exists, bail if (signedAuditLogger == null) { @@ -1492,4 +2240,149 @@ public class ProfileProcessor { return groupID; } + /** + * Signed Audit Log Info Value + * + * This method is called to obtain the "reason" for + * a signed audit log message. + * <P> + * + * @param request the actual request + * @return reason string containing the signed audit log message reason + */ + private String auditInfoValue(IRequest request) { + // if no signed audit object exists, bail + if (signedAuditLogger == null) { + return null; + } + + String reason = ILogger.SIGNED_AUDIT_EMPTY_VALUE; + + if (request != null) { + // overwrite "reason" if and only if "info" != null + String info = + request.getExtDataInString(SIGNED_AUDIT_CERT_REQUEST_REASON); + + if (info != null) { + reason = info.trim(); + + // overwrite "reason" if and only if "reason" is empty + if (reason.equals("")) { + reason = ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + } + } + + return reason; + } + + /** + * Signed Audit Log Info Certificate Value + * + * This method is called to obtain the certificate from the passed in + * "X509CertImpl" for a signed audit log message. + * <P> + * + * @param x509cert an X509CertImpl + * @return cert string containing the certificate + */ + private String auditInfoCertValue(X509CertImpl x509cert) { + // if no signed audit object exists, bail + if (signedAuditLogger == null) { + return null; + } + + if (x509cert == null) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + byte rawData[] = null; + + try { + rawData = x509cert.getEncoded(); + } catch (CertificateEncodingException e) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + String cert = null; + + // convert "rawData" into "base64Data" + if (rawData != null) { + String base64Data = null; + + base64Data = Utils.base64encode(rawData).trim(); + + // extract all line separators from the "base64Data" + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < base64Data.length(); i++) { + if (!Character.isWhitespace(base64Data.charAt(i))) { + sb.append(base64Data.charAt(i)); + } + } + cert = sb.toString(); + } + + if (cert != null) { + cert = cert.trim(); + + if (cert.equals("")) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } else { + return cert; + } + } else { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + } + + /** + * Signed Audit Groups + * + * This method is called to extract all "groups" associated + * with the "auditSubjectID()". + * <P> + * + * @param SubjectID string containing the signed audit log message SubjectID + * @return a delimited string of groups associated + * with the "auditSubjectID()" + */ + private String auditGroups(String SubjectID) { + // if no signed audit object exists, bail + if (signedAuditLogger == null) { + return null; + } + + if ((SubjectID == null) || + (SubjectID.equals(ILogger.UNIDENTIFIED))) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + Enumeration<IGroup> groups = null; + + try { + groups = ug.findGroups("*"); + } catch (Exception e) { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + + StringBuffer membersString = new StringBuffer(); + + while (groups.hasMoreElements()) { + IGroup group = groups.nextElement(); + + if (group.isMember(SubjectID) == true) { + if (membersString.length() != 0) { + membersString.append(", "); + } + + membersString.append(group.getGroupID()); + } + } + + if (membersString.length() != 0) { + return membersString.toString(); + } else { + return ILogger.SIGNED_AUDIT_EMPTY_VALUE; + } + } } diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/PolicyAttribute.java b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyAttribute.java new file mode 100644 index 00000000..00288214 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyAttribute.java @@ -0,0 +1,63 @@ +package com.netscape.cms.servlet.profile.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.netscape.certsrv.property.Descriptor; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class PolicyAttribute { + + @XmlAttribute + private String name; + + @XmlElement + private String value; + + @XmlElement + private Descriptor descriptor; + + public PolicyAttribute() { + // required for jax-b + } + + public PolicyAttribute(String name, String value, Descriptor descriptor) { + this.name = name; + this.value = value; + this.descriptor = descriptor; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Descriptor getDescriptor() { + return descriptor; + } + + public void setDescriptor(Descriptor descriptor) { + this.descriptor = descriptor; + } + + @Override + public String toString() { + return "PolicyAttribute [name=" + name + ", value=" + value + ", descriptor=" + descriptor + "]"; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/PolicyConstraint.java b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyConstraint.java new file mode 100644 index 00000000..285f9bfb --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyConstraint.java @@ -0,0 +1,74 @@ +package com.netscape.cms.servlet.profile.model; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.netscape.certsrv.profile.IPolicyConstraint; +import com.netscape.certsrv.property.Descriptor; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class PolicyConstraint { + @XmlAttribute(name="id") + private String name; + + @XmlElement(name="description") + private String text; + + @XmlElement(name="constraint") + private List<PolicyConstraintValue> constraints = new ArrayList<PolicyConstraintValue>(); + + public PolicyConstraint() { + // required for jaxb + } + + public PolicyConstraint(Locale locale, IPolicyConstraint cons) { + this.name = cons.getName(locale); + this.text = cons.getText(locale); + + Enumeration<String> conNames = cons.getConfigNames(); + while (conNames.hasMoreElements()) { + String conName = conNames.nextElement(); + PolicyConstraintValue dataVal = + new PolicyConstraintValue(conName,(Descriptor) cons.getConfigDescriptor(locale, conName)); + this.constraints.add(dataVal); + } + } + + public void addConstraint(PolicyConstraintValue constraint) { + constraints.add(constraint); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public List<PolicyConstraintValue> getConstraints() { + return constraints; + } + + public void setConstraints(List<PolicyConstraintValue> constraints) { + this.constraints = constraints; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/PolicyConstraintValue.java b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyConstraintValue.java new file mode 100644 index 00000000..6a843750 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyConstraintValue.java @@ -0,0 +1,44 @@ +package com.netscape.cms.servlet.profile.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.netscape.certsrv.property.Descriptor; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class PolicyConstraintValue { + @XmlAttribute(name="id") + private String name; + + @XmlElement + private Descriptor descriptor; + + public PolicyConstraintValue() { + // required for jax-b + } + + public PolicyConstraintValue(String name, Descriptor descriptor) { + this.name = name; + this.descriptor = descriptor; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Descriptor getDescriptor() { + return descriptor; + } + + public void setDescriptor(Descriptor descriptor) { + this.descriptor = descriptor; + } +} diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/PolicyDefault.java b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyDefault.java new file mode 100644 index 00000000..87c496f5 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/model/PolicyDefault.java @@ -0,0 +1,78 @@ +package com.netscape.cms.servlet.profile.model; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import com.netscape.certsrv.profile.IPolicyDefault; +import com.netscape.certsrv.property.Descriptor; +import com.netscape.certsrv.property.EPropertyException; +import com.netscape.certsrv.request.IRequest; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class PolicyDefault { + @XmlAttribute(name="id") + private String name; + + @XmlElement(name="description") + private String text; + + @XmlElement(name="policyAttribute") + private List<PolicyAttribute> attributes = new ArrayList<PolicyAttribute>(); + + public PolicyDefault() { + // required for jaxb + } + + public PolicyDefault(IRequest request, Locale locale, IPolicyDefault def) throws EPropertyException { + this.name = def.getName(locale); + this.text = def.getText(locale); + + Enumeration<String> defNames = def.getValueNames(); + while (defNames.hasMoreElements()) { + String defName = defNames.nextElement(); + PolicyAttribute attr = new PolicyAttribute( + defName, + def.getValue(defName, locale, request), + (Descriptor) def.getValueDescriptor(locale, defName)); + this.attributes.add(attr); + } + } + + public void addAttribute(PolicyAttribute attr) { + attributes.add(attr); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public List<PolicyAttribute> getAttributes() { + return attributes; + } + + public void setAttributes(List<PolicyAttribute> attributes) { + this.attributes = attributes; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java b/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java index 47cfdb73..582e1089 100644 --- a/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java +++ b/base/common/src/com/netscape/cms/servlet/profile/model/ProfileInput.java @@ -18,8 +18,10 @@ package com.netscape.cms.servlet.profile.model; import java.util.ArrayList; +import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import javax.xml.bind.annotation.XmlAttribute; @@ -28,8 +30,28 @@ import javax.xml.bind.annotation.XmlValue; import javax.xml.bind.annotation.adapters.XmlAdapter; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import com.netscape.certsrv.profile.EProfileException; +import com.netscape.certsrv.profile.IProfileInput; +import com.netscape.certsrv.request.IRequest; + public class ProfileInput { + public ProfileInput() { + // required for jaxb + } + + public ProfileInput(IProfileInput input, IRequest request, Locale locale) throws EProfileException { + this.inputId = input.getName(locale); + Enumeration<String> names = input.getValueNames(); + while (names.hasMoreElements()) { + String name = names.nextElement(); + String value = input.getValue(name, locale, request); + if (value != null) { + InputAttrs.put(name, value); + } + } + } + @XmlElement public String getInputId() { return inputId; diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/ProfilePolicy.java b/base/common/src/com/netscape/cms/servlet/profile/model/ProfilePolicy.java new file mode 100644 index 00000000..4330e6f8 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/model/ProfilePolicy.java @@ -0,0 +1,65 @@ +package com.netscape.cms.servlet.profile.model; + +import java.io.ByteArrayOutputStream; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class ProfilePolicy { + @XmlAttribute + private String id = null; + + @XmlElement + private PolicyDefault def = null; + + @XmlElement + private PolicyConstraint constraint = null; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public PolicyDefault getDef() { + return def; + } + + public void setDef(PolicyDefault def) { + this.def = def; + } + + public PolicyConstraint getConstraint() { + return constraint; + } + + public void setConstraint(PolicyConstraint constraint) { + this.constraint = constraint; + } + + public String toString() { + try { + JAXBContext context = JAXBContext.newInstance(ProfilePolicy.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + marshaller.marshal(this, stream); + return stream.toString(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/profile/model/ProfilePolicySet.java b/base/common/src/com/netscape/cms/servlet/profile/model/ProfilePolicySet.java new file mode 100644 index 00000000..07b7feea --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/profile/model/ProfilePolicySet.java @@ -0,0 +1,33 @@ +package com.netscape.cms.servlet.profile.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class ProfilePolicySet { + @XmlElement + protected List<ProfilePolicy> policies = new ArrayList<ProfilePolicy>(); + + public List<ProfilePolicy> getPolicies() { + return policies; + } + + public void setPolicies(List<ProfilePolicy> policies) { + this.policies = policies; + } + + public void addPolicy(ProfilePolicy policy) { + policies.add(policy); + } + + public void removePolicy(ProfilePolicy policy) { + policies.remove(policy); + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/request/CertRequestResource.java b/base/common/src/com/netscape/cms/servlet/request/CertRequestResource.java index 3195cf73..631bd782 100644 --- a/base/common/src/com/netscape/cms/servlet/request/CertRequestResource.java +++ b/base/common/src/com/netscape/cms/servlet/request/CertRequestResource.java @@ -27,6 +27,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import com.netscape.certsrv.request.RequestId; +import com.netscape.cms.servlet.request.model.AgentEnrollmentRequestData; import com.netscape.cms.servlet.request.model.CertRequestInfo; import com.netscape.cms.servlet.request.model.CertRequestInfos; import com.netscape.cms.servlet.request.model.EnrollmentRequestData; @@ -42,6 +43,11 @@ public interface CertRequestResource { @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML }) public CertRequestInfo getRequestInfo(@PathParam("id") RequestId id); + @GET + @Path("{id}/agentView") + @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON, MediaType.TEXT_XML }) + public AgentEnrollmentRequestData reviewRequest(@PathParam("id") RequestId id); + // Enrollment - used to test integration with a browser @POST @Path("enroll") @@ -56,15 +62,37 @@ public interface CertRequestResource { public CertRequestInfos enrollCert(EnrollmentRequestData data); @POST - @Path("approve/{id}") - public void approveRequest(@PathParam("id") RequestId id); + @Path("approve") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void approveRequest(AgentEnrollmentRequestData data); @POST - @Path("reject/{id}") - public void rejectRequest(@PathParam("id") RequestId id); + @Path("reject") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void rejectRequest(AgentEnrollmentRequestData data); @POST - @Path("cancel/{id}") - public void cancelRequest(@PathParam("id") RequestId id); + @Path("cancel") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void cancelRequest(AgentEnrollmentRequestData data); + + @POST + @Path("update") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void updateRequest(AgentEnrollmentRequestData data); + @POST + @Path("validate") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void validateRequest(AgentEnrollmentRequestData data); + + @POST + @Path("unassign") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void unassignRequest(AgentEnrollmentRequestData data); + + @POST + @Path("assign") + @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + public void assignRequest(AgentEnrollmentRequestData data); } diff --git a/base/common/src/com/netscape/cms/servlet/request/CertRequestResourceService.java b/base/common/src/com/netscape/cms/servlet/request/CertRequestResourceService.java index 8046fa8a..928b561a 100644 --- a/base/common/src/com/netscape/cms/servlet/request/CertRequestResourceService.java +++ b/base/common/src/com/netscape/cms/servlet/request/CertRequestResourceService.java @@ -18,14 +18,24 @@ package com.netscape.cms.servlet.request; -import javax.servlet.ServletException; +import javax.ws.rs.PathParam; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import com.netscape.certsrv.apps.CMS; +import com.netscape.certsrv.authentication.EAuthException; +import com.netscape.certsrv.authorization.EAuthzException; +import com.netscape.certsrv.base.BadRequestDataException; import com.netscape.certsrv.base.EBaseException; +import com.netscape.certsrv.profile.EDeferException; +import com.netscape.certsrv.profile.EProfileException; +import com.netscape.certsrv.profile.ERejectException; +import com.netscape.certsrv.property.EPropertyException; import com.netscape.certsrv.request.RequestId; import com.netscape.cms.servlet.base.BadRequestException; import com.netscape.cms.servlet.base.CMSException; import com.netscape.cms.servlet.base.CMSResourceService; +import com.netscape.cms.servlet.request.model.AgentEnrollmentRequestData; import com.netscape.cms.servlet.request.model.CertRequestDAO; import com.netscape.cms.servlet.request.model.CertRequestInfo; import com.netscape.cms.servlet.request.model.CertRequestInfos; @@ -75,41 +85,104 @@ public class CertRequestResourceService extends CMSResourceService implements Ce CertRequestDAO dao = new CertRequestDAO(); try { - infos = dao.submitRequest(data, servletRequest, uriInfo); + infos = dao.submitRequest(data, servletRequest, uriInfo, getLocale()); + } catch (EAuthException e) { + CMS.debug("enrollCert: authentication failed: " + e); + throw new CMSException(Response.Status.UNAUTHORIZED, e.toString()); + } catch (EAuthzException e) { + CMS.debug("enrollCert: authorization failed: " + e); + throw new CMSException(Response.Status.UNAUTHORIZED, e.toString()); + } catch (BadRequestDataException e) { + CMS.debug("enrollCert: bad request data: " + e); + throw new CMSException(Response.Status.BAD_REQUEST, e.toString()); } catch (EBaseException e) { - throw new CMSException("Problem enrolling cert in CertRequestResource.enrollCert!"); - } catch (ServletException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - throw new CMSException("Problem enrolling cert in CertRequestResource.enrollCert!"); + throw new CMSException(e.toString()); } return infos; } - public void approveRequest(RequestId id) { - if (id == null) { - throw new BadRequestException("Bad data input in CertRequestResourceService.approveRequest!"); - } - //TODO implement - throw new CMSException("Problem approving request in CertRequestResource.approveRequest!"); + public void approveRequest(AgentEnrollmentRequestData data) { + changeRequestState(data, "approve"); } - public void rejectRequest(RequestId id) { - if (id == null) { - throw new BadRequestException("Bad data input into CertRequestResourceService.rejectRequest!"); - } - //TODO implement + public void rejectRequest(AgentEnrollmentRequestData data) { + changeRequestState(data, "reject"); + } - throw new CMSException("Problem rejecting request in CertRequestResource.rejectRequest!"); + public void cancelRequest(AgentEnrollmentRequestData data) { + changeRequestState(data, "cancel"); + } + public void updateRequest(AgentEnrollmentRequestData data) { + changeRequestState(data, "update"); } - public void cancelRequest(RequestId id) { + public void validateRequest(AgentEnrollmentRequestData data) { + changeRequestState(data, "validate"); + } + + public void unassignRequest(AgentEnrollmentRequestData data) { + changeRequestState(data, "unassign"); + } + + public void assignRequest(AgentEnrollmentRequestData data) { + changeRequestState(data, "assign"); + } + + public void changeRequestState(AgentEnrollmentRequestData data, String op) { + RequestId id = data.getRequestId(); if (id == null) { - throw new BadRequestException("Bad data input in CertRequestResourceService.cancelRequest!"); + throw new BadRequestException("Bad data input in CertRequestResourceService. op:" + op); + } + + CertRequestDAO dao = new CertRequestDAO(); + try { + dao.changeRequestState(servletRequest, data, getLocale(), op); + } catch (ERejectException e) { + CMS.debug("changeRequestState: execution rejected " + e); + throw new CMSException(Response.Status.BAD_REQUEST, + CMS.getUserMessage(getLocale(), "CMS_PROFILE_REJECTED", e.toString())); + } catch (EDeferException e) { + CMS.debug("changeRequestState: execution defered " + e); + // TODO do we throw an exception here? + throw new CMSException(Response.Status.BAD_REQUEST, + CMS.getUserMessage(getLocale(), "CMS_PROFILE_DEFERRED", e.toString())); + } catch (BadRequestDataException e) { + CMS.debug("changeRequestState: bad request data: " + e); + throw new CMSException(Response.Status.BAD_REQUEST, e.toString()); + } catch (EPropertyException e) { + CMS.debug("changeRequestState: execution error " + e); + throw new CMSException(CMS.getUserMessage(getLocale(), + "CMS_PROFILE_PROPERTY_ERROR", e.toString())); + } catch (EProfileException e) { + CMS.debug("ProfileProcessServlet: execution error " + e); + throw new CMSException(CMS.getUserMessage(getLocale(), "CMS_INTERNAL_ERROR")); + } catch (EBaseException e) { + e.printStackTrace(); + throw new CMSException("Problem approving request in CertRequestResource.assignRequest!"); } - //TODO implement - throw new CMSException("Problem cancelling request in CertRequestResource.cancelRequest!"); } + + public AgentEnrollmentRequestData reviewRequest(@PathParam("id") RequestId id) { + // auth and authz + AgentEnrollmentRequestData info; + + CertRequestDAO dao = new CertRequestDAO(); + try { + info = dao.reviewRequest(servletRequest, id, uriInfo, getLocale()); + } catch (EBaseException e) { + // log error + e.printStackTrace(); + throw new CMSException("Error getting Cert request info!"); + } + + if (info == null) { + // request does not exist + throw new RequestNotFoundException(id); + } + + return info; + } + } diff --git a/base/common/src/com/netscape/cms/servlet/request/model/AgentEnrollmentRequestData.java b/base/common/src/com/netscape/cms/servlet/request/model/AgentEnrollmentRequestData.java new file mode 100644 index 00000000..0596d918 --- /dev/null +++ b/base/common/src/com/netscape/cms/servlet/request/model/AgentEnrollmentRequestData.java @@ -0,0 +1,210 @@ +package com.netscape.cms.servlet.request.model; + +import java.io.ByteArrayOutputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.Marshaller; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import com.netscape.certsrv.request.RequestId; +import com.netscape.certsrv.request.RequestIdAdapter; +import com.netscape.cms.servlet.profile.model.ProfilePolicySet; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class AgentEnrollmentRequestData extends EnrollmentRequestData { + + @XmlElement(name="ProfilePolicySet") + protected List<ProfilePolicySet> policySets = new ArrayList<ProfilePolicySet>(); + + protected String nonce; + + @XmlElement + @XmlJavaTypeAdapter(RequestIdAdapter.class) + protected RequestId requestId; + + protected String requestType; + + protected String requestStatus; + + protected String requestOwner; + + protected String requestCreationTime; + + protected String requestModificationTime; + + protected String requestNotes; + + protected String profileApprovedBy; + + protected String profileSetId; + + protected String profileIsVisible; + + protected String profileName; + + protected String profileDescription; + + protected String profileRemoteHost; + + protected String profileRemoteAddr; + + public String getNonce() { + return nonce; + } + + public void setNonce(String nonce) { + this.nonce = nonce; + } + + public RequestId getRequestId() { + return requestId; + } + + public void setRequestId(RequestId requestId) { + this.requestId = requestId; + } + + public String getRequestType() { + return requestType; + } + + public void setRequestType(String requestType) { + this.requestType = requestType; + } + + public String getRequestStatus() { + return requestStatus; + } + + public void setRequestStatus(String requestStatus) { + this.requestStatus = requestStatus; + } + + public String getRequestOwner() { + return requestOwner; + } + + public void setRequestOwner(String requestOwner) { + this.requestOwner = requestOwner; + } + + public String getRequestCreationTime() { + return requestCreationTime; + } + + public void setRequestCreationTime(String requestCreationTime) { + this.requestCreationTime = requestCreationTime; + } + + public String getRequestModificationTime() { + return requestModificationTime; + } + + public void setRequestModificationTime(String requestModificationTime) { + this.requestModificationTime = requestModificationTime; + } + + public String getRequestNotes() { + return requestNotes; + } + + public void setRequestNotes(String requestNotes) { + this.requestNotes = requestNotes; + } + + public String getProfileApprovedBy() { + return profileApprovedBy; + } + + public void setProfileApprovedBy(String profileApprovedBy) { + this.profileApprovedBy = profileApprovedBy; + } + + public String getProfileSetId() { + return profileSetId; + } + + public void setProfileSetId(String profileSetId) { + this.profileSetId = profileSetId; + } + + public String getProfileIsVisible() { + return profileIsVisible; + } + + public void setProfileIsVisible(String profileIsVisible) { + this.profileIsVisible = profileIsVisible; + } + + public String getProfileName() { + return profileName; + } + + public void setProfileName(String profileName) { + this.profileName = profileName; + } + + public String getProfileDescription() { + return profileDescription; + } + + public void setProfileDescription(String profileDescription) { + this.profileDescription = profileDescription; + } + + public String getProfileRemoteHost() { + return profileRemoteHost; + } + + public void setProfileRemoteHost(String profileRemoteHost) { + this.profileRemoteHost = profileRemoteHost; + } + + public String getProfileRemoteAddr() { + return profileRemoteAddr; + } + + public void setProfileRemoteAddr(String profileRemoteAddr) { + this.profileRemoteAddr = profileRemoteAddr; + } + + public String toString() { + try { + JAXBContext context = JAXBContext.newInstance(AgentEnrollmentRequestData.class); + Marshaller marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + + marshaller.marshal(this, stream); + return stream.toString(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public List<ProfilePolicySet> getPolicySets() { + return policySets; + } + + public void setPolicySets(List<ProfilePolicySet> policySets) { + this.policySets = policySets; + } + + public void addProfilePolicySet(ProfilePolicySet policySet) { + policySets.add(policySet); + } + + public void removeProfilePolicySet(ProfilePolicySet policySet) { + policySets.remove(policySet); + } + +} diff --git a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java index 0809fe8d..d68a5ac1 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestDAO.java @@ -20,10 +20,12 @@ package com.netscape.cms.servlet.request.model; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; +import java.util.Enumeration; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Random; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; @@ -35,17 +37,27 @@ import netscape.security.x509.X509CertImpl; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.base.EBaseException; -import com.netscape.certsrv.base.IConfigStore; +import com.netscape.certsrv.base.Nonces; import com.netscape.certsrv.ca.ICertificateAuthority; import com.netscape.certsrv.profile.IEnrollProfile; +import com.netscape.certsrv.profile.IPolicyDefault; +import com.netscape.certsrv.profile.IProfile; +import com.netscape.certsrv.profile.IProfileInput; +import com.netscape.certsrv.profile.IProfilePolicy; +import com.netscape.certsrv.profile.IProfileSubsystem; import com.netscape.certsrv.request.IRequest; import com.netscape.certsrv.request.IRequestQueue; import com.netscape.certsrv.request.RequestId; -import com.netscape.certsrv.request.RequestStatus; import com.netscape.cms.servlet.cert.CertResource; -import com.netscape.cms.servlet.common.ServletUtils; +import com.netscape.cms.servlet.common.CMSRequest; +import com.netscape.cms.servlet.profile.ProfileConfig; import com.netscape.cms.servlet.profile.ProfileProcessor; +import com.netscape.cms.servlet.profile.model.PolicyAttribute; +import com.netscape.cms.servlet.profile.model.PolicyConstraint; +import com.netscape.cms.servlet.profile.model.PolicyDefault; import com.netscape.cms.servlet.profile.model.ProfileInput; +import com.netscape.cms.servlet.profile.model.ProfilePolicy; +import com.netscape.cms.servlet.profile.model.ProfilePolicySet; import com.netscape.cms.servlet.request.CertRequestResource; /** @@ -55,16 +67,20 @@ import com.netscape.cms.servlet.request.CertRequestResource; public class CertRequestDAO extends CMSRequestDAO { private IRequestQueue queue; private ICertificateAuthority ca; + private Nonces nonces = null; + private Random random = null; public static final String ATTR_SERIALNO = "serialNumber"; private static final String REQ_COMPLETE = "complete"; public CertRequestDAO() { - super("ca"); ca = (ICertificateAuthority) CMS.getSubsystem("ca"); queue = ca.getRequestQueue(); - + if (ca.noncesEnabled()) { + random = new Random(); + nonces = ca.getNonces(); + } } /** @@ -131,6 +147,37 @@ public class CertRequestDAO extends CMSRequestDAO { } /** + * Gets info for a specific request + * + * @param id + * @return info for specific request + * @throws EBaseException + */ + public AgentEnrollmentRequestData reviewRequest(HttpServletRequest servletRequest, RequestId id, + UriInfo uriInfo, Locale locale) throws EBaseException { + IRequest request = queue.findRequest(id); + if (request == null) { + return null; + } + AgentEnrollmentRequestData info = createAgentCertRequestInfo(request, uriInfo, locale); + if (ca.noncesEnabled()) { + addNonce(info, servletRequest); + } + return info; + } + + + private void addNonce(AgentEnrollmentRequestData info, HttpServletRequest servletRequest) throws EBaseException { + if (nonces != null) { + long n = random.nextLong(); + long m = nonces.addNonce(n, ProfileProcessor.getSSLClientCertificate(servletRequest)); + if ((n + m) != 0) { + info.setNonce(Long.toString(m)); + } + } + } + + /** * Submits an enrollment request and processes it. * * @param data @@ -138,22 +185,13 @@ public class CertRequestDAO extends CMSRequestDAO { * @throws EBaseException * @throws ServletException */ - public CertRequestInfos submitRequest(EnrollmentRequestData data, HttpServletRequest request, UriInfo uriInfo) throws EBaseException, - ServletException { + public CertRequestInfos submitRequest(EnrollmentRequestData data, HttpServletRequest request, UriInfo uriInfo, + Locale locale) throws EBaseException { HttpServletRequest extReq = createServletRequest(request, data); - IConfigStore cs = CMS.getConfigStore(); - String profileID = null; - try { - profileID = cs.getString("caProfileSubmit.profileID"); - } catch (Exception e) { - // no profileID specified - } - Locale locale = request.getLocale(); - - String aclMethod = ServletUtils.getACLMethod("caProfileSubmit"); + ProfileConfig config = new ProfileConfig("caProfileSubmit"); - ProfileProcessor processor = new ProfileProcessor("ca", profileID, aclMethod, locale); + ProfileProcessor processor = new ProfileProcessor(config, locale); HashMap<String, Object> results; if (data.getIsRenewal()) { results = processor.processRenewal(extReq); @@ -162,9 +200,9 @@ public class CertRequestDAO extends CMSRequestDAO { } CertRequestInfos ret = new CertRequestInfos(); - ArrayList<CertRequestInfo> infos= new ArrayList<CertRequestInfo>(); - IRequest reqs[] = (IRequest []) results.get(ProfileProcessor.ARG_REQUESTS); - for (IRequest req: reqs) { + ArrayList<CertRequestInfo> infos = new ArrayList<CertRequestInfo>(); + IRequest reqs[] = (IRequest[]) results.get(ProfileProcessor.ARG_REQUESTS); + for (IRequest req : reqs) { CertRequestInfo info = createCertRequestInfo(req, uriInfo); infos.add(info); } @@ -191,27 +229,53 @@ public class CertRequestDAO extends CMSRequestDAO { return extReq; } - public void approveRequest(RequestId id) throws EBaseException { - IRequest request = queue.findRequest(id); - request.setRequestStatus(RequestStatus.APPROVED); - queue.updateRequest(request); - } + public void changeRequestState(HttpServletRequest request, AgentEnrollmentRequestData data, Locale locale, String op) + throws EBaseException { + ProfileConfig config = new ProfileConfig("caProfileProcess"); + ProfileProcessor processor = new ProfileProcessor(config, locale); + CMSRequest cmsReq = createCMSRequest(request, data, op); + + processor.processRequest(cmsReq); - public void rejectRequest(RequestId id) throws EBaseException { - IRequest request = queue.findRequest(id); - request.setRequestStatus(RequestStatus.CANCELED); - queue.updateRequest(request); } - public void cancelRequest(RequestId id) throws EBaseException { - IRequest request = queue.findRequest(id); - request.setRequestStatus(RequestStatus.REJECTED); - queue.updateRequest(request); + private CMSRequest createCMSRequest(HttpServletRequest request, AgentEnrollmentRequestData data, String op) { + + ExtendableHttpRequest extReq = new ExtendableHttpRequest(request); + extReq.addParameter("profileId", data.getProfileId()); + extReq.addParameter("serial_num", data.getSerialNum()); + extReq.addParameter("requestId", data.getRequestId().toString()); + extReq.addParameter("requestNotes", data.getRequestNotes()); + + if (nonces != null) { + extReq.addParameter("nonces", data.getNonce()); + } + + for (ProfilePolicySet policySet: data.getPolicySets()) { + for (ProfilePolicy policy: policySet.getPolicies()) { + PolicyDefault def = policy.getDef(); + List<PolicyAttribute> attrs = def.getAttributes(); + for (PolicyAttribute attr: attrs) { + extReq.addParameter(attr.getName(), attr.getValue()); + } + } + } + + extReq.addParameter(ProfileProcessor.ARG_OP, op); + + CMSRequest ret = new CMSRequest(); + ret.setHttpReq(extReq); + + return ret; } private CertRequestInfo createCertRequestInfo(IRequest request, UriInfo uriInfo) { CertRequestInfo ret = new CertRequestInfo(); + populateCertRequestInfo(request, uriInfo, ret); + return ret; + } + private void populateCertRequestInfo(IRequest request, UriInfo uriInfo, CertRequestInfo ret) { String requestType = request.getRequestType(); String requestStatus = request.getRequestStatus().toString(); @@ -251,8 +315,6 @@ public class CertRequestDAO extends CMSRequestDAO { certBuilder.path(certPath.value() + "/" + serialNoStr); ret.setCertURL(certBuilder.build().toString()); } - - return ret; } @Override @@ -260,4 +322,92 @@ public class CertRequestDAO extends CMSRequestDAO { return createCertRequestInfo(request, uriInfo); } + public AgentEnrollmentRequestData createAgentCertRequestInfo(IRequest request, UriInfo uriInfo, Locale locale) throws EBaseException { + AgentEnrollmentRequestData ret = new AgentEnrollmentRequestData(); + + String profileId = request.getExtDataInString("profileId"); + ProfileConfig config = new ProfileConfig("caProfileSubmit"); + IProfileSubsystem ps = (IProfileSubsystem) CMS.getSubsystem(config.getProfileSubId()); + IProfile profile = ps.getProfile(profileId); + + ret.setProfileId(request.getExtDataInString("profileId")); + if (request.getRequestType().equals("renewal")) { + ret.setIsRenewal(true); + } else { + ret.setIsRenewal(false); + } + + ret.setRequestId(request.getRequestId()); + ret.setRequestType(request.getRequestType()); + ret.setRequestStatus(request.getRequestStatus().toString()); + if (request.getRequestOwner() == null) { + ret.setRequestOwner(""); + } else { + ret.setRequestOwner(request.getRequestOwner()); + } + ret.setRequestCreationTime(request.getCreationTime().toString()); + ret.setRequestModificationTime(request.getModificationTime().toString()); + + ret.setProfileId(profileId); + ret.setProfileApprovedBy(request.getExtDataInString("profileApprovedBy")); + ret.setProfileSetId(request.getExtDataInString("profileSetId")); + if (profile.isVisible()) { + ret.setProfileIsVisible("true"); + } else { + ret.setProfileIsVisible("false"); + } + + ret.setProfileName(profile.getName(locale)); + ret.setProfileDescription(profile.getDescription(locale)); + ret.setProfileRemoteHost(request.getExtDataInString("profileRemoteHost")); + ret.setProfileRemoteAddr(request.getExtDataInString("profileRemoteAddr")); + if (request.getExtDataInString("requestNotes") == null) { + ret.setRequestNotes(""); + } else { + ret.setRequestNotes(request.getExtDataInString("requestNotes")); + } + + // populate profile inputs + Enumeration<String> inputIds = profile.getProfileInputIds(); + while (inputIds.hasMoreElements()) { + IProfileInput input = profile.getProfileInput(inputIds.nextElement()); + ProfileInput addInput = new ProfileInput(input, request, locale); + ret.addInput(addInput); + } + + String profileSetId = request.getExtDataInString("profileSetId"); + CMS.debug("createAgentCertRequestInfo: profileSetId=" + profileSetId); + Enumeration<String> policyIds = (profileSetId != null && profileSetId.length() > 0) ? + profile.getProfilePolicyIds(profileSetId) : null; + ProfilePolicySet dataPolicySet = new ProfilePolicySet(); + + if (policyIds != null) { + while (policyIds.hasMoreElements()) { + String id = policyIds.nextElement(); + CMS.debug("policyId:" + id); + IProfilePolicy policy = profile.getProfilePolicy(profileSetId, id); + ProfilePolicy dataPolicy = new ProfilePolicy(); + + //populate defaults + IPolicyDefault def = policy.getDefault(); + PolicyDefault dataDef = new PolicyDefault(request, locale, def); + dataPolicy.setDef(dataDef); + + //populate constraints + PolicyConstraint dataCons = new PolicyConstraint(locale, policy.getConstraint()); + dataPolicy.setConstraint(dataCons); + + dataPolicySet.addPolicy(dataPolicy); + CMS.debug(dataPolicy.toString()); + } + } + + + ret.addProfilePolicySet(dataPolicySet); + + // TODO populate profile outputs + + CMS.debug(ret.toString()); + return ret; + } } diff --git a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java index 25083126..20c29813 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/CertRequestInfo.java @@ -74,6 +74,7 @@ public class CertRequestInfo extends CMSRequestInfo { */ public CertId getCertId() { + if (certURL == null) return null; String id = certURL.substring(certURL.lastIndexOf("/") + 1); return new CertId(id); } diff --git a/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java b/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java index aa2f4a33..2e10fa8a 100644 --- a/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java +++ b/base/common/src/com/netscape/cms/servlet/request/model/EnrollmentRequestData.java @@ -65,6 +65,7 @@ public class EnrollmentRequestData { protected List<ProfileInput> inputs = new ArrayList<ProfileInput>(); public EnrollmentRequestData() { + // required for jaxb } public EnrollmentRequestData(MultivaluedMap<String, String> form) { @@ -99,7 +100,22 @@ public class EnrollmentRequestData { return isRenewal; } - public ProfileInput addInput(String name) { + public void addInput(ProfileInput input) { + ProfileInput curInput = getInput(input.getInputId()); + if (curInput != null) { + inputs.remove(curInput); + } + inputs.add(input); + } + + public void deleteInput(ProfileInput input) { + ProfileInput curInput = getInput(input.getInputId()); + if (curInput != null) { + inputs.remove(curInput); + } + } + + public ProfileInput createInput(String name) { ProfileInput oldInput = getInput(name); @@ -121,11 +137,8 @@ public class EnrollmentRequestData { Iterator<ProfileInput> it = inputs.iterator(); ProfileInput curInput = null; - while (it.hasNext()) - - { + while (it.hasNext()) { curInput = it.next(); - if (curInput != null && curInput.getInputId().equals(name)) break; } @@ -147,13 +160,13 @@ public class EnrollmentRequestData { //Simulate a "caUserCert" Profile enrollment - ProfileInput certReq = data.addInput("KeyGenInput"); + ProfileInput certReq = data.createInput("KeyGenInput"); certReq.setInputAttr("cert_request_type", "crmf"); certReq.setInputAttr( "cert_request", "MIIBozCCAZ8wggEFAgQBMQp8MIHHgAECpQ4wDDEKMAgGA1UEAxMBeKaBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA2NgaPHp0jiohcP4M+ufrJOZEqH8GV+liu5JLbT8nWpkfhC+8EUBqT6g+n3qroSxIcNVGNdcsBEqs1utvpItzyslAbpdyat3WwQep1dWMzo6RHrPDuIoxNA0Yka1n3qEX4U//08cLQtUv2bYglYgN/hOCNQemLV6vZWAv0n7zelkCAwEAAakQMA4GA1UdDwEB/wQEAwIF4DAzMBUGCSsGAQUFBwUBAQwIcmVnVG9rZW4wGgYJKwYBBQUHBQECDA1hdXRoZW50aWNhdG9yoYGTMA0GCSqGSIb3DQEBBQUAA4GBAJ1VOQcaSEhdHa94s8kifVbSZ2WZeYE5//qxL6wVlEst20vq4ybj13CetnbN3+WT49Zkwp7Fg+6lALKgSk47suTg3EbbQDm+8yOrC0nc/q4PTRoHl0alMmUxIhirYc1t3xoCMqJewmjX1bNP8lpVIZAYFZo4eZCpZaiSkM5BeHhz"); - ProfileInput subjectName = data.addInput("SubjectNameInput"); + ProfileInput subjectName = data.createInput("SubjectNameInput"); subjectName.setInputAttr("sn_uid", "jmagne"); subjectName.setInputAttr("sn_e", "jmagne@redhat.com"); subjectName.setInputAttr("sn_c", "US"); @@ -164,7 +177,7 @@ public class EnrollmentRequestData { subjectName.setInputAttr("sn_cn", "Common"); subjectName.setInputAttr("sn_o", "RedHat"); - ProfileInput submitter = data.addInput("SubmitterInfoInput"); + ProfileInput submitter = data.createInput("SubmitterInfoInput"); submitter.setInputAttr("requestor_name", "admin"); submitter.setInputAttr("requestor_email", "admin@redhat.com"); submitter.setInputAttr("requestor_phone", "650-555-5555"); |