< Summary

Information
Class: Renci.SshNet.ServiceFactory
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\ServiceFactory.cs
Line coverage
88%
Covered lines: 69
Uncovered lines: 9
Coverable lines: 78
Total lines: 297
Line coverage: 88.4%
Branch coverage
80%
Covered branches: 12
Total branches: 15
Branch coverage: 80%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

\home\appveyor\projects\ssh-net\src\Renci.SshNet\ServiceFactory.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.Linq;
 4using System.Net.Sockets;
 5using System.Text;
 6
 7using Renci.SshNet.Abstractions;
 8using Renci.SshNet.Common;
 9using Renci.SshNet.Connection;
 10using Renci.SshNet.Messages.Transport;
 11using Renci.SshNet.NetConf;
 12using Renci.SshNet.Security;
 13using Renci.SshNet.Sftp;
 14
 15namespace Renci.SshNet
 16{
 17    /// <summary>
 18    /// Basic factory for creating new services.
 19    /// </summary>
 20    internal sealed partial class ServiceFactory : IServiceFactory
 21    {
 22        /// <summary>
 23        /// Defines the number of times an authentication attempt with any given <see cref="IAuthenticationMethod"/>
 24        /// can result in <see cref="AuthenticationResult.PartialSuccess"/> before it is disregarded.
 25        /// </summary>
 26        private const int PartialSuccessLimit = 5;
 27
 28        /// <summary>
 29        /// Creates an <see cref="IClientAuthentication"/>.
 30        /// </summary>
 31        /// <returns>
 32        /// An <see cref="IClientAuthentication"/>.
 33        /// </returns>
 34        public IClientAuthentication CreateClientAuthentication()
 120435        {
 120436            return new ClientAuthentication(PartialSuccessLimit);
 120437        }
 38
 39        /// <summary>
 40        /// Creates a new <see cref="ISession"/> with the specified <see cref="ConnectionInfo"/> and
 41        /// <see cref="ISocketFactory"/>.
 42        /// </summary>
 43        /// <param name="connectionInfo">The <see cref="ConnectionInfo"/> to use for creating a new session.</param>
 44        /// <param name="socketFactory">A factory to create <see cref="Socket"/> instances.</param>
 45        /// <returns>
 46        /// An <see cref="ISession"/> for the specified <see cref="ConnectionInfo"/>.
 47        /// </returns>
 48        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <see langword="null"/>.</except
 49        /// <exception cref="ArgumentNullException"><paramref name="socketFactory"/> is <see langword="null"/>.</excepti
 50        public ISession CreateSession(ConnectionInfo connectionInfo, ISocketFactory socketFactory)
 121151        {
 121152            return new Session(connectionInfo, this, socketFactory);
 121153        }
 54
 55        /// <summary>
 56        /// Creates a new <see cref="ISftpSession"/> in a given <see cref="ISession"/> and with
 57        /// the specified operation timeout and encoding.
 58        /// </summary>
 59        /// <param name="session">The <see cref="ISession"/> to create the <see cref="ISftpSession"/> in.</param>
 60        /// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or <c>-1</c>
 61        /// <param name="encoding">The encoding.</param>
 62        /// <param name="sftpMessageFactory">The factory to use for creating SFTP messages.</param>
 63        /// <returns>
 64        /// An <see cref="ISftpSession"/>.
 65        /// </returns>
 66        public ISftpSession CreateSftpSession(ISession session, int operationTimeout, Encoding encoding, ISftpResponseFa
 61867        {
 61868            return new SftpSession(session, operationTimeout, encoding, sftpMessageFactory);
 61869        }
 70
 71        /// <summary>
 72        /// Create a new <see cref="PipeStream"/>.
 73        /// </summary>
 74        /// <returns>
 75        /// A <see cref="PipeStream"/>.
 76        /// </returns>
 77        public PipeStream CreatePipeStream()
 35978        {
 35979            return new PipeStream();
 35980        }
 81
 82        /// <summary>
 83        /// Negotiates a key exchange algorithm, and creates a <see cref="IKeyExchange" /> for the negotiated
 84        /// algorithm.
 85        /// </summary>
 86        /// <param name="clientAlgorithms">A <see cref="IDictionary{String, Type}"/> of the key exchange algorithms supp
 87        /// <param name="serverAlgorithms">The names of the key exchange algorithms supported by the SSH server.</param>
 88        /// <returns>
 89        /// A <see cref="IKeyExchange"/> that was negotiated between client and server.
 90        /// </returns>
 91        /// <exception cref="ArgumentNullException"><paramref name="clientAlgorithms"/> is <see langword="null"/>.</exce
 92        /// <exception cref="ArgumentNullException"><paramref name="serverAlgorithms"/> is <see langword="null"/>.</exce
 93        /// <exception cref="SshConnectionException">No key exchange algorithms are supported by both client and server.
 94        public IKeyExchange CreateKeyExchange(IDictionary<string, Type> clientAlgorithms, string[] serverAlgorithms)
 119995        {
 119996            if (clientAlgorithms is null)
 097            {
 098                throw new ArgumentNullException(nameof(clientAlgorithms));
 99            }
 100
 1199101            if (serverAlgorithms is null)
 0102            {
 0103                throw new ArgumentNullException(nameof(serverAlgorithms));
 104            }
 105
 106            // find an algorithm that is supported by both client and server
 1199107            var keyExchangeAlgorithmType = (from c in clientAlgorithms
 3894108                                            from s in serverAlgorithms
 2530109                                            where s == c.Key
 2398110                                            select c.Value).FirstOrDefault();
 111
 1199112            if (keyExchangeAlgorithmType is null)
 0113            {
 0114                throw new SshConnectionException("Failed to negotiate key exchange algorithm.", DisconnectReason.KeyExch
 115            }
 116
 1199117            return keyExchangeAlgorithmType.CreateInstance<IKeyExchange>();
 1199118        }
 119
 120        /// <summary>
 121        /// Creates a new <see cref="INetConfSession"/> in a given <see cref="ISession"/>
 122        /// and with the specified operation timeout.
 123        /// </summary>
 124        /// <param name="session">The <see cref="ISession"/> to create the <see cref="INetConfSession"/> in.</param>
 125        /// <param name="operationTimeout">The number of milliseconds to wait for an operation to complete, or <c>-1</c>
 126        /// <returns>
 127        /// An <see cref="INetConfSession"/>.
 128        /// </returns>
 129        public INetConfSession CreateNetConfSession(ISession session, int operationTimeout)
 0130        {
 0131            return new NetConfSession(session, operationTimeout);
 0132        }
 133
 134        /// <summary>
 135        /// Creates an <see cref="ISftpFileReader"/> for the specified file and with the specified
 136        /// buffer size.
 137        /// </summary>
 138        /// <param name="fileName">The file to read.</param>
 139        /// <param name="sftpSession">The SFTP session to use.</param>
 140        /// <param name="bufferSize">The size of buffer.</param>
 141        /// <returns>
 142        /// An <see cref="ISftpFileReader"/>.
 143        /// </returns>
 144        public ISftpFileReader CreateSftpFileReader(string fileName, ISftpSession sftpSession, uint bufferSize)
 74145        {
 146            const int defaultMaxPendingReads = 10;
 147
 148            // Issue #292: Avoid overlapping SSH_FXP_OPEN and SSH_FXP_LSTAT requests for the same file as this
 149            // causes a performance degradation on Sun SSH
 74150            var openAsyncResult = sftpSession.BeginOpen(fileName, Flags.Read, callback: null, state: null);
 74151            var handle = sftpSession.EndOpen(openAsyncResult);
 152
 70153            var statAsyncResult = sftpSession.BeginLStat(fileName, callback: null, state: null);
 154
 155            long? fileSize;
 156            int maxPendingReads;
 157
 70158            var chunkSize = sftpSession.CalculateOptimalReadLength(bufferSize);
 159
 160            // fallback to a default maximum of pending reads when remote server does not allow us to obtain
 161            // the attributes of the file
 162            try
 70163            {
 70164                var fileAttributes = sftpSession.EndLStat(statAsyncResult);
 67165                fileSize = fileAttributes.Size;
 67166                maxPendingReads = Math.Min(100, (int)Math.Ceiling((double)fileAttributes.Size / chunkSize) + 1);
 67167            }
 3168            catch (SshException ex)
 3169            {
 3170                fileSize = null;
 3171                maxPendingReads = defaultMaxPendingReads;
 172
 3173                DiagnosticAbstraction.Log(string.Format("Failed to obtain size of file. Allowing maximum {0} pending rea
 3174            }
 175
 70176            return sftpSession.CreateFileReader(handle, sftpSession, chunkSize, maxPendingReads, fileSize);
 70177        }
 178
 179        /// <summary>
 180        /// Creates a new <see cref="ISftpResponseFactory"/> instance.
 181        /// </summary>
 182        /// <returns>
 183        /// An <see cref="ISftpResponseFactory"/>.
 184        /// </returns>
 185        public ISftpResponseFactory CreateSftpResponseFactory()
 618186        {
 618187            return new SftpResponseFactory();
 618188        }
 189
 190        /// <summary>
 191        /// Creates a shell stream.
 192        /// </summary>
 193        /// <param name="session">The SSH session.</param>
 194        /// <param name="terminalName">The <c>TERM</c> environment variable.</param>
 195        /// <param name="columns">The terminal width in columns.</param>
 196        /// <param name="rows">The terminal width in rows.</param>
 197        /// <param name="width">The terminal width in pixels.</param>
 198        /// <param name="height">The terminal height in pixels.</param>
 199        /// <param name="terminalModeValues">The terminal mode values.</param>
 200        /// <param name="bufferSize">The size of the buffer.</param>
 201        /// <returns>
 202        /// The created <see cref="ShellStream"/> instance.
 203        /// </returns>
 204        /// <exception cref="SshConnectionException">Client is not connected.</exception>
 205        /// <remarks>
 206        /// <para>
 207        /// The <c>TERM</c> environment variable contains an identifier for the text window's capabilities.
 208        /// You can get a detailed list of these cababilities by using the ‘infocmp’ command.
 209        /// </para>
 210        /// <para>
 211        /// The column/row dimensions override the pixel dimensions(when non-zero). Pixel dimensions refer
 212        /// to the drawable area of the window.
 213        /// </para>
 214        /// </remarks>
 215        public ShellStream CreateShellStream(ISession session, string terminalName, uint columns, uint rows, uint width,
 48216        {
 48217            return new ShellStream(session, terminalName, columns, rows, width, height, terminalModeValues, bufferSize);
 18218        }
 219
 220        /// <summary>
 221        /// Creates an <see cref="IRemotePathTransformation"/> that encloses a path in double quotes, and escapes
 222        /// any embedded double quote with a backslash.
 223        /// </summary>
 224        /// <returns>
 225        /// An <see cref="IRemotePathTransformation"/> that encloses a path in double quotes, and escapes any
 226        /// embedded double quote with a backslash.
 227        /// with a shell.
 228        /// </returns>
 229        public IRemotePathTransformation CreateRemotePathDoubleQuoteTransformation()
 309230        {
 309231            return RemotePathTransformation.DoubleQuote;
 309232        }
 233
 234        /// <summary>
 235        /// Creates an <see cref="IConnector"/> that can be used to establish a connection
 236        /// to the server identified by the specified <paramref name="connectionInfo"/>.
 237        /// </summary>
 238        /// <param name="connectionInfo">A <see cref="IConnectionInfo"/> detailing the server to establish a connection 
 239        /// <param name="socketFactory">A factory to create <see cref="Socket"/> instances.</param>
 240        /// <returns>
 241        /// An <see cref="IConnector"/> that can be used to establish a connection to the
 242        /// server identified by the specified <paramref name="connectionInfo"/>.
 243        /// </returns>
 244        /// <exception cref="ArgumentNullException"><paramref name="connectionInfo"/> is <see langword="null"/>.</except
 245        /// <exception cref="ArgumentNullException"><paramref name="socketFactory"/> is <see langword="null"/>.</excepti
 246        /// <exception cref="NotSupportedException">The <see cref="IConnectionInfo.ProxyType"/> value of <paramref name=
 247        public IConnector CreateConnector(IConnectionInfo connectionInfo, ISocketFactory socketFactory)
 1232248        {
 1232249            if (connectionInfo is null)
 3250            {
 3251                throw new ArgumentNullException(nameof(connectionInfo));
 252            }
 253
 1229254            if (socketFactory is null)
 3255            {
 3256                throw new ArgumentNullException(nameof(socketFactory));
 257            }
 258
 1226259            switch (connectionInfo.ProxyType)
 260            {
 261                case ProxyTypes.None:
 1208262                    return new DirectConnector(socketFactory);
 263                case ProxyTypes.Socks4:
 3264                    return new Socks4Connector(socketFactory);
 265                case ProxyTypes.Socks5:
 3266                    return new Socks5Connector(socketFactory);
 267                case ProxyTypes.Http:
 9268                    return new HttpConnector(socketFactory);
 269                default:
 3270                    throw new NotSupportedException(string.Format("ProxyTypes '{0}' is not supported.", connectionInfo.P
 271            }
 1223272        }
 273
 274        /// <summary>
 275        /// Creates an <see cref="IProtocolVersionExchange"/> that deals with the SSH protocol
 276        /// version exchange.
 277        /// </summary>
 278        /// <returns>
 279        /// An <see cref="IProtocolVersionExchange"/>.
 280        /// </returns>
 281        public IProtocolVersionExchange CreateProtocolVersionExchange()
 1199282        {
 1199283            return new ProtocolVersionExchange();
 1199284        }
 285
 286        /// <summary>
 287        /// Creates a factory to create <see cref="Socket"/> instances.
 288        /// </summary>
 289        /// <returns>
 290        /// An <see cref="ISocketFactory"/>.
 291        /// </returns>
 292        public ISocketFactory CreateSocketFactory()
 1211293        {
 1211294            return new SocketFactory();
 1211295        }
 296    }
 297}