Repository: hive
Updated Branches:
  refs/heads/master 230ed7876 -> b569b49e0


HIVE-15661 : Add security error logging to LLAP (Sergey Shelukhin, reviewed by 
Jason Dere)


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

Branch: refs/heads/master
Commit: b569b49e0596c52234fadc620c014844d0539f0e
Parents: 230ed78
Author: Sergey Shelukhin <ser...@apache.org>
Authored: Thu Jan 19 15:10:21 2017 -0800
Committer: Sergey Shelukhin <ser...@apache.org>
Committed: Thu Jan 19 15:14:20 2017 -0800

----------------------------------------------------------------------
 .../hive/llap/security/LlapTokenIdentifier.java |  3 +-
 .../llap/daemon/impl/ContainerRunnerImpl.java   | 45 ++++++++++++++++++--
 .../hive/llap/daemon/impl/LlapTokenChecker.java |  4 +-
 3 files changed, 45 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hive/blob/b569b49e/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java
----------------------------------------------------------------------
diff --git 
a/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java
 
b/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java
index 08c141f..0786b7a 100644
--- 
a/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java
+++ 
b/llap-common/src/java/org/apache/hadoop/hive/llap/security/LlapTokenIdentifier.java
@@ -105,7 +105,8 @@ public class LlapTokenIdentifier extends 
AbstractDelegationTokenIdentifier {
 
   @Override
   public String toString() {
-    return KIND + "; " + super.toString() + ", cluster " + clusterId + ", app 
ID " + appId;
+    return KIND + "; " + super.toString() + ", cluster " + clusterId
+        + ", app ID " + appId + ", signing " + isSigningRequired;
   }
 
   @InterfaceAudience.Private

http://git-wip-us.apache.org/repos/asf/hive/blob/b569b49e/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java
----------------------------------------------------------------------
diff --git 
a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java
 
b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java
index 1346050..6d7d4de 100644
--- 
a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java
+++ 
b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/ContainerRunnerImpl.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.hadoop.conf.Configuration;
@@ -54,6 +55,7 @@ import 
org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.Terminate
 import 
org.apache.hadoop.hive.llap.daemon.rpc.LlapDaemonProtocolProtos.VertexOrBinary;
 import org.apache.hadoop.hive.llap.metrics.LlapDaemonExecutorMetrics;
 import org.apache.hadoop.hive.llap.security.LlapSignerImpl;
+import org.apache.hadoop.hive.llap.security.LlapTokenIdentifier;
 import org.apache.hadoop.hive.llap.tez.Converters;
 import org.apache.hadoop.hive.llap.tezplugins.LlapTezUtils;
 import org.apache.hadoop.io.DataInputBuffer;
@@ -171,7 +173,13 @@ public class ContainerRunnerImpl extends CompositeService 
implements ContainerRu
 
   @Override
   public SubmitWorkResponseProto submitWork(SubmitWorkRequestProto request) 
throws IOException {
-    LlapTokenInfo tokenInfo = LlapTokenChecker.getTokenInfo(clusterId);
+    LlapTokenInfo tokenInfo = null;
+    try {
+      tokenInfo = LlapTokenChecker.getTokenInfo(clusterId);
+    } catch (SecurityException ex) {
+      logSecurityErrorRarely(null);
+      throw ex;
+    }
     SignableVertexSpec vertex = extractVertexSpec(request, tokenInfo);
     TezEvent initialEvent = extractInitialEvent(request, tokenInfo);
 
@@ -296,10 +304,16 @@ public class ContainerRunnerImpl extends CompositeService 
implements ContainerRu
     NotTezEvent initialEvent = NotTezEvent.parseFrom(initialEventBytes);
     if (tokenInfo.isSigningRequired) {
       if (!request.hasInitialEventSignature()) {
+        logSecurityErrorRarely(tokenInfo.userName);
         throw new SecurityException("Unsigned initial event is not allowed");
       }
       byte[] signatureBytes = request.getInitialEventSignature().toByteArray();
-      signer.checkSignature(initialEventBytes, signatureBytes, 
initialEvent.getKeyId());
+      try {
+        signer.checkSignature(initialEventBytes, signatureBytes, 
initialEvent.getKeyId());
+      } catch (SecurityException ex) {
+        logSecurityErrorRarely(tokenInfo.userName);
+        throw ex;
+      }
     }
     return NotTezEventHelper.toTezEvent(initialEvent);
   }
@@ -307,6 +321,7 @@ public class ContainerRunnerImpl extends CompositeService 
implements ContainerRu
   private void checkSignature(SignableVertexSpec vertex, ByteString 
vertexBinary,
       SubmitWorkRequestProto request, String tokenUserName) throws 
SecurityException, IOException {
     if (!request.hasWorkSpecSignature()) {
+      logSecurityErrorRarely(tokenUserName);
       throw new SecurityException("Unsigned fragment not allowed");
     }
     if (vertexBinary == null) {
@@ -314,14 +329,36 @@ public class ContainerRunnerImpl extends CompositeService 
implements ContainerRu
       vertex.writeTo(os);
       vertexBinary = os.toByteString();
     }
-    signer.checkSignature(vertexBinary.toByteArray(),
-        request.getWorkSpecSignature().toByteArray(), 
(int)vertex.getSignatureKeyId());
+    try {
+      signer.checkSignature(vertexBinary.toByteArray(),
+          request.getWorkSpecSignature().toByteArray(), 
(int)vertex.getSignatureKeyId());
+    } catch (SecurityException ex) {
+      logSecurityErrorRarely(tokenUserName);
+      throw ex;
+    }
     if (!vertex.hasUser() || !vertex.getUser().equals(tokenUserName)) {
+      logSecurityErrorRarely(tokenUserName);
       throw new SecurityException("LLAP token is for " + tokenUserName
           + " but the fragment is for " + (vertex.hasUser() ? vertex.getUser() 
: null));
     }
   }
 
+  private final AtomicLong lastLoggedError = new AtomicLong(0);
+  private void logSecurityErrorRarely(String userName) {
+    if (!LOG.isWarnEnabled()) return;
+    long time = System.nanoTime();
+    long oldTime = lastLoggedError.get();
+    if (oldTime != 0 && (time - oldTime) < 1000000000L) return; // 1 second
+    if (!lastLoggedError.compareAndSet(oldTime, time)) return;
+    String tokens = null;
+    try {
+      tokens = "" + 
LlapTokenChecker.getLlapTokens(UserGroupInformation.getCurrentUser(), null);
+    } catch (Exception e) {
+      tokens = "error: " + e.getMessage();
+    }
+    LOG.warn("Security error from " + userName + "; cluster " + clusterId + "; 
tokens " + tokens);
+  }
+
   @Override
   public SourceStateUpdatedResponseProto sourceStateUpdated(
       SourceStateUpdatedRequestProto request) throws IOException {

http://git-wip-us.apache.org/repos/asf/hive/blob/b569b49e/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java
----------------------------------------------------------------------
diff --git 
a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java
 
b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java
index c606c9b..170ba33 100644
--- 
a/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java
+++ 
b/llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/LlapTokenChecker.java
@@ -72,7 +72,7 @@ public final class LlapTokenChecker {
     }
   }
 
-  private static List<LlapTokenIdentifier> getLlapTokens(
+  static List<LlapTokenIdentifier> getLlapTokens(
       UserGroupInformation ugi, String clusterId) {
     List<LlapTokenIdentifier> tokens = null;
     for (TokenIdentifier id : ugi.getTokenIdentifiers()) {
@@ -81,7 +81,7 @@ public final class LlapTokenChecker {
         LOG.debug("Token {}", id);
       }
       LlapTokenIdentifier llapId = (LlapTokenIdentifier)id;
-      if (!clusterId.equals(llapId.getClusterId())) continue;
+      if (clusterId != null && !clusterId.equals(llapId.getClusterId())) 
continue;
       if (tokens == null) {
         tokens = new ArrayList<>();
       }

Reply via email to