Skip to content

Commit 443347b

Browse files
committed
Merged PR 4078: [4.0.5]
1 parent 34401b3 commit 443347b

File tree

9 files changed

+285
-202
lines changed

9 files changed

+285
-202
lines changed

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

Lines changed: 67 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
851851
int payloadOffset = 0;
852852
int payloadLength = 0;
853853
int option = payload[offset++];
854+
bool serverSupportsEncryption = false;
854855

855856
while (option != (byte)PreLoginOptions.LASTOPT)
856857
{
@@ -887,18 +888,11 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
887888
LOGIN
888889
} */
889890

891+
// Any response other than NOT_SUP means the server supports encryption.
892+
serverSupportsEncryption = serverOption != EncryptionOptions.NOT_SUP;
893+
890894
switch (_encryptionOption)
891895
{
892-
case (EncryptionOptions.ON):
893-
if (serverOption == EncryptionOptions.NOT_SUP)
894-
{
895-
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
896-
_physicalStateObj.Dispose();
897-
ThrowExceptionAndWarning(_physicalStateObj);
898-
}
899-
900-
break;
901-
902896
case (EncryptionOptions.OFF):
903897
if (serverOption == EncryptionOptions.OFF)
904898
{
@@ -916,6 +910,7 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
916910
case (EncryptionOptions.NOT_SUP):
917911
if (serverOption == EncryptionOptions.REQ)
918912
{
913+
// Server requires encryption, but client does not support it.
919914
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByClient(), "", 0));
920915
_physicalStateObj.Dispose();
921916
ThrowExceptionAndWarning(_physicalStateObj);
@@ -924,57 +919,15 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
924919
break;
925920

926921
default:
927-
Debug.Fail("Invalid client encryption option detected");
928-
break;
929-
}
930-
931-
if (_encryptionOption == EncryptionOptions.ON ||
932-
_encryptionOption == EncryptionOptions.LOGIN)
933-
{
934-
uint error = 0;
935-
936-
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
937-
bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || (_connHandler._accessTokenInBytes != null && !trustServerCert);
938-
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
939-
| (isYukonOrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0);
940-
941-
if (encrypt && !integratedSecurity)
942-
{
943-
// optimization: in case of SQL Authentication and encryption, set SNI_SSL_IGNORE_CHANNEL_BINDINGS to let SNI
944-
// know that it does not need to allocate/retrieve the Channel Bindings from the SSL context.
945-
// This applies to Native SNI
946-
info |= TdsEnums.SNI_SSL_IGNORE_CHANNEL_BINDINGS;
947-
}
948-
949-
error = _physicalStateObj.EnableSsl(ref info);
950-
951-
if (error != TdsEnums.SNI_SUCCESS)
952-
{
953-
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
954-
ThrowExceptionAndWarning(_physicalStateObj);
955-
}
956-
957-
int protocolVersion = 0;
958-
WaitForSSLHandShakeToComplete(ref error, ref protocolVersion);
959-
960-
SslProtocols protocol = (SslProtocols)protocolVersion;
961-
string warningMessage = protocol.GetProtocolWarning();
962-
if (!string.IsNullOrEmpty(warningMessage))
963-
{
964-
if (!encrypt && LocalAppContextSwitches.SuppressInsecureTLSWarning)
965-
{
966-
// Skip console warning
967-
SqlClientEventSource.Log.TryTraceEvent("<sc|{0}|{1}|{2}>{3}", nameof(TdsParser), nameof(ConsumePreLoginHandshake), SqlClientLogger.LogLevel.Warning, warningMessage);
968-
}
969-
else
922+
// Any other client option needs encryption
923+
if (serverOption == EncryptionOptions.NOT_SUP)
970924
{
971-
// This logs console warning of insecure protocol in use.
972-
_logger.LogWarning(nameof(TdsParser), nameof(ConsumePreLoginHandshake), warningMessage);
925+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
926+
_physicalStateObj.Dispose();
927+
ThrowExceptionAndWarning(_physicalStateObj);
973928
}
974-
}
975929

976-
// create a new packet encryption changes the internal packet size
977-
_physicalStateObj.ClearAllWritePackets();
930+
break;
978931
}
979932

980933
break;
@@ -1057,6 +1010,62 @@ private PreLoginHandshakeStatus ConsumePreLoginHandshake(bool encrypt, bool trus
10571010
}
10581011
}
10591012

1013+
if (_encryptionOption == EncryptionOptions.ON ||
1014+
_encryptionOption == EncryptionOptions.LOGIN)
1015+
{
1016+
if (!serverSupportsEncryption)
1017+
{
1018+
_physicalStateObj.AddError(new SqlError(TdsEnums.ENCRYPTION_NOT_SUPPORTED, (byte)0x00, TdsEnums.FATAL_ERROR_CLASS, _server, SQLMessage.EncryptionNotSupportedByServer(), "", 0));
1019+
_physicalStateObj.Dispose();
1020+
ThrowExceptionAndWarning(_physicalStateObj);
1021+
}
1022+
1023+
uint error = 0;
1024+
1025+
// Validate Certificate if Trust Server Certificate=false and Encryption forced (EncryptionOptions.ON) from Server.
1026+
bool shouldValidateServerCert = (_encryptionOption == EncryptionOptions.ON && !trustServerCert) || (_connHandler._accessTokenInBytes != null && !trustServerCert);
1027+
uint info = (shouldValidateServerCert ? TdsEnums.SNI_SSL_VALIDATE_CERTIFICATE : 0)
1028+
| (isYukonOrLater ? TdsEnums.SNI_SSL_USE_SCHANNEL_CACHE : 0);
1029+
1030+
if (encrypt && !integratedSecurity)
1031+
{
1032+
// optimization: in case of SQL Authentication and encryption, set SNI_SSL_IGNORE_CHANNEL_BINDINGS to let SNI
1033+
// know that it does not need to allocate/retrieve the Channel Bindings from the SSL context.
1034+
// This applies to Native SNI
1035+
info |= TdsEnums.SNI_SSL_IGNORE_CHANNEL_BINDINGS;
1036+
}
1037+
1038+
error = _physicalStateObj.EnableSsl(ref info);
1039+
1040+
if (error != TdsEnums.SNI_SUCCESS)
1041+
{
1042+
_physicalStateObj.AddError(ProcessSNIError(_physicalStateObj));
1043+
ThrowExceptionAndWarning(_physicalStateObj);
1044+
}
1045+
1046+
int protocolVersion = 0;
1047+
WaitForSSLHandShakeToComplete(ref error, ref protocolVersion);
1048+
1049+
SslProtocols protocol = (SslProtocols)protocolVersion;
1050+
string warningMessage = protocol.GetProtocolWarning();
1051+
if (!string.IsNullOrEmpty(warningMessage))
1052+
{
1053+
if (!encrypt && LocalAppContextSwitches.SuppressInsecureTLSWarning)
1054+
{
1055+
// Skip console warning
1056+
SqlClientEventSource.Log.TryTraceEvent("<sc|{0}|{1}|{2}>{3}", nameof(TdsParser), nameof(ConsumePreLoginHandshake), SqlClientLogger.LogLevel.Warning, warningMessage);
1057+
}
1058+
else
1059+
{
1060+
// This logs console warning of insecure protocol in use.
1061+
_logger.LogWarning(nameof(TdsParser), nameof(ConsumePreLoginHandshake), warningMessage);
1062+
}
1063+
}
1064+
1065+
// create a new packet encryption changes the internal packet size
1066+
_physicalStateObj.ClearAllWritePackets();
1067+
}
1068+
10601069
return PreLoginHandshakeStatus.Successful;
10611070
}
10621071

0 commit comments

Comments
 (0)