[ https://issues.apache.org/jira/browse/ZOOKEEPER-2775?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16011195#comment-16011195 ]
ASF GitHub Bot commented on ZOOKEEPER-2775: ------------------------------------------- Github user afine commented on a diff in the pull request: https://github.com/apache/zookeeper/pull/254#discussion_r116581847 --- Diff: src/java/test/org/apache/zookeeper/SaslAuthTest.java --- @@ -0,0 +1,187 @@ +/** + * 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.zookeeper; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; +import static org.junit.Assert.assertTrue; + +import org.apache.zookeeper.ClientCnxn.SendThread; +import org.apache.zookeeper.Watcher.Event.KeeperState; +import org.apache.zookeeper.ZooDefs.Ids; +import org.apache.zookeeper.data.ACL; +import org.apache.zookeeper.data.Id; +import org.apache.zookeeper.test.ClientBase; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class SaslAuthTest extends ClientBase { + + @BeforeClass + public static void init() { + System.setProperty("zookeeper.authProvider.1", "org.apache.zookeeper.server.auth.SASLAuthenticationProvider"); + try { + File tmpDir = createTmpDir(); + File saslConfFile = new File(tmpDir, "jaas.conf"); + FileWriter fwriter = new FileWriter(saslConfFile); + + fwriter.write("" + "Server {\n" + " org.apache.zookeeper.server.auth.DigestLoginModule required\n" + + " user_super=\"test\";\n" + "};\n" + "Client {\n" + + " org.apache.zookeeper.server.auth.DigestLoginModule required\n" + + " username=\"super\"\n" + " password=\"test\";\n" + "};" + "\n"); + fwriter.close(); + System.setProperty("java.security.auth.login.config", saslConfFile.getAbsolutePath()); + } catch (IOException e) { + // could not create tmp directory to hold JAAS conf file : test will + // fail now. + } + } + + @AfterClass + public static void clean() { + System.clearProperty("zookeeper.authProvider.1"); + System.clearProperty("java.security.auth.login.config"); + } + + private AtomicInteger authFailed = new AtomicInteger(0); + + @Override + protected TestableZooKeeper createClient(String hp) throws IOException, InterruptedException { + MyWatcher watcher = new MyWatcher(); + return createClient(watcher, hp); + } + + private class MyWatcher extends CountdownWatcher { + @Override + public synchronized void process(WatchedEvent event) { + if (event.getState() == KeeperState.AuthFailed) { + authFailed.incrementAndGet(); + } else { + super.process(event); + } + } + } + + @Test + public void testAuth() throws Exception { + ZooKeeper zk = createClient(); + try { + zk.create("/path1", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT); + Thread.sleep(1000); + } finally { + zk.close(); + } + } + + @Test + public void testValidSaslIds() throws Exception { + ZooKeeper zk = createClient(); + + List<String> validIds = new ArrayList<String>(); + validIds.add("user"); + validIds.add("service/host.name.com"); + validIds.add("user@KERB.REALM"); + validIds.add("service/host.name.com@KERB.REALM"); + + int i = 0; + for (String validId : validIds) { + List<ACL> aclList = new ArrayList<ACL>(); + ACL acl = new ACL(0, new Id("sasl", validId)); + aclList.add(acl); + zk.create("/valid" + i, null, aclList, CreateMode.PERSISTENT); + i++; + } + } + + @Test + public void testInvalidSaslIds() throws Exception { + ZooKeeper zk = createClient(); + + List<String> invalidIds = new ArrayList<String>(); + invalidIds.add("user@KERB.REALM/server.com"); + invalidIds.add("user@KERB.REALM1@KERB.REALM2"); + + int i = 0; + for (String invalidId : invalidIds) { + List<ACL> aclList = new ArrayList<ACL>(); + try { + ACL acl = new ACL(0, new Id("sasl", invalidId)); + aclList.add(acl); + zk.create("/invalid" + i, null, aclList, CreateMode.PERSISTENT); + Assert.fail("SASLAuthenticationProvider.isValid() failed to catch invalid Id."); + } catch (KeeperException.InvalidACLException e) { + // ok. + } finally { + i++; + } + } + } + + @Test + public void testZKOperationsAfterClientSaslAuthFailure() throws Exception { + CountdownWatcher watcher = new CountdownWatcher(); + ZooKeeper zk = new ZooKeeper(hostPort, CONNECTION_TIMEOUT, watcher); + watcher.waitForConnected(CONNECTION_TIMEOUT); + try { + setSaslFailureFlag(zk); + + // try node creation for around 15 second, + int totalTry = 10; + int tryCount = 0; + + boolean success = false; + while (!success && tryCount++ <= totalTry) { + try { + zk.create("/saslAuthFail", "data".getBytes(), Ids.OPEN_ACL_UNSAFE, + CreateMode.PERSISTENT_SEQUENTIAL); + success = true; + } catch (KeeperException.ConnectionLossException e) { + Thread.sleep(1000); + // do nothing + } + } + assertTrue("ZNode creation is failing continusly after Sasl auth failure.", success); + + } finally { + zk.close(); + } + } + + // set saslLoginFailed to true to simulate SASL login failure, + // LoginException + private void setSaslFailureFlag(ZooKeeper zk) throws Exception { --- End diff -- would it be possible to inject a mock ZooKeeperSaslClient for the test, it may be cleaner and more maintainable than reflection? > ZK Client not able to connect with Xid out of order error > ---------------------------------------------------------- > > Key: ZOOKEEPER-2775 > URL: https://issues.apache.org/jira/browse/ZOOKEEPER-2775 > Project: ZooKeeper > Issue Type: Bug > Components: java client > Affects Versions: 3.4.10, 3.5.3, 3.6.0 > Reporter: Bhupendra Kumar Jain > Assignee: Mohammad Arshad > Priority: Critical > Attachments: ZOOKEEPER-2775-01.patch > > > During Network unreachable scenario in one of the cluster, we observed Xid > out of order and Nothing in the queue error continously. And ZK client it > finally not able to connect successully to ZK server. > *Logs:* > unexpected error, closing socket connection and attempting reconnect | > org.apache.zookeeper.ClientCnxn (ClientCnxn.java:1447) > java.io.IOException: Xid out of order. Got Xid 52 with err 0 expected Xid 53 > for a packet with details: clientPath:null serverPath:null finished:false > header:: 53,101 replyHeader:: 0,0,-4 request:: > 12885502275,v{'/app1/controller,'/app1/config/changes},v{},v{'/app1/config/changes} > response:: null > at > org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:996) > at > org.apache.zookeeper.ClientCnxnSocketNIO.doIO(ClientCnxnSocketNIO.java:101) > at > org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:370) > at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1426) > unexpected error, closing socket connection and attempting reconnect > java.io.IOException: Nothing in the queue, but got 1 > at > org.apache.zookeeper.ClientCnxn$SendThread.readResponse(ClientCnxn.java:983) > at > org.apache.zookeeper.ClientCnxnSocketNIO.doIO(ClientCnxnSocketNIO.java:101) > at > org.apache.zookeeper.ClientCnxnSocketNIO.doTransport(ClientCnxnSocketNIO.java:370) > at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1426) > > *Analysis:* > 1) First time Client fails to do SASL login due to network unreachable > problem. > 2017-03-29 10:03:59,377 | WARN | [main-SendThread(192.168.130.8:24002)] | > SASL configuration failed: javax.security.auth.login.LoginException: Network > is unreachable (sendto failed) Will continue connection to Zookeeper server > without SASL authentication, if Zookeeper server allows it. | > org.apache.zookeeper.ClientCnxn (ClientCnxn.java:1307) > Here the boolean saslLoginFailed becomes true. > 2) After some time network connection is recovered and client is successully > able to login but still the boolean saslLoginFailed is not reset to false. > 3) Now SASL negotiation between client and server start happening and during > this time no user request will be sent. ( As the socket channel will be > closed for write till sasl negotiation complets) > 4) Now response from server for SASL packet will be processed by the client > and client assumes that tunnelAuthInProgress() is finished ( method checks > for saslLoginFailed boolean Since the boolean is true it assumes its done.) > and tries to process the packet as a other packet and will result in above > errors. > *Solution:* Reset the saslLoginFailed boolean every time before client login -- This message was sent by Atlassian JIRA (v6.3.15#6346)