Skip to content

Commit c9aa89f

Browse files
author
Johnny Pham
authored
Update error code when certificate validation fails in managed SNI (#1130)
1 parent 2325ddd commit c9aa89f

File tree

4 files changed

+32
-25
lines changed

4 files changed

+32
-25
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNICommon.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ internal enum SNISMUXFlags
102102
internal class SNICommon
103103
{
104104
private const string s_className = nameof(SNICommon);
105-
105+
106106
// Each error number maps to SNI_ERROR_* in String.resx
107107
internal const int ConnTerminatedError = 2;
108108
internal const int InvalidParameterError = 5;
@@ -220,11 +220,12 @@ internal static uint ReportSNIError(SNIProviders provider, uint nativeError, uin
220220
/// <param name="provider">SNI provider</param>
221221
/// <param name="sniError">SNI error code</param>
222222
/// <param name="sniException">SNI Exception</param>
223+
/// <param name="nativeErrorCode">Native SNI error code</param>
223224
/// <returns></returns>
224-
internal static uint ReportSNIError(SNIProviders provider, uint sniError, Exception sniException)
225+
internal static uint ReportSNIError(SNIProviders provider, uint sniError, Exception sniException, uint nativeErrorCode = 0)
225226
{
226227
SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Provider = {0}, SNI Error = {1}, Exception = {2}", args0: provider, args1: sniError, args2: sniException?.Message);
227-
return ReportSNIError(new SNIError(provider, sniError, sniException));
228+
return ReportSNIError(new SNIError(provider, sniError, sniException, nativeErrorCode));
228229
}
229230

230231
/// <summary>

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIError.cs

+14-11
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ namespace Microsoft.Data.SqlClient.SNI
1111
/// </summary>
1212
internal class SNIError
1313
{
14+
// Error numbers from native SNI implementation
15+
internal const uint CertificateValidationErrorCode = 2148074277;
16+
1417
public readonly SNIProviders provider;
1518
public readonly string errorMessage;
1619
public readonly uint nativeError;
@@ -21,24 +24,24 @@ internal class SNIError
2124

2225
public SNIError(SNIProviders provider, uint nativeError, uint sniErrorCode, string errorMessage)
2326
{
24-
this.lineNumber = 0;
25-
this.function = string.Empty;
27+
lineNumber = 0;
28+
function = string.Empty;
2629
this.provider = provider;
2730
this.nativeError = nativeError;
28-
this.sniError = sniErrorCode;
31+
sniError = sniErrorCode;
2932
this.errorMessage = errorMessage;
30-
this.exception = null;
33+
exception = null;
3134
}
3235

33-
public SNIError(SNIProviders provider, uint sniErrorCode, Exception sniException)
36+
public SNIError(SNIProviders provider, uint sniErrorCode, Exception sniException, uint nativeErrorCode = 0)
3437
{
35-
this.lineNumber = 0;
36-
this.function = string.Empty;
38+
lineNumber = 0;
39+
function = string.Empty;
3740
this.provider = provider;
38-
this.nativeError = 0;
39-
this.sniError = sniErrorCode;
40-
this.errorMessage = string.Empty;
41-
this.exception = sniException;
41+
nativeError = nativeErrorCode;
42+
sniError = sniErrorCode;
43+
errorMessage = string.Empty;
44+
exception = sniException;
4245
}
4346
}
4447
}

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNITcpHandle.cs

+11-8
Original file line numberDiff line numberDiff line change
@@ -179,10 +179,13 @@ public SNITCPHandle(string serverName, int port, long timerExpire, bool parallel
179179
string firstCachedIP;
180180
string secondCachedIP;
181181

182-
if (SqlConnectionIPAddressPreference.IPv6First == ipPreference) {
182+
if (SqlConnectionIPAddressPreference.IPv6First == ipPreference)
183+
{
183184
firstCachedIP = cachedDNSInfo.AddrIPv6;
184185
secondCachedIP = cachedDNSInfo.AddrIPv4;
185-
} else {
186+
}
187+
else
188+
{
186189
firstCachedIP = cachedDNSInfo.AddrIPv4;
187190
secondCachedIP = cachedDNSInfo.AddrIPv6;
188191
}
@@ -339,8 +342,8 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout, boo
339342
IPAddress[] ipAddresses = Dns.GetHostAddresses(serverName);
340343

341344
string IPv4String = null;
342-
string IPv6String = null;
343-
345+
string IPv6String = null;
346+
344347
// Returning null socket is handled by the caller function.
345348
if (ipAddresses == null || ipAddresses.Length == 0)
346349
{
@@ -434,7 +437,7 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout, boo
434437

435438
// If we have already got a valid Socket, or the platform default was prefered
436439
// we won't do the second traversal.
437-
if (availableSocket != null || ipPreference == SqlConnectionIPAddressPreference.UsePlatformDefault)
440+
if (availableSocket is not null || ipPreference == SqlConnectionIPAddressPreference.UsePlatformDefault)
438441
{
439442
break;
440443
}
@@ -590,7 +593,7 @@ public override uint EnableSsl(uint options)
590593
catch (AuthenticationException aue)
591594
{
592595
SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Connection Id {0}, Authentication exception occurred: {1}", args0: _connectionId, args1: aue?.Message);
593-
return ReportTcpSNIError(aue);
596+
return ReportTcpSNIError(aue, SNIError.CertificateValidationErrorCode);
594597
}
595598
catch (InvalidOperationException ioe)
596599
{
@@ -882,10 +885,10 @@ public override uint CheckConnection()
882885
return TdsEnums.SNI_SUCCESS;
883886
}
884887

885-
private uint ReportTcpSNIError(Exception sniException)
888+
private uint ReportTcpSNIError(Exception sniException, uint nativeErrorCode = 0)
886889
{
887890
_status = TdsEnums.SNI_ERROR;
888-
return SNICommon.ReportSNIError(SNIProviders.TCP_PROV, SNICommon.InternalExceptionError, sniException);
891+
return SNICommon.ReportSNIError(SNIProviders.TCP_PROV, SNICommon.InternalExceptionError, sniException, nativeErrorCode);
889892
}
890893

891894
private uint ReportTcpSNIError(uint nativeError, uint sniError, string errorMessage)

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ internal void Connect(
482482
// On Instance failure re-connect and flush SNI named instance cache.
483483
_physicalStateObj.SniContext = SniContext.Snix_Connect;
484484

485-
_physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref _sniSpnBuffer, true, true, fParallel,
485+
_physicalStateObj.CreatePhysicalSNIHandle(serverInfo.ExtendedServerName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref _sniSpnBuffer, true, true, fParallel,
486486
_connHandler.ConnectionOptions.IPAddressPreference, FQDNforDNSCahce, ref _connHandler.pendingSQLDNSObject, integratedSecurity);
487487

488488
if (TdsEnums.SNI_SUCCESS != _physicalStateObj.Status)
@@ -1432,8 +1432,8 @@ internal SqlError ProcessSNIError(TdsParserStateObject stateObj)
14321432
SqlClientEventSource.Log.TryAdvancedTraceErrorEvent("<sc.TdsParser.ProcessSNIError |ERR|ADV > SNI Error Message. Native Error = {0}, Line Number ={1}, Function ={2}, Exception ={3}, Server = {4}",
14331433
(int)details.nativeError, (int)details.lineNumber, details.function, details.exception, _server);
14341434

1435-
return new SqlError((int)details.nativeError, 0x00, TdsEnums.FATAL_ERROR_CLASS,
1436-
_server, errorMessage, details.function, (int)details.lineNumber, details.nativeError, details.exception);
1435+
return new SqlError(infoNumber: (int)details.nativeError, errorState: 0x00, TdsEnums.FATAL_ERROR_CLASS, _server,
1436+
errorMessage, details.function, (int)details.lineNumber, win32ErrorCode: details.nativeError, details.exception);
14371437
}
14381438
finally
14391439
{

0 commit comments

Comments
 (0)