diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java index ac1ee78..23081d0 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/Authorizations.java @@ -33,15 +33,26 @@ import org.apache.hadoop.classification.InterfaceStability; public class Authorizations { private List labels; - public Authorizations(String... labels) { this.labels = new ArrayList(labels.length); for (String label : labels) { + validateLabel(label); this.labels.add(label); } } + private void validateLabel(String label) { + if (!VisibilityLabelsValidator.isValidLabel(label)) { + throw new IllegalArgumentException("Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + + " and cannot be empty"); + } + } + public Authorizations(List labels) { + if (!VisibilityLabelsValidator.isValidLabel(labels)) { + throw new IllegalArgumentException("Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + + " and cannot be empty"); + } this.labels = labels; } diff --git hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java index d60c43c..89c79b5 100644 --- hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java +++ hbase-client/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityLabelsValidator.java @@ -17,6 +17,10 @@ */ package org.apache.hadoop.hbase.security.visibility; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import org.apache.hadoop.classification.InterfaceAudience; /** @@ -26,6 +30,9 @@ import org.apache.hadoop.classification.InterfaceAudience; public class VisibilityLabelsValidator { // We follow Accumulo parity for valid visibility labels. private static final boolean[] validAuthChars = new boolean[256]; + + public static final String regex = "[A-Za-z_\\-\\:\\/\\.0-9]+"; + public static final Pattern pattern = Pattern.compile(regex); static { for (int i = 0; i < 256; i++) { @@ -63,4 +70,18 @@ public class VisibilityLabelsValidator { } return true; } + + public static final boolean isValidLabel(List labels) { + for (String label : labels) { + if (!isValidLabel(label)) { + return false; + } + } + return true; + } + + public static final boolean isValidLabel(String label) { + Matcher matcher = pattern.matcher(label); + return matcher.matches(); + } } diff --git hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java index 9565764..97c5f0f 100644 --- hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java +++ hbase-client/src/test/java/org/apache/hadoop/hbase/client/TestScan.java @@ -19,6 +19,8 @@ package org.apache.hadoop.hbase.client; +import static org.junit.Assert.fail; + import java.io.IOException; import java.util.Arrays; import java.util.Set; @@ -26,6 +28,7 @@ import java.util.Set; import org.apache.hadoop.hbase.SmallTests; import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.protobuf.generated.ClientProtos; +import org.apache.hadoop.hbase.security.visibility.Authorizations; import org.apache.hadoop.hbase.util.Bytes; import org.junit.Assert; import org.junit.Test; @@ -107,5 +110,61 @@ public class TestScan { Set qualifiers = scan.getFamilyMap().get(family); Assert.assertEquals(1, qualifiers.size()); } + + @Test + public void testSetAuthorizations() { + Scan scan = new Scan(); + scan.setAuthorizations(new Authorizations("A", "B", "0123", "A0", "1A1", "_a")); + try { + scan.setAuthorizations(new Authorizations("A|B")); + fail("Should have failed for A|B."); + } catch (IllegalArgumentException e) { + } + try { + scan.setAuthorizations(new Authorizations("A&B")); + fail("Should have failed for A&B."); + } catch (IllegalArgumentException e) { + } + try { + scan.setAuthorizations(new Authorizations("!B")); + fail("Should have failed for !B."); + } catch (IllegalArgumentException e) { + } + try { + scan.setAuthorizations(new Authorizations("A", "(A)")); + fail("Should have failed for (A)."); + } catch (IllegalArgumentException e) { + } + try { + scan.setAuthorizations(new Authorizations("A", "{A")); + fail("Should have failed for {A."); + } catch (IllegalArgumentException e) { + } + try { + scan.setAuthorizations(new Authorizations(" ")); + fail("Should have failed for empty"); + } catch (IllegalArgumentException e) { + } + try { + scan.setAuthorizations(new Authorizations(":B")); + } catch (IllegalArgumentException e) { + fail("Should not have failed for :B"); + } + try { + scan.setAuthorizations(new Authorizations("-B")); + } catch (IllegalArgumentException e) { + fail("Should not have failed for -B"); + } + try { + scan.setAuthorizations(new Authorizations(".B")); + } catch (IllegalArgumentException e) { + fail("Should not have failed for .B"); + } + try { + scan.setAuthorizations(new Authorizations("/B")); + } catch (IllegalArgumentException e) { + fail("Should not have failed for /B"); + } + } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java index d0bbbd7..570126d 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/rest/model/ScannerModel.java @@ -32,7 +32,6 @@ import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; -import com.google.protobuf.HBaseZeroCopyByteString; import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.client.Scan; @@ -71,10 +70,12 @@ import org.apache.hadoop.hbase.filter.WhileMatchFilter; import org.apache.hadoop.hbase.rest.ProtobufMessageHandler; import org.apache.hadoop.hbase.rest.protobuf.generated.ScannerMessage.Scanner; import org.apache.hadoop.hbase.security.visibility.Authorizations; +import org.apache.hadoop.hbase.security.visibility.VisibilityLabelsValidator; import org.apache.hadoop.hbase.util.Base64; import org.apache.hadoop.hbase.util.Bytes; import com.google.protobuf.ByteString; +import com.google.protobuf.HBaseZeroCopyByteString; import com.sun.jersey.api.json.JSONConfiguration; import com.sun.jersey.api.json.JSONJAXBContext; import com.sun.jersey.api.json.JSONMarshaller; @@ -525,6 +526,10 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable { if (authorizations != null) { List labels = authorizations.getLabels(); for (String label : labels) { + if (!VisibilityLabelsValidator.isValidLabel(label)) { + throw new IOException("Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + + " and cannot be empty"); + } model.addLabel(label); } } diff --git hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java index ad190e9..589bea8 100644 --- hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java +++ hbase-server/src/main/java/org/apache/hadoop/hbase/security/visibility/VisibilityController.java @@ -35,7 +35,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import com.google.protobuf.HBaseZeroCopyByteString; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience; @@ -115,6 +114,7 @@ import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher; import com.google.common.collect.Lists; import com.google.common.collect.MapMaker; import com.google.protobuf.ByteString; +import com.google.protobuf.HBaseZeroCopyByteString; import com.google.protobuf.RpcCallback; import com.google.protobuf.RpcController; import com.google.protobuf.Service; @@ -883,6 +883,10 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb } try { authorizations = scan.getAuthorizations(); + if (!VisibilityLabelsValidator.isValidLabel(authorizations.getLabels())) { + throw new IOException("Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + + " and cannot be empty"); + } } catch (DeserializationException de) { throw new IOException(de); } @@ -963,6 +967,10 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb } try { authorizations = get.getAuthorizations(); + if (!VisibilityLabelsValidator.isValidLabel(authorizations.getLabels())) { + throw new IOException("Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + + " and cannot be empty"); + } } catch (DeserializationException de) { throw new IOException(de); }