// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System;
using System.Management.Automation.Language;
using Microsoft.Windows.PowerShell.ScriptAnalyzer.Generic;
#if !CORECLR
using System.ComponentModel.Composition;
#endif
using System.Globalization;
using System.Linq;
namespace Microsoft.Windows.PowerShell.ScriptAnalyzer.BuiltinRules
{
///
/// AvoidUsingComputerNameHardcoded: Check that parameter ComputerName is not hardcoded.
///
#if !CORECLR
[Export(typeof(IScriptRule))]
#endif
public class AvoidUsingComputerNameHardcoded : AvoidParameterGeneric
{
private readonly string[] localhostRepresentations = new string[]
{
"localhost",
".",
"::1",
"127.0.0.1"
};
///
/// Condition on the cmdlet that must be satisfied for the error to be raised
///
///
///
public override bool CommandCondition(CommandAst CmdAst)
{
return true;
}
///
/// Condition on the parameter that must be satisfied for the error to be raised.
///
///
///
///
public override bool ParameterCondition(CommandAst CmdAst, CommandElementAst CeAst)
{
if (CeAst is CommandParameterAst)
{
CommandParameterAst cmdParamAst = CeAst as CommandParameterAst;
if (String.Equals(cmdParamAst.ParameterName, "computername", StringComparison.OrdinalIgnoreCase))
{
Ast computerNameArgument = cmdParamAst.Argument;
if (computerNameArgument == null)
{
computerNameArgument = GetComputerNameArg(CmdAst, cmdParamAst.Extent.StartOffset);
if (computerNameArgument == null)
{
return false;
}
}
var constExprAst = computerNameArgument as ConstantExpressionAst;
if (constExprAst != null)
{
return !IsLocalhost(constExprAst);
}
}
}
return false;
}
private bool IsLocalhost(ConstantExpressionAst constExprAst)
{
var constExprVal = constExprAst.Value as string;
if (constExprVal != null)
{
return localhostRepresentations.Contains(
constExprVal,
StringComparer.OrdinalIgnoreCase);
}
return false;
}
private Ast GetComputerNameArg(CommandAst CmdAst, int StartIndex)
{
int small = int.MaxValue;
Ast computerNameArg = null;
foreach (Ast ast in CmdAst.CommandElements)
{
if (ast.Extent.StartOffset > StartIndex && ast.Extent.StartOffset < small)
{
computerNameArg = ast;
small = ast.Extent.StartOffset;
}
}
return computerNameArg;
}
///
/// Retrieves the error message
///
///
///
///
public override string GetError(string FileName, CommandAst CmdAst)
{
if (CmdAst == null)
{
return string.Empty;
}
return string.Format(CultureInfo.CurrentCulture, Strings.AvoidComputerNameHardcodedError, CmdAst.GetCommandName());
}
///
/// GetName: Retrieves the name of this rule.
///
/// The name of this rule
public override string GetName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.NameSpaceFormat, GetSourceName(), Strings.AvoidComputerNameHardcodedName);
}
///
/// GetCommonName: Retrieves the common name of this rule.
///
/// The common name of this rule
public override string GetCommonName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.AvoidComputerNameHardcodedCommonName);
}
///
/// GetDescription: Retrieves the description of this rule.
///
/// The description of this rule
public override string GetDescription()
{
return string.Format(CultureInfo.CurrentCulture, Strings.AvoidComputerNameHardcodedDescription);
}
///
/// GetSourceType: Retrieves the type of the rule: builtin, managed or module.
///
public override SourceType GetSourceType()
{
return SourceType.Builtin;
}
///
/// GetSeverity: Retrieves the severity of the rule: error, warning or information.
///
///
public override RuleSeverity GetSeverity()
{
return RuleSeverity.Error;
}
///
/// DiagnosticSeverity: Retrieves the severity of the rule of type DiagnosticSeverity: error, warning or information.
///
///
public override DiagnosticSeverity GetDiagnosticSeverity()
{
return DiagnosticSeverity.Error;
}
///
/// GetSourceName: Retrieves the module/assembly name the rule is from.
///
public override string GetSourceName()
{
return string.Format(CultureInfo.CurrentCulture, Strings.SourceName);
}
}
}