using System; using System.Diagnostics.CodeAnalysis; using System.Net; using System.Xml; using Renci.SshNet.Common; using Renci.SshNet.NetConf; namespace Renci.SshNet { /// /// Contains operation for working with NetConf server. /// public class NetConfClient : BaseClient { private int _operationTimeout; /// /// Holds instance that used to communicate to the server. /// private INetConfSession _netConfSession; /// /// Gets or sets the operation timeout. /// /// /// The timeout to wait until an operation completes. The default value is negative /// one (-1) milliseconds, which indicates an infinite time-out period. /// /// represents a value that is less than -1 or greater than milliseconds. public TimeSpan OperationTimeout { get { return TimeSpan.FromMilliseconds(_operationTimeout); } set { var timeoutInMilliseconds = value.TotalMilliseconds; if (timeoutInMilliseconds is < -1d or > int.MaxValue) { throw new ArgumentOutOfRangeException(nameof(value), "The timeout must represent a value between -1 and Int32.MaxValue, inclusive."); } _operationTimeout = (int) timeoutInMilliseconds; } } /// /// Gets the current NetConf session. /// /// /// The current NetConf session. /// internal INetConfSession NetConfSession { get { return _netConfSession; } } /// /// Initializes a new instance of the class. /// /// The connection info. /// is null. public NetConfClient(ConnectionInfo connectionInfo) : this(connectionInfo, ownsConnectionInfo: false) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Connection port. /// Authentication username. /// Authentication password. /// is null. /// is invalid, or is null or contains only whitespace characters. /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public NetConfClient(string host, int port, string username, string password) : this(new PasswordConnectionInfo(host, port, username, password), ownsConnectionInfo: true) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Authentication username. /// Authentication password. /// is null. /// is invalid, or is null or contains only whitespace characters. public NetConfClient(string host, string username, string password) : this(host, ConnectionInfo.DefaultPort, username, password) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Connection port. /// Authentication username. /// Authentication private key file(s) . /// is null. /// is invalid, -or- is null or contains only whitespace characters. /// is not within and . [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Disposed in Dispose(bool) method.")] public NetConfClient(string host, int port, string username, params IPrivateKeySource[] keyFiles) : this(new PrivateKeyConnectionInfo(host, port, username, keyFiles), ownsConnectionInfo: true) { } /// /// Initializes a new instance of the class. /// /// Connection host. /// Authentication username. /// Authentication private key file(s) . /// is null. /// is invalid, -or- is null or contains only whitespace characters. public NetConfClient(string host, string username, params IPrivateKeySource[] keyFiles) : this(host, ConnectionInfo.DefaultPort, username, keyFiles) { } /// /// Initializes a new instance of the class. /// /// The connection info. /// Specified whether this instance owns the connection info. /// is null. /// /// If is true, then the /// connection info will be disposed when this instance is disposed. /// private NetConfClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo) : this(connectionInfo, ownsConnectionInfo, new ServiceFactory()) { } /// /// Initializes a new instance of the class. /// /// The connection info. /// Specified whether this instance owns the connection info. /// The factory to use for creating new services. /// is null. /// is null. /// /// If is true, then the /// connection info will be disposed when this instance is disposed. /// internal NetConfClient(ConnectionInfo connectionInfo, bool ownsConnectionInfo, IServiceFactory serviceFactory) : base(connectionInfo, ownsConnectionInfo, serviceFactory) { _operationTimeout = SshNet.Session.Infinite; AutomaticMessageIdHandling = true; } /// /// Gets the NetConf server capabilities. /// /// /// The NetConf server capabilities. /// public XmlDocument ServerCapabilities { get { return _netConfSession.ServerCapabilities; } } /// /// Gets the NetConf client capabilities. /// /// /// The NetConf client capabilities. /// public XmlDocument ClientCapabilities { get { return _netConfSession.ClientCapabilities; } } /// /// Gets or sets a value indicating whether automatic message id handling is /// enabled. /// /// /// true if automatic message id handling is enabled; otherwise, false. /// The default value is true. /// public bool AutomaticMessageIdHandling { get; set; } /// /// Sends the receive RPC. /// /// The RPC. /// /// Reply message to RPC request. /// /// Client is not connected. public XmlDocument SendReceiveRpc(XmlDocument rpc) { return _netConfSession.SendReceiveRpc(rpc, AutomaticMessageIdHandling); } /// /// Sends the receive RPC. /// /// The XML. /// /// Reply message to RPC request. /// public XmlDocument SendReceiveRpc(string xml) { var rpc = new XmlDocument(); rpc.LoadXml(xml); return SendReceiveRpc(rpc); } /// /// Sends the close RPC. /// /// /// Reply message to closing RPC request. /// /// Client is not connected. public XmlDocument SendCloseRpc() { var rpc = new XmlDocument(); rpc.LoadXml(""); return _netConfSession.SendReceiveRpc(rpc, AutomaticMessageIdHandling); } /// /// Called when client is connected to the server. /// protected override void OnConnected() { base.OnConnected(); _netConfSession = CreateAndConnectNetConfSession(); } /// /// Called when client is disconnecting from the server. /// protected override void OnDisconnecting() { base.OnDisconnecting(); _netConfSession.Disconnect(); } /// /// Releases unmanaged and - optionally - managed resources. /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { if (_netConfSession != null) { _netConfSession.Dispose(); _netConfSession = null; } } } private INetConfSession CreateAndConnectNetConfSession() { var netConfSession = ServiceFactory.CreateNetConfSession(Session, _operationTimeout); try { netConfSession.Connect(); return netConfSession; } catch { netConfSession.Dispose(); throw; } } } }