605 lines
18 KiB
C#
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//----------------------------------------------------------------------------
//
// 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;
}
}
}