You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by zj...@apache.org on 2014/11/05 19:58:17 UTC

git commit: YARN-2767. Added a test case to verify that http static user cannot kill or submit apps in the secure mode. Contributed by Varun Vasudev.

Repository: hadoop
Updated Branches:
  refs/heads/trunk 7b07acb0a -> b4c951ab8


YARN-2767. Added a test case to verify that http static user cannot kill or submit apps in the secure mode. Contributed by Varun Vasudev.


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

Branch: refs/heads/trunk
Commit: b4c951ab832f85189d815fb6df57eda4121c0199
Parents: 7b07acb
Author: Zhijie Shen <zj...@apache.org>
Authored: Wed Nov 5 10:56:39 2014 -0800
Committer: Zhijie Shen <zj...@apache.org>
Committed: Wed Nov 5 10:57:38 2014 -0800

----------------------------------------------------------------------
 hadoop-yarn-project/CHANGES.txt                 |   3 +
 ...tRMWebServicesHttpStaticUserPermissions.java | 195 +++++++++++++++++++
 2 files changed, 198 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hadoop/blob/b4c951ab/hadoop-yarn-project/CHANGES.txt
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/CHANGES.txt b/hadoop-yarn-project/CHANGES.txt
index b5aec42..2870583 100644
--- a/hadoop-yarn-project/CHANGES.txt
+++ b/hadoop-yarn-project/CHANGES.txt
@@ -862,6 +862,9 @@ Release 2.6.0 - UNRELEASED
     YARN-2804. Fixed Timeline service to not fill the logs with JAXB bindings
     exceptions. (Zhijie Shen via vinodkv)
 
+    YARN-2767. Added a test case to verify that http static user cannot kill or submit
+    apps in the secure mode. (Varun Vasudev via zjshen)
+
 Release 2.5.2 - UNRELEASED
 
   INCOMPATIBLE CHANGES

http://git-wip-us.apache.org/repos/asf/hadoop/blob/b4c951ab/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesHttpStaticUserPermissions.java
----------------------------------------------------------------------
diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesHttpStaticUserPermissions.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesHttpStaticUserPermissions.java
new file mode 100644
index 0000000..3d47233
--- /dev/null
+++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/webapp/TestRMWebServicesHttpStaticUserPermissions.java
@@ -0,0 +1,195 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.yarn.server.resourcemanager.webapp;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.Map;
+import java.util.HashMap;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
+import org.apache.hadoop.minikdc.MiniKdc;
+import org.apache.hadoop.security.UserGroupInformation;
+import org.apache.hadoop.security.authentication.KerberosTestUtils;
+import org.apache.hadoop.yarn.conf.YarnConfiguration;
+import org.apache.hadoop.yarn.server.resourcemanager.MockRM;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.ResourceScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.scheduler.fifo.FifoScheduler;
+import org.apache.hadoop.yarn.server.resourcemanager.webapp.dao.ApplicationSubmissionContextInfo;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.sun.jersey.api.client.ClientResponse.Status;
+
+public class TestRMWebServicesHttpStaticUserPermissions {
+
+  private static final File testRootDir = new File("target",
+    TestRMWebServicesHttpStaticUserPermissions.class.getName() + "-root");
+  private static File spnegoKeytabFile = new File(
+    KerberosTestUtils.getKeytabFile());
+
+  private static String spnegoPrincipal = KerberosTestUtils
+    .getServerPrincipal();
+
+  private static MiniKdc testMiniKDC;
+  private static MockRM rm;
+
+  static class Helper {
+    String method;
+    String requestBody;
+
+    Helper(String method, String requestBody) {
+      this.method = method;
+      this.requestBody = requestBody;
+    }
+  }
+
+  @BeforeClass
+  public static void setUp() {
+    try {
+      testMiniKDC = new MiniKdc(MiniKdc.createConf(), testRootDir);
+      setupKDC();
+      setupAndStartRM();
+    } catch (Exception e) {
+      fail("Couldn't create MiniKDC");
+    }
+  }
+
+  @AfterClass
+  public static void tearDown() {
+    if (testMiniKDC != null) {
+      testMiniKDC.stop();
+    }
+    if (rm != null) {
+      rm.stop();
+    }
+  }
+
+  public TestRMWebServicesHttpStaticUserPermissions() throws Exception {
+    super();
+  }
+
+  private static void setupAndStartRM() throws Exception {
+    Configuration rmconf = new Configuration();
+    rmconf.setInt(YarnConfiguration.RM_AM_MAX_ATTEMPTS,
+      YarnConfiguration.DEFAULT_RM_AM_MAX_ATTEMPTS);
+    rmconf.setClass(YarnConfiguration.RM_SCHEDULER, FifoScheduler.class,
+      ResourceScheduler.class);
+    rmconf.setBoolean(YarnConfiguration.YARN_ACL_ENABLE, true);
+    rmconf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION,
+      "kerberos");
+    rmconf.set("yarn.resourcemanager.principal", spnegoPrincipal);
+    rmconf.set("yarn.resourcemanager.keytab",
+        spnegoKeytabFile.getAbsolutePath());
+    rmconf.setBoolean("mockrm.webapp.enabled", true);
+    UserGroupInformation.setConfiguration(rmconf);
+    rm = new MockRM(rmconf);
+    rm.start();
+
+  }
+
+  private static void setupKDC() throws Exception {
+    testMiniKDC.start();
+    testMiniKDC.createPrincipal(spnegoKeytabFile, "HTTP/localhost", "client",
+      UserGroupInformation.getLoginUser().getShortUserName(), "client2");
+  }
+
+  // Test that the http static user can't submit or kill apps
+  // when secure mode is turned on
+
+  @Test
+  public void testWebServiceAccess() throws Exception {
+
+    ApplicationSubmissionContextInfo app =
+        new ApplicationSubmissionContextInfo();
+    String appid = "application_123_0";
+    app.setApplicationId(appid);
+    String submitAppRequestBody =
+        TestRMWebServicesDelegationTokenAuthentication
+          .getMarshalledAppInfo(app);
+
+    URL url = new URL("http://localhost:8088/ws/v1/cluster/apps");
+    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+
+    // we should be access the apps page with the static user
+    TestRMWebServicesDelegationTokenAuthentication.setupConn(conn, "GET", "",
+      "");
+    try {
+      conn.getInputStream();
+      assertEquals(Status.OK.getStatusCode(), conn.getResponseCode());
+    } catch (IOException e) {
+      fail("Got " + conn.getResponseCode() + " instead of 200 accessing "
+          + url.toString());
+    }
+    conn.disconnect();
+
+    // new-application, submit app and kill should fail with
+    // forbidden
+    Map<String, Helper> urlRequestMap = new HashMap<String, Helper>();
+    String killAppRequestBody =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+            + "<appstate>\n" + "  <state>KILLED</state>\n" + "</appstate>";
+
+    urlRequestMap.put("http://localhost:8088/ws/v1/cluster/apps", new Helper(
+      "POST", submitAppRequestBody));
+    urlRequestMap.put(
+      "http://localhost:8088/ws/v1/cluster/apps/new-application", new Helper(
+        "POST", ""));
+    urlRequestMap.put(
+      "http://localhost:8088/ws/v1/cluster/apps/app_123_1/state", new Helper(
+        "PUT", killAppRequestBody));
+
+    for (Map.Entry<String, Helper> entry : urlRequestMap.entrySet()) {
+      URL reqURL = new URL(entry.getKey());
+      conn = (HttpURLConnection) reqURL.openConnection();
+      String method = entry.getValue().method;
+      String body = entry.getValue().requestBody;
+      TestRMWebServicesDelegationTokenAuthentication.setupConn(conn, method,
+        "application/xml", body);
+      try {
+        conn.getInputStream();
+        fail("Request " + entry.getKey() + "succeeded but should have failed");
+      } catch (IOException e) {
+        assertEquals(Status.FORBIDDEN.getStatusCode(), conn.getResponseCode());
+        InputStream errorStream = conn.getErrorStream();
+        String error = "";
+        BufferedReader reader =
+            new BufferedReader(new InputStreamReader(errorStream, "UTF8"));
+        for (String line; (line = reader.readLine()) != null;) {
+          error += line;
+        }
+        reader.close();
+        errorStream.close();
+        assertEquals(
+          "The default static user cannot carry out this operation.", error);
+      }
+      conn.disconnect();
+    }
+  }
+}