Repository: hbase
Updated Branches:
  refs/heads/0.96 bd5922729 -> 6ea0b7f8c
  refs/heads/0.98 230a768a3 -> 7caceb23c
  refs/heads/master 9dcebc396 -> b168b8b2d


HBASE-11149 Wire encryption is broken (Devaraj Das)


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

Branch: refs/heads/0.96
Commit: 6ea0b7f8c2af72c6fd379f04e2d7145928e237ad
Parents: bd59227
Author: Andrew Purtell <[email protected]>
Authored: Thu May 22 18:21:30 2014 -0700
Committer: Andrew Purtell <[email protected]>
Committed: Thu May 22 18:43:48 2014 -0700

----------------------------------------------------------------------
 .../org/apache/hadoop/hbase/ipc/RpcClient.java  |  5 +-
 .../hbase/security/HBaseSaslRpcClient.java      | 27 +++++++-
 .../apache/hadoop/hbase/security/SaslUtil.java  | 32 +++++++++
 .../hbase/security/HBaseSaslRpcServer.java      | 33 +--------
 .../hbase/security/TestHBaseSaslRpcClient.java  | 72 ++++++++++++++++++++
 5 files changed, 137 insertions(+), 32 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/hbase/blob/6ea0b7f8/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClient.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClient.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClient.java
index 90fe601..1615732 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClient.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/ipc/RpcClient.java
@@ -72,6 +72,7 @@ import 
org.apache.hadoop.hbase.protobuf.generated.RPCProtos.UserInformation;
 import org.apache.hadoop.hbase.protobuf.generated.TracingProtos.RPCTInfo;
 import org.apache.hadoop.hbase.security.AuthMethod;
 import org.apache.hadoop.hbase.security.HBaseSaslRpcClient;
+import org.apache.hadoop.hbase.security.SaslUtil.QualityOfProtection;
 import org.apache.hadoop.hbase.security.SecurityInfo;
 import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.security.UserProvider;
@@ -759,7 +760,9 @@ private UserProvider userProvider;
 
     private synchronized boolean setupSaslConnection(final InputStream in2,
         final OutputStream out2) throws IOException {
-      saslRpcClient = new HBaseSaslRpcClient(authMethod, token, 
serverPrincipal, fallbackAllowed);
+      saslRpcClient = new HBaseSaslRpcClient(authMethod, token, 
serverPrincipal, fallbackAllowed,
+          conf.get("hbase.rpc.protection", 
+              QualityOfProtection.AUTHENTICATION.name().toLowerCase()));
       return saslRpcClient.saslConnect(in2, out2);
     }
 

http://git-wip-us.apache.org/repos/asf/hbase/blob/6ea0b7f8/hbase-client/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcClient.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcClient.java
 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcClient.java
index 41acb4f..a591747 100644
--- 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcClient.java
+++ 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcClient.java
@@ -54,7 +54,6 @@ public class HBaseSaslRpcClient {
 
   private final SaslClient saslClient;
   private final boolean fallbackAllowed;
-
   /**
    * Create a HBaseSaslRpcClient for an authentication method
    * 
@@ -62,11 +61,37 @@ public class HBaseSaslRpcClient {
    *          the requested authentication method
    * @param token
    *          token to use if needed by the authentication method
+   * @param serverPrincipal
+   *          the server principal that we are trying to set the connection up 
to
+   * @param fallbackAllowed
+   *          does the client allow fallback to simple authentication
+   * @throws IOException
    */
   public HBaseSaslRpcClient(AuthMethod method,
       Token<? extends TokenIdentifier> token, String serverPrincipal, boolean 
fallbackAllowed)
       throws IOException {
+    this(method, token, serverPrincipal, fallbackAllowed, "authentication"); 
+  }
+  /**
+   * Create a HBaseSaslRpcClient for an authentication method
+   * 
+   * @param method
+   *          the requested authentication method
+   * @param token
+   *          token to use if needed by the authentication method
+   * @param serverPrincipal
+   *          the server principal that we are trying to set the connection up 
to
+   * @param fallbackAllowed
+   *          does the client allow fallback to simple authentication
+   * @param rpcProtection
+   *          the protection level ("authentication", "integrity" or "privacy")
+   * @throws IOException
+   */
+  public HBaseSaslRpcClient(AuthMethod method,
+      Token<? extends TokenIdentifier> token, String serverPrincipal, boolean 
fallbackAllowed,
+      String rpcProtection) throws IOException {
     this.fallbackAllowed = fallbackAllowed;
+    SaslUtil.initSaslProperties(rpcProtection);
     switch (method) {
     case DIGEST:
       if (LOG.isDebugEnabled())

http://git-wip-us.apache.org/repos/asf/hbase/blob/6ea0b7f8/hbase-client/src/main/java/org/apache/hadoop/hbase/security/SaslUtil.java
----------------------------------------------------------------------
diff --git 
a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/SaslUtil.java 
b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/SaslUtil.java
index 42e21be..351052b 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/security/SaslUtil.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/security/SaslUtil.java
@@ -23,12 +23,30 @@ import org.apache.commons.codec.binary.Base64;
 import java.util.Map;
 import java.util.TreeMap;
 
+import javax.security.sasl.Sasl;
+
 public class SaslUtil {
   public static final String SASL_DEFAULT_REALM = "default";
   public static final Map<String, String> SASL_PROPS =
       new TreeMap<String, String>();
   public static final int SWITCH_TO_SIMPLE_AUTH = -88;
 
+  public static enum QualityOfProtection {
+    AUTHENTICATION("auth"),
+    INTEGRITY("auth-int"),
+    PRIVACY("auth-conf");
+
+    public final String saslQop;
+
+    private QualityOfProtection(String saslQop) {
+      this.saslQop = saslQop;
+    }
+
+    public String getSaslQop() {
+      return saslQop;
+    }
+  }
+
   /** Splitting fully qualified Kerberos name into parts */
   public static String[] splitKerberosName(String fullName) {
     return fullName.split("[/@]");
@@ -45,4 +63,18 @@ public class SaslUtil {
   static char[] encodePassword(byte[] password) {
     return new String(Base64.encodeBase64(password)).toCharArray();
   }
+
+  static void initSaslProperties(String rpcProtection) {
+    QualityOfProtection saslQOP = QualityOfProtection.AUTHENTICATION;
+    if (QualityOfProtection.INTEGRITY.name().toLowerCase()
+        .equals(rpcProtection)) {
+      saslQOP = QualityOfProtection.INTEGRITY;
+    } else if (QualityOfProtection.PRIVACY.name().toLowerCase().equals(
+        rpcProtection)) {
+      saslQOP = QualityOfProtection.PRIVACY;
+    }
+
+    SaslUtil.SASL_PROPS.put(Sasl.QOP, saslQOP.getSaslQop());
+    SaslUtil.SASL_PROPS.put(Sasl.SERVER_AUTH, "true");
+  }
 }

http://git-wip-us.apache.org/repos/asf/hbase/blob/6ea0b7f8/hbase-server/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcServer.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcServer.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcServer.java
index 514fee3..2dd94d6 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcServer.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/security/HBaseSaslRpcServer.java
@@ -29,12 +29,12 @@ import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.sasl.AuthorizeCallback;
 import javax.security.sasl.RealmCallback;
-import javax.security.sasl.Sasl;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.hbase.ipc.RpcServer;
+import org.apache.hadoop.hbase.security.SaslUtil.QualityOfProtection;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.security.token.SecretManager;
 import org.apache.hadoop.security.token.TokenIdentifier;
@@ -46,36 +46,9 @@ import 
org.apache.hadoop.security.token.SecretManager.InvalidToken;
 public class HBaseSaslRpcServer {
   public static final Log LOG = LogFactory.getLog(HBaseSaslRpcServer.class);
 
-  public static enum QualityOfProtection {
-    AUTHENTICATION("auth"),
-    INTEGRITY("auth-int"),
-    PRIVACY("auth-conf");
-
-    public final String saslQop;
-
-    private QualityOfProtection(String saslQop) {
-      this.saslQop = saslQop;
-    }
-
-    public String getSaslQop() {
-      return saslQop;
-    }
-  }
-
   public static void init(Configuration conf) {
-    QualityOfProtection saslQOP = QualityOfProtection.AUTHENTICATION;
-    String rpcProtection = conf.get("hbase.rpc.protection",
-        QualityOfProtection.AUTHENTICATION.name().toLowerCase());
-    if (QualityOfProtection.INTEGRITY.name().toLowerCase()
-        .equals(rpcProtection)) {
-      saslQOP = QualityOfProtection.INTEGRITY;
-    } else if (QualityOfProtection.PRIVACY.name().toLowerCase().equals(
-        rpcProtection)) {
-      saslQOP = QualityOfProtection.PRIVACY;
-    }
-
-    SaslUtil.SASL_PROPS.put(Sasl.QOP, saslQOP.getSaslQop());
-    SaslUtil.SASL_PROPS.put(Sasl.SERVER_AUTH, "true");
+    SaslUtil.initSaslProperties(conf.get("hbase.rpc.protection", 
+          QualityOfProtection.AUTHENTICATION.name().toLowerCase()));
   }
 
   public static <T extends TokenIdentifier> T getIdentifier(String id,

http://git-wip-us.apache.org/repos/asf/hbase/blob/6ea0b7f8/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestHBaseSaslRpcClient.java
----------------------------------------------------------------------
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestHBaseSaslRpcClient.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestHBaseSaslRpcClient.java
new file mode 100644
index 0000000..ab43b63
--- /dev/null
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/security/TestHBaseSaslRpcClient.java
@@ -0,0 +1,72 @@
+/*
+ *
+ * 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.hbase.security;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import javax.security.sasl.Sasl;
+
+import org.apache.hadoop.hbase.SmallTests;
+import org.apache.hadoop.security.token.Token;
+import org.apache.hadoop.security.token.TokenIdentifier;
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+@Category(SmallTests.class)
+public class TestHBaseSaslRpcClient {
+  
+  static {
+    System.setProperty("java.security.krb5.realm", "DOMAIN.COM");
+    System.setProperty("java.security.krb5.kdc", "DOMAIN.COM");
+  }
+  
+  static final String DEFAULT_USER_NAME = "principal";
+  static final String DEFAULT_USER_PASSWORD = "password";
+
+  @BeforeClass
+  public static void before() {
+    Logger.getRootLogger().setLevel(Level.DEBUG);
+  }
+
+  @Test
+  public void testSaslQOPNotEmpty() throws Exception {
+    // default QOP is authentication
+    new HBaseSaslRpcClient(AuthMethod.KERBEROS, createTokenMock(), 
"principal/[email protected]", false);
+    
assertTrue(SaslUtil.SASL_PROPS.get(Sasl.QOP).equals(SaslUtil.QualityOfProtection.AUTHENTICATION.getSaslQop()));
+
+    // check with specific QOPs
+    new HBaseSaslRpcClient(AuthMethod.KERBEROS, createTokenMock(), 
"principal/[email protected]", false, "authentication");
+    
assertTrue(SaslUtil.SASL_PROPS.get(Sasl.QOP).equals(SaslUtil.QualityOfProtection.AUTHENTICATION.getSaslQop()));
+
+    new HBaseSaslRpcClient(AuthMethod.KERBEROS, createTokenMock(), 
"principal/[email protected]", false, "privacy");
+    
assertTrue(SaslUtil.SASL_PROPS.get(Sasl.QOP).equals(SaslUtil.QualityOfProtection.PRIVACY.getSaslQop()));
+
+    new HBaseSaslRpcClient(AuthMethod.KERBEROS, createTokenMock(), 
"principal/[email protected]", false, "integrity");
+    
assertTrue(SaslUtil.SASL_PROPS.get(Sasl.QOP).equals(SaslUtil.QualityOfProtection.INTEGRITY.getSaslQop()));
+  }
+
+  @SuppressWarnings("unchecked")
+  private Token<? extends TokenIdentifier> createTokenMock() {
+    return mock(Token.class);
+  }
+}

Reply via email to