605 lines
18 KiB
C#
605 lines
18 KiB
C#
//----------------------------------------------------------------------------
|
||
//
|
||
// 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
|
||
{
|
||
/// <summary>
|
||
/// 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.
|
||
/// </summary>
|
||
[ComVisible(true)]
|
||
[ProgId("Intel.Manageability.ConnectionInfo")]
|
||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||
[Obsolete("ConnectionInfo class has been deprecated.", false)]
|
||
public class ConnectionInfo : ICloneable, IDisposable
|
||
{
|
||
#region Consts
|
||
|
||
/// <summary>
|
||
/// consts defining username and password limits
|
||
/// </summary>
|
||
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
|
||
|
||
/// <summary>
|
||
/// Clone - return a new copy of this object.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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
|
||
|
||
/// <summary>
|
||
/// Enum that represents the authentication type
|
||
/// </summary>
|
||
public enum AuthMethod
|
||
{
|
||
/// <summary>
|
||
/// HTTP Digest access authentication
|
||
/// </summary>
|
||
Digest,
|
||
|
||
/// <summary>
|
||
/// HTTP Kerberos access authentication
|
||
/// </summary>
|
||
Kerberos
|
||
}
|
||
|
||
/// <summary>
|
||
/// Class which represents a SOCKS proxy.
|
||
/// XXX: This might should be replaced with an IWebProxy.
|
||
/// </summary>
|
||
public class SocksProxy : IDisposable
|
||
{
|
||
/// <summary>
|
||
/// Hostname / IP of the machine to connect.
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Port of the machine to connect.
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// User name of the machine to connect.
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Password of the machine to connect.
|
||
/// </summary>
|
||
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);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Class which represents overriding paramters.
|
||
/// </summary>
|
||
public class TcpForwarder
|
||
{
|
||
/// <summary>
|
||
/// The forwarder's hostname.
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// The overriding port to use for SOAP/WSMAN
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// The overriding port to use to redirection
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// The overriding port to use for RFB
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Constructor
|
||
/// </summary>
|
||
/// <param name="host">Hostname / IP of the machine to connect.</param>
|
||
/// <param name="userName">User name of the machine to connect.</param>
|
||
/// <param name="password">Password of the machine to connect.</param>
|
||
/// <param name="secure">Indicates whether or not to use TLS in the connection.</param>
|
||
/// <param name="certificate">Certificate name (as it appears in the subject field of the certificate).</param>
|
||
/// <param name="auth">Enum that represents the authentication type.</param>
|
||
/// <param name="proxy">Indicates whether or not to use a proxy in the connection.</param>
|
||
/// <param name="socksProxy">Indicate whether to use a SOCKS proxy.</param>
|
||
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;
|
||
|
||
/// <summary>
|
||
/// Implement IDisposable method
|
||
/// </summary>
|
||
/// <param name="disposing"></param>
|
||
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// Hostname / IP of the machine to connect.
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// User name of the machine to connect.
|
||
/// </summary>
|
||
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");
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Password of the machine to connect.
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Full URI (e.g. http://hostname:16992/wsman)
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Indicates whether or not to use TLS in the connection.
|
||
/// </summary>
|
||
public bool Secure { set; get; }
|
||
|
||
/// <summary>
|
||
/// Indicates whether or not to accept self signed certificate in a TLS connection.
|
||
/// </summary>
|
||
public bool AcceptSelfSignedCertificate { set; get; }
|
||
|
||
/// <summary>
|
||
/// Certificate name (as it appears in the subject field of the certificate)
|
||
/// </summary>
|
||
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");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Enum that represents the authentication type
|
||
/// </summary>
|
||
public AuthMethod Auth { set; get; }
|
||
|
||
/// <summary>
|
||
/// Indicates whether or not to use a proxy in the connection.
|
||
/// </summary>
|
||
public IWebProxy Proxy { set; get; }
|
||
|
||
/// <summary>
|
||
/// Use a SOCKS proxy. Needed for redirection connections.
|
||
/// </summary>
|
||
public SocksProxy SoxProxy { get; set; }
|
||
|
||
/// <summary>
|
||
/// Use TCP forwarding parameters. Needed for redirected connections.
|
||
/// </summary>
|
||
public TcpForwarder Forwarder { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 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".
|
||
/// </summary>
|
||
public class ManagedSystem : IDisposable, ICloneable
|
||
{
|
||
/// <summary>
|
||
/// WS-Man Connection.
|
||
/// </summary>
|
||
public const string TRANSPORT_WS_MAN = "ws-man";
|
||
|
||
/// <summary>
|
||
/// Soap Connection.
|
||
/// </summary>
|
||
public const string TRANSPORT_SOAP = "soap"; // not used much right now
|
||
|
||
#region ICloneable interface implementation
|
||
|
||
/// <summary>
|
||
/// Clone - return a new copy of this object.
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
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
|
||
|
||
/// <summary>
|
||
/// The connection information for this session.
|
||
/// </summary>
|
||
public ConnectionInfo ConnectionInfo { get; set; }
|
||
|
||
/// <summary>
|
||
/// The transport mechanism to use
|
||
/// </summary>
|
||
public string TransportMechanism { get; set; }
|
||
|
||
/// <summary>
|
||
/// Constructor.
|
||
/// </summary>
|
||
/// <param name="info">The connection information for this session.</param>
|
||
/// <param name="transport">The transport mechanism to use</param>
|
||
public ManagedSystem(ConnectionInfo info, string transport)
|
||
{
|
||
ConnectionInfo = info;
|
||
TransportMechanism = transport;
|
||
}
|
||
|
||
/// <summary>
|
||
/// Constructor.
|
||
/// </summary>
|
||
/// <param name="info">The connection information for this session.</param>
|
||
public ManagedSystem(ConnectionInfo info)
|
||
{
|
||
ConnectionInfo = info;
|
||
TransportMechanism = TRANSPORT_WS_MAN;
|
||
}
|
||
}
|
||
} |