Repository: mesos
Updated Branches:
  refs/heads/master 4e2eddb6f -> 1bb7ed289


Allowed the agent to require executor authentication.

This patch updates the agent initialization code to make use
of the new `--authenticate_http_executors` flag. When the
flag is set, authentication is required on the executor realm
and the JWT authenticator is loaded.

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


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

Branch: refs/heads/master
Commit: 1bb7ed28977d9b03c6a9162e8d8d10c7420a47f9
Parents: 3e62a13
Author: Greg Mann <[email protected]>
Authored: Fri Mar 24 10:01:06 2017 -0700
Committer: Anand Mazumdar <[email protected]>
Committed: Fri Mar 24 10:01:33 2017 -0700

----------------------------------------------------------------------
 src/common/http.cpp | 39 ++++++++++++++++++++++++++++++-
 src/common/http.hpp |  7 +++++-
 src/slave/flags.cpp |  3 +--
 src/slave/flags.hpp |  2 +-
 src/slave/slave.cpp | 60 ++++++++++++++++++++++++++++++++++++++++++++----
 src/slave/slave.hpp |  6 +++++
 6 files changed, 108 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/1bb7ed28/src/common/http.cpp
----------------------------------------------------------------------
diff --git a/src/common/http.cpp b/src/common/http.cpp
index 942761e..7afbc61 100644
--- a/src/common/http.cpp
+++ b/src/common/http.cpp
@@ -30,6 +30,7 @@
 #include <mesos/authorizer/authorizer.hpp>
 #include <mesos/module/http_authenticator.hpp>
 
+#include <process/authenticator.hpp>
 #include <process/dispatch.hpp>
 #include <process/future.hpp>
 #include <process/http.hpp>
@@ -59,6 +60,9 @@ using process::Failure;
 using process::Owned;
 
 using process::http::authentication::Authenticator;
+#ifdef USE_SSL_SOCKET
+using process::http::authentication::JWTAuthenticator;
+#endif // USE_SSL_SOCKET
 using process::http::authentication::Principal;
 
 using process::http::authorization::AuthorizationCallbacks;
@@ -962,6 +966,28 @@ Result<Authenticator*> createBasicAuthenticator(
 }
 
 
+#ifdef USE_SSL_SOCKET
+Result<Authenticator*> createJWTAuthenticator(
+    const string& realm,
+    const string& authenticatorName,
+    const Option<string>& secretKey)
+{
+  if (secretKey.isNone()) {
+    return Error(
+        "No secret key provided for the default '" +
+        string(internal::DEFAULT_JWT_HTTP_AUTHENTICATOR) +
+        "' HTTP authenticator for realm '" + realm + "'");
+  }
+
+  LOG(INFO) << "Creating default '"
+            << internal::DEFAULT_JWT_HTTP_AUTHENTICATOR
+            << "' HTTP authenticator for realm '" << realm << "'";
+
+  return new JWTAuthenticator(realm, secretKey.get());
+}
+#endif // USE_SSL_SOCKET
+
+
 Result<Authenticator*> createCustomAuthenticator(
     const string& realm,
     const string& authenticatorName)
@@ -986,7 +1012,8 @@ Result<Authenticator*> createCustomAuthenticator(
 Try<Nothing> initializeHttpAuthenticators(
     const string& realm,
     const vector<string>& authenticatorNames,
-    const Option<Credentials>& credentials)
+    const Option<Credentials>& credentials,
+    const Option<string>& secretKey)
 {
   if (authenticatorNames.empty()) {
     return Error(
@@ -1000,6 +1027,12 @@ Try<Nothing> initializeHttpAuthenticators(
     if (authenticatorNames[0] == internal::DEFAULT_BASIC_HTTP_AUTHENTICATOR) {
       authenticator_ =
         createBasicAuthenticator(realm, authenticatorNames[0], credentials);
+#ifdef USE_SSL_SOCKET
+    } else if (
+        authenticatorNames[0] == internal::DEFAULT_JWT_HTTP_AUTHENTICATOR) {
+      authenticator_ =
+        createJWTAuthenticator(realm, authenticatorNames[0], secretKey);
+#endif // USE_SSL_SOCKET
     } else {
       authenticator_ = createCustomAuthenticator(realm, authenticatorNames[0]);
     }
@@ -1020,6 +1053,10 @@ Try<Nothing> initializeHttpAuthenticators(
       Result<Authenticator*> authenticator_ = None();
       if (name == internal::DEFAULT_BASIC_HTTP_AUTHENTICATOR) {
         authenticator_ = createBasicAuthenticator(realm, name, credentials);
+#ifdef USE_SSL_SOCKET
+      } else if (name == internal::DEFAULT_JWT_HTTP_AUTHENTICATOR) {
+        authenticator_ = createJWTAuthenticator(realm, name, secretKey);
+#endif // USE_SSL_SOCKET
       } else {
         authenticator_ = createCustomAuthenticator(realm, name);
       }

http://git-wip-us.apache.org/repos/asf/mesos/blob/1bb7ed28/src/common/http.hpp
----------------------------------------------------------------------
diff --git a/src/common/http.hpp b/src/common/http.hpp
index 23984b3..9a10312 100644
--- a/src/common/http.hpp
+++ b/src/common/http.hpp
@@ -46,6 +46,9 @@ namespace internal {
 // Name of the default, basic authenticator.
 constexpr char DEFAULT_BASIC_HTTP_AUTHENTICATOR[] = "basic";
 
+// Name of the default, JWT authenticator.
+constexpr char DEFAULT_JWT_HTTP_AUTHENTICATOR[] = "jwt";
+
 extern hashset<std::string> AUTHORIZABLE_ENDPOINTS;
 
 
@@ -206,6 +209,7 @@ bool approveViewRole(
  * @param realm name of the realm.
  * @param authenticatorNames a vector of authenticator names.
  * @param credentials optional credentials for BasicAuthenticator only.
+ * @param secretKey optional secret key for the JWTAuthenticator only.
  * @return nothing if authenticators are initialized and registered to
  *         libprocess successfully, or error if authenticators cannot
  *         be initialized.
@@ -213,7 +217,8 @@ bool approveViewRole(
 Try<Nothing> initializeHttpAuthenticators(
     const std::string& realm,
     const std::vector<std::string>& httpAuthenticatorNames,
-    const Option<Credentials>& credentials);
+    const Option<Credentials>& credentials = None(),
+    const Option<std::string>& secretKey = None());
 
 } // namespace mesos {
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/1bb7ed28/src/slave/flags.cpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.cpp b/src/slave/flags.cpp
index 8d2e2e3..7688153 100644
--- a/src/slave/flags.cpp
+++ b/src/slave/flags.cpp
@@ -877,8 +877,7 @@ mesos::internal::slave::Flags::Flags()
       "HTTP authenticator implementation to use when handling requests to\n"
       "authenticated endpoints. Use the default\n"
       "`" + string(DEFAULT_BASIC_HTTP_AUTHENTICATOR) + "`, or load an\n"
-      "alternate HTTP authenticator module using `--modules`.",
-      DEFAULT_BASIC_HTTP_AUTHENTICATOR);
+      "alternate HTTP authenticator module using `--modules`.");
 
   add(&Flags::authenticate_http_readwrite,
       "authenticate_http_readwrite",

http://git-wip-us.apache.org/repos/asf/mesos/blob/1bb7ed28/src/slave/flags.hpp
----------------------------------------------------------------------
diff --git a/src/slave/flags.hpp b/src/slave/flags.hpp
index 2d982f9..224fac1 100644
--- a/src/slave/flags.hpp
+++ b/src/slave/flags.hpp
@@ -144,7 +144,7 @@ public:
   Option<std::string> modulesDir;
   std::string authenticatee;
   std::string authorizer;
-  std::string http_authenticators;
+  Option<std::string> http_authenticators;
   bool authenticate_http_readonly;
   bool authenticate_http_readwrite;
 #ifdef USE_SSL_SOCKET

http://git-wip-us.apache.org/repos/asf/mesos/blob/1bb7ed28/src/slave/slave.cpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.cpp b/src/slave/slave.cpp
index 3acb29d..d68d6b9 100644
--- a/src/slave/slave.cpp
+++ b/src/slave/slave.cpp
@@ -31,6 +31,8 @@
 
 #include <mesos/type_utils.hpp>
 
+#include <mesos/authentication/secret_generator.hpp>
+
 #include <mesos/module/authenticatee.hpp>
 
 #include <process/async.hpp>
@@ -63,6 +65,10 @@
 
 #include "authentication/cram_md5/authenticatee.hpp"
 
+#ifdef USE_SSL_SOCKET
+#include "authentication/executor/jwt_secret_generator.hpp"
+#endif // USE_SSL_SOCKET
+
 #include "common/build.hpp"
 #include "common/protobuf_utils.hpp"
 #include "common/resources_utils.hpp"
@@ -98,6 +104,12 @@
 
 using google::protobuf::RepeatedPtrField;
 
+using mesos::SecretGenerator;
+
+#ifdef USE_SSL_SOCKET
+using mesos::authentication::executor::JWTSecretGenerator;
+#endif // USE_SSL_SOCKET
+
 using mesos::authorization::createSubject;
 
 using mesos::executor::Call;
@@ -260,11 +272,50 @@ void Slave::initialize()
     httpCredentials = credentials.get();
   }
 
+  string httpAuthenticators;
+  if (flags.http_authenticators.isSome()) {
+    httpAuthenticators = flags.http_authenticators.get();
+#ifdef USE_SSL_SOCKET
+  } else if (flags.authenticate_http_executors) {
+    httpAuthenticators =
+      string(DEFAULT_BASIC_HTTP_AUTHENTICATOR) + "," +
+      string(DEFAULT_JWT_HTTP_AUTHENTICATOR);
+#endif // USE_SSL_SOCKET
+  } else {
+    httpAuthenticators = DEFAULT_BASIC_HTTP_AUTHENTICATOR;
+  }
+
+  Option<string> secretKey;
+#ifdef USE_SSL_SOCKET
+  if (flags.executor_secret_key.isSome()) {
+    secretKey = flags.executor_secret_key.get();
+    secretGenerator.reset(new JWTSecretGenerator(secretKey.get()));
+  }
+
+  if (flags.authenticate_http_executors) {
+    if (flags.executor_secret_key.isNone()) {
+      EXIT(EXIT_FAILURE) << "--executor_secret_key must be specified when "
+                         << "--authenticate_http_executors is set to true";
+    }
+
+    Try<Nothing> result = initializeHttpAuthenticators(
+        EXECUTOR_HTTP_AUTHENTICATION_REALM,
+        strings::split(httpAuthenticators, ","),
+        httpCredentials,
+        secretKey);
+
+    if (result.isError()) {
+      EXIT(EXIT_FAILURE) << result.error();
+    }
+  }
+#endif // USE_SSL_SOCKET
+
   if (flags.authenticate_http_readonly) {
     Try<Nothing> result = initializeHttpAuthenticators(
         READONLY_HTTP_AUTHENTICATION_REALM,
-        strings::split(flags.http_authenticators, ","),
-        httpCredentials);
+        strings::split(httpAuthenticators, ","),
+        httpCredentials,
+        secretKey);
 
     if (result.isError()) {
       EXIT(EXIT_FAILURE) << result.error();
@@ -274,8 +325,9 @@ void Slave::initialize()
   if (flags.authenticate_http_readwrite) {
     Try<Nothing> result = initializeHttpAuthenticators(
         READWRITE_HTTP_AUTHENTICATION_REALM,
-        strings::split(flags.http_authenticators, ","),
-        httpCredentials);
+        strings::split(httpAuthenticators, ","),
+        httpCredentials,
+        secretKey);
 
     if (result.isError()) {
       EXIT(EXIT_FAILURE) << result.error();

http://git-wip-us.apache.org/repos/asf/mesos/blob/1bb7ed28/src/slave/slave.hpp
----------------------------------------------------------------------
diff --git a/src/slave/slave.hpp b/src/slave/slave.hpp
index 7ab646e..e06525b 100644
--- a/src/slave/slave.hpp
+++ b/src/slave/slave.hpp
@@ -32,6 +32,8 @@
 
 #include <mesos/agent/agent.hpp>
 
+#include <mesos/authentication/secret_generator.hpp>
+
 #include <mesos/executor/executor.hpp>
 
 #include <mesos/master/detector.hpp>
@@ -884,6 +886,10 @@ private:
   // The most recent estimate of the total amount of oversubscribed
   // (allocated and oversubscribable) resources.
   Option<Resources> oversubscribedResources;
+
+protected:
+  // Made protected for testing purposes.
+  process::Owned<mesos::SecretGenerator> secretGenerator;
 };
 
 

Reply via email to