diff --git a/pom.xml b/pom.xml index f04f015cf..2e7587316 100644 --- a/pom.xml +++ b/pom.xml @@ -388,9 +388,6 @@ META-INF/services/java.sql.Driver - - src/main/resources - diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java b/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java index 650edbd7d..9d5251866 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java @@ -5,14 +5,7 @@ package com.microsoft.sqlserver.jdbc; -import java.io.File; -import java.io.FileOutputStream; -import java.io.InputStream; -import java.nio.file.Files; -import java.nio.file.Paths; import java.text.MessageFormat; -import java.util.Date; -import java.util.UUID; import java.util.logging.Level; @@ -32,7 +25,7 @@ class FedAuthDllInfo { */ final class AuthenticationJNI extends SSPIAuthentication { private static final int MAXPOINTERSIZE = 128; // we keep the SNI_Sec pointer - static boolean isDllLoaded = false; + private static boolean enabled = false; private static java.util.logging.Logger authLogger = java.util.logging.Logger .getLogger("com.microsoft.sqlserver.jdbc.internals.AuthenticationJNI"); private static int sspiBlobMaxlen = 0; @@ -48,95 +41,36 @@ static int getMaxSSPIBlobSize() { return sspiBlobMaxlen; } + static boolean isDllLoaded() { + return enabled; + } + static { UnsatisfiedLinkError temp = null; - - // Load the DLL in java.library.path + // Load the DLL try { System.loadLibrary(SQLServerDriver.AUTH_DLL_NAME); int[] pkg = new int[1]; - + pkg[0] = 0; if (0 == SNISecInitPackage(pkg, authLogger)) { sspiBlobMaxlen = pkg[0]; } else { - MessageFormat form = new MessageFormat( - SQLServerException.getErrString("R_UnableToLoadAuthDllManually")); - throw new UnsatisfiedLinkError(form.format(new Object[] {SQLServerDriver.AUTH_DLL_NAME})); - } - isDllLoaded = true; - } catch (UnsatisfiedLinkError ue) { - // If os is windows, attempt to extract and load the DLL packaged with the driver - if (SQLServerConnection.isWindows) { - String tempDirectory = System.getProperty("java.io.tmpdir") + SQLServerDriver.DLL_NAME + "\\"; - File outputDLL = new File(tempDirectory + UUID.randomUUID() + "-" + new Date().getTime() + ".dll"); - - try { - Files.createDirectories(Paths.get(tempDirectory)); - if (authLogger.isLoggable(Level.FINEST)) { - authLogger.finest("DLL extracted to: " + outputDLL.getAbsolutePath()); - } - - try (InputStream is = AuthenticationJNI.class.getResourceAsStream( - "/" + SQLServerDriver.DLL_NAME + "." + Util.getJVMArchOnWindows() + ".dll")) { - - try (FileOutputStream fos = new FileOutputStream(outputDLL)) { - if (is != null) { - int length = is.available(); - byte[] buffer = new byte[length]; - - // length may not be returned all at once so a loop is required - int pos = 0; - do { - int b = is.read(buffer, pos, length - pos); - if (b == -1) { - break; - } else { - fos.write(buffer, pos, b); - pos += b; - } - } while (pos < length); - } else { - throw new UnsatisfiedLinkError( - SQLServerException.getErrString("R_UnableToLoadPackagedAuthDll")); - } - } - } - - System.load(outputDLL.getAbsolutePath()); - - int[] pkg = new int[1]; - if (0 == SNISecInitPackage(pkg, authLogger)) { - sspiBlobMaxlen = pkg[0]; - } else { - throw new UnsatisfiedLinkError( - SQLServerException.getErrString("R_UnableToLoadPackagedAuthDll")); - } - - isDllLoaded = true; - } catch (UnsatisfiedLinkError ule) { - temp = ule; // R_UnableToLoadPackagedAuthDll - } catch (Exception e) { - temp = new UnsatisfiedLinkError(e.getMessage()); - } finally { - Runtime.getRuntime().addShutdownHook(cleanup(tempDirectory)); - } - } - - // If temp is still null and DLL is still not enabled, we attempted to load the DLL manually and failed - if (null == temp && !isDllLoaded) { - temp = ue; // R_UnableToLoadAuthDllManually + throw new UnsatisfiedLinkError(); } - - // The errors above are not re-thrown on purpose - the constructor will terminate properly - // with the appropriate error string - + enabled = true; + } catch (UnsatisfiedLinkError e) { + MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_UnableLoadAuthDll")); + temp = new UnsatisfiedLinkError(form.format(new Object[] {SQLServerDriver.AUTH_DLL_NAME})); + // This is not re-thrown on purpose - the constructor will terminate the properly with the appropriate error + // string } finally { linkError = temp; } + } AuthenticationJNI(SQLServerConnection con, String address, int serverport) throws SQLServerException { - if (!isDllLoaded) { + if (!enabled) { con.terminate(SQLServerException.DRIVER_ERROR_NONE, SQLServerException.getErrString("R_notConfiguredForIntegrated"), linkError); } @@ -201,20 +135,6 @@ private static String initDNSArray(String address) { return dns[0]; } - private static Thread cleanup(String dllDirectory) { - return new Thread(() -> { - File[] files = new File(dllDirectory).listFiles(); - - if (null != files) { - for (File dll : files) { - // If DLL is still loaded and in use, deletion will fail. So, it is safe - // to iterate and delete all files. - dll.delete(); - } - } - }); - } - // we use arrays of size one in many places to retrieve output values // Java Integer objects are immutable so we cant use them to get the output sizes. // Same for String diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java index d05edaf39..2b822fbf4 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java @@ -17,12 +17,22 @@ public final class SQLServerColumnEncryptionCertificateStoreProvider extends SQL static final private java.util.logging.Logger windowsCertificateStoreLogger = java.util.logging.Logger .getLogger("com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionCertificateStoreProvider"); + static boolean isWindows; + String name = "MSSQL_CERTIFICATE_STORE"; static final String LOCAL_MACHINE_DIRECTORY = "LocalMachine"; static final String CURRENT_USER_DIRECTORY = "CurrentUser"; static final String MY_CERTIFICATE_STORE = "My"; + static { + if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows")) { + isWindows = true; + } else { + isWindows = false; + } + } + /** * Constructs a SQLServerColumnEncryptionCertificateStoreProvider. */ @@ -61,7 +71,7 @@ public byte[] decryptColumnEncryptionKey(String masterKeyPath, String encryption windowsCertificateStoreLogger.entering(SQLServerColumnEncryptionCertificateStoreProvider.class.getName(), "decryptColumnEncryptionKey", "Decrypting Column Encryption Key."); byte[] plainCek; - if (SQLServerConnection.isWindows) { + if (isWindows) { plainCek = decryptColumnEncryptionKeyWindows(masterKeyPath, encryptionAlgorithm, encryptedColumnEncryptionKey); } else { diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java index ff1dc2343..c8bc87abd 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java @@ -944,10 +944,8 @@ IdleConnectionResiliency getSessionRecovery() { /** global system ColumnEncryptionKeyStoreProviders */ static Map globalSystemColumnEncryptionKeyStoreProviders = new HashMap<>(); - static boolean isWindows = System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows"); - static { - if (isWindows) { + if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows")) { SQLServerColumnEncryptionCertificateStoreProvider provider = new SQLServerColumnEncryptionCertificateStoreProvider(); globalSystemColumnEncryptionKeyStoreProviders.put(provider.getName(), provider); } @@ -5720,7 +5718,8 @@ private SqlAuthenticationToken getFedAuthToken(SqlFedAuthInfo fedAuthInfo) throw } else if (authenticationString .equalsIgnoreCase(SqlAuthentication.ACTIVE_DIRECTORY_INTEGRATED.toString())) { // If operating system is windows and mssql-jdbc_auth is loaded then choose the DLL authentication. - if (isWindows && AuthenticationJNI.isDllLoaded) { + if (System.getProperty("os.name").toLowerCase(Locale.ENGLISH).startsWith("windows") + && AuthenticationJNI.isDllLoaded()) { try { FedAuthDllInfo dllInfo = AuthenticationJNI.getAccessTokenForWindowsIntegrated( fedAuthInfo.stsurl, fedAuthInfo.spn, clientConnectionId.toString(), diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java index 12bbf21d7..163fb3885 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java @@ -717,8 +717,7 @@ public String toString() { public final class SQLServerDriver implements java.sql.Driver { static final String PRODUCT_NAME = "Microsoft JDBC Driver " + SQLJdbcVersion.MAJOR + "." + SQLJdbcVersion.MINOR + " for SQL Server"; - static final String DLL_NAME = "mssql-jdbc_auth"; - static final String AUTH_DLL_NAME = DLL_NAME + "-" + SQLJdbcVersion.MAJOR + "." + SQLJdbcVersion.MINOR + "." + static final String AUTH_DLL_NAME = "mssql-jdbc_auth-" + SQLJdbcVersion.MAJOR + "." + SQLJdbcVersion.MINOR + "." + SQLJdbcVersion.PATCH + "." + Util.getJVMArchOnWindows() + SQLJdbcVersion.RELEASE_EXT; static final String DEFAULT_APP_NAME = "Microsoft JDBC Driver for SQL Server"; diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java index 8f1639d33..d4634ae8b 100644 --- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java +++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java @@ -510,8 +510,6 @@ protected Object[][] getContents() { {"R_unassignableError", "The class specified by the {0} property must be assignable to {1}."}, {"R_InvalidCSVQuotes", "Failed to parse the CSV file, verify that the fields are correctly enclosed in double quotes."}, {"R_TokenRequireUrl", "Token credentials require a URL using the HTTPS protocol scheme."}, - {"R_UnableToLoadPackagedAuthDll", "Unable to load authentication DLL packaged with driver."}, - {"R_UnableToLoadAuthDllManually", "Unable to load authentication DLL specified by VM argument java.library.path. Failed to load auth DLL with name {0}."}, {"R_maxResultBufferPropertyDescription", "Determines maximum amount of bytes that can be read during retrieval of result set"}, {"R_maxResultBufferInvalidSyntax", "Invalid syntax: {0} in maxResultBuffer parameter."}, {"R_maxResultBufferNegativeParameterValue", "MaxResultBuffer must have positive value: {0}."}, diff --git a/src/main/resources/mssql-jdbc_auth.x64.dll b/src/main/resources/mssql-jdbc_auth.x64.dll deleted file mode 100644 index 9c13bbff7..000000000 Binary files a/src/main/resources/mssql-jdbc_auth.x64.dll and /dev/null differ diff --git a/src/main/resources/mssql-jdbc_auth.x86.dll b/src/main/resources/mssql-jdbc_auth.x86.dll deleted file mode 100644 index 08ed8d05d..000000000 Binary files a/src/main/resources/mssql-jdbc_auth.x86.dll and /dev/null differ diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionTest.java b/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionTest.java index 4b13f25e2..0f28b61f5 100644 --- a/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionTest.java +++ b/src/test/java/com/microsoft/sqlserver/jdbc/connection/ConnectionTest.java @@ -8,9 +8,7 @@ import java.sql.SQLException; import com.microsoft.sqlserver.jdbc.TestUtils; -import com.microsoft.sqlserver.testframework.Constants; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; @@ -71,20 +69,4 @@ public void testInvalidConnectWithIPAddressPreference() throws SQLException { } } - @Test - @Tag(Constants.xAzureSQLDW) - @Tag(Constants.xAzureSQLDB) - @Tag(Constants.xAzureSQLMI) - public void testConnectionWithIntegratedSecurityWhenAuthDLLIsNotProvided() throws SQLException { - org.junit.Assume.assumeTrue(isWindows); - SQLServerDataSource ds = new SQLServerDataSource(); - ds.setURL(connectionString); - ds.setUser(""); - ds.setPassword(""); - ds.setIntegratedSecurity(true); - - // Driver should use packaged auth DLL - try (Connection con = ds.getConnection()) {} - } - }