HADOOP-10211. Enable RPC protocol to negotiate SASL-QOP values between clients and servers. (Contributed by Benoy Antony)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1574697 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Arpit Agarwal 2014-03-05 22:30:56 +00:00
parent 6adf7a0ecb
commit 097e8b205e
4 changed files with 43 additions and 18 deletions

View File

@ -364,6 +364,9 @@ Release 2.4.0 - UNRELEASED
HADOOP-10379. Protect authentication cookies with the HttpOnly and Secure HADOOP-10379. Protect authentication cookies with the HttpOnly and Secure
flags. (wheat9) flags. (wheat9)
HADOOP-10211. Enable RPC protocol to negotiate SASL-QOP values between
clients and servers. (Benoy Antony via Arpit Agarwal)
OPTIMIZATIONS OPTIMIZATIONS
BUG FIXES BUG FIXES

View File

@ -57,6 +57,7 @@ import org.apache.hadoop.ipc.StandbyException;
import org.apache.hadoop.security.token.SecretManager; import org.apache.hadoop.security.token.SecretManager;
import org.apache.hadoop.security.token.SecretManager.InvalidToken; import org.apache.hadoop.security.token.SecretManager.InvalidToken;
import org.apache.hadoop.security.token.TokenIdentifier; import org.apache.hadoop.security.token.TokenIdentifier;
import org.apache.hadoop.util.StringUtils;
/** /**
* A utility class for dealing with SASL on RPC server * A utility class for dealing with SASL on RPC server
@ -179,18 +180,14 @@ public class SaslRpcServer {
} }
public static void init(Configuration conf) { public static void init(Configuration conf) {
QualityOfProtection saslQOP = QualityOfProtection.AUTHENTICATION; String[] qop = conf.getStrings("hadoop.rpc.protection",
String rpcProtection = conf.get("hadoop.rpc.protection", QualityOfProtection.AUTHENTICATION.toString());
QualityOfProtection.AUTHENTICATION.name().toLowerCase());
if (QualityOfProtection.INTEGRITY.name().toLowerCase() for (int i=0; i < qop.length; i++) {
.equals(rpcProtection)) { qop[i] = QualityOfProtection.valueOf(qop[i].toUpperCase()).getSaslQop();
saslQOP = QualityOfProtection.INTEGRITY;
} else if (QualityOfProtection.PRIVACY.name().toLowerCase().equals(
rpcProtection)) {
saslQOP = QualityOfProtection.PRIVACY;
} }
SASL_PROPS.put(Sasl.QOP, saslQOP.getSaslQop()); SASL_PROPS.put(Sasl.QOP, StringUtils.join(",", qop));
SASL_PROPS.put(Sasl.SERVER_AUTH, "true"); SASL_PROPS.put(Sasl.SERVER_AUTH, "true");
Security.addProvider(new SaslPlainServer.SecurityProvider()); Security.addProvider(new SaslPlainServer.SecurityProvider());
saslFactory = new FastSaslServerFactory(SASL_PROPS); saslFactory = new FastSaslServerFactory(SASL_PROPS);

View File

@ -256,7 +256,7 @@
<property> <property>
<name>hadoop.rpc.protection</name> <name>hadoop.rpc.protection</name>
<value>authentication</value> <value>authentication</value>
<description>This field sets the quality of protection for secured sasl <description>A comma-separated list of protection values for secured sasl
connections. Possible values are authentication, integrity and privacy. connections. Possible values are authentication, integrity and privacy.
authentication means authentication only and no integrity or privacy; authentication means authentication only and no integrity or privacy;
integrity implies authentication and integrity are enabled; and privacy integrity implies authentication and integrity are enabled; and privacy

View File

@ -19,8 +19,15 @@
package org.apache.hadoop.ipc; package org.apache.hadoop.ipc;
import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION; import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_AUTHENTICATION;
import static org.apache.hadoop.security.SaslRpcServer.AuthMethod.*; import static org.apache.hadoop.security.SaslRpcServer.AuthMethod.KERBEROS;
import static org.junit.Assert.*; import static org.apache.hadoop.security.SaslRpcServer.AuthMethod.SIMPLE;
import static org.apache.hadoop.security.SaslRpcServer.AuthMethod.TOKEN;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.DataInput; import java.io.DataInput;
import java.io.DataOutput; import java.io.DataOutput;
@ -87,15 +94,21 @@ public class TestSaslRPC {
public static Collection<Object[]> data() { public static Collection<Object[]> data() {
Collection<Object[]> params = new ArrayList<Object[]>(); Collection<Object[]> params = new ArrayList<Object[]>();
for (QualityOfProtection qop : QualityOfProtection.values()) { for (QualityOfProtection qop : QualityOfProtection.values()) {
params.add(new Object[]{ qop }); params.add(new Object[]{ new QualityOfProtection[]{qop},qop });
} }
params.add(new Object[]{ new QualityOfProtection[]{
QualityOfProtection.PRIVACY,QualityOfProtection.AUTHENTICATION },
QualityOfProtection.PRIVACY });
return params; return params;
} }
QualityOfProtection[] qop;
QualityOfProtection expectedQop; QualityOfProtection expectedQop;
public TestSaslRPC(QualityOfProtection qop) { public TestSaslRPC(QualityOfProtection[] qop,
expectedQop = qop; QualityOfProtection expectedQop) {
this.qop=qop;
this.expectedQop = expectedQop;
} }
private static final String ADDRESS = "0.0.0.0"; private static final String ADDRESS = "0.0.0.0";
@ -134,19 +147,31 @@ public class TestSaslRPC {
@Before @Before
public void setup() { public void setup() {
LOG.info("---------------------------------"); LOG.info("---------------------------------");
LOG.info("Testing QOP:"+expectedQop); LOG.info("Testing QOP:"+ getQOPNames(qop));
LOG.info("---------------------------------"); LOG.info("---------------------------------");
conf = new Configuration(); conf = new Configuration();
// the specific tests for kerberos will enable kerberos. forcing it // the specific tests for kerberos will enable kerberos. forcing it
// for all tests will cause tests to fail if the user has a TGT // for all tests will cause tests to fail if the user has a TGT
conf.set(HADOOP_SECURITY_AUTHENTICATION, SIMPLE.toString()); conf.set(HADOOP_SECURITY_AUTHENTICATION, SIMPLE.toString());
conf.set("hadoop.rpc.protection", expectedQop.name().toLowerCase()); conf.set("hadoop.rpc.protection", getQOPNames(qop));
UserGroupInformation.setConfiguration(conf); UserGroupInformation.setConfiguration(conf);
enableSecretManager = null; enableSecretManager = null;
forceSecretManager = null; forceSecretManager = null;
clientFallBackToSimpleAllowed = true; clientFallBackToSimpleAllowed = true;
} }
static String getQOPNames (QualityOfProtection[] qops){
StringBuilder sb = new StringBuilder();
int i = 0;
for (QualityOfProtection qop:qops){
sb.append(qop.name().toLowerCase());
if (++i < qops.length){
sb.append(",");
}
}
return sb.toString();
}
static { static {
((Log4JLogger) Client.LOG).getLogger().setLevel(Level.ALL); ((Log4JLogger) Client.LOG).getLogger().setLevel(Level.ALL);
((Log4JLogger) Server.LOG).getLogger().setLevel(Level.ALL); ((Log4JLogger) Server.LOG).getLogger().setLevel(Level.ALL);