Ver código fonte

ZOOKEEPER-435. allow "super" admin digest based auth to be configurable

git-svn-id: https://svn.apache.org/repos/asf/hadoop/zookeeper/trunk@782882 13f79535-47bb-0310-9956-ffa450edef68
Benjamin Reed 16 anos atrás
pai
commit
601320c337

+ 2 - 0
CHANGES.txt

@@ -113,6 +113,8 @@ BUGFIXES:
 
   ZOOKEEPER-406. address all findbugs warnings in persistence classes. (phunt et al via breed)
 
+  ZOOKEEPER-435. allow "super" admin digest based auth to be configurable (phunt via breed)
+
 IMPROVEMENTS:
   ZOOKEEPER-308. improve the atomic broadcast performance 3x.
   (breed via mahadev)

+ 41 - 0
src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml

@@ -822,6 +822,47 @@ server.3=zoo3:2888:3888</computeroutput></para>
         <para></para>
       </section>
 
+      <section id="sc_authOptions">
+        <title>Authentication &amp; Authorization Options</title>
+
+        <para>The options in this section allow control over
+        authentication/authorization performed by the service.</para>
+
+        <variablelist>
+          <varlistentry>
+            <term>zookeeper.DigestAuthenticationProvider.superDigest</term>
+
+            <listitem>
+              <para>(Java system property only: <emphasis
+              role="bold">zookeeper.DigestAuthenticationProvider.superDigest</emphasis>)</para>
+
+              <para>By default this feature is <emphasis
+              role="bold">disabled</emphasis></para>
+
+              <para><emphasis role="bold">New in 3.2:</emphasis>
+              Enables a ZooKeeper ensemble administrator to access the
+              znode hierarchy as a "super" user. In particular no ACL
+              checking occurs for a user authenticated as
+              super.</para>
+
+              <para>org.apache.zookeeper.server.auth.DigestAuthenticationProvider
+              can be used to generate the superDigest, call it with
+              one parameter of "super:&lt;password>". Provide the
+              generated "super:&lt;data>" as the system property value
+              when starting each server of the ensemble.</para>
+
+              <para>When authenticating to a ZooKeeper server (from a
+              ZooKeeper client) pass a scheme of "digest" and authdata
+              of "super:&lt;password>". Note that digest auth passes
+              the authdata in plaintext to the server, it would be
+              prudent to use this authentication method only on
+              localhost (not over the network) or over an encrypted
+              connection.</para>
+            </listitem>
+          </varlistentry>
+        </variablelist>
+      </section>
+
       <section>
         <title>Unsafe Options</title>
 

+ 15 - 5
src/java/main/org/apache/zookeeper/server/auth/DigestAuthenticationProvider.java

@@ -18,7 +18,6 @@
 
 package org.apache.zookeeper.server.auth;
 
-import java.io.IOException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
@@ -28,9 +27,16 @@ import org.apache.zookeeper.data.Id;
 import org.apache.zookeeper.server.ServerCnxn;
 
 public class DigestAuthenticationProvider implements AuthenticationProvider {
-    private static final Logger LOG = Logger.getLogger(DigestAuthenticationProvider.class);
+    private static final Logger LOG =
+        Logger.getLogger(DigestAuthenticationProvider.class);
 
-    public final static String superDigest = "super:1wZ8qIvQBMTq0KPxMc6RQ/PCXKM=";
+    /** specify a command line property with key of 
+     * "zookeeper.DigestAuthenticationProvider.superDigest"
+     * and value of "super:<base64encoded(SHA1(password))>" to enable
+     * super user access (i.e. acls disabled)
+     */
+    private final static String superDigest = System.getProperty(
+        "zookeeper.DigestAuthenticationProvider.superDigest");
 
     public String getScheme() {
         return "digest";
@@ -119,8 +125,12 @@ public class DigestAuthenticationProvider implements AuthenticationProvider {
         return id.equals(aclExpr);
     }
 
-    public static void main(String args[]) throws IOException,
-            NoSuchAlgorithmException {
+    /** Call with a single argument of user:pass to generate authdata.
+     * Authdata output can be used when setting superDigest for example. 
+     * @param args single argument of user:pass
+     * @throws NoSuchAlgorithmException
+     */
+    public static void main(String args[]) throws NoSuchAlgorithmException {
         for (int i = 0; i < args.length; i++) {
             System.out.println(args[i] + "->" + generateDigest(args[i]));
         }

+ 79 - 0
src/java/test/org/apache/zookeeper/test/AuthTest.java

@@ -0,0 +1,79 @@
+/**
+ * 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.test;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Test;
+
+public class AuthTest extends ClientBase {
+    static {
+        // password is test
+        System.setProperty("zookeeper.DigestAuthenticationProvider.superDigest",
+                "super:D/InIHSb7yEEbrWz8b9l71RjZJU=");        
+    }
+
+    @Test
+    public void testSuper() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "pat:pass".getBytes());
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL,
+                    CreateMode.PERSISTENT);
+            zk.close();
+            // verify no auth
+            zk = createClient();
+            try {
+                zk.getData("/path1", false, null);
+                fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify bad pass fails
+            zk = createClient();
+            zk.addAuthInfo("digest", "pat:pass2".getBytes());
+            try {
+                zk.getData("/path1", false, null);
+                fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify super with bad pass fails
+            zk = createClient();
+            zk.addAuthInfo("digest", "super:test2".getBytes());
+            try {
+                zk.getData("/path1", false, null);
+                fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify super with correct pass success
+            zk = createClient();
+            zk.addAuthInfo("digest", "super:test".getBytes());
+            zk.getData("/path1", false, null);
+        } finally {
+            zk.close();
+        }
+    }
+}