Files
sqltoolsservice/src/Microsoft.SqlTools.ResourceProvider.Core/Firewall/FirewallErrorParser.cs
Karl Burtram 71cda5bbdc Update to latest .Net SDK 7.0 (#1760)
* Bump to SDK 7.0 and related updates

* More net 7 updates

* Install SDK 2.0 for ESRP

* Fix typo

* Address comment and update integration test script

* Disable new warnings from SDK update
2022-11-14 20:24:25 -08:00

106 lines
3.8 KiB
C#

//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System;
using Microsoft.Data.SqlClient;
using System.Net;
using System.Text.RegularExpressions;
namespace Microsoft.SqlTools.ResourceProvider.Core.Firewall
{
internal interface IFirewallErrorParser
{
/// <summary>
/// Parses given error message and error code to see if it's firewall rule error
/// and finds the blocked ip address
/// </summary>
FirewallParserResponse ParseErrorMessage(string errorMessage, int errorCode);
/// <summary>
/// Parses given error message and error code to see if it's firewall rule error
/// and finds the blocked ip address
/// </summary>
FirewallParserResponse ParseException(SqlException sqlException);
}
/// <summary>
/// Parses an error to check for firewall rule error. Will include the blocked ip address if firewall rule error is detected
/// </summary>
public class FirewallErrorParser : IFirewallErrorParser
{
/// <summary>
/// Parses given error message and error code to see if it's firewall rule error
/// and finds the blocked ip address
/// </summary>
public FirewallParserResponse ParseException(SqlException sqlException)
{
CommonUtil.CheckForNull(sqlException, "sqlException");
return ParseErrorMessage(sqlException.Message, sqlException.Number);
}
/// <summary>
/// Parses given error message and error code to see if it's firewall rule error
/// and finds the blocked ip address
/// </summary>
public FirewallParserResponse ParseErrorMessage(string errorMessage, int errorCode)
{
CommonUtil.CheckForNull(errorMessage, "errorMessage");
FirewallParserResponse response = new FirewallParserResponse();
if (IsSqlAzureFirewallBlocked(errorCode))
{
// Connection failed due to blocked client IP
IPAddress clientIp;
if (TryParseClientIp(errorMessage, out clientIp))
{
response = new FirewallParserResponse(true, clientIp);
}
}
return response;
}
/// <summary>
/// Parses the given message to find the blocked ip address
/// </summary>
private static bool TryParseClientIp(string message, out IPAddress clientIp)
{
clientIp = null;
try
{
#pragma warning disable SYSLIB1045
Regex regex =
new Regex(
@"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b",
RegexOptions.IgnoreCase);
#pragma warning restore SYSLIB1045
Match match = regex.Match(message);
if (match.Success)
{
string clientIpValue = match.Value;
return IPAddress.TryParse(clientIpValue, out clientIp);
}
return false;
}
catch (Exception)
{
//TODO: trace?
return false;
}
}
/// <summary>
/// Returns true if given error code is firewall rule blocked error code
/// </summary>
private bool IsSqlAzureFirewallBlocked(int errorCode)
{
return errorCode == SqlAzureFirewallBlockedErrorNumber;
}
private const int SqlAzureFirewallBlockedErrorNumber = 40615; // http://msdn.microsoft.com/en-us/library/windowsazure/ff394106.aspx
}
}