//---------------------------------------------------------------------------- // // Copyright (c) Intel Corporation, 2008 - 2010 All Rights Reserved. // // File: ConnectionInfo.cs // // Contents: This file contains the implementation of a class that // represents the connection information. // //---------------------------------------------------------------------------- using System; using System.Net; using System.Runtime.InteropServices; using Intel.Manageability.WSManagement; using System.Security; namespace Intel.Manageability { /// /// A class that represents the connection information. /// This covers basic TCP connectivity: hostname, port, TLS or not, via web proxy or not, /// or via SOCKS proxy or not. /// [ComVisible(true)] [ProgId("Intel.Manageability.ConnectionInfo")] [ClassInterface(ClassInterfaceType.AutoDual)] [Obsolete("ConnectionInfo class has been deprecated.", false)] public class ConnectionInfo : ICloneable, IDisposable { #region Consts /// /// consts defining username and password limits /// public const int MAX_PWD_LENGTH = 32; public const int MIN_PWD_LENGTH = 8; public const int MAX_USERNAME_LENGTH = 32; #endregion #region ICloneable interface implementation /// /// Clone - return a new copy of this object. /// /// public object Clone() { SocksProxy socksProxyClone = null; if (SoxProxy != null) { socksProxyClone = new SocksProxy { Host = SoxProxy.Host, Password = SoxProxy.Password.Copy(), Port = SoxProxy.Port, UserName = SoxProxy.UserName, }; } var hostClone = (string)Host.Clone(); var usernameClone = (string)UserName.Clone(); var certificateClone = (string)Certificate.Clone(); ConnectionInfo clone; try { var passwordClone = Password.Copy(); clone = new ConnectionInfo(hostClone, usernameClone, passwordClone, Secure, certificateClone, Auth, Proxy, socksProxyClone, AcceptSelfSignedCertificate); } catch { password?.Dispose(); socksProxyClone?.Dispose(); throw; } return clone; } #endregion /// /// Enum that represents the authentication type /// public enum AuthMethod { /// /// HTTP Digest access authentication /// Digest, /// /// HTTP Kerberos access authentication /// Kerberos } /// /// Class which represents a SOCKS proxy. /// XXX: This might should be replaced with an IWebProxy. /// public class SocksProxy : IDisposable { /// /// Hostname / IP of the machine to connect. /// private string host; public string Host { get { return host; } set { //Valdiate host name if (Uri.CheckHostName(value) == UriHostNameType.Unknown) throw new ArgumentException("Argument error - Unknown Host name"); host = value; } } /// /// Port of the machine to connect. /// private int port; public int Port { get { return port; } set { //The largest possible source port number is 2^16 (=65535) if (value < 0 || value > Math.Pow(2.0, 16.0)) { throw new ArgumentException("Argument error - Invalid port number"); } else port = value; } } /// /// User name of the machine to connect. /// private string userName; public string UserName { get { return userName; } set { if (String.IsNullOrEmpty(value)) userName = ""; else { if (value.Length > MAX_USERNAME_LENGTH) throw new ArgumentException("Argument error - Invalid username"); userName = value; } } } /// /// Password of the machine to connect. /// private SecureString password; public SecureString Password { get { return password; } set { //Accepting null value for Kerberos connection (setting value to empty string) if (value == null || value.Length == 0) { password?.Dispose(); password = new SecureString(); } else { if (value.Length < MIN_PWD_LENGTH || value.Length > MAX_PWD_LENGTH) throw new ArgumentException("Argument error - Invalid password"); password?.Dispose(); password = value; } } } private bool _disposed = false; protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { Password?.Dispose(); } _disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~SocksProxy() { Dispose(false); } } /// /// Class which represents overriding paramters. /// public class TcpForwarder { /// /// The forwarder's hostname. /// private string host; public string Host { get { return host; } set { //Valdiate host name if (Uri.CheckHostName(value) == UriHostNameType.Unknown) throw new ArgumentException(String.Format("Argument error - Unknown Host name")); host = value; } } /// /// The overriding port to use for SOAP/WSMAN /// private int port; public int Port { get { return port; } set { //The largest possible source port number is 2^16 (=65535) if (value < 0 || value > Math.Pow(2.0, 16.0)) { throw new ArgumentException("Argument error - Invalid port number"); } else port = value; } } /// /// The overriding port to use to redirection /// private int redirectPort; public int RedirectPort { get { return redirectPort; } set { //The largest possible source port number is 2^16 (=65535) if (value < 0 || value > Math.Pow(2.0, 16.0)) { throw new ArgumentException("Argument error - Invalid port number"); } else redirectPort = value; } } /// /// The overriding port to use for RFB /// private int rfbPort; public int RFBPort { get { return rfbPort; } set { //The largest possible source port number is 2^16 (=65535) if (value < 0 || value > Math.Pow(2.0, 16.0)) { throw new ArgumentException("Argument error - Invalid port number"); } else rfbPort = value; } } } /// /// Constructor /// /// Hostname / IP of the machine to connect. /// User name of the machine to connect. /// Password of the machine to connect. /// Indicates whether or not to use TLS in the connection. /// Certificate name (as it appears in the subject field of the certificate). /// Enum that represents the authentication type. /// Indicates whether or not to use a proxy in the connection. /// Indicate whether to use a SOCKS proxy. public ConnectionInfo() { Host = UserName = Certificate = string.Empty; Password = new SecureString(); } public ConnectionInfo(string host, string userName, SecureString password, bool secure, string certificate, AuthMethod auth, IWebProxy proxy, SocksProxy socksProxy, bool acceptSelfSignedCert = false) { Host = host; UserName = userName; Password = password; Secure = secure; Certificate = certificate; Auth = auth; Proxy = proxy; SoxProxy = socksProxy; AcceptSelfSignedCertificate = acceptSelfSignedCert; } private bool _disposed = false; /// /// Implement IDisposable method /// /// protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { Password?.Dispose(); SoxProxy?.Dispose(); } _disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~ConnectionInfo() { Dispose(false); } /// /// Hostname / IP of the machine to connect. /// private string host; public string Host { get { return host; } set { //Valdiate host name if (Uri.CheckHostName(value) == UriHostNameType.Unknown) throw new ArgumentException("Argument error - Unknown Host name"); host = value; } } /// /// User name of the machine to connect. /// private string userName; public string UserName { get { return userName; } set { if (String.IsNullOrEmpty(value)) { //Accepting null value for Kerberos connection (setting value to empty string) if (Auth == AuthMethod.Kerberos) userName = ""; else throw new ArgumentException("Argument error - Invalid username"); } else { userName = value; if (userName.Length > MAX_USERNAME_LENGTH) throw new ArgumentException("Argument error - Invalid username"); } } } /// /// Password of the machine to connect. /// private SecureString password; public SecureString Password { get { return password; } set { if (value == null || value.Length == 0) { //Accepting null value for Kerberos connection (setting value to empty string) if (Auth == AuthMethod.Kerberos) { password.Dispose(); password = new SecureString(); } else { throw new ArgumentException("Argument error - empty password"); } } else { if (value.Length < MIN_PWD_LENGTH || value.Length > MAX_PWD_LENGTH) throw new ArgumentException("Argument error - Invalid password"); password?.Dispose(); password = value; } } } /// /// Full URI (e.g. http://hostname:16992/wsman) /// public Uri HostUri { get { UriBuilder newUri; if (Forwarder == null) { newUri = new UriBuilder((Secure ? "https" : "http"), Host, (Secure ? 16993 : 16992), "wsman"); } else { newUri = new UriBuilder((Secure ? "https" : "http"), Forwarder.Host, Forwarder.Port, "wsman"); } return newUri.Uri; } } /// /// Indicates whether or not to use TLS in the connection. /// public bool Secure { set; get; } /// /// Indicates whether or not to accept self signed certificate in a TLS connection. /// public bool AcceptSelfSignedCertificate { set; get; } /// /// Certificate name (as it appears in the subject field of the certificate) /// private string certificate; public string Certificate { get { return certificate; } set { if (value == null) certificate = ""; else certificate = value; // In the common name field of the DN of a X509 certificate, , the limit is up to 64 characters if (certificate.Length > 64) throw new ArgumentException("Argument error - Invalid certificate"); } } /// /// Enum that represents the authentication type /// public AuthMethod Auth { set; get; } /// /// Indicates whether or not to use a proxy in the connection. /// public IWebProxy Proxy { set; get; } /// /// Use a SOCKS proxy. Needed for redirection connections. /// public SocksProxy SoxProxy { get; set; } /// /// Use TCP forwarding parameters. Needed for redirected connections. /// public TcpForwarder Forwarder { get; set; } } /// /// This class represents a management session: the host to connect to and how /// (as represented in the ConnectionInfo), and the management transport to use, /// which should be either "ws-man", "soap", or "none". /// public class ManagedSystem : IDisposable, ICloneable { /// /// WS-Man Connection. /// public const string TRANSPORT_WS_MAN = "ws-man"; /// /// Soap Connection. /// public const string TRANSPORT_SOAP = "soap"; // not used much right now #region ICloneable interface implementation /// /// Clone - return a new copy of this object. /// /// public object Clone() { ConnectionInfo i = (ConnectionInfo)this.ConnectionInfo.Clone(); ManagedSystem m = new ManagedSystem(i, this.TransportMechanism); return m; } #endregion #region IDisposable interface implementation private bool _disposed = false; protected virtual void Dispose(bool disposing) { if (_disposed) return; if (disposing) { ConnectionInfo?.Dispose(); } _disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } ~ManagedSystem() { Dispose(false); } #endregion /// /// The connection information for this session. /// public ConnectionInfo ConnectionInfo { get; set; } /// /// The transport mechanism to use /// public string TransportMechanism { get; set; } /// /// Constructor. /// /// The connection information for this session. /// The transport mechanism to use public ManagedSystem(ConnectionInfo info, string transport) { ConnectionInfo = info; TransportMechanism = transport; } /// /// Constructor. /// /// The connection information for this session. public ManagedSystem(ConnectionInfo info) { ConnectionInfo = info; TransportMechanism = TRANSPORT_WS_MAN; } } }