Skip to content

Commit

Permalink
tdss
Browse files Browse the repository at this point in the history
  • Loading branch information
lilgreenbird committed Feb 24, 2022
1 parent f9caf73 commit 1a20762
Show file tree
Hide file tree
Showing 112 changed files with 319 additions and 265 deletions.
89 changes: 51 additions & 38 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
Expand Down Expand Up @@ -753,13 +754,17 @@ void resetPooledConnection() {
* @return InetSocketAddress of the connection socket.
*/
final InetSocketAddress open(String host, int port, int timeoutMillis, boolean useParallel, boolean useTnir,
boolean isTnirFirstAttempt, int timeoutMillisForFullTimeout) throws SQLServerException {
boolean isTnirFirstAttempt, int timeoutMillisForFullTimeout, boolean isTDSS) throws SQLServerException {
if (logger.isLoggable(Level.FINER))
logger.finer(this.toString() + ": Opening TCP socket...");

SocketFinder socketFinder = new SocketFinder(traceID, con);
channelSocket = tcpSocket = socketFinder.findSocket(host, port, timeoutMillis, useParallel, useTnir,
isTnirFirstAttempt, timeoutMillisForFullTimeout);
if (isTDSS) {
channelSocket = tcpSocket = sslSocket;
} else {
SocketFinder socketFinder = new SocketFinder(traceID, con);
channelSocket = tcpSocket = socketFinder.findSocket(host, port, timeoutMillis, useParallel, useTnir,
isTnirFirstAttempt, timeoutMillisForFullTimeout);
}
try {

// Set socket options
Expand Down Expand Up @@ -1828,8 +1833,8 @@ enum SSLHandhsakeState {
* Private key file's password
* @throws SQLServerException
*/
void enableSSL(String host, int port, String clientCertificate, String clientKey,
String clientKeyPassword) throws SQLServerException {
void enableSSL(String host, int port, String clientCertificate, String clientKey, String clientKeyPassword,
boolean isTDSS) throws SQLServerException {
// If enabling SSL fails, which it can for a number of reasons, the following items
// are used in logging information to the TDS channel logger to help diagnose the problem.
Provider tmfProvider = null; // TrustManagerFactory provider
Expand Down Expand Up @@ -1870,12 +1875,11 @@ void enableSSL(String host, int port, String clientCertificate, String clientKey
validateFips(trustStoreType, trustStoreFileName);
}

assert TDS.ENCRYPT_OFF == con.getRequestedEncryptionLevel() || // Login only SSL
TDS.ENCRYPT_ON == con.getRequestedEncryptionLevel(); // Full SSL

assert TDS.ENCRYPT_OFF == con.getNegotiatedEncryptionLevel() || // Login only SSL
TDS.ENCRYPT_ON == con.getNegotiatedEncryptionLevel() || // Full SSL
TDS.ENCRYPT_REQ == con.getNegotiatedEncryptionLevel(); // Full SSL
byte requestedEncryptLevel = con.getRequestedEncryptionLevel();
assert TDS.ENCRYPT_OFF == requestedEncryptLevel || // Login only SSL
TDS.ENCRYPT_ON == requestedEncryptLevel || // Full SSL
TDS.ENCRYPT_REQ == requestedEncryptLevel || // Full SSL
(isTDSS && TDS.ENCRYPT_NOT_SUP == requestedEncryptLevel); // TDSS

// If encryption wasn't negotiated or trust server certificate is specified,
// then we'll "validate" the server certificate using a naive TrustManager that trusts
Expand Down Expand Up @@ -2001,43 +2005,51 @@ else if (con.getTrustManagerClass() != null) {

sslContext.init(km, tm, null);

// Got the SSL context. Now create an SSL socket over our own proxy socket
// which we can toggle between TDS-encapsulated and raw communications.
// Initially, the proxy is set to encapsulate the SSL handshake in TDS packets.
proxySocket = new ProxySocket(this);
if (isTDSS) {
sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(host, port);

if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Creating SSL socket");
handshakeState = SSLHandhsakeState.SSL_HANDHSAKE_STARTED;
sslSocket.startHandshake();
handshakeState = SSLHandhsakeState.SSL_HANDHSAKE_COMPLETE;
} else {
// Got the SSL context. Now create an SSL socket over our own proxy socket
// which we can toggle between TDS-encapsulated and raw communications.
// Initially, the proxy is set to encapsulate the SSL handshake in TDS packets.
proxySocket = new ProxySocket(this);

// don't close proxy when SSL socket is closed
sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(proxySocket, host, port, false);
if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Creating SSL socket");

// At long last, start the SSL handshake ...
if (logger.isLoggable(Level.FINER))
logger.finer(toString() + " Starting SSL handshake");
// don't close proxy when SSL socket is closed
sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(proxySocket, host, port, false);

// TLS 1.2 intermittent exception happens here.
handshakeState = SSLHandhsakeState.SSL_HANDHSAKE_STARTED;
sslSocket.startHandshake();
handshakeState = SSLHandhsakeState.SSL_HANDHSAKE_COMPLETE;
// At long last, start the SSL handshake ...
if (logger.isLoggable(Level.FINER))
logger.finer(toString() + " Starting SSL handshake");

// After SSL handshake is complete, rewire proxy socket to use raw TCP/IP streams ...
if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Rewiring proxy streams after handshake");
// TLS 1.2 intermittent exception happens here.
handshakeState = SSLHandhsakeState.SSL_HANDHSAKE_STARTED;
sslSocket.startHandshake();
handshakeState = SSLHandhsakeState.SSL_HANDHSAKE_COMPLETE;

proxySocket.setStreams(inputStream, outputStream);
// After SSL handshake is complete, rewire proxy socket to use raw TCP/IP streams ...
if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Rewiring proxy streams after handshake");

// ... and rewire TDSChannel to use SSL streams.
if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Getting SSL InputStream");
proxySocket.setStreams(inputStream, outputStream);

inputStream = new ProxyInputStream(sslSocket.getInputStream());
// ... and rewire TDSChannel to use SSL streams.
if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Getting SSL InputStream");

if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Getting SSL OutputStream");
inputStream = new ProxyInputStream(sslSocket.getInputStream());

outputStream = sslSocket.getOutputStream();
if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Getting SSL OutputStream");

outputStream = sslSocket.getOutputStream();
}

// SSL is now enabled; switch over the channel socket
channelSocket = sslSocket;

Expand All @@ -2053,6 +2065,7 @@ else if (con.getTrustManagerClass() != null) {

if (logger.isLoggable(Level.FINER))
logger.finer(toString() + " SSL enabled");

} catch (Exception e) {
// Log the original exception and its source at FINER level
if (logger.isLoggable(Level.FINER))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,19 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
boolean getLastUpdateCount();

/**
* Sets a Boolean value that indicates if the encrypt property is enabled.
* Sets the option whether TLS encryption is used.
*
* @param encrypt
* true if the Secure Sockets Layer (SSL) encryption is enabled between the client and the SQL Server.
* Otherwise, false.
* @param encryptOption
* TLS encrypt option. Default is true
*/
void setEncrypt(boolean encrypt);
void setEncrypt(String encryptOption);

/**
* Returns a Boolean value that indicates if the encrypt property is enabled.
* Returns the TLS encryption option.
*
* @return true if encrypt is enabled. Otherwise, false.
* @return the TLS encrypt option
*/
boolean getEncrypt();
String getEncrypt();

/**
* Sets the value to enable/disable Transparent Netowrk IP Resolution (TNIR). Beginning in version 6.0 of the
Expand Down Expand Up @@ -143,18 +142,20 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
boolean getTransparentNetworkIPResolution();

/**
* Sets a Boolean value that indicates if the trustServerCertificate property is enabled.
* Sets a value that indicates if the trustServerCertificate property is enabled.
*
* @param e
* true, if the server Secure Sockets Layer (SSL) certificate should be automatically trusted when the
* communication layer is encrypted using SSL. Otherwise, false.
* communication layer is encrypted using SSL. false, if server SLL certificate should not be trusted
* certificate location, if encrypt=strict
*/
void setTrustServerCertificate(boolean e);

/**
* Returns a Boolean value that indicates if the trustServerCertificate property is enabled.
* Returns value that indicates if the trustServerCertificate property is enabled.
*
* @return true if trustServerCertificate is enabled. Otherwise, false.
* @return true if trustServerCertificate is enabled. Otherwise, false. If encrypt=strict, returns server
* certificate location
*/
boolean getTrustServerCertificate();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* Abstract class that implements ISQLServerBulkRecord
*
*/
@SuppressWarnings("deprecation")
abstract class SQLServerBulkRecord implements ISQLServerBulkRecord {

/**
Expand Down
Loading

0 comments on commit 1a20762

Please sign in to comment.