mirror of
https://github.com/ckaczor/sqltoolsservice.git
synced 2026-01-13 17:23:02 -05:00
* 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
106 lines
3.8 KiB
C#
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
|
|
}
|
|
}
|