You are viewing a plain text version of this content. The canonical link for it is here.
Posted to yarn-commits@hadoop.apache.org by ss...@apache.org on 2013/05/31 06:13:18 UTC

svn commit: r1488085 [3/3] - in /hadoop/common/trunk/hadoop-yarn-project: ./ hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/ hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/api/protocolrecords/impl...

Modified: hadoop/common/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestContainerManagerSecurity.java
URL: http://svn.apache.org/viewvc/hadoop/common/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestContainerManagerSecurity.java?rev=1488085&r1=1488084&r2=1488085&view=diff
==============================================================================
--- hadoop/common/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestContainerManagerSecurity.java (original)
+++ hadoop/common/trunk/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-tests/src/test/java/org/apache/hadoop/yarn/server/TestContainerManagerSecurity.java Fri May 31 04:13:16 2013
@@ -38,9 +38,7 @@ import org.apache.commons.logging.LogFac
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
 import org.apache.hadoop.fs.UnsupportedFileSystemException;
-import org.apache.hadoop.io.DataInputBuffer;
 import org.apache.hadoop.io.Text;
-import org.apache.hadoop.ipc.RPC;
 import org.apache.hadoop.net.NetUtils;
 import org.apache.hadoop.security.SecurityUtil;
 import org.apache.hadoop.security.UserGroupInformation;
@@ -49,7 +47,6 @@ import org.apache.hadoop.util.Shell;
 import org.apache.hadoop.yarn.api.AMRMProtocol;
 import org.apache.hadoop.yarn.api.ContainerManager;
 import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
-import org.apache.hadoop.yarn.api.protocolrecords.GetContainerStatusRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.GetNewApplicationRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.KillApplicationRequest;
 import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest;
@@ -121,8 +118,8 @@ public class TestContainerManagerSecurit
       // Testing for malicious user
       testMaliceUser();
       
-      // Testing for unauthorized user
-      testUnauthorizedUser();
+      // Testing for usage of expired tokens
+      testExpiredTokens();
       
     } finally {
       if (yarnCluster != null) {
@@ -184,6 +181,15 @@ public class TestContainerManagerSecurit
     resourceManager.getClientRMService().forceKillApplication(request);
   }
 
+  /**
+   * This tests a malice user getting a proper token but then messing with it by
+   * tampering with containerID/Resource etc.. His/her containers should be
+   * rejected.
+   * 
+   * @throws IOException
+   * @throws InterruptedException
+   * @throws YarnRemoteException
+   */
   private void testMaliceUser() throws IOException, InterruptedException,
       YarnRemoteException {
 
@@ -205,30 +211,60 @@ public class TestContainerManagerSecurit
         appID);
 
     // Now talk to the NM for launching the container with modified resource
-    final ContainerId containerID = allocatedContainer.getId();
-    UserGroupInformation maliceUser = UserGroupInformation
-        .createRemoteUser(containerID.toString());
 
     ContainerToken containerToken = allocatedContainer.getContainerToken();
-    byte[] identifierBytes = containerToken.getIdentifier().array();
-
-    DataInputBuffer di = new DataInputBuffer();
-    di.reset(identifierBytes, identifierBytes.length);
-
-    ContainerTokenIdentifier dummyIdentifier = new ContainerTokenIdentifier();
-    dummyIdentifier.readFields(di);
+    ContainerTokenIdentifier originalContainerTokenId =
+        BuilderUtils.newContainerTokenIdentifier(containerToken);
 
     // Malice user modifies the resource amount
     Resource modifiedResource = BuilderUtils.newResource(2048, 1);
     ContainerTokenIdentifier modifiedIdentifier =
-        new ContainerTokenIdentifier(dummyIdentifier.getContainerID(),
-          dummyIdentifier.getNmHostAddress(), "testUser", modifiedResource,
-          Long.MAX_VALUE, dummyIdentifier.getMasterKeyId(),
+        new ContainerTokenIdentifier(originalContainerTokenId.getContainerID(),
+          originalContainerTokenId.getNmHostAddress(), "testUser",
+          modifiedResource, Long.MAX_VALUE,
+          originalContainerTokenId.getMasterKeyId(),
           ResourceManager.clusterTimeStamp);
-    Token<ContainerTokenIdentifier> modifiedToken = new Token<ContainerTokenIdentifier>(
-        modifiedIdentifier.getBytes(), containerToken.getPassword().array(),
-        new Text(containerToken.getKind()), new Text(containerToken
-            .getService()));
+    Token<ContainerTokenIdentifier> modifiedToken =
+        new Token<ContainerTokenIdentifier>(modifiedIdentifier.getBytes(),
+          containerToken.getPassword().array(), new Text(
+            containerToken.getKind()), new Text(containerToken.getService()));
+    makeTamperedStartContainerCall(yarnRPC, allocatedContainer,
+      modifiedIdentifier, modifiedToken);
+
+    // Malice user modifies the container-Id
+    ContainerId newContainerId =
+        BuilderUtils.newContainerId(
+          BuilderUtils.newApplicationAttemptId(originalContainerTokenId
+            .getContainerID().getApplicationAttemptId().getApplicationId(), 1),
+          originalContainerTokenId.getContainerID().getId() + 42);
+    modifiedIdentifier =
+        new ContainerTokenIdentifier(newContainerId,
+          originalContainerTokenId.getNmHostAddress(), "testUser",
+          originalContainerTokenId.getResource(), Long.MAX_VALUE,
+          originalContainerTokenId.getMasterKeyId(),
+          ResourceManager.clusterTimeStamp);
+    modifiedToken =
+        new Token<ContainerTokenIdentifier>(modifiedIdentifier.getBytes(),
+          containerToken.getPassword().array(), new Text(
+            containerToken.getKind()), new Text(containerToken.getService()));
+    makeTamperedStartContainerCall(yarnRPC, allocatedContainer,
+      modifiedIdentifier, modifiedToken);
+
+    // Similarly messing with anything else will fail.
+
+    KillApplicationRequest request = Records
+        .newRecord(KillApplicationRequest.class);
+    request.setApplicationId(appID);
+    resourceManager.getClientRMService().forceKillApplication(request);
+  }
+
+  private void makeTamperedStartContainerCall(final YarnRPC yarnRPC,
+      final Container allocatedContainer,
+      final ContainerTokenIdentifier modifiedIdentifier,
+      Token<ContainerTokenIdentifier> modifiedToken) {
+    final ContainerId containerID = allocatedContainer.getId();
+    UserGroupInformation maliceUser = UserGroupInformation
+        .createRemoteUser(containerID.toString());
     maliceUser.addToken(modifiedToken);
     maliceUser.doAs(new PrivilegedAction<Void>() {
       @Override
@@ -239,11 +275,14 @@ public class TestContainerManagerSecurit
             conf);
 
         LOG.info("Going to contact NM:  ilLegal request");
-        GetContainerStatusRequest request = recordFactory
-            .newRecordInstance(GetContainerStatusRequest.class);
-        request.setContainerId(containerID);
+        StartContainerRequest request =
+            Records.newRecord(StartContainerRequest.class);
         try {
-          client.getContainerStatus(request);
+          request.setContainerToken(allocatedContainer.getContainerToken());
+          ContainerLaunchContext context =
+              createContainerLaunchContextForTest(modifiedIdentifier);
+          request.setContainerLaunchContext(context);
+          client.startContainer(request);
           fail("Connection initiation with illegally modified "
               + "tokens is expected to fail.");
         } catch (YarnRemoteException e) {
@@ -263,14 +302,9 @@ public class TestContainerManagerSecurit
         return null;
       }
     });
-
-    KillApplicationRequest request = Records
-        .newRecord(KillApplicationRequest.class);
-    request.setApplicationId(appID);
-    resourceManager.getClientRMService().forceKillApplication(request);
   }
 
-  private void testUnauthorizedUser() throws IOException, InterruptedException,
+  private void testExpiredTokens() throws IOException, InterruptedException,
       YarnRemoteException {
 
     LOG.info("\n\nRunning test for malice user");
@@ -293,48 +327,12 @@ public class TestContainerManagerSecurit
     // Now talk to the NM for launching the container with modified containerID
     final ContainerId containerID = allocatedContainer.getId();
 
-    /////////// Test calls with illegal containerIDs and illegal Resources
-    UserGroupInformation unauthorizedUser = UserGroupInformation
-        .createRemoteUser(containerID.toString());
     ContainerToken containerToken = allocatedContainer.getContainerToken();
-
-    byte[] identifierBytes = containerToken.getIdentifier().array();
-    DataInputBuffer di = new DataInputBuffer();
-    di.reset(identifierBytes, identifierBytes.length);
-    final ContainerTokenIdentifier tokenId = new ContainerTokenIdentifier();
-    tokenId.readFields(di);
-
-    Token<ContainerTokenIdentifier> token = new Token<ContainerTokenIdentifier>(
-        identifierBytes, containerToken.getPassword().array(), new Text(
-            containerToken.getKind()), new Text(containerToken.getService()));
-
-    unauthorizedUser.addToken(token);
-    ContainerManager client =
-        unauthorizedUser.doAs(new PrivilegedAction<ContainerManager>() {
-      @Override
-      public ContainerManager run() {
-        ContainerManager client = (ContainerManager) yarnRPC.getProxy(
-            ContainerManager.class, NetUtils
-                .createSocketAddr(allocatedContainer.getNodeId().toString()),
-            conf);
-
-        LOG.info("Going to contact NM:  unauthorized request");
-
-        callWithIllegalContainerID(client, tokenId, allocatedContainer);
-        callWithIllegalResource(client, tokenId, allocatedContainer);
-        // UserName is no longer sent using containerLaunchContext.
-//        callWithIllegalUserName(client, tokenId, allocatedContainer);
-
-        return client;
-      }
-    });
-    
-    // ///////// End of testing for illegal containerIDs, illegal Resources and
-    // illegal users
+    final ContainerTokenIdentifier tokenId =
+        BuilderUtils.newContainerTokenIdentifier(containerToken);
 
     /////////// Test calls with expired tokens
-    RPC.stopProxy(client);
-    unauthorizedUser = UserGroupInformation
+    UserGroupInformation unauthorizedUser = UserGroupInformation
         .createRemoteUser(containerID.toString());
 
     RMContainerTokenSecretManager containerTokenSecreteManager = 
@@ -349,9 +347,10 @@ public class TestContainerManagerSecurit
         containerTokenSecreteManager.createPassword(
             newTokenId);
     // Create a valid token by using the key from the RM.
-    token = new Token<ContainerTokenIdentifier>(
-        newTokenId.getBytes(), passowrd, new Text(
-            containerToken.getKind()), new Text(containerToken.getService()));
+    Token<ContainerTokenIdentifier> token =
+        new Token<ContainerTokenIdentifier>(newTokenId.getBytes(), passowrd,
+          new Text(containerToken.getKind()), new Text(
+            containerToken.getService()));
 
     unauthorizedUser.addToken(token);
     unauthorizedUser.doAs(new PrivilegedAction<Void>() {
@@ -369,7 +368,7 @@ public class TestContainerManagerSecurit
         request.setContainerLaunchContext(context);
         allocatedContainer.setContainerToken(BuilderUtils.newContainerToken(
             allocatedContainer.getNodeId(), passowrd, newTokenId));
-        request.setContainer(allocatedContainer);
+        request.setContainerToken(allocatedContainer.getContainerToken());
 
         //Calling startContainer with an expired token.
         try {
@@ -524,93 +523,6 @@ public class TestContainerManagerSecurit
     return allocatedContainers.get(0);
   }
 
-  void callWithIllegalContainerID(ContainerManager client,
-      ContainerTokenIdentifier tokenId, Container container) {
-    StartContainerRequest request = recordFactory
-        .newRecordInstance(StartContainerRequest.class);
-    ContainerLaunchContext context =
-        createContainerLaunchContextForTest(tokenId);
-    ContainerId newContainerId = BuilderUtils.newContainerId(BuilderUtils
-        .newApplicationAttemptId(tokenId.getContainerID()
-            .getApplicationAttemptId().getApplicationId(), 1), 42);
-    ContainerId oldContainerId = container.getId();
-    try {
-      container.setId(newContainerId);
-      request.setContainer(container);
-      request.setContainerLaunchContext(context);
-      client.startContainer(request);
-      fail("Connection initiation with unauthorized "
-          + "access is expected to fail.");
-    } catch (YarnRemoteException e) {
-      LOG.info("Got exception : ", e);
-      Assert.assertTrue(e.getMessage().contains(
-          "Unauthorized request to start container. "
-              + "\nExpected containerId: " + tokenId.getContainerID()
-              + " Found: " + newContainerId.toString()));
-    } catch (IOException e) {
-      LOG.info("Got IOException: ",e);
-      fail("IOException is not expected.");
-    } finally {
-      container.setId(oldContainerId);
-    }
-  }
-
-  void callWithIllegalResource(ContainerManager client,
-      ContainerTokenIdentifier tokenId, Container container) {
-    StartContainerRequest request = recordFactory
-        .newRecordInstance(StartContainerRequest.class);
-    // Authenticated but unauthorized, due to wrong resource
-    ContainerLaunchContext context =
-        createContainerLaunchContextForTest(tokenId);
-    Resource rsrc = container.getResource();
-    container.setResource(BuilderUtils.newResource(2048, 1));
-    request.setContainerLaunchContext(context);
-    request.setContainer(container);
-    try {
-      client.startContainer(request);
-      fail("Connection initiation with unauthorized "
-          + "access is expected to fail.");
-    } catch (YarnRemoteException e) {
-      LOG.info("Got exception : ", e);
-      Assert.assertTrue(e.getMessage().contains(
-          "Unauthorized request to start container. "));
-      Assert.assertTrue(e.getMessage().contains(
-          "\nExpected resource " + tokenId.getResource().toString()
-              + " but found " + container.getResource().toString()));
-    } catch (IOException e) {
-      LOG.info("Got IOException: ",e);
-      fail("IOException is not expected.");
-    }
-    container.setResource(rsrc);
-  }
-
-  void callWithIllegalUserName(ContainerManager client,
-      ContainerTokenIdentifier tokenId, Container container) {
-    StartContainerRequest request = recordFactory
-        .newRecordInstance(StartContainerRequest.class);
-    // Authenticated but unauthorized, due to wrong resource
-    ContainerLaunchContext context =
-        createContainerLaunchContextForTest(tokenId);
-    String user = "invalidUser";
-    request.setContainerLaunchContext(context);
-    request.setContainer(container);
-    try {
-      client.startContainer(request);
-      fail("Connection initiation with unauthorized "
-          + "access is expected to fail.");
-    } catch (YarnRemoteException e) {
-      LOG.info("Got exception : ", e);
-      Assert.assertTrue(e.getMessage().contains(
-          "Unauthorized request to start container. "));
-      Assert.assertTrue(e.getMessage().contains(
-        "Expected user-name " + tokenId.getApplicationSubmitter()
-            + " but found " + user));
-    } catch (IOException e) {
-      LOG.info("Got IOException: ",e);
-      fail("IOException is not expected.");
-    }
-  }
-
   private ContainerLaunchContext createContainerLaunchContextForTest(
       ContainerTokenIdentifier tokenId) {
     ContainerLaunchContext context =