655 lines
24 KiB
C#
655 lines
24 KiB
C#
//----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) Intel Corporation, 2006 - 2010 All Rights Reserved.
|
|
//
|
|
// File: CmdLineArguments.cs
|
|
//
|
|
// Contents: This file is an infrastructure for the entire WSMan sample.
|
|
// It contains a parser for the information inputted by the user
|
|
// via the command line arguments.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Specialized;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Net;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Intel.Manageability.Utils
|
|
{
|
|
/// <summary>
|
|
/// This class is used to parse command line arguments.
|
|
/// Parameters can be given in the following format: [Parameter Value] pair
|
|
/// Parameter starting with - or / and Value separated from a Name with a space.
|
|
/// </summary>
|
|
public class CmdLineArguments
|
|
{
|
|
#region CONSTANTS
|
|
|
|
public const string OPT_HOST = "host";
|
|
public const string OPT_PASS = "pass";
|
|
public const string OPT_USER = "user";
|
|
public const string OPT_SECURE = "tls";
|
|
public const string OPT_KRB = "krb";
|
|
public const string OPT_CERT = "certname";
|
|
public const string OPT_VERBOSE = "verbose";
|
|
public const string OPT_PROXY = "proxy";
|
|
public const string OPT_PROXY_USER = "proxyuser";
|
|
public const string OPT_PROXY_PASSWORD = "proxypass";
|
|
public const string OPT_HELP = "help";
|
|
|
|
private static List<string> PreDefinedFlags = new List<string>();
|
|
private static List<string> StandAloneArguments = new List<string>();
|
|
|
|
static CmdLineArguments()
|
|
{
|
|
InitStandAloneArguments();
|
|
}
|
|
|
|
private static void InitStandAloneArguments()
|
|
{
|
|
string[] tmpFlags = new string[] { OPT_HOST, OPT_PASS, OPT_USER, OPT_SECURE, OPT_KRB, OPT_CERT, OPT_VERBOSE, OPT_PROXY, OPT_PROXY_USER, OPT_PROXY_PASSWORD, OPT_HELP };
|
|
PreDefinedFlags.AddRange(tmpFlags);
|
|
StandAloneArguments.AddRange(tmpFlags);
|
|
}
|
|
|
|
/// <summary>
|
|
/// This enum will be used if the calling
|
|
/// application would like to disable specific conditions
|
|
/// </summary>
|
|
[Flags]
|
|
public enum ExclusionList
|
|
{
|
|
None = 0,
|
|
/// <summary>
|
|
/// The following value should disable the condition
|
|
/// of (username & pwd) | kerberos is needed
|
|
/// Notice the next enum values should be 2, 4, 8 ...
|
|
/// </summary>
|
|
DISABLE_AUTHENTICATION_CHECK = 1
|
|
};
|
|
|
|
|
|
#endregion CONSTANTS
|
|
|
|
#region DATA_MEMBERS
|
|
|
|
/// <summary>
|
|
/// This class represents a command line parameter (argument).
|
|
/// </summary>
|
|
public class Argument
|
|
{
|
|
/// <summary>Argument name identifer without the - , -- or / </summary>
|
|
private string _name = String.Empty;
|
|
|
|
/// <summary>The value of this argument.</summary>
|
|
private string _value = String.Empty;
|
|
|
|
/// <summary>Short description for this argument.</summary>
|
|
private string _description = String.Empty;
|
|
|
|
/// <summary>Indicates if this argument is mandatory.</summary>
|
|
private bool _mandatory; // Initializes by default to false
|
|
|
|
/// <summary>Indicates if this argument was found in the command line. </summary>
|
|
private bool _selected; // Initializes by default to false
|
|
|
|
/// <summary>Indicated whether this argument requires a value</summary>
|
|
private bool _hasValue; // Initializes by default to false
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="name">string, argument identifier</param>
|
|
/// <param name="hasValue">bool, value required</param>
|
|
/// <param name="mandatory">bool, is argument mandatory</param>
|
|
public Argument(string name, bool hasValue, bool mandatory, string description)
|
|
{
|
|
_name = name;
|
|
_hasValue = hasValue;
|
|
_mandatory = mandatory;
|
|
_description = description;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor (for old version support)
|
|
/// </summary>
|
|
/// <param name="name">string, argument identifier</param>
|
|
/// <param name="hasValue">bool, value required</param>
|
|
/// <param name="mandatory">bool, is argument mandatory</param>
|
|
public Argument(string name, bool hasValue, bool mandatory)
|
|
{
|
|
_name = name;
|
|
_hasValue = hasValue;
|
|
_mandatory = mandatory;
|
|
_description = "";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="name">string, argument identifier</param>
|
|
/// <param name="hasValue">bool, value required</param>
|
|
public Argument(string name, bool hasValue)
|
|
{
|
|
_name = name;
|
|
_hasValue = hasValue;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get a string representation of this class
|
|
/// </summary>
|
|
/// <returns>string</returns>
|
|
public override string ToString()
|
|
{
|
|
return _value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property: Argument description
|
|
/// </summary>
|
|
public string Description
|
|
{
|
|
get { return _description; }
|
|
set { _description = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property: Argument identifer without the - , -- or /
|
|
/// </summary>
|
|
public string Name
|
|
{
|
|
get { return _name; }
|
|
set { _name = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property: Indicates whether this argument requires a value
|
|
/// </summary>
|
|
public bool HasValue
|
|
{
|
|
get { return _hasValue; }
|
|
set { _hasValue = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property: Indicates if this argument is mandatory
|
|
/// </summary>
|
|
public bool Mandatory
|
|
{
|
|
get { return _mandatory; }
|
|
set { _mandatory = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property: The value of this argument.
|
|
/// </summary>
|
|
public string Value
|
|
{
|
|
get { return _value; }
|
|
set { _value = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Property: indicates if this argument was found in the command line
|
|
/// </summary>
|
|
public bool Selected
|
|
{
|
|
get { return _selected; }
|
|
set { _selected = value; }
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Thrown by the ApplicationCommandLine during processing
|
|
/// </summary>
|
|
[SerializableAttribute]
|
|
public class Exception : System.Exception
|
|
{
|
|
/// <summary>
|
|
/// Default constructor
|
|
/// </summary>
|
|
/// <param name="msg">string, Error message</param>
|
|
public Exception(string msg) : base(msg) { }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hashtable for arguments
|
|
/// </summary>
|
|
private Dictionary<string, Argument> _arguments;
|
|
|
|
/// <summary>
|
|
/// Indicate if more than one option can be specified - false by default
|
|
/// </summary>
|
|
private bool _hasMultipleOptions = false;
|
|
|
|
public bool HasMultipleOptions
|
|
{
|
|
get { return _hasMultipleOptions; }
|
|
set { _hasMultipleOptions = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// the following variable will contain list of
|
|
/// conditions that the calling application would like to disable
|
|
/// </summary>
|
|
private ExclusionList _exclusionList;
|
|
|
|
#endregion DATA_MEMBERS
|
|
|
|
#region CONSTRUCTORS
|
|
|
|
/// <summary>
|
|
/// Default Constructor
|
|
/// </summary>
|
|
public CmdLineArguments()
|
|
{
|
|
_arguments = new Dictionary<string, Argument>();
|
|
_exclusionList = ExclusionList.None;
|
|
}
|
|
|
|
|
|
|
|
#endregion CONSTRUCTORS
|
|
|
|
#region PUBLIC_FUNCTIONS
|
|
|
|
/// <summary>
|
|
/// Creates a usage explanation string
|
|
/// </summary>
|
|
/// <returns> string, the usage string</returns>
|
|
public string CreateUsage(string assemblyName, string additionalData, bool verbose)
|
|
{
|
|
string usageStr = CreateUsage(assemblyName, verbose);
|
|
|
|
usageStr += "\n" + additionalData + "\n";
|
|
|
|
return usageStr;
|
|
}
|
|
|
|
public void SetExclusionList(ExclusionList exclusionList)
|
|
{
|
|
_exclusionList = exclusionList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a usage explanation string
|
|
/// </summary>
|
|
/// <returns> string, the usage string</returns>
|
|
public string CreateUsage(string assemblyName, bool verbose)
|
|
{
|
|
string usageStr = String.Empty;
|
|
StringBuilder optionsStr = new StringBuilder();
|
|
bool optionsExist = false;
|
|
string firstOption = String.Empty; // Holds first option, if exists, for usage example
|
|
// Go over the options (if any)
|
|
IDictionaryEnumerator e = _arguments.GetEnumerator();
|
|
|
|
int maxOptionNameLength = 0;
|
|
while (e.MoveNext())
|
|
{
|
|
Argument arg = (Argument)_arguments[e.Key.ToString()];
|
|
if (IsCommonArg(arg.Name) == false)
|
|
{
|
|
if (arg.Name.Length > maxOptionNameLength)
|
|
{
|
|
maxOptionNameLength = arg.Name.Length;
|
|
}
|
|
}
|
|
}
|
|
|
|
e = _arguments.GetEnumerator();
|
|
while (e.MoveNext())
|
|
{
|
|
Argument arg = (Argument)_arguments[e.Key.ToString()];
|
|
if (IsCommonArg(arg.Name) == false)
|
|
{
|
|
optionsExist = true;
|
|
optionsStr.Append("\t -" + arg.Name);
|
|
if (String.IsNullOrEmpty(firstOption)) // Gets the first option exists that doesn't have a value
|
|
if (!arg.HasValue)
|
|
firstOption = arg.Name;
|
|
if (arg.HasValue)
|
|
optionsStr.Append(" <value>");
|
|
for (int i = arg.Name.Length; i <= maxOptionNameLength; i++)
|
|
{
|
|
optionsStr.Append(" ");
|
|
}
|
|
optionsStr.Append(": " + arg.Description + "\n");
|
|
}
|
|
}
|
|
|
|
usageStr += "\n";
|
|
usageStr += "Usage:\n======\n\n";
|
|
usageStr += "Run " + assemblyName +".exe to open the GUI application, \n" +
|
|
"Or provide the following connection settings to load them to the GUI:\n";
|
|
|
|
usageStr += "\n";
|
|
usageStr += assemblyName + ".exe";
|
|
if (optionsExist)
|
|
usageStr += " <opt>";
|
|
usageStr += " -host <Hostname> [-user <user name> -pass <password>] [-krb] [-tls -certName <certName>]"
|
|
+ " [-proxy <host:port> [-proxyUser <proxy user> -proxyPass <proxy password>]]";
|
|
usageStr += createUsageForStandAloneComponents();
|
|
|
|
usageStr += "\n\n";
|
|
|
|
if (optionsExist)
|
|
{
|
|
usageStr += "Where <opt> is :\n";
|
|
usageStr += optionsStr.ToString();
|
|
}
|
|
|
|
if (verbose)
|
|
usageStr += "\nIf -verbose is used the sample will display additional output information." + "\n";
|
|
|
|
usageStr += "\nIf -user <username> -pass <password> are defined and -krb isn't defined the Digest authentication scheme is used." + "\n\n"
|
|
+ "If -krb is used the Kerberos authentication scheme will be attempted." + "\n"
|
|
+ "\tIf specified, the kerberos user should be given in domain\\name format." + "\n\n"
|
|
+ "If -tls is used the sample application will perform server authentication. This option is required if the Intel AMT platform is configured for TLS." + "\n"
|
|
+ "Use -certName <name> to specify the client certificate's Common Name (CN)." + "\n\t"
|
|
+ "Used in TLS Mutual Authentication mode only." + "\n\t"
|
|
+ "If this option is not specified the sample application will search the" + "\n\t"
|
|
+ "certificate store for a client certificate matching Intel(R) AMT" + "\n\t" + "requirements." + "\n\t"
|
|
+ "The first one found will be used for authentication." + "\n\n"
|
|
+ "Use -proxy <host:port> when there is a proxy server between the sample application and Intel AMT." + "\n"
|
|
+ "Use -proxyUser <proxy user> -proxyPass <proxy password> when the proxy requires these parameters." + "\n";
|
|
|
|
usageStr += createDescriptionUsageForStandAloneComponents();
|
|
|
|
usageStr += "\nExamples:\n" + GetExamples(assemblyName, firstOption, verbose) + "\n";
|
|
|
|
return usageStr;
|
|
}
|
|
|
|
private string createDescriptionUsageForStandAloneComponents()
|
|
{
|
|
StringBuilder optionsStr = new StringBuilder();
|
|
|
|
foreach (string item in StandAloneArguments)
|
|
{
|
|
if (PreDefinedFlags.Contains(item))
|
|
continue;
|
|
|
|
Argument arg = (Argument)_arguments[item];
|
|
optionsStr.Append(arg.Description + "\n");
|
|
}
|
|
return optionsStr.ToString();
|
|
}
|
|
|
|
private string createUsageForStandAloneComponents()
|
|
{
|
|
StringBuilder optionsStr = new StringBuilder();
|
|
|
|
foreach (string item in StandAloneArguments)
|
|
{
|
|
if (PreDefinedFlags.Contains(item))
|
|
continue;
|
|
|
|
optionsStr.Append(" ");
|
|
Argument arg = (Argument)_arguments[item];
|
|
StringBuilder val = new StringBuilder();
|
|
if (arg.HasValue)
|
|
{
|
|
val.Append(" <value>");
|
|
}
|
|
if (arg.Mandatory)
|
|
{
|
|
optionsStr.Append("-" + item + val);
|
|
}
|
|
else
|
|
{
|
|
optionsStr.Append("[" + "-" + item + val + "]");
|
|
}
|
|
}
|
|
|
|
return optionsStr.ToString();
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Returns a IWebProxy according to the proxy parameters
|
|
/// </summary>
|
|
/// <returns> a IWebProxy or null if proxy parameter not define</returns>
|
|
public IWebProxy GetWebProxy()
|
|
{
|
|
string proxyAddress = this[OPT_PROXY];
|
|
if (proxyAddress != null)
|
|
{
|
|
if (!Regex.IsMatch(proxyAddress, @"\w\:\w"))
|
|
{
|
|
throw new ArgumentException("proxy argument is not according to usage");
|
|
}
|
|
string[] splitAddress = proxyAddress.Split(':');
|
|
int port = 0;
|
|
if (splitAddress.Length != 2 || !int.TryParse(splitAddress[1], out port))
|
|
{
|
|
throw new ArgumentException("proxy argument is not according to usage");
|
|
}
|
|
|
|
IWebProxy proxy = new WebProxy(splitAddress[0], port);
|
|
if (this[OPT_PROXY_USER] != null && this[OPT_PROXY_PASSWORD] != null)
|
|
{
|
|
proxy.Credentials = new NetworkCredential(this[OPT_PROXY_USER], this[OPT_PROXY_PASSWORD]);
|
|
}
|
|
return proxy;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Parse the command line arguments.
|
|
/// </summary>
|
|
/// <param name="args">string array, typically the string[] received from Main</param>
|
|
public void Parse(string[] args)
|
|
{
|
|
int runOptions = 0;
|
|
// Iterate arguments
|
|
for (int i = 0; i < args.Length; i++)
|
|
{
|
|
// if the argument starts with an argument prefix
|
|
if (args[i].StartsWith("-") || args[i].StartsWith("/"))
|
|
{
|
|
string argName = args[i].Substring(1).ToLower();
|
|
// Check if argument is in our _arguments list.
|
|
if (true == _arguments.ContainsKey(argName))
|
|
{
|
|
if (!IsCommonArg(argName))
|
|
{
|
|
runOptions++;
|
|
}
|
|
// Process it
|
|
Argument arg = (Argument)_arguments[argName.ToLower()];
|
|
|
|
// set it to selected
|
|
arg.Selected = true;
|
|
|
|
// Check if argument requires a value.
|
|
if (arg.HasValue)
|
|
{
|
|
if (++i >= args.Length)
|
|
throw new Exception("Could not find value for " + argName + ".");
|
|
|
|
if (args[i].StartsWith("-") || args[i].StartsWith("/"))
|
|
throw new Exception("Could not find value for " + argName + ".");
|
|
arg.Value = args[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Invalid argument
|
|
throw new Exception("Invalid argument: " + argName + ".");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
throw new Exception("Invalid argument: " + args[i] + ".");
|
|
}
|
|
}
|
|
|
|
if (runOptions > 1 && !_hasMultipleOptions)
|
|
{
|
|
throw new Exception("Specified more than one option");
|
|
}
|
|
|
|
// Make sure we received all mandatory arguments
|
|
for (IDictionaryEnumerator e = _arguments.GetEnumerator(); e.MoveNext(); )
|
|
{
|
|
Argument arg = (Argument)e.Value;
|
|
if (arg.Mandatory && !arg.Selected)
|
|
throw new Exception(arg.Name + " is not specified.");
|
|
}
|
|
// Checks appearance of both username and pass or none
|
|
if (((Argument)_arguments["user"]).Selected == !((Argument)_arguments["pass"]).Selected)
|
|
{
|
|
throw new Exception("user and pass must be both specified or both not specified.");
|
|
}
|
|
if (((Argument)_arguments["proxyuser"]).Selected == !((Argument)_arguments["proxypass"]).Selected)
|
|
{
|
|
throw new Exception("proxyUser and proxyPass must be both specified or both not specified.");
|
|
}
|
|
if (!((_exclusionList & ExclusionList.DISABLE_AUTHENTICATION_CHECK) == ExclusionList.DISABLE_AUTHENTICATION_CHECK))
|
|
{
|
|
// Checks authentication method
|
|
if (!((Argument)_arguments["user"]).Selected && !((Argument)_arguments["pass"]).Selected && !((Argument)_arguments["krb"]).Selected)
|
|
{
|
|
throw new Exception("No authentication method available.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an argument to the valid argument list.
|
|
/// </summary>
|
|
/// <param name="arg">Argument, Add an expected argument</param>
|
|
public void AddArg(Argument arg)
|
|
{
|
|
_arguments.Add(arg.Name.ToLower(), arg);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an argument to the valid argument list.
|
|
/// </summary>
|
|
/// <param name="name">string, argument name. </param>
|
|
/// <param name="hasValue">bool, is value required</param>
|
|
/// <param name="mandatory">bool, is mandatory argument</param>
|
|
public void AddArg(string name, bool hasValue, bool mandatory, string description)
|
|
{
|
|
AddArg(new Argument(name.ToLower(), hasValue, mandatory, description));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an argument to the valid argument list.
|
|
/// </summary>
|
|
/// <param name="name">string, argument name. </param>
|
|
/// <param name="hasValue">bool, is value required</param>
|
|
/// <param name="mandatory">bool, is mandatory argument</param>
|
|
public void AddStandAloneArg(string name, bool hasValue, bool mandatory, string description)
|
|
{
|
|
AddArg(new Argument(name.ToLower(), hasValue, mandatory, description));
|
|
StandAloneArguments.Add(name.ToLower());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Add an argument to the valid argument list.
|
|
/// </summary>
|
|
/// <param name="name">string, argument name. </param>
|
|
/// <param name="hasValue">bool, is value required</param>
|
|
/// <param name="mandatory">bool, is mandatory argument</param>
|
|
public void AddArg(string name, bool hasValue, bool mandatory)
|
|
{
|
|
AddArg(new Argument(name.ToLower(), hasValue, mandatory, ""));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Check whether argument was given in the command line.
|
|
/// </summary>
|
|
/// <param name="name">argument name</param>
|
|
/// <returns>true if argument was selected</returns>
|
|
public bool Selected(string name)
|
|
{
|
|
if (_arguments.ContainsKey(name.ToLower()))
|
|
return ((Argument)_arguments[name.ToLower()]).Selected;
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Indexer by argument name (only get)
|
|
/// </summary>
|
|
/// <param name="name">argument</param>
|
|
/// <returns></returns>
|
|
public string this[string name]
|
|
{
|
|
get
|
|
{
|
|
if (_arguments.ContainsKey(name.ToLower()))
|
|
{
|
|
Argument arg = (Argument)_arguments[name.ToLower()];
|
|
if (arg.Selected)
|
|
{
|
|
if (arg.HasValue)
|
|
return arg.Value;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
|
|
#endregion PUBLIC_FUNCTIONS
|
|
|
|
#region PRIVATE_FUNCTIONS
|
|
|
|
/// <summary>
|
|
/// Checks if the parameter name is a common argument that exists as a const.
|
|
/// </summary>
|
|
/// <param name="name">string, name to check</param>
|
|
/// <returns> bool, true if it's a common argument, false if not</returns>
|
|
private static bool IsCommonArg(string name)
|
|
{
|
|
return StandAloneArguments.Contains(name);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the 3 usage examples.
|
|
/// </summary>
|
|
/// <param name="assemblyName">string, the assembly name</param>
|
|
/// <param name="option">string, the first option, or an empty string if no option exists</param>
|
|
/// <param name="verbose">bool, true if verbose flag is on</param>
|
|
/// <returns> string, the 3 examples as a string</returns>
|
|
private static string GetExamples(string assemblyName, string option, bool verbose)
|
|
{
|
|
string examples = String.Empty;
|
|
|
|
// Creates first example
|
|
examples += assemblyName;
|
|
if (!String.IsNullOrEmpty(option))
|
|
examples += " -" + option;
|
|
if (verbose)
|
|
examples += " -" + OPT_VERBOSE;
|
|
examples += " -" + OPT_HOST + " 192.168.0.1 -" + OPT_USER + " admin -" + OPT_PASS + " P@ssw0rd" + "\n";
|
|
// Creates second example
|
|
examples += assemblyName;
|
|
if (!String.IsNullOrEmpty(option))
|
|
examples += " -" + option;
|
|
if (verbose)
|
|
examples += " -" + OPT_VERBOSE;
|
|
examples += " -" + OPT_HOST + " hostname -" + OPT_KRB + "\n";
|
|
// Creates third example
|
|
examples += assemblyName;
|
|
if (!String.IsNullOrEmpty(option))
|
|
examples += " -" + option;
|
|
if (verbose)
|
|
examples += " -" + OPT_VERBOSE;
|
|
examples += " -" + OPT_HOST + " hostname -" + OPT_USER + " admin -" + OPT_PASS + " P@ssw0rd -"
|
|
+ OPT_SECURE + " -" + OPT_CERT + " certCommonName\n";
|
|
|
|
return examples;
|
|
}
|
|
|
|
#endregion PRIVATE_FUNCTIONS
|
|
}
|
|
}
|