HBASE-10883-Restrict the universe of labels and authorizations(Ram)

git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1585946 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
ramkrishna 2014-04-09 11:57:24 +00:00
parent 2922c5284d
commit e17ef0d87b
5 changed files with 97 additions and 4 deletions

View File

@ -33,15 +33,25 @@ import org.apache.hadoop.classification.InterfaceStability;
public class Authorizations { public class Authorizations {
private List<String> labels; private List<String> labels;
public Authorizations(String... labels) { public Authorizations(String... labels) {
this.labels = new ArrayList<String>(labels.length); this.labels = new ArrayList<String>(labels.length);
for (String label : labels) { for (String label : labels) {
validateLabel(label);
this.labels.add(label); this.labels.add(label);
} }
} }
private void validateLabel(String label) {
if (!VisibilityLabelsValidator.isValidLabel(label)) {
throw new IllegalArgumentException("Invalid authorization label : " + label
+ ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " and cannot be empty");
}
}
public Authorizations(List<String> labels) { public Authorizations(List<String> labels) {
for (String label : labels) {
validateLabel(label);
}
this.labels = labels; this.labels = labels;
} }

View File

@ -17,6 +17,9 @@
*/ */
package org.apache.hadoop.hbase.security.visibility; package org.apache.hadoop.hbase.security.visibility;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
/** /**
@ -27,6 +30,9 @@ public class VisibilityLabelsValidator {
// We follow Accumulo parity for valid visibility labels. // We follow Accumulo parity for valid visibility labels.
private static final boolean[] validAuthChars = new boolean[256]; 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 { static {
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
validAuthChars[i] = false; validAuthChars[i] = false;
@ -63,4 +69,9 @@ public class VisibilityLabelsValidator {
} }
return true; return true;
} }
public static final boolean isValidLabel(String label) {
Matcher matcher = pattern.matcher(label);
return matcher.matches();
}
} }

View File

@ -19,6 +19,8 @@
package org.apache.hadoop.hbase.client; package org.apache.hadoop.hbase.client;
import static org.junit.Assert.fail;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.Set;
@ -26,6 +28,7 @@ import java.util.Set;
import org.apache.hadoop.hbase.SmallTests; import org.apache.hadoop.hbase.SmallTests;
import org.apache.hadoop.hbase.protobuf.ProtobufUtil; import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
import org.apache.hadoop.hbase.protobuf.generated.ClientProtos; 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.apache.hadoop.hbase.util.Bytes;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
@ -107,5 +110,61 @@ public class TestScan {
Set<byte[]> qualifiers = scan.getFamilyMap().get(family); Set<byte[]> qualifiers = scan.getFamilyMap().get(family);
Assert.assertEquals(1, qualifiers.size()); 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");
}
}
} }

View File

@ -32,7 +32,6 @@ import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlRootElement;
import com.google.protobuf.HBaseZeroCopyByteString;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.Scan; 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.ProtobufMessageHandler;
import org.apache.hadoop.hbase.rest.protobuf.generated.ScannerMessage.Scanner; 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.Authorizations;
import org.apache.hadoop.hbase.security.visibility.VisibilityLabelsValidator;
import org.apache.hadoop.hbase.util.Base64; import org.apache.hadoop.hbase.util.Base64;
import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Bytes;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.google.protobuf.HBaseZeroCopyByteString;
import com.sun.jersey.api.json.JSONConfiguration; import com.sun.jersey.api.json.JSONConfiguration;
import com.sun.jersey.api.json.JSONJAXBContext; import com.sun.jersey.api.json.JSONJAXBContext;
import com.sun.jersey.api.json.JSONMarshaller; import com.sun.jersey.api.json.JSONMarshaller;
@ -525,6 +526,11 @@ public class ScannerModel implements ProtobufMessageHandler, Serializable {
if (authorizations != null) { if (authorizations != null) {
List<String> labels = authorizations.getLabels(); List<String> labels = authorizations.getLabels();
for (String label : labels) { for (String label : labels) {
if (!VisibilityLabelsValidator.isValidLabel(label)) {
throw new IllegalArgumentException("Invalid authorization label : " + label
+ ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " " +
"and cannot be empty");
}
model.addLabel(label); model.addLabel(label);
} }
} }

View File

@ -35,7 +35,6 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.google.protobuf.HBaseZeroCopyByteString;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.classification.InterfaceAudience;
@ -117,6 +116,7 @@ import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import com.google.protobuf.ByteString; import com.google.protobuf.ByteString;
import com.google.protobuf.HBaseZeroCopyByteString;
import com.google.protobuf.RpcCallback; import com.google.protobuf.RpcCallback;
import com.google.protobuf.RpcController; import com.google.protobuf.RpcController;
import com.google.protobuf.Service; import com.google.protobuf.Service;
@ -980,7 +980,8 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb
} }
} }
private Filter createVisibilityLabelFilter(HRegion region, Authorizations authorizations) { private Filter createVisibilityLabelFilter(HRegion region, Authorizations authorizations)
throws IOException {
Map<ByteRange, Integer> cfVsMaxVersions = new HashMap<ByteRange, Integer>(); Map<ByteRange, Integer> cfVsMaxVersions = new HashMap<ByteRange, Integer>();
for (HColumnDescriptor hcd : region.getTableDesc().getFamilies()) { for (HColumnDescriptor hcd : region.getTableDesc().getFamilies()) {
cfVsMaxVersions.put(new SimpleByteRange(hcd.getName()), hcd.getMaxVersions()); cfVsMaxVersions.put(new SimpleByteRange(hcd.getName()), hcd.getMaxVersions());
@ -996,6 +997,12 @@ public class VisibilityController extends BaseRegionObserver implements MasterOb
} }
return new VisibilityLabelFilter(new BitSet(0), cfVsMaxVersions); return new VisibilityLabelFilter(new BitSet(0), cfVsMaxVersions);
} }
for (String label : authorizations.getLabels()) {
if (!VisibilityLabelsValidator.isValidLabel(label)) {
throw new IllegalArgumentException("Invalid authorization label : " + label
+ ". Authorizations cannot contain '(', ')' ,'&' ,'|', '!'" + " and cannot be empty");
}
}
Filter visibilityLabelFilter = null; Filter visibilityLabelFilter = null;
if (this.scanLabelGenerator != null) { if (this.scanLabelGenerator != null) {
List<String> labels = null; List<String> labels = null;