blob: 9d5848ea03497485d757b00fe7c1efc5e22f0ff1 [file] [log] [blame]
/*
* 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.registry.secure;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.service.ServiceOperations;
import org.apache.hadoop.registry.client.impl.zk.ZKPathDumper;
import org.apache.hadoop.registry.client.impl.zk.CuratorService;
import org.apache.hadoop.registry.client.impl.zk.RegistrySecurity;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.Login;
import org.apache.zookeeper.server.ZooKeeperSaslServer;
import org.apache.zookeeper.server.auth.SaslServerCallbackHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.security.auth.login.AppConfigurationEntry;
import javax.security.auth.login.LoginContext;
import static org.apache.hadoop.registry.client.api.RegistryConstants.*;
import static org.apache.hadoop.registry.client.impl.zk.ZookeeperConfigOptions.PROP_ZK_SASL_CLIENT_CONTEXT;
import static org.apache.hadoop.registry.client.impl.zk.ZookeeperConfigOptions.PROP_ZK_SASL_CLIENT_USERNAME;
/**
* Verify that the Mini ZK service can be started up securely
*/
public class TestSecureRegistry extends AbstractSecureRegistryTest {
private static final Logger LOG =
LoggerFactory.getLogger(TestSecureRegistry.class);
@Before
public void beforeTestSecureZKService() throws Throwable {
enableKerberosDebugging();
}
@After
public void afterTestSecureZKService() throws Throwable {
disableKerberosDebugging();
RegistrySecurity.clearZKSaslClientProperties();
}
/**
* this is a cut and paste of some of the ZK internal code that was
* failing on windows and swallowing its exceptions
*/
@Test
public void testLowlevelZKSaslLogin() throws Throwable {
RegistrySecurity.bindZKToServerJAASContext(ZOOKEEPER_SERVER_CONTEXT);
String serverSection =
System.getProperty(ZooKeeperSaslServer.LOGIN_CONTEXT_NAME_KEY,
ZooKeeperSaslServer.DEFAULT_LOGIN_CONTEXT_NAME);
assertEquals(ZOOKEEPER_SERVER_CONTEXT, serverSection);
AppConfigurationEntry entries[];
entries = javax.security.auth.login.Configuration.getConfiguration()
.getAppConfigurationEntry(
serverSection);
assertNotNull("null entries", entries);
SaslServerCallbackHandler saslServerCallbackHandler =
new SaslServerCallbackHandler(
javax.security.auth.login.Configuration.getConfiguration());
Login login = new Login(serverSection, saslServerCallbackHandler);
try {
login.startThreadIfNeeded();
} finally {
login.shutdown();
}
}
@Test
public void testCreateSecureZK() throws Throwable {
startSecureZK();
secureZK.stop();
}
@Test
public void testInsecureClientToZK() throws Throwable {
startSecureZK();
userZookeeperToCreateRoot();
RegistrySecurity.clearZKSaslClientProperties();
CuratorService curatorService =
startCuratorServiceInstance("insecure client", false);
curatorService.zkList("/");
curatorService.zkMkPath("", CreateMode.PERSISTENT, false,
RegistrySecurity.WorldReadWriteACL);
}
/**
* test that ZK can write as itself
* @throws Throwable
*/
@Test
public void testZookeeperCanWrite() throws Throwable {
System.setProperty("curator-log-events", "true");
startSecureZK();
CuratorService curator = null;
LoginContext login = login(ZOOKEEPER_LOCALHOST,
ZOOKEEPER_CLIENT_CONTEXT,
keytab_zk);
try {
logLoginDetails(ZOOKEEPER, login);
RegistrySecurity.setZKSaslClientProperties(ZOOKEEPER,
ZOOKEEPER_CLIENT_CONTEXT);
curator = startCuratorServiceInstance("ZK", true);
LOG.info(curator.toString());
addToTeardown(curator);
curator.zkMkPath("/", CreateMode.PERSISTENT, false,
RegistrySecurity.WorldReadWriteACL);
curator.zkList("/");
curator.zkMkPath("/zookeeper", CreateMode.PERSISTENT, false,
RegistrySecurity.WorldReadWriteACL);
} finally {
logout(login);
ServiceOperations.stop(curator);
}
}
@Test
public void testSystemPropertyOverwrite() {
System.setProperty(PROP_ZK_SASL_CLIENT_USERNAME, "");
System.setProperty(PROP_ZK_SASL_CLIENT_CONTEXT, "");
RegistrySecurity.setZKSaslClientProperties(ZOOKEEPER,
ZOOKEEPER_CLIENT_CONTEXT);
assertEquals(ZOOKEEPER, System.getProperty(PROP_ZK_SASL_CLIENT_USERNAME));
assertEquals(ZOOKEEPER_CLIENT_CONTEXT,
System.getProperty(PROP_ZK_SASL_CLIENT_CONTEXT));
String userName = "user1";
String context = "context1";
System.setProperty(PROP_ZK_SASL_CLIENT_USERNAME, userName);
System.setProperty(PROP_ZK_SASL_CLIENT_CONTEXT, context);
RegistrySecurity.setZKSaslClientProperties(ZOOKEEPER,
ZOOKEEPER_CLIENT_CONTEXT);
assertEquals(userName, System.getProperty(PROP_ZK_SASL_CLIENT_USERNAME));
assertEquals(context, System.getProperty(PROP_ZK_SASL_CLIENT_CONTEXT));
}
/**
* Start a curator service instance
* @param name name
* @param secure flag to indicate the cluster is secure
* @return an inited and started curator service
*/
protected CuratorService startCuratorServiceInstance(String name,
boolean secure) {
Configuration clientConf = new Configuration();
clientConf.set(KEY_REGISTRY_ZK_ROOT, "/");
clientConf.setBoolean(KEY_REGISTRY_SECURE, secure);
describe(LOG, "Starting Curator service");
CuratorService curatorService = new CuratorService(name, secureZK);
curatorService.init(clientConf);
curatorService.start();
LOG.info("Curator Binding {}",
curatorService.bindingDiagnosticDetails());
return curatorService;
}
/**
* have the ZK user create the root dir.
* This logs out the ZK user after and stops its curator instance,
* to avoid contamination
* @throws Throwable
*/
public void userZookeeperToCreateRoot() throws Throwable {
System.setProperty("curator-log-events", "true");
CuratorService curator = null;
LoginContext login = login(ZOOKEEPER_LOCALHOST,
ZOOKEEPER_CLIENT_CONTEXT,
keytab_zk);
try {
logLoginDetails(ZOOKEEPER, login);
RegistrySecurity.setZKSaslClientProperties(ZOOKEEPER,
ZOOKEEPER_CLIENT_CONTEXT);
curator = startCuratorServiceInstance("ZK", true);
LOG.info(curator.toString());
addToTeardown(curator);
curator.zkMkPath("/", CreateMode.PERSISTENT, false,
RegistrySecurity.WorldReadWriteACL);
ZKPathDumper pathDumper = curator.dumpPath(true);
LOG.info(pathDumper.toString());
} finally {
logout(login);
ServiceOperations.stop(curator);
}
}
}