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");
