Added implicit authorization to the agent executor API.

This patch updates the agent handler for the executor API to
verify the FrameworkID and ExecutorID contained within the
executor's `Principal`, if present. This effectively performs
implicit authorization of executor calls.

Review: https://reviews.apache.org/r/58255/


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ccb102f2
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ccb102f2
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ccb102f2

Branch: refs/heads/master
Commit: ccb102f212d38cd5ad2bb5ce848b8ebe7629b6ba
Parents: ecab5ff
Author: Greg Mann <[email protected]>
Authored: Fri Apr 21 10:45:24 2017 -0700
Committer: Vinod Kone <[email protected]>
Committed: Fri Apr 21 10:45:24 2017 -0700

----------------------------------------------------------------------
 src/slave/http.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/ccb102f2/src/slave/http.cpp
----------------------------------------------------------------------
diff --git a/src/slave/http.cpp b/src/slave/http.cpp
index 93825fa..2ce345d 100644
--- a/src/slave/http.cpp
+++ b/src/slave/http.cpp
@@ -619,6 +619,40 @@ string Slave::Http::EXECUTOR_HELP() {
 }
 
 
+// TODO(greggomann): Remove this function when implicit executor authorization
+// is moved into the authorizer. See MESOS-7399.
+Option<Error> verifyExecutorClaims(
+    const Principal& principal,
+    const FrameworkID& frameworkId,
+    const ExecutorID& executorId,
+    const ContainerID& containerId) {
+  if (!(principal.claims.contains("fid") &&
+        principal.claims.at("fid") == frameworkId.value())) {
+    return Error(
+        "Authenticated principal '" + stringify(principal) + "' does not "
+        "contain an 'fid' claim with the framework ID " +
+        stringify(frameworkId) + ", which is set in the call");
+  }
+
+  if (!(principal.claims.contains("eid") &&
+        principal.claims.at("eid") == executorId.value())) {
+    return Error(
+        "Authenticated principal '" + stringify(principal) + "' does not "
+        "contain an 'eid' claim with the executor ID " +
+        stringify(executorId) + ", which is set in the call");
+  }
+
+  if (!(principal.claims.contains("cid") &&
+        principal.claims.at("cid") == containerId.value())) {
+    return Error(
+        "Authenticated principal '" + stringify(principal) + "' does not "
+        "contain a 'cid' claim with the correct active ContainerID");
+  }
+
+  return None();
+}
+
+
 Future<Response> Slave::Http::executor(
     const Request& request,
     const Option<Principal>& principal) const
@@ -707,6 +741,20 @@ Future<Response> Slave::Http::executor(
     return BadRequest("Executor cannot be found");
   }
 
+  // TODO(greggomann): Move this implicit executor authorization
+  // into the authorizer. See MESOS-7399.
+  if (principal.isSome()) {
+    error = verifyExecutorClaims(
+        principal.get(),
+        call.framework_id(),
+        call.executor_id(),
+        executor->containerId);
+
+    if (error.isSome()) {
+      return Forbidden(error->message);
+    }
+  }
+
   if (executor->state == Executor::REGISTERING &&
       call.type() != executor::Call::SUBSCRIBE) {
     return Forbidden("Executor is not subscribed");

Reply via email to