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:
parent
2922c5284d
commit
e17ef0d87b
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue