Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature | Added support for Data Classification v2 #1338

Merged
merged 22 commits into from
Jun 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c97b863
Fix AEv2 tests exclude for reqExternalSetup and cleanup (#1247)
lilgreenbird Feb 5, 2020
54b5a19
Fix | Add null check for getObject() with LocalTime and LocalDate (#1…
peterbae Feb 8, 2020
672b7d6
added all AKV tests to use reqExternalSetup tag so they will be skipp…
lilgreenbird Feb 10, 2020
3c3331b
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 25, 2020
e2c5640
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 26, 2020
aad6966
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 28, 2020
92bf04c
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Mar 31, 2020
3ba5ab7
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 4, 2020
d20823d
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 7, 2020
4cc959f
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 29, 2020
7b301f8
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird Apr 30, 2020
56bcf13
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird May 7, 2020
744e0ca
Merge remote-tracking branch 'upstream/dev' into dev
lilgreenbird May 12, 2020
8479062
dataclassification v2
lilgreenbird May 16, 2020
8dbcca6
fix
lilgreenbird May 18, 2020
c64011d
Merge remote-tracking branch 'upstream/dev' into dataclass
lilgreenbird May 19, 2020
234512b
fixed typo
lilgreenbird May 19, 2020
621bc2e
comment
lilgreenbird May 20, 2020
7712b19
resolved conflicts
lilgreenbird Jun 10, 2020
0599353
Merge branch 'dataclass' of https://github.com/lilgreenbird/mssql-jdb…
lilgreenbird Jun 10, 2020
23da8c2
Merge remote-tracking branch 'upstream/dev' into dataclass
lilgreenbird Jun 18, 2020
6461154
review updates
lilgreenbird Jun 18, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ final class TDS {
// Data Classification constants
static final byte TDS_FEATURE_EXT_DATACLASSIFICATION = 0x09;
static final byte DATA_CLASSIFICATION_NOT_ENABLED = 0x00;
static final byte MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION = 0x01;
static final byte MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION = 0x02;

static final int AES_256_CBC = 1;
static final int AEAD_AES_256_CBC_HMAC_SHA256 = 2;
Expand Down Expand Up @@ -6434,6 +6434,8 @@ final SQLServerConnection getConnection() {
private boolean useColumnEncryption = false;
private boolean serverSupportsColumnEncryption = false;
private boolean serverSupportsDataClassification = false;
private byte serverSupportedDataClassificationVersion = TDS.DATA_CLASSIFICATION_NOT_ENABLED;

private ColumnEncryptionVersion columnEncryptionVersion;

private final byte valueBytes[] = new byte[256];
Expand Down Expand Up @@ -6461,6 +6463,7 @@ private static int nextReaderID() {
serverSupportsColumnEncryption = con.getServerSupportsColumnEncryption();
columnEncryptionVersion = con.getServerColumnEncryptionVersion();
serverSupportsDataClassification = con.getServerSupportsDataClassification();
serverSupportedDataClassificationVersion = con.getServerSupportedDataClassificationVersion();
}

final boolean isColumnEncryptionSettingEnabled() {
Expand All @@ -6475,6 +6478,10 @@ final boolean getServerSupportsDataClassification() {
return serverSupportsDataClassification;
}

final byte getServerSupportedDataClassificationVersion() {
return serverSupportedDataClassificationVersion;
}

final void throwInvalidTDS() throws SQLServerException {
if (logger.isLoggable(Level.SEVERE))
logger.severe(toString() + " got unexpected value in TDS response at offset:" + payloadOffset);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -680,11 +680,16 @@ ColumnEncryptionVersion getServerColumnEncryptionVersion() {
}

private boolean serverSupportsDataClassification = false;
private byte serverSupportedDataClassificationVersion = TDS.DATA_CLASSIFICATION_NOT_ENABLED;

boolean getServerSupportsDataClassification() {
return serverSupportsDataClassification;
}

byte getServerSupportedDataClassificationVersion() {
return serverSupportedDataClassificationVersion;
}

// Boolean that indicates whether LOB objects created by this connection should be loaded into memory
private boolean delayLoadingLobs = SQLServerDriverBooleanProperty.DELAY_LOADING_LOBS.getDefaultValue();

Expand Down Expand Up @@ -4669,9 +4674,9 @@ private void onFeatureExtAck(byte featureId, byte[] data) throws SQLServerExcept
throw new SQLServerException(SQLServerException.getErrString("R_UnknownDataClsTokenNumber"), null);
}

byte supportedDataClassificationVersion = data[0];
if ((0 == supportedDataClassificationVersion)
|| (supportedDataClassificationVersion > TDS.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION)) {
serverSupportedDataClassificationVersion = data[0];
if ((0 == serverSupportedDataClassificationVersion)
|| (serverSupportedDataClassificationVersion > TDS.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION)) {
throw new SQLServerException(SQLServerException.getErrString("R_InvalidDataClsVersionNumber"),
null);
}
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,36 @@ public String toString() {
}


enum SensitivityRank {
NOT_DEFINED(-1),
NONE(0),
LOW(10),
MEDIUM(20),
HIGH(30),
CRITICAL(40);

private static final SensitivityRank[] VALUES = values();
private int rank;

private SensitivityRank(int rank) {
this.rank = rank;
}

public int getValue() {
return rank;
}

static boolean isValid(int rank) throws SQLServerException {
for (SensitivityRank r : VALUES) {
if (r.getValue() == rank) {
return true;
}
}
return false;
}
}


/**
* Provides methods to connect to a SQL Server database and to obtain information about the JDBC driver.
*/
Expand Down
58 changes: 38 additions & 20 deletions src/main/java/com/microsoft/sqlserver/jdbc/StreamColumns.java
Original file line number Diff line number Diff line change
Expand Up @@ -259,55 +259,73 @@ private SensitivityClassification processDataClassification(TDSReader tdsReader)
SensitivityClassification sensitivityClassification = null;

// get the label count
int numLabels = tdsReader.readUnsignedShort();
List<Label> labels = new ArrayList<Label>(numLabels);
int sensitivityLabelCount = tdsReader.readUnsignedShort();
List<Label> sensitivityLabels = new ArrayList<Label>(sensitivityLabelCount);

for (int i = 0; i < numLabels; i++) {
labels.add(readSensitivityLabel(tdsReader));
for (int i = 0; i < sensitivityLabelCount; i++) {
sensitivityLabels.add(readSensitivityLabel(tdsReader));
}

// get the information type count
int numInformationTypes = tdsReader.readUnsignedShort();
int informationTypeCount = tdsReader.readUnsignedShort();

List<InformationType> informationTypes = new ArrayList<InformationType>(numInformationTypes);
for (int i = 0; i < numInformationTypes; i++) {
List<InformationType> informationTypes = new ArrayList<InformationType>(informationTypeCount);
for (int i = 0; i < informationTypeCount; i++) {
informationTypes.add(readSensitivityInformationType(tdsReader));
}

int sensitivityRank = SensitivityRank.NOT_DEFINED.getValue();
if (TDS.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION <= tdsReader.getServerSupportedDataClassificationVersion()) {
lilgreenbird marked this conversation as resolved.
Show resolved Hide resolved
sensitivityRank = tdsReader.readInt();
if (!SensitivityRank.isValid(sensitivityRank)) {
tdsReader.throwInvalidTDS();
}
}

// get the per column classification data (corresponds to order of output columns for query)
int numResultColumns = tdsReader.readUnsignedShort();
int numResultSetColumns = tdsReader.readUnsignedShort();

List<ColumnSensitivity> columnSensitivities = new ArrayList<ColumnSensitivity>(numResultColumns);
for (int columnNum = 0; columnNum < numResultColumns; columnNum++) {
List<ColumnSensitivity> columnSensitivities = new ArrayList<ColumnSensitivity>(numResultSetColumns);
for (int columnNum = 0; columnNum < numResultSetColumns; columnNum++) {

// get sensitivity properties for all the different sources which were used in generating the column output
int numSources = tdsReader.readUnsignedShort();
List<SensitivityProperty> sensitivityProperties = new ArrayList<SensitivityProperty>(numSources);
for (int sourceNum = 0; sourceNum < numSources; sourceNum++) {
int numSensitivityProperties = tdsReader.readUnsignedShort();
List<SensitivityProperty> sensitivityProperties = new ArrayList<SensitivityProperty>(
numSensitivityProperties);
for (int sourceNum = 0; sourceNum < numSensitivityProperties; sourceNum++) {

// get the label index and then lookup label to use for source
int labelIndex = tdsReader.readUnsignedShort();
int sensitivityLabelIndex = tdsReader.readUnsignedShort();
Label label = null;
if (labelIndex != Integer.MAX_VALUE) {
if (labelIndex >= labels.size()) {
if (sensitivityLabelIndex != Integer.MAX_VALUE) {
if (sensitivityLabelIndex >= sensitivityLabels.size()) {
tdsReader.throwInvalidTDS();
}
label = labels.get(labelIndex);
label = sensitivityLabels.get(sensitivityLabelIndex);
}

// get the information type index and then lookup information type to use for source
int informationTypeIndex = tdsReader.readUnsignedShort();
InformationType informationType = null;
if (informationTypeIndex != Integer.MAX_VALUE) {
if (informationTypeIndex >= informationTypes.size()) {}
informationType = informationTypes.get(informationTypeIndex);
}

if (TDS.MAX_SUPPORTED_DATA_CLASSIFICATION_VERSION <= tdsReader
.getServerSupportedDataClassificationVersion()) {
sensitivityRank = tdsReader.readInt();
if (!SensitivityRank.isValid(sensitivityRank)) {
tdsReader.throwInvalidTDS();
}
}

// add sensitivity properties for the source
sensitivityProperties.add(new SensitivityProperty(label, informationType));
sensitivityProperties.add(new SensitivityProperty(label, informationType, sensitivityRank));
}
columnSensitivities.add(new ColumnSensitivity(sensitivityProperties));
}
sensitivityClassification = new SensitivityClassification(labels, informationTypes, columnSensitivities);
sensitivityClassification = new SensitivityClassification(sensitivityLabels, informationTypes,
columnSensitivities);
return sensitivityClassification;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
public class SensitivityProperty {
private Label label;
private InformationType informationType;
private int sensitivityRank;

/**
* Constructs a SensitivityProperty
Expand All @@ -25,6 +26,22 @@ public SensitivityProperty(Label label, InformationType informationType) {
this.informationType = informationType;
}

/**
* Constructs a SensitivityProperty
*
* @param label
* Label as received from SQL Server for this SensitivityProperty
* @param informationType
* InformationType as received from SQL Server for this SensitivityProperty
* @param sensitivityRank
* sensitivity rank as received from SQL Server for this SensitivityProperty
*/
public SensitivityProperty(Label label, InformationType informationType, int sensitivityRank) {
lilgreenbird marked this conversation as resolved.
Show resolved Hide resolved
this.label = label;
this.informationType = informationType;
this.sensitivityRank = sensitivityRank;
}

/**
* Returns the label data for this <code>SensitivityProperty</code> Object
*
Expand All @@ -42,4 +59,8 @@ public Label getLabel() {
public InformationType getInformationType() {
return informationType;
}

public int getSensitivityRank() {
return sensitivityRank;
}
}
3 changes: 2 additions & 1 deletion src/test/java/com/microsoft/sqlserver/jdbc/TestResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,6 @@ protected Object[][] getContents() {
{"R_invalidEnclaveSessionFailed", "invalidate enclave session failed."},
{"R_invalidEnclaveType", "Invalid enclave type {0}."},
{"R_keystorePassword", "keystore password was incorrect"},
{"R_enclaveNotEnabled", "The statement triggers enclave computations"}};
{"R_enclaveNotEnabled", "The statement triggers enclave computations"},
{"R_dataClassificationNotSupported", "Data Classification is not supported on this server."}};
}
Loading