From a07e4174f57e7eef24e57499ccff84296cf5d6a8 Mon Sep 17 00:00:00 2001
From: Ade Lee <alee@redhat.com>
Date: Sat, 16 Apr 2016 16:43:28 -0400
Subject: [PATCH 292/293] Add authz checks for all operations

We add authz realm checks as appropriate for each
operation.

Part of Trac Ticket #2041
---
 base/kra/src/CMakeLists.txt                        |  8 +-
 .../server/kra/rest/KeyRequestService.java         | 89 ++++++++++++++--------
 .../org/dogtagpki/server/kra/rest/KeyService.java  | 40 +++++++++-
 .../com/netscape/cms/servlet/base/PKIService.java  |  3 +
 .../netscape/cms/servlet/key/KeyRequestDAO.java    | 60 ++++++++++++---
 5 files changed, 156 insertions(+), 44 deletions(-)

diff --git a/base/kra/src/CMakeLists.txt b/base/kra/src/CMakeLists.txt
index bcac9704cd60a5d4dbac3ba948fc9dbcc002e4f2..bfc8cdddaf150a4030e9c48ddebf8e8e828018a6 100644
--- a/base/kra/src/CMakeLists.txt
+++ b/base/kra/src/CMakeLists.txt
@@ -104,6 +104,12 @@ find_file(COMMONS_LANG_JAR
 	/usr/share/java
 )
 
+find_file(TOMCAT_CATALINA_JAR
+    NAMES
+        catalina.jar
+    PATHS
+        /usr/share/java/tomcat
+)
 
 # build pki-kra
 javac(pki-kra-classes
@@ -117,7 +123,7 @@ javac(pki-kra-classes
         ${SERVLET_JAR}
         ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR} ${RESTEASY_ATOM_PROVIDER_JAR}
         ${PKI_CMSUTIL_JAR} ${PKI_NSUTIL_JAR}
-        ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR}
+        ${PKI_CERTSRV_JAR} ${PKI_CMS_JAR} ${PKI_CMSCORE_JAR} ${TOMCAT_CATALINA_JAR}
     OUTPUT_DIR
         ${CMAKE_BINARY_DIR}/classes
     DEPENDS
diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java b/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java
index 39f2d33a3dbbaa39e111b363163a508694ef1120..8504f0ea2b5c713f99fc171e9ad8b65c9fe291bb 100644
--- a/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java
+++ b/base/kra/src/org/dogtagpki/server/kra/rest/KeyRequestService.java
@@ -21,6 +21,7 @@ package org.dogtagpki.server.kra.rest;
 import java.lang.reflect.InvocationTargetException;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.security.Principal;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -35,6 +36,8 @@ import javax.ws.rs.core.UriInfo;
 import org.mozilla.jss.crypto.SymmetricKey;
 
 import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
 import com.netscape.certsrv.base.BadRequestException;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.PKIException;
@@ -52,6 +55,7 @@ import com.netscape.certsrv.key.SymKeyGenerationRequest;
 import com.netscape.certsrv.logging.ILogger;
 import com.netscape.certsrv.request.RequestId;
 import com.netscape.certsrv.request.RequestNotFoundException;
+import com.netscape.cms.realm.PKIPrincipal;
 import com.netscape.cms.servlet.base.PKIService;
 import com.netscape.cms.servlet.key.KeyRequestDAO;
 import com.netscape.cmsutil.ldap.LDAPUtil;
@@ -118,7 +122,9 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         KeyRequestDAO dao = new KeyRequestDAO();
         KeyRequestInfo info;
         try {
-            info = dao.getRequest(id, uriInfo);
+            info = dao.getRequest(id, uriInfo, getAuthToken());
+        } catch (EAuthzAccessDenied e) {
+            throw new UnauthorizedException("Not authorized to get request");
         } catch (EBaseException e) {
             // log error
             e.printStackTrace();
@@ -162,11 +168,10 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         KeyRequestDAO dao = new KeyRequestDAO();
         KeyRequestResponse response;
         try {
-            String owner = servletRequest.getUserPrincipal().getName();
-            if (owner == null) {
+            if (getRequestor() == null) {
                 throw new UnauthorizedException("Archival must be performed by an agent");
             }
-            response = dao.submitRequest(data, uriInfo, owner);
+            response = dao.submitRequest(data, uriInfo, getRequestor());
             auditArchivalRequestMade(response.getRequestInfo().getRequestId(), ILogger.SUCCESS, data.getClientKeyId());
 
             return createCreatedResponse(response, new URI(response.getRequestInfo().getRequestURL()));
@@ -197,14 +202,12 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         KeyRequestDAO dao = new KeyRequestDAO();
         KeyRequestResponse response;
         try {
-            String requestor = servletRequest.getUserPrincipal().getName();
-            if (requestor == null) {
+            if (getRequestor() == null) {
                 throw new UnauthorizedException("Recovery must be initiated by an agent");
             }
             response = (data.getCertificate() != null)?
-                    dao.submitAsyncKeyRecoveryRequest(data, uriInfo, requestor):
-                    dao.submitRequest(data, uriInfo, requestor);
-
+                    dao.submitAsyncKeyRecoveryRequest(data, uriInfo, getRequestor(), getAuthToken()):
+                    dao.submitRequest(data, uriInfo, getRequestor(), getAuthToken());
             auditRecoveryRequestMade(response.getRequestInfo().getRequestId(),
                     ILogger.SUCCESS, data.getKeyId());
 
@@ -223,13 +226,14 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
             throw new BadRequestException("Invalid request id.");
         }
         KeyRequestDAO dao = new KeyRequestDAO();
-        String requestor = servletRequest.getUserPrincipal().getName();
-        if (requestor == null) {
+        if (getRequestor() == null) {
             throw new UnauthorizedException("Request approval must be initiated by an agent");
         }
         try {
-            dao.approveRequest(id, requestor);
+            dao.approveRequest(id, getRequestor(), getAuthToken());
             auditRecoveryRequestChange(id, ILogger.SUCCESS, "approve");
+        } catch (EAuthzAccessDenied e) {
+            throw new UnauthorizedException("Not authorized to approve request");
         } catch (EBaseException e) {
             e.printStackTrace();
             auditRecoveryRequestChange(id, ILogger.FAILURE, "approve");
@@ -247,8 +251,10 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         // auth and authz
         KeyRequestDAO dao = new KeyRequestDAO();
         try {
-            dao.rejectRequest(id);
+            dao.rejectRequest(id, getAuthToken());
             auditRecoveryRequestChange(id, ILogger.SUCCESS, "reject");
+        }catch (EAuthzAccessDenied e) {
+            throw new UnauthorizedException("Not authorized to reject request");
         } catch (EBaseException e) {
             e.printStackTrace();
             auditRecoveryRequestChange(id, ILogger.FAILURE, "reject");
@@ -266,8 +272,10 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         // auth and authz
         KeyRequestDAO dao = new KeyRequestDAO();
         try {
-            dao.cancelRequest(id);
+            dao.cancelRequest(id, getAuthToken());
             auditRecoveryRequestChange(id, ILogger.SUCCESS, "cancel");
+        } catch (EAuthzAccessDenied e) {
+            throw new UnauthorizedException("Not authorized to cancel request");
         } catch (EBaseException e) {
             e.printStackTrace();
             auditRecoveryRequestChange(id, ILogger.FAILURE, "cancel");
@@ -283,8 +291,16 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
     @Override
     public Response listRequests(String requestState, String requestType, String clientKeyID,
             RequestId start, Integer pageSize, Integer maxResults, Integer maxTime, String realm) {
-        // auth and authz
-
+        if (realm != null) {
+            try {
+                authz.checkRealm(realm, getAuthToken(), null, "keyRequests", "list");
+            } catch (EAuthzAccessDenied e) {
+                throw new UnauthorizedException("Not authorized to list these requests");
+            } catch (EBaseException e) {
+                CMS.debug("listRequests: unable to authorize realm" + e);
+                throw new PKIException(e.toString());
+            }
+        }
         // get ldap filter
         String filter = createSearchFilter(requestState, requestType, clientKeyID, realm);
         CMS.debug("listRequests: filter is " + filter);
@@ -306,7 +322,8 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         return createOKResponse(requests);
     }
 
-    private String createSearchFilter(String requestState, String requestType, String clientKeyID, String realm) {
+    private String createSearchFilter(String requestState, String requestType, String clientKeyID,
+            String realm) {
         String filter = "";
         int matches = 0;
 
@@ -317,17 +334,17 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
 
         if (requestState != null) {
             filter += "(requeststate=" + LDAPUtil.escapeFilter(requestState) + ")";
-            matches ++;
+            matches++;
         }
 
         if (requestType != null) {
             filter += "(requesttype=" + LDAPUtil.escapeFilter(requestType) + ")";
-            matches ++;
+            matches++;
         }
 
         if (clientKeyID != null) {
             filter += "(clientID=" + LDAPUtil.escapeFilter(clientKeyID) + ")";
-            matches ++;
+            matches++;
         }
 
         if (realm != null) {
@@ -348,7 +365,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
     public void auditRecoveryRequestChange(RequestId requestId, String status, String operation) {
         String msg = CMS.getLogMessage(
                 LOGGING_SIGNED_AUDIT_SECURITY_DATA_RECOVERY_REQUEST_STATE_CHANGE,
-                servletRequest.getUserPrincipal().getName(),
+                getRequestor(),
                 status,
                 requestId.toString(),
                 operation);
@@ -358,7 +375,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
     public void auditRecoveryRequestMade(RequestId requestId, String status, KeyId dataId) {
         String msg = CMS.getLogMessage(
                 LOGGING_SIGNED_AUDIT_SECURITY_DATA_RECOVERY_REQUEST,
-                servletRequest.getUserPrincipal().getName(),
+                getRequestor(),
                 status,
                 requestId != null? requestId.toString(): "null",
                 dataId.toString());
@@ -368,7 +385,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
     public void auditArchivalRequestMade(RequestId requestId, String status, String clientKeyID) {
         String msg = CMS.getLogMessage(
                 LOGGING_SIGNED_AUDIT_SECURITY_DATA_ARCHIVAL_REQUEST,
-                servletRequest.getUserPrincipal().getName(),
+                getRequestor(),
                 status,
                 requestId != null? requestId.toString(): "null",
                 clientKeyID);
@@ -378,7 +395,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
     public void auditSymKeyGenRequestMade(RequestId requestId, String status, String clientKeyID) {
         String msg = CMS.getLogMessage(
                 LOGGING_SIGNED_AUDIT_SYMKEY_GENERATION_REQUEST,
-                servletRequest.getUserPrincipal().getName(),
+                getRequestor(),
                 status,
                 requestId != null ? requestId.toString() : "null",
                 clientKeyID);
@@ -388,7 +405,7 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
     public void auditAsymKeyGenRequestMade(RequestId requestId, String status, String clientKeyID) {
         String msg = CMS.getLogMessage(
                 LOGGING_SIGNED_AUDIT_ASYMKEY_GENERATION_REQUEST,
-                servletRequest.getUserPrincipal().getName(),
+                getRequestor(),
                 status,
                 requestId != null ? requestId.toString() : "null",
                 clientKeyID);
@@ -433,11 +450,10 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         KeyRequestDAO dao = new KeyRequestDAO();
         KeyRequestResponse response;
         try {
-            String owner = servletRequest.getUserPrincipal().getName();
-            if (owner == null) {
+            if (getRequestor() == null) {
                 throw new UnauthorizedException("Key generation must be performed by an agent");
             }
-            response = dao.submitRequest(data, uriInfo, owner);
+            response = dao.submitRequest(data, uriInfo, getRequestor());
             auditSymKeyGenRequestMade(response.getRequestInfo().getRequestId(), ILogger.SUCCESS,
                     data.getClientKeyId());
 
@@ -458,8 +474,10 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
         KeyRequestDAO dao = new KeyRequestDAO();
         KeyRequestResponse response;
         try {
-            String owner = servletRequest.getUserPrincipal().getName();
-            response = dao.submitRequest(data, uriInfo, owner);
+            if (getRequestor() == null) {
+                throw new UnauthorizedException("Key generation must be performed by an agent");
+            }
+            response = dao.submitRequest(data, uriInfo, getRequestor());
             auditAsymKeyGenRequestMade(response.getRequestInfo().getRequestId(), ILogger.SUCCESS,
                     data.getClientKeyId());
 
@@ -471,4 +489,15 @@ public class KeyRequestService extends PKIService implements KeyRequestResource
             throw new PKIException(e.toString());
         }
     }
+
+    private IAuthToken getAuthToken() {
+        Principal principal = servletRequest.getUserPrincipal();
+        PKIPrincipal pkiprincipal = (PKIPrincipal) principal;
+        IAuthToken authToken = pkiprincipal.getAuthToken();
+        return authToken;
+    }
+
+    private String getRequestor() {
+        return servletRequest.getUserPrincipal().getName();
+    }
 }
diff --git a/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java b/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
index 43a5f540ab9aeeccffbdaab60390e84938fda77b..52df7696ff36e6a59592970b1e4bd6bc4080b258 100644
--- a/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
+++ b/base/kra/src/org/dogtagpki/server/kra/rest/KeyService.java
@@ -21,6 +21,7 @@ package org.dogtagpki.server.kra.rest;
 
 import java.math.BigInteger;
 import java.net.URI;
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Enumeration;
@@ -41,6 +42,8 @@ import javax.ws.rs.core.UriInfo;
 import org.jboss.resteasy.plugins.providers.atom.Link;
 
 import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
+import com.netscape.certsrv.authorization.EAuthzAccessDenied;
 import com.netscape.certsrv.base.BadRequestException;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.HTTPGoneException;
@@ -67,6 +70,7 @@ 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.realm.PKIPrincipal;
 import com.netscape.cms.servlet.base.PKIService;
 import com.netscape.cms.servlet.key.KeyRequestDAO;
 import com.netscape.cmsutil.ldap.LDAPUtil;
@@ -337,7 +341,7 @@ public class KeyService extends PKIService implements KeyResource {
         KeyRequestDAO reqDAO = new KeyRequestDAO();
         KeyRequestInfo reqInfo;
         try {
-            reqInfo = reqDAO.getRequest(reqId, uriInfo);
+            reqInfo = reqDAO.getRequest(reqId, uriInfo, getAuthToken());
         } catch (EBaseException e1) {
             // failed to get request
             logMessage = "failed to get request";
@@ -415,6 +419,17 @@ public class KeyService extends PKIService implements KeyResource {
         start = start == null ? 0 : start;
         size = size == null ? DEFAULT_SIZE : size;
 
+        if (realm != null) {
+            try {
+                authz.checkRealm(realm, getAuthToken(), null, "keys", "list");
+            } catch (EAuthzAccessDenied e) {
+                throw new UnauthorizedException("Not authorized to list these keys");
+            } catch (EBaseException e) {
+                CMS.debug("listRequests: unable to authorize realm" + e);
+                throw new PKIException(e.toString());
+            }
+        }
+
         // get ldap filter
         String filter = createSearchFilter(status, clientKeyID, realm);
         CMS.debug("listKeys: filter is " + filter);
@@ -489,7 +504,16 @@ public class KeyService extends PKIService implements KeyResource {
         while (iter.hasNext()) {
             KeyInfo info = iter.next();
             if (info != null) {
-                // return the first one
+                // return the first one, but first confirm that the requester has access to this key
+                try {
+                    authz.checkRealm(info.getRealm(), getAuthToken(), info.getOwnerName(), "key", "read");
+                } catch (EAuthzAccessDenied e) {
+                    throw new UnauthorizedException("Not authorized to read this key");
+                } catch (EBaseException e) {
+                    CMS.debug("listRequests: unable to authorize realm" + e);
+                    throw new PKIException(e.toString());
+                }
+
                 auditRetrieveKey(ILogger.SUCCESS, null, clientKeyID, auditInfo);
 
                 return createOKResponse(info);
@@ -654,10 +678,15 @@ public class KeyService extends PKIService implements KeyResource {
         IKeyRecord rec = null;
         try {
             rec = repo.readKeyRecord(keyId.toBigInteger());
+            authz.checkRealm(rec.getRealm(), getAuthToken(), rec.getOwnerName(), "key", "read");
             KeyInfo info = createKeyDataInfo(rec, true);
             auditRetrieveKey(ILogger.SUCCESS, null, keyId, auditInfo);
 
             return createOKResponse(info);
+        } catch (EAuthzAccessDenied e) {
+            auditInfo = method + "Unauthorized access for key record";
+            auditRetrieveKey(ILogger.FAILURE, null, keyId, auditInfo);
+            throw new UnauthorizedException(auditInfo);
         } catch (EDBRecordNotFoundException e) {
             auditInfo = method + e.getMessage();
             auditRetrieveKey(ILogger.FAILURE, null, keyId, auditInfo);
@@ -672,6 +701,13 @@ public class KeyService extends PKIService implements KeyResource {
         }
     }
 
+    private IAuthToken getAuthToken() {
+        Principal principal = servletRequest.getUserPrincipal();
+        PKIPrincipal pkiprincipal = (PKIPrincipal) principal;
+        IAuthToken authToken = pkiprincipal.getAuthToken();
+        return authToken;
+    }
+
     @Override
     public Response modifyKeyStatus(KeyId keyId, String status) {
         String method = "KeyService.modifyKeyStatus: ";
diff --git a/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java b/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java
index 7ed9c0dc86b08add5066a9c6df29ce791775e54e..d8d9cee5d58c48484ed10a66e21b861cfb91af98 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/base/PKIService.java
@@ -43,6 +43,7 @@ import javax.ws.rs.core.Response.ResponseBuilder;
 import javax.ws.rs.core.UriInfo;
 
 import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authorization.IAuthzSubsystem;
 import com.netscape.certsrv.base.PKIException;
 import com.netscape.certsrv.logging.IAuditor;
 import com.netscape.certsrv.logging.ILogger;
@@ -85,6 +86,8 @@ public class PKIService {
     @Context
     protected ServletContext servletContext;
 
+    protected IAuthzSubsystem authz = (IAuthzSubsystem) CMS.getSubsystem(CMS.SUBSYSTEM_AUTHZ);
+
     public ILogger logger = CMS.getLogger();
     public IAuditor auditor = CMS.getAuditor();
 
diff --git a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
index bdb1269a80499f212e639379431086136d9727a0..8aa0d21eeb6386c06f55553eef811522ff006106 100644
--- a/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
+++ b/base/server/cms/src/com/netscape/cms/servlet/key/KeyRequestDAO.java
@@ -36,9 +36,11 @@ import org.mozilla.jss.crypto.KeyGenAlgorithm;
 import org.mozilla.jss.crypto.KeyPairAlgorithm;
 
 import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authentication.IAuthToken;
 import com.netscape.certsrv.base.BadRequestException;
 import com.netscape.certsrv.base.EBaseException;
 import com.netscape.certsrv.base.PKIException;
+import com.netscape.certsrv.base.UnauthorizedException;
 import com.netscape.certsrv.dbs.EDBRecordNotFoundException;
 import com.netscape.certsrv.dbs.keydb.IKeyRecord;
 import com.netscape.certsrv.dbs.keydb.IKeyRepository;
@@ -122,6 +124,7 @@ public class KeyRequestDAO extends CMSRequestDAO {
      * @param maxResults - max results to be returned in normal search
      * @param maxTime - max time for normal search
      * @param uriInfo - uri context of request
+     * @param authToken - auth token
      * @return collection of key request info
      * @throws EBaseException
      */
@@ -153,14 +156,20 @@ public class KeyRequestDAO extends CMSRequestDAO {
      * Gets info for a specific request
      *
      * @param id
+     * @param uriInfo
+     * @param authToken - authentication token for this request
      * @return info for specific request
      * @throws EBaseException
      */
-    public KeyRequestInfo getRequest(RequestId id, UriInfo uriInfo) throws EBaseException {
+    public KeyRequestInfo getRequest(RequestId id, UriInfo uriInfo, IAuthToken authToken) throws EBaseException {
         IRequest request = queue.findRequest(id);
         if (request == null) {
             return null;
         }
+
+        authz.checkRealm(request.getRealm(), authToken, request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER),
+                "keyRequest", "read");
+
         KeyRequestInfo info = createKeyRequestInfo(request, uriInfo);
         return info;
     }
@@ -228,10 +237,14 @@ public class KeyRequestDAO extends CMSRequestDAO {
      * Submits a key recovery request.
      *
      * @param data
+     * @param uriInfo
+     * @param requestor
+     * @param authToken
      * @return info on the recovery request created
      * @throws EBaseException
      */
-    public KeyRequestResponse submitRequest(KeyRecoveryRequest data, UriInfo uriInfo, String requestor)
+    public KeyRequestResponse submitRequest(KeyRecoveryRequest data, UriInfo uriInfo, String requestor,
+            IAuthToken authToken)
             throws EBaseException {
         // set data using request.setExtData(field, data)
 
@@ -249,6 +262,12 @@ public class KeyRequestDAO extends CMSRequestDAO {
             throw new KeyNotFoundException(keyId);
         }
 
+        try {
+            authz.checkRealm(rec.getRealm(), authToken, rec.getOwnerName(), "key", "recover");
+        } catch (EBaseException e) {
+            throw new UnauthorizedException("Agent not authorized by realm");
+        }
+
         Hashtable<String, Object> requestParams;
 
         requestParams = ((IKeyRecoveryAuthority) authority).createVolatileRequest(request.getRequestId());
@@ -286,7 +305,7 @@ public class KeyRequestDAO extends CMSRequestDAO {
     }
 
     public KeyRequestResponse submitAsyncKeyRecoveryRequest(KeyRecoveryRequest data, UriInfo uriInfo,
-            String requestor) throws EBaseException {
+            String requestor, IAuthToken authToken) throws EBaseException {
         if (data == null) {
             throw new BadRequestException("Invalid request.");
         }
@@ -299,6 +318,12 @@ public class KeyRequestDAO extends CMSRequestDAO {
             throw new KeyNotFoundException(keyId);
         }
 
+        try {
+            authz.checkRealm(rec.getRealm(), authToken, rec.getOwnerName(), "key", "recover");
+        } catch (EBaseException e) {
+            throw new UnauthorizedException("Agent not authorized by realm");
+        }
+
         String b64Certificate = data.getCertificate();
         byte[] certData = Utils.base64decode(b64Certificate);
         String requestId = null;
@@ -317,7 +342,6 @@ public class KeyRequestDAO extends CMSRequestDAO {
         return createCMSRequestResponse(request, uriInfo);
     }
 
-
     public KeyRequestResponse submitRequest(SymKeyGenerationRequest data, UriInfo uriInfo, String owner)
             throws EBaseException {
         String clientKeyId = data.getClientKeyId();
@@ -455,33 +479,47 @@ public class KeyRequestDAO extends CMSRequestDAO {
         request.setExtData(IRequest.SECURITY_DATA_CLIENT_KEY_ID, clientKeyId);
         request.setExtData(IRequest.ATTR_REQUEST_OWNER, owner);
 
+        if (realm != null) {
+            request.setRealm(realm);
+        }
+
         if (transWrappedSessionKey != null) {
             request.setExtData(IRequest.KEY_GEN_TRANS_WRAPPED_SESSION_KEY,
                     transWrappedSessionKey);
         }
 
-        if (realm != null) {
-            request.setRealm(realm);
-        }
-
         queue.processRequest(request);
         queue.markAsServiced(request);
 
         return createKeyRequestResponse(request, uriInfo);
     }
 
-    public void approveRequest(RequestId id, String requestor) throws EBaseException {
+    public void approveRequest(RequestId id, String requestor, IAuthToken authToken)
+            throws EBaseException {
+        IRequest request = queue.findRequest(id);
+        authz.checkRealm(request.getRealm(), authToken,
+                request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER),
+                "keyRequest", "approve");
+
         service.addAgentAsyncKeyRecovery(id.toString(), requestor);
     }
 
-    public void rejectRequest(RequestId id) throws EBaseException {
+    public void rejectRequest(RequestId id, IAuthToken authToken) throws EBaseException {
         IRequest request = queue.findRequest(id);
+        String realm = request.getRealm();
+        authz.checkRealm(realm, authToken,
+                request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER),
+                "keyRequest", "reject");
         request.setRequestStatus(RequestStatus.REJECTED);
         queue.updateRequest(request);
     }
 
-    public void cancelRequest(RequestId id) throws EBaseException {
+    public void cancelRequest(RequestId id, IAuthToken authToken) throws EBaseException {
         IRequest request = queue.findRequest(id);
+        String realm = request.getRealm();
+        authz.checkRealm(realm, authToken,
+                request.getExtDataInString(IRequest.ATTR_REQUEST_OWNER),
+                "keyRequest", "cancel");
         request.setRequestStatus(RequestStatus.CANCELED);
         queue.updateRequest(request);
     }
-- 
2.4.3

