Your message dated Wed, 12 Jun 2019 13:51:25 +0000 with message-id <E1hb3ev-0007sj-Bm@respighi.debian.org> and subject line unblock zookeeper has caused the Debian Bug report #930106, regarding unblock: zookeeper/3.4.13-2 to be marked as done. This means that you claim that the problem has been dealt with. If this is not the case it is now your responsibility to reopen the Bug report if necessary, and/or fix the problem forthwith. (NB: If you are a system administrator and have no idea what this message is talking about, this may indicate a serious mail system misconfiguration somewhere. Please contact owner@bugs.debian.org immediately.) -- 930106: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930106 Debian Bug Tracking System Contact owner@bugs.debian.org with problems
--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: unblock: zookeeper/3.4.13-2
- From: tony mancill <tmancill@debian.org>
- Date: Thu, 6 Jun 2019 21:19:15 -0700
- Message-id: <[🔎] 20190607041915.GA10210@lark>
Package: release.debian.org Severity: normal User: release.debian.org@packages.debian.org Usertags: unblock Dear Release Team, Please unblock package zookeeper. The 3.4.13-2 package addresses CVE-2019-0201 (Debian: #929283). The debdiff against 3.4.13-1 is attached, and there is additional information about the testing of the patched package in the BTS: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=929283 Thank you for your time and consideration! tony unblock zookeeper/3.4.13-2diff -Nru zookeeper-3.4.13/debian/changelog zookeeper-3.4.13/debian/changelog --- zookeeper-3.4.13/debian/changelog 2018-10-18 20:19:42.000000000 -0700 +++ zookeeper-3.4.13/debian/changelog 2019-06-04 21:22:04.000000000 -0700 @@ -1,3 +1,9 @@ +zookeeper (3.4.13-2) unstable; urgency=medium + + * Add patch for CVE-2019-0201 (Debian: #929283) + + -- tony mancill <tmancill@debian.org> Tue, 04 Jun 2019 21:22:04 -0700 + zookeeper (3.4.13-1) unstable; urgency=medium * New upstream version 3.4.13 diff -Nru zookeeper-3.4.13/debian/patches/16-ZOOKEEPER-1392.patch zookeeper-3.4.13/debian/patches/16-ZOOKEEPER-1392.patch --- zookeeper-3.4.13/debian/patches/16-ZOOKEEPER-1392.patch 1969-12-31 16:00:00.000000000 -0800 +++ zookeeper-3.4.13/debian/patches/16-ZOOKEEPER-1392.patch 2019-06-04 21:22:04.000000000 -0700 @@ -0,0 +1,292 @@ +Description: Prevent ACL disclosure when unauthorized (CVE-2019-0201) +Origin: https://git-wip-us.apache.org/repos/asf?p=zookeeper.git;a=commitdiff;h=5ff19e3672987bdde2843a3f031e2bf0010e35f1 +Bug: https://issues.apache.org/jira/browse/ZOOKEEPER-1392 +Debian-Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=929283 + +--- a/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java ++++ b/src/java/main/org/apache/zookeeper/server/FinalRequestProcessor.java +@@ -20,10 +20,12 @@ + + import java.io.IOException; + import java.nio.ByteBuffer; ++import java.util.ArrayList; + import java.util.List; + + import org.apache.jute.Record; + import org.apache.zookeeper.common.Time; ++import org.apache.zookeeper.data.Id; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.apache.zookeeper.KeeperException; +@@ -309,10 +311,35 @@ + GetACLRequest getACLRequest = new GetACLRequest(); + ByteBufferInputStream.byteBuffer2Record(request.request, + getACLRequest); ++ DataNode n = zks.getZKDatabase().getNode(getACLRequest.getPath()); ++ if (n == null) { ++ throw new KeeperException.NoNodeException(); ++ } ++ PrepRequestProcessor.checkACL(zks, zks.getZKDatabase().aclForNode(n), ++ ZooDefs.Perms.READ | ZooDefs.Perms.ADMIN, ++ request.authInfo); ++ + Stat stat = new Stat(); +- List<ACL> acl = +- zks.getZKDatabase().getACL(getACLRequest.getPath(), stat); +- rsp = new GetACLResponse(acl, stat); ++ List<ACL> acl = ++ zks.getZKDatabase().getACL(getACLRequest.getPath(), stat); ++ try { ++ PrepRequestProcessor.checkACL(zks, zks.getZKDatabase().aclForNode(n), ++ ZooDefs.Perms.ADMIN, ++ request.authInfo); ++ rsp = new GetACLResponse(acl, stat); ++ } catch (KeeperException.NoAuthException e) { ++ List<ACL> acl1 = new ArrayList<ACL>(acl.size()); ++ for (ACL a : acl) { ++ if ("digest".equals(a.getId().getScheme())) { ++ Id id = a.getId(); ++ Id id1 = new Id(id.getScheme(), id.getId().replaceAll(":.*", ":x")); ++ acl1.add(new ACL(a.getPerms(), id1)); ++ } else { ++ acl1.add(a); ++ } ++ } ++ rsp = new GetACLResponse(acl1, stat); ++ } + break; + } + case OpCode.getChildren: { +--- /dev/null ++++ b/src/java/test/org/apache/zookeeper/server/FinalRequestProcessorTest.java +@@ -0,0 +1,230 @@ ++/** ++ * 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.server; ++ ++import org.apache.jute.BinaryOutputArchive; ++import org.apache.jute.Record; ++import org.apache.zookeeper.KeeperException; ++import org.apache.zookeeper.ZooDefs; ++import org.apache.zookeeper.data.ACL; ++import org.apache.zookeeper.data.Id; ++import org.apache.zookeeper.data.Stat; ++import org.apache.zookeeper.proto.GetACLRequest; ++import org.apache.zookeeper.proto.GetACLResponse; ++import org.apache.zookeeper.proto.ReplyHeader; ++import org.junit.Before; ++import org.junit.Test; ++import org.mockito.invocation.InvocationOnMock; ++import org.mockito.stubbing.Answer; ++ ++import java.io.ByteArrayOutputStream; ++import java.io.IOException; ++import java.nio.ByteBuffer; ++import java.util.ArrayList; ++import java.util.Arrays; ++import java.util.List; ++ ++import static org.hamcrest.Matchers.equalTo; ++import static org.junit.Assert.assertThat; ++import static org.junit.Assert.assertTrue; ++import static org.mockito.Matchers.any; ++import static org.mockito.Matchers.anyString; ++import static org.mockito.Matchers.eq; ++import static org.mockito.Mockito.doAnswer; ++import static org.mockito.Mockito.mock; ++import static org.mockito.Mockito.when; ++ ++public class FinalRequestProcessorTest { ++ private List<ACL> testACLs = new ArrayList<ACL>(); ++ private final Record[] responseRecord = new Record[1]; ++ private final ReplyHeader[] replyHeaders = new ReplyHeader[1]; ++ ++ private ServerCnxn cnxn; ++ private ByteBuffer bb; ++ private FinalRequestProcessor processor; ++ ++ @Before ++ public void setUp() throws KeeperException.NoNodeException, IOException { ++ testACLs.clear(); ++ testACLs.addAll(Arrays.asList( ++ new ACL(ZooDefs.Perms.ALL, new Id("digest", "user:secrethash")), ++ new ACL(ZooDefs.Perms.ADMIN, new Id("digest", "adminuser:adminsecret")), ++ new ACL(ZooDefs.Perms.READ, new Id("world", "anyone")) ++ )); ++ ++ ZooKeeperServer zks = new ZooKeeperServer(); ++ ZKDatabase db = mock(ZKDatabase.class); ++ String testPath = "/testPath"; ++ when(db.getNode(eq(testPath))).thenReturn(new DataNode()); ++ when(db.getACL(eq(testPath), any(Stat.class))).thenReturn(testACLs); ++ when(db.aclForNode(any(DataNode.class))).thenReturn(testACLs); ++ zks.setZKDatabase(db); ++ processor = new FinalRequestProcessor(zks); ++ ++ cnxn = mock(ServerCnxn.class); ++ doAnswer(new Answer() { ++ @Override ++ public Object answer(InvocationOnMock invocationOnMock) { ++ replyHeaders[0] = (ReplyHeader) invocationOnMock.getArguments()[0]; ++ responseRecord[0] = (Record) invocationOnMock.getArguments()[1]; ++ return null; ++ } ++ }).when(cnxn).sendResponse(any(ReplyHeader.class), any(Record.class), anyString()); ++ ++ GetACLRequest getACLRequest = new GetACLRequest(); ++ getACLRequest.setPath(testPath); ++ ByteArrayOutputStream baos = new ByteArrayOutputStream(); ++ BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos); ++ getACLRequest.serialize(boa, "request"); ++ baos.close(); ++ bb = ByteBuffer.wrap(baos.toByteArray()); ++ } ++ ++ @Test ++ public void testACLDigestHashHiding_NoAuth_WorldCanRead() { ++ // Arrange ++ ++ // Act ++ Request r = new Request(cnxn, 0, 0, ZooDefs.OpCode.getACL, bb, new ArrayList<Id>()); ++ processor.processRequest(r); ++ ++ // Assert ++ assertMasked(true); ++ } ++ ++ @Test ++ public void testACLDigestHashHiding_NoAuth_NoWorld() { ++ // Arrange ++ testACLs.remove(2); ++ ++ // Act ++ Request r = new Request(cnxn, 0, 0, ZooDefs.OpCode.getACL, bb, new ArrayList<Id>()); ++ processor.processRequest(r); ++ ++ // Assert ++ assertThat(KeeperException.Code.get(replyHeaders[0].getErr()), equalTo(KeeperException.Code.NOAUTH)); ++ } ++ ++ @Test ++ public void testACLDigestHashHiding_UserCanRead() { ++ // Arrange ++ List<Id> authInfo = new ArrayList<Id>(); ++ authInfo.add(new Id("digest", "otheruser:somesecrethash")); ++ ++ // Act ++ Request r = new Request(cnxn, 0, 0, ZooDefs.OpCode.getACL, bb, authInfo); ++ processor.processRequest(r); ++ ++ // Assert ++ assertMasked(true); ++ } ++ ++ @Test ++ public void testACLDigestHashHiding_UserCanAll() { ++ // Arrange ++ List<Id> authInfo = new ArrayList<Id>(); ++ authInfo.add(new Id("digest", "user:secrethash")); ++ ++ // Act ++ Request r = new Request(cnxn, 0, 0, ZooDefs.OpCode.getACL, bb, authInfo); ++ processor.processRequest(r); ++ ++ // Assert ++ assertMasked(false); ++ } ++ ++ @Test ++ public void testACLDigestHashHiding_AdminUser() { ++ // Arrange ++ List<Id> authInfo = new ArrayList<Id>(); ++ authInfo.add(new Id("digest", "adminuser:adminsecret")); ++ ++ // Act ++ Request r = new Request(cnxn, 0, 0, ZooDefs.OpCode.getACL, bb, authInfo); ++ processor.processRequest(r); ++ ++ // Assert ++ assertMasked(false); ++ } ++ ++ @Test ++ public void testACLDigestHashHiding_OnlyAdmin() { ++ // Arrange ++ testACLs.clear(); ++ testACLs.addAll(Arrays.asList( ++ new ACL(ZooDefs.Perms.READ, new Id("digest", "user:secrethash")), ++ new ACL(ZooDefs.Perms.ADMIN, new Id("digest", "adminuser:adminsecret")) ++ )); ++ List<Id> authInfo = new ArrayList<Id>(); ++ authInfo.add(new Id("digest", "adminuser:adminsecret")); ++ ++ // Act ++ Request r = new Request(cnxn, 0, 0, ZooDefs.OpCode.getACL, bb, authInfo); ++ processor.processRequest(r); ++ ++ // Assert ++ assertTrue("Not a GetACL response. Auth failed?", responseRecord[0] instanceof GetACLResponse); ++ GetACLResponse rsp = (GetACLResponse)responseRecord[0]; ++ assertThat("Number of ACLs in the response are different", rsp.getAcl().size(), equalTo(2)); ++ ++ // Verify ACLs in the response ++ assertThat("Password hash mismatch in the response", rsp.getAcl().get(0).getId().getId(), equalTo("user:secrethash")); ++ assertThat("Password hash mismatch in the response", rsp.getAcl().get(1).getId().getId(), equalTo("adminuser:adminsecret")); ++ } ++ ++ private void assertMasked(boolean masked) { ++ assertTrue("Not a GetACL response. Auth failed?", responseRecord[0] instanceof GetACLResponse); ++ GetACLResponse rsp = (GetACLResponse)responseRecord[0]; ++ assertThat("Number of ACLs in the response are different", rsp.getAcl().size(), equalTo(3)); ++ ++ // Verify ACLs in the response ++ assertThat("Invalid ACL list in the response", rsp.getAcl().get(0).getPerms(), equalTo(ZooDefs.Perms.ALL)); ++ assertThat("Invalid ACL list in the response", rsp.getAcl().get(0).getId().getScheme(), equalTo("digest")); ++ if (masked) { ++ assertThat("Password hash is not masked in the response", rsp.getAcl().get(0).getId().getId(), equalTo("user:x")); ++ } else { ++ assertThat("Password hash mismatch in the response", rsp.getAcl().get(0).getId().getId(), equalTo("user:secrethash")); ++ } ++ ++ assertThat("Invalid ACL list in the response", rsp.getAcl().get(1).getPerms(), equalTo(ZooDefs.Perms.ADMIN)); ++ assertThat("Invalid ACL list in the response", rsp.getAcl().get(1).getId().getScheme(), equalTo("digest")); ++ if (masked) { ++ assertThat("Password hash is not masked in the response", rsp.getAcl().get(1).getId().getId(), equalTo("adminuser:x")); ++ } else { ++ assertThat("Password hash mismatch in the response", rsp.getAcl().get(1).getId().getId(), equalTo("adminuser:adminsecret")); ++ } ++ ++ assertThat("Invalid ACL list in the response", rsp.getAcl().get(2).getPerms(), equalTo(ZooDefs.Perms.READ)); ++ assertThat("Invalid ACL list in the response", rsp.getAcl().get(2).getId().getScheme(), equalTo("world")); ++ assertThat("Invalid ACL list in the response", rsp.getAcl().get(2).getId().getId(), equalTo("anyone")); ++ ++ // Verify that FinalRequestProcessor hasn't changed the original ACL objects ++ assertThat("Original ACL list has been modified", testACLs.get(0).getPerms(), equalTo(ZooDefs.Perms.ALL)); ++ assertThat("Original ACL list has been modified", testACLs.get(0).getId().getScheme(), equalTo("digest")); ++ assertThat("Original ACL list has been modified", testACLs.get(0).getId().getId(), equalTo("user:secrethash")); ++ ++ assertThat("Original ACL list has been modified", testACLs.get(1).getPerms(), equalTo(ZooDefs.Perms.ADMIN)); ++ assertThat("Original ACL list has been modified", testACLs.get(1).getId().getScheme(), equalTo("digest")); ++ assertThat("Original ACL list has been modified", testACLs.get(1).getId().getId(), equalTo("adminuser:adminsecret")); ++ ++ assertThat("Original ACL list has been modified", testACLs.get(2).getPerms(), equalTo(ZooDefs.Perms.READ)); ++ assertThat("Original ACL list has been modified", testACLs.get(2).getId().getScheme(), equalTo("world")); ++ assertThat("Original ACL list has been modified", testACLs.get(2).getId().getId(), equalTo("anyone")); ++ } ++} diff -Nru zookeeper-3.4.13/debian/patches/series zookeeper-3.4.13/debian/patches/series --- zookeeper-3.4.13/debian/patches/series 2018-10-18 20:19:42.000000000 -0700 +++ zookeeper-3.4.13/debian/patches/series 2019-06-04 21:22:04.000000000 -0700 @@ -11,3 +11,4 @@ 13-disable-netty-connection-factory.patch 14-ftbfs-with-gcc-8.patch 15-javadoc-doclet.patch +16-ZOOKEEPER-1392.patchAttachment: signature.asc
Description: PGP signature
--- End Message ---
--- Begin Message ---
- To: 930106-done@bugs.debian.org
- Subject: unblock zookeeper
- From: Ivo De Decker <ivodd@respighi.debian.org>
- Date: Wed, 12 Jun 2019 13:51:25 +0000
- Message-id: <E1hb3ev-0007sj-Bm@respighi.debian.org>
Unblocked zookeeper.
--- End Message ---