Skip to content

Commit 2463cb8

Browse files
committed
Merged PR 4072: [2.1.7]
1 parent acfdeca commit 2463cb8

File tree

9 files changed

+272
-188
lines changed

9 files changed

+272
-188
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
864864
int payloadOffset = 0;
865865
int payloadLength = 0;
866866
int option = payload[offset++];
867+
bool serverSupportsEncryption = false;
867868

868869
while (option != (byte)PreLoginOptions.LASTOPT)
869870
{
@@ -900,18 +901,11 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
900901
LOGIN
901902
} */
902903

904+
// Any response other than NOT_SUP means the server supports encryption.
905+
serverSupportsEncryption = serverOption != EncryptionOptions.NOT_SUP;
906+
903907
switch (_encryptionOption)
904908
{
905-
case (EncryptionOptions.ON):
906-
if (serverOption == EncryptionOptions.NOT_SUP)
907-
{
908-
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
909-
_physicalStateObj.Dispose();
910-
ThrowExceptionAndWarning(_physicalStateObj);
911-
}
912-
913-
break;
914-
915909
case (EncryptionOptions.OFF):
916910
if (serverOption == EncryptionOptions.OFF)
917911
{
@@ -929,6 +923,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
929923
case (EncryptionOptions.NOT_SUP):
930924
if (serverOption == EncryptionOptions.REQ)
931925
{
926+
// Server requires encryption, but client does not support it.
932927
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByClient(), "", 0));
933928
_physicalStateObj.Dispose();
934929
ThrowExceptionAndWarning(_physicalStateObj);
@@ -937,49 +932,15 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
937932
break;
938933

939934
default:
940-
Debug.Fail("Invalid client encryption option detected");
941-
break;
942-
}
943-
944-
if (_encryptionOption == EncryptionOptions.ON ||
945-
_encryptionOption == EncryptionOptions.LOGIN)
946-
{
947-
uint error = 0;
948-
949-
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
950-
bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || (_connHandler._accessTokenInBytes != null && !trustServerCert);
951-
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
952-
| (isYukonOrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0);
953-
954-
if (encrypt && !integratedSecurity)
955-
{
956-
// optimization: in case of SQL Authentication and encryption, set SNI_SSL_IGNORE_CHANNEL_BINDINGS to let SNI
957-
// know that it does not need to allocate/retrieve the Channel Bindings from the SSL context.
958-
// This applies to Native SNI
959-
info |= TdsEnums.SNI_SSL_IGNORE_CHANNEL_BINDINGS;
960-
}
961-
962-
error = _physicalStateObj.EnableSsl(ref info);
963-
964-
if (error != TdsEnums.SNI_SUCCESS)
965-
{
966-
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
967-
ThrowExceptionAndWarning(_physicalStateObj);
968-
}
969-
970-
int protocolVersion = 0;
971-
WaitForSSLHandShakeToComplete(ref error, ref protocolVersion);
972-
973-
SslProtocols protocol = (SslProtocols)protocolVersion;
974-
string warningMessage = protocol.GetProtocolWarning();
975-
if (!string.IsNullOrEmpty(warningMessage))
976-
{
977-
// This logs console warning of insecure protocol in use.
978-
_logger.LogWarning(_typeName, MethodBase.GetCurrentMethod().Name, warningMessage);
979-
}
935+
// Any other client option needs encryption
936+
if (serverOption == EncryptionOptions.NOT_SUP)
937+
{
938+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
939+
_physicalStateObj.Dispose();
940+
ThrowExceptionAndWarning(_physicalStateObj);
941+
}
980942

981-
// create a new packet encryption changes the internal packet size
982-
_physicalStateObj.ClearAllWritePackets();
943+
break;
983944
}
984945

985946
break;
@@ -1062,6 +1023,54 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
10621023
}
10631024
}
10641025

1026+
if (_encryptionOption == EncryptionOptions.ON ||
1027+
_encryptionOption == EncryptionOptions.LOGIN)
1028+
{
1029+
if (!serverSupportsEncryption)
1030+
{
1031+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
1032+
_physicalStateObj.Dispose();
1033+
ThrowExceptionAndWarning(_physicalStateObj);
1034+
}
1035+
1036+
uint error = 0;
1037+
1038+
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
1039+
bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || (_connHandler._accessTokenInBytes != null && !trustServerCert);
1040+
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
1041+
| (isYukonOrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0);
1042+
1043+
if (encrypt && !integratedSecurity)
1044+
{
1045+
// optimization: in case of SQL Authentication and encryption, set SNI_SSL_IGNORE_CHANNEL_BINDINGS to let SNI
1046+
// know that it does not need to allocate/retrieve the Channel Bindings from the SSL context.
1047+
// This applies to Native SNI
1048+
info |= TdsEnums.SNI_SSL_IGNORE_CHANNEL_BINDINGS;
1049+
}
1050+
1051+
error = _physicalStateObj.EnableSsl(ref info);
1052+
1053+
if (error != TdsEnums.SNI_SUCCESS)
1054+
{
1055+
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
1056+
ThrowExceptionAndWarning(_physicalStateObj);
1057+
}
1058+
1059+
int protocolVersion = 0;
1060+
WaitForSSLHandShakeToComplete(ref error, ref protocolVersion);
1061+
1062+
SslProtocols protocol = (SslProtocols)protocolVersion;
1063+
string warningMessage = protocol.GetProtocolWarning();
1064+
if (!string.IsNullOrEmpty(warningMessage))
1065+
{
1066+
// This logs console warning of insecure protocol in use.
1067+
_logger.LogWarning(_typeName, MethodBase.GetCurrentMethod().Name, warningMessage);
1068+
}
1069+
1070+
// create a new packet encryption changes the internal packet size
1071+
_physicalStateObj.ClearAllWritePackets();
1072+
}
1073+
10651074
return PreLoginHandshakeStatus.Successful;
10661075
}
10671076

0 commit comments

Comments
 (0)