< Summary

Information
Class: Renci.SshNet.KeyboardInteractiveAuthenticationMethod
Assembly: Renci.SshNet
File(s): \home\appveyor\projects\ssh-net\src\Renci.SshNet\KeyboardInteractiveAuthenticationMethod.cs
Line coverage
72%
Covered lines: 69
Uncovered lines: 26
Coverable lines: 95
Total lines: 185
Line coverage: 72.6%
Branch coverage
50%
Covered branches: 7
Total branches: 14
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Name()100%1100%
Authenticate(...)50%286.36%
Session_UserAuthenticationSuccessReceived(...)100%1100%
Session_UserAuthenticationFailureReceived(...)50%272.72%
Session_UserAuthenticationInformationRequestReceived(...)75%482.75%
Dispose()100%10%
Dispose(...)33.33%626.66%
Finalize()100%1100%

File(s)

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

#LineLine coverage
 1using System;
 2using System.Linq;
 3using System.Runtime.ExceptionServices;
 4using System.Threading;
 5
 6using Renci.SshNet.Abstractions;
 7using Renci.SshNet.Common;
 8using Renci.SshNet.Messages;
 9using Renci.SshNet.Messages.Authentication;
 10
 11namespace Renci.SshNet
 12{
 13    /// <summary>
 14    /// Provides functionality to perform keyboard interactive authentication.
 15    /// </summary>
 16    public class KeyboardInteractiveAuthenticationMethod : AuthenticationMethod, IDisposable
 17    {
 18        private readonly RequestMessage _requestMessage;
 53519        private AuthenticationResult _authenticationResult = AuthenticationResult.Failure;
 20        private Session _session;
 53521        private EventWaitHandle _authenticationCompleted = new AutoResetEvent(initialState: false);
 22        private Exception _exception;
 23        private bool _isDisposed;
 24
 25        /// <summary>
 26        /// Gets the name of the authentication method.
 27        /// </summary>
 28        /// <value>
 29        /// The name of the authentication method.
 30        /// </value>
 31        public override string Name
 32        {
 1233            get { return _requestMessage.MethodName; }
 34        }
 35
 36        /// <summary>
 37        /// Occurs when server prompts for more authentication information.
 38        /// </summary>
 39        public event EventHandler<AuthenticationPromptEventArgs> AuthenticationPrompt;
 40
 41        /// <summary>
 42        /// Initializes a new instance of the <see cref="KeyboardInteractiveAuthenticationMethod"/> class.
 43        /// </summary>
 44        /// <param name="username">The username.</param>
 45        /// <exception cref="ArgumentException"><paramref name="username"/> is whitespace or <see langword="null"/>.</ex
 46        public KeyboardInteractiveAuthenticationMethod(string username)
 53547            : base(username)
 52948        {
 52949            _requestMessage = new RequestMessageKeyboardInteractive(ServiceName.Connection, username);
 52950        }
 51
 52        /// <summary>
 53        /// Authenticates the specified session.
 54        /// </summary>
 55        /// <param name="session">The session to authenticate.</param>
 56        /// <returns>Result of authentication  process.</returns>
 57        public override AuthenticationResult Authenticate(Session session)
 358        {
 359            _session = session;
 60
 361            session.UserAuthenticationSuccessReceived += Session_UserAuthenticationSuccessReceived;
 362            session.UserAuthenticationFailureReceived += Session_UserAuthenticationFailureReceived;
 363            session.UserAuthenticationInformationRequestReceived += Session_UserAuthenticationInformationRequestReceived
 64
 365            session.RegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
 66
 67            try
 368            {
 369                session.SendMessage(_requestMessage);
 370                session.WaitOnHandle(_authenticationCompleted);
 371            }
 72            finally
 373            {
 374                session.UnRegisterMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
 375                session.UserAuthenticationSuccessReceived -= Session_UserAuthenticationSuccessReceived;
 376                session.UserAuthenticationFailureReceived -= Session_UserAuthenticationFailureReceived;
 377                session.UserAuthenticationInformationRequestReceived -= Session_UserAuthenticationInformationRequestRece
 378            }
 79
 380            if (_exception != null)
 081            {
 082                ExceptionDispatchInfo.Capture(_exception).Throw();
 083            }
 84
 385            return _authenticationResult;
 386        }
 87
 88        private void Session_UserAuthenticationSuccessReceived(object sender, MessageEventArgs<SuccessMessage> e)
 289        {
 290            _authenticationResult = AuthenticationResult.Success;
 291            _ = _authenticationCompleted.Set();
 292        }
 93
 94        private void Session_UserAuthenticationFailureReceived(object sender, MessageEventArgs<FailureMessage> e)
 195        {
 196            if (e.Message.PartialSuccess)
 197            {
 198                _authenticationResult = AuthenticationResult.PartialSuccess;
 199            }
 100            else
 0101            {
 0102                _authenticationResult = AuthenticationResult.Failure;
 0103            }
 104
 105            // Copy allowed authentication methods
 1106            AllowedAuthentications = e.Message.AllowedAuthentications;
 107
 1108            _ = _authenticationCompleted.Set();
 1109        }
 110
 111        private void Session_UserAuthenticationInformationRequestReceived(object sender, MessageEventArgs<InformationReq
 9112        {
 9113            var informationRequestMessage = e.Message;
 114
 9115            var eventArgs = new AuthenticationPromptEventArgs(Username,
 9116                                                              informationRequestMessage.Instruction,
 9117                                                              informationRequestMessage.Language,
 9118                                                              informationRequestMessage.Prompts);
 119
 9120            ThreadAbstraction.ExecuteThread(() =>
 9121                {
 9122                    try
 9123                    {
 9124                        AuthenticationPrompt?.Invoke(this, eventArgs);
 9125
 9126                        var informationResponse = new InformationResponseMessage();
 9127
 51128                        foreach (var response in from r in eventArgs.Prompts orderby r.Id ascending select r.Response)
 6129                        {
 6130                            informationResponse.Responses.Add(response);
 6131                        }
 9132
 9133                        // Send information response message
 9134                        _session.SendMessage(informationResponse);
 9135                    }
 0136                    catch (Exception exp)
 0137                    {
 0138                        _exception = exp;
 0139                        _ = _authenticationCompleted.Set();
 0140                    }
 18141                });
 9142        }
 143
 144        /// <summary>
 145        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 146        /// </summary>
 147        public void Dispose()
 0148        {
 0149            Dispose(disposing: true);
 0150            GC.SuppressFinalize(this);
 0151        }
 152
 153        /// <summary>
 154        /// Releases unmanaged and - optionally - managed resources.
 155        /// </summary>
 156        /// <param name="disposing"><see langword="true"/> to release both managed and unmanaged resources; <see langwor
 157        protected virtual void Dispose(bool disposing)
 532158        {
 532159            if (_isDisposed)
 0160            {
 0161                return;
 162            }
 163
 532164            if (disposing)
 0165            {
 0166                var authenticationCompleted = _authenticationCompleted;
 0167                if (authenticationCompleted != null)
 0168                {
 0169                    _authenticationCompleted = null;
 0170                    authenticationCompleted.Dispose();
 0171                }
 172
 0173                _isDisposed = true;
 0174            }
 532175        }
 176
 177        /// <summary>
 178        /// Finalizes an instance of the <see cref="KeyboardInteractiveAuthenticationMethod"/> class.
 179        /// </summary>
 180        ~KeyboardInteractiveAuthenticationMethod()
 1064181        {
 532182            Dispose(disposing: false);
 1064183        }
 184    }
 185}