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

Add connection properties for specifying custom TrustManager #70

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 23 additions & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1605,7 +1605,21 @@ void enableSSL(String host, int port) throws SQLServerException

tm = new TrustManager[] { new PermissiveX509TrustManager(this) };
}

// Otherwise, we'll check if a specific TrustManager implemenation has been requested and
// if so instantiate it, optionally specifying a constructor argument to customize it.
else if (con.getTrustManagerClass() != null)
{
Class<?> tmClazz = Class.forName(con.getTrustManagerClass());
if (!TrustManager.class.isAssignableFrom(tmClazz)) {
throw new IllegalArgumentException("The class specified by the trustManagerClass property must implement javax.net.ssl.TrustManager");
}
String constructorArg = con.getTrustManagerConstructorArg();
if (constructorArg == null) {
tm = new TrustManager[] {(TrustManager) tmClazz.getDeclaredConstructor().newInstance()};
} else {
tm = new TrustManager[] {(TrustManager) tmClazz.getDeclaredConstructor(String.class).newInstance(constructorArg)};
}
}
// Otherwise, we'll validate the certificate using a real TrustManager obtained
// from the a security provider that is capable of validating X.509 certificates.
else
Expand Down Expand Up @@ -1801,6 +1815,14 @@ void enableSSL(String host, int port) throws SQLServerException

// It is important to get the localized message here, otherwise error messages won't match for different locales.
String errMsg = e.getLocalizedMessage();
// If the message is null replace it with the non-localized message or a dummy string. This can happen if a custom
// TrustManager implementation is specified that does not provide localized messages.
if (errMsg == null) {
errMsg = e.getMessage();
}
if (errMsg == null) {
errMsg = "";
}

// The error message may have a connection id appended to it. Extract the message only for comparison.
// This client connection id is appended in method checkAndAppendClientConnId().
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,20 @@ final byte getNegotiatedEncryptionLevel()
return negotiatedEncryptionLevel;
}

private String trustManagerClass = null;
final String getTrustManagerClass()
{
assert TDS.ENCRYPT_INVALID != requestedEncryptionLevel;
return trustManagerClass;
}

private String trustManagerConstructorArg = null;
final String getTrustManagerConstructorArg()
{
assert TDS.ENCRYPT_INVALID != requestedEncryptionLevel;
return trustManagerConstructorArg;
}

static final String RESERVED_PROVIDER_NAME_PREFIX = "MSSQL_";
String columnEncryptionSetting = null;
boolean isColumnEncryptionSettingEnabled() {
Expand Down Expand Up @@ -1177,6 +1191,9 @@ Connection connectInternal(Properties propsIn, SQLServerPooledConnection pooledC

trustServerCertificate = booleanPropertyOn(sPropKey,sPropValue);

trustManagerClass = activeConnectionProperties.getProperty(SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.toString());
trustManagerConstructorArg = activeConnectionProperties.getProperty(SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.toString());

sPropKey = SQLServerDriverStringProperty.SELECT_METHOD.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (sPropValue == null) sPropValue = SQLServerDriverStringProperty.SELECT_METHOD.getDefaultValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ enum SQLServerDriverStringProperty
SERVER_SPN("serverSpn", ""),
TRUST_STORE("trustStore", ""),
TRUST_STORE_PASSWORD("trustStorePassword", ""),
TRUST_MANAGER_CLASS("trustManagerClass", ""),
TRUST_MANAGER_CONSTRUCTOR_ARG("trustManagerConstructorArg", ""),
USER("user", ""),
WORKSTATION_ID("workstationID", Util.WSIDNotAvailable),
AUTHENTICATION_SCHEME("authenticationScheme", AuthenticationScheme.nativeAuthentication.toString()),
Expand Down Expand Up @@ -375,6 +377,8 @@ public final class SQLServerDriver implements java.sql.Driver
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.toString(), Boolean.toString(SQLServerDriverBooleanProperty.TRUST_SERVER_CERTIFICATE.getDefaultValue()), false, TRUE_FALSE),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_STORE.toString(), SQLServerDriverStringProperty.TRUST_STORE.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString(), SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.toString(), SQLServerDriverStringProperty.TRUST_MANAGER_CLASS.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.toString(), SQLServerDriverStringProperty.TRUST_MANAGER_CONSTRUCTOR_ARG.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(), Boolean.toString(SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue()), false, TRUE_FALSE),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.USER.toString(), SQLServerDriverStringProperty.USER.getDefaultValue(), true, null),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.WORKSTATION_ID.toString(), SQLServerDriverStringProperty.WORKSTATION_ID.getDefaultValue(), false, null),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ protected Object[][] getContents()
{"R_trustServerCertificatePropertyDescription", "Determines if the driver should validate the SQL Server Secure Sockets Layer (SSL) certificate."},
{"R_trustStorePropertyDescription", "The path to the certificate trust store file."},
{"R_trustStorePasswordPropertyDescription", "The password used to check the integrity of the trust store data."},
{"R_trustManagerClassPropertyDescription", "The class to instantiate as the TrustManager for SSL connections."},
{"R_trustManagerConstructorArgPropertyDescription", "The optional argument to pass to the constructor specified by trustManagerClass."},
{"R_hostNameInCertificatePropertyDescription", "The host name to be used when validating the SQL Server Secure Sockets Layer (SSL) certificate."},
{"R_sendTimeAsDatetimePropertyDescription", "Determines whether to use the SQL Server datetime data type to send java.sql.Time values to the database."},
{"R_TransparentNetworkIPResolutionPropertyDescription", "Determines whether to use the Transparent Network IP Resolution feature."},
Expand Down